Merge "Create new ShortcutInfo when dropping predicted deep shortcuts." into ub-launcher3-master
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 549c65e..adea1f2 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -432,6 +432,8 @@
         boolean isBelowCenterY = lp.topMargin < centerY;
         x.setDuration(isBelowCenterY ? 500 : 233);
         y.setDuration(isBelowCenterY ? 233 : 500);
+        x.setInterpolator(Interpolators.AGGRESSIVE_EASE);
+        y.setInterpolator(Interpolators.AGGRESSIVE_EASE);
         appIconAnimatorSet.play(x);
         appIconAnimatorSet.play(y);
 
@@ -444,18 +446,18 @@
         ObjectAnimator sY = ObjectAnimator.ofFloat(mFloatingView, View.SCALE_Y, 1f, scale);
         sX.setDuration(500);
         sY.setDuration(500);
+        sX.setInterpolator(Interpolators.EXAGGERATED_EASE);
+        sY.setInterpolator(Interpolators.EXAGGERATED_EASE);
         appIconAnimatorSet.play(sX);
         appIconAnimatorSet.play(sY);
 
         // Fade out the app icon.
         ObjectAnimator alpha = ObjectAnimator.ofFloat(mFloatingView, View.ALPHA, 1f, 0f);
-        alpha.setStartDelay(17);
-        alpha.setDuration(33);
+        alpha.setStartDelay(32);
+        alpha.setDuration(50);
+        alpha.setInterpolator(Interpolators.LINEAR);
         appIconAnimatorSet.play(alpha);
 
-        for (Animator a : appIconAnimatorSet.getChildAnimations()) {
-            a.setInterpolator(Interpolators.AGGRESSIVE_EASE);
-        }
         return appIconAnimatorSet;
     }
 
@@ -516,9 +518,9 @@
 
                 // Fade in the app window.
                 float alphaDelay = 0;
-                float alphaDuration = 50;
+                float alphaDuration = 60;
                 float alpha = getValue(0f, 1f, alphaDelay, alphaDuration,
-                        appAnimator.getDuration() * percent, Interpolators.AGGRESSIVE_EASE);
+                        appAnimator.getDuration() * percent, Interpolators.LINEAR);
 
                 // Animate the window crop so that it starts off as a square, and then reveals
                 // horizontally.
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 1e48a53..19e1cca 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -22,6 +22,7 @@
 import static android.view.MotionEvent.ACTION_UP;
 import static android.view.MotionEvent.INVALID_POINTER_ID;
 import static com.android.quickstep.RemoteRunnable.executeSafely;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
 
 import android.app.ActivityManager.RunningTaskInfo;
@@ -131,7 +132,8 @@
 
     public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
             RecentsModel recentsModel, Intent homeIntent, ISystemUiProxy systemUiProxy,
-            MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer) {
+            MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer,
+            @HitTarget int downHitTarget) {
         super(base);
         mRunningTask = runningTaskInfo;
         mRecentsModel = recentsModel;
@@ -140,10 +142,6 @@
         mISystemUiProxy = systemUiProxy;
         mMainThreadExecutor = mainThreadExecutor;
         mBackgroundThreadChoreographer = backgroundThreadChoreographer;
-    }
-
-    @Override
-    public void setDownHitTarget(@HitTarget int downHitTarget) {
         mDownHitTarget = downHitTarget;
     }
 
@@ -163,7 +161,7 @@
 
                 // Start the window animation on down to give more time for launcher to draw if the
                 // user didn't start the gesture over the back button
-                if (!isUsingScreenShot()) {
+                if (!isUsingScreenShot() && mDownHitTarget != HIT_TARGET_BACK) {
                     startTouchTrackingForWindowAnimation(ev.getEventTime());
                 }
 
@@ -205,6 +203,10 @@
 
                         if (isUsingScreenShot()) {
                             startTouchTrackingForScreenshotAnimation();
+                        } else if (mDownHitTarget == HIT_TARGET_BACK) {
+                            // If we deferred starting the window animation on touch down, then
+                            // start tracking now
+                            startTouchTrackingForWindowAnimation(ev.getEventTime());
                         }
 
                         notifyGestureStarted();
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index bc7647a..bda9688 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -33,7 +33,9 @@
     public static final int QUICK_SWITCH_START_DURATION = 133;
     public static final int QUICK_SWITCH_SNAP_DURATION = 120;
 
-    private static final int NUM_QUICK_SCRUB_SECTIONS = 5;
+    private static final boolean ENABLE_AUTO_ADVANCE = true;
+    private static final int NUM_QUICK_SCRUB_SECTIONS = 3;
+    private static final long INITIAL_AUTO_ADVANCE_DELAY = 1000;
     private static final long AUTO_ADVANCE_DELAY = 500;
     private static final int QUICKSCRUB_SNAP_DURATION_PER_PAGE = 325;
     private static final int QUICKSCRUB_END_SNAP_DURATION_PER_PAGE = 60;
@@ -44,22 +46,28 @@
     private boolean mInQuickScrub;
     private int mQuickScrubSection;
     private int mStartPage;
+    private boolean mHasAlarmRun;
 
     public QuickScrubController(RecentsView recentsView) {
         mRecentsView = recentsView;
-        mAutoAdvanceAlarm = new Alarm();
-        mAutoAdvanceAlarm.setOnAlarmListener(this);
+        if (ENABLE_AUTO_ADVANCE) {
+            mAutoAdvanceAlarm = new Alarm();
+            mAutoAdvanceAlarm.setOnAlarmListener(this);
+        }
     }
 
     public void onQuickScrubStart(boolean startingFromHome) {
         mInQuickScrub = true;
         mStartPage = startingFromHome ? 0 : mRecentsView.getFirstTaskIndex();
         mQuickScrubSection = 0;
+        mHasAlarmRun = false;
     }
 
     public void onQuickScrubEnd() {
         mInQuickScrub = false;
-        mAutoAdvanceAlarm.cancelAlarm();
+        if (ENABLE_AUTO_ADVANCE) {
+            mAutoAdvanceAlarm.cancelAlarm();
+        }
         int page = mRecentsView.getNextPage();
         Runnable launchTaskRunnable = () -> {
             if (page < mRecentsView.getFirstTaskIndex()) {
@@ -84,10 +92,13 @@
         if (quickScrubSection != mQuickScrubSection) {
             int pageToGoTo = mRecentsView.getNextPage() + quickScrubSection - mQuickScrubSection;
             goToPageWithHaptic(pageToGoTo);
-            if (quickScrubSection == NUM_QUICK_SCRUB_SECTIONS || quickScrubSection == 0) {
-                mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
-            } else {
-                mAutoAdvanceAlarm.cancelAlarm();
+            if (ENABLE_AUTO_ADVANCE) {
+                if (quickScrubSection == NUM_QUICK_SCRUB_SECTIONS || quickScrubSection == 0) {
+                    mAutoAdvanceAlarm.setAlarm(mHasAlarmRun
+                            ? AUTO_ADVANCE_DELAY : INITIAL_AUTO_ADVANCE_DELAY);
+                } else {
+                    mAutoAdvanceAlarm.cancelAlarm();
+                }
             }
             mQuickScrubSection = quickScrubSection;
         }
@@ -136,6 +147,9 @@
         } else if (mQuickScrubSection == 0 && currPage > mStartPage) {
             goToPageWithHaptic(currPage - 1);
         }
-        mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
+        mHasAlarmRun = true;
+        if (ENABLE_AUTO_ADVANCE) {
+            mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
+        }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index a9d5e63..cb510c8 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -478,9 +478,7 @@
         mRunningTaskId = runningTaskId;
         setCurrentPage(mFirstTaskIndex);
         if (mCurrentPage >= mFirstTaskIndex) {
-            TaskView currentTask = (TaskView) getPageAt(mCurrentPage);
-            currentTask.setIconScale(0);
-            currentTask.setAlpha(0);
+            getPageAt(mCurrentPage).setAlpha(0);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index d8ba186..9c3f0d4 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -23,7 +23,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.util.Log;
 import android.view.View;
 
@@ -101,8 +100,11 @@
             if (launcher.getDeviceProfile().inMultiWindowMode()) {
                 return null;
             }
+            final Task task  = taskView.getTask();
+            if (!task.isDockable) {
+                return null;
+            }
             return (v -> {
-                Task task  = taskView.getTask();
                 final ActivityOptions options = ActivityOptionsCompat.makeSplitScreenOptions(true);
                 final Consumer<Boolean> resultCallback = success -> {
                     if (success) {
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index aaea379..f35f6a6 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -49,8 +49,6 @@
 
     default void reset() { }
 
-    default void setDownHitTarget(@HitTarget int downHitTarget) { }
-
     default void updateTouchTracking(@InteractionType int interactionType) { }
 
     default void onQuickScrubEnd() { }
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index ccc1e12..8cd2c02 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -192,7 +192,7 @@
             mEventQueue = new MotionEventQueue(mMainThreadChoreographer,
                     new OtherActivityTouchConsumer(this, mRunningTask, mRecentsModel,
                     mHomeIntent, mISystemUiProxy, mMainThreadExecutor,
-                    mBackgroundThreadChoreographer));
+                    mBackgroundThreadChoreographer, downHitTarget));
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 6b1c5e1..ddddbf6 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -569,6 +569,14 @@
      */
     private void notifyGestureStarted() {
         mLauncher.onQuickstepGestureStarted(mWasLauncherAlreadyVisible);
+
+        mMainExecutor.execute(() -> {
+            // Prepare to animate the first icon.
+            View currentRecentsPage = mRecentsView.getPageAt(mRecentsView.getCurrentPage());
+            if (currentRecentsPage instanceof TaskView) {
+                ((TaskView) currentRecentsPage).setIconScale(0f);
+            }
+        });
     }
 
     @WorkerThread
@@ -673,7 +681,7 @@
         // Re apply state in case we did something funky during the transition.
         mLauncher.getStateManager().reapplyState();
 
-        // Animate ui the first icon.
+        // Animate the first icon.
         View currentRecentsPage = mRecentsView.getPageAt(mRecentsView.getCurrentPage());
         if (currentRecentsPage instanceof TaskView) {
             ((TaskView) currentRecentsPage).animateIconToScale(1f);
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index e0b84bf..170fcd7 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -175,6 +175,7 @@
         mConfig.reset();
 
         if (!animated) {
+            preOnStateTransitionStart();
             onStateTransitionStart(state);
             for (StateHandler handler : getStateHandlers()) {
                 handler.setState(state);
@@ -231,6 +232,8 @@
 
     protected AnimatorSet createAnimationToNewWorkspaceInternal(final LauncherState state,
             AnimatorSetBuilder builder, final Runnable onCompleteRunnable) {
+        preOnStateTransitionStart();
+
         for (StateHandler handler : getStateHandlers()) {
             builder.startTag(handler);
             handler.setStateWithAnimation(state, builder, mConfig);
@@ -269,6 +272,15 @@
         return mConfig.mCurrentAnimation;
     }
 
+    private void preOnStateTransitionStart() {
+        // If we are still animating to launcher from an app,
+        // finish it and let this state animation take over.
+        LauncherAppTransitionManager transitionManager = mLauncher.getAppTransitionManager();
+        if (transitionManager != null) {
+            transitionManager.finishLauncherAnimation();
+        }
+    }
+
     private void onStateTransitionStart(LauncherState state) {
         mState.onStateDisabled(mLauncher);
         mState = state;
@@ -279,13 +291,6 @@
             // Only disable clipping if needed, otherwise leave it as previous value.
             mLauncher.getWorkspace().setClipChildren(false);
         }
-
-        // If we are still animating to launcher from an app,
-        // finish it and let this state animation take over.
-        LauncherAppTransitionManager transitionManager = mLauncher.getAppTransitionManager();
-        if (transitionManager != null) {
-            transitionManager.finishLauncherAnimation();
-        }
     }
 
     private void onStateTransitionEnd(LauncherState state) {
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 0dcebe3..6078776 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.anim;
 
+import android.graphics.Path;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
@@ -44,9 +45,19 @@
     public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
 
     public static final Interpolator AGGRESSIVE_EASE = new PathInterpolator(0.2f, 0f, 0f, 1f);
-    public static final Interpolator AGGRESSIVE_EASE_IN_OUT = new PathInterpolator(0.8f,0, 0.4f, 1);
+    public static final Interpolator AGGRESSIVE_EASE_IN_OUT = new PathInterpolator(0.6f,0, 0.4f, 1);
 
-    public static final Interpolator APP_CLOSE_ALPHA = new PathInterpolator(0.9f, 0, 1f, 1f);
+    public static final Interpolator EXAGGERATED_EASE;
+
+    static {
+        Path exaggeratedEase = new Path();
+        exaggeratedEase.moveTo(0, 0);
+        exaggeratedEase.cubicTo(0.05f, 0f, 0.133333f, 0.08f, 0.166666f, 0.4f);
+        exaggeratedEase.cubicTo(0.225f, 0.94f, 0.5f, 1f, 1f, 1f);
+        EXAGGERATED_EASE = new PathInterpolator(exaggeratedEase);
+    }
+
+    public static final Interpolator APP_CLOSE_ALPHA = new PathInterpolator(0.4f, 0, 1f, 1f);
 
     public static final Interpolator OVERSHOOT_0 = new OvershootInterpolator(0);