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

Commit 97ec86e9 authored by Kazuki Takise's avatar Kazuki Takise
Browse files

Fix NPE in adding/removing presentation

In automated testing, there seem to be some cases where a new
transition gets created for a presentation but immediately gets
aborted without moving to the collecting state (e.g. when sysui
gets killed or crashed when running a test, in which case no
transition player exists).

This change adds a check whether a display of interest is newly
added in the collecting transition in this operation.

Flag: com.android.window.flags.enable_presentation_for_connected_displays
Bug: 404107800
Test: PresentationTest
Change-Id: Icea03ae491c77b0c7e642ca822372d9999ed6916
parent 6fcbeebd
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -512,9 +512,14 @@ class TransitionController {
        return false;
    }

    /** Returns {@code true} if the display contains a collecting transition. */
    boolean isCollectingTransitionOnDisplay(@NonNull DisplayContent dc) {
        return mCollectingTransition != null && mCollectingTransition.isOnDisplay(dc);
    }

    /** Returns {@code true} if the display contains a running or pending transition. */
    boolean isTransitionOnDisplay(@NonNull DisplayContent dc) {
        if (mCollectingTransition != null && mCollectingTransition.isOnDisplay(dc)) {
        if (isCollectingTransitionOnDisplay(dc)) {
            return true;
        }
        for (int i = mWaitingTransitions.size() - 1; i >= 0; --i) {
+13 −5
Original line number Diff line number Diff line
@@ -1845,9 +1845,12 @@ public class WindowManagerService extends IWindowManager.Stub
            // Only a presentation window needs a transition because its visibility affets the
            // lifecycle of apps below (b/390481865).
            if (enablePresentationForConnectedDisplays() && win.isPresentation()) {
                Transition transition = null;
                final boolean wasTransitionOnDisplay =
                        win.mTransitionController.isCollectingTransitionOnDisplay(displayContent);
                Transition newlyCreatedTransition = null;
                if (!win.mTransitionController.isCollecting()) {
                    transition = win.mTransitionController.createAndStartCollecting(TRANSIT_OPEN);
                    newlyCreatedTransition =
                            win.mTransitionController.createAndStartCollecting(TRANSIT_OPEN);
                }
                win.mTransitionController.collect(win.mToken);
                res |= addWindowInner(win, displayPolicy, activity, displayContent, outInsetsState,
@@ -1856,9 +1859,14 @@ public class WindowManagerService extends IWindowManager.Stub
                // A presentation hides all activities behind on the same display.
                win.mDisplayContent.ensureActivitiesVisible(/*starting=*/ null,
                        /*notifyClients=*/ true);
                win.mTransitionController.getCollectingTransition().setReady(win.mToken, true);
                if (transition != null) {
                    win.mTransitionController.requestStartTransition(transition, null,
                if (!wasTransitionOnDisplay && win.mTransitionController
                        .isCollectingTransitionOnDisplay(displayContent)) {
                    // Set the display ready only when the display gets added to the collecting
                    // transition in this operation.
                    win.mTransitionController.setReady(win.mToken);
                }
                if (newlyCreatedTransition != null) {
                    win.mTransitionController.requestStartTransition(newlyCreatedTransition, null,
                            null /* remoteTransition */, null /* displayChange */);
                }
            } else {
+13 −5
Original line number Diff line number Diff line
@@ -2359,9 +2359,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            // Only a presentation window needs a transition because its visibility affets the
            // lifecycle of apps below (b/390481865).
            if (enablePresentationForConnectedDisplays() && isPresentation()) {
                Transition transition = null;
                final boolean wasTransitionOnDisplay =
                        mTransitionController.isCollectingTransitionOnDisplay(displayContent);
                Transition newlyCreatedTransition = null;
                if (!mTransitionController.isCollecting()) {
                    transition = mTransitionController.createAndStartCollecting(TRANSIT_CLOSE);
                    newlyCreatedTransition =
                            mTransitionController.createAndStartCollecting(TRANSIT_CLOSE);
                }
                mTransitionController.collect(mToken);
                mAnimatingExit = true;
@@ -2370,9 +2373,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                // A presentation hides all activities behind on the same display.
                mDisplayContent.ensureActivitiesVisible(/*starting=*/ null,
                        /*notifyClients=*/ true);
                mTransitionController.getCollectingTransition().setReady(mToken, true);
                if (transition != null) {
                    mTransitionController.requestStartTransition(transition, null,
                if (!wasTransitionOnDisplay && mTransitionController
                        .isCollectingTransitionOnDisplay(displayContent)) {
                    // Set the display ready only when the display gets added to the collecting
                    // transition in this operation.
                    mTransitionController.setReady(mToken);
                }
                if (newlyCreatedTransition != null) {
                    mTransitionController.requestStartTransition(newlyCreatedTransition, null,
                            null /* remoteTransition */, null /* displayChange */);
                }
            } else {