Merge "Avoid full unparcelling where possible in Bundle" am: 3ad4ecc296 am: 3aaf984908
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1842226 Change-Id: I598b562401860e5e838f891eb2944e49becc2fe6
This commit is contained in:
@@ -3887,7 +3887,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 {
|
||||||
|
|||||||
@@ -8834,16 +8834,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.
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -348,56 +348,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) {
|
||||||
|
|||||||
@@ -3573,14 +3573,17 @@ public final class Parcel {
|
|||||||
Parcel source = mSource;
|
Parcel source = mSource;
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
synchronized (source) {
|
synchronized (source) {
|
||||||
int restore = source.dataPosition();
|
// Check mSource != null guarantees callers won't ever see different objects.
|
||||||
try {
|
if (mSource != null) {
|
||||||
source.setDataPosition(mPosition);
|
int restore = source.dataPosition();
|
||||||
mObject = source.readValue(mLoader);
|
try {
|
||||||
} finally {
|
source.setDataPosition(mPosition);
|
||||||
source.setDataPosition(restore);
|
mObject = source.readValue(mLoader);
|
||||||
|
} finally {
|
||||||
|
source.setDataPosition(restore);
|
||||||
|
}
|
||||||
|
mSource = null;
|
||||||
}
|
}
|
||||||
mSource = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mObject;
|
return mObject;
|
||||||
|
|||||||
@@ -35,6 +35,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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,6 +104,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.
|
||||||
@@ -110,7 +115,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user