summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hani Kazmi <hanikazmi@google.com> 2022-06-15 09:51:53 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2022-06-15 09:51:53 +0000
commit34b061c00a781c1783b7c89a2d49b2b68e44758b (patch)
tree5b55d9c8a6d3e9135a5b5a2de0f01f5b31ae69e4
parent6e64c643cff30a3e7e7c1d4d4492f995d4977f93 (diff)
parent1b74a666d3b4c6a5bf063671eb5dac62a74a9c21 (diff)
Merge "BaseBundle.java: Recycle underlying parcel when bundle is cleared."
-rw-r--r--core/java/android/os/BaseBundle.java26
-rw-r--r--core/java/android/os/Bundle.java2
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