Merge "Avoid full unparcelling where possible in Bundle"
This commit is contained in:
@@ -3724,7 +3724,6 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
Intent intent = new Intent(activityIntent);
|
||||
intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
|
||||
intent.removeUnsafeExtras();
|
||||
content.setDefaultIntent(intent);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -8567,16 +8567,6 @@ public class Intent implements Parcelable, Cloneable {
|
||||
: 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 itself as-is.
|
||||
|
||||
@@ -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);
|
||||
return mMap;
|
||||
}
|
||||
@@ -519,7 +527,7 @@ public class BaseBundle {
|
||||
final int N = fromMap.size();
|
||||
mMap = new ArrayMap<>(N);
|
||||
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 {
|
||||
@@ -1791,7 +1799,7 @@ public class BaseBundle {
|
||||
pw.println("[null]");
|
||||
return;
|
||||
}
|
||||
final ArrayMap<String, Object> map = bundle.getMap();
|
||||
final ArrayMap<String, Object> map = bundle.getItemwiseMap();
|
||||
for (int i = 0; i < map.size(); i++) {
|
||||
dumpStats(pw, map.keyAt(i), map.valueAt(i));
|
||||
}
|
||||
|
||||
@@ -347,56 +347,6 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
|
||||
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} */
|
||||
@Override
|
||||
public void putObject(@Nullable String key, @Nullable Object value) {
|
||||
|
||||
@@ -3532,14 +3532,17 @@ public final class Parcel {
|
||||
Parcel source = mSource;
|
||||
if (source != null) {
|
||||
synchronized (source) {
|
||||
int restore = source.dataPosition();
|
||||
try {
|
||||
source.setDataPosition(mPosition);
|
||||
mObject = source.readValue(mLoader);
|
||||
} finally {
|
||||
source.setDataPosition(restore);
|
||||
// Check mSource != null guarantees callers won't ever see different objects.
|
||||
if (mSource != null) {
|
||||
int restore = source.dataPosition();
|
||||
try {
|
||||
source.setDataPosition(mPosition);
|
||||
mObject = source.readValue(mLoader);
|
||||
} finally {
|
||||
source.setDataPosition(restore);
|
||||
}
|
||||
mSource = null;
|
||||
}
|
||||
mSource = null;
|
||||
}
|
||||
}
|
||||
return mObject;
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.xmlpull.v1.XmlSerializer;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
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.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public PersistableBundle(Bundle b) {
|
||||
this(b.getMap());
|
||||
this(b.getItemwiseMap());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user