Cleaning up some animation states:

> When running one-off animations during quickstep, cancelling prevoisly
  running animations.
> Cancelling such one-off animations when state is reset
> Preventing touch proxied from recent transition to affect quickswitch
  (by affecting pagedView)

Bug: 135686388
Bug: 135571566
Change-Id: Id647015a583761d8fd46a02e3e2d88027e282a79
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 eac4dce..371161e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -16,25 +16,32 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
 import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
 import static com.android.quickstep.TaskViewUtils.getRecentsWindowAnimator;
 
+import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_PIXELS;
+import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY;
+import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_MEDIUM;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
-import android.app.ActivityOptions;
 import android.content.Context;
 import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.anim.SpringObjectAnimator;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
@@ -46,11 +53,12 @@
  */
 public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransitionManagerImpl {
 
-    private RecentsView mRecentsView;
+    public static final int INDEX_SHELF_ANIM = 0;
+    public static final int INDEX_RECENTS_FADE_ANIM = 1;
+    public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = 2;
 
     public LauncherAppTransitionManagerImpl(Context context) {
         super(context);
-        mRecentsView = mLauncher.getOverviewPanel();
     }
 
     @Override
@@ -133,4 +141,25 @@
             mLauncher.getStateManager().reapplyState();
         };
     }
+
+    @Override
+    public int getStateElementAnimationsCount() {
+        return 3;
+    }
+
+    @Override
+    public Animator createStateElementAnimation(int index, float... values) {
+        switch (index) {
+            case INDEX_SHELF_ANIM:
+                return mLauncher.getAllAppsController().createSpringAnimation(values);
+            case INDEX_RECENTS_FADE_ANIM:
+                return ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(),
+                        RecentsView.CONTENT_ALPHA, values);
+            case INDEX_RECENTS_TRANSLATE_X_ANIM:
+                return new SpringObjectAnimator<>(mLauncher.getOverviewPanel(),
+                        VIEW_TRANSLATE_X, MIN_VISIBLE_CHANGE_PIXELS, 0.8f, 250, values);
+            default:
+                return super.createStateElementAnimation(index, values);
+        }
+    }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 755d978..07c0496 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -16,14 +16,15 @@
 package com.android.quickstep;
 
 import static android.view.View.TRANSLATION_Y;
+
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_FADE_ANIM;
+import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_TRANSLATE_X_ANIM;
+import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_SHELF_ANIM;
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
 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.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
-import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_DAMPING_RATIO;
-import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS;
 import static com.android.launcher3.anim.Interpolators.ACCEL_2;
 import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
 import static com.android.launcher3.anim.Interpolators.INSTANT;
@@ -31,7 +32,6 @@
 import static com.android.quickstep.WindowTransformSwipeHandler.RECENTS_ATTACH_DURATION;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
@@ -48,8 +48,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
-import androidx.dynamicanimation.animation.SpringAnimation;
-import androidx.dynamicanimation.animation.SpringForce;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
@@ -60,7 +58,6 @@
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.AnimatorSetBuilder;
-import com.android.launcher3.anim.SpringObjectAnimator;
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.uioverrides.states.OverviewState;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -68,6 +65,7 @@
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.util.StaggeredWorkspaceAnim;
+import com.android.quickstep.views.LauncherRecentsView;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -217,10 +215,7 @@
         activity.getAppsView().getContentView().setVisibility(View.GONE);
 
         return new AnimationFactory() {
-            private Animator mShelfAnim;
             private ShelfAnimState mShelfState;
-            private Animator mAttachToWindowFadeAnim;
-            private SpringAnimation mAttachToWindowTranslationXAnim;
             private boolean mIsAttachedToWindow;
 
             @Override
@@ -253,9 +248,7 @@
                     return;
                 }
                 mShelfState = shelfState;
-                if (mShelfAnim != null) {
-                    mShelfAnim.cancel();
-                }
+                activity.getStateManager().cancelStateElementAnimation(INDEX_SHELF_ANIM);
                 if (mShelfState == ShelfAnimState.CANCEL) {
                     return;
                 }
@@ -271,16 +264,10 @@
                         : mShelfState == ShelfAnimState.PEEK
                                 ? shelfPeekingProgress
                                 : shelfOverviewProgress;
-                mShelfAnim = createShelfAnim(activity, toProgress);
-                mShelfAnim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        mShelfAnim = null;
-                    }
-                });
-                mShelfAnim.setInterpolator(interpolator);
-                mShelfAnim.setDuration(duration);
-                mShelfAnim.start();
+                Animator shelfAnim = activity.getStateManager()
+                        .createStateElementAnimation(INDEX_SHELF_ANIM, toProgress);
+                shelfAnim.setInterpolator(interpolator);
+                shelfAnim.setDuration(duration).start();
             }
 
             @Override
@@ -289,12 +276,10 @@
                     return;
                 }
                 mIsAttachedToWindow = attached;
-                if (mAttachToWindowFadeAnim != null) {
-                    mAttachToWindowFadeAnim.cancel();
-                }
-                RecentsView recentsView = activity.getOverviewPanel();
-                mAttachToWindowFadeAnim = ObjectAnimator.ofFloat(recentsView,
-                        RecentsView.CONTENT_ALPHA, attached ? 1 : 0);
+                LauncherRecentsView recentsView = activity.getOverviewPanel();
+                Animator fadeAnim = activity.getStateManager()
+                        .createStateElementAnimation(
+                        INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0);
 
                 int runningTaskIndex = recentsView.getRunningTaskIndex();
                 if (runningTaskIndex == 0) {
@@ -316,33 +301,28 @@
 
                     float fromTranslationX = attached ? offscreenX - scrollOffsetX : 0;
                     float toTranslationX = attached ? 0 : offscreenX - scrollOffsetX;
-                    if (mAttachToWindowTranslationXAnim == null) {
-                        mAttachToWindowTranslationXAnim = new SpringAnimation(recentsView,
-                                SpringAnimation.TRANSLATION_X).setSpring(new SpringForce()
-                                .setDampingRatio(0.8f)
-                                .setStiffness(250));
-                    }
+                    activity.getStateManager()
+                            .cancelStateElementAnimation(INDEX_RECENTS_TRANSLATE_X_ANIM);
+
                     if (!recentsView.isShown() && animate) {
                         recentsView.setTranslationX(fromTranslationX);
-                        mAttachToWindowTranslationXAnim.setStartValue(fromTranslationX);
-                    }
-                    mAttachToWindowTranslationXAnim.animateToFinalPosition(toTranslationX);
-                    if (!animate && mAttachToWindowTranslationXAnim.canSkipToEnd()) {
-                        mAttachToWindowTranslationXAnim.skipToEnd();
+                    } else {
+                        fromTranslationX = recentsView.getTranslationX();
                     }
 
-                    mAttachToWindowFadeAnim.setInterpolator(attached ? INSTANT : ACCEL_2);
-                } else {
-                    mAttachToWindowFadeAnim.setInterpolator(ACCEL_DEACCEL);
-                }
-                mAttachToWindowFadeAnim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        mAttachToWindowFadeAnim = null;
+                    if (!animate) {
+                        recentsView.setTranslationX(toTranslationX);
+                    } else {
+                        activity.getStateManager().createStateElementAnimation(
+                                INDEX_RECENTS_TRANSLATE_X_ANIM,
+                                fromTranslationX, toTranslationX).start();
                     }
-                });
-                mAttachToWindowFadeAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0);
-                mAttachToWindowFadeAnim.start();
+
+                    fadeAnim.setInterpolator(attached ? INSTANT : ACCEL_2);
+                } else {
+                    fadeAnim.setInterpolator(ACCEL_DEACCEL);
+                }
+                fadeAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0).start();
             }
         };
     }
@@ -358,10 +338,10 @@
         if (!activity.getDeviceProfile().isVerticalBarLayout()
                 && SysUINavigationMode.getMode(activity) != Mode.NO_BUTTON) {
             // Don't animate the shelf when the mode is NO_BUTTON, because we update it atomically.
-            Animator shiftAnim = createShelfAnim(activity,
+            anim.play(activity.getStateManager().createStateElementAnimation(
+                    INDEX_SHELF_ANIM,
                     fromState.getVerticalProgress(activity),
-                    endState.getVerticalProgress(activity));
-            anim.play(shiftAnim);
+                    endState.getVerticalProgress(activity)));
         }
         playScaleDownAnim(anim, activity, fromState, endState);
 
@@ -379,13 +359,6 @@
         callback.accept(controller);
     }
 
-    private Animator createShelfAnim(Launcher activity, float ... progressValues) {
-        Animator shiftAnim = new SpringObjectAnimator<>(activity.getAllAppsController(),
-                ALL_APPS_PROGRESS, activity.getAllAppsController().getShiftRange(),
-                SPRING_DAMPING_RATIO, SPRING_STIFFNESS, progressValues);
-        return shiftAnim;
-    }
-
     /**
      * Scale down recents from the center task being full screen to being in overview.
      */
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
index 5eecf17..ddd28a3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -19,6 +19,8 @@
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_UP;
 
+import static com.android.launcher3.Utilities.FLAG_NO_GESTURES;
+
 import android.view.InputEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -182,7 +184,10 @@
             }
         }
         if (mInputConsumer != null) {
+            int flags = ev.getEdgeFlags();
+            ev.setEdgeFlags(flags | FLAG_NO_GESTURES);
             mInputConsumer.onMotionEvent(ev);
+            ev.setEdgeFlags(flags);
         }
 
         return true;
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 06a8e2e..a98df0f 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
@@ -16,6 +16,8 @@
 
 package com.android.quickstep.views;
 
+import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_PIXELS;
+
 import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
 import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
@@ -125,10 +127,6 @@
 
     private static final String TAG = RecentsView.class.getSimpleName();
 
-    public static final float SPRING_MIN_VISIBLE_CHANGE = 0.001f;
-    public static final float SPRING_DAMPING_RATIO = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY;
-    public static final float SPRING_STIFFNESS = SpringForce.STIFFNESS_MEDIUM;
-
     public static final FloatProperty<RecentsView> CONTENT_ALPHA =
             new FloatProperty<RecentsView>("contentAlpha") {
                 @Override
@@ -1033,7 +1031,8 @@
         addAnim(ObjectAnimator.ofFloat(taskView, ALPHA, 0), duration, ACCEL_2, anim);
         if (QUICKSTEP_SPRINGS.get() && taskView instanceof TaskView)
             addAnim(new SpringObjectAnimator<>(taskView, VIEW_TRANSLATE_Y,
-                            SPRING_MIN_VISIBLE_CHANGE, SPRING_DAMPING_RATIO, SPRING_STIFFNESS,
+                            MIN_VISIBLE_CHANGE_PIXELS, SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY,
+                            SpringForce.STIFFNESS_MEDIUM,
                             0, -taskView.getHeight()),
                     duration, LINEAR, anim);
         else {
@@ -1111,7 +1110,8 @@
                 if (scrollDiff != 0) {
                     if (QUICKSTEP_SPRINGS.get() && child instanceof TaskView) {
                         addAnim(new SpringObjectAnimator<>(child, VIEW_TRANSLATE_X,
-                                SPRING_MIN_VISIBLE_CHANGE, SPRING_DAMPING_RATIO, SPRING_STIFFNESS,
+                                MIN_VISIBLE_CHANGE_PIXELS, SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY,
+                                SpringForce.STIFFNESS_MEDIUM,
                                 0, scrollDiff), duration, ACCEL, anim);
                     } else {
                         addAnim(ObjectAnimator.ofFloat(child, TRANSLATION_X, scrollDiff), duration,
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
index 4bddc6a..c55c120 100644
--- a/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -17,6 +17,7 @@
 package com.android.launcher3;
 
 
+import android.animation.Animator;
 import android.app.ActivityOptions;
 import android.content.Context;
 import android.graphics.Rect;
@@ -55,4 +56,15 @@
     public boolean supportsAdaptiveIconAnimation() {
         return false;
     }
+
+    /**
+     * Number of animations which run on state properties.
+     */
+    public int getStateElementAnimationsCount() {
+        return 0;
+    }
+
+    public Animator createStateElementAnimation(int index, float... values) {
+        throw new RuntimeException("Unknown gesture animation " + index);
+    }
 }
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 505918e..2c8c208 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -111,6 +111,9 @@
     private final Launcher mLauncher;
     private final ArrayList<StateListener> mListeners = new ArrayList<>();
 
+    // Animators which are run on properties also controlled by state animations.
+    private Animator[] mStateElementAnimators;
+
     private StateHandler[] mStateHandlers;
     private LauncherState mState = NORMAL;
 
@@ -209,6 +212,7 @@
     public void reapplyState(boolean cancelCurrentAnimation) {
         boolean wasInAnimation = mConfig.mCurrentAnimation != null;
         if (cancelCurrentAnimation) {
+            cancelAllStateElementAnimation();
             cancelAnimation();
         }
         if (mConfig.mCurrentAnimation == null) {
@@ -250,6 +254,7 @@
         mConfig.reset();
 
         if (!animated) {
+            cancelAllStateElementAnimation();
             onStateTransitionStart(state);
             for (StateHandler handler : getStateHandlers()) {
                 handler.setState(state);
@@ -521,6 +526,47 @@
         mConfig.setAnimation(anim, null);
     }
 
+    private void cancelAllStateElementAnimation() {
+        if (mStateElementAnimators == null) {
+            return;
+        }
+
+        for (Animator animator : mStateElementAnimators) {
+            if (animator != null) {
+                animator.cancel();
+            }
+        }
+    }
+
+    /**
+     * Cancels a currently running gesture animation
+     */
+    public void cancelStateElementAnimation(int index) {
+        if (mStateElementAnimators == null) {
+            return;
+        }
+        if (mStateElementAnimators[index] != null) {
+            mStateElementAnimators[index].cancel();
+        }
+    }
+
+    public Animator createStateElementAnimation(int index, float... values) {
+        cancelStateElementAnimation(index);
+        LauncherAppTransitionManager latm = mLauncher.getAppTransitionManager();
+        if (mStateElementAnimators == null) {
+            mStateElementAnimators = new Animator[latm.getStateElementAnimationsCount()];
+        }
+        Animator anim = latm.createStateElementAnimation(index, values);
+        mStateElementAnimators[index] = anim;
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mStateElementAnimators[index] = null;
+            }
+        });
+        return anim;
+    }
+
     private void clearCurrentAnimation() {
         if (mConfig.mCurrentAnimation != null) {
             mConfig.mCurrentAnimation.removeListener(mConfig);
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index dfa3e1b..2eeb132 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.Utilities.shouldDisableGestures;
 import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
 import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
 import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
@@ -844,10 +845,11 @@
          * If we return true, onTouchEvent will be called and we do the actual
          * scrolling there.
          */
-        acquireVelocityTrackerAndAddMovement(ev);
 
         // Skip touch handling if there are no pages to swipe
-        if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev);
+        if (getChildCount() <= 0 || shouldDisableGestures(ev)) return false;
+
+        acquireVelocityTrackerAndAddMovement(ev);
 
         /*
          * Shortcut the most recurring case: the user is in the dragging
@@ -1093,7 +1095,7 @@
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         // Skip touch handling if there are no pages to swipe
-        if (getChildCount() <= 0) return false;
+        if (getChildCount() <= 0 || shouldDisableGestures(ev)) return false;
 
         acquireVelocityTrackerAndAddMovement(ev);
 
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 7bdbb95..65aa3a7 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -128,6 +128,16 @@
     public static final int EDGE_NAV_BAR = 1 << 8;
 
     /**
+     * Set on a motion event do disallow any gestures and only handle touch.
+     * See {@link MotionEvent#setEdgeFlags(int)}.
+     */
+    public static final int FLAG_NO_GESTURES = 1 << 9;
+
+    public static boolean shouldDisableGestures(MotionEvent ev) {
+        return (ev.getEdgeFlags() & FLAG_NO_GESTURES) == FLAG_NO_GESTURES;
+    }
+
+    /**
      * Indicates if the device has a debug build. Should only be used to store additional info or
      * add extra logging and not for changing the app behavior.
      */
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 3289d7d..4683893 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -47,8 +47,8 @@
  */
 public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener {
 
-    public static final float SPRING_DAMPING_RATIO = 0.9f;
-    public static final float SPRING_STIFFNESS = 600f;
+    private static final float SPRING_DAMPING_RATIO = 0.9f;
+    private static final float SPRING_STIFFNESS = 600f;
 
     public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
             new FloatProperty<AllAppsTransitionController>("allAppsProgress") {
@@ -188,8 +188,7 @@
         Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
                 ? builder.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
                 : FAST_OUT_SLOW_IN;
-        Animator anim = new SpringObjectAnimator<>(this, ALL_APPS_PROGRESS, 1f / mShiftRange,
-                SPRING_DAMPING_RATIO, SPRING_STIFFNESS, mProgress, targetProgress);
+        Animator anim = createSpringAnimation(mProgress, targetProgress);
         anim.setDuration(config.duration);
         anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
         anim.addListener(getProgressAnimatorListener());
@@ -199,6 +198,11 @@
         setAlphas(toState, config, builder);
     }
 
+    public Animator createSpringAnimation(float... progressValues) {
+        return new SpringObjectAnimator<>(this, ALL_APPS_PROGRESS, 1f / mShiftRange,
+                SPRING_DAMPING_RATIO, SPRING_STIFFNESS, progressValues);
+    }
+
     private void setAlphas(LauncherState toState, AnimationConfig config,
             AnimatorSetBuilder builder) {
         setAlphas(toState.getVisibleElements(mLauncher), config, builder);
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 51c7022..c1ba780 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -21,6 +21,7 @@
 import static android.view.MotionEvent.ACTION_UP;
 
 import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
+import static com.android.launcher3.Utilities.shouldDisableGestures;
 
 import android.annotation.TargetApi;
 import android.content.Context;
@@ -151,6 +152,8 @@
     }
 
     private TouchController findControllerToHandleTouch(MotionEvent ev) {
+        if (shouldDisableGestures(ev)) return null;
+
         AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
         if (topView != null && topView.onControllerInterceptTouchEvent(ev)) {
             return topView;