Merge "Fixes the animation and state when docking a task by drag" into oc-dev
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b55bae9..53afe78 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2364,7 +2364,7 @@
     }
 
     void notifyAppTransitionDone() {
-        continueUpdateBounds(HOME_STACK_ID);
+        continueUpdateBounds(RECENTS_STACK_ID);
         for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
             final int taskId = mResizingTasksDuringAnimation.valueAt(i);
             final TaskRecord task =
@@ -5090,73 +5090,79 @@
                     + taskId + " can't be launch in the home/recents stack.");
         }
 
-        if (launchStackId == DOCKED_STACK_ID) {
-            mWindowManager.setDockedStackCreateState(
-                    activityOptions.getDockCreateMode(), null /* initialBounds */);
+        mWindowManager.deferSurfaceLayout();
+        try {
+            if (launchStackId == DOCKED_STACK_ID) {
+                mWindowManager.setDockedStackCreateState(
+                        activityOptions.getDockCreateMode(), null /* initialBounds */);
 
-            // Defer updating the stack in which recents is until the app transition is done, to
-            // not run into issues where we still need to draw the task in recents but the
-            // docked stack is already created.
-            deferUpdateBounds(HOME_STACK_ID);
-            mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
-        }
-
-        task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
-                launchStackId);
-        if (task == null) {
-            continueUpdateBounds(HOME_STACK_ID);
-            mWindowManager.executeAppTransition();
-            throw new IllegalArgumentException(
-                    "startActivityFromRecentsInner: Task " + taskId + " not found.");
-        }
-
-        // Since we don't have an actual source record here, we assume that the currently focused
-        // activity was the source.
-        final ActivityStack focusedStack = getFocusedStack();
-        final ActivityRecord sourceRecord =
-                focusedStack != null ? focusedStack.topActivity() : null;
-
-        if (launchStackId != INVALID_STACK_ID) {
-            if (task.getStackId() != launchStackId) {
-                task.reparent(launchStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
-                        DEFER_RESUME, "startActivityFromRecents");
+                // Defer updating the stack in which recents is until the app transition is done, to
+                // not run into issues where we still need to draw the task in recents but the
+                // docked stack is already created.
+                deferUpdateBounds(RECENTS_STACK_ID);
+                mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
             }
-        }
 
-        // If the user must confirm credentials (e.g. when first launching a work app and the
-        // Work Challenge is present) let startActivityInPackage handle the intercepting.
-        if (!mService.mUserController.shouldConfirmCredentials(task.userId)
-                && task.getRootActivity() != null) {
-            mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
-            mActivityMetricsLogger.notifyActivityLaunching();
-            mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
-            mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
-                    task.getTopActivity());
+            task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
+                    launchStackId);
+            if (task == null) {
+                continueUpdateBounds(RECENTS_STACK_ID);
+                mWindowManager.executeAppTransition();
+                throw new IllegalArgumentException(
+                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
+            }
 
-            // If we are launching the task in the docked stack, put it into resizing mode so
-            // the window renders full-screen with the background filling the void. Also only
-            // call this at the end to make sure that tasks exists on the window manager side.
+            // Since we don't have an actual source record here, we assume that the currently
+            // focused activity was the source.
+            final ActivityStack focusedStack = getFocusedStack();
+            final ActivityRecord sourceRecord =
+                    focusedStack != null ? focusedStack.topActivity() : null;
+
+            if (launchStackId != INVALID_STACK_ID) {
+                if (task.getStackId() != launchStackId) {
+                    task.reparent(launchStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
+                            DEFER_RESUME, "startActivityFromRecents");
+                }
+            }
+
+            // If the user must confirm credentials (e.g. when first launching a work app and the
+            // Work Challenge is present) let startActivityInPackage handle the intercepting.
+            if (!mService.mUserController.shouldConfirmCredentials(task.userId)
+                    && task.getRootActivity() != null) {
+                mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
+                mActivityMetricsLogger.notifyActivityLaunching();
+                mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
+                mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
+                        task.getTopActivity());
+
+                // If we are launching the task in the docked stack, put it into resizing mode so
+                // the window renders full-screen with the background filling the void. Also only
+                // call this at the end to make sure that tasks exists on the window manager side.
+                if (launchStackId == DOCKED_STACK_ID) {
+                    setResizingDuringAnimation(task);
+                }
+
+                mService.mActivityStarter.postStartActivityProcessing(task.getTopActivity(),
+                        ActivityManager.START_TASK_TO_FRONT,
+                        sourceRecord != null
+                                ? sourceRecord.getTask().getStackId() : INVALID_STACK_ID,
+                        sourceRecord, task.getStack());
+                return ActivityManager.START_TASK_TO_FRONT;
+            }
+            callingUid = task.mCallingUid;
+            callingPackage = task.mCallingPackage;
+            intent = task.intent;
+            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
+            userId = task.userId;
+            int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
+                    null, null, 0, 0, bOptions, userId, null, task);
             if (launchStackId == DOCKED_STACK_ID) {
                 setResizingDuringAnimation(task);
             }
-
-            mService.mActivityStarter.postStartActivityProcessing(task.getTopActivity(),
-                    ActivityManager.START_TASK_TO_FRONT,
-                    sourceRecord != null ? sourceRecord.getTask().getStackId() : INVALID_STACK_ID,
-                    sourceRecord, task.getStack());
-            return ActivityManager.START_TASK_TO_FRONT;
+            return result;
+        } finally {
+            mWindowManager.continueSurfaceLayout();
         }
-        callingUid = task.mCallingUid;
-        callingPackage = task.mCallingPackage;
-        intent = task.intent;
-        intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
-        userId = task.userId;
-        int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
-                null, null, 0, 0, bOptions, userId, null, task);
-        if (launchStackId == DOCKED_STACK_ID) {
-            setResizingDuringAnimation(task);
-        }
-        return result;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 6640184..8cfbf68 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -18,6 +18,8 @@
 
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+
+import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
@@ -581,8 +583,12 @@
 
     private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
             boolean allowTaskSnapshot, boolean activityCreated) {
-        if (newTask || !processRunning
-                || (taskSwitch && !activityCreated)) {
+        if (mService.mAppTransition.getAppTransition() == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+            // TODO(b/34099271): Remove this statement to add back the starting window and figure
+            // out why it causes flickering, the starting window appears over the thumbnail while
+            // the docked from recents transition occurs
+            return STARTING_WINDOW_TYPE_NONE;
+        } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
             return STARTING_WINDOW_TYPE_SNAPSHOT;