From 7cd7c2d333c1b4f77a5b1a9f08cbaaebb242700c Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Wed, 18 Jan 2017 12:14:37 -0800 Subject: Notify task about display change when moved to new stack Bug: 34176283 Test: android.server.cts.ActivityManagerDisplayTests Test: #testMoveTaskBetweenDisplays Test: bit FrameworksServicesTests:com.android.server.wm.TaskWindowContainerControllerTests Test: bit FrameworksServicesTests:com.android.server.wm.TaskStackContainersTests Change-Id: If085246926790089e014a94093d788805e812489 --- .../java/com/android/server/wm/DisplayContent.java | 14 +++++---- services/core/java/com/android/server/wm/Task.java | 10 +++++++ .../server/wm/TaskWindowContainerController.java | 2 -- .../server/wm/TaskStackContainersTests.java | 31 ++++++++++++++++++++ .../wm/TaskWindowContainerControllerTests.java | 34 ++++++++++++++++++++++ .../src/com/android/server/wm/WindowTestsBase.java | 7 +++++ 6 files changed, 91 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 47003fa8c8de..592eaec7f31d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1437,6 +1437,12 @@ class DisplayContent extends WindowContainer= topChildPosition; int targetPosition = requestedPosition; - if (toTop - && mService.isStackVisibleLocked(PINNED_STACK_ID) - && stack.mStackId != PINNED_STACK_ID) { + if (toTop && isStackVisible(PINNED_STACK_ID) && stack.mStackId != PINNED_STACK_ID) { // The pinned stack is always the top most stack (always-on-top) when it is visible. TaskStack topStack = mChildren.get(topChildPosition); if (topStack.mStackId != PINNED_STACK_ID) { @@ -2577,8 +2581,8 @@ class DisplayContent extends WindowContainer implements DimLayer.DimLayerU if (DEBUG_STACK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId + " from stack=" + mStack); EventLog.writeEvent(WM_TASK_REMOVED, mTaskId, "reParentTask"); + final DisplayContent prevDisplayContent = getDisplayContent(); + getParent().removeChild(this); stack.addTask(this, position, showForAllUsers(), false /* moveParents */); + + // Relayout display(s). + final DisplayContent displayContent = stack.getDisplayContent(); + displayContent.setLayoutNeeded(); + if (prevDisplayContent != displayContent) { + onDisplayChanged(displayContent); + prevDisplayContent.setLayoutNeeded(); + } } /** @see com.android.server.am.ActivityManagerService#positionTaskInStack(int, int, int). */ diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java index bbc9ed2ef332..885eb500cdb2 100644 --- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java +++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java @@ -117,8 +117,6 @@ public class TaskWindowContainerController throw new IllegalArgumentException("reparent: could not find stackId=" + stackId); } mContainer.reparent(stack, position); - final DisplayContent displayContent = stack.getDisplayContent(); - displayContent.setLayoutNeeded(); mService.mWindowPlacerLocked.performSurfacePlacement(); } } diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java index 24893a142b20..bb9bc9eef97a 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java @@ -17,13 +17,17 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; +import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import org.junit.Test; import org.junit.runner.RunWith; +import android.hardware.display.DisplayManagerGlobal; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.view.Display; +import android.view.DisplayInfo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -88,6 +92,33 @@ public class TaskStackContainersTests extends WindowTestsBase { assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), pinnedStack); } + @Test + public void testReparentBetweenDisplays() throws Exception { + // Create first stack on primary display. + final TaskStack stack1 = createTaskStackOnDisplay(sDisplayContent); + final TestTaskWindowContainerController taskController = + new TestTaskWindowContainerController(stack1.mStackId); + final TestTask task1 = (TestTask) taskController.mContainer; + task1.mOnDisplayChangedCalled = false; + + // Create second display and put second stack on it. + final Display display = new Display(DisplayManagerGlobal.getInstance(), + sDisplayContent.getDisplayId() + 1, new DisplayInfo(), + DEFAULT_DISPLAY_ADJUSTMENTS); + final DisplayContent dc = new DisplayContent(display, sWm, sLayersController, + new WallpaperController(sWm)); + sWm.mRoot.addChild(dc, 1); + final TaskStack stack2 = createTaskStackOnDisplay(dc); + + // Reparent and check state.DisplayContent.java:2572 + sWm.moveStackToDisplay(stack1.mStackId, dc.getDisplayId()); + assertEquals(dc, stack1.getDisplayContent()); + final int stack1PositionInParent = stack1.getParent().mChildren.indexOf(stack1); + final int stack2PositionInParent = stack1.getParent().mChildren.indexOf(stack2); + assertEquals(stack1PositionInParent, stack2PositionInParent + 1); + assertTrue(task1.mOnDisplayChangedCalled); + } + private TaskStack addPinnedStack() { TaskStack pinnedStack = sWm.mStackIdToStack.get(PINNED_STACK_ID); if (pinnedStack == null) { diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java index f84bf607204b..7cd3f648d8b1 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java @@ -16,11 +16,16 @@ package com.android.server.wm; +import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; + import org.junit.Test; +import android.hardware.display.DisplayManagerGlobal; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.view.Display; +import android.view.DisplayInfo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -106,4 +111,33 @@ public class TaskWindowContainerControllerTests extends WindowTestsBase { assertEquals(0, ((TestTask) taskController.mContainer).positionInParent()); assertEquals(1, ((TestTask) taskController2.mContainer).positionInParent()); } + + @Test + public void testReparentBetweenDisplays() throws Exception { + // Create first stack on primary display. + final TaskStack stack1 = createTaskStackOnDisplay(sDisplayContent); + final TestTaskWindowContainerController taskController = + new TestTaskWindowContainerController(stack1.mStackId); + final TestTask task1 = (TestTask) taskController.mContainer; + task1.mOnDisplayChangedCalled = false; + + // Create second display and put second stack on it. + final Display display = new Display(DisplayManagerGlobal.getInstance(), + sDisplayContent.getDisplayId() + 1, new DisplayInfo(), + DEFAULT_DISPLAY_ADJUSTMENTS); + final DisplayContent dc = new DisplayContent(display, sWm, sLayersController, + new WallpaperController(sWm)); + sWm.mRoot.addChild(dc, 1); + final TaskStack stack2 = createTaskStackOnDisplay(dc); + final TestTaskWindowContainerController taskController2 = + new TestTaskWindowContainerController(stack2.mStackId); + final TestTask task2 = (TestTask) taskController2.mContainer; + + // Reparent and check state + taskController.reparent(stack2.mStackId, 0); + assertEquals(stack2, task1.getParent()); + assertEquals(0, task1.positionInParent()); + assertEquals(1, task2.positionInParent()); + assertTrue(task1.mOnDisplayChangedCalled); + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java index 44d5055d5eb6..5a5b31753e22 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java @@ -210,6 +210,7 @@ class WindowTestsBase { class TestTask extends Task { boolean mShouldDeferRemoval = false; + boolean mOnDisplayChangedCalled = false; TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds, Configuration overrideConfig, boolean isOnTopLauncher, int resizeMode, @@ -225,6 +226,12 @@ class WindowTestsBase { int positionInParent() { return getParent().mChildren.indexOf(this); } + + @Override + void onDisplayChanged(DisplayContent dc) { + super.onDisplayChanged(dc); + mOnDisplayChangedCalled = true; + } } /** -- cgit v1.2.3-59-g8ed1b