Polish app => recents animation (3/N)

This CL takes the current scale down animation and updates its
interpolators and durations to match the UX spec. In addition, we move
the core logic to a helper method as the whole remote animation will
have other animations as well in the future.

Bug: 132112131
Test: Manual
Change-Id: I68b1d623b1b2c980dc34e41bbb5460cc021b5887
diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index 2dc2554..62e40d1 100644
--- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -23,7 +23,6 @@
 import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
 import android.util.Log;
-import android.view.View;
 
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.quickstep.util.RemoteAnimationProvider;
@@ -119,7 +118,7 @@
             return anim;
         }
 
-        mRecentsView.playAppScaleDownAnim(anim, closingAppTarget, recentsTarget);
+        mRecentsView.playRemoteAppToRecentsAnimation(anim, closingAppTarget, recentsTarget);
 
         return anim;
     }
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index 89d248c..58c6709 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -20,7 +20,6 @@
 import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
 
 import static com.android.launcher3.anim.Interpolators.ACCEL_2;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
 import static com.android.quickstep.TaskAdapter.CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT;
 import static com.android.quickstep.TaskAdapter.ITEM_TYPE_CLEAR_ALL;
 import static com.android.quickstep.TaskAdapter.ITEM_TYPE_TASK;
@@ -45,6 +44,7 @@
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewTreeObserver;
+import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 
 import androidx.annotation.NonNull;
@@ -111,10 +111,15 @@
     private static final float ITEM_ANIMATE_OUT_TRANSLATION_X_RATIO = .25f;
     private static final long CLEAR_ALL_FADE_DELAY = 120;
 
-    private static final long APP_TO_THUMBNAIL_FADE_DURATION = 50;
-    private static final long APP_SCALE_DOWN_DURATION = 400;
+    private static final long REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION = 300;
 
-    public static final long REMOTE_APP_TO_OVERVIEW_DURATION = APP_SCALE_DOWN_DURATION;
+    private static final PathInterpolator FAST_OUT_SLOW_IN_1 =
+            new PathInterpolator(.4f, 0f, 0f, 1f);
+    private static final PathInterpolator FAST_OUT_SLOW_IN_2 =
+            new PathInterpolator(.5f, 0f, 0f, 1f);
+
+    public static final long REMOTE_APP_TO_OVERVIEW_DURATION =
+            REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION;
 
     /**
      * A ratio representing the view's relative placement within its padded space. For example, 0
@@ -397,7 +402,7 @@
      *
      * @return the thumbnail view if laid out
      */
-    public @Nullable View getBottomThumbnailView() {
+    private @Nullable View getBottomThumbnailView() {
         ArrayList<TaskItemView> taskViews = getTaskViews();
         if (taskViews.isEmpty()) {
             return null;
@@ -580,18 +585,17 @@
     }
 
     /**
-     * Animate a closing app to scale down to the location of the thumbnail view in recents.
+     * Play remote animation from app to recents. This should scale the currently closing app down
+     * to the recents thumbnail.
      *
      * @param anim animator set
      * @param appTarget the app surface thats closing
      * @param recentsTarget the surface containing recents
      */
-    public void playAppScaleDownAnim(@NonNull AnimatorSet anim,
+    public void playRemoteAppToRecentsAnimation(@NonNull AnimatorSet anim,
             @NonNull RemoteAnimationTargetCompat appTarget,
             @NonNull RemoteAnimationTargetCompat recentsTarget) {
-
         View thumbnailView = getBottomThumbnailView();
-
         if (thumbnailView == null) {
             // This can be null if there were previously 0 tasks and the recycler view has not had
             // enough time to take in the data change, bind a new view, and lay out the new view.
@@ -599,15 +603,28 @@
             anim.play(ValueAnimator.ofInt(0, 1).setDuration(REMOTE_APP_TO_OVERVIEW_DURATION));
         }
 
+        // TODO: Play other animations in app => recents
+        playRemoteAppScaleDownAnim(anim, appTarget, recentsTarget, thumbnailView);
+    }
+
+    /**
+     * Play the scale down animation for the remote app to recents animation where the app surface
+     * scales down to where the thumbnail is.
+     *
+     * @param anim animator set to play on
+     * @param appTarget closing app target
+     * @param recentsTarget opening recents target
+     * @param thumbnailView thumbnail view to animate to
+     */
+    private void playRemoteAppScaleDownAnim(@NonNull AnimatorSet anim,
+            @NonNull RemoteAnimationTargetCompat appTarget,
+            @NonNull RemoteAnimationTargetCompat recentsTarget,
+            @NonNull View thumbnailView) {
         // Identify where the entering remote app should animate to.
         Rect endRect = new Rect();
         thumbnailView.getGlobalVisibleRect(endRect);
-
         Rect appBounds = appTarget.sourceContainerBounds;
 
-        ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1);
-        valueAnimator.setDuration(APP_SCALE_DOWN_DURATION);
-
         SyncRtSurfaceTransactionApplierCompat surfaceApplier =
                 new SyncRtSurfaceTransactionApplierCompat(thumbnailView);
 
@@ -618,7 +635,9 @@
         params[0] = new SurfaceParams(recentsTarget.leash, 1f, null /* matrix */,
                 null /* windowCrop */, getLayer(recentsTarget, boostedMode), 0 /* cornerRadius */);
 
-        valueAnimator.addUpdateListener(new MultiValueUpdateListener() {
+        ValueAnimator remoteAppAnim = ValueAnimator.ofInt(0, 1);
+        remoteAppAnim.setDuration(REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION);
+        remoteAppAnim.addUpdateListener(new MultiValueUpdateListener() {
             private final FloatProp mScaleX;
             private final FloatProp mScaleY;
             private final FloatProp mTranslationX;
@@ -628,30 +647,27 @@
             {
                 // Scale down and move to view location.
                 float endScaleX = ((float) endRect.width()) / appBounds.width();
-                mScaleX = new FloatProp(1f, endScaleX, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
+                mScaleX = new FloatProp(1f, endScaleX, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
+                        FAST_OUT_SLOW_IN_1);
                 float endScaleY = ((float) endRect.height()) / appBounds.height();
-                mScaleY = new FloatProp(1f, endScaleY, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
+                mScaleY = new FloatProp(1f, endScaleY, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
+                        FAST_OUT_SLOW_IN_1);
                 float endTranslationX = endRect.left -
                         (appBounds.width() - thumbnailView.getWidth()) / 2.0f;
-                mTranslationX = new FloatProp(0, endTranslationX, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
+                mTranslationX = new FloatProp(0, endTranslationX, 0,
+                        REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION, FAST_OUT_SLOW_IN_1);
                 float endTranslationY = endRect.top -
                         (appBounds.height() - thumbnailView.getHeight()) / 2.0f;
-                mTranslationY = new FloatProp(0, endTranslationY, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
-
-                // Fade out quietly near the end to be replaced by the real view.
-                mAlpha = new FloatProp(1.0f, 0,
-                        APP_SCALE_DOWN_DURATION - APP_TO_THUMBNAIL_FADE_DURATION,
-                        APP_TO_THUMBNAIL_FADE_DURATION, ACCEL_2);
+                mTranslationY = new FloatProp(0, endTranslationY, 0,
+                        REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION, FAST_OUT_SLOW_IN_2);
+                mAlpha = new FloatProp(1.0f, 0, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
+                        ACCEL_2);
             }
 
             @Override
             public void onUpdate(float percent) {
                 Matrix m = new Matrix();
-                m.setScale(mScaleX.value, mScaleY.value,
+                m.preScale(mScaleX.value, mScaleY.value,
                         appBounds.width() / 2.0f, appBounds.height() / 2.0f);
                 m.postTranslate(mTranslationX.value, mTranslationY.value);
 
@@ -661,11 +677,7 @@
                 surfaceApplier.scheduleApply(params);
             }
         });
-        anim.play(valueAnimator);
-    }
-
-    public long getAppToOverviewAnimationDuration() {
-        return APP_SCALE_DOWN_DURATION;
+        anim.play(remoteAppAnim);
     }
 
     @Override