BaseBundle.java: Recycle underlying parcel when bundle is cleared. am: 2685de9862

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18795008

Change-Id: If037011bab47819a0a0678570904b834041e34c7
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Hani Kazmi
2022-06-14 09:30:28 +00:00
committed by Automerger Merge Worker
2 changed files with 27 additions and 1 deletions

View File

@@ -31,6 +31,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import java.io.Serializable; import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@@ -102,7 +103,7 @@ public class BaseBundle {
/* /*
* If mParcelledData is non-null, then mMap will be null and the * If mParcelledData is non-null, then mMap will be null and the
* data are stored as a Parcel containing a Bundle. When the data * 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 @UnsupportedAppUsage
volatile Parcel mParcelledData = null; volatile Parcel mParcelledData = null;
@@ -112,6 +113,19 @@ public class BaseBundle {
*/ */
private boolean mParcelledByNative; 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. * The ClassLoader used when unparcelling data from mParcelledData.
*/ */
@@ -200,6 +214,9 @@ public class BaseBundle {
mClassLoader = from.mClassLoader; mClassLoader = from.mClassLoader;
if (from.mMap != null) { if (from.mMap != null) {
mOwnsLazyValues = false;
from.mOwnsLazyValues = false;
if (!deep) { if (!deep) {
mMap = new ArrayMap<>(from.mMap); mMap = new ArrayMap<>(from.mMap);
} else { } else {
@@ -434,6 +451,9 @@ public class BaseBundle {
mMap = map; mMap = map;
if (recycleParcel) { if (recycleParcel) {
recycleParcel(parcelledData); recycleParcel(parcelledData);
mWeakParcelledData = null;
} else {
mWeakParcelledData = new WeakReference<>(parcelledData);
} }
mParcelledByNative = false; mParcelledByNative = false;
mParcelledData = null; mParcelledData = null;
@@ -575,6 +595,10 @@ public class BaseBundle {
*/ */
public void clear() { public void clear() {
unparcel(); unparcel();
if (mOwnsLazyValues && mWeakParcelledData != null) {
recycleParcel(mWeakParcelledData.get());
mWeakParcelledData = null;
}
mMap.clear(); mMap.clear();
} }

View File

@@ -301,6 +301,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
public void putAll(Bundle bundle) { public void putAll(Bundle bundle) {
unparcel(); unparcel();
bundle.unparcel(); bundle.unparcel();
mOwnsLazyValues = false;
bundle.mOwnsLazyValues = false;
mMap.putAll(bundle.mMap); mMap.putAll(bundle.mMap);
// FD state is now known if and only if both bundles already knew // FD state is now known if and only if both bundles already knew