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

Commit 8f8802fd authored by Hongwei Wang's avatar Hongwei Wang
Browse files

Reset state on aborted PiP transition

When a resize PiP transition is aborted, the PipTransitionState is left
in SCHEDULED_BOUNDS_CHANGE state and touches would be disabled, i.e. PiP
window is not interactable.

Fix the issue by advancing to CHANGED_BOUNDS state if we detect such
scenario. Moving forward, we should think about other PiP transitions
being aborted, like when in ENTERING_PIP or SWIPING_PIP states.

Added also logs for PipTransitionState#setState

Flag: com.android.wm.shell.enable_pip2
Bug: 407961511
Video: http://recall/-/aaaaaabFQoRHlzixHdtY/ccPLyTWRVRM7TBKy0EPtOI
Test: Tap QSB and screen off immediately, with active PiP, see Video
Test: atest WMShellUnitTests:PipTransitionStateTest
Change-Id: I2e3969172115f4927474f3f7753d8c1c613aeaf2
parent 76765bb4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -398,6 +398,12 @@ public abstract class PipTransitionController implements Transitions.TransitionH
    public void finishTransition() {
    }

    /**
     * Callback when the transition is aborted.
     */
    public void onTransitionAborted() {
    }

    /**
     * End the currently-playing PiP animation.
     *
+24 −1
Original line number Diff line number Diff line
@@ -281,7 +281,11 @@ public class PipTransition extends PipTransitionController implements

    @Override
    public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
            @Nullable SurfaceControl.Transaction finishT) {}
            @Nullable SurfaceControl.Transaction finishT) {
        if (transition == mBoundsChangeTransition && aborted) {
            onTransitionAborted();
        }
    }

    @Override
    public boolean startAnimation(@NonNull IBinder transition,
@@ -1032,6 +1036,25 @@ public class PipTransition extends PipTransitionController implements
        }
    }

    @Override
    public void onTransitionAborted() {
        final int currentState = mPipTransitionState.getState();
        int nextState = PipTransitionState.UNDEFINED;
        switch (currentState) {
            case PipTransitionState.SCHEDULED_BOUNDS_CHANGE:
                nextState = PipTransitionState.CHANGED_PIP_BOUNDS;
                break;
        }

        if (nextState == PipTransitionState.UNDEFINED) {
            Log.wtf(TAG, String.format("""
                        PipTransitionState resolved to an undefined state in abortTransition().
                        callers=%s""", Debug.getCallers(4)));
        }

        mPipTransitionState.setState(nextState);
    }

    @Override
    public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState,
            @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) {
+4 −1
Original line number Diff line number Diff line
@@ -203,6 +203,9 @@ public class PipTransitionState {
     * @param extra a bundle passed to the subscribed listeners to resolve/cache extra info.
     */
    public void setState(@TransitionState int state, @Nullable Bundle extra) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s setState from=%s to=%s",
                TAG, stateToString(mState), stateToString(state));
        if (state == ENTERING_PIP || state == SWIPING_TO_PIP
                || state == SCHEDULED_BOUNDS_CHANGE || state == CHANGING_PIP_BOUNDS) {
            // States listed above require extra bundles to be provided.
@@ -425,8 +428,8 @@ public class PipTransitionState {
            case CHANGED_PIP_BOUNDS: return "changed-bounds";
            case EXITING_PIP: return "exiting-pip";
            case EXITED_PIP: return "exited-pip";
            default: return "custom-state(" + state + ")";
        }
        throw new IllegalStateException("Unknown state: " + state);
    }

    public boolean isPipStateIdle() {