From 041a5abbd5ac8b0d279cde5e330dd4e56ab1b4d1 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 18 May 2023 21:16:53 +0800 Subject: [PATCH] Skip snapshot task when finishing activity for shell transition With shell transition, the snapshot from ActivityRecord#finishIfPossible is always replaced by Transition#onTransactionReady -> TaskSnapshotController#recordSnapshot And because currently SnapshotController#onTransitionReady is a dead code so the task added by addSkipClosingAppSnapshotTasks won't be cleared. So the duplicated snapshot can be skipped that eliminates the only one caller that will add task to mSkipClosingAppSnapshotTasks. Which also makes finishActivity more efficient. Also change mSkipClosingAppSnapshotTasks to store task id. So it won't keep heavy references. Bug: 283177730 Bug: 273198446 Test: TaskSnapshotControllerTest Change-Id: I3d03c34d506d0f3b1c0e070b8702a6a66a4de3c1 --- .../com/android/server/wm/ActivityRecord.java | 2 +- .../server/wm/TaskSnapshotController.java | 48 +++---------------- .../wm/RecentsAnimationControllerTest.java | 2 - .../server/wm/TaskSnapshotControllerTest.java | 19 ++++++-- 4 files changed, 24 insertions(+), 47 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 0b7618da4d34c..2649ea5da0274 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3560,7 +3560,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Note that RecentsAnimation will handle task snapshot while switching apps with // the best capture timing (e.g. IME window capture), // No need additional task capture while task is controlled by RecentsAnimation. - if (mAtmService.mWindowManager.mTaskSnapshotController != null + if (!mTransitionController.isShellTransitionsEnabled() && !task.isAnimatingByRecents()) { final ArraySet tasks = Sets.newArraySet(task); mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 4d0bff961e608..32a9822d222ec 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -28,6 +28,7 @@ import android.graphics.Rect; import android.os.Environment; import android.os.Handler; import android.util.ArraySet; +import android.util.IntArray; import android.util.Slog; import android.view.Display; import android.window.ScreenCapture; @@ -37,8 +38,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.server.policy.WindowManagerPolicy.ScreenOffListener; import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider; -import com.google.android.collect.Sets; - import java.util.Set; /** @@ -58,7 +57,7 @@ class TaskSnapshotController extends AbsAppSnapshotController mSkipClosingAppSnapshotTasks = new ArraySet<>(); + private final IntArray mSkipClosingAppSnapshotTasks = new IntArray(); private final ArraySet mTmpTasks = new ArraySet<>(); private final Handler mHandler = new Handler(); @@ -134,26 +133,6 @@ class TaskSnapshotController extends AbsAppSnapshotController closingApps) { - if (shouldDisableSnapshots()) { - return; - } - // We need to take a snapshot of the task if and only if all activities of the task are - // either closing or hidden. - getClosingTasks(closingApps, mTmpTasks); - snapshotTasks(mTmpTasks); - mSkipClosingAppSnapshotTasks.clear(); - } - /** * Adds the given {@param tasks} to the list of tasks which should not have their snapshots * taken upon the next processing of the set of closing apps. The caller is responsible for @@ -164,7 +143,9 @@ class TaskSnapshotController extends AbsAppSnapshotController tasks) { @@ -271,31 +252,16 @@ class TaskSnapshotController extends AbsAppSnapshotController closingApps, ArraySet outClosingTasks) { - outClosingTasks.clear(); - for (int i = closingApps.size() - 1; i >= 0; i--) { - final ActivityRecord activity = closingApps.valueAt(i); - final Task task = activity.getTask(); - if (task == null) continue; - - getClosingTasksInner(task, outClosingTasks); - } - } - void getClosingTasksInner(Task task, ArraySet outClosingTasks) { // Since RecentsAnimation will handle task snapshot while switching apps with the // best capture timing (e.g. IME window capture), // No need additional task capture while task is controlled by RecentsAnimation. if (isAnimatingByRecents(task)) { - mSkipClosingAppSnapshotTasks.add(task); + mSkipClosingAppSnapshotTasks.add(task.mTaskId); } // If the task of the app is not visible anymore, it means no other app in that task // is opening. Thus, the task is closing. - if (!task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) { + if (!task.isVisible() && mSkipClosingAppSnapshotTasks.indexOf(task.mTaskId) < 0) { outClosingTasks.add(task); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index 7092b0b5ac342..6e52af1b4e7d7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -298,8 +298,6 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertTrue(mController.isAnimatingTask(activity.getTask())); spyOn(mWm.mTaskSnapshotController); - doNothing().when(mWm.mTaskSnapshotController).notifyAppVisibilityChanged(any(), - anyBoolean()); doReturn(mMockTaskSnapshot).when(mWm.mTaskSnapshotController).getSnapshot(anyInt(), anyInt(), eq(false) /* restoreFromDisk */, eq(false) /* isLowResolution */); mController.setDeferredCancel(true /* deferred */, true /* screenshot */); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java index 4c7b0aa0714e5..91256ee8a1c41 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java @@ -75,7 +75,7 @@ public class TaskSnapshotControllerTest extends WindowTestsBase { final ArraySet closingApps = new ArraySet<>(); closingApps.add(closingWindow.mActivityRecord); final ArraySet closingTasks = new ArraySet<>(); - mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks); + getClosingTasks(closingApps, closingTasks); assertEquals(1, closingTasks.size()); assertEquals(closingWindow.mActivityRecord.getTask(), closingTasks.valueAt(0)); } @@ -93,7 +93,7 @@ public class TaskSnapshotControllerTest extends WindowTestsBase { final ArraySet closingApps = new ArraySet<>(); closingApps.add(closingWindow.mActivityRecord); final ArraySet closingTasks = new ArraySet<>(); - mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks); + getClosingTasks(closingApps, closingTasks); assertEquals(0, closingTasks.size()); } @@ -108,10 +108,23 @@ public class TaskSnapshotControllerTest extends WindowTestsBase { final ArraySet closingTasks = new ArraySet<>(); mWm.mTaskSnapshotController.addSkipClosingAppSnapshotTasks( Sets.newArraySet(closingWindow.mActivityRecord.getTask())); - mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks); + getClosingTasks(closingApps, closingTasks); assertEquals(0, closingTasks.size()); } + /** Retrieves all closing tasks based on the list of closing apps during an app transition. */ + private void getClosingTasks(ArraySet closingApps, + ArraySet outClosingTasks) { + outClosingTasks.clear(); + for (int i = closingApps.size() - 1; i >= 0; i--) { + final ActivityRecord activity = closingApps.valueAt(i); + final Task task = activity.getTask(); + if (task == null) continue; + + mWm.mTaskSnapshotController.getClosingTasksInner(task, outClosingTasks); + } + } + @Test public void testGetSnapshotMode() { final WindowState disabledWindow = createWindow(null,