Loading services/core/java/com/android/server/wm/DisplayContent.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading services/core/java/com/android/server/wm/WindowManagerService.java +11 −4 Original line number Diff line number Diff line Loading @@ -7970,18 +7970,25 @@ 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()) { 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 { mActivityTaskManager.setFocusedTask(task.mTaskId); Loading services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +32 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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( Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +79 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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) Loading Loading @@ -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); } } services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +14 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
services/core/java/com/android/server/wm/WindowManagerService.java +11 −4 Original line number Diff line number Diff line Loading @@ -7970,18 +7970,25 @@ 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()) { 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 { mActivityTaskManager.setFocusedTask(task.mTaskId); Loading
services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +32 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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( Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +79 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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) Loading Loading @@ -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); } }
services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +14 −0 Original line number Diff line number Diff line Loading @@ -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); Loading