diff options
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<DisplayContent.DisplayChildWindowCo return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\""; } + /** Checks if stack with provided id is visible on this display. */ + boolean isStackVisible(int stackId) { + final TaskStack stack = getStackById(stackId); + return (stack != null && stack.isVisible()); + } + /** * @return The docked stack, but only if it is visible, and {@code null} otherwise. */ @@ -2565,9 +2571,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo : requestedPosition >= 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<DisplayContent.DisplayChildWindowCo // So, stack is moved just below the pinned stack. // When we're adding a new stack the target is the current pinned stack position. // When we're positioning an existing stack the target is the position below pinned - // stack, because WindowContainer#positionAt() first removes element and then adds it - // to specified place. + // stack, because WindowContainer#positionAt() first removes element and then adds + // it to specified place. targetPosition = adding ? topChildPosition : topChildPosition - 1; } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 4b680e5da666..824d4606dfe9 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -186,8 +186,18 @@ class Task extends WindowContainer<AppWindowToken> 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 26e36dc7bbbd..96b79a6e19a2 100644 --- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java +++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java @@ -136,8 +136,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 dd5077bb9e45..813d2638ac94 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java @@ -212,6 +212,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, @@ -227,6 +228,12 @@ class WindowTestsBase { int positionInParent() { return getParent().mChildren.indexOf(this); } + + @Override + void onDisplayChanged(DisplayContent dc) { + super.onDisplayChanged(dc); + mOnDisplayChangedCalled = true; + } } /** |