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

Commit 4893b904 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Let the finishing transition commit the visibility

There may have visibility changes by WindowContainerTransaction
before calling Transition#finishTransition.

To make sure the visibility of transition participants can be
committed in Transition#finishTransition, if there is a request
to change activity visibility in a finishing transition, then
only set the requested visibility without commit.

Bug: 273440622
Test: atest TransitionTests#testTransientLaunch

Change-Id: I7517785795f43d5b8a2d1de54a95fbef1891ed41
parent 4489eec9
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -5263,15 +5263,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

        // Before setting mVisibleRequested so we can track changes.
        boolean isCollecting = false;
        boolean inFinishingTransition = false;
        if (mTransitionController.isShellTransitionsEnabled()) {
            isCollecting = mTransitionController.isCollecting();
            if (isCollecting) {
                mTransitionController.collect(this);
            } else {
                Slog.e(TAG, "setVisibility=" + visible + " while transition is not collecting "
                inFinishingTransition = mTransitionController.inFinishingTransition(this);
                if (!inFinishingTransition) {
                    Slog.e(TAG, "setVisibility=" + visible
                            + " while transition is not collecting or finishing "
                            + this + " caller=" + Debug.getCallers(8));
                }
            }
        }

        onChildVisibilityRequested(visible);

@@ -5346,6 +5351,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            }
            return;
        }
        if (inFinishingTransition) {
            // Let the finishing transition commit the visibility.
            return;
        }
        // If we are preparing an app transition, then delay changing
        // the visibility of this token until we execute that transition.
        if (deferCommitVisibilityChange(visible)) {
+3 −1
Original line number Diff line number Diff line
@@ -814,6 +814,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        if (mState < STATE_PLAYING) {
            throw new IllegalStateException("Can't finish a non-playing transition " + mSyncId);
        }
        mController.mFinishingTransition = this;

        boolean hasParticipatedDisplay = false;
        boolean hasVisibleTransientLaunch = false;
@@ -995,6 +996,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {

        // Handle back animation if it's already started.
        mController.mAtm.mBackNavigationController.handleDeferredBackAnimation(mTargets);
        mController.mFinishingTransition = null;
    }

    void abort() {
@@ -1274,7 +1276,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        if (mFinishTransaction != null) {
            mFinishTransaction.apply();
        }
        mController.finishTransition(mToken);
        mController.finishTransition(this);
    }

    private void cleanUpInternal() {
+12 −5
Original line number Diff line number Diff line
@@ -107,6 +107,9 @@ class TransitionController {
     */
    private final ArrayList<Transition> mPlayingTransitions = new ArrayList<>();

    /** The currently finishing transition. */
    Transition mFinishingTransition;

    /**
     * The windows that request to be invisible while it is in transition. After the transition
     * is finished and the windows are no longer animating, their surfaces will be destroyed.
@@ -313,6 +316,11 @@ class TransitionController {
        return false;
    }

    /** Returns {@code true} if the `wc` is a participant of the finishing transition. */
    boolean inFinishingTransition(WindowContainer<?> wc) {
        return mFinishingTransition != null && mFinishingTransition.mParticipants.contains(wc);
    }

    /** @return {@code true} if a transition is running */
    boolean inTransition() {
        // TODO(shell-transitions): eventually properly support multiple
@@ -672,14 +680,13 @@ class TransitionController {
    }

    /** @see Transition#finishTransition */
    void finishTransition(@NonNull IBinder token) {
    void finishTransition(Transition record) {
        // It is usually a no-op but make sure that the metric consumer is removed.
        mTransitionMetricsReporter.reportAnimationStart(token, 0 /* startTime */);
        mTransitionMetricsReporter.reportAnimationStart(record.getToken(), 0 /* startTime */);
        // It is a no-op if the transition did not change the display.
        mAtm.endLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
        final Transition record = Transition.fromBinder(token);
        if (record == null || !mPlayingTransitions.contains(record)) {
            Slog.e(TAG, "Trying to finish a non-playing transition " + token);
        if (!mPlayingTransitions.contains(record)) {
            Slog.e(TAG, "Trying to finish a non-playing transition " + record);
            return;
        }
        ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Finish Transition: %s", record);
+6 −1
Original line number Diff line number Diff line
@@ -391,9 +391,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                // apply the incoming transaction before finish in case it alters the visibility
                // of the participants.
                if (t != null) {
                    // Set the finishing transition before applyTransaction so the visibility
                    // changes of the transition participants will only set visible-requested
                    // and still let finishTransition handle the participants.
                    mTransitionController.mFinishingTransition = transition;
                    applyTransaction(t, syncId, null /*transition*/, caller, transition);
                }
                getTransitionController().finishTransition(transitionToken);
                mTransitionController.finishTransition(transition);
                mTransitionController.mFinishingTransition = null;
                if (syncId >= 0) {
                    setSyncReady(syncId);
                }
+14 −2
Original line number Diff line number Diff line
@@ -1391,7 +1391,7 @@ public class TransitionTests extends WindowTestsBase {

        verify(snapshotController, times(1)).recordSnapshot(eq(task2), eq(false));

        openTransition.finishTransition();
        controller.finishTransition(openTransition);

        // We are now going to simulate closing task1 to return back to (open) task2.
        final Transition closeTransition = controller.createTransition(TRANSIT_CLOSE);
@@ -1416,7 +1416,19 @@ public class TransitionTests extends WindowTestsBase {
        verify(snapshotController, times(0)).recordSnapshot(eq(task1), eq(false));

        enteringAnimReports.clear();
        closeTransition.finishTransition();
        final boolean[] wasInFinishingTransition = { false };
        controller.registerLegacyListener(new WindowManagerInternal.AppTransitionListener() {
            @Override
            public void onAppTransitionFinishedLocked(IBinder token) {
                final ActivityRecord r = ActivityRecord.forToken(token);
                if (r != null) {
                    wasInFinishingTransition[0] = controller.inFinishingTransition(r);
                }
            }
        });
        controller.finishTransition(closeTransition);
        assertTrue(wasInFinishingTransition[0]);
        assertNull(controller.mFinishingTransition);

        assertEquals(ActivityTaskManagerService.APP_SWITCH_DISALLOW, mAtm.getBalAppSwitchesState());
        assertFalse(activity1.app.hasActivityInVisibleTask());
Loading