From 742313e4c3e406c8a3aedb8310e208ad0b01764c Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 5 May 2020 17:20:32 +0800 Subject: [PATCH 1/3] Do not capture task snapshot with fixed rotated activity Because the rotation of activity and task are different, The information of snapshot may be inconsistent. And since it is a temporal state, in most cases the snapshot is available after the fixed rotation is cleared. This fixes a non-rotated snapshot is shown on a rotated activity when repeating launch and swipe to home quickly. Also the fixed rotation launching app should not be cleared if there is pending rotation, otherwise it is too early that the display is still in old rotation. This fixes flickering when switching between activities in different rotation from quickstep. Bug: 155862858 Test: atest TaskSnapshotControllerTest#testPrepareTaskSnapshot ActivityRecordTests#testActivityOnCancelFixedRotationTransform Change-Id: I8e30e87ea4aad907c4ad4338b91fcff3078380ad --- .../java/com/android/server/wm/DisplayContent.java | 4 ++++ .../android/server/wm/TaskSnapshotController.java | 7 +++++++ .../com/android/server/wm/ActivityRecordTests.java | 4 ++++ .../server/wm/TaskSnapshotControllerTest.java | 12 ++++++++++-- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 6655e92634e4c..b11502db5a535 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1511,6 +1511,10 @@ class DisplayContent extends WindowContainer Date: Wed, 13 May 2020 01:07:33 +0800 Subject: [PATCH 2/3] Only use snapshot starting window for the same rotation So the snapshot won't show half if the its has a delta of 90 degree rotation with the actual activity. If the snapshot is not compatible with the activity, the starting window type will be splash screen. Bug: 155862858 Test: atest ActivityRecordTests#testIsSnapshotCompatible Change-Id: I8d8a926d057f1d18d028fcc03bddbb17ffbbf96b --- .../com/android/server/wm/ActivityRecord.java | 31 +++++++++++-------- .../server/wm/ActivityStackSupervisor.java | 2 +- .../server/wm/ActivityTaskManagerService.java | 7 ++--- .../com/android/server/wm/DisplayContent.java | 18 ++++++----- .../server/wm/ActivityRecordTests.java | 27 ++++++++++++++++ .../server/wm/AppWindowTokenTests.java | 18 +++++------ 6 files changed, 68 insertions(+), 35 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index d177c12362e8c..35cb8f906b41d 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1705,7 +1705,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags, IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning, - boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) { + boolean allowTaskSnapshot, boolean activityCreated) { // If the display is frozen, we won't do anything until the actual window is // displayed so there is no reason to put in the starting window. if (!okToDisplay()) { @@ -1726,7 +1726,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mWmService.mTaskSnapshotController.getSnapshot(task.mTaskId, task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); final int type = getStartingWindowType(newTask, taskSwitch, processRunning, - allowTaskSnapshot, activityCreated, fromRecents, snapshot); + allowTaskSnapshot, activityCreated, snapshot); if (type == STARTING_WINDOW_TYPE_SNAPSHOT) { if (isActivityTypeHome()) { @@ -1888,12 +1888,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private final AddStartingWindow mAddStartingWindow = new AddStartingWindow(); private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning, - boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents, + boolean allowTaskSnapshot, boolean activityCreated, ActivityManager.TaskSnapshot snapshot) { if (newTask || !processRunning || (taskSwitch && !activityCreated)) { return STARTING_WINDOW_TYPE_SPLASH_SCREEN; } else if (taskSwitch && allowTaskSnapshot) { - if (snapshotOrientationSameAsTask(snapshot) || (snapshot != null && fromRecents)) { + if (isSnapshotCompatible(snapshot)) { return STARTING_WINDOW_TYPE_SNAPSHOT; } if (!isActivityTypeHome()) { @@ -1905,11 +1905,22 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } - private boolean snapshotOrientationSameAsTask(ActivityManager.TaskSnapshot snapshot) { + /** + * Returns {@code true} if the task snapshot is compatible with this activity (at least the + * rotation must be the same). + */ + @VisibleForTesting + boolean isSnapshotCompatible(ActivityManager.TaskSnapshot snapshot) { if (snapshot == null) { return false; } - return task.getConfiguration().orientation == snapshot.getOrientation(); + final int rotation = mDisplayContent.rotationForActivityInDifferentOrientation(this); + final int targetRotation = rotation != ROTATION_UNDEFINED + // The display may rotate according to the orientation of this activity. + ? rotation + // The activity won't change display orientation. + : task.getWindowConfiguration().getRotation(); + return snapshot.getRotation() == targetRotation; } void removeStartingWindow() { @@ -5664,11 +5675,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) { - showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */); - } - - void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch, - boolean fromRecents) { if (mTaskOverlay) { // We don't show starting window for overlay activities. return; @@ -5685,8 +5691,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags, prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(), allowTaskSnapshot(), - mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(), - fromRecents); + mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal()); if (shown) { mStartingWindowState = STARTING_WINDOW_SHOWN; } diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 3e7e0c8b936d3..62979ffc4a8cc 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -2498,7 +2498,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mActivityMetricsLogger.notifyActivityLaunching(task.intent); try { mService.moveTaskToFrontLocked(null /* appThread */, null /* callingPackage */, - task.mTaskId, 0, options, true /* fromRecents */); + task.mTaskId, 0, options); // Apply options to prevent pendingOptions be taken by client to make sure // the override pending app transition will be applied immediately. targetActivity.applyOptionsLocked(); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index f21ec6b0e5ccf..7e974608f9b7e 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -2476,13 +2476,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId); synchronized (mGlobalLock) { moveTaskToFrontLocked(appThread, callingPackage, taskId, flags, - SafeActivityOptions.fromBundle(bOptions), false /* fromRecents */); + SafeActivityOptions.fromBundle(bOptions)); } } void moveTaskToFrontLocked(@Nullable IApplicationThread appThread, - @Nullable String callingPackage, int taskId, int flags, SafeActivityOptions options, - boolean fromRecents) { + @Nullable String callingPackage, int taskId, int flags, SafeActivityOptions options) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); assertPackageMatchesCallingUid(callingPackage); @@ -2527,7 +2526,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // We are reshowing a task, use a starting window to hide the initial draw delay // so the transition can start earlier. topActivity.showStartingWindow(null /* prev */, false /* newTask */, - true /* taskSwitch */, fromRecents); + true /* taskSwitch */); } } finally { Binder.restoreCallingIdentity(origId); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index b11502db5a535..d0f7021f7e96b 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -235,7 +235,6 @@ class DisplayContent extends WindowContainer Date: Wed, 13 May 2020 01:50:17 +0800 Subject: [PATCH 3/3] Apply fixed rotation when showing snapshot starting window Unlike splash screen starting window that inherits the size of activity directly, task snapshot needs the final size to draw right after adding to display. Otherwise the content will look like as cropped because the surface size uses different orientation. And because starting window is added before executing transition, assume there will have transition if the owner of starting window is also the top activity. Bug: 155862858 Test: ActivityRecordTests#testFixedRotationSnapshotStartingWindow Change-Id: Idb4f9a92a6e2594356416afd0ab6360e94e66497 --- .../com/android/server/wm/DisplayContent.java | 44 ++++++++++-------- .../server/wm/TaskSnapshotSurface.java | 10 ++++ .../server/wm/ActivityRecordTests.java | 46 +++++++++++++++++++ 3 files changed, 80 insertions(+), 20 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index d0f7021f7e96b..3acb127673e97 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1393,17 +1393,18 @@ class DisplayContent extends WindowContainer