Ensures that the swipe up to home animation is ended prior to view recycling.

Bug: 154163960
Change-Id: I70b2c6290a2a17be8b80ba0209528173d6627332
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 6a3466c..32ab98b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -472,6 +472,7 @@
             FloatingIconView fiv = (FloatingIconView) floatingView;
             anim.addAnimatorListener(fiv);
             fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
+            fiv.setFastFinishRunnable(anim::end);
         }
 
         AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
index dde7605..8a6c4a1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -207,9 +207,23 @@
                 mRectScaleAnim.skipToEnd();
             }
         }
+        mRectXAnimEnded = true;
+        mRectYAnimEnded = true;
+        mRectScaleAnimEnded = true;
+        maybeOnEnd();
+    }
+
+    private boolean isEnded() {
+        return mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded;
     }
 
     private void onUpdate() {
+        if (isEnded()) {
+            // Prevent further updates from being called. This can happen between callbacks for
+            // ending the x/y/scale animations.
+            return;
+        }
+
         if (!mOnUpdateListeners.isEmpty()) {
             float currentWidth = Utilities.mapRange(mCurrentScaleProgress, mStartRect.width(),
                     mTargetRect.width());
@@ -229,7 +243,7 @@
     }
 
     private void maybeOnEnd() {
-        if (mAnimsStarted && mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded) {
+        if (mAnimsStarted && isEnded()) {
             mAnimsStarted = false;
             for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
                 animatorListener.onAnimationEnd(null);
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 5b3840f..6e21512 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -19,7 +19,6 @@
 import static com.android.launcher3.Utilities.getBadge;
 import static com.android.launcher3.Utilities.getFullDrawable;
 import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
-import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
 import android.animation.Animator;
@@ -100,6 +99,7 @@
 
     private AnimatorSet mFadeAnimatorSet;
     private ListenerView mListenerView;
+    private Runnable mFastFinishRunnable;
 
     public FloatingIconView(Context context) {
         this(context, null);
@@ -443,9 +443,21 @@
         }
     }
 
+    /**
+     * Sets a runnable that is called after a call to {@link #fastFinish()}.
+     */
+    public void setFastFinishRunnable(Runnable runnable) {
+        mFastFinishRunnable = runnable;
+    }
+
     public void fastFinish() {
+        if (mFastFinishRunnable != null) {
+            mFastFinishRunnable.run();
+            mFastFinishRunnable = null;
+        }
         if (mLoadIconSignal != null) {
             mLoadIconSignal.cancel();
+            mLoadIconSignal = null;
         }
         if (mEndRunnable != null) {
             mEndRunnable.run();
@@ -655,6 +667,7 @@
         sTmpObjArray[0] = null;
         mIconLoadResult = null;
         mClipIconView.recycle();
+        mFastFinishRunnable = null;
     }
 
     private static class IconLoadResult {