Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73d27711 authored by Louis Chang's avatar Louis Chang
Browse files

Allow changing focus between embedded activities in a Task

The focused window was determined by looking up the focusable windows
from top to bottom.

In order to switch the focus between the embedded activities in the
same leaf Task without reordering the position of the activities, the
focused app can also be updated based on the window that user was
touched, and the focusable windows that were on other TaskFragment
in the same Task cannot be focused.

Bug: 189385926
Test: changing focused app by touching embedded activity
Change-Id: Id84461572cc768f474ffa313da1c10ff4010408e
parent 558a160f
Loading
Loading
Loading
Loading
+6 −18
Original line number Diff line number Diff line
@@ -79,12 +79,6 @@
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "at": "com\/android\/server\/wm\/Transition.java"
    },
    "-2029985709": {
      "message": "setFocusedTask: taskId=%d",
      "level": "DEBUG",
      "group": "WM_DEBUG_FOCUS",
      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
    },
    "-2024464438": {
      "message": "app-onAnimationFinished(): mOuter=%s",
      "level": "DEBUG",
@@ -169,12 +163,6 @@
      "group": "WM_DEBUG_WINDOW_ORGANIZER",
      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
    },
    "-1939358269": {
      "message": "mRecentScreenshotAnimator finish",
      "level": "DEBUG",
      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
    },
    "-1938839202": {
      "message": "SURFACE LEAK DESTROY: %s",
      "level": "INFO",
@@ -1783,6 +1771,12 @@
      "group": "WM_DEBUG_STATES",
      "at": "com\/android\/server\/wm\/TaskFragment.java"
    },
    "-55185509": {
      "message": "setFocusedTask: taskId=%d touchedActivity=%s",
      "level": "DEBUG",
      "group": "WM_DEBUG_FOCUS",
      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
    },
    "-50336993": {
      "message": "moveFocusableActivityToTop: activity=%s",
      "level": "DEBUG",
@@ -3535,12 +3529,6 @@
      "group": "WM_DEBUG_APP_TRANSITIONS",
      "at": "com\/android\/server\/wm\/AppTransitionController.java"
    },
    "1984470582": {
      "message": "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d",
      "level": "DEBUG",
      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
      "at": "com\/android\/server\/wm\/TaskScreenshotAnimatable.java"
    },
    "1984782949": {
      "message": ">>> OPEN TRANSACTION animate",
      "level": "INFO",
+27 −10
Original line number Diff line number Diff line
@@ -1875,22 +1875,39 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    @Override
    public void setFocusedTask(int taskId) {
        enforceTaskPermission("setFocusedTask()");
        ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedTask: taskId=%d", taskId);
        final long callingId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                        MATCH_ATTACHED_TASK_ONLY);
                setFocusedTask(taskId, null /* touchedActivity */);
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

    void setFocusedTask(int taskId, ActivityRecord touchedActivity) {
        ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedTask: taskId=%d touchedActivity=%s", taskId,
                touchedActivity);
        final Task task = mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_ONLY);
        if (task == null) {
            return;
        }
        final ActivityRecord r = task.topRunningActivityLocked();
                if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
                    mRootWindowContainer.resumeFocusedTasksTopActivities();
                }
        if (r == null) {
            return;
        }
        } finally {
            Binder.restoreCallingIdentity(callingId);

        if (r.moveFocusableActivityToTop("setFocusedTask")) {
            mRootWindowContainer.resumeFocusedTasksTopActivities();
        } else if (touchedActivity != null && touchedActivity != r
                && touchedActivity.getTask() == r.getTask()
                && touchedActivity.getTaskFragment() != r.getTaskFragment()) {
            // Set the focused app directly since the focused window is not on the
            // top-most TaskFragment of the top-most Task
            final DisplayContent displayContent = touchedActivity.getDisplayContent();
            displayContent.setFocusedApp(touchedActivity);
            mWindowManager.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
                    true /* updateInputWindows */);
        }
    }

+6 −0
Original line number Diff line number Diff line
@@ -770,6 +770,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                mTmpWindow = null;
                return true;
            }

            if (focusedApp.getTask() == activity.getTask()
                    && focusedApp.getTaskFragment() != activity.getTaskFragment()) {
                // Do not use the activity window of another TaskFragment in the same leaf Task
                return false;
            }
        }

        ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: Found new focus @ %s", w);
+3 −3
Original line number Diff line number Diff line
@@ -8183,11 +8183,11 @@ public class WindowManagerService extends IWindowManager.Stub
            displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP, displayContent,
                    true /* includingParents */);
        }
        handleTaskFocusChange(touchedWindow.getTask());
        handleTaskFocusChange(touchedWindow.getTask(), touchedWindow.mActivityRecord);
    }

    @VisibleForTesting
    void handleTaskFocusChange(Task task) {
    void handleTaskFocusChange(Task task, ActivityRecord touchedActivity) {
        if (task == null) {
            return;
        }
@@ -8206,7 +8206,7 @@ public class WindowManagerService extends IWindowManager.Stub
            }
        }

        mAtmService.setFocusedTask(task.mTaskId);
        mAtmService.setFocusedTask(task.mTaskId, touchedActivity);
    }

    /**
+6 −6
Original line number Diff line number Diff line
@@ -107,9 +107,9 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        Task tappedTask = createTaskInRootTask(tappedRootTask, 0 /* userId */);
        spyOn(mWm.mAtmService);

        mWm.handleTaskFocusChange(tappedTask);
        mWm.handleTaskFocusChange(tappedTask, null /* window */);

        verify(mWm.mAtmService).setFocusedTask(tappedTask.mTaskId);
        verify(mWm.mAtmService).setFocusedTask(tappedTask.mTaskId, null);
    }

    @Test
@@ -128,9 +128,9 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        Task tappedTask = createTaskInRootTask(tappedRootTask, 0 /* userId */);
        spyOn(mWm.mAtmService);

        mWm.handleTaskFocusChange(tappedTask);
        mWm.handleTaskFocusChange(tappedTask, null /* window */);

        verify(mWm.mAtmService, never()).setFocusedTask(tappedTask.mTaskId);
        verify(mWm.mAtmService, never()).setFocusedTask(tappedTask.mTaskId, null);
    }

    @Test
@@ -151,9 +151,9 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        Task tappedTask = createTaskInRootTask(tappedRootTask, 0 /* userId */);
        spyOn(mWm.mAtmService);

        mWm.handleTaskFocusChange(tappedTask);
        mWm.handleTaskFocusChange(tappedTask, null /* window */);

        verify(mWm.mAtmService).setFocusedTask(tappedTask.mTaskId);
        verify(mWm.mAtmService).setFocusedTask(tappedTask.mTaskId, null);
    }

    @Test