Merge "Improve @hide Parcel.hasFileDescriptors(Object)"

This commit is contained in:
Bernardo Rufino
2021-11-05 14:51:18 +00:00
committed by Gerrit Code Review
2 changed files with 51 additions and 56 deletions

View File

@@ -324,28 +324,10 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/ */
public boolean hasFileDescriptors() { public boolean hasFileDescriptors() {
if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) { if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
boolean fdFound = false; // keep going until we find one or run out of data Parcel p = mParcelledData;
mFlags = (Parcel.hasFileDescriptors((p != null) ? p : mMap))
if (mParcelledData != null) { ? mFlags | FLAG_HAS_FDS
if (mParcelledData.hasFileDescriptors()) { : mFlags & ~FLAG_HAS_FDS;
fdFound = true;
}
} else {
// It's been unparcelled, so we need to walk the map
for (int i=mMap.size()-1; i>=0; i--) {
Object obj = mMap.valueAt(i);
if (Parcel.hasFileDescriptors(obj)) {
fdFound = true;
break;
}
}
}
if (fdFound) {
mFlags |= FLAG_HAS_FDS;
} else {
mFlags &= ~FLAG_HAS_FDS;
}
mFlags |= FLAG_HAS_FDS_KNOWN; mFlags |= FLAG_HAS_FDS_KNOWN;
} }
return (mFlags & FLAG_HAS_FDS) != 0; return (mFlags & FLAG_HAS_FDS) != 0;

View File

@@ -747,59 +747,72 @@ public final class Parcel {
} }
/** /**
* Check if the object used in {@link #readValue(ClassLoader)} / {@link #writeValue(Object)} * Check if the object has file descriptors.
* has file descriptors. *
* <p>Objects supported are {@link Parcel} and objects that can be passed to {@link
* #writeValue(Object)}}
* *
* <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method * <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method
* for that. * for that.
* *
* @throws IllegalArgumentException if you provide any object not supported by above methods. * @throws IllegalArgumentException if you provide any object not supported by above methods
* Most notably, if you pass {@link Parcel}, this method will throw, for that check * (including if the unsupported object is inside a nested container).
* {@link Parcel#hasFileDescriptors()}
* *
* @hide * @hide
*/ */
public static boolean hasFileDescriptors(Object value) { public static boolean hasFileDescriptors(Object value) {
if (value instanceof LazyValue) { if (value instanceof Parcel) {
return ((LazyValue) value).hasFileDescriptors(); Parcel parcel = (Parcel) value;
} else if (value instanceof Parcelable) { if (parcel.hasFileDescriptors()) {
if ((((Parcelable) value).describeContents()
& Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
return true; return true;
} }
} else if (value instanceof Parcelable[]) { } else if (value instanceof LazyValue) {
Parcelable[] array = (Parcelable[]) value; LazyValue lazy = (LazyValue) value;
for (int n = array.length - 1; n >= 0; n--) { if (lazy.hasFileDescriptors()) {
Parcelable p = array[n]; return true;
if (p != null && ((p.describeContents() }
& Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) { } else if (value instanceof Parcelable) {
Parcelable parcelable = (Parcelable) value;
if ((parcelable.describeContents() & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
return true;
}
} else if (value instanceof ArrayMap<?, ?>) {
ArrayMap<?, ?> map = (ArrayMap<?, ?>) value;
for (int i = 0, n = map.size(); i < n; i++) {
if (hasFileDescriptors(map.keyAt(i))
|| hasFileDescriptors(map.valueAt(i))) {
return true;
}
}
} else if (value instanceof Map<?, ?>) {
Map<?, ?> map = (Map<?, ?>) value;
for (Map.Entry<?, ?> entry : map.entrySet()) {
if (hasFileDescriptors(entry.getKey())
|| hasFileDescriptors(entry.getValue())) {
return true;
}
}
} else if (value instanceof List<?>) {
List<?> list = (List<?>) value;
for (int i = 0, n = list.size(); i < n; i++) {
if (hasFileDescriptors(list.get(i))) {
return true; return true;
} }
} }
} else if (value instanceof SparseArray<?>) { } else if (value instanceof SparseArray<?>) {
SparseArray<?> array = (SparseArray<?>) value; SparseArray<?> array = (SparseArray<?>) value;
for (int n = array.size() - 1; n >= 0; n--) { for (int i = 0, n = array.size(); i < n; i++) {
Object object = array.valueAt(n); if (hasFileDescriptors(array.valueAt(i))) {
if (object instanceof Parcelable) {
Parcelable p = (Parcelable) object;
if (p != null && (p.describeContents()
& Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
return true; return true;
} }
} }
} } else if (value instanceof Object[]) {
} else if (value instanceof ArrayList<?>) { Object[] array = (Object[]) value;
ArrayList<?> array = (ArrayList<?>) value; for (int i = 0, n = array.length; i < n; i++) {
for (int n = array.size() - 1; n >= 0; n--) { if (hasFileDescriptors(array[i])) {
Object object = array.get(n);
if (object instanceof Parcelable) {
Parcelable p = (Parcelable) object;
if (p != null && ((p.describeContents()
& Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
return true; return true;
} }
} }
}
} else { } else {
getValueType(value); // Will throw if value is not supported getValueType(value); // Will throw if value is not supported
} }