diff options
| author | 2022-06-15 09:51:53 +0000 | |
|---|---|---|
| committer | 2022-06-15 09:51:53 +0000 | |
| commit | 34b061c00a781c1783b7c89a2d49b2b68e44758b (patch) | |
| tree | 5b55d9c8a6d3e9135a5b5a2de0f01f5b31ae69e4 | |
| parent | 6e64c643cff30a3e7e7c1d4d4492f995d4977f93 (diff) | |
| parent | 1b74a666d3b4c6a5bf063671eb5dac62a74a9c21 (diff) | |
Merge "BaseBundle.java: Recycle underlying parcel when bundle is cleared."
| -rw-r--r-- | core/java/android/os/BaseBundle.java | 26 | ||||
| -rw-r--r-- | core/java/android/os/Bundle.java | 2 |
2 files changed, 27 insertions, 1 deletions
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index e5dab0539a8e..0418a4bb9f80 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -31,6 +31,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; import java.io.Serializable; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Set; import java.util.function.BiFunction; @@ -102,7 +103,7 @@ public class BaseBundle { /* * If mParcelledData is non-null, then mMap will be null and the * data are stored as a Parcel containing a Bundle. When the data - * are unparcelled, mParcelledData willbe set to null. + * are unparcelled, mParcelledData will be set to null. */ @UnsupportedAppUsage volatile Parcel mParcelledData = null; @@ -112,6 +113,19 @@ public class BaseBundle { */ private boolean mParcelledByNative; + /* + * Flag indicating if mParcelledData is only referenced in this bundle. + * mParcelledData could be referenced by other bundles if mMap contains lazy values, + * and bundle data is copied to another bundle using putAll or the copy constructors. + */ + boolean mOwnsLazyValues = true; + + /* + * As mParcelledData is set to null when it is unparcelled, we keep a weak reference to + * it to aid in recycling it. Do not use this reference otherwise. + */ + private WeakReference<Parcel> mWeakParcelledData = null; + /** * The ClassLoader used when unparcelling data from mParcelledData. */ @@ -200,6 +214,9 @@ public class BaseBundle { mClassLoader = from.mClassLoader; if (from.mMap != null) { + mOwnsLazyValues = false; + from.mOwnsLazyValues = false; + if (!deep) { mMap = new ArrayMap<>(from.mMap); } else { @@ -434,6 +451,9 @@ public class BaseBundle { mMap = map; if (recycleParcel) { recycleParcel(parcelledData); + mWeakParcelledData = null; + } else { + mWeakParcelledData = new WeakReference<>(parcelledData); } mParcelledByNative = false; mParcelledData = null; @@ -575,6 +595,10 @@ public class BaseBundle { */ public void clear() { unparcel(); + if (mOwnsLazyValues && mWeakParcelledData != null) { + recycleParcel(mWeakParcelledData.get()); + mWeakParcelledData = null; + } mMap.clear(); } diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index cf28c1639fac..7e355d95cdb3 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -301,6 +301,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { public void putAll(Bundle bundle) { unparcel(); bundle.unparcel(); + mOwnsLazyValues = false; + bundle.mOwnsLazyValues = false; mMap.putAll(bundle.mMap); // FD state is now known if and only if both bundles already knew |