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

Commit d217a53b authored by wilsonshih's avatar wilsonshih Committed by Android Build Coastguard Worker
Browse files

[PB] Always cleanup fixed rotation when finish predictive back animation

Always reset FixedRotationLaunchingApp when finish animation.
Also, if animation target is for predictive back, ignore
dispatchLegacyAppTransitionFinished which will reset the
mLauncherTaskBehind, so core won't trigger configuration change twice
due to ensureActivitiesVisible happen before global configuration
change.

Flag: EXEMPT bugfix
Bug: 347497084
Test: atest BackNavigationControllerTests BackGestureInvokedTest
Test: verify fixed rotation will be reset after every type of animation
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0654191f7a8f669a2a018387cf50dac3db99be40)
Merged-In: I10012d558f3c302f90129a3df72f568fa5795651
Change-Id: I10012d558f3c302f90129a3df72f568fa5795651
parent 200b35ad
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -256,7 +256,8 @@ public class AppTransitionController {
            tmpCloseApps = new ArraySet<>(mDisplayContent.mClosingApps);
            if (mDisplayContent.mAtmService.mBackNavigationController
                    .removeIfContainsBackAnimationTargets(tmpOpenApps, tmpCloseApps)) {
                mDisplayContent.mAtmService.mBackNavigationController.clearBackAnimations();
                mDisplayContent.mAtmService.mBackNavigationController
                        .clearBackAnimations(false /* cancel */);
            }
        }

+35 −35
Original line number Diff line number Diff line
@@ -751,7 +751,7 @@ class BackNavigationController {
                mObserver.sendResult(null /* result */);
            }
            if (isMonitorAnimationOrTransition()) {
                clearBackAnimations();
                clearBackAnimations(true /* cancel */);
            }
            cancelPendingAnimation();
        }
@@ -843,24 +843,23 @@ class BackNavigationController {
     * Cleanup animation, this can either happen when legacy transition ready, or when the Shell
     * transition finish.
     */
    void clearBackAnimations() {
        mAnimationHandler.clearBackAnimateTarget();
    void clearBackAnimations(boolean cancel) {
        mAnimationHandler.clearBackAnimateTarget(cancel);
        mNavigationMonitor.stopMonitorTransition();
        mWaitTransitionFinish = null;
    }

    /**
     * Called when a transition finished.
     * Handle the pending animation when the running transition finished.
     * Handle the pending animation when the running transition finished, all the visibility change
     * has applied so ready to start pending predictive back animation.
     * @param targets The final animation targets derived in transition.
     * @param finishedTransition The finished transition target.
    */
    void onTransitionFinish(ArrayList<Transition.ChangeInfo> targets,
            @NonNull Transition finishedTransition) {
        if (finishedTransition == mWaitTransitionFinish) {
            clearBackAnimations();
            clearBackAnimations(false /* cancel */);
        }

        if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) {
            return;
        }
@@ -994,7 +993,7 @@ class BackNavigationController {
            mCloseAdaptor = createAdaptor(close, false, mSwitchType);
            if (mCloseAdaptor.mAnimationTarget == null) {
                Slog.w(TAG, "composeNewAnimations fail, skip");
                clearBackAnimateTarget();
                clearBackAnimateTarget(true /* cancel */);
                return;
            }

@@ -1013,7 +1012,7 @@ class BackNavigationController {
            mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(true, mSwitchType, open);
            if (!mOpenAnimAdaptor.isValid()) {
                Slog.w(TAG, "compose animations fail, skip");
                clearBackAnimateTarget();
                clearBackAnimateTarget(true /* cancel */);
                return;
            }
            mOpenActivities = openingActivities;
@@ -1025,7 +1024,7 @@ class BackNavigationController {
                Slog.e(TAG, "Previous animation is running " + this);
                return false;
            }
            clearBackAnimateTarget();
            clearBackAnimateTarget(true /* cancel */);
            if (close == null || open == null || open.length == 0 || open.length > 2) {
                Slog.e(TAG, "reset animation with null target close: "
                        + close + " open: " + Arrays.toString(open));
@@ -1114,7 +1113,19 @@ class BackNavigationController {
            return false;
        }

        void finishPresentAnimations() {
        void finishPresentAnimations(boolean cancel) {
            if (mOpenActivities != null) {
                for (int i = mOpenActivities.length - 1; i >= 0; --i) {
                    final ActivityRecord resetActivity = mOpenActivities[i];
                    if (resetActivity.mDisplayContent.isFixedRotationLaunchingApp(resetActivity)) {
                        resetActivity.mDisplayContent
                                .continueUpdateOrientationForDiffOrienLaunchingApp();
                    }
                    if (resetActivity.mLaunchTaskBehind) {
                        restoreLaunchBehind(resetActivity, cancel);
                    }
                }
            }
            if (mCloseAdaptor != null) {
                mCloseAdaptor.mTarget.cancelAnimation();
                mCloseAdaptor = null;
@@ -1123,15 +1134,6 @@ class BackNavigationController {
                mOpenAnimAdaptor.cleanUp(mStartingSurfaceTargetMatch);
                mOpenAnimAdaptor = null;
            }

            if (mOpenActivities != null) {
                for (int i = mOpenActivities.length - 1; i >= 0; --i) {
                    final ActivityRecord resetActivity = mOpenActivities[i];
                    if (resetActivity.mLaunchTaskBehind) {
                        restoreLaunchBehind(resetActivity);
                    }
                }
            }
        }

        void markStartingSurfaceMatch(SurfaceControl.Transaction reparentTransaction) {
@@ -1142,10 +1144,10 @@ class BackNavigationController {
            mOpenAnimAdaptor.reparentWindowlessSurfaceToTarget(reparentTransaction);
        }

        void clearBackAnimateTarget() {
        void clearBackAnimateTarget(boolean cancel) {
            if (mComposed) {
                mComposed = false;
                finishPresentAnimations();
                finishPresentAnimations(cancel);
            }
            mWaitTransition = false;
            mStartingSurfaceTargetMatch = false;
@@ -1661,7 +1663,7 @@ class BackNavigationController {
                                return;
                            }
                            if (!triggerBack) {
                                clearBackAnimateTarget();
                                clearBackAnimateTarget(true /* cancel */);
                            } else {
                                mWaitTransition = true;
                            }
@@ -1744,25 +1746,23 @@ class BackNavigationController {
                true /* notifyClients */);
    }

    private static void restoreLaunchBehind(@NonNull ActivityRecord activity) {
    private static void restoreLaunchBehind(@NonNull ActivityRecord activity, boolean cancel) {
        if (!activity.isAttached()) {
            // The activity was detached from hierarchy.
            return;
        }

        if (activity.mDisplayContent.isFixedRotationLaunchingApp(activity)) {
            activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
        }

        // Restore the launch-behind state.
        activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
        activity.mLaunchTaskBehind = false;
        // Ignore all change
        activity.mTransitionController.mSnapshotController
                .mActivitySnapshotController.clearOnBackPressedActivities();
        ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
                "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
                activity);
        if (cancel) {
            // Restore the launch-behind state
            // TODO b/347168362 Change status directly during collecting for a transition.
            activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
            // Ignore all change
            activity.mTransitionController.mSnapshotController
                    .mActivitySnapshotController.clearOnBackPressedActivities();
        }
    }

    void checkAnimationReady(WallpaperController wallpaperController) {
@@ -1782,7 +1782,7 @@ class BackNavigationController {
        if (!mBackAnimationInProgress) {
            // gesture is already finished, do not start animation
            if (mPendingAnimation != null) {
                clearBackAnimations();
                clearBackAnimations(true /* cancel */);
                mPendingAnimation = null;
            }
            return;
+6 −2
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;

import android.annotation.IntDef;
@@ -1195,7 +1197,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            throw new IllegalStateException("Can't finish a non-playing transition " + mSyncId);
        }
        mController.mFinishingTransition = this;

        if (mTransientHideTasks != null && !mTransientHideTasks.isEmpty()) {
            // The transient hide tasks could be occluded now, e.g. returning to home. So trigger
            // the update to make the activities in the tasks invisible-requested, then the next
@@ -1380,7 +1381,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            // If the activity was just inserted to an invisible task, it will keep INITIALIZING
            // state. Then no need to notify the callback to avoid clearing some states
            // unexpectedly, e.g. launch-task-behind.
            if (ar.isVisibleRequested() || !ar.isState(ActivityRecord.State.INITIALIZING)) {
            // However, skip dispatch to predictive back animation target, because it only set
            // launch-task-behind to make the activity become visible.
            if ((ar.isVisibleRequested() || !ar.isState(ActivityRecord.State.INITIALIZING))
                    && !ar.isAnimating(PARENTS, ANIMATION_TYPE_PREDICT_BACK)) {
                mController.dispatchLegacyAppTransitionFinished(ar);
            }

+14 −10
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {

        // reset drawing status to test translucent activity
        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        final ActivityRecord topActivity = topTask.getTopMostActivity();
        makeWindowVisibleAndDrawn(topActivity.findMainWindow());
        // simulate translucent
@@ -170,7 +170,8 @@ public class BackNavigationControllerTests extends WindowTestsBase {

        // reset drawing status to test if previous task is translucent activity
        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        makeWindowVisibleAndDrawn(topActivity.findMainWindow());
        // simulate translucent
        recordA.setOccludesParent(false);
        backNavigationInfo = startBackNavigation();
@@ -181,7 +182,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {
        topActivity.setOccludesParent(true);
        recordA.setOccludesParent(true);
        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        makeWindowVisibleAndDrawn(topActivity.findMainWindow());
        setupKeyguardOccluded();
        backNavigationInfo = startBackNavigation();
@@ -189,7 +190,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {
                .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK));

        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        doReturn(true).when(recordA).canShowWhenLocked();
        backNavigationInfo = startBackNavigation();
        assertThat(typeToString(backNavigationInfo.getType()))
@@ -248,7 +249,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {
        // reset drawing status
        testCase.recordBack.setState(STOPPED, "stopped");
        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        makeWindowVisibleAndDrawn(testCase.recordFront.findMainWindow());
        setupKeyguardOccluded();
        backNavigationInfo = startBackNavigation();
@@ -257,7 +258,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {

        // reset drawing status, test if top activity is translucent
        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        makeWindowVisibleAndDrawn(testCase.recordFront.findMainWindow());
        // simulate translucent
        testCase.recordFront.setOccludesParent(false);
@@ -268,7 +269,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {

        // reset drawing status, test if bottom activity is translucent
        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        makeWindowVisibleAndDrawn(testCase.recordBack.findMainWindow());
        // simulate translucent
        testCase.recordBack.setOccludesParent(false);
@@ -279,7 +280,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {

        // reset drawing status, test canShowWhenLocked
        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);
        doReturn(true).when(testCase.recordBack).canShowWhenLocked();
        backNavigationInfo = startBackNavigation();
        assertThat(typeToString(backNavigationInfo.getType()))
@@ -482,7 +483,10 @@ public class BackNavigationControllerTests extends WindowTestsBase {
                .isEqualTo(typeToString(BackNavigationInfo.TYPE_RETURN_TO_HOME));

        backNavigationInfo.onBackNavigationFinished(false);
        mBackNavigationController.clearBackAnimations();
        mBackNavigationController.clearBackAnimations(true);

        final WindowState window = topTask.getTopVisibleAppMainWindow();
        makeWindowVisibleAndDrawn(window);
        setupKeyguardOccluded();
        backNavigationInfo = startBackNavigation();
        assertThat(typeToString(backNavigationInfo.getType()))
@@ -842,7 +846,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {
        toHomeBuilder.build();
        verify(mAtm.mTaskOrganizerController, never()).addWindowlessStartingSurface(
                any(), any(), any(), any(), any(), any());
        animationHandler.clearBackAnimateTarget();
        animationHandler.clearBackAnimateTarget(true);
        openActivities.clear();

        // Back to ACTIVITY and TASK have the same logic, just with different target.