From c5a937ce646136aa910137e702f790261d7b3ac9 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Wed, 29 Apr 2020 23:43:52 -0700 Subject: [PATCH] Do not ignore home activity focus change on multi TaskDisplayArea device Before, tapping home search didn't bring up IME because of no focus. Now, it will focus home if it is on a different TDA. Fix: 155000370 Test: manual: verify on a dual TDA device Test: atest WmTests:WindowContainerTests Test: atest WmTests:WindowManagerServiceTests Change-Id: I9c6e815e62ad6f82d6d6b5fbbd361437b40d5e89 --- .../com/android/server/wm/DisplayContent.java | 3 +- .../server/wm/WindowManagerService.java | 15 +++- .../server/wm/WindowContainerTests.java | 32 ++++++++ .../server/wm/WindowManagerServiceTests.java | 79 +++++++++++++++++++ .../android/server/wm/WindowTestsBase.java | 14 ++++ 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 c66ff330edbdf..e109dede7532e 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 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 79b9ae1b902a3..f52905ef6ae9b 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 94c204ab0fe05..0eaab527267a7 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);