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

Commit c8da7519 authored by wilsonshih's avatar wilsonshih
Browse files

Use WeakReference for the TaskSnapshotWindow in inner Window.

Use WeakReference for the TaskSnapshotWindow so it can be clear at GC.
Also clear the TaskSnapshotWindow reference in
mStartingWindowRecords since it should be removed immediately.

Still observer the native Binder reference could hold the reference to
the TaskSnapshotWindow$Window object, from the local test it can be
released after force GC(need to trigger on system_server and systemUI).
So at least with this patch, TaskSnapshotWindow object can be released
immediately.

Bug: 225363815
Test: open several tasksnapshot starting window, verify the memory can
be released on perfetto.
Test: atest TaskSnapshotWindowTest StartingSurfaceDrawerTests

Change-Id: Iaa0a266c2c6756cef24d92cde57a6debc947e133
parent 500a0751
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -633,7 +633,7 @@ public class StartingSurfaceDrawer {
                    Slog.e(TAG, "Found empty splash screen, remove!");
                    removeWindowInner(record.mDecorView, false);
                }
                mStartingWindowRecords.remove(taskId);

            }
            if (record.mTaskSnapshotWindow != null) {
                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
@@ -641,10 +641,10 @@ public class StartingSurfaceDrawer {
                if (immediately) {
                    record.mTaskSnapshotWindow.removeImmediately();
                } else {
                    record.mTaskSnapshotWindow.scheduleRemove(() ->
                            mStartingWindowRecords.remove(taskId), removalInfo.deferRemoveForIme);
                    record.mTaskSnapshotWindow.scheduleRemove(removalInfo.deferRemoveForIme);
                }
            }
            mStartingWindowRecords.remove(taskId);
        }
    }

+25 −29
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ import com.android.internal.view.BaseIWindow;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;

import java.lang.ref.WeakReference;

/**
 * This class represents a starting window that shows a snapshot.
 *
@@ -149,7 +151,7 @@ public class TaskSnapshotWindow {
    private final SurfaceControl.Transaction mTransaction;
    private final Matrix mSnapshotMatrix = new Matrix();
    private final float[] mTmpFloat9 = new float[9];
    private Runnable mScheduledRunnable;
    private final Runnable mScheduledRunnable = this::removeImmediately;
    private final boolean mHasImeSurface;

    static TaskSnapshotWindow create(StartingWindowInfo info, IBinder appToken,
@@ -306,21 +308,13 @@ public class TaskSnapshotWindow {
        mSystemBarBackgroundPainter.drawNavigationBarBackground(c);
    }

    void scheduleRemove(Runnable onRemove, boolean deferRemoveForIme) {
    void scheduleRemove(boolean deferRemoveForIme) {
        // Show the latest content as soon as possible for unlocking to home.
        if (mActivityType == ACTIVITY_TYPE_HOME) {
            removeImmediately();
            onRemove.run();
            return;
        }
        if (mScheduledRunnable != null) {
        mSplashScreenExecutor.removeCallbacks(mScheduledRunnable);
            mScheduledRunnable = null;
        }
        mScheduledRunnable = () -> {
            TaskSnapshotWindow.this.removeImmediately();
            onRemove.run();
        };
        final long delayRemovalTime = mHasImeSurface && deferRemoveForIme
                ? MAX_DELAY_REMOVAL_TIME_IME_VISIBLE
                : DELAY_REMOVAL_TIME_GENERAL;
@@ -524,37 +518,39 @@ public class TaskSnapshotWindow {
        }
    }

    @BinderThread
    static class Window extends BaseIWindow {
        private TaskSnapshotWindow mOuter;
        private WeakReference<TaskSnapshotWindow> mOuter;

        public void setOuter(TaskSnapshotWindow outer) {
            mOuter = outer;
            mOuter = new WeakReference<>(outer);
        }

        @BinderThread
        @Override
        public void resized(ClientWindowFrames frames, boolean reportDraw,
                MergedConfiguration mergedConfiguration, InsetsState insetsState,
                boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int seqId,
                int resizeMode) {
            if (mOuter != null) {
                mOuter.mSplashScreenExecutor.execute(() -> {
            final TaskSnapshotWindow snapshot = mOuter.get();
            if (snapshot == null) {
                return;
            }
            snapshot.mSplashScreenExecutor.execute(() -> {
                if (mergedConfiguration != null
                            && mOuter.mOrientationOnCreation
                        && snapshot.mOrientationOnCreation
                        != mergedConfiguration.getMergedConfiguration().orientation) {
                    // The orientation of the screen is changing. We better remove the snapshot
                    // ASAP as we are going to wait on the new window in any case to unfreeze
                    // the screen, and the starting window is not needed anymore.
                        mOuter.clearWindowSynced();
                    snapshot.clearWindowSynced();
                } else if (reportDraw) {
                        if (mOuter.mHasDrawn) {
                            mOuter.reportDrawn();
                    if (snapshot.mHasDrawn) {
                        snapshot.reportDrawn();
                    }
                }
            });
        }
    }
    }

    /**
     * Helper class to draw the background of the system bars in regions the task snapshot isn't