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

Commit c262b2c1 authored by wilsonshih's avatar wilsonshih
Browse files

Refactor snapshot access between from cache and disk.

1. Correct the scope of the lock in SnapshotCache.
The lock is now held from the snapshot cache to allow adding an extra
reference if the snapshot is used outside the Window Manager lock. This
ensures proper synchronization and prevents premature release of the
snapshot.
2. Allows adding a reference for restored snapshots.
Snapshots restored from disk can now also have an extra reference added.
This enables quicker release of the associated hardware buffer,
improving memory management.
3. Separates snapshot retrieval methods.
The `getSnapshot` method is split into `FromDisk` and `FromCache`
variants. This clarifies when the WM lock/Cache lock should be held,
improving code readability and maintainability.

Bug: 238206323
Bug: 379546318
Flag: com.android.window.flags.release_snapshot_aggressively
Test: atest TaskSnapshotLowResDisabledTest TaskSnapshotCacheTest
Test: Verify the snapshot load from disk can be released after parcel.
Change-Id: I1982f1eb3fdf65d942c6bfae9ecee977984a222e
parent 17408328
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -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
+2 −3
Original line number Diff line number Diff line
@@ -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);

+2 −1
Original line number Diff line number Diff line
@@ -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) {
+10 −6
Original line number Diff line number Diff line
@@ -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);
        }
+1 −2
Original line number Diff line number Diff line
@@ -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) {
Loading