Move stack to front in-sync with task reparenting

When reparenting a task to another stack have window manager move the
destination stack to the front at the same time it is reparenting the
task if REPARENT_MOVE_STACK_TO_FRONT is set to avoid jank.

Test: manual
Bug: 37299899
Change-Id: I45678e742188a4871f93a11178f7ab2b60c7bcc3
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index c7f20b9f..f8a4d4b 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -658,7 +658,8 @@
 
             // Must reparent first in window manager to avoid a situation where AM can delete the
             // we are coming from in WM before we reparent because it became empty.
-            mWindowContainerController.reparent(toStack.getWindowContainerController(), position);
+            mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
+                    moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
 
             // Move the task
             sourceStack.removeTask(this, reason, REMOVE_TASK_MODE_MOVING);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 5c46ca9..4262d12 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -184,7 +184,7 @@
         super.removeImmediately();
     }
 
-    void reparent(TaskStack stack, int position) {
+    void reparent(TaskStack stack, int position, boolean moveParents) {
         if (stack == mStack) {
             throw new IllegalArgumentException(
                     "task=" + this + " already child of stack=" + mStack);
@@ -195,7 +195,7 @@
         final DisplayContent prevDisplayContent = getDisplayContent();
 
         getParent().removeChild(this);
-        stack.addTask(this, position, showForAllUsers(), false /* moveParents */);
+        stack.addTask(this, position, showForAllUsers(), moveParents);
 
         // Relayout display(s).
         final DisplayContent displayContent = stack.getDisplayContent();
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index efc2e11..9f02485 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -121,7 +121,7 @@
         }
     }
 
-    public void reparent(StackWindowController stackController, int position) {
+    public void reparent(StackWindowController stackController, int position, boolean moveParents) {
         synchronized (mWindowMap) {
             if (DEBUG_STACK) Slog.i(TAG_WM, "reparent: moving taskId=" + mTaskId
                     + " to stack=" + stackController + " at " + position);
@@ -135,7 +135,7 @@
                 throw new IllegalArgumentException("reparent: could not find stack="
                         + stackController);
             }
-            mContainer.reparent(stack, position);
+            mContainer.reparent(stack, position, moveParents);
             mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
         }
     }
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 1819c56..98d20a2 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
@@ -89,7 +89,7 @@
 
         boolean gotException = false;
         try {
-            taskController.reparent(stackController1, 0);
+            taskController.reparent(stackController1, 0, false/* moveParents */);
         } catch (IllegalArgumentException e) {
             gotException = true;
         }
@@ -100,14 +100,14 @@
         stackController3.setContainer(null);
         gotException = false;
         try {
-            taskController.reparent(stackController3, 0);
+            taskController.reparent(stackController3, 0, false/* moveParents */);
         } catch (IllegalArgumentException e) {
             gotException = true;
         }
         assertTrue("Should not be able to reparent to a stack that doesn't have a container",
                 gotException);
 
-        taskController.reparent(stackController2, 0);
+        taskController.reparent(stackController2, 0, false/* moveParents */);
         assertEquals(stackController2.mContainer, taskController.mContainer.getParent());
         assertEquals(0, ((WindowTestUtils.TestTask) taskController.mContainer).positionInParent());
         assertEquals(1, ((WindowTestUtils.TestTask) taskController2.mContainer).positionInParent());
@@ -135,7 +135,7 @@
                 (WindowTestUtils.TestTask) taskController2.mContainer;
 
         // Reparent and check state
-        taskController.reparent(stack2Controller, 0);
+        taskController.reparent(stack2Controller, 0, false /* moveParents */);
         assertEquals(stack2, task1.getParent());
         assertEquals(0, task1.positionInParent());
         assertEquals(1, task2.positionInParent());