Adjust interpolators when swiping from overview to all apps

- All apps content fades in quickly so that icons are opaque by the time
  they are on screen
- Recents fades out late so that we don't see it as translucent while
  the transition is continuing (the translucent icon top of tranclucent
  task view looks bad, for instance)
- Fix colored scrim that appears over recents - was using 0 to 1 instead
  of 255

Bug: 79867407
Change-Id: I4f50423157f7870c8d0708f586a72e3e5a7b6559
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 512d19a..b8ebaa4 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -18,7 +18,11 @@
 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.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 
 import android.animation.TimeInterpolator;
@@ -50,6 +54,16 @@
 
     private static final String TAG = "PortraitStatesTouchCtrl";
 
+    /**
+     * The progress at which all apps content will be fully visible when swiping up from overview.
+     */
+    private static final float ALL_APPS_CONTENT_FADE_THRESHOLD = 0.08f;
+
+    /**
+     * The progress at which recents will begin fading out when swiping up from overview.
+     */
+    private static final float RECENTS_FADE_THRESHOLD = 0.88f;
+
     private InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper();
 
     // If true, we will finish the current animation instantly on second touch.
@@ -114,7 +128,38 @@
 
         AnimatorSetBuilder builder = new AnimatorSetBuilder();
         builder.setInterpolator(ANIM_VERTICAL_PROGRESS, mAllAppsInterpolatorWrapper);
+        return builder;
+    }
 
+    public static AnimatorSetBuilder getOverviewToAllAppsAnimation() {
+        AnimatorSetBuilder builder = new AnimatorSetBuilder();
+        builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
+                0, ALL_APPS_CONTENT_FADE_THRESHOLD));
+        builder.setInterpolator(ANIM_OVERVIEW_FADE, Interpolators.clampToProgress(DEACCEL,
+                RECENTS_FADE_THRESHOLD, 1));
+        return builder;
+    }
+
+    private AnimatorSetBuilder getAllAppsToOverviewAnimation() {
+        AnimatorSetBuilder builder = new AnimatorSetBuilder();
+        builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL,
+                1 - ALL_APPS_CONTENT_FADE_THRESHOLD, 1));
+        builder.setInterpolator(ANIM_OVERVIEW_FADE, Interpolators.clampToProgress(ACCEL,
+                0f, 1 - RECENTS_FADE_THRESHOLD));
+        return builder;
+    }
+
+    @Override
+    protected AnimatorSetBuilder getAnimatorSetBuilderForStates(LauncherState fromState,
+            LauncherState toState) {
+        AnimatorSetBuilder builder = new AnimatorSetBuilder();
+        if (fromState == NORMAL && toState == OVERVIEW) {
+            builder = getNormalToOverviewAnimation();
+        } else if (fromState == OVERVIEW && toState == ALL_APPS) {
+            builder = getOverviewToAllAppsAnimation();
+        } else if (fromState == ALL_APPS && toState == OVERVIEW) {
+            builder = getAllAppsToOverviewAnimation();
+        }
         return builder;
     }
 
@@ -128,13 +173,8 @@
 
         float totalShift = endVerticalShift - startVerticalShift;
 
-        final AnimatorSetBuilder builder;
-
-        if (mFromState == NORMAL && mToState == OVERVIEW && totalShift != 0) {
-            builder = getNormalToOverviewAnimation();
-        } else {
-            builder = new AnimatorSetBuilder();
-        }
+        final AnimatorSetBuilder builder = totalShift == 0 ? new AnimatorSetBuilder()
+                : getAnimatorSetBuilderForStates(mFromState, mToState);
 
         cancelPendingAnim();
 
diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
index 336be2b..0785093 100644
--- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java
+++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
@@ -25,10 +25,13 @@
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.LauncherStateManager;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.uioverrides.PortraitStatesTouchController;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -67,8 +70,10 @@
         AllAppsTransitionController controller = mLauncher.getAllAppsController();
         // TODO: Scale it down so that we can reach all-apps in screen space
         mMaxSwipeDistance = Math.max(1, controller.getProgress() * controller.getShiftRange());
-        mAnimator = mLauncher.getStateManager()
-                .createAnimationToNewWorkspace(ALL_APPS, Math.round(2 * mMaxSwipeDistance));
+
+        AnimatorSetBuilder builder = PortraitStatesTouchController.getOverviewToAllAppsAnimation();
+        mAnimator = mLauncher.getStateManager().createAnimationToNewWorkspace(ALL_APPS, builder,
+                Math.round(2 * mMaxSwipeDistance), null, LauncherStateManager.ANIM_ALL);
         mAnimator.dispatchOnStart();
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index d7e527c..8b5e832 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -16,7 +16,6 @@
 package com.android.quickstep.views;
 
 import static android.support.v4.graphics.ColorUtils.setAlphaComponent;
-
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.ACCEL;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -33,6 +32,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ScrimView;
 
@@ -55,7 +55,7 @@
     // For shelf mode
     private final int mEndAlpha;
     private final float mRadius;
-    private final float mMaxScrimAlpha;
+    private final int mMaxScrimAlpha;
     private final Paint mPaint;
 
     // Mid point where the alpha changes
@@ -78,7 +78,7 @@
 
     public ShelfScrimView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher);
+        mMaxScrimAlpha = Math.round(OVERVIEW.getWorkspaceScrimAlpha(mLauncher) * 255);
 
         mEndAlpha = Color.alpha(mEndScrim);
         mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
@@ -144,9 +144,10 @@
         } else {
             mDragHandleOffset += mShiftRange * (mMidProgress - mProgress);
 
+            // Note that these ranges and interpolators are inverted because progress goes 1 to 0.
             int alpha = Math.round(
                     Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha,
-                            (float) mMidAlpha, LINEAR));
+                            (float) mMidAlpha, Interpolators.clampToProgress(ACCEL, 0.5f, 1f)));
             mShelfColor = setAlphaComponent(mEndScrim, alpha);
 
             int remainingScrimAlpha = Math.round(
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index ccd5586..24a8d51 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -5,6 +5,7 @@
 import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.LauncherState.VERTICAL_SWIPE_INDICATOR;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
@@ -151,7 +152,7 @@
     @Override
     public void setState(LauncherState state) {
         setProgress(state.getVerticalProgress(mLauncher));
-        setAlphas(state, NO_ANIM_PROPERTY_SETTER);
+        setAlphas(state, null, new AnimatorSetBuilder());
         onProgressAnimationEnd();
     }
 
@@ -164,7 +165,7 @@
             AnimatorSetBuilder builder, AnimationConfig config) {
         float targetProgress = toState.getVerticalProgress(mLauncher);
         if (Float.compare(mProgress, targetProgress) == 0) {
-            setAlphas(toState, config.getPropertySetter(builder));
+            setAlphas(toState, config, builder);
             // Fail fast
             onProgressAnimationEnd();
             return;
@@ -186,19 +187,24 @@
 
         builder.play(anim);
 
-        setAlphas(toState, config.getPropertySetter(builder));
+        setAlphas(toState, config, builder);
     }
 
-    private void setAlphas(LauncherState toState, PropertySetter setter) {
+    private void setAlphas(LauncherState toState, AnimationConfig config,
+            AnimatorSetBuilder builder) {
+        PropertySetter setter = config == null ? NO_ANIM_PROPERTY_SETTER
+                : config.getPropertySetter(builder);
         int visibleElements = toState.getVisibleElements(mLauncher);
         boolean hasHeader = (visibleElements & ALL_APPS_HEADER) != 0;
         boolean hasHeaderExtra = (visibleElements & ALL_APPS_HEADER_EXTRA) != 0;
         boolean hasContent = (visibleElements & ALL_APPS_CONTENT) != 0;
 
-        setter.setViewAlpha(mAppsView.getSearchView(), hasHeader ? 1 : 0, LINEAR);
-        setter.setViewAlpha(mAppsView.getContentView(), hasContent ? 1 : 0, LINEAR);
-        setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, LINEAR);
-        mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter);
+        Interpolator allAppsFade = builder.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
+        setter.setViewAlpha(mAppsView.getSearchView(), hasHeader ? 1 : 0, allAppsFade);
+        setter.setViewAlpha(mAppsView.getContentView(), hasContent ? 1 : 0, allAppsFade);
+        setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, allAppsFade);
+        mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter,
+                allAppsFade);
 
         setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA,
                 (visibleElements & VERTICAL_SWIPE_INDICATOR) != 0 ? 255 : 0, LINEAR);
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 462e7f3..eaa7774 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -15,8 +15,6 @@
  */
 package com.android.launcher3.allapps;
 
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Point;
@@ -28,6 +26,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.Interpolator;
 import android.widget.LinearLayout;
 
 import com.android.launcher3.R;
@@ -227,8 +226,9 @@
         p.y = getTop() - mCurrentRV.getTop() - mParent.getTop();
     }
 
-    public void setContentVisibility(boolean hasHeader, boolean hasContent, PropertySetter setter) {
-        setter.setViewAlpha(this, hasContent ? 1 : 0, LINEAR);
+    public void setContentVisibility(boolean hasHeader, boolean hasContent, PropertySetter setter,
+            Interpolator fadeInterpolator) {
+        setter.setViewAlpha(this, hasContent ? 1 : 0, fadeInterpolator);
         allowTouchForwarding(hasContent);
     }
 
diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
index f10bce8..307f258 100644
--- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java
+++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
@@ -35,6 +35,7 @@
     public static final int ANIM_WORKSPACE_FADE = 2;
     public static final int ANIM_OVERVIEW_SCALE = 3;
     public static final int ANIM_OVERVIEW_FADE = 4;
+    public static final int ANIM_ALL_APPS_FADE = 5;
 
     protected final ArrayList<Animator> mAnims = new ArrayList<>();
 
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 955177a..cec21d5 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -341,7 +341,7 @@
 
     private AnimatorSet createAtomicAnimForState(LauncherState fromState, LauncherState targetState,
             long duration) {
-        AnimatorSetBuilder builder = new AnimatorSetBuilder();
+        AnimatorSetBuilder builder = getAnimatorSetBuilderForStates(fromState, targetState);
         mLauncher.getStateManager().prepareForAtomicAnimation(fromState, targetState, builder);
         AnimationConfig config = new AnimationConfig();
         config.animComponents = ATOMIC_COMPONENT;
@@ -352,6 +352,11 @@
         return builder.build();
     }
 
+    protected AnimatorSetBuilder getAnimatorSetBuilderForStates(LauncherState fromState,
+            LauncherState toState) {
+        return new AnimatorSetBuilder();
+    }
+
     @Override
     public void onDragEnd(float velocity, boolean fling) {
         final int logAction = fling ? Touch.FLING : Touch.SWIPE;