Add FLAG_DONT_ANIMATE_OVERVIEW to AnimatorSetBuilder

This allows us to specify when a second animation will handle the overview
animation, so it doesn't conflict with existing state transitions.

Bug: 125362112
Change-Id: I497c02924862bfba558c107bee3c88a9f40ec0f1
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java
index a41362f..a9c8f0d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java
@@ -46,7 +46,7 @@
 
         super.onDragStart(start);
 
-        if (mStartState == NORMAL) {
+        if (handlingOverviewAnim()) {
             mMotionPauseDetector.setOnMotionPauseListener(isPaused -> {
                 RecentsView recentsView = mLauncher.getOverviewPanel();
                 recentsView.setOverviewStateEnabled(isPaused);
@@ -55,6 +55,14 @@
         }
     }
 
+    /**
+     * @return Whether we are handling the overview animation, rather than
+     * having it as part of the existing animation to the target state.
+     */
+    private boolean handlingOverviewAnim() {
+        return mStartState == NORMAL;
+    }
+
     @Override
     public boolean onDrag(float displacement) {
         mMotionPauseDetector.addPosition(displacement, 0);
@@ -63,7 +71,7 @@
 
     @Override
     public void onDragEnd(float velocity, boolean fling) {
-        if (mMotionPauseDetector.isPaused() && mStartState == NORMAL) {
+        if (mMotionPauseDetector.isPaused() && handlingOverviewAnim()) {
             float range = getShiftRange();
             long maxAccuracy = (long) (2 * range);
 
@@ -93,4 +101,13 @@
         }
         mMotionPauseDetector.clear();
     }
+
+    @Override
+    protected void updateAnimatorBuilderOnReinit(AnimatorSetBuilder builder) {
+        if (handlingOverviewAnim()) {
+            // We don't want the state transition to all apps to animate overview,
+            // as that will cause a jump after our atomic animation.
+            builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW);
+        }
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index e74d84d..50e59af 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -19,6 +19,7 @@
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 
@@ -66,6 +67,9 @@
             // The entire recents animation is played atomically.
             return;
         }
+        if (builder.hasFlag(FLAG_DONT_ANIMATE_OVERVIEW)) {
+            return;
+        }
         setStateWithAnimationInternal(toState, builder, config);
     }
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index d20ffbb..62e525c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -195,6 +195,7 @@
 
         final AnimatorSetBuilder builder = totalShift == 0 ? new AnimatorSetBuilder()
                 : getAnimatorSetBuilderForStates(mFromState, mToState);
+        updateAnimatorBuilderOnReinit(builder);
 
         cancelPendingAnim();
 
@@ -228,6 +229,12 @@
         return 1 / totalShift;
     }
 
+    /**
+     * Give subclasses the chance to update the animation when we re-initialize towards a new state.
+     */
+    protected void updateAnimatorBuilderOnReinit(AnimatorSetBuilder builder) {
+    }
+
     private void cancelPendingAnim() {
         if (mPendingAnimation != null) {
             mPendingAnimation.finish(false, Touch.SWIPE);
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index f6b54f2..97c8f51 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -373,7 +373,6 @@
             AnimatorSetBuilder builder, final Runnable onCompleteRunnable) {
 
         for (StateHandler handler : getStateHandlers()) {
-            builder.startTag(handler);
             handler.setStateWithAnimation(state, builder, mConfig);
         }
 
diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
index fdac5c8..e135c0d 100644
--- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java
+++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
@@ -35,15 +35,13 @@
     public static final int ANIM_OVERVIEW_FADE = 4;
     public static final int ANIM_ALL_APPS_FADE = 5;
 
+    public static final int FLAG_DONT_ANIMATE_OVERVIEW = 1 << 0;
+
     protected final ArrayList<Animator> mAnims = new ArrayList<>();
 
     private final SparseArray<Interpolator> mInterpolators = new SparseArray<>();
     private List<Runnable> mOnFinishRunnables = new ArrayList<>();
-
-    /**
-     * Associates a tag with all the animations added after this call.
-     */
-    public void startTag(Object obj) { }
+    private int mFlags = 0;
 
     public void play(Animator anim) {
         mAnims.add(anim);
@@ -77,4 +75,12 @@
     public void setInterpolator(int animId, Interpolator interpolator) {
         mInterpolators.put(animId, interpolator);
     }
+
+    public void addFlag(int flag) {
+        mFlags |= flag;
+    }
+
+    public boolean hasFlag(int flag) {
+        return (mFlags & flag) != 0;
+    }
 }