diff options
Diffstat (limited to 'core/java/android/os/Bundle.java')
| -rw-r--r-- | core/java/android/os/Bundle.java | 106 |
1 files changed, 70 insertions, 36 deletions
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index be9566c3e0a0..7ef86f22d86e 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -27,11 +27,17 @@ import java.util.ArrayList; import java.util.List; /** - * A mapping from String values to various Parcelable types. + * A mapping from String keys to various {@link Parcelable} values. * + * @see PersistableBundle */ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { + private static final int FLAG_HAS_FDS = 1 << 8; + private static final int FLAG_HAS_FDS_KNOWN = 1 << 9; + private static final int FLAG_ALLOW_FDS = 1 << 10; + public static final Bundle EMPTY; + static final Parcel EMPTY_PARCEL; static { @@ -40,15 +46,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { EMPTY_PARCEL = BaseBundle.EMPTY_PARCEL; } - private boolean mHasFds = false; - private boolean mFdsKnown = true; - private boolean mAllowFds = true; - /** * Constructs a new, empty Bundle. */ public Bundle() { super(); + mFlags = FLAG_HAS_FDS_KNOWN; } /** @@ -59,16 +62,18 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { */ Bundle(Parcel parcelledData) { super(parcelledData); - - mHasFds = mParcelledData.hasFileDescriptors(); - mFdsKnown = true; + mFlags = FLAG_HAS_FDS_KNOWN; + if (mParcelledData.hasFileDescriptors()) { + mFlags |= FLAG_HAS_FDS; + } } /* package */ Bundle(Parcel parcelledData, int length) { super(parcelledData, length); - - mHasFds = mParcelledData.hasFileDescriptors(); - mFdsKnown = true; + mFlags = FLAG_HAS_FDS_KNOWN; + if (mParcelledData.hasFileDescriptors()) { + mFlags |= FLAG_HAS_FDS; + } } /** @@ -80,6 +85,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { */ public Bundle(ClassLoader loader) { super(loader); + mFlags = FLAG_HAS_FDS_KNOWN; } /** @@ -90,6 +96,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { */ public Bundle(int capacity) { super(capacity); + mFlags = FLAG_HAS_FDS_KNOWN; } /** @@ -100,9 +107,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { */ public Bundle(Bundle b) { super(b); - - mHasFds = b.mHasFds; - mFdsKnown = b.mFdsKnown; + mFlags = b.mFlags; } /** @@ -113,6 +118,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { */ public Bundle(PersistableBundle b) { super(b); + mFlags = FLAG_HAS_FDS_KNOWN; } /** @@ -152,14 +158,37 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { return super.getClassLoader(); } - /** @hide */ + /** {@hide} */ public boolean setAllowFds(boolean allowFds) { - boolean orig = mAllowFds; - mAllowFds = allowFds; + final boolean orig = (mFlags & FLAG_ALLOW_FDS) != 0; + if (allowFds) { + mFlags |= FLAG_ALLOW_FDS; + } else { + mFlags &= ~FLAG_ALLOW_FDS; + } return orig; } /** + * Mark if this Bundle is okay to "defuse." That is, it's okay for system + * processes to ignore any {@link BadParcelableException} encountered when + * unparceling it, leaving an empty bundle in its place. + * <p> + * This should <em>only</em> be set when the Bundle reaches its final + * destination, otherwise a system process may clobber contents that were + * destined for an app that could have unparceled them. + * + * @hide + */ + public void setDefusable(boolean defusable) { + if (defusable) { + mFlags |= FLAG_DEFUSABLE; + } else { + mFlags &= ~FLAG_DEFUSABLE; + } + } + + /** * Clones the current Bundle. The internal map is cloned, but the keys and * values to which it refers are copied by reference. */ @@ -187,9 +216,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { @Override public void clear() { super.clear(); - - mHasFds = false; - mFdsKnown = true; + mFlags = FLAG_HAS_FDS_KNOWN; } /** @@ -202,16 +229,20 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { bundle.unparcel(); mMap.putAll(bundle.mMap); - // fd state is now known if and only if both bundles already knew - mHasFds |= bundle.mHasFds; - mFdsKnown = mFdsKnown && bundle.mFdsKnown; + // FD state is now known if and only if both bundles already knew + if ((bundle.mFlags & FLAG_HAS_FDS) != 0) { + mFlags |= FLAG_HAS_FDS; + } + if ((bundle.mFlags & FLAG_HAS_FDS_KNOWN) == 0) { + mFlags &= ~FLAG_HAS_FDS_KNOWN; + } } /** * Reports whether the bundle contains any parcelled file descriptors. */ public boolean hasFileDescriptors() { - if (!mFdsKnown) { + if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) { boolean fdFound = false; // keep going until we find one or run out of data if (mParcelledData != null) { @@ -267,10 +298,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } } - mHasFds = fdFound; - mFdsKnown = true; + if (fdFound) { + mFlags |= FLAG_HAS_FDS; + } + mFlags |= FLAG_HAS_FDS_KNOWN; } - return mHasFds; + return (mFlags & FLAG_HAS_FDS) != 0; } /** @@ -366,7 +399,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { public void putParcelable(@Nullable String key, @Nullable Parcelable value) { unparcel(); mMap.put(key, value); - mFdsKnown = false; + mFlags &= ~FLAG_HAS_FDS_KNOWN; } /** @@ -404,7 +437,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) { unparcel(); mMap.put(key, value); - mFdsKnown = false; + mFlags &= ~FLAG_HAS_FDS_KNOWN; } /** @@ -419,14 +452,14 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { @Nullable ArrayList<? extends Parcelable> value) { unparcel(); mMap.put(key, value); - mFdsKnown = false; + mFlags &= ~FLAG_HAS_FDS_KNOWN; } /** {@hide} */ public void putParcelableList(String key, List<? extends Parcelable> value) { unparcel(); mMap.put(key, value); - mFdsKnown = false; + mFlags &= ~FLAG_HAS_FDS_KNOWN; } /** @@ -441,7 +474,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { @Nullable SparseArray<? extends Parcelable> value) { unparcel(); mMap.put(key, value); - mFdsKnown = false; + mFlags &= ~FLAG_HAS_FDS_KNOWN; } /** @@ -1094,7 +1127,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { */ @Override public void writeToParcel(Parcel parcel, int flags) { - final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds); + final boolean oldAllowFds = parcel.pushAllowFds((mFlags & FLAG_ALLOW_FDS) != 0); try { super.writeToParcelInner(parcel, flags); } finally { @@ -1109,8 +1142,10 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { */ public void readFromParcel(Parcel parcel) { super.readFromParcelInner(parcel); - mHasFds = mParcelledData.hasFileDescriptors(); - mFdsKnown = true; + mFlags = FLAG_HAS_FDS_KNOWN; + if (mParcelledData.hasFileDescriptors()) { + mFlags |= FLAG_HAS_FDS; + } } @Override @@ -1125,5 +1160,4 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } return "Bundle[" + mMap.toString() + "]"; } - } |
