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

Commit b6ea0ff3 authored by Arthur Hung's avatar Arthur Hung Committed by Android (Google) Code Review
Browse files

Merge "Fix back animation doesn't work when triggered a second time" into udc-dev

parents a38aeb81 708287bc
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -561,6 +561,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        }
        if (runner.isWaitingAnimation()) {
            ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready.");
            // Supposed it is in post commit animation state, and start the timeout to watch
            // if the animation is ready.
            mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION);
            return;
        } else if (runner.isAnimationCancelled()) {
            invokeOrCancelBack();
@@ -577,6 +580,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        if (mPostCommitAnimationInProgress) {
            return;
        }

        mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable);
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: startPostCommitAnimation()");
        mPostCommitAnimationInProgress = true;
        mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION);
@@ -595,9 +600,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
     */
    @VisibleForTesting
    void onBackAnimationFinished() {
        if (!mPostCommitAnimationInProgress) {
            return;
        }
        // Stop timeout runner.
        mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable);
        mPostCommitAnimationInProgress = false;
+16 −0
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ public class BackAnimationControllerTest extends ShellTestCase {
        doMotionEvent(MotionEvent.ACTION_DOWN, 0);
        doMotionEvent(MotionEvent.ACTION_MOVE, 0);
        mController.setTriggerBack(true);
    }

    private void releaseBackGesture() {
        doMotionEvent(MotionEvent.ACTION_UP, 0);
    }

@@ -201,6 +204,8 @@ public class BackAnimationControllerTest extends ShellTestCase {
                    .setOnBackNavigationDone(new RemoteCallback(result)));
            triggerBackGesture();
            simulateRemoteAnimationStart(type);
            mShellExecutor.flushAll();
            releaseBackGesture();
            simulateRemoteAnimationFinished();
            mShellExecutor.flushAll();

@@ -252,6 +257,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, false);

        triggerBackGesture();
        releaseBackGesture();

        verify(mAppCallback, times(1)).onBackInvoked();

@@ -269,6 +275,8 @@ public class BackAnimationControllerTest extends ShellTestCase {

        triggerBackGesture();
        simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME);
        releaseBackGesture();

        // Check that back invocation is dispatched.
        verify(mAnimatorCallback).onBackInvoked();
        verify(mBackAnimationRunner).onAnimationStart(anyInt(), any(), any(), any(), any());
@@ -308,6 +316,9 @@ public class BackAnimationControllerTest extends ShellTestCase {

        triggerBackGesture();
        simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME);
        mShellExecutor.flushAll();

        releaseBackGesture();

        // Simulate transition timeout.
        mShellExecutor.flushAll();
@@ -369,6 +380,9 @@ public class BackAnimationControllerTest extends ShellTestCase {
            simulateRemoteAnimationStart(type);
            mShellExecutor.flushAll();

            releaseBackGesture();
            mShellExecutor.flushAll();

            assertTrue("Navigation Done callback not called for "
                    + BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
            assertTrue("TriggerBack should have been true", result.mTriggerBack);
@@ -395,6 +409,8 @@ public class BackAnimationControllerTest extends ShellTestCase {
                .setOnBackNavigationDone(new RemoteCallback(result)));
        triggerBackGesture();
        mShellExecutor.flushAll();
        releaseBackGesture();
        mShellExecutor.flushAll();

        assertTrue("Navigation Done callback not called for "
                + BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
+24 −16
Original line number Diff line number Diff line
@@ -648,31 +648,28 @@ class BackNavigationController {
        if (finishedTransition == mWaitTransitionFinish) {
            clearBackAnimations();
        }

        if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) {
            return false;
        }

        ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
                "Handling the deferred animation after transition finished");

        // Show the target surface and its parents to prevent it or its parents hidden when
        // the transition finished.
        // The target could be affected by transition when :
        // Open transition -> the open target in back navigation
        // Close transition -> the close target in back navigation.
        // Find the participated container collected by transition when :
        // Open transition -> the open target in back navigation, the close target in transition.
        // Close transition -> the close target in back navigation, the open target in transition.
        boolean hasTarget = false;
        final SurfaceControl.Transaction t =
                mPendingAnimationBuilder.mCloseTarget.getPendingTransaction();
        for (int i = 0; i < targets.size(); i++) {
            final WindowContainer wc = targets.get(i).mContainer;
            if (wc.asActivityRecord() == null && wc.asTask() == null) {
                continue;
            } else if (!mPendingAnimationBuilder.containTarget(wc)) {
        for (int i = 0; i < finishedTransition.mParticipants.size(); i++) {
            final WindowContainer wc = finishedTransition.mParticipants.valueAt(i);
            if (wc.asActivityRecord() == null && wc.asTask() == null
                    && wc.asTaskFragment() == null) {
                continue;
            }

            if (mPendingAnimationBuilder.containTarget(wc)) {
                hasTarget = true;
            t.show(wc.getSurfaceControl());
                break;
            }
        }

        if (!hasTarget) {
@@ -689,6 +686,12 @@ class BackNavigationController {
            return false;
        }

        // Ensure the final animation targets which hidden by transition could be visible.
        for (int i = 0; i < targets.size(); i++) {
            final WindowContainer wc = targets.get(i).mContainer;
            wc.prepareSurfaces();
        }

        scheduleAnimation(mPendingAnimationBuilder);
        mPendingAnimationBuilder = null;
        return true;
@@ -1076,7 +1079,7 @@ class BackNavigationController {

            boolean containTarget(@NonNull WindowContainer wc) {
                return wc == mOpenTarget || wc == mCloseTarget
                        || wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget);
                        || mOpenTarget.hasChild(wc) || mCloseTarget.hasChild(wc);
            }

            /**
@@ -1151,6 +1154,11 @@ class BackNavigationController {
    private static void setLaunchBehind(@NonNull ActivityRecord activity) {
        if (!activity.isVisibleRequested()) {
            activity.setVisibility(true);
            // The transition could commit the visibility and in the finishing state, that could
            // skip commitVisibility call in setVisibility cause the activity won't visible here.
            // Call it again to make sure the activity could be visible while handling the pending
            // animation.
            activity.commitVisibility(true, true);
        }
        activity.mLaunchTaskBehind = true;