Merge "Exposing AnimatorListeners in StateManager to receive both success and failure callback" into sc-dev
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 25be30f..d04bfe9 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -63,7 +63,6 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.Build;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.view.MotionEvent;
@@ -136,7 +135,6 @@
     protected final BaseActivityInterface<S, T> mActivityInterface;
     protected final InputConsumerProxy mInputConsumerProxy;
     protected final ActivityInitListener mActivityInitListener;
-    private final Handler mHandler = new Handler();
     // Callbacks to be made once the recents animation starts
     private final ArrayList<Runnable> mRecentsAnimationStartCallbacks = new ArrayList<>();
     private final OnScrollChangedListener mOnRecentsScrollListener = this::onRecentsViewScroll;
@@ -148,9 +146,6 @@
     protected Runnable mGestureEndCallback;
     protected MultiStateCallback mStateCallback;
     protected boolean mCanceled;
-    // One time flag set when onConsumerAboutToBeSwitched() is called, indicating that certain
-    // shared animations should not be canceled when this handler is invalidated
-    private boolean mConsumerIsSwitching;
     private boolean mRecentsViewScrollLinked = false;
 
     private static int getFlagForIndex(int index, String name) {
@@ -1007,14 +1002,7 @@
         animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocity);
     }
 
-    private int getLogGestureTaskIndex(@Nullable TaskView targetTask) {
-        return mRecentsView == null || targetTask == null
-                ? LOG_NO_OP_PAGE_INDEX
-                : mRecentsView.indexOfChild(targetTask);
-    }
-
-    private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask,
-            int pageIndex) {
+    private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
         StatsLogManager.EventEnum event;
         switch (endTarget) {
             case HOME:
@@ -1043,6 +1031,9 @@
             // We probably never received an animation controller, skip logging.
             return;
         }
+        int pageIndex = endTarget == LAST_TASK
+                ? LOG_NO_OP_PAGE_INDEX
+                : mRecentsView.getNextPage();
         // TODO: set correct container using the pageIndex
         logger.log(event);
     }
@@ -1294,18 +1285,18 @@
     }
 
     public void onConsumerAboutToBeSwitched() {
-        mConsumerIsSwitching = true;
         if (mActivity != null) {
             // In the off chance that the gesture ends before Launcher is started, we should clear
             // the callback here so that it doesn't update with the wrong state
             mActivity.clearRunOnceOnStartCallback();
+            resetLauncherListeners();
         }
         if (mGestureState.getEndTarget() != null && !mGestureState.isRunningAnimationToLauncher()) {
             cancelCurrentAnimation();
         } else {
             mStateCallback.setStateOnUiThread(STATE_FINISH_WITH_NO_END);
+            reset();
         }
-        reset();
     }
 
     public boolean isCanceled() {
@@ -1316,14 +1307,13 @@
     private void resumeLastTask() {
         mRecentsAnimationController.finish(false /* toRecents */, null);
         ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
-        doLogGesture(LAST_TASK, null, getLogGestureTaskIndex(null));
+        doLogGesture(LAST_TASK, null);
         reset();
     }
 
     @UiThread
     private void startNewTask() {
         TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getNextPageTaskView();
-        int taskPageIndex = getLogGestureTaskIndex(taskToLaunch);
         startNewTask(success -> {
             if (!success) {
                 reset();
@@ -1332,7 +1322,7 @@
                 endLauncherTransitionController();
                 updateSysUiFlags(1 /* windowProgress == overview */);
             }
-            doLogGesture(NEW_TASK, taskToLaunch, taskPageIndex);
+            doLogGesture(NEW_TASK, taskToLaunch);
         });
     }
 
@@ -1366,39 +1356,29 @@
     }
 
     private void invalidateHandler() {
-        if (!mConsumerIsSwitching) {
-            if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
-                    || mGestureState.getEndTarget() != RECENTS) {
-                mInputConsumerProxy.destroy();
-                mTaskAnimationManager.setLiveTileCleanUpHandler(null);
-            }
-            endRunningWindowAnim(false /* cancel */);
+        if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
+                || mGestureState.getEndTarget() != RECENTS) {
+            mInputConsumerProxy.destroy();
+            mTaskAnimationManager.setLiveTileCleanUpHandler(null);
+        }
+        mInputConsumerProxy.unregisterCallback();
+        endRunningWindowAnim(false /* cancel */);
 
-            if (mGestureEndCallback != null) {
-                mGestureEndCallback.run();
-            }
+        if (mGestureEndCallback != null) {
+            mGestureEndCallback.run();
         }
 
-        mInputConsumerProxy.unregisterCallback();
         mActivityInitListener.unregister();
         ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mActivityRestartListener);
         mTaskSnapshot = null;
     }
 
     private void invalidateHandlerWithLauncher() {
-        if (!mConsumerIsSwitching) {
-            endLauncherTransitionController();
-            mRecentsView.onGestureAnimationEnd();
-        }
+        endLauncherTransitionController();
 
         mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
+        mRecentsView.onGestureAnimationEnd();
         resetLauncherListeners();
-
-        mHandler.post(() -> {
-            // Defer clearing the activity since invalidation can happen over multiple callbacks.
-            mActivity = null;
-            mRecentsView = null;
-        });
     }
 
     private void endLauncherTransitionController() {
@@ -1516,8 +1496,7 @@
                     () -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
         }
         ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
-        TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView();
-        doLogGesture(HOME, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
+        doLogGesture(HOME, mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView());
     }
 
     /**
@@ -1548,8 +1527,7 @@
         }
 
         SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
-        TaskView taskToLaunch = mRecentsView.getCurrentPageTaskView();
-        doLogGesture(RECENTS, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
+        doLogGesture(RECENTS, mRecentsView.getCurrentPageTaskView());
         reset();
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 49fc2dd..a36c9af 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3635,6 +3635,12 @@
      * capturing the snapshot at the same time.
      */
     public void switchToScreenshot(Runnable onFinishRunnable) {
+        if (mRecentsAnimationController == null) {
+            if (onFinishRunnable != null) {
+                onFinishRunnable.run();
+            }
+            return;
+        }
         switchToScreenshot(mRunningTaskId == -1 ? null
                 : mRecentsAnimationController.screenshotTask(mRunningTaskId), onFinishRunnable);
     }
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e5c28f6..b26a7ea 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -459,11 +459,6 @@
         }
     }
 
-    // we moved this functionality to a helper function so SmoothPagedView can reuse it
-    protected boolean computeScrollHelper() {
-        return computeScrollHelper(true);
-    }
-
     protected void announcePageForAccessibility() {
         if (isAccessibilityEnabled(getContext())) {
             // Notify the user when the page changes
@@ -471,7 +466,7 @@
         }
     }
 
-    protected boolean computeScrollHelper(boolean shouldInvalidate) {
+    protected boolean computeScrollHelper() {
         if (mScroller.computeScrollOffset()) {
             // Don't bother scrolling if the page does not need to be moved
             int oldPos = mOrientationHandler.getPrimaryScroll(this);
@@ -479,23 +474,29 @@
             if (oldPos != newPos) {
                 mOrientationHandler.set(this, VIEW_SCROLL_TO, mScroller.getCurrX());
             }
-            if (shouldInvalidate) {
-                if (mAllowOverScroll) {
-                    if (newPos < mMinScroll && oldPos >= mMinScroll) {
-                        mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
-                        mScroller.abortAnimation();
-                    } else if (newPos > mMaxScroll && oldPos <= mMaxScroll) {
-                        mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
-                        mScroller.abortAnimation();
-                    }
+
+            if (mAllowOverScroll) {
+                if (newPos < mMinScroll && oldPos >= mMinScroll) {
+                    mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
+                    mScroller.abortAnimation();
+                } else if (newPos > mMaxScroll && oldPos <= mMaxScroll) {
+                    mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
+                    mScroller.abortAnimation();
                 }
-
-                invalidate();
             }
-            return true;
-        } else if (mNextPage != INVALID_PAGE && shouldInvalidate) {
-            sendScrollAccessibilityEvent();
 
+            // If the scroller has scrolled to the final position and there is no edge effect, then
+            // finish the scroller to skip waiting for additional settling
+            int finalPos = mOrientationHandler.getPrimaryValue(mScroller.getFinalX(),
+                    mScroller.getFinalY());
+            if (newPos == finalPos && mEdgeGlowLeft.isFinished() && mEdgeGlowRight.isFinished()) {
+                mScroller.abortAnimation();
+            }
+
+            invalidate();
+            return true;
+        } else if (mNextPage != INVALID_PAGE) {
+            sendScrollAccessibilityEvent();
             int prevPage = mCurrentPage;
             mCurrentPage = validateNewPage(mNextPage);
             mNextPage = INVALID_PAGE;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 81d4fcf..5ba7623 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1164,10 +1164,6 @@
         mWallpaperOffset.syncWithScroll();
     }
 
-    public void computeScrollWithoutInvalidation() {
-        computeScrollHelper(false);
-    }
-
     @Override
     public void announceForAccessibility(CharSequence text) {
         // Don't announce if apps is on top of us.
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 6b42d98..7ef43ed 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -174,12 +174,12 @@
             "Replace Smartspace with the enhanced version. "
                     + "Ignored if ENABLE_SMARTSPACE_UNIVERSAL is enabled.");
 
-    public static final BooleanFlag ENABLE_SMARTSPACE_FEEDBACK = new DeviceFlag(
+    public static final BooleanFlag ENABLE_SMARTSPACE_FEEDBACK = getDebugFlag(
             "ENABLE_SMARTSPACE_FEEDBACK", true,
             "Adds a menu option to send feedback for Enhanced Smartspace.");
 
-    public static final BooleanFlag ENABLE_SMARTSPACE_DISMISS = new DeviceFlag(
-            "ENABLE_SMARTSPACE_DISMISS", false,
+    public static final BooleanFlag ENABLE_SMARTSPACE_DISMISS = getDebugFlag(
+            "ENABLE_SMARTSPACE_DISMISS", true,
             "Adds a menu option to dismiss the current Enhanced Smartspace card.");
 
     public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS =
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index d8e5a48..6811438 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -105,7 +105,7 @@
     int getPrimaryValue(int x, int y);
     int getSecondaryValue(int x, int y);
 
-    float  getPrimaryValue(float x, float y);
+    float getPrimaryValue(float x, float y);
     float getSecondaryValue(float x, float y);
 
     boolean isLayoutNaturalToLauncher();