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 Original line Diff line number Diff line
@@ -633,7 +633,7 @@ public class StartingSurfaceDrawer {
                    Slog.e(TAG, "Found empty splash screen, remove!");
                    Slog.e(TAG, "Found empty splash screen, remove!");
                    removeWindowInner(record.mDecorView, false);
                    removeWindowInner(record.mDecorView, false);
                }
                }
                mStartingWindowRecords.remove(taskId);

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


+25 −29
Original line number Original line 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.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.protolog.ShellProtoLogGroup;


import java.lang.ref.WeakReference;

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


    static TaskSnapshotWindow create(StartingWindowInfo info, IBinder appToken,
    static TaskSnapshotWindow create(StartingWindowInfo info, IBinder appToken,
@@ -306,21 +308,13 @@ public class TaskSnapshotWindow {
        mSystemBarBackgroundPainter.drawNavigationBarBackground(c);
        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.
        // Show the latest content as soon as possible for unlocking to home.
        if (mActivityType == ACTIVITY_TYPE_HOME) {
        if (mActivityType == ACTIVITY_TYPE_HOME) {
            removeImmediately();
            removeImmediately();
            onRemove.run();
            return;
            return;
        }
        }
        if (mScheduledRunnable != null) {
        mSplashScreenExecutor.removeCallbacks(mScheduledRunnable);
        mSplashScreenExecutor.removeCallbacks(mScheduledRunnable);
            mScheduledRunnable = null;
        }
        mScheduledRunnable = () -> {
            TaskSnapshotWindow.this.removeImmediately();
            onRemove.run();
        };
        final long delayRemovalTime = mHasImeSurface && deferRemoveForIme
        final long delayRemovalTime = mHasImeSurface && deferRemoveForIme
                ? MAX_DELAY_REMOVAL_TIME_IME_VISIBLE
                ? MAX_DELAY_REMOVAL_TIME_IME_VISIBLE
                : DELAY_REMOVAL_TIME_GENERAL;
                : DELAY_REMOVAL_TIME_GENERAL;
@@ -524,37 +518,39 @@ public class TaskSnapshotWindow {
        }
        }
    }
    }


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


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


        @BinderThread
        @Override
        @Override
        public void resized(ClientWindowFrames frames, boolean reportDraw,
        public void resized(ClientWindowFrames frames, boolean reportDraw,
                MergedConfiguration mergedConfiguration, InsetsState insetsState,
                MergedConfiguration mergedConfiguration, InsetsState insetsState,
                boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int seqId,
                boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int seqId,
                int resizeMode) {
                int resizeMode) {
            if (mOuter != null) {
            final TaskSnapshotWindow snapshot = mOuter.get();
                mOuter.mSplashScreenExecutor.execute(() -> {
            if (snapshot == null) {
                return;
            }
            snapshot.mSplashScreenExecutor.execute(() -> {
                if (mergedConfiguration != null
                if (mergedConfiguration != null
                            && mOuter.mOrientationOnCreation
                        && snapshot.mOrientationOnCreation
                        != mergedConfiguration.getMergedConfiguration().orientation) {
                        != mergedConfiguration.getMergedConfiguration().orientation) {
                    // The orientation of the screen is changing. We better remove the snapshot
                    // 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
                    // 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.
                    // the screen, and the starting window is not needed anymore.
                        mOuter.clearWindowSynced();
                    snapshot.clearWindowSynced();
                } else if (reportDraw) {
                } else if (reportDraw) {
                        if (mOuter.mHasDrawn) {
                    if (snapshot.mHasDrawn) {
                            mOuter.reportDrawn();
                        snapshot.reportDrawn();
                    }
                    }
                }
                }
            });
            });
        }
        }
    }
    }
    }


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