Merge "Avoid full unparcelling where possible in Bundle"

This commit is contained in:
Treehugger Robot
2021-10-06 12:06:59 +00:00
committed by Gerrit Code Review
6 changed files with 28 additions and 73 deletions

View File

@@ -3724,7 +3724,6 @@ public final class ActivityThread extends ClientTransactionHandler {
Intent intent = new Intent(activityIntent); Intent intent = new Intent(activityIntent);
intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)); | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
intent.removeUnsafeExtras();
content.setDefaultIntent(intent); content.setDefaultIntent(intent);
} }
} else { } else {

View File

@@ -8567,16 +8567,6 @@ public class Intent implements Parcelable, Cloneable {
: null; : null;
} }
/**
* Filter extras to only basic types.
* @hide
*/
public void removeUnsafeExtras() {
if (mExtras != null) {
mExtras = mExtras.filterValues();
}
}
/** /**
* @return Whether {@link #maybeStripForHistory} will return an lightened intent or * @return Whether {@link #maybeStripForHistory} will return an lightened intent or
* return itself as-is. * return itself as-is.

View File

@@ -395,8 +395,16 @@ public class BaseBundle {
} }
} }
/** @hide */ /**
ArrayMap<String, Object> getMap() { * Returns the backing map of this bundle after deserializing every item.
*
* <p><b>Warning:</b> This method will deserialize every item on the bundle, including custom
* types such as {@link Parcelable} and {@link Serializable}, so only use this when you trust
* the source. Specifically don't use this method on app-provided bundles.
*
* @hide
*/
ArrayMap<String, Object> getItemwiseMap() {
unparcel(/* itemwise */ true); unparcel(/* itemwise */ true);
return mMap; return mMap;
} }
@@ -519,7 +527,7 @@ public class BaseBundle {
final int N = fromMap.size(); final int N = fromMap.size();
mMap = new ArrayMap<>(N); mMap = new ArrayMap<>(N);
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
mMap.append(fromMap.keyAt(i), deepCopyValue(from.getValueAt(i))); mMap.append(fromMap.keyAt(i), deepCopyValue(fromMap.valueAt(i)));
} }
} }
} else { } else {
@@ -1791,7 +1799,7 @@ public class BaseBundle {
pw.println("[null]"); pw.println("[null]");
return; return;
} }
final ArrayMap<String, Object> map = bundle.getMap(); final ArrayMap<String, Object> map = bundle.getItemwiseMap();
for (int i = 0; i < map.size(); i++) { for (int i = 0; i < map.size(); i++) {
dumpStats(pw, map.keyAt(i), map.valueAt(i)); dumpStats(pw, map.keyAt(i), map.valueAt(i));
} }

View File

@@ -347,56 +347,6 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
return (mFlags & FLAG_HAS_FDS) != 0; return (mFlags & FLAG_HAS_FDS) != 0;
} }
/**
* Filter values in Bundle to only basic types.
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Bundle filterValues() {
unparcel(/* itemwise */ true);
Bundle bundle = this;
if (mMap != null) {
ArrayMap<String, Object> map = mMap;
for (int i = map.size() - 1; i >= 0; i--) {
Object value = map.valueAt(i);
if (PersistableBundle.isValidType(value)) {
continue;
}
if (value instanceof Bundle) {
Bundle newBundle = ((Bundle)value).filterValues();
if (newBundle != value) {
if (map == mMap) {
// The filter had to generate a new bundle, but we have not yet
// created a new one here. Do that now.
bundle = new Bundle(this);
// Note the ArrayMap<> constructor is guaranteed to generate
// a new object with items in the same order as the original.
map = bundle.mMap;
}
// Replace this current entry with the new child bundle.
map.setValueAt(i, newBundle);
}
continue;
}
if (value.getClass().getName().startsWith("android.")) {
continue;
}
if (map == mMap) {
// This is the first time we have had to remove something, that means we
// need to switch to a new Bundle.
bundle = new Bundle(this);
// Note the ArrayMap<> constructor is guaranteed to generate
// a new object with items in the same order as the original.
map = bundle.mMap;
}
map.removeAt(i);
}
}
mFlags |= FLAG_HAS_FDS_KNOWN;
mFlags &= ~FLAG_HAS_FDS;
return bundle;
}
/** {@hide} */ /** {@hide} */
@Override @Override
public void putObject(@Nullable String key, @Nullable Object value) { public void putObject(@Nullable String key, @Nullable Object value) {

View File

@@ -3532,6 +3532,8 @@ public final class Parcel {
Parcel source = mSource; Parcel source = mSource;
if (source != null) { if (source != null) {
synchronized (source) { synchronized (source) {
// Check mSource != null guarantees callers won't ever see different objects.
if (mSource != null) {
int restore = source.dataPosition(); int restore = source.dataPosition();
try { try {
source.setDataPosition(mPosition); source.setDataPosition(mPosition);
@@ -3542,6 +3544,7 @@ public final class Parcel {
mSource = null; mSource = null;
} }
} }
}
return mObject; return mObject;
} }

View File

@@ -34,6 +34,7 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@@ -100,6 +101,10 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
/** /**
* Constructs a PersistableBundle from a Bundle. Does only a shallow copy of the Bundle. * Constructs a PersistableBundle from a Bundle. Does only a shallow copy of the Bundle.
* *
* <p><b>Warning:</b> This method will deserialize every item on the bundle, including custom
* types such as {@link Parcelable} and {@link Serializable}, so only use this when you trust
* the source. Specifically don't use this method on app-provided bundles.
*
* @param b a Bundle to be copied. * @param b a Bundle to be copied.
* *
* @throws IllegalArgumentException if any element of {@code b} cannot be persisted. * @throws IllegalArgumentException if any element of {@code b} cannot be persisted.
@@ -107,7 +112,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
* @hide * @hide
*/ */
public PersistableBundle(Bundle b) { public PersistableBundle(Bundle b) {
this(b.getMap()); this(b.getItemwiseMap());
} }
/** /**