Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8698cfba authored by Shan Huang's avatar Shan Huang
Browse files

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
parent 7c093004
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -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;
        }
+6 −1
Original line number Diff line number Diff line
@@ -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();