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

Commit 9fb47fba authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Avoid additional focus change when entering PiP from fullscreen

When entering PiP, the task will also be moved to top (from
onRootTaskWindowingModeChanged), and because the activity is
still fullscreen mode during animation, it will be detected as
focusable, that may cause additional focus change.

Also set defer-visibility-update if it is not called from a WCT,
which can reduce additional ensureActivitiesVisible
and resumeFocusedTasksTopActivities when setting the windowing
mode of task (Task#setWindowingModeInSurfaceTransaction). That
also avoid visibility and other states from being updated too
early before a series of PiP operations are done.

E.g.
 moveActivityToPinnedRootTask
   task.setWindowingMode(WINDOWING_MODE_PINNED)
     > ensureActivitiesVisible (can be omitted)
     > resumeFocusedTasksTopActivities (can be omitted)
   task.setBounds(bounds)
   task...
   ensureActivitiesVisible
   resumeFocusedTasksTopActivities

Note that if isPip2ExperimentEnabled() is true, it means that
moveActivityToPinnedRootTask is called from a WCT, and the WCT
should already use setDeferRootVisibilityUpdate. So the logic
of localVisibilityDeferred is the same as !isPip2ExperimentEnabled().

Bug: 307214895
Test: Swipe an immersive auto pip activity to home.
      The bar won't be flickering by changing focus from
      home->pip->home.
Change-Id: I3cb601c4f4c63e2b22e0413764d2eef53387232d
parent c9d20f37
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -2040,6 +2040,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>


        transitionController.deferTransitionReady();
        transitionController.deferTransitionReady();
        mService.deferWindowLayout();
        mService.deferWindowLayout();
        boolean localVisibilityDeferred = false;
        // If the caller is from WindowOrganizerController, it should be already deferred.
        if (!mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
            mTaskSupervisor.setDeferRootVisibilityUpdate(true);
            localVisibilityDeferred = true;
        }
        try {
        try {
            // This will change the root pinned task's windowing mode to its original mode, ensuring
            // This will change the root pinned task's windowing mode to its original mode, ensuring
            // we only have one root task that is in pinned mode.
            // we only have one root task that is in pinned mode.
@@ -2211,14 +2217,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
                mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
                        organizedTf);
                        organizedTf);
            }
            }

            if (taskDisplayArea.getFocusedRootTask() == rootTask) {
                taskDisplayArea.clearPreferredTopFocusableRootTask();
            }
        } finally {
        } finally {
            mService.continueWindowLayout();
            mService.continueWindowLayout();
            try {
            try {
                if (!isPip2ExperimentEnabled()) {
                if (localVisibilityDeferred) {
                    mTaskSupervisor.setDeferRootVisibilityUpdate(false);
                    ensureActivitiesVisible(null, 0, false /* preserveWindows */);
                    ensureActivitiesVisible(null, 0, false /* preserveWindows */);
                }
                }
            } finally {
            } finally {
+2 −1
Original line number Original line Diff line number Diff line
@@ -412,7 +412,8 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
        // wasContained} restricts the preferred root task is set only when moving an existing
        // wasContained} restricts the preferred root task is set only when moving an existing
        // root task to top instead of adding a new root task that may be too early (e.g. in the
        // root task to top instead of adding a new root task that may be too early (e.g. in the
        // middle of launching or reparenting).
        // middle of launching or reparenting).
        final boolean isTopFocusableTask = moveToTop && child.isTopActivityFocusable();
        final boolean isTopFocusableTask = moveToTop && child != mRootPinnedTask
                && child.isTopActivityFocusable();
        if (isTopFocusableTask) {
        if (isTopFocusableTask) {
            mPreferredTopFocusableRootTask =
            mPreferredTopFocusableRootTask =
                    child.shouldBeVisible(null /* starting */) ? child : null;
                    child.shouldBeVisible(null /* starting */) ? child : null;