diff options
| -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 |