diff options
author | 2020-05-01 00:00:38 +0000 | |
---|---|---|
committer | 2020-05-01 00:00:38 +0000 | |
commit | 64b88db3d279e63301e150c1cd150f6f60451d65 (patch) | |
tree | 63e8ce672b7adcdd56f74b129be439a0b3c7f265 | |
parent | 28c136e1cb243730b86f94aa8237137d4f6d8ff9 (diff) | |
parent | c5a937ce646136aa910137e702f790261d7b3ac9 (diff) |
Merge "Do not ignore home activity focus change on multi TaskDisplayArea device" into rvc-dev
5 files changed, 138 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c66ff330edbd..e109dede7532 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -280,7 +280,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final DisplayArea.Root mRootDisplayArea = new DisplayArea.Root(mWmService); - private final DisplayAreaPolicy mDisplayAreaPolicy; + @VisibleForTesting + final DisplayAreaPolicy mDisplayAreaPolicy; private WindowState mTmpWindow; private WindowState mTmpWindow2; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 84d749f148fb..33152d5dea43 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7970,17 +7970,24 @@ public class WindowManagerService extends IWindowManager.Stub handleTaskFocusChange(touchedWindow.getTask()); } - private void handleTaskFocusChange(Task task) { + @VisibleForTesting + void handleTaskFocusChange(Task task) { if (task == null) { return; } - final ActivityStack stack = task.getStack(); // We ignore home stack since we don't want home stack to move to front when touched. // Specifically, in freeform we don't want tapping on home to cause the freeform apps to go // behind home. See b/117376413 - if (stack.isActivityTypeHome()) { - return; + if (task.isActivityTypeHome()) { + // Only ignore home stack if the requested focus home Task is in the same + // TaskDisplayArea as the current focus Task. + TaskDisplayArea homeTda = task.getDisplayArea(); + WindowState curFocusedWindow = getFocusedWindow(); + if (curFocusedWindow != null && homeTda != null + && curFocusedWindow.isDescendantOf(homeTda)) { + return; + } } try { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 353c781c15ef..00439f84702d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -23,6 +23,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.TRANSIT_TASK_OPEN; +import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyFloat; @@ -35,6 +36,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.wm.DisplayArea.Type.ANY; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; @@ -839,6 +841,36 @@ public class WindowContainerTests extends WindowTestsBase { verifyWindowContainerApplyAnimation(stack, activity); } + @Test + public void testGetDisplayArea() { + // WindowContainer + final WindowContainer windowContainer = new WindowContainer(mWm); + + assertNull(windowContainer.getDisplayArea()); + + // ActivityStack > WindowContainer + final ActivityStack activityStack = createTaskStackOnDisplay(mDisplayContent); + activityStack.addChild(windowContainer, 0); + activityStack.setParent(null); + + assertNull(windowContainer.getDisplayArea()); + assertNull(activityStack.getDisplayArea()); + + // TaskDisplayArea > ActivityStack > WindowContainer + final TaskDisplayArea taskDisplayArea = new TaskDisplayArea( + mDisplayContent, mWm, "TaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER); + taskDisplayArea.addChild(activityStack, 0); + + assertEquals(taskDisplayArea, windowContainer.getDisplayArea()); + assertEquals(taskDisplayArea, activityStack.getDisplayArea()); + assertEquals(taskDisplayArea, taskDisplayArea.getDisplayArea()); + + // DisplayArea + final DisplayArea displayArea = new DisplayArea(mWm, ANY, "DisplayArea"); + + assertEquals(displayArea, displayArea.getDisplayArea()); + } + private void verifyWindowContainerApplyAnimation(WindowContainer wc, ActivityRecord act) { // Initial remote animation for app transition. final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( 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 79b9ae1b902a..f52905ef6ae9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -16,21 +16,30 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.os.Process.INVALID_UID; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; +import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.pm.PackageManager; import android.os.IBinder; +import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; @@ -40,6 +49,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; +/** + * Build/Install/Run: + * atest WmTests:WindowManagerServiceTests + */ @SmallTest @Presubmit @RunWith(WindowTestRunner.class) @@ -105,4 +118,70 @@ public class WindowManagerServiceTests extends WindowTestsBase { mWm.removeWindowToken(token, mDisplayContent.getDisplayId()); } + + @Test + public void testTaskFocusChange_stackNotHomeType_focusChanges() throws RemoteException { + DisplayContent display = createNewDisplay(); + // Current focused window + ActivityStack focusedStack = createTaskStackOnDisplay( + WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display); + Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */); + WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window"); + mDisplayContent.mCurrentFocus = focusedWindow; + // Tapped task + ActivityStack tappedStack = createTaskStackOnDisplay( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, display); + Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */); + spyOn(mWm.mActivityTaskManager); + + mWm.handleTaskFocusChange(tappedTask); + + verify(mWm.mActivityTaskManager).setFocusedTask(tappedTask.mTaskId); + } + + @Test + public void testTaskFocusChange_stackHomeTypeWithSameTaskDisplayArea_focusDoesNotChange() + throws RemoteException { + DisplayContent display = createNewDisplay(); + // Current focused window + ActivityStack focusedStack = createTaskStackOnDisplay( + WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display); + Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */); + WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window"); + mDisplayContent.mCurrentFocus = focusedWindow; + // Tapped home task + ActivityStack tappedStack = createTaskStackOnDisplay( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, display); + Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */); + spyOn(mWm.mActivityTaskManager); + + mWm.handleTaskFocusChange(tappedTask); + + verify(mWm.mActivityTaskManager, never()).setFocusedTask(tappedTask.mTaskId); + } + + @Test + public void testTaskFocusChange_stackHomeTypeWithDifferentTaskDisplayArea_focusChanges() + throws RemoteException { + DisplayContent display = createNewDisplay(); + TaskDisplayArea secondTda = + new TaskDisplayArea(display, mWm, "Tapped TDA", FEATURE_VENDOR_FIRST); + display.mDisplayAreaPolicy.mRoot.addChild(secondTda, 1); + display.mDisplayAreaPolicy.mTaskDisplayAreas.add(secondTda); + // Current focused window + ActivityStack focusedStack = createTaskStackOnDisplay( + WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display); + Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */); + WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window"); + mDisplayContent.mCurrentFocus = focusedWindow; + // Tapped home task on another task display area + ActivityStack tappedStack = createTaskStackOnTaskDisplayArea( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, secondTda); + Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */); + spyOn(mWm.mActivityTaskManager); + + mWm.handleTaskFocusChange(tappedTask); + + verify(mWm.mActivityTaskManager).setFocusedTask(tappedTask.mTaskId); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 94c204ab0fe0..0eaab527267a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -304,6 +304,20 @@ class WindowTestsBase extends SystemServiceTestsBase { } } + ActivityStack createTaskStackOnTaskDisplayArea( + int windowingMode, int activityType, TaskDisplayArea tda) { + synchronized (mWm.mGlobalLock) { + return new ActivityTestsBase.StackBuilder( + tda.mDisplayContent.mWmService.mAtmService.mRootWindowContainer) + .setTaskDisplayArea(tda) + .setWindowingMode(windowingMode) + .setActivityType(activityType) + .setCreateActivity(false) + .setIntent(new Intent()) + .build(); + } + } + /** Creates a {@link Task} and adds it to the specified {@link ActivityStack}. */ Task createTaskInStack(ActivityStack stack, int userId) { return WindowTestUtils.createTaskInStack(mWm, stack, userId); |