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
This commit is contained in:
Louis Chang
2021-07-05 11:52:27 +08:00
parent 4718d33ee0
commit be3d9a3bde
4 changed files with 23 additions and 3 deletions

View File

@@ -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.
*

View File

@@ -1973,7 +1973,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
*/
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
if (mTaskSupervisor.inActivityVisibilityUpdate()) {
if (mTaskSupervisor.inActivityVisibilityUpdate()
|| mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
// Don't do recursive work.
return;
}

View File

@@ -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() {

View File

@@ -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();
}
}