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

Commit ef72e86c authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Revert^2 "Bunlde ClientTransactionItems when enter/exit PiP"

This reverts commit a5dca25e.

Enter PiP:
When changing the top activity from fullscreen to pip, the next
activity can be resumed by the same window transaction.

Exit PiP:
ResumeActivityItem and ActivityConfigurationChangeItem will be
bundled. In other words, the pip activity will be resumed before
the animation starts. Note that pip2 won't need this logic because
WOC#applyChanges already adds TRANSACT_EFFECTS_LIFECYCLE if task
windowing mode is changed to non-pip.

Bug: 333452456
Flag: com.android.window.flags.apply_lifecycle_on_pip_change
Test: atest WindowOrganizerTests#testResumeTopsWhenLeavingPinned
Test: adb shell setprop persist.wm.debug.apply_lifecycle_on_pip_change 1
      Expand pip, both the pip activity and task will become
      fullscreen windowing mode before the animation starts.
      And then TRANSACT_EFFECTS_LIFECYCLE will resume the pip
      because there is a windowing mode change on task.

Change-Id: I610ca30fd3068a3e400d176e7e9f3dbe014139b9
parent 56b9b7a3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -18,6 +18,16 @@ flag {
    }
}

flag {
    name: "apply_lifecycle_on_pip_change"
    namespace: "windowing_frontend"
    description: "Make pip activity lifecyle change with windowing mode"
    bug: "333452456"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "blast_sync_notification_shade_on_display_switch"
    namespace: "windowing_frontend"
+25 −9
Original line number Diff line number Diff line
@@ -878,15 +878,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub

        final int childWindowingMode = c.getActivityWindowingMode();
        if (!ActivityTaskManagerService.isPip2ExperimentEnabled()
                && tr.getWindowingMode() == WINDOWING_MODE_PINNED
                && (childWindowingMode == WINDOWING_MODE_PINNED
                || childWindowingMode == WINDOWING_MODE_UNDEFINED)) {
                && tr.getWindowingMode() == WINDOWING_MODE_PINNED) {
            if (childWindowingMode == WINDOWING_MODE_PINNED
                    || childWindowingMode == WINDOWING_MODE_UNDEFINED) {
                // If setActivityWindowingMode requested to match its pinned task's windowing mode,
                // remove any inconsistency checking timeout callbacks for PiP.
                Slog.d(TAG, "Task and activity windowing modes match, so remove any timeout "
                        + "abort PiP callbacks scheduled if needed; task_win_mode="
                        + tr.getWindowingMode() + ", activity_win_mode=" + childWindowingMode);
                mService.mRootWindowContainer.removeAllMaybeAbortPipEnterRunnable();
            } else if (shouldApplyLifecycleEffectOnPipChange()) {
                // This is leaving PiP: task is pinned mode and activity changes to non-pip mode.
                // Then the activity can be resumed because it becomes focusable.
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
            }
        }
        if (childWindowingMode > -1) {
            tr.forAllActivities(a -> { a.setWindowingMode(childWindowingMode); });
@@ -911,6 +916,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                if (canEnterPip) {
                    canEnterPip = mService.mActivityClientController
                            .requestPictureInPictureMode(activity);
                    if (canEnterPip && shouldApplyLifecycleEffectOnPipChange()) {
                        effects |= TRANSACT_EFFECTS_LIFECYCLE;
                    }
                }
                if (!canEnterPip) {
                    // Restore the flag to its previous state when the activity cannot enter PIP.
@@ -922,6 +930,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        return effects;
    }

    // TODO(b/333452456): For testing on local easier. Remove after the use case is gone.
    @VisibleForTesting
    static boolean shouldApplyLifecycleEffectOnPipChange() {
        return android.os.SystemProperties.getBoolean(
                "persist.wm.debug.apply_lifecycle_on_pip_change", false)
                || com.android.window.flags.Flags.applyLifecycleOnPipChange();
    }

    private int applyDisplayAreaChanges(DisplayArea displayArea,
            WindowContainerTransaction.Change c) {
        final int[] effects = new int[1];
+25 −10
Original line number Diff line number Diff line
@@ -1725,26 +1725,41 @@ public class WindowOrganizerTests extends WindowTestsBase {
        assertTrue(optionsCaptor.getValue().getOriginalOptions().getTransientLaunch());
    }

    @SuppressWarnings("GuardedBy")
    @Test
    public void testResumeTopsWhenLeavingPinned() {
        final ActivityRecord record = makePipableActivity();
        final Task rootTask = record.getRootTask();
        final ActivityRecord home = new ActivityBuilder(mAtm).setTask(
                mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask()).build();
        final Task homeTask = home.getTask();
        final ActivityRecord pipActivity = makePipableActivity();

        clearInvocations(mWm.mAtmService.mRootWindowContainer);
        final WindowContainerTransaction t = new WindowContainerTransaction();
        WindowContainerToken wct = rootTask.mRemoteToken.toWindowContainerToken();
        t.setWindowingMode(wct, WINDOWING_MODE_PINNED);
        t.setWindowingMode(pipActivity.getTask().mRemoteToken.toWindowContainerToken(),
                WINDOWING_MODE_PINNED);
        clearInvocations(homeTask);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
        if (WindowOrganizerController.shouldApplyLifecycleEffectOnPipChange()) {
            verify(homeTask).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
        } else {
            verify(homeTask, never()).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
        }

        // Undo the effect of legacy logic in RootWindowContainer#moveActivityToPinnedRootTask.
        if (pipActivity.mWaitForEnteringPinnedMode) {
            pipActivity.mWaitForEnteringPinnedMode = false;
            pipActivity.setWindowingMode(WINDOWING_MODE_UNDEFINED);
        }
        assertFalse(pipActivity.isFocusable());

        clearInvocations(mWm.mAtmService.mRootWindowContainer);
        // The token for the PIP root task may have changed when the task entered PIP mode, so do
        // not reuse the one from above.
        final WindowContainerToken newToken =
                record.getRootTask().mRemoteToken.toWindowContainerToken();
        final Task pipTask = pipActivity.getTask();
        final WindowContainerToken newToken = pipTask.mRemoteToken.toWindowContainerToken();
        t.setWindowingMode(newToken, WINDOWING_MODE_FULLSCREEN);
        clearInvocations(pipTask);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
        assertTrue(pipActivity.isFocusable());
        verify(pipTask).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
    }

    @Test