Merge "Force finishing spring animation on second touch, if the animation is close to completion" into ub-launcher3-master
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 785a480..6fc03b1 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
@@ -120,8 +120,8 @@
         mPeekAnim.start();
         VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
 
-        mLauncher.getDragLayer().getScrim().animateToSysuiMultiplier(isPaused ? 0 : 1,
-                peekDuration, 0);
+        mLauncher.getDragLayer().getScrim().createSysuiMultiplierAnim(isPaused ? 0 : 1)
+                .setDuration(peekDuration).start();
     }
 
     /**
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 43c5cb5..9cf45b3 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
@@ -126,6 +126,8 @@
             addScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
         }
 
+        mAnimators.play(launcher.getDragLayer().getScrim().createSysuiMultiplierAnim(0f, 1f)
+                .setDuration(ALPHA_DURATION_MS));
         mAnimators.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -153,6 +155,10 @@
         launcher.<RecentsView>getOverviewPanel().getScroller().forceFinished(true);
     }
 
+    public AnimatorSet getAnimators() {
+        return mAnimators;
+    }
+
     /**
      * Starts the animation.
      */
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index b9bd6b1..1b39242 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3;
 
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+
 import static com.android.launcher3.BaseActivity.INVISIBLE_ALL;
 import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS;
 import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS;
@@ -29,6 +31,7 @@
 import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
 import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
 import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
 import static com.android.launcher3.uioverrides.BackgroundBlurController.BACKGROUND_BLUR;
 import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
@@ -58,6 +61,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Pair;
+import android.util.TypedValue;
 import android.view.View;
 
 import androidx.annotation.NonNull;
@@ -70,12 +74,14 @@
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.launcher3.uioverrides.BackgroundBlurController;
+import com.android.launcher3.util.DynamicResource;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.views.FloatingIconView;
 import com.android.quickstep.RemoteAnimationTargets;
 import com.android.quickstep.util.MultiValueUpdateListener;
 import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.quickstep.util.StaggeredWorkspaceAnim;
 import com.android.systemui.shared.system.ActivityCompat;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
 import com.android.systemui.shared.system.QuickStepContract;
@@ -156,6 +162,7 @@
     // Strong refs to runners which are cleared when the launcher activity is destroyed
     private WrappedAnimationRunnerImpl mWallpaperOpenRunner;
     private WrappedAnimationRunnerImpl mAppLaunchRunner;
+    private WrappedAnimationRunnerImpl mKeyguardGoingAwayRunner;
 
     private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
         @Override
@@ -623,6 +630,17 @@
                             new WrappedLauncherAnimationRunner<>(mWallpaperOpenRunner,
                                     false /* startAtFrontOfQueue */),
                             CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
+
+            if (KEYGUARD_ANIMATION.get()) {
+                mKeyguardGoingAwayRunner = createWallpaperOpenRunner(true /* fromUnlock */);
+                definition.addRemoteAnimation(
+                        WindowManagerWrapper.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
+                        new RemoteAnimationAdapterCompat(
+                                new WrappedLauncherAnimationRunner<>(mKeyguardGoingAwayRunner,
+                                        true /* startAtFrontOfQueue */),
+                                CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
+            }
+
             new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
         }
     }
@@ -639,6 +657,7 @@
             // definition so we don't have to wait for the system gc
             mWallpaperOpenRunner = null;
             mAppLaunchRunner = null;
+            mKeyguardGoingAwayRunner = null;
         }
     }
 
@@ -868,18 +887,14 @@
                         || mLauncher.isForceInvisible()) {
                     // Only register the content animation for cancellation when state changes
                     mLauncher.getStateManager().setCurrentAnimation(anim);
+
                     if (mFromUnlock) {
-                        Pair<AnimatorSet, Runnable> contentAnimator =
-                                getLauncherContentAnimator(false /* isAppOpening */,
-                                        new float[] {mContentTransY, 0});
-                        contentAnimator.first.setStartDelay(0);
-                        anim.play(contentAnimator.first);
-                        anim.addListener(new AnimatorListenerAdapter() {
-                            @Override
-                            public void onAnimationEnd(Animator animation) {
-                                contentAnimator.second.run();
-                            }
-                        });
+                        float velocityDpPerS = DynamicResource.provider(mLauncher)
+                                .getDimension(R.dimen.unlock_staggered_velocity_dp_per_s);
+                        float velocityPxPerS = TypedValue.applyDimension(COMPLEX_UNIT_DIP,
+                                velocityDpPerS, mLauncher.getResources().getDisplayMetrics());
+                        anim.play(new StaggeredWorkspaceAnim(mLauncher, velocityPxPerS, false)
+                                .getAnimators());
                     } else {
                         createLauncherResumeAnimation(anim);
                     }
diff --git a/res/values/config.xml b/res/values/config.xml
index df0f233..6c239bd 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -142,6 +142,7 @@
 
     <item name="staggered_damping_ratio" type="dimen" format="float">0.7</item>
     <item name="staggered_stiffness" type="dimen" format="float">150</item>
+    <dimen name="unlock_staggered_velocity_dp_per_s">3dp</dimen>
 
     <!-- Swipe up to home related -->
     <dimen name="swipe_up_fling_min_visible_change">18dp</dimen>
@@ -170,6 +171,7 @@
 
         <item>@dimen/staggered_damping_ratio</item>
         <item>@dimen/staggered_stiffness</item>
+        <item>@dimen/unlock_staggered_velocity_dp_per_s</item>
 
         <item>@dimen/swipe_up_fling_min_visible_change</item>
         <item>@dimen/swipe_up_y_overshoot</item>
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 8453c41..0237b50 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -83,6 +83,9 @@
     public static final BooleanFlag UNSTABLE_SPRINGS = getDebugFlag(
             "UNSTABLE_SPRINGS", false, "Enable unstable springs for quickstep animations");
 
+    public static final BooleanFlag KEYGUARD_ANIMATION = getDebugFlag(
+            "KEYGUARD_ANIMATION", false, "Enable animation for keyguard going away on wallpaper");
+
     public static final BooleanFlag ADAPTIVE_ICON_WINDOW_ANIM = getDebugFlag(
             "ADAPTIVE_ICON_WINDOW_ANIM", true, "Use adaptive icons for window animations.");
 
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index 83349bc..2c7f891 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -19,6 +19,7 @@
 import static android.content.Intent.ACTION_SCREEN_OFF;
 import static android.content.Intent.ACTION_USER_PRESENT;
 
+import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
 import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 import android.animation.ObjectAnimator;
@@ -81,6 +82,10 @@
                 }
             };
 
+    /**
+     * Receiver used to get a signal that the user unlocked their device.
+     * @see KEYGUARD_ANIMATION For proper signal.
+     */
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -164,8 +169,10 @@
                 mSysUiAnimMultiplier = 0;
                 reapplySysUiAlphaNoInvalidate();
 
-                animateToSysuiMultiplier(1, 600,
-                        mLauncher.getWindow().getTransitionBackgroundFadeDuration());
+                ObjectAnimator oa = createSysuiMultiplierAnim(1);
+                oa.setDuration(600);
+                oa.setStartDelay(mLauncher.getWindow().getTransitionBackgroundFadeDuration());
+                oa.start();
                 mAnimateScrimOnNextDraw = false;
             }
 
@@ -178,13 +185,13 @@
         }
     }
 
-    public void animateToSysuiMultiplier(float toMultiplier, long duration,
-            long startDelay) {
-        ObjectAnimator anim = ObjectAnimator.ofFloat(this, SYSUI_ANIM_MULTIPLIER, toMultiplier);
+    /**
+     * @return an ObjectAnimator that controls the fade in/out of the sys ui scrim.
+     */
+    public ObjectAnimator createSysuiMultiplierAnim(float... values) {
+        ObjectAnimator anim = ObjectAnimator.ofFloat(this, SYSUI_ANIM_MULTIPLIER, values);
         anim.setAutoCancel(true);
-        anim.setDuration(duration);
-        anim.setStartDelay(startDelay);
-        anim.start();
+        return anim;
     }
 
     public void onInsetsChanged(Rect insets) {
@@ -197,7 +204,7 @@
     public void onViewAttachedToWindow(View view) {
         super.onViewAttachedToWindow(view);
 
-        if (mTopScrim != null) {
+        if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
             IntentFilter filter = new IntentFilter(ACTION_SCREEN_OFF);
             filter.addAction(ACTION_USER_PRESENT); // When the device wakes up + keyguard is gone
             mRoot.getContext().registerReceiver(mReceiver, filter);
@@ -207,7 +214,7 @@
     @Override
     public void onViewDetachedFromWindow(View view) {
         super.onViewDetachedFromWindow(view);
-        if (mTopScrim != null) {
+        if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
             mRoot.getContext().unregisterReceiver(mReceiver);
         }
     }
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 3770d17..89077ee 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -143,7 +143,7 @@
             fillIntentInfo(itemTarget, intent, userHandle);
         }
         LauncherEvent event = newLauncherEvent(action,  targets);
-        ItemInfo info = (ItemInfo) v.getTag();
+        ItemInfo info = v == null ? null : (ItemInfo) v.getTag();
         if (info != null && Utilities.IS_DEBUG_DEVICE && FeatureFlags.ENABLE_HYBRID_HOTSEAT.get()) {
             FileLog.d(TAG, "appLaunch: packageName:" + info.getTargetComponent().getPackageName()
                     + ",isWorkApp:" + (info.user != null && !Process.myUserHandle().equals(
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 1d14a8f..cbc5257 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -535,7 +535,7 @@
             // case the user started interacting with it before the animation finished.
             mLauncher.getStateManager().goToState(targetState, false /* animated */);
         }
-        mLauncher.getDragLayer().getScrim().animateToSysuiMultiplier(1, 0, 0);
+        mLauncher.getDragLayer().getScrim().createSysuiMultiplierAnim(1f).setDuration(0).start();
     }
 
     private void logReachedState(int logAction, LauncherState targetState) {