From be3d9a3bde16692b812e4196e8bf37be25ef2517 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Mon, 5 Jul 2021 11:52:27 +0800 Subject: [PATCH] Deferring visibility updates while applying WCT The activity was relaunched twice when applying a WCT. The first relaunch was due to windowing mode changes. The second relaunch was due to orientation changes. The issue was observed on freeform display when moving the freeform tasks into split-screen. The orientation of the freefrom tasks were changed from landscape to portrait when entering split-screen, which caused the activity relaunch second time. Deferring the visibility updates while applying WCT and just do it once (if needed) after all of the changes in the WCT are done. Bug: 191891601 Test: atest ActivityLifecycleLegacySplitScreenTests Change-Id: I9a09e11c0ce87a2454a38cf9305f0f15d5399390 --- .../android/server/wm/ActivityTaskSupervisor.java | 14 ++++++++++++++ .../com/android/server/wm/RootWindowContainer.java | 3 ++- services/core/java/com/android/server/wm/Task.java | 6 ++++-- .../server/wm/WindowOrganizerController.java | 3 +++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 08bca353f910d..74efe0c7422f4 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -347,6 +347,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { */ private int mVisibilityTransactionDepth; + /** + * Whether to the visibility updates that started from {@code RootWindowContainer} should be + * deferred. + */ + private boolean mDeferRootVisibilityUpdate; + private ActivityMetricsLogger mActivityMetricsLogger; /** Check if placing task or activity on specified display is allowed. */ @@ -2263,6 +2269,14 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { return mVisibilityTransactionDepth > 0; } + void setDeferRootVisibilityUpdate(boolean deferUpdate) { + mDeferRootVisibilityUpdate = deferUpdate; + } + + boolean isRootVisibilityUpdateDeferred() { + return mDeferRootVisibilityUpdate; + } + /** * Called when the state or visibility of an attached activity is changed. * diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 539bea2faef91..0b80bae71ab83 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -1973,7 +1973,8 @@ class RootWindowContainer extends WindowContainer */ void ensureActivitiesVisible(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { - if (mTaskSupervisor.inActivityVisibilityUpdate()) { + if (mTaskSupervisor.inActivityVisibilityUpdate() + || mTaskSupervisor.isRootVisibilityUpdateDeferred()) { // Don't do recursive work. return; } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 88c082146d369..c803f06840d09 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -4500,8 +4500,10 @@ class Task extends TaskFragment { mAtmService.continueWindowLayout(); } - mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); - mRootWindowContainer.resumeFocusedTasksTopActivities(); + if (!mTaskSupervisor.isRootVisibilityUpdateDeferred()) { + mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); + mRootWindowContainer.resumeFocusedTasksTopActivities(); + } } void resumeNextFocusAfterReparent() { diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index b82819c8396eb..eeb83c66ce2bf 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -275,6 +275,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub int effects = 0; ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); mService.deferWindowLayout(); + mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */); try { if (transition != null) { // First check if we have a display rotation transition and if so, update it. @@ -363,6 +364,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub task.setMainWindowSizeChangeTransaction(sft); } if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) { + mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */); // Already calls ensureActivityConfig mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); mService.mRootWindowContainer.resumeFocusedTasksTopActivities(); @@ -384,6 +386,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mService.addWindowLayoutReasons(LAYOUT_REASON_CONFIG_CHANGED); } } finally { + mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */); mService.continueWindowLayout(); } }