Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf47618b authored by wilsonshih's avatar wilsonshih
Browse files

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
parent 1798b05a
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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,
+7 −2
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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);
+25 −2
Original line number Diff line number Diff line
@@ -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