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
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 0b7618d..2649ea5 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 @@
// 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<Task> 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 4d0bff9..32a9822 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.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.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 @@
static final String SNAPSHOTS_DIRNAME = "snapshots";
private final TaskSnapshotPersister mPersister;
- private final ArraySet<Task> mSkipClosingAppSnapshotTasks = new ArraySet<>();
+ private final IntArray mSkipClosingAppSnapshotTasks = new IntArray();
private final ArraySet<Task> mTmpTasks = new ArraySet<>();
private final Handler mHandler = new Handler();
@@ -135,26 +134,6 @@
}
/**
- * Called when the visibility of an app changes outside of the regular app transition flow.
- */
- void notifyAppVisibilityChanged(ActivityRecord appWindowToken, boolean visible) {
- if (!visible) {
- handleClosingApps(Sets.newArraySet(appWindowToken));
- }
- }
-
- private void handleClosingApps(ArraySet<ActivityRecord> 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
* calling {@link #snapshotTasks} to ensure that the task has an up-to-date snapshot.
@@ -164,7 +143,9 @@
if (shouldDisableSnapshots()) {
return;
}
- mSkipClosingAppSnapshotTasks.addAll(tasks);
+ for (Task task : tasks) {
+ mSkipClosingAppSnapshotTasks.add(task.mTaskId);
+ }
}
void snapshotTasks(ArraySet<Task> tasks) {
@@ -271,31 +252,16 @@
return source.getTaskDescription();
}
- /**
- * Retrieves all closing tasks based on the list of closing apps during an app transition.
- */
- @VisibleForTesting
- void getClosingTasks(ArraySet<ActivityRecord> closingApps, ArraySet<Task> 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<Task> 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 7092b0b..6e52af1 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 @@
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 4c7b0aa0..91256ee 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 @@
final ArraySet<ActivityRecord> closingApps = new ArraySet<>();
closingApps.add(closingWindow.mActivityRecord);
final ArraySet<Task> 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 @@
final ArraySet<ActivityRecord> closingApps = new ArraySet<>();
closingApps.add(closingWindow.mActivityRecord);
final ArraySet<Task> closingTasks = new ArraySet<>();
- mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+ getClosingTasks(closingApps, closingTasks);
assertEquals(0, closingTasks.size());
}
@@ -108,10 +108,23 @@
final ArraySet<Task> 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<ActivityRecord> closingApps,
+ ArraySet<Task> 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,