summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2023-10-26 15:46:05 +0800
committer Riddle Hsu <riddlehsu@google.com> 2023-10-30 10:43:57 +0000
commit9fb47fbafce7ce638581e294bde483e80190ce9e (patch)
treebef9637d44cd3f91a70b7d6955b621446e9c514e
parentc9d20f37276dbdedbe6579f2e0be02eece55996f (diff)
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
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java13
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java3
2 files changed, 10 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 7a442e708130..a2aea27614c9 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2040,6 +2040,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
transitionController.deferTransitionReady();
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 {
// 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.
@@ -2211,14 +2217,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
organizedTf);
}
-
- if (taskDisplayArea.getFocusedRootTask() == rootTask) {
- taskDisplayArea.clearPreferredTopFocusableRootTask();
- }
} finally {
mService.continueWindowLayout();
try {
- if (!isPip2ExperimentEnabled()) {
+ if (localVisibilityDeferred) {
+ mTaskSupervisor.setDeferRootVisibilityUpdate(false);
ensureActivitiesVisible(null, 0, false /* preserveWindows */);
}
} finally {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index ae794a89480a..f0a66540061d 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -412,7 +412,8 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
// 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
// middle of launching or reparenting).
- final boolean isTopFocusableTask = moveToTop && child.isTopActivityFocusable();
+ final boolean isTopFocusableTask = moveToTop && child != mRootPinnedTask
+ && child.isTopActivityFocusable();
if (isTopFocusableTask) {
mPreferredTopFocusableRootTask =
child.shouldBeVisible(null /* starting */) ? child : null;