From 22f8ad0dc07c2f0d41ed518502173346764d0919 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 18 Apr 2022 18:17:28 -0700 Subject: [PATCH] Set mState = mCurrentStableState in onAnimationCancel() Context: there was a bug where you could get stuck in HintState if you did the following (timing is critical): 1. Short swipe from nav region towards HintState, but not far enough or fast enough to commit before letting go; this cancels the state animation, returning towards Normal (but, crucially, StateManager still has state set as Hint) 2. While previous animation is animating back to Normal, swipe up again, but this time faster/farther to actually reach Hint; this time, the animation does go towards Hint, but gets stuck there. The reason it gets stuck is because StateManager thinks we're already in Hint from step 1, so doesn't call onStateTransitionEnd(Hint) in step 2. Thus, we never get QuickstepLauncher#onStateSetEnd(Hint), which is what we rely on to return to Normal. Fix is to have StateManager change its internal state to mCurrentStableState (the state the transition started from) if the animation is canceled. (Also need to keep that state if restarting the animation, which AbstractStateChangeTouchController does in onDragEnd, regardless of whether it ends up going to mFromState or mToState.) Test: short swipe followed immediately by fast fling from nav region on home successfully goes to HintState and back to Normal Fixes: 228276181 Change-Id: I2e3aeac06d482b57729416d5de55cc6ffc9df23c --- .../android/launcher3/anim/AnimationSuccessListener.java | 3 +++ src/com/android/launcher3/statemanager/StateManager.java | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/anim/AnimationSuccessListener.java b/src/com/android/launcher3/anim/AnimationSuccessListener.java index a312070e58..6196df23ed 100644 --- a/src/com/android/launcher3/anim/AnimationSuccessListener.java +++ b/src/com/android/launcher3/anim/AnimationSuccessListener.java @@ -19,6 +19,8 @@ package com.android.launcher3.anim; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import androidx.annotation.CallSuper; + /** * Extension of {@link AnimatorListenerAdapter} for listening for non-cancelled animations */ @@ -27,6 +29,7 @@ public abstract class AnimationSuccessListener extends AnimatorListenerAdapter { protected boolean mCancelled = false; @Override + @CallSuper public void onAnimationCancel(Animator animation) { mCancelled = true; } diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java index 1767939114..691d4dff66 100644 --- a/src/com/android/launcher3/statemanager/StateManager.java +++ b/src/com/android/launcher3/statemanager/StateManager.java @@ -335,7 +335,13 @@ public class StateManager> { @Override public void onAnimationStart(Animator animation) { // Change the internal state only when the transition actually starts - onStateTransitionStart(state); + onStateTransitionStart(mCancelled ? mCurrentStableState : state); + } + + @Override + public void onAnimationCancel(Animator animation) { + super.onAnimationCancel(animation); + mState = mCurrentStableState; } @Override