Home | History | Annotate | Download | only in os
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.os;
     18 
     19 import android.annotation.Nullable;
     20 import android.util.ArrayMap;
     21 import android.util.Size;
     22 import android.util.SizeF;
     23 import android.util.SparseArray;
     24 import android.util.proto.ProtoOutputStream;
     25 
     26 import com.android.internal.annotations.VisibleForTesting;
     27 
     28 import java.io.Serializable;
     29 import java.util.ArrayList;
     30 import java.util.List;
     31 
     32 /**
     33  * A mapping from String keys to various {@link Parcelable} values.
     34  *
     35  * @see PersistableBundle
     36  */
     37 public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
     38     @VisibleForTesting
     39     static final int FLAG_HAS_FDS = 1 << 8;
     40 
     41     @VisibleForTesting
     42     static final int FLAG_HAS_FDS_KNOWN = 1 << 9;
     43 
     44     @VisibleForTesting
     45     static final int FLAG_ALLOW_FDS = 1 << 10;
     46 
     47     public static final Bundle EMPTY;
     48 
     49     /**
     50      * Special extras used to denote extras have been stripped off.
     51      * @hide
     52      */
     53     public static final Bundle STRIPPED;
     54 
     55     static {
     56         EMPTY = new Bundle();
     57         EMPTY.mMap = ArrayMap.EMPTY;
     58 
     59         STRIPPED = new Bundle();
     60         STRIPPED.putInt("STRIPPED", 1);
     61     }
     62 
     63     /**
     64      * Constructs a new, empty Bundle.
     65      */
     66     public Bundle() {
     67         super();
     68         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
     69     }
     70 
     71     /**
     72      * Constructs a Bundle whose data is stored as a Parcel.  The data
     73      * will be unparcelled on first contact, using the assigned ClassLoader.
     74      *
     75      * @param parcelledData a Parcel containing a Bundle
     76      *
     77      * @hide
     78      */
     79     @VisibleForTesting
     80     public Bundle(Parcel parcelledData) {
     81         super(parcelledData);
     82         mFlags = FLAG_ALLOW_FDS;
     83         maybePrefillHasFds();
     84     }
     85 
     86     /**
     87      * Constructor from a parcel for when the length is known *and is not stored in the parcel.*
     88      * The other constructor that takes a parcel assumes the length is in the parcel.
     89      *
     90      * @hide
     91      */
     92     @VisibleForTesting
     93     public Bundle(Parcel parcelledData, int length) {
     94         super(parcelledData, length);
     95         mFlags = FLAG_ALLOW_FDS;
     96         maybePrefillHasFds();
     97     }
     98 
     99     /**
    100      * If {@link #mParcelledData} is not null, copy the HAS FDS bit from it because it's fast.
    101      * Otherwise (if {@link #mParcelledData} is already null), leave {@link #FLAG_HAS_FDS_KNOWN}
    102      * unset, because scanning a map is slower.  We'll do it lazily in
    103      * {@link #hasFileDescriptors()}.
    104      */
    105     private void maybePrefillHasFds() {
    106         if (mParcelledData != null) {
    107             if (mParcelledData.hasFileDescriptors()) {
    108                 mFlags |= FLAG_HAS_FDS | FLAG_HAS_FDS_KNOWN;
    109             } else {
    110                 mFlags |= FLAG_HAS_FDS_KNOWN;
    111             }
    112         }
    113     }
    114 
    115     /**
    116      * Constructs a new, empty Bundle that uses a specific ClassLoader for
    117      * instantiating Parcelable and Serializable objects.
    118      *
    119      * @param loader An explicit ClassLoader to use when instantiating objects
    120      * inside of the Bundle.
    121      */
    122     public Bundle(ClassLoader loader) {
    123         super(loader);
    124         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
    125     }
    126 
    127     /**
    128      * Constructs a new, empty Bundle sized to hold the given number of
    129      * elements. The Bundle will grow as needed.
    130      *
    131      * @param capacity the initial capacity of the Bundle
    132      */
    133     public Bundle(int capacity) {
    134         super(capacity);
    135         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
    136     }
    137 
    138     /**
    139      * Constructs a Bundle containing a copy of the mappings from the given
    140      * Bundle.  Does only a shallow copy of the original Bundle -- see
    141      * {@link #deepCopy()} if that is not what you want.
    142      *
    143      * @param b a Bundle to be copied.
    144      *
    145      * @see #deepCopy()
    146      */
    147     public Bundle(Bundle b) {
    148         super(b);
    149         mFlags = b.mFlags;
    150     }
    151 
    152     /**
    153      * Constructs a Bundle containing a copy of the mappings from the given
    154      * PersistableBundle.  Does only a shallow copy of the PersistableBundle -- see
    155      * {@link PersistableBundle#deepCopy()} if you don't want that.
    156      *
    157      * @param b a PersistableBundle to be copied.
    158      */
    159     public Bundle(PersistableBundle b) {
    160         super(b);
    161         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
    162     }
    163 
    164     /**
    165      * Constructs a Bundle without initializing it.
    166      */
    167     Bundle(boolean doInit) {
    168         super(doInit);
    169     }
    170 
    171     /**
    172      * Make a Bundle for a single key/value pair.
    173      *
    174      * @hide
    175      */
    176     public static Bundle forPair(String key, String value) {
    177         Bundle b = new Bundle(1);
    178         b.putString(key, value);
    179         return b;
    180     }
    181 
    182     /**
    183      * Changes the ClassLoader this Bundle uses when instantiating objects.
    184      *
    185      * @param loader An explicit ClassLoader to use when instantiating objects
    186      * inside of the Bundle.
    187      */
    188     @Override
    189     public void setClassLoader(ClassLoader loader) {
    190         super.setClassLoader(loader);
    191     }
    192 
    193     /**
    194      * Return the ClassLoader currently associated with this Bundle.
    195      */
    196     @Override
    197     public ClassLoader getClassLoader() {
    198         return super.getClassLoader();
    199     }
    200 
    201     /** {@hide} */
    202     public boolean setAllowFds(boolean allowFds) {
    203         final boolean orig = (mFlags & FLAG_ALLOW_FDS) != 0;
    204         if (allowFds) {
    205             mFlags |= FLAG_ALLOW_FDS;
    206         } else {
    207             mFlags &= ~FLAG_ALLOW_FDS;
    208         }
    209         return orig;
    210     }
    211 
    212     /**
    213      * Mark if this Bundle is okay to "defuse." That is, it's okay for system
    214      * processes to ignore any {@link BadParcelableException} encountered when
    215      * unparceling it, leaving an empty bundle in its place.
    216      * <p>
    217      * This should <em>only</em> be set when the Bundle reaches its final
    218      * destination, otherwise a system process may clobber contents that were
    219      * destined for an app that could have unparceled them.
    220      *
    221      * @hide
    222      */
    223     public void setDefusable(boolean defusable) {
    224         if (defusable) {
    225             mFlags |= FLAG_DEFUSABLE;
    226         } else {
    227             mFlags &= ~FLAG_DEFUSABLE;
    228         }
    229     }
    230 
    231     /** {@hide} */
    232     public static Bundle setDefusable(Bundle bundle, boolean defusable) {
    233         if (bundle != null) {
    234             bundle.setDefusable(defusable);
    235         }
    236         return bundle;
    237     }
    238 
    239     /**
    240      * Clones the current Bundle. The internal map is cloned, but the keys and
    241      * values to which it refers are copied by reference.
    242      */
    243     @Override
    244     public Object clone() {
    245         return new Bundle(this);
    246     }
    247 
    248     /**
    249      * Make a deep copy of the given bundle.  Traverses into inner containers and copies
    250      * them as well, so they are not shared across bundles.  Will traverse in to
    251      * {@link Bundle}, {@link PersistableBundle}, {@link ArrayList}, and all types of
    252      * primitive arrays.  Other types of objects (such as Parcelable or Serializable)
    253      * are referenced as-is and not copied in any way.
    254      */
    255     public Bundle deepCopy() {
    256         Bundle b = new Bundle(false);
    257         b.copyInternal(this, true);
    258         return b;
    259     }
    260 
    261     /**
    262      * Removes all elements from the mapping of this Bundle.
    263      */
    264     @Override
    265     public void clear() {
    266         super.clear();
    267         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
    268     }
    269 
    270     /**
    271      * Removes any entry with the given key from the mapping of this Bundle.
    272      *
    273      * @param key a String key
    274      */
    275     public void remove(String key) {
    276         super.remove(key);
    277         if ((mFlags & FLAG_HAS_FDS) != 0) {
    278             mFlags &= ~FLAG_HAS_FDS_KNOWN;
    279         }
    280     }
    281 
    282     /**
    283      * Inserts all mappings from the given Bundle into this Bundle.
    284      *
    285      * @param bundle a Bundle
    286      */
    287     public void putAll(Bundle bundle) {
    288         unparcel();
    289         bundle.unparcel();
    290         mMap.putAll(bundle.mMap);
    291 
    292         // FD state is now known if and only if both bundles already knew
    293         if ((bundle.mFlags & FLAG_HAS_FDS) != 0) {
    294             mFlags |= FLAG_HAS_FDS;
    295         }
    296         if ((bundle.mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
    297             mFlags &= ~FLAG_HAS_FDS_KNOWN;
    298         }
    299     }
    300 
    301     /**
    302      * Return the size of {@link #mParcelledData} in bytes if available, otherwise {@code 0}.
    303      *
    304      * @hide
    305      */
    306     public int getSize() {
    307         if (mParcelledData != null) {
    308             return mParcelledData.dataSize();
    309         } else {
    310             return 0;
    311         }
    312     }
    313 
    314     /**
    315      * Reports whether the bundle contains any parcelled file descriptors.
    316      */
    317     public boolean hasFileDescriptors() {
    318         if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
    319             boolean fdFound = false;    // keep going until we find one or run out of data
    320 
    321             if (mParcelledData != null) {
    322                 if (mParcelledData.hasFileDescriptors()) {
    323                     fdFound = true;
    324                 }
    325             } else {
    326                 // It's been unparcelled, so we need to walk the map
    327                 for (int i=mMap.size()-1; i>=0; i--) {
    328                     Object obj = mMap.valueAt(i);
    329                     if (obj instanceof Parcelable) {
    330                         if ((((Parcelable)obj).describeContents()
    331                                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
    332                             fdFound = true;
    333                             break;
    334                         }
    335                     } else if (obj instanceof Parcelable[]) {
    336                         Parcelable[] array = (Parcelable[]) obj;
    337                         for (int n = array.length - 1; n >= 0; n--) {
    338                             Parcelable p = array[n];
    339                             if (p != null && ((p.describeContents()
    340                                     & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
    341                                 fdFound = true;
    342                                 break;
    343                             }
    344                         }
    345                     } else if (obj instanceof SparseArray) {
    346                         SparseArray<? extends Parcelable> array =
    347                                 (SparseArray<? extends Parcelable>) obj;
    348                         for (int n = array.size() - 1; n >= 0; n--) {
    349                             Parcelable p = array.valueAt(n);
    350                             if (p != null && (p.describeContents()
    351                                     & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
    352                                 fdFound = true;
    353                                 break;
    354                             }
    355                         }
    356                     } else if (obj instanceof ArrayList) {
    357                         ArrayList array = (ArrayList) obj;
    358                         // an ArrayList here might contain either Strings or
    359                         // Parcelables; only look inside for Parcelables
    360                         if (!array.isEmpty() && (array.get(0) instanceof Parcelable)) {
    361                             for (int n = array.size() - 1; n >= 0; n--) {
    362                                 Parcelable p = (Parcelable) array.get(n);
    363                                 if (p != null && ((p.describeContents()
    364                                         & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
    365                                     fdFound = true;
    366                                     break;
    367                                 }
    368                             }
    369                         }
    370                     }
    371                 }
    372             }
    373 
    374             if (fdFound) {
    375                 mFlags |= FLAG_HAS_FDS;
    376             } else {
    377                 mFlags &= ~FLAG_HAS_FDS;
    378             }
    379             mFlags |= FLAG_HAS_FDS_KNOWN;
    380         }
    381         return (mFlags & FLAG_HAS_FDS) != 0;
    382     }
    383 
    384     /**
    385      * Filter values in Bundle to only basic types.
    386      * @hide
    387      */
    388     public Bundle filterValues() {
    389         unparcel();
    390         Bundle bundle = this;
    391         if (mMap != null) {
    392             ArrayMap<String, Object> map = mMap;
    393             for (int i = map.size() - 1; i >= 0; i--) {
    394                 Object value = map.valueAt(i);
    395                 if (PersistableBundle.isValidType(value)) {
    396                     continue;
    397                 }
    398                 if (value instanceof Bundle) {
    399                     Bundle newBundle = ((Bundle)value).filterValues();
    400                     if (newBundle != value) {
    401                         if (map == mMap) {
    402                             // The filter had to generate a new bundle, but we have not yet
    403                             // created a new one here.  Do that now.
    404                             bundle = new Bundle(this);
    405                             // Note the ArrayMap<> constructor is guaranteed to generate
    406                             // a new object with items in the same order as the original.
    407                             map = bundle.mMap;
    408                         }
    409                         // Replace this current entry with the new child bundle.
    410                         map.setValueAt(i, newBundle);
    411                     }
    412                     continue;
    413                 }
    414                 if (value.getClass().getName().startsWith("android.")) {
    415                     continue;
    416                 }
    417                 if (map == mMap) {
    418                     // This is the first time we have had to remove something, that means we
    419                     // need to switch to a new Bundle.
    420                     bundle = new Bundle(this);
    421                     // Note the ArrayMap<> constructor is guaranteed to generate
    422                     // a new object with items in the same order as the original.
    423                     map = bundle.mMap;
    424                 }
    425                 map.removeAt(i);
    426             }
    427         }
    428         mFlags |= FLAG_HAS_FDS_KNOWN;
    429         mFlags &= ~FLAG_HAS_FDS;
    430         return bundle;
    431     }
    432 
    433     /**
    434      * Inserts a byte value into the mapping of this Bundle, replacing
    435      * any existing value for the given key.
    436      *
    437      * @param key a String, or null
    438      * @param value a byte
    439      */
    440     @Override
    441     public void putByte(@Nullable String key, byte value) {
    442         super.putByte(key, value);
    443     }
    444 
    445     /**
    446      * Inserts a char value into the mapping of this Bundle, replacing
    447      * any existing value for the given key.
    448      *
    449      * @param key a String, or null
    450      * @param value a char
    451      */
    452     @Override
    453     public void putChar(@Nullable String key, char value) {
    454         super.putChar(key, value);
    455     }
    456 
    457     /**
    458      * Inserts a short value into the mapping of this Bundle, replacing
    459      * any existing value for the given key.
    460      *
    461      * @param key a String, or null
    462      * @param value a short
    463      */
    464     @Override
    465     public void putShort(@Nullable String key, short value) {
    466         super.putShort(key, value);
    467     }
    468 
    469     /**
    470      * Inserts a float value into the mapping of this Bundle, replacing
    471      * any existing value for the given key.
    472      *
    473      * @param key a String, or null
    474      * @param value a float
    475      */
    476     @Override
    477     public void putFloat(@Nullable String key, float value) {
    478         super.putFloat(key, value);
    479     }
    480 
    481     /**
    482      * Inserts a CharSequence value into the mapping of this Bundle, replacing
    483      * any existing value for the given key.  Either key or value may be null.
    484      *
    485      * @param key a String, or null
    486      * @param value a CharSequence, or null
    487      */
    488     @Override
    489     public void putCharSequence(@Nullable String key, @Nullable CharSequence value) {
    490         super.putCharSequence(key, value);
    491     }
    492 
    493     /**
    494      * Inserts a Parcelable value into the mapping of this Bundle, replacing
    495      * any existing value for the given key.  Either key or value may be null.
    496      *
    497      * @param key a String, or null
    498      * @param value a Parcelable object, or null
    499      */
    500     public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
    501         unparcel();
    502         mMap.put(key, value);
    503         mFlags &= ~FLAG_HAS_FDS_KNOWN;
    504     }
    505 
    506     /**
    507      * Inserts a Size value into the mapping of this Bundle, replacing
    508      * any existing value for the given key.  Either key or value may be null.
    509      *
    510      * @param key a String, or null
    511      * @param value a Size object, or null
    512      */
    513     public void putSize(@Nullable String key, @Nullable Size value) {
    514         unparcel();
    515         mMap.put(key, value);
    516     }
    517 
    518     /**
    519      * Inserts a SizeF value into the mapping of this Bundle, replacing
    520      * any existing value for the given key.  Either key or value may be null.
    521      *
    522      * @param key a String, or null
    523      * @param value a SizeF object, or null
    524      */
    525     public void putSizeF(@Nullable String key, @Nullable SizeF value) {
    526         unparcel();
    527         mMap.put(key, value);
    528     }
    529 
    530     /**
    531      * Inserts an array of Parcelable values into the mapping of this Bundle,
    532      * replacing any existing value for the given key.  Either key or value may
    533      * be null.
    534      *
    535      * @param key a String, or null
    536      * @param value an array of Parcelable objects, or null
    537      */
    538     public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
    539         unparcel();
    540         mMap.put(key, value);
    541         mFlags &= ~FLAG_HAS_FDS_KNOWN;
    542     }
    543 
    544     /**
    545      * Inserts a List of Parcelable values into the mapping of this Bundle,
    546      * replacing any existing value for the given key.  Either key or value may
    547      * be null.
    548      *
    549      * @param key a String, or null
    550      * @param value an ArrayList of Parcelable objects, or null
    551      */
    552     public void putParcelableArrayList(@Nullable String key,
    553             @Nullable ArrayList<? extends Parcelable> value) {
    554         unparcel();
    555         mMap.put(key, value);
    556         mFlags &= ~FLAG_HAS_FDS_KNOWN;
    557     }
    558 
    559     /** {@hide} */
    560     public void putParcelableList(String key, List<? extends Parcelable> value) {
    561         unparcel();
    562         mMap.put(key, value);
    563         mFlags &= ~FLAG_HAS_FDS_KNOWN;
    564     }
    565 
    566     /**
    567      * Inserts a SparceArray of Parcelable values into the mapping of this
    568      * Bundle, replacing any existing value for the given key.  Either key
    569      * or value may be null.
    570      *
    571      * @param key a String, or null
    572      * @param value a SparseArray of Parcelable objects, or null
    573      */
    574     public void putSparseParcelableArray(@Nullable String key,
    575             @Nullable SparseArray<? extends Parcelable> value) {
    576         unparcel();
    577         mMap.put(key, value);
    578         mFlags &= ~FLAG_HAS_FDS_KNOWN;
    579     }
    580 
    581     /**
    582      * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
    583      * any existing value for the given key.  Either key or value may be null.
    584      *
    585      * @param key a String, or null
    586      * @param value an ArrayList<Integer> object, or null
    587      */
    588     @Override
    589     public void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
    590         super.putIntegerArrayList(key, value);
    591     }
    592 
    593     /**
    594      * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
    595      * any existing value for the given key.  Either key or value may be null.
    596      *
    597      * @param key a String, or null
    598      * @param value an ArrayList<String> object, or null
    599      */
    600     @Override
    601     public void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
    602         super.putStringArrayList(key, value);
    603     }
    604 
    605     /**
    606      * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
    607      * any existing value for the given key.  Either key or value may be null.
    608      *
    609      * @param key a String, or null
    610      * @param value an ArrayList<CharSequence> object, or null
    611      */
    612     @Override
    613     public void putCharSequenceArrayList(@Nullable String key,
    614             @Nullable ArrayList<CharSequence> value) {
    615         super.putCharSequenceArrayList(key, value);
    616     }
    617 
    618     /**
    619      * Inserts a Serializable value into the mapping of this Bundle, replacing
    620      * any existing value for the given key.  Either key or value may be null.
    621      *
    622      * @param key a String, or null
    623      * @param value a Serializable object, or null
    624      */
    625     @Override
    626     public void putSerializable(@Nullable String key, @Nullable Serializable value) {
    627         super.putSerializable(key, value);
    628     }
    629 
    630     /**
    631      * Inserts a byte array value into the mapping of this Bundle, replacing
    632      * any existing value for the given key.  Either key or value may be null.
    633      *
    634      * @param key a String, or null
    635      * @param value a byte array object, or null
    636      */
    637     @Override
    638     public void putByteArray(@Nullable String key, @Nullable byte[] value) {
    639         super.putByteArray(key, value);
    640     }
    641 
    642     /**
    643      * Inserts a short array value into the mapping of this Bundle, replacing
    644      * any existing value for the given key.  Either key or value may be null.
    645      *
    646      * @param key a String, or null
    647      * @param value a short array object, or null
    648      */
    649     @Override
    650     public void putShortArray(@Nullable String key, @Nullable short[] value) {
    651         super.putShortArray(key, value);
    652     }
    653 
    654     /**
    655      * Inserts a char array value into the mapping of this Bundle, replacing
    656      * any existing value for the given key.  Either key or value may be null.
    657      *
    658      * @param key a String, or null
    659      * @param value a char array object, or null
    660      */
    661     @Override
    662     public void putCharArray(@Nullable String key, @Nullable char[] value) {
    663         super.putCharArray(key, value);
    664     }
    665 
    666     /**
    667      * Inserts a float array value into the mapping of this Bundle, replacing
    668      * any existing value for the given key.  Either key or value may be null.
    669      *
    670      * @param key a String, or null
    671      * @param value a float array object, or null
    672      */
    673     @Override
    674     public void putFloatArray(@Nullable String key, @Nullable float[] value) {
    675         super.putFloatArray(key, value);
    676     }
    677 
    678     /**
    679      * Inserts a CharSequence array value into the mapping of this Bundle, replacing
    680      * any existing value for the given key.  Either key or value may be null.
    681      *
    682      * @param key a String, or null
    683      * @param value a CharSequence array object, or null
    684      */
    685     @Override
    686     public void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
    687         super.putCharSequenceArray(key, value);
    688     }
    689 
    690     /**
    691      * Inserts a Bundle value into the mapping of this Bundle, replacing
    692      * any existing value for the given key.  Either key or value may be null.
    693      *
    694      * @param key a String, or null
    695      * @param value a Bundle object, or null
    696      */
    697     public void putBundle(@Nullable String key, @Nullable Bundle value) {
    698         unparcel();
    699         mMap.put(key, value);
    700     }
    701 
    702     /**
    703      * Inserts an {@link IBinder} value into the mapping of this Bundle, replacing
    704      * any existing value for the given key.  Either key or value may be null.
    705      *
    706      * <p class="note">You should be very careful when using this function.  In many
    707      * places where Bundles are used (such as inside of Intent objects), the Bundle
    708      * can live longer inside of another process than the process that had originally
    709      * created it.  In that case, the IBinder you supply here will become invalid
    710      * when your process goes away, and no longer usable, even if a new process is
    711      * created for you later on.</p>
    712      *
    713      * @param key a String, or null
    714      * @param value an IBinder object, or null
    715      */
    716     public void putBinder(@Nullable String key, @Nullable IBinder value) {
    717         unparcel();
    718         mMap.put(key, value);
    719     }
    720 
    721     /**
    722      * Inserts an IBinder value into the mapping of this Bundle, replacing
    723      * any existing value for the given key.  Either key or value may be null.
    724      *
    725      * @param key a String, or null
    726      * @param value an IBinder object, or null
    727      *
    728      * @deprecated
    729      * @hide This is the old name of the function.
    730      */
    731     @Deprecated
    732     public void putIBinder(@Nullable String key, @Nullable IBinder value) {
    733         unparcel();
    734         mMap.put(key, value);
    735     }
    736 
    737     /**
    738      * Returns the value associated with the given key, or (byte) 0 if
    739      * no mapping of the desired type exists for the given key.
    740      *
    741      * @param key a String
    742      * @return a byte value
    743      */
    744     @Override
    745     public byte getByte(String key) {
    746         return super.getByte(key);
    747     }
    748 
    749     /**
    750      * Returns the value associated with the given key, or defaultValue if
    751      * no mapping of the desired type exists for the given key.
    752      *
    753      * @param key a String
    754      * @param defaultValue Value to return if key does not exist
    755      * @return a byte value
    756      */
    757     @Override
    758     public Byte getByte(String key, byte defaultValue) {
    759         return super.getByte(key, defaultValue);
    760     }
    761 
    762     /**
    763      * Returns the value associated with the given key, or (char) 0 if
    764      * no mapping of the desired type exists for the given key.
    765      *
    766      * @param key a String
    767      * @return a char value
    768      */
    769     @Override
    770     public char getChar(String key) {
    771         return super.getChar(key);
    772     }
    773 
    774     /**
    775      * Returns the value associated with the given key, or defaultValue if
    776      * no mapping of the desired type exists for the given key.
    777      *
    778      * @param key a String
    779      * @param defaultValue Value to return if key does not exist
    780      * @return a char value
    781      */
    782     @Override
    783     public char getChar(String key, char defaultValue) {
    784         return super.getChar(key, defaultValue);
    785     }
    786 
    787     /**
    788      * Returns the value associated with the given key, or (short) 0 if
    789      * no mapping of the desired type exists for the given key.
    790      *
    791      * @param key a String
    792      * @return a short value
    793      */
    794     @Override
    795     public short getShort(String key) {
    796         return super.getShort(key);
    797     }
    798 
    799     /**
    800      * Returns the value associated with the given key, or defaultValue if
    801      * no mapping of the desired type exists for the given key.
    802      *
    803      * @param key a String
    804      * @param defaultValue Value to return if key does not exist
    805      * @return a short value
    806      */
    807     @Override
    808     public short getShort(String key, short defaultValue) {
    809         return super.getShort(key, defaultValue);
    810     }
    811 
    812     /**
    813      * Returns the value associated with the given key, or 0.0f if
    814      * no mapping of the desired type exists for the given key.
    815      *
    816      * @param key a String
    817      * @return a float value
    818      */
    819     @Override
    820     public float getFloat(String key) {
    821         return super.getFloat(key);
    822     }
    823 
    824     /**
    825      * Returns the value associated with the given key, or defaultValue if
    826      * no mapping of the desired type exists for the given key.
    827      *
    828      * @param key a String
    829      * @param defaultValue Value to return if key does not exist
    830      * @return a float value
    831      */
    832     @Override
    833     public float getFloat(String key, float defaultValue) {
    834         return super.getFloat(key, defaultValue);
    835     }
    836 
    837     /**
    838      * Returns the value associated with the given key, or null if
    839      * no mapping of the desired type exists for the given key or a null
    840      * value is explicitly associated with the key.
    841      *
    842      * @param key a String, or null
    843      * @return a CharSequence value, or null
    844      */
    845     @Override
    846     @Nullable
    847     public CharSequence getCharSequence(@Nullable String key) {
    848         return super.getCharSequence(key);
    849     }
    850 
    851     /**
    852      * Returns the value associated with the given key, or defaultValue if
    853      * no mapping of the desired type exists for the given key or if a null
    854      * value is explicitly associatd with the given key.
    855      *
    856      * @param key a String, or null
    857      * @param defaultValue Value to return if key does not exist or if a null
    858      *     value is associated with the given key.
    859      * @return the CharSequence value associated with the given key, or defaultValue
    860      *     if no valid CharSequence object is currently mapped to that key.
    861      */
    862     @Override
    863     public CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) {
    864         return super.getCharSequence(key, defaultValue);
    865     }
    866 
    867     /**
    868      * Returns the value associated with the given key, or null if
    869      * no mapping of the desired type exists for the given key or a null
    870      * value is explicitly associated with the key.
    871      *
    872      * @param key a String, or null
    873      * @return a Size value, or null
    874      */
    875     @Nullable
    876     public Size getSize(@Nullable String key) {
    877         unparcel();
    878         final Object o = mMap.get(key);
    879         try {
    880             return (Size) o;
    881         } catch (ClassCastException e) {
    882             typeWarning(key, o, "Size", e);
    883             return null;
    884         }
    885     }
    886 
    887     /**
    888      * Returns the value associated with the given key, or null if
    889      * no mapping of the desired type exists for the given key or a null
    890      * value is explicitly associated with the key.
    891      *
    892      * @param key a String, or null
    893      * @return a Size value, or null
    894      */
    895     @Nullable
    896     public SizeF getSizeF(@Nullable String key) {
    897         unparcel();
    898         final Object o = mMap.get(key);
    899         try {
    900             return (SizeF) o;
    901         } catch (ClassCastException e) {
    902             typeWarning(key, o, "SizeF", e);
    903             return null;
    904         }
    905     }
    906 
    907     /**
    908      * Returns the value associated with the given key, or null if
    909      * no mapping of the desired type exists for the given key or a null
    910      * value is explicitly associated with the key.
    911      *
    912      * @param key a String, or null
    913      * @return a Bundle value, or null
    914      */
    915     @Nullable
    916     public Bundle getBundle(@Nullable String key) {
    917         unparcel();
    918         Object o = mMap.get(key);
    919         if (o == null) {
    920             return null;
    921         }
    922         try {
    923             return (Bundle) o;
    924         } catch (ClassCastException e) {
    925             typeWarning(key, o, "Bundle", e);
    926             return null;
    927         }
    928     }
    929 
    930     /**
    931      * Returns the value associated with the given key, or null if
    932      * no mapping of the desired type exists for the given key or a null
    933      * value is explicitly associated with the key.
    934      *
    935      * @param key a String, or null
    936      * @return a Parcelable value, or null
    937      */
    938     @Nullable
    939     public <T extends Parcelable> T getParcelable(@Nullable String key) {
    940         unparcel();
    941         Object o = mMap.get(key);
    942         if (o == null) {
    943             return null;
    944         }
    945         try {
    946             return (T) o;
    947         } catch (ClassCastException e) {
    948             typeWarning(key, o, "Parcelable", e);
    949             return null;
    950         }
    951     }
    952 
    953     /**
    954      * Returns the value associated with the given key, or null if
    955      * no mapping of the desired type exists for the given key or a null
    956      * value is explicitly associated with the key.
    957      *
    958      * @param key a String, or null
    959      * @return a Parcelable[] value, or null
    960      */
    961     @Nullable
    962     public Parcelable[] getParcelableArray(@Nullable String key) {
    963         unparcel();
    964         Object o = mMap.get(key);
    965         if (o == null) {
    966             return null;
    967         }
    968         try {
    969             return (Parcelable[]) o;
    970         } catch (ClassCastException e) {
    971             typeWarning(key, o, "Parcelable[]", e);
    972             return null;
    973         }
    974     }
    975 
    976     /**
    977      * Returns the value associated with the given key, or null if
    978      * no mapping of the desired type exists for the given key or a null
    979      * value is explicitly associated with the key.
    980      *
    981      * @param key a String, or null
    982      * @return an ArrayList<T> value, or null
    983      */
    984     @Nullable
    985     public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) {
    986         unparcel();
    987         Object o = mMap.get(key);
    988         if (o == null) {
    989             return null;
    990         }
    991         try {
    992             return (ArrayList<T>) o;
    993         } catch (ClassCastException e) {
    994             typeWarning(key, o, "ArrayList", e);
    995             return null;
    996         }
    997     }
    998 
    999     /**
   1000      * Returns the value associated with the given key, or null if
   1001      * no mapping of the desired type exists for the given key or a null
   1002      * value is explicitly associated with the key.
   1003      *
   1004      * @param key a String, or null
   1005      *
   1006      * @return a SparseArray of T values, or null
   1007      */
   1008     @Nullable
   1009     public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(@Nullable String key) {
   1010         unparcel();
   1011         Object o = mMap.get(key);
   1012         if (o == null) {
   1013             return null;
   1014         }
   1015         try {
   1016             return (SparseArray<T>) o;
   1017         } catch (ClassCastException e) {
   1018             typeWarning(key, o, "SparseArray", e);
   1019             return null;
   1020         }
   1021     }
   1022 
   1023     /**
   1024      * Returns the value associated with the given key, or null if
   1025      * no mapping of the desired type exists for the given key or a null
   1026      * value is explicitly associated with the key.
   1027      *
   1028      * @param key a String, or null
   1029      * @return a Serializable value, or null
   1030      */
   1031     @Override
   1032     @Nullable
   1033     public Serializable getSerializable(@Nullable String key) {
   1034         return super.getSerializable(key);
   1035     }
   1036 
   1037     /**
   1038      * Returns the value associated with the given key, or null if
   1039      * no mapping of the desired type exists for the given key or a null
   1040      * value is explicitly associated with the key.
   1041      *
   1042      * @param key a String, or null
   1043      * @return an ArrayList<String> value, or null
   1044      */
   1045     @Override
   1046     @Nullable
   1047     public ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
   1048         return super.getIntegerArrayList(key);
   1049     }
   1050 
   1051     /**
   1052      * Returns the value associated with the given key, or null if
   1053      * no mapping of the desired type exists for the given key or a null
   1054      * value is explicitly associated with the key.
   1055      *
   1056      * @param key a String, or null
   1057      * @return an ArrayList<String> value, or null
   1058      */
   1059     @Override
   1060     @Nullable
   1061     public ArrayList<String> getStringArrayList(@Nullable String key) {
   1062         return super.getStringArrayList(key);
   1063     }
   1064 
   1065     /**
   1066      * Returns the value associated with the given key, or null if
   1067      * no mapping of the desired type exists for the given key or a null
   1068      * value is explicitly associated with the key.
   1069      *
   1070      * @param key a String, or null
   1071      * @return an ArrayList<CharSequence> value, or null
   1072      */
   1073     @Override
   1074     @Nullable
   1075     public ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) {
   1076         return super.getCharSequenceArrayList(key);
   1077     }
   1078 
   1079     /**
   1080      * Returns the value associated with the given key, or null if
   1081      * no mapping of the desired type exists for the given key or a null
   1082      * value is explicitly associated with the key.
   1083      *
   1084      * @param key a String, or null
   1085      * @return a byte[] value, or null
   1086      */
   1087     @Override
   1088     @Nullable
   1089     public byte[] getByteArray(@Nullable String key) {
   1090         return super.getByteArray(key);
   1091     }
   1092 
   1093     /**
   1094      * Returns the value associated with the given key, or null if
   1095      * no mapping of the desired type exists for the given key or a null
   1096      * value is explicitly associated with the key.
   1097      *
   1098      * @param key a String, or null
   1099      * @return a short[] value, or null
   1100      */
   1101     @Override
   1102     @Nullable
   1103     public short[] getShortArray(@Nullable String key) {
   1104         return super.getShortArray(key);
   1105     }
   1106 
   1107     /**
   1108      * Returns the value associated with the given key, or null if
   1109      * no mapping of the desired type exists for the given key or a null
   1110      * value is explicitly associated with the key.
   1111      *
   1112      * @param key a String, or null
   1113      * @return a char[] value, or null
   1114      */
   1115     @Override
   1116     @Nullable
   1117     public char[] getCharArray(@Nullable String key) {
   1118         return super.getCharArray(key);
   1119     }
   1120 
   1121     /**
   1122      * Returns the value associated with the given key, or null if
   1123      * no mapping of the desired type exists for the given key or a null
   1124      * value is explicitly associated with the key.
   1125      *
   1126      * @param key a String, or null
   1127      * @return a float[] value, or null
   1128      */
   1129     @Override
   1130     @Nullable
   1131     public float[] getFloatArray(@Nullable String key) {
   1132         return super.getFloatArray(key);
   1133     }
   1134 
   1135     /**
   1136      * Returns the value associated with the given key, or null if
   1137      * no mapping of the desired type exists for the given key or a null
   1138      * value is explicitly associated with the key.
   1139      *
   1140      * @param key a String, or null
   1141      * @return a CharSequence[] value, or null
   1142      */
   1143     @Override
   1144     @Nullable
   1145     public CharSequence[] getCharSequenceArray(@Nullable String key) {
   1146         return super.getCharSequenceArray(key);
   1147     }
   1148 
   1149     /**
   1150      * Returns the value associated with the given key, or null if
   1151      * no mapping of the desired type exists for the given key or a null
   1152      * value is explicitly associated with the key.
   1153      *
   1154      * @param key a String, or null
   1155      * @return an IBinder value, or null
   1156      */
   1157     @Nullable
   1158     public IBinder getBinder(@Nullable String key) {
   1159         unparcel();
   1160         Object o = mMap.get(key);
   1161         if (o == null) {
   1162             return null;
   1163         }
   1164         try {
   1165             return (IBinder) o;
   1166         } catch (ClassCastException e) {
   1167             typeWarning(key, o, "IBinder", e);
   1168             return null;
   1169         }
   1170     }
   1171 
   1172     /**
   1173      * Returns the value associated with the given key, or null if
   1174      * no mapping of the desired type exists for the given key or a null
   1175      * value is explicitly associated with the key.
   1176      *
   1177      * @param key a String, or null
   1178      * @return an IBinder value, or null
   1179      *
   1180      * @deprecated
   1181      * @hide This is the old name of the function.
   1182      */
   1183     @Deprecated
   1184     @Nullable
   1185     public IBinder getIBinder(@Nullable String key) {
   1186         unparcel();
   1187         Object o = mMap.get(key);
   1188         if (o == null) {
   1189             return null;
   1190         }
   1191         try {
   1192             return (IBinder) o;
   1193         } catch (ClassCastException e) {
   1194             typeWarning(key, o, "IBinder", e);
   1195             return null;
   1196         }
   1197     }
   1198 
   1199     public static final Parcelable.Creator<Bundle> CREATOR =
   1200         new Parcelable.Creator<Bundle>() {
   1201         @Override
   1202         public Bundle createFromParcel(Parcel in) {
   1203             return in.readBundle();
   1204         }
   1205 
   1206         @Override
   1207         public Bundle[] newArray(int size) {
   1208             return new Bundle[size];
   1209         }
   1210     };
   1211 
   1212     /**
   1213      * Report the nature of this Parcelable's contents
   1214      */
   1215     @Override
   1216     public int describeContents() {
   1217         int mask = 0;
   1218         if (hasFileDescriptors()) {
   1219             mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
   1220         }
   1221         return mask;
   1222     }
   1223 
   1224     /**
   1225      * Writes the Bundle contents to a Parcel, typically in order for
   1226      * it to be passed through an IBinder connection.
   1227      * @param parcel The parcel to copy this bundle to.
   1228      */
   1229     @Override
   1230     public void writeToParcel(Parcel parcel, int flags) {
   1231         final boolean oldAllowFds = parcel.pushAllowFds((mFlags & FLAG_ALLOW_FDS) != 0);
   1232         try {
   1233             super.writeToParcelInner(parcel, flags);
   1234         } finally {
   1235             parcel.restoreAllowFds(oldAllowFds);
   1236         }
   1237     }
   1238 
   1239     /**
   1240      * Reads the Parcel contents into this Bundle, typically in order for
   1241      * it to be passed through an IBinder connection.
   1242      * @param parcel The parcel to overwrite this bundle from.
   1243      */
   1244     public void readFromParcel(Parcel parcel) {
   1245         super.readFromParcelInner(parcel);
   1246         mFlags = FLAG_ALLOW_FDS;
   1247         maybePrefillHasFds();
   1248     }
   1249 
   1250     @Override
   1251     public synchronized String toString() {
   1252         if (mParcelledData != null) {
   1253             if (isEmptyParcel()) {
   1254                 return "Bundle[EMPTY_PARCEL]";
   1255             } else {
   1256                 return "Bundle[mParcelledData.dataSize=" +
   1257                         mParcelledData.dataSize() + "]";
   1258             }
   1259         }
   1260         return "Bundle[" + mMap.toString() + "]";
   1261     }
   1262 
   1263     /**
   1264      * @hide
   1265      */
   1266     public synchronized String toShortString() {
   1267         if (mParcelledData != null) {
   1268             if (isEmptyParcel()) {
   1269                 return "EMPTY_PARCEL";
   1270             } else {
   1271                 return "mParcelledData.dataSize=" + mParcelledData.dataSize();
   1272             }
   1273         }
   1274         return mMap.toString();
   1275     }
   1276 
   1277     /** @hide */
   1278     public void writeToProto(ProtoOutputStream proto, long fieldId) {
   1279         final long token = proto.start(fieldId);
   1280 
   1281         if (mParcelledData != null) {
   1282             if (isEmptyParcel()) {
   1283                 proto.write(BundleProto.PARCELLED_DATA_SIZE, 0);
   1284             } else {
   1285                 proto.write(BundleProto.PARCELLED_DATA_SIZE, mParcelledData.dataSize());
   1286             }
   1287         } else {
   1288             proto.write(BundleProto.MAP_DATA, mMap.toString());
   1289         }
   1290 
   1291         proto.end(token);
   1292     }
   1293 }
   1294