Loading services/core/java/com/android/server/wm/ActivitySnapshotController.java +8 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.wm; 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; Loading Loading @@ -343,6 +345,11 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord 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) { Loading Loading @@ -432,7 +439,7 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord 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"); } } Loading services/core/java/com/android/server/wm/SnapshotPersistQueue.java +7 −2 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ import java.util.ArrayDeque; 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") Loading Loading @@ -154,7 +154,12 @@ class SnapshotPersistQueue { } } @VisibleForTesting int peekWriteQueueSize() { synchronized (mLock) { return mStoreQueueItems.size(); } } int peekQueueSize() { synchronized (mLock) { return mWriteQueue.size(); Loading services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java +36 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -61,14 +54,20 @@ import java.util.Arrays; @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(); } Loading @@ -92,12 +91,11 @@ public class ActivitySnapshotControllerTests extends WindowTestsBase { 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, Loading Loading @@ -249,15 +247,28 @@ public class ActivitySnapshotControllerTests extends WindowTestsBase { 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)); } } Loading
services/core/java/com/android/server/wm/ActivitySnapshotController.java +8 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.wm; 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; Loading Loading @@ -343,6 +345,11 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord 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) { Loading Loading @@ -432,7 +439,7 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord 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"); } } Loading
services/core/java/com/android/server/wm/SnapshotPersistQueue.java +7 −2 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ import java.util.ArrayDeque; 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") Loading Loading @@ -154,7 +154,12 @@ class SnapshotPersistQueue { } } @VisibleForTesting int peekWriteQueueSize() { synchronized (mLock) { return mStoreQueueItems.size(); } } int peekQueueSize() { synchronized (mLock) { return mWriteQueue.size(); Loading
services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java +36 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -61,14 +54,20 @@ import java.util.Arrays; @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(); } Loading @@ -92,12 +91,11 @@ public class ActivitySnapshotControllerTests extends WindowTestsBase { 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, Loading Loading @@ -249,15 +247,28 @@ public class ActivitySnapshotControllerTests extends WindowTestsBase { 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)); } }