Merge "Synchronize split dismiss timing w/ launcher state transition" into main
diff --git a/quickstep/src/com/android/quickstep/util/AnimUtils.java b/quickstep/src/com/android/quickstep/util/AnimUtils.java
index 8e3d44f..31aca03 100644
--- a/quickstep/src/com/android/quickstep/util/AnimUtils.java
+++ b/quickstep/src/com/android/quickstep/util/AnimUtils.java
@@ -17,18 +17,28 @@
 package com.android.quickstep.util;
 
 import static com.android.app.animation.Interpolators.clampToProgress;
+import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
+import android.animation.AnimatorSet;
+import android.annotation.NonNull;
 import android.os.Bundle;
 import android.os.IRemoteCallback;
 import android.view.animation.Interpolator;
 
+import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.statemanager.BaseState;
+import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.util.RunnableList;
+import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * Utility class containing methods to help manage animations, interpolators, and timings.
  */
 public class AnimUtils {
+    private static final int DURATION_DEFAULT_SPLIT_DISMISS = 350;
+
     /**
      * Fetches device-specific timings for the Overview > Split animation
      * (splitscreen initiated from Overview).
@@ -59,6 +69,33 @@
     }
 
     /**
+     * Synchronizes the timing for the split dismiss animation to the current transition to
+     * NORMAL (launcher home/workspace)
+     */
+    public static void goToNormalStateWithSplitDismissal(@NonNull StateManager stateManager,
+            @NonNull RecentsViewContainer container,
+            @NonNull StatsLogManager.LauncherEvent exitReason,
+            @NonNull SplitAnimationController animationController) {
+        StateAnimationConfig config = new StateAnimationConfig();
+        BaseState startState = stateManager.getState();
+        long duration = startState.getTransitionDuration(container.asContext(),
+                false /*isToState*/);
+        if (duration == 0) {
+            // Case where we're in contextual on workspace (NORMAL), which by default has 0
+            // transition duration
+            duration = DURATION_DEFAULT_SPLIT_DISMISS;
+        }
+        config.duration = duration;
+        AnimatorSet stateAnim = stateManager.createAtomicAnimation(
+                startState, NORMAL, config);
+        AnimatorSet dismissAnim = animationController
+                .createPlaceholderDismissAnim(container, exitReason, duration);
+        stateAnim.play(dismissAnim);
+        stateManager.setCurrentAnimation(stateAnim, NORMAL);
+        stateAnim.start();
+    }
+
+    /**
      * Returns a IRemoteCallback which completes the provided list as a result
      */
     public static IRemoteCallback completeRunnableListCallback(RunnableList list) {
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index e48a7c6..b2d2302 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -54,6 +54,7 @@
 import com.android.quickstep.LauncherActivityInterface;
 import com.android.quickstep.RotationTouchHelper;
 import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.AnimUtils;
 import com.android.quickstep.util.SplitSelectStateController;
 import com.android.systemui.shared.recents.model.Task;
 
@@ -91,10 +92,12 @@
     protected void handleStartHome(boolean animated) {
         StateManager stateManager = getStateManager();
         animated &= stateManager.shouldAnimateStateChange();
-        stateManager.goToState(NORMAL, animated);
-        if (FeatureFlags.enableSplitContextually()) {
-            mSplitSelectStateController.getSplitAnimationController()
-                    .playPlaceholderDismissAnim(mContainer, LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
+        if (mSplitSelectStateController.isSplitSelectActive()) {
+            AnimUtils.goToNormalStateWithSplitDismissal(stateManager, mContainer,
+                    LAUNCHER_SPLIT_SELECTION_EXIT_HOME,
+                    mSplitSelectStateController.getSplitAnimationController());
+        } else {
+            stateManager.goToState(NORMAL, animated);
         }
         AbstractFloatingView.closeAllOpenViews(mContainer, animated);
     }
diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
index 3d994e8..f6393e4 100644
--- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
@@ -16,13 +16,11 @@
 
 package com.android.quickstep.views;
 
-import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_CANCEL_BUTTON;
 import static com.android.settingslib.widget.theme.R.dimen.settingslib_preferred_minimum_touch_target;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
@@ -42,9 +40,8 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.states.StateAnimationConfig;
+import com.android.quickstep.util.AnimUtils;
 import com.android.quickstep.util.SplitSelectStateController;
 
 /**
@@ -57,7 +54,6 @@
 public class SplitInstructionsView extends LinearLayout {
     private static final int BOUNCE_DURATION = 250;
     private static final float BOUNCE_HEIGHT = 20;
-    private static final int DURATION_DEFAULT_SPLIT_DISMISS = 350;
 
     private final RecentsViewContainer mContainer;
     public boolean mIsCurrentlyAnimating = false;
@@ -165,25 +161,11 @@
     private void exitSplitSelection() {
         RecentsView recentsView = mContainer.getOverviewPanel();
         SplitSelectStateController splitSelectController = recentsView.getSplitSelectController();
-
         StateManager stateManager = recentsView.getStateManager();
-        BaseState startState = stateManager.getState();
-        long duration = startState.getTransitionDuration(mContainer.asContext(), false);
-        if (duration == 0) {
-            // Case where we're in contextual on workspace (NORMAL), which by default has 0
-            // transition duration
-            duration = DURATION_DEFAULT_SPLIT_DISMISS;
-        }
-        StateAnimationConfig config = new StateAnimationConfig();
-        config.duration = duration;
-        AnimatorSet stateAnim = stateManager.createAtomicAnimation(
-                startState, NORMAL, config);
-        AnimatorSet dismissAnim = splitSelectController.getSplitAnimationController()
-                .createPlaceholderDismissAnim(mContainer,
-                        LAUNCHER_SPLIT_SELECTION_EXIT_CANCEL_BUTTON, duration);
-        stateAnim.play(dismissAnim);
-        stateManager.setCurrentAnimation(stateAnim, NORMAL);
-        stateAnim.start();
+
+        AnimUtils.goToNormalStateWithSplitDismissal(stateManager, mContainer,
+                LAUNCHER_SPLIT_SELECTION_EXIT_CANCEL_BUTTON,
+                splitSelectController.getSplitAnimationController());
     }
 
     void ensureProperRotation() {