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

Commit 3dfdc4c2 authored by wilsonshih's avatar wilsonshih
Browse files

Only cache low-resolution task snapshots in the system server.(5/N)

This change reduces both heap and dma_buf usage in the system server by
replacing high-resolution snapshots in the cache with low-resolution:

1. After a low-resolution bitmap is created in the persist thread, a
new task snapshot object is created from it. This then replaces the
previous high-resolution snapshot in the snapshot cache.
2. When getTaskSnapshot is called with a low-resolution request, a
low-resolution snapshot is either retrieved or created from the latest
task snapshot (if it exists). This replaces the high-resolution
snapshot in the snapshot cache. By respect the request, this also
reduce the memory usage in the client process since the returned
snapshot is smaller than the high-resolution one.

To prevent duplicate tasks resulting from both scenarios (1 and 2),
the second put-to-cache task can be ignored if the convert already
occurred.

3. Support takeTaskSnapshot to return a low-resolution snapshot, which
will be useful when clients request a snapshot but specifically require
a lower-resolution version.

Flag: com.android.window.flags.reduce_task_snapshot_memory_usage
Flag: com.android.window.flags.respect_requested_task_snapshot_resolution
Bug: 238206323
Test: dumpsys window every time after a close task transition finish,
verify the resolution in task snapshot cache is low-resolution.
dump dmabuf everytime after a close task transition finish, verify the
dmabuf won't increase in system server.

Change-Id: I37ebbef4f75a86c952f8e633fdbc8aedaf5b3d69
parent d1b30acd
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -46,11 +46,13 @@ interface ITaskSnapshotManager {
     *                    If it is true, the snapshot can be either real content or app-theme mode
     *                    depending on the attributes of app. Otherwise, the snapshot will be taken
     *                    with real content.
     * @param lowResolution Whether to get the new snapshot in low resolution.
     * @throws RemoteException
     * @return a graphic buffer representing a screenshot of a task, or {@code null} if no
     *         corresponding task can be found.
     */
    android.window.TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache);
    android.window.TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache,
            boolean lowResolution);

    void registerTaskSnapshotListener(in ITaskSnapshotListener listener);
    void unregisterTaskSnapshotListener(in ITaskSnapshotListener listener);
+5 −1
Original line number Diff line number Diff line
@@ -101,13 +101,17 @@ public class TaskSnapshot implements Parcelable {
    /** 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;
    /** This snapshot object is being used to convert resolution . */
    public static final int REFERENCE_CONVERT_RESOLUTION = 1 << 5;

    @IntDef(flag = true, prefix = { "REFERENCE_" }, value = {
            REFERENCE_NONE,
            REFERENCE_BROADCAST,
            REFERENCE_CACHE,
            REFERENCE_PERSIST,
            REFERENCE_CONTENT_SUGGESTION,
            REFERENCE_WRITE_TO_PARCEL
            REFERENCE_WRITE_TO_PARCEL,
            REFERENCE_CONVERT_RESOLUTION
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ReferenceFlags {}
+23 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.util.Singleton;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.window.flags.Flags;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -146,9 +147,28 @@ public class TaskSnapshotManager {
     *         corresponding task can be found.
     */
    public TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache) throws RemoteException {
        return takeTaskSnapshot(taskId, updateCache, false /* lowResolution */);
    }

    /**
     * Requests for a new snapshot to be taken for the task with the given id, storing it in the
     * task snapshot cache only if requested.
     *
     * @param taskId the id of the task to take a snapshot of
     * @param updateCache Whether to store the new snapshot in the system's task snapshot cache.
     *                    If it is true, the snapshot can be either real content or app-theme mode
     *                    depending on the attributes of app. Otherwise, the snapshot will be taken
     *                    with real content.
     * @param lowResolution Whether to get the new snapshot in low resolution.
     * @return a graphic buffer representing a screenshot of a task,  or {@code null} if no
     *         corresponding task can be found.
     */
    public TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache,
            boolean lowResolution) throws RemoteException {
        final TaskSnapshot t;
        try {
            t = ISnapshotManagerSingleton.get().takeTaskSnapshot(taskId, updateCache);
            t = ISnapshotManagerSingleton.get().takeTaskSnapshot(taskId, updateCache,
                    lowResolution);
        } catch (RemoteException r) {
            Log.e(TAG, "takeTaskSnapshot fail: " + r);
            throw r;
@@ -210,6 +230,8 @@ public class TaskSnapshotManager {
        final boolean isLowRes = snapshot.isLowResolution();
        if (isLowRes) {
            return retrieveResolution == TaskSnapshotManager.RESOLUTION_LOW;
        } else if (Flags.respectRequestedTaskSnapshotResolution()) {
            return retrieveResolution == TaskSnapshotManager.RESOLUTION_HIGH;
        }
        return true;
    }
+10 −0
Original line number Diff line number Diff line
@@ -344,6 +344,16 @@ flag {
    }
}

flag {
    name: "respect_requested_task_snapshot_resolution"
    namespace: "windowing_frontend"
    description: "Produce a task snapshot object that respects the requested resolution, and only cache low resolution snapshot in system server."
    bug: "238206323"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "scramble_snapshot_file_name"
    namespace: "windowing_frontend"
+24 −0
Original line number Diff line number Diff line
@@ -177,6 +177,30 @@ public class ActivityManagerWrapper {
        }
    }

    /**
     * Requests for a new snapshot to be taken for the given task, stores it in the cache, and
     * returns a {@link ThumbnailData} with specific resolution as result.
     */
    @NonNull
    public ThumbnailData takeTaskThumbnail(int taskId, boolean lowResolution) {
        if (!com.android.window.flags.Flags.respectRequestedTaskSnapshotResolution()
                || !com.android.window.flags.Flags.reduceTaskSnapshotMemoryUsage()) {
            return takeTaskThumbnail(taskId);
        }
        TaskSnapshot snapshot = null;
        try {
            snapshot = TaskSnapshotManager.getInstance().takeTaskSnapshot(taskId,
                    true /* updateCache */, lowResolution);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to take task snapshot", e);
        }
        if (snapshot != null) {
            return ThumbnailData.fromSnapshot(snapshot);
        } else {
            return new ThumbnailData();
        }
    }

    /**
     * Removes the outdated snapshot of home task.
     *
Loading