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
This commit is contained in:
Louis Chang
2021-06-25 16:39:39 +08:00
parent 558a160fff
commit 73d277117d
5 changed files with 48 additions and 37 deletions

View File

@@ -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",

View File

@@ -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()");

View File

@@ -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);

View File

@@ -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);
}
/**

View File

@@ -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