Force finish any pending animations if the insets or orientation change

Some animation might be running from a previous orientation, which can cuase property changes
to get skipped.

Bug: 77848165
Bug: 77774619
Change-Id: I3e198196192746abdd72a1970ff2ef407bf4aff9
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ec0a8ff..5e06d92 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -360,7 +360,7 @@
             dispatchDeviceProfileChanged();
 
             getRootView().dispatchInsets();
-            getStateManager().reapplyState();
+            getStateManager().reapplyState(true /* cancelCurrentAnimation */);
 
             // Recreate touch controllers
             mDragLayer.setup(mDragController);
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index f204c16..ad1456a2 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -1,5 +1,8 @@
 package com.android.launcher3;
 
+import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
+import static com.android.launcher3.util.SystemUiController.UI_STATE_ROOT_VIEW;
+
 import android.annotation.TargetApi;
 import android.app.ActivityManager;
 import android.content.Context;
@@ -13,9 +16,6 @@
 
 import com.android.launcher3.util.Themes;
 
-import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
-import static com.android.launcher3.util.SystemUiController.UI_STATE_ROOT_VIEW;
-
 public class LauncherRootView extends InsettableFrameLayout {
 
     private final Launcher mLauncher;
@@ -82,7 +82,7 @@
             }
         }
         if (resetState) {
-            mLauncher.getStateManager().reapplyState();
+            mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
         }
 
         return true; // I'll take it from here
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index e611af7..d196c37 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -157,6 +157,13 @@
     }
 
     public void reapplyState() {
+        reapplyState(false);
+    }
+
+    public void reapplyState(boolean cancelCurrentAnimation) {
+        if (cancelCurrentAnimation) {
+            cancelAnimation();
+        }
         if (mConfig.mCurrentAnimation == null) {
             for (StateHandler handler : getStateHandlers()) {
                 handler.setState(mState);
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 087752d..1dba7d6 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -17,6 +17,7 @@
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
@@ -52,45 +53,37 @@
     private final long mDuration;
 
     protected final AnimatorSet mAnim;
-    private AnimatorSet mOriginalTarget;
 
     protected float mCurrentFraction;
     private Runnable mEndAction;
 
+    protected boolean mTargetCancelled = false;
+
     protected AnimatorPlaybackController(AnimatorSet anim, long duration) {
         mAnim = anim;
-        mOriginalTarget = mAnim;
         mDuration = duration;
 
         mAnimationPlayer = ValueAnimator.ofFloat(0, 1);
         mAnimationPlayer.setInterpolator(Interpolators.LINEAR);
         mAnimationPlayer.addListener(new OnAnimationEndDispatcher());
         mAnimationPlayer.addUpdateListener(this);
+
+        mAnim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                mTargetCancelled = true;
+            }
+        });
     }
 
     public AnimatorSet getTarget() {
         return mAnim;
     }
 
-    public void setOriginalTarget(AnimatorSet anim) {
-        mOriginalTarget = anim;
-    }
-
-    public AnimatorSet getOriginalTarget() {
-        return mOriginalTarget;
-    }
-
     public long getDuration() {
         return mDuration;
     }
 
-    public AnimatorPlaybackController cloneFor(AnimatorSet anim) {
-        AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(anim, mDuration);
-        controller.setOriginalTarget(mOriginalTarget);
-        controller.setPlayFraction(mCurrentFraction);
-        return controller;
-    }
-
     /**
      * Starts playing the animation forward from current position.
      */
@@ -206,6 +199,11 @@
         @Override
         public void setPlayFraction(float fraction) {
             mCurrentFraction = fraction;
+            // Let the animator report the progress but don't apply the progress to child
+            // animations if it has been cancelled.
+            if (mTargetCancelled) {
+                return;
+            }
             long playPos = clampDuration(fraction);
             for (ValueAnimator anim : mChildAnimations) {
                 anim.setCurrentPlayTime(Math.min(playPos, anim.getDuration()));
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index f1195ed..4c7ce1f 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -279,7 +279,7 @@
 
     @Override
     public void onAnimationCancel(Animator animation) {
-        if (mCurrentAnimation != null && animation == mCurrentAnimation.getOriginalTarget()) {
+        if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) {
             Log.e(TAG, "Who dare cancel the animation when I am in control", new Exception());
             clearState();
         }