Fix back to home animation restarts on a second swipe.
If a second swipe starts before a back to home animation finishes, it's possible for subsequent MOVE events to start another back animation. The fix is to only start back animation when the swipe's DOWN event is not rejected. Bug: 240109403 Fixes: 240109403 Test: Follow repro steps in 240109403#10 and make sure a second animation cannot be started. Test: BackAnimationControllerTest Change-Id: Id2a5fb00f632fb9be175ef10cad7fea511d09ae0
This commit is contained in:
@@ -97,6 +97,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
|
||||
/** Tracks if an uninterruptible transition is in progress */
|
||||
private boolean mTransitionInProgress = false;
|
||||
/** Tracks if we should start the back gesture on the next motion move event */
|
||||
private boolean mShouldStartOnNextMoveEvent = false;
|
||||
/** @see #setTriggerBack(boolean) */
|
||||
private boolean mTriggerBack;
|
||||
|
||||
@@ -286,12 +288,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
if (mTransitionInProgress) {
|
||||
return;
|
||||
}
|
||||
if (keyAction == MotionEvent.ACTION_MOVE) {
|
||||
if (keyAction == MotionEvent.ACTION_DOWN) {
|
||||
if (!mBackGestureStarted) {
|
||||
mShouldStartOnNextMoveEvent = true;
|
||||
}
|
||||
} else if (keyAction == MotionEvent.ACTION_MOVE) {
|
||||
if (!mBackGestureStarted && mShouldStartOnNextMoveEvent) {
|
||||
// Let the animation initialized here to make sure the onPointerDownOutsideFocus
|
||||
// could be happened when ACTION_DOWN, it may change the current focus that we
|
||||
// would access it when startBackNavigation.
|
||||
onGestureStarted(touchX, touchY);
|
||||
mShouldStartOnNextMoveEvent = false;
|
||||
}
|
||||
onMove(touchX, touchY, swipeEdge);
|
||||
} else if (keyAction == MotionEvent.ACTION_UP || keyAction == MotionEvent.ACTION_CANCEL) {
|
||||
@@ -425,6 +432,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
|
||||
private void onGestureFinished(boolean fromTouch) {
|
||||
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "onGestureFinished() mTriggerBack == %s", mTriggerBack);
|
||||
if (!mBackGestureStarted) {
|
||||
finishAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fromTouch) {
|
||||
// Let touch reset the flag otherwise it will start a new back navigation and refresh
|
||||
// the info when received a new move event.
|
||||
@@ -540,6 +552,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
boolean triggerBack = mTriggerBack;
|
||||
mBackNavigationInfo = null;
|
||||
mTriggerBack = false;
|
||||
mShouldStartOnNextMoveEvent = false;
|
||||
if (backNavigationInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -272,9 +272,14 @@ public class BackAnimationControllerTest extends ShellTestCase {
|
||||
// the previous transition is finished.
|
||||
doMotionEvent(MotionEvent.ACTION_DOWN, 0);
|
||||
verifyNoMoreInteractions(mIOnBackInvokedCallback);
|
||||
mController.onBackToLauncherAnimationFinished();
|
||||
|
||||
// Verify that more events from a rejected swipe cannot start animation.
|
||||
doMotionEvent(MotionEvent.ACTION_MOVE, 100);
|
||||
doMotionEvent(MotionEvent.ACTION_UP, 0);
|
||||
verifyNoMoreInteractions(mIOnBackInvokedCallback);
|
||||
|
||||
// Verify that we start accepting gestures again once transition finishes.
|
||||
mController.onBackToLauncherAnimationFinished();
|
||||
doMotionEvent(MotionEvent.ACTION_DOWN, 0);
|
||||
doMotionEvent(MotionEvent.ACTION_MOVE, 100);
|
||||
verify(mIOnBackInvokedCallback).onBackStarted();
|
||||
|
||||
Reference in New Issue
Block a user