From c8da7519c5a80344f42cf1054b003823b72fe62d Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Mon, 21 Mar 2022 19:30:38 +0800 Subject: 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 --- .../startingsurface/StartingSurfaceDrawer.java | 6 +-- .../shell/startingsurface/TaskSnapshotWindow.java | 54 ++++++++++------------ 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java index 04d6ef7f9505..11f23e3e941b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java @@ -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); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java index 2debcf296ea8..fd6e59ee6a81 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java @@ -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(); - }; + mSplashScreenExecutor.removeCallbacks(mScheduledRunnable); final long delayRemovalTime = mHasImeSurface && deferRemoveForIme ? MAX_DELAY_REMOVAL_TIME_IME_VISIBLE : DELAY_REMOVAL_TIME_GENERAL; @@ -524,35 +518,37 @@ public class TaskSnapshotWindow { } } - @BinderThread static class Window extends BaseIWindow { - private TaskSnapshotWindow mOuter; + private WeakReference 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(() -> { - if (mergedConfiguration != null - && mOuter.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(); - } else if (reportDraw) { - if (mOuter.mHasDrawn) { - mOuter.reportDrawn(); - } - } - }); + final TaskSnapshotWindow snapshot = mOuter.get(); + if (snapshot == null) { + return; } + snapshot.mSplashScreenExecutor.execute(() -> { + if (mergedConfiguration != null + && 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. + snapshot.clearWindowSynced(); + } else if (reportDraw) { + if (snapshot.mHasDrawn) { + snapshot.reportDrawn(); + } + } + }); } } -- cgit v1.2.3-59-g8ed1b