Merge "Only allow horizontal spring if page will change." into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 7bc656a..95198b8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -20,7 +20,7 @@
 import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
+import static com.android.launcher3.LauncherStateManager.ANIM_ALL_COMPONENTS;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_SCALE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_TRANSLATE;
@@ -220,7 +220,7 @@
                 LauncherStateManager stateManager = mLauncher.getStateManager();
                 return stateManager.createAtomicAnimation(
                         stateManager.getCurrentStableState(), OVERVIEW, builder,
-                        ANIM_ALL, ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW);
+                        ANIM_ALL_COMPONENTS, ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW);
             }
 
             default:
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index b5d8424..65aaf22 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -30,6 +30,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.PropertySetter;
 import com.android.quickstep.views.ClearAllButton;
@@ -64,20 +65,16 @@
             @NonNull AnimatorSetBuilder builder, @NonNull AnimationConfig config) {
         super.setStateWithAnimationInternal(toState, builder, config);
 
-        if (!toState.overviewUi) {
-            builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals);
-        }
-
+        ValueAnimator updateAnim = ValueAnimator.ofFloat(0, 1).setDuration(config.duration);
         if (toState.overviewUi) {
-            ValueAnimator updateAnim = ValueAnimator.ofFloat(0, 1);
-            updateAnim.addUpdateListener(valueAnimator -> {
-                // While animating into recents, update the visible task data as needed
-                mRecentsView.loadVisibleTaskData();
-            });
-            updateAnim.setDuration(config.duration);
-            builder.play(updateAnim);
+            // While animating into recents, update the visible task data as needed
+            updateAnim.addUpdateListener(valueAnimator -> mRecentsView.loadVisibleTaskData());
             mRecentsView.updateEmptyMessage();
+        } else {
+            updateAnim.addListener(
+                    AnimationSuccessListener.forRunnable(mRecentsView::resetTaskVisuals));
         }
+        builder.play(updateAnim);
 
         PropertySetter propertySetter = config.getPropertySetter(builder);
         setAlphas(propertySetter, toState.getVisibleElements(mLauncher));
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index 9cbe11a..b347013 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -21,7 +21,8 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
-import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_PEEK_COMPONENT;
+import static com.android.launcher3.LauncherStateManager.PLAY_ATOMIC_OVERVIEW_PEEK;
+import static com.android.launcher3.LauncherStateManager.SKIP_OVERVIEW;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_HEADER_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
@@ -43,6 +44,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppTransitionManagerImpl;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationFlags;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.Interpolators;
@@ -104,7 +106,7 @@
         LauncherState toState = isPaused ? OVERVIEW_PEEK : NORMAL;
         long peekDuration = isPaused ? PEEK_IN_ANIM_DURATION : PEEK_OUT_ANIM_DURATION;
         mPeekAnim = mLauncher.getStateManager().createAtomicAnimation(fromState, toState,
-                new AnimatorSetBuilder(), ATOMIC_OVERVIEW_PEEK_COMPONENT, peekDuration);
+                new AnimatorSetBuilder(), PLAY_ATOMIC_OVERVIEW_PEEK, peekDuration);
         mPeekAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -210,7 +212,7 @@
                 super.onAnimationEnd(animation);
                 if (mCancelled) {
                     mPeekAnim = mLauncher.getStateManager().createAtomicAnimation(mFromState,
-                            mToState, new AnimatorSetBuilder(), ATOMIC_OVERVIEW_PEEK_COMPONENT,
+                            mToState, new AnimatorSetBuilder(), PLAY_ATOMIC_OVERVIEW_PEEK,
                             PEEK_OUT_ANIM_DURATION);
                     mPeekAnim.start();
                 }
@@ -237,11 +239,14 @@
     }
 
     @Override
-    protected void updateAnimatorBuilderOnReinit(AnimatorSetBuilder builder) {
+    @AnimationFlags
+    protected int updateAnimComponentsOnReinit(@AnimationFlags int animComponents) {
         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);
+            return animComponents | SKIP_OVERVIEW;
+        } else {
+            return animComponents;
         }
     }
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 7bae211..7cebabe 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -19,7 +19,7 @@
 import static com.android.launcher3.LauncherState.HINT_STATE;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_PEEK_COMPONENT;
+import static com.android.launcher3.LauncherStateManager.PLAY_ATOMIC_OVERVIEW_PEEK;
 import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
 import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
 import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
@@ -175,7 +175,7 @@
                 long duration = OVERVIEW.getTransitionDuration(mLauncher);
                 AnimatorSet anim = stateManager.createAtomicAnimation(
                         stateManager.getState(), NORMAL, builder,
-                        ATOMIC_OVERVIEW_PEEK_COMPONENT, duration);
+                        PLAY_ATOMIC_OVERVIEW_PEEK, duration);
                 anim.addListener(AnimationSuccessListener.forRunnable(
                         () -> onSwipeInteractionCompleted(NORMAL, Touch.SWIPE)));
                 anim.start();
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 52625dc..81a6d9b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -21,13 +21,13 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.LauncherState.QUICK_SWITCH;
-import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
+import static com.android.launcher3.LauncherStateManager.ANIM_ALL_COMPONENTS;
+import static com.android.launcher3.LauncherStateManager.SKIP_OVERVIEW;
 import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_TRANSLATE;
-import static com.android.launcher3.anim.AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_5;
@@ -55,8 +55,8 @@
 
 import com.android.launcher3.BaseQuickstepLauncher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager;
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.LauncherStateManager.AnimationFlags;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.allapps.AllAppsTransitionController;
@@ -214,7 +214,7 @@
         nonOverviewBuilder.setInterpolator(ANIM_ALL_APPS_FADE, FADE_OUT_INTERPOLATOR);
         nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_TRANSLATE, TRANSLATE_OUT_INTERPOLATOR);
         nonOverviewBuilder.setInterpolator(ANIM_VERTICAL_PROGRESS, TRANSLATE_OUT_INTERPOLATOR);
-        updateNonOverviewAnim(QUICK_SWITCH, nonOverviewBuilder, ANIM_ALL);
+        updateNonOverviewAnim(QUICK_SWITCH, nonOverviewBuilder, ANIM_ALL_COMPONENTS);
         mNonOverviewAnim.dispatchOnStart();
 
         if (mRecentsView.getTaskViewCount() == 0) {
@@ -231,11 +231,10 @@
 
     /** Create state animation to control non-overview components. */
     private void updateNonOverviewAnim(LauncherState toState, AnimatorSetBuilder builder,
-            @LauncherStateManager.AnimationComponents int animComponents) {
-        builder.addFlag(FLAG_DONT_ANIMATE_OVERVIEW);
+            @AnimationFlags int animComponents) {
         long accuracy = (long) (Math.max(mXRange, mYRange) * 2);
         mNonOverviewAnim = mLauncher.getStateManager().createAnimationToNewWorkspace(toState,
-                builder, accuracy, this::clearState, animComponents);
+                builder, accuracy, this::clearState, animComponents | SKIP_OVERVIEW);
     }
 
     private void setupOverviewAnimators() {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index d5b221d..8de1b3a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -17,6 +17,7 @@
 
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.QUICK_SWITCH;
+import static com.android.launcher3.LauncherStateManager.ANIM_ALL_COMPONENTS;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
@@ -39,7 +40,6 @@
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
@@ -112,7 +112,7 @@
         setupInterpolators(animatorSetBuilder);
         long accuracy = (long) (getShiftRange() * 2);
         mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(mToState,
-                animatorSetBuilder, accuracy, this::clearState, LauncherStateManager.ANIM_ALL);
+                animatorSetBuilder, accuracy, this::clearState, ANIM_ALL_COMPONENTS);
         mCurrentAnimation.getAnimationPlayer().addUpdateListener(valueAnimator -> {
             updateFullscreenProgress((Float) valueAnimator.getAnimatedValue());
         });
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 9f19bb3..f390d0f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -79,6 +79,7 @@
     private static final String TAG = "BaseSwipeUpHandler";
     protected static final Rect TEMP_RECT = new Rect();
 
+    public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.7f;
     private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL;
 
     // The distance needed to drag to reach the task size in recents.
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
index ce67457..ea5561b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -21,7 +21,6 @@
 import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
 import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
 import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
-import static com.android.quickstep.LauncherSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
 import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
 import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID;
 import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL;
@@ -97,7 +96,7 @@
 
     private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged);
 
-    private boolean mIsMotionPaused = false;
+    private boolean mOverviewThresholdPassed = false;
 
     private final boolean mInQuickSwitchMode;
     private final boolean mContinuingLastGesture;
@@ -222,10 +221,16 @@
 
     @Override
     public void onMotionPauseChanged(boolean isPaused) {
-        if (!mInQuickSwitchMode) {
-            mIsMotionPaused = isPaused;
+        if (!mInQuickSwitchMode && mDeviceState.isFullyGesturalNavMode()) {
+            updateOverviewThresholdPassed(isPaused);
+        }
+    }
+
+    private void updateOverviewThresholdPassed(boolean passed) {
+        if (passed != mOverviewThresholdPassed) {
+            mOverviewThresholdPassed = passed;
             if (mSwipeUpOverHome) {
-                mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1)
+                mLauncherAlpha.animateToValue(mLauncherAlpha.value, passed ? 0 : 1)
                         .setDuration(150).start();
             }
             performHapticFeedback();
@@ -234,7 +239,7 @@
 
     @Override
     public Intent getLaunchIntent() {
-        if (mInQuickSwitchMode || mSwipeUpOverHome) {
+        if (mInQuickSwitchMode || mSwipeUpOverHome || !mDeviceState.isFullyGesturalNavMode()) {
             return mGestureState.getOverviewIntent();
         } else {
             return mGestureState.getHomeIntent();
@@ -248,6 +253,11 @@
             mRecentsAnimationController.setWindowThresholdCrossed(!mInQuickSwitchMode
                     && (mCurrentShift.value > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD));
         }
+
+        if (!mInQuickSwitchMode && !mDeviceState.isFullyGesturalNavMode()) {
+            updateOverviewThresholdPassed(mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW);
+        }
+
         if (mRecentsAnimationTargets != null) {
             applyTransformUnchecked();
         }
@@ -271,14 +281,25 @@
                     .getDimension(R.dimen.quickstep_fling_threshold_velocity);
             boolean isFling = Math.abs(endVelocity) > flingThreshold;
 
-            if (isFling) {
-                mGestureState.setEndTarget(endVelocity < 0 ? HOME : LAST_TASK);
-            } else if (mIsMotionPaused) {
-                mGestureState.setEndTarget(RECENTS);
+            if (mDeviceState.isFullyGesturalNavMode()) {
+                if (isFling) {
+                    mGestureState.setEndTarget(endVelocity < 0 ? HOME : LAST_TASK);
+                } else if (mOverviewThresholdPassed) {
+                    mGestureState.setEndTarget(RECENTS);
+                } else {
+                    mGestureState.setEndTarget(mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW
+                            ? HOME
+                            : LAST_TASK);
+                }
             } else {
-                mGestureState.setEndTarget(mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW
-                        ? HOME
-                        : LAST_TASK);
+                GestureEndTarget startState = mSwipeUpOverHome ? HOME : LAST_TASK;
+                if (isFling) {
+                    mGestureState.setEndTarget(endVelocity < 0 ? RECENTS : startState);
+                } else {
+                    mGestureState.setEndTarget(mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW
+                            ? RECENTS
+                            : startState);
+                }
             }
         }
         mStateCallback.setStateOnUiThread(STATE_GESTURE_COMPLETED);
@@ -353,7 +374,7 @@
                 mRecentsAnimationController.finish(false, null, false);
                 break;
             case RECENTS: {
-                if (mSwipeUpOverHome) {
+                if (mSwipeUpOverHome || !mDeviceState.isFullyGesturalNavMode()) {
                     mRecentsAnimationController.finish(true, null, true);
                     break;
                 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 0f63336..63ef766 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -616,11 +616,7 @@
 
         if (!mOverviewComponentObserver.isHomeAndOverviewSame()) {
             shouldDefer = previousGestureState.getFinishingRecentsAnimationTaskId() < 0;
-            if (mDeviceState.isFullyGesturalNavMode()) {
-                factory = mFallbackSwipeHandlerFactory;
-            } else {
-                factory = this::determineFallbackTwoButtonSwipeHandler;
-            }
+            factory = mFallbackSwipeHandlerFactory;
         } else {
             shouldDefer = gestureState.getActivityInterface().deferStartingActivity(mDeviceState,
                     event);
@@ -633,23 +629,6 @@
                 mInputMonitorCompat, disableHorizontalSwipe, factory);
     }
 
-    /**
-     * Determines whether to use the LauncherSwipeHandler or FallbackSwipeHandler at runtime.
-     * We need to use the FallbackSwipeHandler to handle quick switch from home, otherwise the
-     * normal LauncherSwipeHandler works.
-     */
-    private BaseSwipeUpHandler determineFallbackTwoButtonSwipeHandler(GestureState gestureState,
-            long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) {
-        boolean runningOverHome = gestureState.getRunningTask() == null
-                || ActivityManagerWrapper.isHomeTask(gestureState.getRunningTask());
-        boolean isQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture;
-        BaseSwipeUpHandler.Factory factory = runningOverHome && isQuickSwitchMode
-                ? mFallbackSwipeHandlerFactory
-                : mLauncherSwipeHandlerFactory;
-        return factory.newHandler(gestureState, touchTimeMs, continuingLastGesture,
-                isLikelyToStartNewTask);
-    }
-
     private InputConsumer createDeviceLockedInputConsumer(GestureState gestureState) {
         if (mDeviceState.isFullyGesturalNavMode() && gestureState.getRunningTask() != null) {
             return new DeviceLockedInputConsumer(this, mDeviceState, mTaskAnimationManager,
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index d2805ed..7e17fbf 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -18,7 +18,8 @@
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
 import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
+import static com.android.launcher3.LauncherStateManager.ANIM_ALL_COMPONENTS;
+import static com.android.launcher3.LauncherStateManager.SKIP_OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 
 import android.animation.Animator;
@@ -32,7 +33,6 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager;
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
@@ -143,11 +143,10 @@
      * Setup workspace with 0 duration to prepare for our staggered animation.
      */
     private void prepareToAnimate(Launcher launcher) {
-        LauncherStateManager stateManager = launcher.getStateManager();
         AnimatorSetBuilder builder = new AnimatorSetBuilder();
         // setRecentsAttachedToAppWindow() will animate recents out.
-        builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW);
-        stateManager.createAtomicAnimation(BACKGROUND_APP, NORMAL, builder, ANIM_ALL, 0);
+        launcher.getStateManager().createAtomicAnimation(
+                BACKGROUND_APP, NORMAL, builder, ANIM_ALL_COMPONENTS | SKIP_OVERVIEW, 0);
         builder.build().start();
 
         // Stop scrolling so that it doesn't interfere with the translation offscreen.
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index f60eaa7..8b0f138 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -37,7 +37,6 @@
 import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
 import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
 
-import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.LayoutTransition;
 import android.animation.LayoutTransition.TransitionListener;
@@ -700,6 +699,21 @@
         return taskViewCount;
     }
 
+    /**
+     * Updates UI for a modal task, including hiding other tasks.
+     */
+    public void updateUiForModalTask(TaskView taskView, boolean isTaskOverlayModal) {
+        int currentIndex = indexOfChild(taskView);
+        TaskView previousTask = getTaskViewAt(currentIndex - 1);
+        TaskView nextTask = getTaskViewAt(currentIndex + 1);
+        if (previousTask != null) {
+            previousTask.setVisibility(isTaskOverlayModal ? View.INVISIBLE : View.VISIBLE);
+        }
+        if (nextTask != null) {
+            nextTask.setVisibility(isTaskOverlayModal ? View.INVISIBLE : View.VISIBLE);
+        }
+    }
+
     protected void onTaskStackUpdated() { }
 
     public void resetTaskVisuals() {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index abc037e..0e1640e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -245,6 +245,13 @@
         return mSnapshotView.getTaskOverlay().isOverlayModal();
     }
 
+    /** Updates UI based on whether the task is modal. */
+    public void updateUiForModalTask() {
+        if (getRecentsView() != null) {
+            getRecentsView().updateUiForModalTask(this, isTaskOverlayModal());
+        }
+    }
+
     public TaskMenuView getMenuView() {
         return mMenuView;
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 9b57fb7..cb9e87a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -20,12 +20,14 @@
 import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
+import static com.android.launcher3.LauncherStateManager.PLAY_ATOMIC_OVERVIEW_PEEK;
+import static com.android.launcher3.LauncherStateManager.PLAY_ATOMIC_OVERVIEW_SCALE;
+import static com.android.launcher3.LauncherStateManager.SKIP_OVERVIEW;
 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.ANIM_OVERVIEW_SCRIM_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATE_X;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATE_Y;
-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;
 import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS;
@@ -86,13 +88,11 @@
     @Override
     public final void setStateWithAnimation(@NonNull final LauncherState toState,
             @NonNull AnimatorSetBuilder builder, @NonNull AnimationConfig config) {
-        boolean playAtomicOverviewComponent = config.playAtomicOverviewScaleComponent()
-                || config.playAtomicOverviewPeekComponent();
-        if (!playAtomicOverviewComponent) {
+        if (!config.hasAnimationComponent(PLAY_ATOMIC_OVERVIEW_PEEK | PLAY_ATOMIC_OVERVIEW_SCALE)) {
             // The entire recents animation is played atomically.
             return;
         }
-        if (builder.hasFlag(FLAG_DONT_ANIMATE_OVERVIEW)) {
+        if (config.hasAnimationComponent(SKIP_OVERVIEW)) {
             return;
         }
         setStateWithAnimationInternal(toState, builder, config);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
index 3cb0088..3d0fc56 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
@@ -9,7 +9,7 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager.AnimationComponents;
+import com.android.launcher3.LauncherStateManager.AnimationFlags;
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
 import com.android.launcher3.touch.SingleAxisSwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -56,7 +56,7 @@
     }
 
     @Override
-    protected float initCurrentAnimation(@AnimationComponents int animComponent) {
+    protected float initCurrentAnimation(@AnimationFlags int animComponent) {
         float range = getShiftRange();
         long maxAccuracy = (long) (2 * range);
         mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(mToState,
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index 95e38e3..a060d64 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -37,7 +37,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager.AnimationComponents;
+import com.android.launcher3.LauncherStateManager.AnimationFlags;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.AnimatorSetBuilder;
@@ -207,7 +207,8 @@
     }
 
     @Override
-    protected float initCurrentAnimation(@AnimationComponents int animComponents) {
+    protected float initCurrentAnimation(@AnimationFlags int animComponents) {
+        animComponents = updateAnimComponentsOnReinit(animComponents);
         float range = getShiftRange();
         long maxAccuracy = (long) (2 * range);
 
@@ -218,7 +219,6 @@
 
         final AnimatorSetBuilder builder = totalShift == 0 ? new AnimatorSetBuilder()
                 : getAnimatorSetBuilderForStates(mFromState, mToState);
-        updateAnimatorBuilderOnReinit(builder);
 
         cancelPendingAnim();
 
@@ -253,7 +253,9 @@
     /**
      * Give subclasses the chance to update the animation when we re-initialize towards a new state.
      */
-    protected void updateAnimatorBuilderOnReinit(AnimatorSetBuilder builder) {
+    @AnimationFlags
+    protected int updateAnimComponentsOnReinit(@AnimationFlags int animComponents) {
+        return animComponents;
     }
 
     private void cancelPendingAnim() {
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 4267f2b..8233cdd 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -88,20 +88,22 @@
     // components may be run atomically - that is, all at once, instead of user-controlled. However,
     // atomic components are not restricted to this purpose; they can be user-controlled alongside
     // non atomic components as well. Note that each gesture model has exactly one atomic component,
-    // ATOMIC_OVERVIEW_SCALE_COMPONENT *or* ATOMIC_OVERVIEW_PEEK_COMPONENT.
+    // PLAY_ATOMIC_OVERVIEW_SCALE *or* PLAY_ATOMIC_OVERVIEW_PEEK.
     @IntDef(flag = true, value = {
-            NON_ATOMIC_COMPONENT,
-            ATOMIC_OVERVIEW_SCALE_COMPONENT,
-            ATOMIC_OVERVIEW_PEEK_COMPONENT,
+            PLAY_NON_ATOMIC,
+            PLAY_ATOMIC_OVERVIEW_SCALE,
+            PLAY_ATOMIC_OVERVIEW_PEEK,
+            SKIP_OVERVIEW,
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface AnimationComponents {}
-    public static final int NON_ATOMIC_COMPONENT = 1 << 0;
-    public static final int ATOMIC_OVERVIEW_SCALE_COMPONENT = 1 << 1;
-    public static final int ATOMIC_OVERVIEW_PEEK_COMPONENT = 1 << 2;
+    public @interface AnimationFlags {}
+    public static final int PLAY_NON_ATOMIC = 1 << 0;
+    public static final int PLAY_ATOMIC_OVERVIEW_SCALE = 1 << 1;
+    public static final int PLAY_ATOMIC_OVERVIEW_PEEK = 1 << 2;
+    public static final int SKIP_OVERVIEW = 1 << 3;
 
-    public static final int ANIM_ALL = NON_ATOMIC_COMPONENT | ATOMIC_OVERVIEW_SCALE_COMPONENT
-            | ATOMIC_OVERVIEW_PEEK_COMPONENT;
+    public static final int ANIM_ALL_COMPONENTS = PLAY_NON_ATOMIC | PLAY_ATOMIC_OVERVIEW_SCALE
+            | PLAY_ATOMIC_OVERVIEW_PEEK;
 
     private final AnimationConfig mConfig = new AnimationConfig();
     private final Handler mUiHandler;
@@ -311,7 +313,7 @@
     }
 
     public AnimatorSet createAtomicAnimation(LauncherState fromState, LauncherState toState,
-            AnimatorSetBuilder builder, @AnimationComponents int atomicComponent, long duration) {
+            AnimatorSetBuilder builder, @AnimationFlags int atomicComponent, long duration) {
         prepareForAtomicAnimation(fromState, toState, builder);
         AnimationConfig config = new AnimationConfig();
         config.animComponents = atomicComponent;
@@ -355,18 +357,18 @@
      */
     public AnimatorPlaybackController createAnimationToNewWorkspace(
             LauncherState state, long duration) {
-        return createAnimationToNewWorkspace(state, duration, LauncherStateManager.ANIM_ALL);
+        return createAnimationToNewWorkspace(state, duration, ANIM_ALL_COMPONENTS);
     }
 
     public AnimatorPlaybackController createAnimationToNewWorkspace(
-            LauncherState state, long duration, @AnimationComponents int animComponents) {
+            LauncherState state, long duration, @AnimationFlags int animComponents) {
         return createAnimationToNewWorkspace(state, new AnimatorSetBuilder(), duration, null,
                 animComponents);
     }
 
     public AnimatorPlaybackController createAnimationToNewWorkspace(LauncherState state,
             AnimatorSetBuilder builder, long duration, Runnable onCancelRunnable,
-            @AnimationComponents int animComponents) {
+            @AnimationFlags int animComponents) {
         mConfig.reset();
         mConfig.userControlled = true;
         mConfig.animComponents = animComponents;
@@ -583,7 +585,7 @@
         public long duration;
         public boolean userControlled;
         public AnimatorPlaybackController playbackController;
-        public @AnimationComponents int animComponents = ANIM_ALL;
+        public @AnimationFlags int animComponents = ANIM_ALL_COMPONENTS;
         private PropertySetter mPropertySetter;
 
         private AnimatorSet mCurrentAnimation;
@@ -597,7 +599,7 @@
         public void reset() {
             duration = 0;
             userControlled = false;
-            animComponents = ANIM_ALL;
+            animComponents = ANIM_ALL_COMPONENTS;
             mPropertySetter = null;
             mTargetState = null;
 
@@ -639,15 +641,18 @@
         }
 
         public boolean playAtomicOverviewScaleComponent() {
-            return (animComponents & ATOMIC_OVERVIEW_SCALE_COMPONENT) != 0;
-        }
-
-        public boolean playAtomicOverviewPeekComponent() {
-            return (animComponents & ATOMIC_OVERVIEW_PEEK_COMPONENT) != 0;
+            return hasAnimationComponent(PLAY_ATOMIC_OVERVIEW_SCALE);
         }
 
         public boolean playNonAtomicComponent() {
-            return (animComponents & NON_ATOMIC_COMPONENT) != 0;
+            return hasAnimationComponent(PLAY_NON_ATOMIC);
+        }
+
+        /**
+         * Returns true if the config and any of the provided component flags
+         */
+        public boolean hasAnimationComponent(@AnimationFlags int a) {
+            return (animComponents & a) != 0;
         }
     }
 
diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
index cd30dea..d814b19 100644
--- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java
+++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
@@ -21,7 +21,6 @@
 import android.view.animation.Interpolator;
 
 import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Utility class for building animator set
@@ -42,36 +41,17 @@
     public static final int ANIM_OVERVIEW_SCRIM_FADE = 11;
     public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions
 
-    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<>();
-    private int mFlags = 0;
 
     public void play(Animator anim) {
         mAnims.add(anim);
     }
 
-    public void addOnFinishRunnable(Runnable onFinishRunnable) {
-        mOnFinishRunnables.add(onFinishRunnable);
-    }
-
     public AnimatorSet build() {
         AnimatorSet anim = new AnimatorSet();
         anim.playTogether(mAnims);
-        if (!mOnFinishRunnables.isEmpty()) {
-            anim.addListener(new AnimationSuccessListener() {
-                @Override
-                public void onAnimationSuccess(Animator animation) {
-                    for (Runnable onFinishRunnable : mOnFinishRunnables) {
-                        onFinishRunnable.run();
-                    }
-                    mOnFinishRunnables.clear();
-                }
-            });
-        }
         return anim;
     }
 
@@ -82,12 +62,4 @@
     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;
-    }
 }
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 1c2acfd..18bc55a 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -240,6 +240,17 @@
      * and align above if there is enough vertical space.
      */
     protected void orientAboutObject() {
+        orientAboutObject(true /* allowAlignLeft */, true /* allowAlignRight */);
+    }
+
+    /**
+     * @see #orientAboutObject()
+     *
+     * @param allowAlignLeft Set to false if we already tried aligning left and didn't have room.
+     * @param allowAlignRight Set to false if we already tried aligning right and didn't have room.
+     * TODO: Can we test this with all permutations of widths/heights and icon locations + RTL?
+     */
+    private void orientAboutObject(boolean allowAlignLeft, boolean allowAlignRight) {
         measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
         int width = getMeasuredWidth();
         int extraVerticalSpace = mArrow.getLayoutParams().height + mArrowOffset
@@ -253,14 +264,8 @@
         // Align left (right in RTL) if there is room.
         int leftAlignedX = mTempRect.left;
         int rightAlignedX = mTempRect.right - width;
-        int x = leftAlignedX;
-        boolean canBeLeftAligned = leftAlignedX + width + insets.left
-                < dragLayer.getRight() - insets.right;
-        boolean canBeRightAligned = rightAlignedX > dragLayer.getLeft() + insets.left;
-        if (!canBeLeftAligned || (mIsRtl && canBeRightAligned)) {
-            x = rightAlignedX;
-        }
-        mIsLeftAligned = x == leftAlignedX;
+        mIsLeftAligned = !mIsRtl ? allowAlignLeft : !allowAlignRight;
+        int x = mIsLeftAligned ? leftAlignedX : rightAlignedX;
 
         // Offset x so that the arrow and shortcut icons are center-aligned with the original icon.
         int iconWidth = mTempRect.width();
@@ -282,6 +287,24 @@
         }
         x += mIsLeftAligned ? xOffset : -xOffset;
 
+        // Check whether we can still align as we originally wanted, now that we've calculated x.
+        if (!allowAlignLeft && !allowAlignRight) {
+            // We've already tried both ways and couldn't make it fit. onLayout() will set the
+            // gravity to CENTER_HORIZONTAL, but continue below to update y.
+        } else {
+            boolean canBeLeftAligned = x + width + insets.left
+                    < dragLayer.getRight() - insets.right;
+            boolean canBeRightAligned = x > dragLayer.getLeft() + insets.left;
+            boolean alignmentStillValid = mIsLeftAligned && canBeLeftAligned
+                    || !mIsLeftAligned && canBeRightAligned;
+            if (!alignmentStillValid) {
+                // Try again, but don't allow this alignment we already know won't work.
+                orientAboutObject(allowAlignLeft && !mIsLeftAligned /* allowAlignLeft */,
+                        allowAlignRight && mIsLeftAligned /* allowAlignRight */);
+                return;
+            }
+        }
+
         // Open above icon if there is room.
         int iconHeight = mTempRect.height();
         int y = mTempRect.top - height;
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 4e98781..c3664c3 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -19,9 +19,9 @@
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
-import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_SCALE_COMPONENT;
-import static com.android.launcher3.LauncherStateManager.NON_ATOMIC_COMPONENT;
+import static com.android.launcher3.LauncherStateManager.ANIM_ALL_COMPONENTS;
+import static com.android.launcher3.LauncherStateManager.PLAY_ATOMIC_OVERVIEW_SCALE;
+import static com.android.launcher3.LauncherStateManager.PLAY_NON_ATOMIC;
 import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
 import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
 import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
@@ -37,7 +37,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager.AnimationComponents;
+import com.android.launcher3.LauncherStateManager.AnimationFlags;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -176,7 +176,7 @@
     protected abstract LauncherState getTargetState(LauncherState fromState,
             boolean isDragTowardPositive);
 
-    protected abstract float initCurrentAnimation(@AnimationComponents int animComponents);
+    protected abstract float initCurrentAnimation(@AnimationFlags int animComponents);
 
     /**
      * Returns the container that the touch started from when leaving NORMAL state.
@@ -201,10 +201,10 @@
             mCurrentAnimation.setOnCancelRunnable(null);
         }
         int animComponents = goingBetweenNormalAndOverview(mFromState, mToState)
-                ? NON_ATOMIC_COMPONENT : ANIM_ALL;
+                ? PLAY_NON_ATOMIC : ANIM_ALL_COMPONENTS;
         mScheduleResumeAtomicComponent = false;
         if (mAtomicAnim != null) {
-            animComponents = NON_ATOMIC_COMPONENT;
+            animComponents = PLAY_NON_ATOMIC;
             // Control the non-atomic components until the atomic animation finishes, then control
             // the atomic components as well.
             mScheduleResumeAtomicComponent = true;
@@ -215,7 +215,7 @@
         }
 
         if (mAtomicComponentsController != null) {
-            animComponents &= ~ATOMIC_OVERVIEW_SCALE_COMPONENT;
+            animComponents &= ~PLAY_ATOMIC_OVERVIEW_SCALE;
         }
         mProgressMultiplier = initCurrentAnimation(animComponents);
         mCurrentAnimation.dispatchOnStart();
@@ -360,7 +360,7 @@
             long duration) {
         AnimatorSetBuilder builder = getAnimatorSetBuilderForStates(fromState, targetState);
         return mLauncher.getStateManager().createAtomicAnimation(fromState, targetState, builder,
-                ATOMIC_OVERVIEW_SCALE_COMPONENT, duration);
+                PLAY_ATOMIC_OVERVIEW_SCALE, duration);
     }
 
     protected AnimatorSetBuilder getAnimatorSetBuilderForStates(LauncherState fromState,
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 31a5d79..8d5f33d 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -23,7 +23,7 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager.AnimationComponents;
+import com.android.launcher3.LauncherStateManager.AnimationFlags;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 
 /**
@@ -76,7 +76,7 @@
     }
 
     @Override
-    protected float initCurrentAnimation(@AnimationComponents int animComponents) {
+    protected float initCurrentAnimation(@AnimationFlags int animComponents) {
         float range = getShiftRange();
         long maxAccuracy = (long) (2 * range);
         mCurrentAnimation = mLauncher.getStateManager()