Merge "Fix PersistableBundle C++ -> Java interop" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-04-27 01:36:52 +00:00
committed by Android (Google) Code Review

View File

@@ -40,8 +40,9 @@ public class BaseBundle {
private static final String TAG = "Bundle";
static final boolean DEBUG = false;
// Keep in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
// Keep them in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
private static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
private static final int BUNDLE_MAGIC_NATIVE = 0x4C444E44; // 'B' 'N' 'D' 'N'
/**
* Flag indicating that this Bundle is okay to "defuse." That is, it's okay
@@ -90,6 +91,11 @@ public class BaseBundle {
*/
Parcel mParcelledData = null;
/**
* Whether {@link #mParcelledData} was generated by native coed or not.
*/
private boolean mParcelledByNative;
/**
* The ClassLoader used when unparcelling data from mParcelledData.
*/
@@ -223,7 +229,7 @@ public class BaseBundle {
synchronized (this) {
final Parcel source = mParcelledData;
if (source != null) {
initializeFromParcelLocked(source, /*recycleParcel=*/ true);
initializeFromParcelLocked(source, /*recycleParcel=*/ true, mParcelledByNative);
} else {
if (DEBUG) {
Log.d(TAG, "unparcel "
@@ -234,7 +240,8 @@ public class BaseBundle {
}
}
private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel) {
private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel,
boolean parcelledByNative) {
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());
@@ -251,6 +258,7 @@ public class BaseBundle {
mMap.erase();
}
mParcelledData = null;
mParcelledByNative = false;
return;
}
@@ -270,7 +278,15 @@ public class BaseBundle {
map.ensureCapacity(count);
}
try {
parcelledData.readArrayMapInternal(map, count, mClassLoader);
if (parcelledByNative) {
// If it was parcelled by native code, then the array map keys aren't sorted
// by their hash codes, so use the safe (slow) one.
parcelledData.readArrayMapSafelyInternal(map, count, mClassLoader);
} else {
// If parcelled by Java, we know the contents are sorted properly,
// so we can use ArrayMap.append().
parcelledData.readArrayMapInternal(map, count, mClassLoader);
}
} catch (BadParcelableException e) {
if (sShouldDefuse) {
Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
@@ -284,6 +300,7 @@ public class BaseBundle {
recycleParcel(parcelledData);
}
mParcelledData = null;
mParcelledByNative = false;
}
if (DEBUG) {
Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
@@ -403,14 +420,17 @@ public class BaseBundle {
if (from.mParcelledData != null) {
if (from.isEmptyParcel()) {
mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
mParcelledByNative = false;
} else {
mParcelledData = Parcel.obtain();
mParcelledData.appendFrom(from.mParcelledData, 0,
from.mParcelledData.dataSize());
mParcelledData.setDataPosition(0);
mParcelledByNative = from.mParcelledByNative;
}
} else {
mParcelledData = null;
mParcelledByNative = false;
}
if (from.mMap != null) {
@@ -1538,7 +1558,7 @@ public class BaseBundle {
} else {
int length = mParcelledData.dataSize();
parcel.writeInt(length);
parcel.writeInt(BUNDLE_MAGIC);
parcel.writeInt(mParcelledByNative ? BUNDLE_MAGIC_NATIVE : BUNDLE_MAGIC);
parcel.appendFrom(mParcelledData, 0, length);
}
return;
@@ -1585,11 +1605,14 @@ public class BaseBundle {
} else if (length == 0) {
// Empty Bundle or end of data.
mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
mParcelledByNative = false;
return;
}
final int magic = parcel.readInt();
if (magic != BUNDLE_MAGIC) {
final boolean isJavaBundle = magic == BUNDLE_MAGIC;
final boolean isNativeBundle = magic == BUNDLE_MAGIC_NATIVE;
if (!isJavaBundle && !isNativeBundle) {
throw new IllegalStateException("Bad magic number for Bundle: 0x"
+ Integer.toHexString(magic));
}
@@ -1598,7 +1621,7 @@ public class BaseBundle {
// If the parcel has a read-write helper, then we can't lazily-unparcel it, so just
// unparcel right away.
synchronized (this) {
initializeFromParcelLocked(parcel, /*recycleParcel=*/ false);
initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle);
}
return;
}
@@ -1616,6 +1639,7 @@ public class BaseBundle {
p.setDataPosition(0);
mParcelledData = p;
mParcelledByNative = isNativeBundle;
}
/** {@hide} */