Merge "Fixes multiple activity snapshots can stay in cache." into main
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index 24ed1bb..57a0bb5 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -18,6 +18,8 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -343,6 +345,11 @@
if (DEBUG) {
Slog.d(TAG, "ActivitySnapshotController#recordSnapshot " + activity);
}
+ if (mPersister.mSnapshotPersistQueue.peekWriteQueueSize() >= MAX_STORE_QUEUE_DEPTH
+ || mPersister.mSnapshotPersistQueue.peekQueueSize() > MAX_PERSIST_SNAPSHOT_COUNT) {
+ Slog.w(TAG, "Skipping recording activity snapshot, too many requests!");
+ return;
+ }
final int size = activity.size();
final int[] mixedCode = new int[size];
if (size == 1) {
@@ -432,7 +439,7 @@
addBelowActivityIfExist(ar, mPendingLoadActivity, false, "load-snapshot");
} else {
// remove the snapshot for the one below close
- addBelowActivityIfExist(ar, mPendingRemoveActivity, true, "remove-snapshot");
+ addBelowActivityIfExist(ar, mPendingRemoveActivity, false, "remove-snapshot");
}
}
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index 8b63ecf7..a545454 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -50,7 +50,7 @@
class SnapshotPersistQueue {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotPersister" : TAG_WM;
private static final long DELAY_MS = 100;
- private static final int MAX_STORE_QUEUE_DEPTH = 2;
+ static final int MAX_STORE_QUEUE_DEPTH = 2;
private static final int COMPRESS_QUALITY = 95;
@GuardedBy("mLock")
@@ -154,7 +154,12 @@
}
}
- @VisibleForTesting
+ int peekWriteQueueSize() {
+ synchronized (mLock) {
+ return mStoreQueueItems.size();
+ }
+ }
+
int peekQueueSize() {
synchronized (mLock) {
return mWriteQueue.size();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
index 2a53df9..a7fc10f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
@@ -17,30 +17,23 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import android.content.ComponentName;
-import android.graphics.ColorSpace;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
-import android.view.Surface;
import android.window.TaskSnapshot;
import androidx.test.filters.SmallTest;
@@ -61,14 +54,20 @@
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivitySnapshotControllerTests extends WindowTestsBase {
+public class ActivitySnapshotControllerTests extends TaskSnapshotPersisterTestBase {
private ActivitySnapshotController mActivitySnapshotController;
+ public ActivitySnapshotControllerTests() {
+ super(0.8f /* highResScale */, 0.5f /* lowResScale */);
+ }
+
+ @Override
@Before
- public void setUp() throws Exception {
- spyOn(mWm.mSnapshotController.mActivitySnapshotController);
- mActivitySnapshotController = mWm.mSnapshotController.mActivitySnapshotController;
+ public void setUp() {
+ super.setUp();
+ mActivitySnapshotController = new ActivitySnapshotController(mWm, mSnapshotPersistQueue);
+ spyOn(mActivitySnapshotController);
doReturn(false).when(mActivitySnapshotController).shouldDisableSnapshots();
mActivitySnapshotController.resetTmpFields();
}
@@ -92,12 +91,11 @@
assertEquals(0, mActivitySnapshotController.mPendingRemoveActivity.size());
mActivitySnapshotController.resetTmpFields();
- // simulate three activity
+ // simulate three activity, the bottom activity won't participate in transition
final WindowState belowClose = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
"belowClose");
belowClose.mActivityRecord.commitVisibility(
false /* visible */, true /* performLayout */);
- windows.add(belowClose.mActivityRecord);
mActivitySnapshotController.handleTransitionFinish(windows);
assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
assertEquals(belowClose.mActivityRecord,
@@ -249,15 +247,28 @@
assertEquals(taskSnapshot, mActivitySnapshotController.getSnapshot(activities));
}
- private TaskSnapshot createSnapshot() {
- HardwareBuffer buffer = mock(HardwareBuffer.class);
- doReturn(100).when(buffer).getWidth();
- doReturn(100).when(buffer).getHeight();
- return new TaskSnapshot(1, 0 /* captureTime */, new ComponentName("", ""), buffer,
- ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
- Surface.ROTATION_0, new Point(100, 100), new Rect() /* contentInsets */,
- new Rect() /* letterboxInsets*/, false /* isLowResolution */,
- true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* mSystemUiVisibility */,
- false /* isTranslucent */, false /* hasImeSurface */, 0 /* uiMode */);
+ /**
+ * Verifies that activity snapshot is skipped if the persister queue has too many pending write
+ * items.
+ */
+ @Test
+ public void testSkipRecordActivity() {
+ doReturn(createSnapshot()).when(mActivitySnapshotController).recordSnapshotInner(any());
+ final Task task = createTask(mDisplayContent);
+
+ mSnapshotPersistQueue.setPaused(true);
+ final ArrayList<ActivityRecord> tmpList = new ArrayList<>();
+ for (int i = 0; i < MAX_STORE_QUEUE_DEPTH; ++i) {
+ tmpList.clear();
+ final ActivityRecord activity = createActivityRecord(task);
+ tmpList.add(activity);
+ mActivitySnapshotController.recordSnapshot(tmpList);
+ assertNotNull(mActivitySnapshotController.findSavedFile(activity));
+ }
+ tmpList.clear();
+ final ActivityRecord activity = createActivityRecord(task);
+ tmpList.add(activity);
+ mActivitySnapshotController.recordSnapshot(tmpList);
+ assertNull(mActivitySnapshotController.findSavedFile(activity));
}
}