From d5063d26f9de055fb02cd5de0515f5269c11febd Mon Sep 17 00:00:00 2001 From: TYM Tsai Date: Mon, 31 Oct 2022 16:34:28 +0800 Subject: [PATCH] Avoid to hold a strong reference to Context object We only use parts of Context in the Content Capture manager and main session, we don't need to cache context object which will cause some memory issues. This change will extract the necessary information to save it, instead of caching the entire context object. Bug: 256247718 Fixes: 239192932 Test: atest CtsContentCaptureServiceTestCases Change-Id: Id7b5e8617c521f31879199b0f2c7e18204bb7526 Merged-In: Id7b5e8617c521f31879199b0f2c7e18204bb7526 (cherry picked from commit c3380c162b27dab9664dd8556611ec20f309ba67) --- .../contentcapture/ContentCaptureManager.java | 32 +++++++++++++++++-- .../MainContentCaptureSession.java | 5 ++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 1664637eac567..d067d4bc366b1 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -378,7 +378,7 @@ public final class ContentCaptureManager { private final Object mLock = new Object(); @NonNull - private final Context mContext; + private final StrippedContext mContext; @NonNull private final IContentCaptureManager mService; @@ -413,10 +413,38 @@ public final class ContentCaptureManager { ComponentName contentCaptureClientGetComponentName(); } + /** @hide */ + static class StrippedContext { + final String mPackageName; + final String mContext; + final @UserIdInt int mUserId; + + private StrippedContext(Context context) { + mPackageName = context.getPackageName(); + mContext = context.toString(); + mUserId = context.getUserId(); + } + + @Override + public String toString() { + return mContext; + } + + public String getPackageName() { + return mPackageName; + } + + @UserIdInt + public int getUserId() { + return mUserId; + } + } + /** @hide */ public ContentCaptureManager(@NonNull Context context, @NonNull IContentCaptureManager service, @NonNull ContentCaptureOptions options) { - mContext = Objects.requireNonNull(context, "context cannot be null"); + Objects.requireNonNull(context, "context cannot be null"); + mContext = new StrippedContext(context); mService = Objects.requireNonNull(service, "service cannot be null"); mOptions = Objects.requireNonNull(options, "options cannot be null"); diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 90384b5203154..1f5e462d71fd8 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -36,7 +36,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UiThread; import android.content.ComponentName; -import android.content.Context; import android.content.pm.ParceledListSlice; import android.graphics.Insets; import android.graphics.Rect; @@ -103,7 +102,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { private final AtomicBoolean mDisabled = new AtomicBoolean(false); @NonNull - private final Context mContext; + private final ContentCaptureManager.StrippedContext mContext; @NonNull private final ContentCaptureManager mManager; @@ -197,7 +196,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } } - protected MainContentCaptureSession(@NonNull Context context, + protected MainContentCaptureSession(@NonNull ContentCaptureManager.StrippedContext context, @NonNull ContentCaptureManager manager, @NonNull Handler handler, @NonNull IContentCaptureManager systemServerInterface) { mContext = context;