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

Commit 36951b97 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Implement auto-enter PiP2 in gesture nav [4/N]

When auto-entering PiP through gesture navigation
directly start a TRANSIT_PIP transition in
RecentsController#finishInner().

Merge the finishWCT meant for finishTransition()
into TRANSIT_PIP's startWCT instead to make sure
all the visibility updates are made after moving
the activity to a pinned root task as a hierarchy-op.

This would also make sure that setConfigAtEnd() properly
pauses the PiP activity's config updates since at first
after startTransition() its state would be RESUMED and
isVisibilityRequested=true.
moveActivityToPinnedRootTask() makes sure the state becomes
PAUSING (if not done by startPausing already in Recents transition).
This is followed by an already present call to schedulePauseActivity().

Eventually, the activity remains in PAUSED state
as enforced by the CTS tests.

Bug: 325481148
Test: manually swipe up auto-enter PiP
Change-Id: I58d330e816101da7bcf328b9dccf092f2bdd99cb
parent 63112b5b
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -87,6 +87,19 @@ public final class WindowContainerTransaction implements Parcelable {
        return out;
    }

    /**
     * Clear the transaction object.
     * This is equivalent to a new empty {@link WindowContainerTransaction} in content.
     *
     * @hide
     */
    public void clear() {
        mChanges.clear();
        mHierarchyOps.clear();
        mErrorCallbackToken = null;
        mTaskFragmentOrganizer = null;
    }

    /**
     * Resize a container.
     */
+1 −1
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ public class PipTransition extends PipTransitionController {
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        if (transition == mEnterTransition) {
        if (transition == mEnterTransition || info.getType() == TRANSIT_PIP) {
            mEnterTransition = null;
            if (mPipScheduler.isInSwipePipToHomeTransition()) {
                // If this is the second transition as a part of swipe PiP to home cuj,
+28 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
@@ -59,6 +60,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.IResultReceiver;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.sysui.ShellInit;
@@ -1023,13 +1025,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
                }
                if (mPipTransaction != null && sendUserLeaveHint) {
                    SurfaceControl pipLeash = null;
                    TransitionInfo.Change pipChange = null;
                    if (mPipTask != null) {
                        pipLeash = mInfo.getChange(mPipTask).getLeash();
                        pipChange = mInfo.getChange(mPipTask);
                        pipLeash = pipChange.getLeash();
                    } else if (mPipTaskId != -1) {
                        // find a task with taskId from #setFinishTaskTransaction()
                        for (TransitionInfo.Change change : mInfo.getChanges()) {
                            if (change.getTaskInfo() != null
                                    && change.getTaskInfo().taskId == mPipTaskId) {
                                pipChange = change;
                                pipLeash = change.getLeash();
                                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                                        "RecentsController.finishInner:"
@@ -1048,6 +1053,28 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                                "RecentsController.finishInner: PiP transaction %s merged",
                                mPipTransaction);
                        if (PipUtils.isPip2ExperimentEnabled()) {
                            // If this path is triggered, we are in auto-enter PiP flow in gesture
                            // navigation mode, which means "Recents" transition should be followed
                            // by a TRANSIT_PIP. Hence, we take the WCT was about to be sent
                            // to Core to be applied during finishTransition(), we modify it to
                            // factor in PiP changes, and we send it as a direct startWCT for
                            // a new TRANSIT_PIP type transition. Recents still sends
                            // finishTransition() to update visibilities, but with finishWCT=null.
                            TransitionRequestInfo requestInfo = new TransitionRequestInfo(
                                    TRANSIT_PIP, null /* triggerTask */, pipChange.getTaskInfo(),
                                    null /* remote */, null /* displayChange */, 0 /* flags */);
                            // Use mTransition IBinder token temporarily just to get PipTransition
                            // to return from its handleRequest(). The actual TRANSIT_PIP will have
                            // anew token once it arrives into PipTransition#startAnimation().
                            Pair<Transitions.TransitionHandler, WindowContainerTransaction>
                                    requestRes = mTransitions.dispatchRequest(mTransition,
                                            requestInfo, null /* skip */);
                            wct.merge(requestRes.second, true);
                            mTransitions.startTransition(TRANSIT_PIP, wct, null /* handler */);
                            // We need to clear the WCT to send finishWCT=null for Recents.
                            wct.clear();
                        }
                    }
                    mPipTaskId = -1;
                    mPipTask = null;
+1 −0
Original line number Diff line number Diff line
@@ -1312,6 +1312,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
                pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
                        + supportsEnterPipOnTaskSwitch);
                pw.println(prefix + "mPauseSchedulePendingForPip=" + mPauseSchedulePendingForPip);
            }
            if (getMaxAspectRatio() != 0) {
                pw.println(prefix + "maxAspectRatio=" + getMaxAspectRatio());
+9 −8
Original line number Diff line number Diff line
@@ -3732,16 +3732,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            return false;
        }

        // If PiP2 flag is on and client-request to enter PiP comes in,
        // we request a direct transition from Shell to TRANSIT_PIP to get the startWct
        // with the right entry bounds. So PiP activity isn't moved to a pinned task until after
        // Shell calls back into Core with the entry bounds passed through.
        if (isPip2ExperimentEnabled()) {
            final Transition legacyEnterPipTransition = new Transition(TRANSIT_PIP,
            // If PiP2 flag is on and request to enter PiP comes in,
            // we request a direct transition TRANSIT_PIP from Shell to get the right entry bounds.
            // So PiP activity isn't moved to a pinned task until after
            // Shell calls back into Core with the entry bounds to be applied with startWCT.
            final Transition enterPipTransition = new Transition(TRANSIT_PIP,
                    0 /* flags */, getTransitionController(), mWindowManager.mSyncEngine);
            legacyEnterPipTransition.setPipActivity(r);
            getTransitionController().startCollectOrQueue(legacyEnterPipTransition, (deferred) -> {
                getTransitionController().requestStartTransition(legacyEnterPipTransition,
            enterPipTransition.setPipActivity(r);
            r.mAutoEnteringPip = isAutoEnter;
            getTransitionController().startCollectOrQueue(enterPipTransition, (deferred) -> {
                getTransitionController().requestStartTransition(enterPipTransition,
                        r.getTask(), null /* remoteTransition */, null /* displayChange */);
            });
            return true;
Loading