From 9b5f4aa48da8fd8fe6f8a5c3fe53f5dbef1664f1 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 15 Nov 2019 11:30:15 -0800 Subject: [PATCH] Fix two small thumbnail leaks - Even though the object wrapper is used within the same process, the call to start the fallback recents activity means that the system still ends up holding a reference to a copy of the intent and its extras, including the reference to the wrapper and the thumbnail it references, until the activity is destroyed (or next restarted). We need to clear the actual object strong ref after it's used when handling the new intent. - The running task can have an associated thumbnail, so we should also clear the tmp running task ref when we leave overview. Change-Id: Icdc0b1989b13927d112949797752615014856970 --- .../src/com/android/quickstep/RecentsActivity.java | 6 +++++- .../src/com/android/quickstep/views/RecentsView.java | 5 +++++ src/com/android/launcher3/util/ObjectWrapper.java | 6 +++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 7b8ec4d886..e0e20ee27e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -89,9 +89,13 @@ public final class RecentsActivity extends BaseRecentsActivity { int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0); IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL); if (taskID != 0 && thumbnail instanceof ObjectWrapper) { - ThumbnailData thumbnailData = ((ObjectWrapper) thumbnail).get(); + ObjectWrapper obj = (ObjectWrapper) thumbnail; + ThumbnailData thumbnailData = obj.get(); mFallbackRecentsView.showCurrentTask(taskID); mFallbackRecentsView.updateThumbnail(taskID, thumbnailData); + // Clear the ref since any reference to the extras on the system side will still + // hold a reference to the wrapper + obj.clear(); } } intent.removeExtra(EXTRA_TASK_ID); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 56c2dd5dbd..6e7214e108 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -485,6 +485,11 @@ public abstract class RecentsView extends PagedView impl public void setOverviewStateEnabled(boolean enabled) { mOverviewStateEnabled = enabled; updateTaskStackListenerState(); + if (!enabled) { + // Reset the running task when leaving overview since it can still have a reference to + // its thumbnail + mTmpRunningTask = null; + } } public void onDigitalWellbeingToastShown() { diff --git a/src/com/android/launcher3/util/ObjectWrapper.java b/src/com/android/launcher3/util/ObjectWrapper.java index b69243117a..e5b4707074 100644 --- a/src/com/android/launcher3/util/ObjectWrapper.java +++ b/src/com/android/launcher3/util/ObjectWrapper.java @@ -25,7 +25,7 @@ import android.os.IBinder; */ public class ObjectWrapper extends Binder { - private final T mObject; + private T mObject; public ObjectWrapper(T object) { mObject = object; @@ -35,6 +35,10 @@ public class ObjectWrapper extends Binder { return mObject; } + public void clear() { + mObject = null; + } + public static IBinder wrap(Object obj) { return new ObjectWrapper<>(obj); }