diff options
12 files changed, 106 insertions, 84 deletions
diff --git a/core/java/android/window/TaskSnapshot.java b/core/java/android/window/TaskSnapshot.java index a37bef80ff04..53c64bd6e664 100644 --- a/core/java/android/window/TaskSnapshot.java +++ b/core/java/android/window/TaskSnapshot.java @@ -77,6 +77,8 @@ public class TaskSnapshot implements Parcelable { private final ColorSpace mColorSpace; private int mInternalReferences; + /** Keep in cache, doesn't need reference. */ + public static final int REFERENCE_NONE = 0; /** This snapshot object is being broadcast. */ public static final int REFERENCE_BROADCAST = 1; /** This snapshot object is in the cache. */ @@ -85,11 +87,16 @@ public class TaskSnapshot implements Parcelable { public static final int REFERENCE_PERSIST = 1 << 2; /** This snapshot object is being used for content suggestion. */ public static final int REFERENCE_CONTENT_SUGGESTION = 1 << 3; + /** This snapshot object will be passing to external process. Keep the snapshot reference after + * writeToParcel*/ + public static final int REFERENCE_WRITE_TO_PARCEL = 1 << 4; @IntDef(flag = true, prefix = { "REFERENCE_" }, value = { + REFERENCE_NONE, REFERENCE_BROADCAST, REFERENCE_CACHE, REFERENCE_PERSIST, - REFERENCE_CONTENT_SUGGESTION + REFERENCE_CONTENT_SUGGESTION, + REFERENCE_WRITE_TO_PARCEL }) @Retention(RetentionPolicy.SOURCE) public @interface ReferenceFlags {} @@ -309,6 +316,11 @@ public class TaskSnapshot implements Parcelable { dest.writeBoolean(mIsTranslucent); dest.writeBoolean(mHasImeSurface); dest.writeInt(mUiMode); + synchronized (this) { + if ((mInternalReferences & REFERENCE_WRITE_TO_PARCEL) != 0) { + removeReference(REFERENCE_WRITE_TO_PARCEL); + } + } } @Override diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 5989fc8465c6..d33d54755d38 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2406,9 +2406,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - final TaskSnapshot snapshot = - mWmService.mTaskSnapshotController.getSnapshot(task.mTaskId, task.mUserId, - false /* restoreFromDisk */, false /* isLowResolution */); + final TaskSnapshot snapshot = mWmService.mTaskSnapshotController.getSnapshot(task.mTaskId, + false /* isLowResolution */); final int type = getStartingWindowType(newTask, taskSwitch, processRunning, allowTaskSnapshot, activityCreated, activityAllDrawn, snapshot); diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java index 57a0bb53c9dc..9aaa0e1cfd6b 100644 --- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java +++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java @@ -149,7 +149,8 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord for (int i = activities.length - 1; i >= 0; --i) { fileId ^= getSystemHashCode(activities[i]); } - return tmpUsf.mFileId == fileId ? mCache.getSnapshot(tmpUsf.mActivityIds.get(0)) : null; + return tmpUsf.mFileId == fileId + ? mCache.getSnapshotInner(tmpUsf.mActivityIds.get(0)) : null; } private void cleanUpUserFiles(int userId) { diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index afa7ea136c77..5eee8ece6a67 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3996,15 +3996,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } // Try to load snapshot from cache first, and add reference if the snapshot is in cache. final TaskSnapshot snapshot = mWindowManager.mTaskSnapshotController.getSnapshot(taskId, - task.mUserId, false /* restoreFromDisk */, isLowResolution); + isLowResolution, usage); if (snapshot != null) { - snapshot.addReference(usage); return snapshot; } } // Don't call this while holding the lock as this operation might hit the disk. - return mWindowManager.mTaskSnapshotController.getSnapshot(taskId, - task.mUserId, true /* restoreFromDisk */, isLowResolution); + return mWindowManager.mTaskSnapshotController.getSnapshotFromDisk(taskId, + task.mUserId, isLowResolution, usage); } @Override @@ -4020,10 +4019,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found"); return null; } + final TaskSnapshot snapshot = mWindowManager.mTaskSnapshotController.getSnapshot( + taskId, isLowResolution, TaskSnapshot.REFERENCE_WRITE_TO_PARCEL); + if (snapshot != null) { + return snapshot; + } } // Don't call this while holding the lock as this operation might hit the disk. - return mWindowManager.mTaskSnapshotController.getSnapshot(taskId, - task.mUserId, true /* restoreFromDisk */, isLowResolution); + return mWindowManager.mTaskSnapshotController.getSnapshotFromDisk(taskId, + task.mUserId, isLowResolution, TaskSnapshot.REFERENCE_WRITE_TO_PARCEL); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index 3968b525f11d..e9e3c9ee389e 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -2251,8 +2251,7 @@ class BackNavigationController { if (w.asTask() != null) { final Task task = w.asTask(); snapshot = task.mRootWindowContainer.mWindowManager.mTaskSnapshotController.getSnapshot( - task.mTaskId, task.mUserId, false /* restoreFromDisk */, - false /* isLowResolution */); + task.mTaskId, false /* isLowResolution */); } else { ActivityRecord ar = w.asActivityRecord(); if (ar == null && w.asTaskFragment() != null) { diff --git a/services/core/java/com/android/server/wm/SnapshotCache.java b/services/core/java/com/android/server/wm/SnapshotCache.java index 1e6ee7dc318f..9812a88bfa5a 100644 --- a/services/core/java/com/android/server/wm/SnapshotCache.java +++ b/services/core/java/com/android/server/wm/SnapshotCache.java @@ -51,7 +51,7 @@ abstract class SnapshotCache<TYPE extends WindowContainer> { } @Nullable - final TaskSnapshot getSnapshot(Integer id) { + final TaskSnapshot getSnapshotInner(Integer id) { synchronized (mLock) { // Try the running cache. final CacheEntry entry = mRunningCache.get(id); diff --git a/services/core/java/com/android/server/wm/SnapshotController.java b/services/core/java/com/android/server/wm/SnapshotController.java index 3ee2e6048634..dcdffa416e33 100644 --- a/services/core/java/com/android/server/wm/SnapshotController.java +++ b/services/core/java/com/android/server/wm/SnapshotController.java @@ -202,7 +202,7 @@ class SnapshotController { final Task task = wc.asTask(); if (task != null && wc.isVisibleRequested() && !task.inPinnedWindowingMode()) { final TaskSnapshot snapshot = mTaskSnapshotController.getSnapshot(task.mTaskId, - task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); + false /* isLowResolution */); if (snapshot != null) { mTaskSnapshotController.removeAndDeleteSnapshot(task.mTaskId, task.mUserId); } diff --git a/services/core/java/com/android/server/wm/TaskSnapshotCache.java b/services/core/java/com/android/server/wm/TaskSnapshotCache.java index 64b9df59990b..cc957bd9ee42 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotCache.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotCache.java @@ -48,26 +48,37 @@ class TaskSnapshotCache extends SnapshotCache<Task> { } /** - * If {@param restoreFromDisk} equals {@code true}, DO NOT HOLD THE WINDOW MANAGER LOCK! + * Retrieves a snapshot from cache. */ - @Nullable TaskSnapshot getSnapshot(int taskId, int userId, boolean restoreFromDisk, - boolean isLowResolution) { - final TaskSnapshot snapshot = getSnapshot(taskId); - if (snapshot != null) { - return snapshot; - } + @Nullable TaskSnapshot getSnapshot(int taskId, boolean isLowResolution) { + return getSnapshot(taskId, isLowResolution, TaskSnapshot.REFERENCE_NONE); + } - // Try to restore from disk if asked. - if (!restoreFromDisk) { - return null; + // TODO (b/238206323) Respect isLowResolution. + @Nullable TaskSnapshot getSnapshot(int taskId, boolean isLowResolution, + @TaskSnapshot.ReferenceFlags int usage) { + synchronized (mLock) { + final TaskSnapshot snapshot = getSnapshotInner(taskId); + if (snapshot != null) { + if (usage != TaskSnapshot.REFERENCE_NONE) { + snapshot.addReference(usage); + } + return snapshot; + } } - return tryRestoreFromDisk(taskId, userId, isLowResolution); + return null; } /** - * DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD! + * Restore snapshot from disk, DO NOT HOLD THE WINDOW MANAGER LOCK! */ - private TaskSnapshot tryRestoreFromDisk(int taskId, int userId, boolean isLowResolution) { - return mLoader.loadTask(taskId, userId, isLowResolution); + @Nullable TaskSnapshot getSnapshotFromDisk(int taskId, int userId, boolean isLowResolution, + @TaskSnapshot.ReferenceFlags int usage) { + final TaskSnapshot snapshot = mLoader.loadTask(taskId, userId, isLowResolution); + // Note: This can be weird if the caller didn't ask for reference. + if (snapshot != null && usage != TaskSnapshot.REFERENCE_NONE) { + snapshot.addReference(usage); + } + return snapshot; } } diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index c130931277fe..38a2ebeba332 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -174,14 +174,32 @@ class TaskSnapshotController extends AbsAppSnapshotController<Task, TaskSnapshot } /** - * Retrieves a snapshot. If {@param restoreFromDisk} equals {@code true}, DO NOT HOLD THE WINDOW - * MANAGER LOCK WHEN CALLING THIS METHOD! + * Retrieves a snapshot from cache. */ @Nullable - TaskSnapshot getSnapshot(int taskId, int userId, boolean restoreFromDisk, - boolean isLowResolution) { - return mCache.getSnapshot(taskId, userId, restoreFromDisk, isLowResolution - && mPersistInfoProvider.enableLowResSnapshots()); + TaskSnapshot getSnapshot(int taskId, boolean isLowResolution) { + return getSnapshot(taskId, false /* isLowResolution */, TaskSnapshot.REFERENCE_NONE); + } + + /** + * Retrieves a snapshot from cache. + */ + @Nullable + TaskSnapshot getSnapshot(int taskId, boolean isLowResolution, + @TaskSnapshot.ReferenceFlags int usage) { + return mCache.getSnapshot(taskId, isLowResolution + && mPersistInfoProvider.enableLowResSnapshots(), usage); + } + + /** + * Retrieves a snapshot from disk. + * DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD! + */ + @Nullable + TaskSnapshot getSnapshotFromDisk(int taskId, int userId, + boolean isLowResolution, @TaskSnapshot.ReferenceFlags int usage) { + return mCache.getSnapshotFromDisk(taskId, userId, isLowResolution + && mPersistInfoProvider.enableLowResSnapshots(), usage); } /** @@ -189,7 +207,7 @@ class TaskSnapshotController extends AbsAppSnapshotController<Task, TaskSnapshot * last taken, or -1 if no such snapshot exists for that task. */ long getSnapshotCaptureTime(int taskId) { - final TaskSnapshot snapshot = mCache.getSnapshot(taskId); + final TaskSnapshot snapshot = mCache.getSnapshot(taskId, false /* isLowResolution */); if (snapshot != null) { return snapshot.getCaptureTime(); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 58319f4cdabc..07e7a915b171 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4292,16 +4292,6 @@ public class WindowManagerService extends IWindowManager.Stub } /** - * Retrieves a snapshot. If restoreFromDisk equals equals {@code true}, DO NOT HOLD THE WINDOW - * MANAGER LOCK WHEN CALLING THIS METHOD! - */ - public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean isLowResolution, - boolean restoreFromDisk) { - return mTaskSnapshotController.getSnapshot(taskId, userId, restoreFromDisk, - isLowResolution); - } - - /** * Generates and returns an up-to-date {@link Bitmap} for the specified taskId. * * @param taskId The task ID of the task for which a Bitmap is requested. @@ -10021,11 +10011,10 @@ public class WindowManagerService extends IWindowManager.Stub && imeTargetWindow.mActivityRecord.mLastImeShown) { return true; } + final TaskSnapshot snapshot = mTaskSnapshotController.getSnapshot( + imeTargetWindowTask.mTaskId, false /* isLowResolution */); + return snapshot != null && snapshot.hasImeSurface(); } - final TaskSnapshot snapshot = getTaskSnapshot(imeTargetWindowTask.mTaskId, - imeTargetWindowTask.mUserId, false /* isLowResolution */, - false /* restoreFromDisk */); - return snapshot != null && snapshot.hasImeSurface(); } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java index 29f48b86a375..f145b40d2292 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java @@ -65,33 +65,27 @@ public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase { public void testAppRemoved() { final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window"); mCache.putSnapshot(window.getTask(), createSnapshot()); - assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); mCache.onAppRemoved(window.mActivityRecord); - assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); } @Test public void testAppDied() { final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window"); mCache.putSnapshot(window.getTask(), createSnapshot()); - assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); mCache.onAppDied(window.mActivityRecord); - assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); } @Test public void testTaskRemoved() { final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window"); mCache.putSnapshot(window.getTask(), createSnapshot()); - assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); mCache.onIdRemoved(window.getTask().mTaskId); - assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); } @Test @@ -99,16 +93,14 @@ public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase { final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window"); mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot()); mSnapshotPersistQueue.waitForQueueEmpty(); - assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); // Load it from disk - assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - true /* restoreFromDisk */, true /* isLowResolution */)); + assertNotNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId, + true /* isLowResolution */, TaskSnapshot.REFERENCE_NONE)); // Make sure it's not in the cache now. - assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); } @Test @@ -116,20 +108,20 @@ public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase { final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window"); mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot()); mSnapshotPersistQueue.waitForQueueEmpty(); - assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); // Load it from disk - assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - true /* restoreFromDisk */, false /* isLowResolution */)); + assertNotNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId, + false/* isLowResolution */, TaskSnapshot.REFERENCE_NONE)); } @Test public void testClearCache() { final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window"); mCache.putSnapshot(window.getTask(), mSnapshot); - assertEquals(mSnapshot, mCache.getSnapshot(window.getTask().mTaskId, 0, false, false)); + assertEquals(mSnapshot, mCache.getSnapshot(window.getTask().mTaskId, + false /* isLowResolution */)); mCache.clearRunningCache(); - assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0, false, false)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java index 7432537902a0..9bde0663d4a3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java @@ -129,23 +129,20 @@ public class TaskSnapshotLowResDisabledTest extends TaskSnapshotPersisterTestBas final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window"); mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot()); mSnapshotPersistQueue.waitForQueueEmpty(); - assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); // Attempt to load the low-res snapshot from the disk - assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - true /* restoreFromDisk */, true /* isLowResolution */)); + assertNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId, + true/* isLowResolution */, TaskSnapshot.REFERENCE_NONE)); // Load the high-res (default) snapshot from disk - assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - true /* restoreFromDisk */, false /* isLowResolution */)); + assertNotNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId, + false /* isLowResolution */, TaskSnapshot.REFERENCE_NONE)); // Make sure it's not in the cache now. - assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - false /* restoreFromDisk */, true /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, true /* isLowResolution */)); // Make sure it's not in the cache now. - assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, - false /* restoreFromDisk */, false /* isLowResolution */)); + assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */)); } } |