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

Commit d1b30acd authored by wilsonshih's avatar wilsonshih
Browse files

Tracking task snapshot usage in client process.(4/N)

- Introduce ITaskSnapshotListener, separate task snapshot related
callbacks from TaskStackListener.
- Prepare to deprecate onTaskSnapshotChanged and
onTaskSnapshotInvalidated in TaskStackListener.
- Relocate some task snapshot access APIs to TaskSnapshotManager.
- Add a reference count for the tracker when returning an existing
TaskSnapshot object from the global tracker.

Flag: com.android.window.flags.reduce_task_snapshot_memory_usage
Bug: 238206323
Test: Use "dumpsys meminfo" to check how many snapshots remain in a
process, and where they are used.

Change-Id: I122898d99e084297a7bea20695d2720fc05533be
parent d6b5b5cf
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -232,6 +232,7 @@ import android.window.SizeConfigurationBuckets;
import android.window.SplashScreen;
import android.window.SplashScreenView;
import android.window.TaskFragmentTransaction;
import android.window.TaskSnapshotManager;
import android.window.WindowContextInfo;
import android.window.WindowProviderService;
import android.window.WindowTokenClientController;
@@ -260,8 +261,8 @@ import com.android.org.conscrypt.TrustedCertificateStore;
import com.android.server.am.BitmapDumpProto;
import com.android.server.am.MemInfoDumpProto;

import dalvik.annotation.optimization.NeverInline;
import dalvik.annotation.optimization.NeverCompile;
import dalvik.annotation.optimization.NeverInline;
import dalvik.system.AppSpecializationHooks;
import dalvik.system.CloseGuard;
import dalvik.system.VMDebug;
@@ -1915,6 +1916,11 @@ public final class ActivityThread extends ClientTransactionHandler
                pw.print(assetAlloc);
            }

            // Task Snapshot
            if (com.android.window.flags.Flags.reduceTaskSnapshotMemoryUsage()) {
                TaskSnapshotManager.getInstance().dump(pw);
            }

            // Unreachable native memory
            if (dumpUnreachable) {
                boolean showContents = ((mBoundApplication != null)
+16 −1
Original line number Diff line number Diff line
@@ -168,15 +168,30 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
            throws RemoteException {
    }

    /**
     * @deprecated Use {@link android.window.TaskSnapshotManager.TaskSnapshotListener} to receive
     * callback.
     */
    @Deprecated
    @Override
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
        if (mIsRemote && snapshot != null && snapshot.getHardwareBuffer() != null) {
        if (!mIsRemote || snapshot == null) {
            return;
        }
        if (com.android.window.flags.Flags.reduceTaskSnapshotMemoryUsage()) {
            snapshot.closeBuffer();
        } else if (snapshot.getHardwareBuffer() != null) {
            // Preemptively clear any reference to the buffer
            snapshot.getHardwareBuffer().close();
        }
    }

    /**
     * @deprecated Use {@link android.window.SnapshotManager.TaskSnapshotListener} to receive
     * callback.
     */
    @Deprecated
    @Override
    public void onTaskSnapshotInvalidated(int taskId) { }

+34 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2025, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.window;

import android.window.TaskSnapshot;

/**
* @hide
*/
oneway interface ITaskSnapshotListener {
    /**
     * Called when a task snapshot got updated.
     */
    void onTaskSnapshotChanged(int taskId, in TaskSnapshot taskSnapshot);

    /**
     * Called when a task snapshot become invalidated.
     */
    void onTaskSnapshotInvalidated(int taskId);
}
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.window;

import android.window.ITaskSnapshotListener;

/**
 * @hide
 */
@@ -49,4 +51,7 @@ interface ITaskSnapshotManager {
     *         corresponding task can be found.
     */
    android.window.TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache);

    void registerTaskSnapshotListener(in ITaskSnapshotListener listener);
    void unregisterTaskSnapshotListener(in ITaskSnapshotListener listener);
}
 No newline at end of file
+7 −3
Original line number Diff line number Diff line
@@ -273,12 +273,12 @@ public class TaskSnapshot implements Parcelable {
                final TaskSnapshotManager.SnapshotTracker tracker = mSnapshotTracker.get();
                if (tracker != null) {
                    TaskSnapshotManager.getInstance().removeTracker(tracker);
                    mSnapshotTracker.clear();
                }
                }
            } else {
                mSnapshot.close();
            }
        }
    }

    /**
     * Returns whether the hardware buffer is valid.
@@ -494,8 +494,12 @@ public class TaskSnapshot implements Parcelable {
    }

    void setSnapshotTracker(TaskSnapshotManager.SnapshotTracker tracker) {
        if (tracker == null) {
            mSnapshotTracker = null;
        } else {
            mSnapshotTracker = new WeakReference<>(tracker);
        }
    }

    /**
     * Adds a reference when the object is held somewhere.
Loading