diff options
author | 2024-08-30 17:09:30 +0800 | |
---|---|---|
committer | 2024-08-30 17:09:30 +0800 | |
commit | bf47618b933d526e7050546022445fbe5fe20bf2 (patch) | |
tree | 4511094a39458f2f7dd386a356d1ecf60b4af0e0 | |
parent | 1798b05a481ab6f668c87c1c12fa898d39de7f2f (diff) |
Add TaskSnapshot reference when used for Content suggestion.
Add reference, so the hardware buffer of the snapshot won't get release
too early.
Flag: com.android.window.flags.release_snapshot_aggressively
Bug: 238206323
Test: enter recents to check content suggestion several times without
seeing crash.
Change-Id: I622e471bfc0f40cf97653dd3ace56e29b49185f7
4 files changed, 38 insertions, 7 deletions
diff --git a/core/java/android/window/TaskSnapshot.java b/core/java/android/window/TaskSnapshot.java index 20d1b3bd12ae..a37bef80ff04 100644 --- a/core/java/android/window/TaskSnapshot.java +++ b/core/java/android/window/TaskSnapshot.java @@ -83,13 +83,16 @@ public class TaskSnapshot implements Parcelable { public static final int REFERENCE_CACHE = 1 << 1; /** This snapshot object is being persistent. */ 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; @IntDef(flag = true, prefix = { "REFERENCE_" }, value = { REFERENCE_BROADCAST, REFERENCE_CACHE, - REFERENCE_PERSIST + REFERENCE_PERSIST, + REFERENCE_CONTENT_SUGGESTION }) @Retention(RetentionPolicy.SOURCE) - @interface ReferenceFlags {} + public @interface ReferenceFlags {} public TaskSnapshot(long id, long captureTime, @NonNull ComponentName topActivityComponent, HardwareBuffer snapshot, diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java index 57c643bb08a1..a7aab49cde56 100644 --- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java +++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java @@ -160,11 +160,13 @@ public class ContentSuggestionsManagerService extends HardwareBuffer snapshotBuffer = null; int colorSpaceId = 0; + TaskSnapshot snapshot = null; // Skip taking TaskSnapshot when bitmap is provided. if (!imageContextRequestExtras.containsKey(ContentSuggestionsManager.EXTRA_BITMAP)) { // Can block, so call before acquiring the lock. - TaskSnapshot snapshot = - mActivityTaskManagerInternal.getTaskSnapshotBlocking(taskId, false); + snapshot = mActivityTaskManagerInternal.getTaskSnapshotBlocking( + taskId, false /* isLowResolution */, + TaskSnapshot.REFERENCE_CONTENT_SUGGESTION); if (snapshot != null) { snapshotBuffer = snapshot.getHardwareBuffer(); ColorSpace colorSpace = snapshot.getColorSpace(); @@ -185,6 +187,9 @@ public class ContentSuggestionsManagerService extends } } } + if (snapshot != null) { + snapshot.removeReference(TaskSnapshot.REFERENCE_CONTENT_SUGGESTION); + } } @Override diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index 26a6b00254d3..3e9c19f01a1a 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -607,7 +607,7 @@ public abstract class ActivityTaskManagerInternal { * sensitive environment. */ public abstract TaskSnapshot getTaskSnapshotBlocking(int taskId, - boolean isLowResolution); + boolean isLowResolution, @TaskSnapshot.ReferenceFlags int usage); /** Returns true if uid is considered foreground for activity start purposes. */ public abstract boolean isUidForeground(int uid); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 0f108c5ed5d7..eedc3b870bbf 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3913,6 +3913,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + private TaskSnapshot getTaskSnapshotInner(int taskId, boolean isLowResolution, + @TaskSnapshot.ReferenceFlags int usage) { + final Task task; + synchronized (mGlobalLock) { + task = mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS); + if (task == null) { + Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found"); + return null; + } + // 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); + 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); + } + @Override public TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution) { mAmInternal.enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); @@ -7235,8 +7257,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public TaskSnapshot getTaskSnapshotBlocking( - int taskId, boolean isLowResolution) { - return ActivityTaskManagerService.this.getTaskSnapshot(taskId, isLowResolution); + int taskId, boolean isLowResolution, @TaskSnapshot.ReferenceFlags int usage) { + return ActivityTaskManagerService.this.getTaskSnapshotInner( + taskId, isLowResolution, usage); } @Override |