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

Commit f4c7e72d authored by Chris Li's avatar Chris Li
Browse files

Bunlde ClientTransactionItems when enter/exit PiP

Enter PiP:

After this CL, PauseActivityItem, TopResumedActivityChangeItem, and
WindowStateResizeItem will be bundled.

However, ActivityConfigurationChangeItem will not.

This is because the ActivityRecord will become unfocusable when
mWaitForEnteringPinnedMode is set, and pause the PiP activity, while the
bounds and windowing mode will be updated after the enter PiP
transition.
Also, the PipStateTransactionItem will come from a separate IPC call
from WM Shell.

Exit PiP:

After this CL, ResumeActivityItem and ActivityConfigurationChangeItem
will be bundled.

Bug: 333452456
Test: manually verify enter/exit PiP
Change-Id: I462f58fc05d4bb63155bc9e1c88414e6801a66be
parent c1a0024a
Loading
Loading
Loading
Loading
+19 −11
Original line number Diff line number Diff line
@@ -3778,6 +3778,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                }
                EventLogTags.writeWmEnterPip(r.mUserId, System.identityHashCode(r),
                        r.shortComponentName, Boolean.toString(isAutoEnter));

                // Ensure the ClientTransactionItems are bundled for this operation.
                deferWindowLayout();
                try {
                    r.setPictureInPictureParams(params);
                    r.mAutoEnteringPip = isAutoEnter;
                    mRootWindowContainer.moveActivityToPinnedRootTask(r,
@@ -3786,9 +3790,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    // Continue the pausing process after entering pip.
                    if (r.isState(PAUSING) && r.mPauseSchedulePendingForPip) {
                        r.getTask().schedulePauseActivity(r, false /* userLeaving */,
                            false /* pauseImmediately */, true /* autoEnteringPip */, "auto-pip");
                                false /* pauseImmediately */, true /* autoEnteringPip */,
                                "auto-pip");
                    }
                    r.mAutoEnteringPip = false;
                } finally {
                    continueWindowLayout();
                }
            }
        };

+8 −0
Original line number Diff line number Diff line
@@ -2380,6 +2380,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            return false;
        }

        return resumeFocusedTasksTopActivitiesUnchecked(targetRootTask, target, targetOptions,
                deferPause);
    }

    @VisibleForTesting
    boolean resumeFocusedTasksTopActivitiesUnchecked(
            Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
            boolean deferPause) {
        boolean result = false;
        if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                || getTopDisplayFocusedRootTask() == targetRootTask)) {
+22 −5
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
import static com.android.server.wm.ActivityRecord.State.PAUSING;
import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;
import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
@@ -828,18 +829,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
    }

    private int applyTaskChanges(Task tr, WindowContainerTransaction.Change c) {
        final boolean wasPrevFocusableAndVisible = tr.isFocusableAndVisible();

        int effects = applyChanges(tr, c);
        final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();

        if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) {
            if (tr.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, c.getHidden())) {
                effects = TRANSACT_EFFECTS_LIFECYCLE;
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
            }
        }

        if ((c.getChangeMask() & CHANGE_FORCE_TRANSLUCENT) != 0) {
            tr.setForceTranslucent(c.getForceTranslucent());
            effects = TRANSACT_EFFECTS_LIFECYCLE;
            effects |= TRANSACT_EFFECTS_LIFECYCLE;
        }

        if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_DRAG_RESIZING) != 0) {
@@ -872,8 +875,17 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                boolean canEnterPip = activity.checkEnterPictureInPictureState(
                        "applyTaskChanges", true /* beforeStopping */);
                if (canEnterPip) {
                    mService.mTaskSupervisor.beginDeferResume();
                    try {
                        canEnterPip = mService.mActivityClientController
                                .requestPictureInPictureMode(activity);
                    } finally {
                        mService.mTaskSupervisor.endDeferResume();
                        if (canEnterPip && !isPip2ExperimentEnabled()) {
                            // Wait until the transaction is applied to only resume once.
                            effects |= TRANSACT_EFFECTS_LIFECYCLE;
                        }
                    }
                }
                if (!canEnterPip) {
                    // Restore the flag to its previous state when the activity cannot enter PIP.
@@ -882,6 +894,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
            }
        }

        // Activity in this Task may resume/pause when enter/exit pip.
        if (wasPrevFocusableAndVisible != tr.isFocusableAndVisible()) {
            effects |= TRANSACT_EFFECTS_LIFECYCLE;
        }

        return effects;
    }

@@ -947,7 +964,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        }
        if ((c.getChangeMask() & CHANGE_FORCE_TRANSLUCENT) != 0) {
            taskFragment.setForceTranslucent(c.getForceTranslucent());
            effects = TRANSACT_EFFECTS_LIFECYCLE;
            effects |= TRANSACT_EFFECTS_LIFECYCLE;
        }

        effects |= applyChanges(taskFragment, c);
+4 −2
Original line number Diff line number Diff line
@@ -1681,7 +1681,8 @@ public class WindowOrganizerTests extends WindowTestsBase {
        WindowContainerToken wct = rootTask.mRemoteToken.toWindowContainerToken();
        t.setWindowingMode(wct, WINDOWING_MODE_PINNED);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivitiesUnchecked(any(),
                any(), any(), anyBoolean());

        clearInvocations(mWm.mAtmService.mRootWindowContainer);
        // The token for the PIP root task may have changed when the task entered PIP mode, so do
@@ -1690,7 +1691,8 @@ public class WindowOrganizerTests extends WindowTestsBase {
                record.getRootTask().mRemoteToken.toWindowContainerToken();
        t.setWindowingMode(newToken, WINDOWING_MODE_FULLSCREEN);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivitiesUnchecked(any(),
                any(), any(), anyBoolean());
    }

    @Test