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

Commit 177bed05 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Block startSwipePipToHome if entry was scheduled

Generally, Launcher's AbsSwipeUpHandler checks whether
there is a PiP present when deciding whether to block
startSwipePipToHome call to get entry bounds. But sometimes
the Binder call might get through if the entry is scheduled or
even as the animation is running, since TaskStackListener updates
Launcher uses are out-of-sync from Transitions updates.

So if startSwipePipToHome() arrives into PipController, make sure
to return null bounds after verifying that we are not indeed past PiP
entry scheduling stage, so that AbsSwipeUpHandler bails early after the
synchronous Binder call returns.

Note: repro-ing the issue is quite hard, but blocking
startSwipePipToHome at this point also means
reparentChildSurfaceToTask() never gets routed to PipTaskListener which
was the root of the crash we ave been seeing reported.

Bug: 432684815
Flag: EXEMPT bugfix
Test: swipe-up to PiP as soon as app directly enters PiP
Change-Id: I2838366fafbea3641378e2d6c27b9e710fe31075
parent d02ea380
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -453,7 +453,7 @@ public class PipController implements ConfigurationChangeListener,
            mPipDisplayLayoutState.rotateTo(toRotation);
        }

        if (!shouldUpdatePipStateOnDisplayChange()) {
        if (!mPipTransitionState.isInPip() && !mPipTransitionState.isEnterPipScheduled()) {
            // Skip the PiP-relevant updates if we aren't in a valid PiP state.
            if (mPipTransitionState.isInFixedRotation()) {
                ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
@@ -543,14 +543,6 @@ public class PipController implements ConfigurationChangeListener,
        mPipDisplayLayoutState.setDisplayLayout(layout);
    }

    private boolean shouldUpdatePipStateOnDisplayChange() {
        // We should at least update internal PiP state, such as PiP bounds state or movement bounds
        // if we are either in PiP or about to enter PiP.
        return mPipTransitionState.isInPip()
                || mPipTransitionState.getState() == PipTransitionState.ENTERING_PIP
                || mPipTransitionState.getState() == PipTransitionState.SCHEDULED_ENTER_PIP;
    }

    //
    // IPip Binder stub helpers
    //
@@ -560,6 +552,15 @@ public class PipController implements ConfigurationChangeListener,
            int launcherRotation, Rect hotseatKeepClearArea) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "getSwipePipToHomeBounds: %s", componentName);
        if (mPipTransitionState.isInPip() || mPipTransitionState.isEnterPipScheduled()) {
            // Launcher might sometimes be unaware that we have scheduled PiP entry already,
            // so make sure swipe-pip-to-home does not go through in case Launcher still requests
            // entry destination bounds from Shell.
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "Launcher attempted to swipe-pip-to-home while already in PiP"
                            + " or about to enter PiP");
            return null;
        }

        // If PiP is enabled on Connected Displays, update PipDisplayLayoutState to have the correct
        // display info that PiP is entering in.
+9 −0
Original line number Diff line number Diff line
@@ -333,6 +333,15 @@ public class PipTransitionState {
        return mState > ENTERING_PIP && mState < EXITING_PIP;
    }

    /**
     * @return true if we have either scheduled enter PiP or are animating the entering.
     */
    public boolean isEnterPipScheduled() {
        return mState == PipTransitionState.ENTERING_PIP
                || mState == PipTransitionState.SCHEDULED_ENTER_PIP;
    }


    void setSwipePipToHomeState(@Nullable SurfaceControl overlayLeash,
            @NonNull Rect appBounds) {
        mInSwipePipToHomeTransition = true;