Merge "Maybe fix issue #28457907: Pebble app crash + reboot" into nyc-dev
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 004b2ce..e83c756 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -169,7 +169,7 @@
}
if (b.mMap != null) {
- mMap = new ArrayMap<String, Object>(b.mMap);
+ mMap = new ArrayMap<>(b.mMap);
} else {
mMap = null;
}
@@ -226,56 +226,62 @@
* using the currently assigned class loader.
*/
/* package */ synchronized void unparcel() {
- if (mParcelledData == null) {
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + ": no parcelled data");
- return;
- }
-
- if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
- Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
- + "clobber all data inside!", new Throwable());
- }
-
- if (isEmptyParcel()) {
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + ": empty");
- if (mMap == null) {
- mMap = new ArrayMap<String, Object>(1);
- } else {
- mMap.erase();
+ synchronized (this) {
+ final Parcel parcelledData = mParcelledData;
+ if (parcelledData == null) {
+ if (DEBUG) Log.d(TAG, "unparcel "
+ + Integer.toHexString(System.identityHashCode(this))
+ + ": no parcelled data");
+ return;
}
- mParcelledData = null;
- return;
- }
- int N = mParcelledData.readInt();
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + ": reading " + N + " maps");
- if (N < 0) {
- return;
- }
- if (mMap == null) {
- mMap = new ArrayMap<String, Object>(N);
- } else {
- mMap.erase();
- mMap.ensureCapacity(N);
- }
- try {
- mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
- } catch (BadParcelableException e) {
- if (sShouldDefuse) {
- Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
- mMap.erase();
- } else {
- throw e;
+ if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
+ Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
+ + "clobber all data inside!", new Throwable());
}
- } finally {
- mParcelledData.recycle();
- mParcelledData = null;
+
+ if (isEmptyParcel()) {
+ if (DEBUG) Log.d(TAG, "unparcel "
+ + Integer.toHexString(System.identityHashCode(this)) + ": empty");
+ if (mMap == null) {
+ mMap = new ArrayMap<>(1);
+ } else {
+ mMap.erase();
+ }
+ mParcelledData = null;
+ return;
+ }
+
+ int N = parcelledData.readInt();
+ if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ + ": reading " + N + " maps");
+ if (N < 0) {
+ return;
+ }
+ ArrayMap<String, Object> map = mMap;
+ if (map == null) {
+ map = new ArrayMap<>(N);
+ } else {
+ map.erase();
+ map.ensureCapacity(N);
+ }
+ try {
+ parcelledData.readArrayMapInternal(map, N, mClassLoader);
+ } catch (BadParcelableException e) {
+ if (sShouldDefuse) {
+ Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
+ map.erase();
+ } else {
+ throw e;
+ }
+ } finally {
+ mMap = map;
+ parcelledData.recycle();
+ mParcelledData = null;
+ }
+ if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ + " final map: " + mMap);
}
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + " final map: " + mMap);
}
/**
@@ -1375,14 +1381,18 @@
void writeToParcelInner(Parcel parcel, int flags) {
// Keep implementation in sync with writeToParcel() in
// frameworks/native/libs/binder/PersistableBundle.cpp.
- if (mParcelledData != null) {
+ final Parcel parcelledData;
+ synchronized (this) {
+ parcelledData = mParcelledData;
+ }
+ if (parcelledData != null) {
if (isEmptyParcel()) {
parcel.writeInt(0);
} else {
- int length = mParcelledData.dataSize();
+ int length = parcelledData.dataSize();
parcel.writeInt(length);
parcel.writeInt(BUNDLE_MAGIC);
- parcel.appendFrom(mParcelledData, 0, length);
+ parcel.appendFrom(parcelledData, 0, length);
}
} else {
// Special case for empty bundles.