From 73d277117d301ca4b5f75eb9bec56ebc36f764f2 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Fri, 25 Jun 2021 16:39:39 +0800 Subject: [PATCH] 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 --- data/etc/services.core.protolog.json | 24 +++--------- .../server/wm/ActivityTaskManagerService.java | 37 ++++++++++++++----- .../com/android/server/wm/DisplayContent.java | 6 +++ .../server/wm/WindowManagerService.java | 6 +-- .../server/wm/WindowManagerServiceTests.java | 12 +++--- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index bfd12f8d76bc9..89f8a29e32808 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -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", diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index d45cd06acfcd1..c77e7fcb846d3 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -1875,25 +1875,42 @@ 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); - if (task == null) { - return; - } - final ActivityRecord r = task.topRunningActivityLocked(); - if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) { - mRootWindowContainer.resumeFocusedTasksTopActivities(); - } + 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) { + return; + } + + 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 */); + } + } + @Override public boolean removeTask(int taskId) { mAmInternal.enforceCallingPermission(REMOVE_TASKS, "removeTask()"); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 8da5f08386c08..736ed0b5d7518 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -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); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f57b7b8ef0f05..0a886228713fc 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -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); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index d9aa871447be5..83cdc3ba3ebd8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -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