Fix issues with starting new recents animation before previous onRecentsAnimationStart

- Fix logic for canceling animation for continued quick switch, so that this case (starting a new gesture before onRecentsAnimationStart() of the previous gesture) instead goes to the STATE_FINISH_WITH_NO_END flow.
- Update the end target so that we go to that state instead of always overview state if swipe was past the halfway threshold when we call endLauncherTransitionController(). This is specifically so we don't use OverviewInputConsumer on the second gesture, given the first one was canceled and didn't actually go to overview.
- GestureState#isRecentsAnimationRunning() now checks for STATE_RECENTS_ANIMATION_STARTED rather than _INITIALIZED, to be consistent with its javadoc and TaskAnimationManager#isRecentsAnimationRunning(). This also ensures we can correctly calculate continued quick switch (see above).
- Call cleanUpRecentsAnimation() before creating a new one in TaskAnimationManager. This ensures that the previous listener doesn't immediately cleanup the new gesture when it gets onRecentsAnimationCanceled() due to the new recents animation starting.

Test: swipe to home twice from the app, locally ignoring the onRecentsAnimationStart() from the first one, and ensure the second one responds normally
Bug: 193851085
Change-Id: I76e27c96b54293805546c0d6c82e77f975c69d7a
Merged-In: I76e27c96b54293805546c0d6c82e77f975c69d7a
(cherry picked from commit 66ed0ff23e)
This commit is contained in:
Tony Wickham 2021-10-05 17:55:22 -07:00
parent 3e39786ec3
commit ee24e46a61
4 changed files with 26 additions and 6 deletions

View File

@ -976,6 +976,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
isFling, isCancel);
// Set the state, but don't notify until the animation completes
mGestureState.setEndTarget(endTarget, false /* isAtomic */);
mAnimationFactory.setEndTarget(endTarget);
float endShift = endTarget.isLauncher ? 1 : 0;
final float startShift;
@ -1360,7 +1361,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mActivity.clearRunOnceOnStartCallback();
resetLauncherListeners();
}
if (mGestureState.getEndTarget() != null && !mGestureState.isRunningAnimationToLauncher()) {
if (mGestureState.isRecentsAnimationRunning() && mGestureState.getEndTarget() != null
&& !mGestureState.getEndTarget().isLauncher) {
// Continued quick switch.
cancelCurrentAnimation();
} else {
mStateCallback.setStateOnUiThread(STATE_FINISH_WITH_NO_END);

View File

@ -77,12 +77,14 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
public final boolean rotationSupportedByActivity;
private final STATE_TYPE mOverviewState, mBackgroundState;
private final STATE_TYPE mBackgroundState;
private STATE_TYPE mTargetState;
protected BaseActivityInterface(boolean rotationSupportedByActivity,
STATE_TYPE overviewState, STATE_TYPE backgroundState) {
this.rotationSupportedByActivity = rotationSupportedByActivity;
mOverviewState = overviewState;
mTargetState = overviewState;
mBackgroundState = backgroundState;
}
@ -399,6 +401,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
default boolean isRecentsAttachedToAppWindow() {
return false;
}
/** Called when the gesture ends and we know what state it is going towards */
default void setEndTarget(GestureState.GestureEndTarget endTarget) { }
}
class DefaultAnimationFactory implements AnimationFactory {
@ -435,7 +440,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
// Since we are changing the start position of the UI, reapply the state, at the end
controller.setEndAction(() -> mActivity.getStateManager().goToState(
controller.getInterpolatedProgress() > 0.5 ? mOverviewState : mBackgroundState,
controller.getInterpolatedProgress() > 0.5 ? mTargetState : mBackgroundState,
false));
RecentsView recentsView = mActivity.getOverviewPanel();
@ -490,6 +495,11 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
return mIsAttachedToWindow;
}
@Override
public void setEndTarget(GestureState.GestureEndTarget endTarget) {
mTargetState = stateFromGestureEndTarget(endTarget);
}
protected void createBackgroundToOverviewAnim(ACTIVITY_TYPE activity, PendingAnimation pa) {
// Scale down recents from being full screen to being in overview.
RecentsView recentsView = activity.getOverviewPanel();

View File

@ -346,8 +346,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
* @return whether the recents animation is started but not yet ended
*/
public boolean isRecentsAnimationRunning() {
return mStateCallback.hasStates(STATE_RECENTS_ANIMATION_INITIALIZED) &&
!mStateCallback.hasStates(STATE_RECENTS_ANIMATION_ENDED);
return mStateCallback.hasStates(STATE_RECENTS_ANIMATION_STARTED)
&& !mStateCallback.hasStates(STATE_RECENTS_ANIMATION_ENDED);
}
@Override

View File

@ -106,6 +106,13 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
// But force-finish it anyways
finishRunningRecentsAnimation(false /* toHome */);
if (mCallbacks != null) {
// If mCallbacks still != null, that means we are getting this startRecentsAnimation()
// before the previous one got onRecentsAnimationStart(). In that case, cleanup the
// previous animation so it doesn't mess up/listen to state changes in this animation.
cleanUpRecentsAnimation();
}
final BaseActivityInterface activityInterface = gestureState.getActivityInterface();
mLastGestureState = gestureState;
mCallbacks = new RecentsAnimationCallbacks(activityInterface.allowMinimizeSplitScreen());