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 
     25 import java.io.Serializable;
     26 import java.util.ArrayList;
     27 import java.util.List;
     28 
     29 /**
     30  * A mapping from String values to various Parcelable types.
     31  *
     32  */
     33 public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
     34     public static final Bundle EMPTY;
     35     static final Parcel EMPTY_PARCEL;
     36 
     37     static {
     38         EMPTY = new Bundle();
     39         EMPTY.mMap = ArrayMap.EMPTY;
     40         EMPTY_PARCEL = BaseBundle.EMPTY_PARCEL;
     41     }
     42 
     43     private boolean mHasFds = false;
     44     private boolean mFdsKnown = true;
     45     private boolean mAllowFds = true;
     46 
     47     /**
     48      * Constructs a new, empty Bundle.
     49      */
     50     public Bundle() {
     51         super();
     52     }
     53 
     54     /**
     55      * Constructs a Bundle whose data is stored as a Parcel.  The data
     56      * will be unparcelled on first contact, using the assigned ClassLoader.
     57      *
     58      * @param parcelledData a Parcel containing a Bundle
     59      */
     60     Bundle(Parcel parcelledData) {
     61         super(parcelledData);
     62 
     63         mHasFds = mParcelledData.hasFileDescriptors();
     64         mFdsKnown = true;
     65     }
     66 
     67     /* package */ Bundle(Parcel parcelledData, int length) {
     68         super(parcelledData, length);
     69 
     70         mHasFds = mParcelledData.hasFileDescriptors();
     71         mFdsKnown = true;
     72     }
     73 
     74     /**
     75      * Constructs a new, empty Bundle that uses a specific ClassLoader for
     76      * instantiating Parcelable and Serializable objects.
     77      *
     78      * @param loader An explicit ClassLoader to use when instantiating objects
     79      * inside of the Bundle.
     80      */
     81     public Bundle(ClassLoader loader) {
     82         super(loader);
     83     }
     84 
     85     /**
     86      * Constructs a new, empty Bundle sized to hold the given number of
     87      * elements. The Bundle will grow as needed.
     88      *
     89      * @param capacity the initial capacity of the Bundle
     90      */
     91     public Bundle(int capacity) {
     92         super(capacity);
     93     }
     94 
     95     /**
     96      * Constructs a Bundle containing a copy of the mappings from the given
     97      * Bundle.
     98      *
     99      * @param b a Bundle to be copied.
    100      */
    101     public Bundle(Bundle b) {
    102         super(b);
    103 
    104         mHasFds = b.mHasFds;
    105         mFdsKnown = b.mFdsKnown;
    106     }
    107 
    108     /**
    109      * Constructs a Bundle containing a copy of the mappings from the given
    110      * PersistableBundle.
    111      *
    112      * @param b a Bundle to be copied.
    113      */
    114     public Bundle(PersistableBundle b) {
    115         super(b);
    116     }
    117 
    118     /**
    119      * Make a Bundle for a single key/value pair.
    120      *
    121      * @hide
    122      */
    123     public static Bundle forPair(String key, String value) {
    124         Bundle b = new Bundle(1);
    125         b.putString(key, value);
    126         return b;
    127     }
    128 
    129     /**
    130      * Changes the ClassLoader this Bundle uses when instantiating objects.
    131      *
    132      * @param loader An explicit ClassLoader to use when instantiating objects
    133      * inside of the Bundle.
    134      */
    135     @Override
    136     public void setClassLoader(ClassLoader loader) {
    137         super.setClassLoader(loader);
    138     }
    139 
    140     /**
    141      * Return the ClassLoader currently associated with this Bundle.
    142      */
    143     @Override
    144     public ClassLoader getClassLoader() {
    145         return super.getClassLoader();
    146     }
    147 
    148     /** @hide */
    149     public boolean setAllowFds(boolean allowFds) {
    150         boolean orig = mAllowFds;
    151         mAllowFds = allowFds;
    152         return orig;
    153     }
    154 
    155     /**
    156      * Clones the current Bundle. The internal map is cloned, but the keys and
    157      * values to which it refers are copied by reference.
    158      */
    159     @Override
    160     public Object clone() {
    161         return new Bundle(this);
    162     }
    163 
    164     /**
    165      * Removes all elements from the mapping of this Bundle.
    166      */
    167     @Override
    168     public void clear() {
    169         super.clear();
    170 
    171         mHasFds = false;
    172         mFdsKnown = true;
    173     }
    174 
    175     /**
    176      * Inserts all mappings from the given Bundle into this Bundle.
    177      *
    178      * @param bundle a Bundle
    179      */
    180     public void putAll(Bundle bundle) {
    181         unparcel();
    182         bundle.unparcel();
    183         mMap.putAll(bundle.mMap);
    184 
    185         // fd state is now known if and only if both bundles already knew
    186         mHasFds |= bundle.mHasFds;
    187         mFdsKnown = mFdsKnown && bundle.mFdsKnown;
    188     }
    189 
    190     /**
    191      * Reports whether the bundle contains any parcelled file descriptors.
    192      */
    193     public boolean hasFileDescriptors() {
    194         if (!mFdsKnown) {
    195             boolean fdFound = false;    // keep going until we find one or run out of data
    196 
    197             if (mParcelledData != null) {
    198                 if (mParcelledData.hasFileDescriptors()) {
    199                     fdFound = true;
    200                 }
    201             } else {
    202                 // It's been unparcelled, so we need to walk the map
    203                 for (int i=mMap.size()-1; i>=0; i--) {
    204                     Object obj = mMap.valueAt(i);
    205                     if (obj instanceof Parcelable) {
    206                         if ((((Parcelable)obj).describeContents()
    207                                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
    208                             fdFound = true;
    209                             break;
    210                         }
    211                     } else if (obj instanceof Parcelable[]) {
    212                         Parcelable[] array = (Parcelable[]) obj;
    213                         for (int n = array.length - 1; n >= 0; n--) {
    214                             Parcelable p = array[n];
    215                             if (p != null && ((p.describeContents()
    216                                     & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
    217                                 fdFound = true;
    218                                 break;
    219                             }
    220                         }
    221                     } else if (obj instanceof SparseArray) {
    222                         SparseArray<? extends Parcelable> array =
    223                                 (SparseArray<? extends Parcelable>) obj;
    224                         for (int n = array.size() - 1; n >= 0; n--) {
    225                             Parcelable p = array.valueAt(n);
    226                             if (p != null && (p.describeContents()
    227                                     & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
    228                                 fdFound = true;
    229                                 break;
    230                             }
    231                         }
    232                     } else if (obj instanceof ArrayList) {
    233                         ArrayList array = (ArrayList) obj;
    234                         // an ArrayList here might contain either Strings or
    235                         // Parcelables; only look inside for Parcelables
    236                         if (!array.isEmpty() && (array.get(0) instanceof Parcelable)) {
    237                             for (int n = array.size() - 1; n >= 0; n--) {
    238                                 Parcelable p = (Parcelable) array.get(n);
    239                                 if (p != null && ((p.describeContents()
    240                                         & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
    241                                     fdFound = true;
    242                                     break;
    243                                 }
    244                             }
    245                         }
    246                     }
    247                 }
    248             }
    249 
    250             mHasFds = fdFound;
    251             mFdsKnown = true;
    252         }
    253         return mHasFds;
    254     }
    255 
    256     /**
    257      * Filter values in Bundle to only basic types.
    258      * @hide
    259      */
    260     public void filterValues() {
    261         unparcel();
    262         if (mMap != null) {
    263             for (int i = mMap.size() - 1; i >= 0; i--) {
    264                 Object value = mMap.valueAt(i);
    265                 if (PersistableBundle.isValidType(value)) {
    266                     continue;
    267                 }
    268                 if (value instanceof Bundle) {
    269                     ((Bundle)value).filterValues();
    270                 }
    271                 if (value.getClass().getName().startsWith("android.")) {
    272                     continue;
    273                 }
    274                 mMap.removeAt(i);
    275             }
    276         }
    277     }
    278 
    279     /**
    280      * Inserts a byte value into the mapping of this Bundle, replacing
    281      * any existing value for the given key.
    282      *
    283      * @param key a String, or null
    284      * @param value a byte
    285      */
    286     @Override
    287     public void putByte(@Nullable String key, byte value) {
    288         super.putByte(key, value);
    289     }
    290 
    291     /**
    292      * Inserts a char value into the mapping of this Bundle, replacing
    293      * any existing value for the given key.
    294      *
    295      * @param key a String, or null
    296      * @param value a char
    297      */
    298     @Override
    299     public void putChar(@Nullable String key, char value) {
    300         super.putChar(key, value);
    301     }
    302 
    303     /**
    304      * Inserts a short value into the mapping of this Bundle, replacing
    305      * any existing value for the given key.
    306      *
    307      * @param key a String, or null
    308      * @param value a short
    309      */
    310     @Override
    311     public void putShort(@Nullable String key, short value) {
    312         super.putShort(key, value);
    313     }
    314 
    315     /**
    316      * Inserts a float value into the mapping of this Bundle, replacing
    317      * any existing value for the given key.
    318      *
    319      * @param key a String, or null
    320      * @param value a float
    321      */
    322     @Override
    323     public void putFloat(@Nullable String key, float value) {
    324         super.putFloat(key, value);
    325     }
    326 
    327     /**
    328      * Inserts a CharSequence value into the mapping of this Bundle, replacing
    329      * any existing value for the given key.  Either key or value may be null.
    330      *
    331      * @param key a String, or null
    332      * @param value a CharSequence, or null
    333      */
    334     @Override
    335     public void putCharSequence(@Nullable String key, @Nullable CharSequence value) {
    336         super.putCharSequence(key, value);
    337     }
    338 
    339     /**
    340      * Inserts a Parcelable value into the mapping of this Bundle, replacing
    341      * any existing value for the given key.  Either key or value may be null.
    342      *
    343      * @param key a String, or null
    344      * @param value a Parcelable object, or null
    345      */
    346     public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
    347         unparcel();
    348         mMap.put(key, value);
    349         mFdsKnown = false;
    350     }
    351 
    352     /**
    353      * Inserts a Size value into the mapping of this Bundle, replacing
    354      * any existing value for the given key.  Either key or value may be null.
    355      *
    356      * @param key a String, or null
    357      * @param value a Size object, or null
    358      */
    359     public void putSize(@Nullable String key, @Nullable Size value) {
    360         unparcel();
    361         mMap.put(key, value);
    362     }
    363 
    364     /**
    365      * Inserts a SizeF value into the mapping of this Bundle, replacing
    366      * any existing value for the given key.  Either key or value may be null.
    367      *
    368      * @param key a String, or null
    369      * @param value a SizeF object, or null
    370      */
    371     public void putSizeF(@Nullable String key, @Nullable SizeF value) {
    372         unparcel();
    373         mMap.put(key, value);
    374     }
    375 
    376     /**
    377      * Inserts an array of Parcelable values into the mapping of this Bundle,
    378      * replacing any existing value for the given key.  Either key or value may
    379      * be null.
    380      *
    381      * @param key a String, or null
    382      * @param value an array of Parcelable objects, or null
    383      */
    384     public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
    385         unparcel();
    386         mMap.put(key, value);
    387         mFdsKnown = false;
    388     }
    389 
    390     /**
    391      * Inserts a List of Parcelable values into the mapping of this Bundle,
    392      * replacing any existing value for the given key.  Either key or value may
    393      * be null.
    394      *
    395      * @param key a String, or null
    396      * @param value an ArrayList of Parcelable objects, or null
    397      */
    398     public void putParcelableArrayList(@Nullable String key,
    399             @Nullable ArrayList<? extends Parcelable> value) {
    400         unparcel();
    401         mMap.put(key, value);
    402         mFdsKnown = false;
    403     }
    404 
    405     /** {@hide} */
    406     public void putParcelableList(String key, List<? extends Parcelable> value) {
    407         unparcel();
    408         mMap.put(key, value);
    409         mFdsKnown = false;
    410     }
    411 
    412     /**
    413      * Inserts a SparceArray of Parcelable values into the mapping of this
    414      * Bundle, replacing any existing value for the given key.  Either key
    415      * or value may be null.
    416      *
    417      * @param key a String, or null
    418      * @param value a SparseArray of Parcelable objects, or null
    419      */
    420     public void putSparseParcelableArray(@Nullable String key,
    421             @Nullable SparseArray<? extends Parcelable> value) {
    422         unparcel();
    423         mMap.put(key, value);
    424         mFdsKnown = false;
    425     }
    426 
    427     /**
    428      * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
    429      * any existing value for the given key.  Either key or value may be null.
    430      *
    431      * @param key a String, or null
    432      * @param value an ArrayList<Integer> object, or null
    433      */
    434     @Override
    435     public void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
    436         super.putIntegerArrayList(key, value);
    437     }
    438 
    439     /**
    440      * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
    441      * any existing value for the given key.  Either key or value may be null.
    442      *
    443      * @param key a String, or null
    444      * @param value an ArrayList<String> object, or null
    445      */
    446     @Override
    447     public void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
    448         super.putStringArrayList(key, value);
    449     }
    450 
    451     /**
    452      * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
    453      * any existing value for the given key.  Either key or value may be null.
    454      *
    455      * @param key a String, or null
    456      * @param value an ArrayList<CharSequence> object, or null
    457      */
    458     @Override
    459     public void putCharSequenceArrayList(@Nullable String key,
    460             @Nullable ArrayList<CharSequence> value) {
    461         super.putCharSequenceArrayList(key, value);
    462     }
    463 
    464     /**
    465      * Inserts a Serializable value into the mapping of this Bundle, replacing
    466      * any existing value for the given key.  Either key or value may be null.
    467      *
    468      * @param key a String, or null
    469      * @param value a Serializable object, or null
    470      */
    471     @Override
    472     public void putSerializable(@Nullable String key, @Nullable Serializable value) {
    473         super.putSerializable(key, value);
    474     }
    475 
    476     /**
    477      * Inserts a byte array value into the mapping of this Bundle, replacing
    478      * any existing value for the given key.  Either key or value may be null.
    479      *
    480      * @param key a String, or null
    481      * @param value a byte array object, or null
    482      */
    483     @Override
    484     public void putByteArray(@Nullable String key, @Nullable byte[] value) {
    485         super.putByteArray(key, value);
    486     }
    487 
    488     /**
    489      * Inserts a short array value into the mapping of this Bundle, replacing
    490      * any existing value for the given key.  Either key or value may be null.
    491      *
    492      * @param key a String, or null
    493      * @param value a short array object, or null
    494      */
    495     @Override
    496     public void putShortArray(@Nullable String key, @Nullable short[] value) {
    497         super.putShortArray(key, value);
    498     }
    499 
    500     /**
    501      * Inserts a char array value into the mapping of this Bundle, replacing
    502      * any existing value for the given key.  Either key or value may be null.
    503      *
    504      * @param key a String, or null
    505      * @param value a char array object, or null
    506      */
    507     @Override
    508     public void putCharArray(@Nullable String key, @Nullable char[] value) {
    509         super.putCharArray(key, value);
    510     }
    511 
    512     /**
    513      * Inserts a float array value into the mapping of this Bundle, replacing
    514      * any existing value for the given key.  Either key or value may be null.
    515      *
    516      * @param key a String, or null
    517      * @param value a float array object, or null
    518      */
    519     @Override
    520     public void putFloatArray(@Nullable String key, @Nullable float[] value) {
    521         super.putFloatArray(key, value);
    522     }
    523 
    524     /**
    525      * Inserts a CharSequence array value into the mapping of this Bundle, replacing
    526      * any existing value for the given key.  Either key or value may be null.
    527      *
    528      * @param key a String, or null
    529      * @param value a CharSequence array object, or null
    530      */
    531     @Override
    532     public void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
    533         super.putCharSequenceArray(key, value);
    534     }
    535 
    536     /**
    537      * Inserts a Bundle value into the mapping of this Bundle, replacing
    538      * any existing value for the given key.  Either key or value may be null.
    539      *
    540      * @param key a String, or null
    541      * @param value a Bundle object, or null
    542      */
    543     public void putBundle(@Nullable String key, @Nullable Bundle value) {
    544         unparcel();
    545         mMap.put(key, value);
    546     }
    547 
    548     /**
    549      * Inserts an {@link IBinder} value into the mapping of this Bundle, replacing
    550      * any existing value for the given key.  Either key or value may be null.
    551      *
    552      * <p class="note">You should be very careful when using this function.  In many
    553      * places where Bundles are used (such as inside of Intent objects), the Bundle
    554      * can live longer inside of another process than the process that had originally
    555      * created it.  In that case, the IBinder you supply here will become invalid
    556      * when your process goes away, and no longer usable, even if a new process is
    557      * created for you later on.</p>
    558      *
    559      * @param key a String, or null
    560      * @param value an IBinder object, or null
    561      */
    562     public void putBinder(@Nullable String key, @Nullable IBinder value) {
    563         unparcel();
    564         mMap.put(key, value);
    565     }
    566 
    567     /**
    568      * Inserts an IBinder value into the mapping of this Bundle, replacing
    569      * any existing value for the given key.  Either key or value may be null.
    570      *
    571      * @param key a String, or null
    572      * @param value an IBinder object, or null
    573      *
    574      * @deprecated
    575      * @hide This is the old name of the function.
    576      */
    577     @Deprecated
    578     public void putIBinder(@Nullable String key, @Nullable IBinder value) {
    579         unparcel();
    580         mMap.put(key, value);
    581     }
    582 
    583     /**
    584      * Returns the value associated with the given key, or (byte) 0 if
    585      * no mapping of the desired type exists for the given key.
    586      *
    587      * @param key a String
    588      * @return a byte value
    589      */
    590     @Override
    591     public byte getByte(String key) {
    592         return super.getByte(key);
    593     }
    594 
    595     /**
    596      * Returns the value associated with the given key, or defaultValue if
    597      * no mapping of the desired type exists for the given key.
    598      *
    599      * @param key a String
    600      * @param defaultValue Value to return if key does not exist
    601      * @return a byte value
    602      */
    603     @Override
    604     public Byte getByte(String key, byte defaultValue) {
    605         return super.getByte(key, defaultValue);
    606     }
    607 
    608     /**
    609      * Returns the value associated with the given key, or (char) 0 if
    610      * no mapping of the desired type exists for the given key.
    611      *
    612      * @param key a String
    613      * @return a char value
    614      */
    615     @Override
    616     public char getChar(String key) {
    617         return super.getChar(key);
    618     }
    619 
    620     /**
    621      * Returns the value associated with the given key, or defaultValue if
    622      * no mapping of the desired type exists for the given key.
    623      *
    624      * @param key a String
    625      * @param defaultValue Value to return if key does not exist
    626      * @return a char value
    627      */
    628     @Override
    629     public char getChar(String key, char defaultValue) {
    630         return super.getChar(key, defaultValue);
    631     }
    632 
    633     /**
    634      * Returns the value associated with the given key, or (short) 0 if
    635      * no mapping of the desired type exists for the given key.
    636      *
    637      * @param key a String
    638      * @return a short value
    639      */
    640     @Override
    641     public short getShort(String key) {
    642         return super.getShort(key);
    643     }
    644 
    645     /**
    646      * Returns the value associated with the given key, or defaultValue if
    647      * no mapping of the desired type exists for the given key.
    648      *
    649      * @param key a String
    650      * @param defaultValue Value to return if key does not exist
    651      * @return a short value
    652      */
    653     @Override
    654     public short getShort(String key, short defaultValue) {
    655         return super.getShort(key, defaultValue);
    656     }
    657 
    658     /**
    659      * Returns the value associated with the given key, or 0.0f if
    660      * no mapping of the desired type exists for the given key.
    661      *
    662      * @param key a String
    663      * @return a float value
    664      */
    665     @Override
    666     public float getFloat(String key) {
    667         return super.getFloat(key);
    668     }
    669 
    670     /**
    671      * Returns the value associated with the given key, or defaultValue if
    672      * no mapping of the desired type exists for the given key.
    673      *
    674      * @param key a String
    675      * @param defaultValue Value to return if key does not exist
    676      * @return a float value
    677      */
    678     @Override
    679     public float getFloat(String key, float defaultValue) {
    680         return super.getFloat(key, defaultValue);
    681     }
    682 
    683     /**
    684      * Returns the value associated with the given key, or null if
    685      * no mapping of the desired type exists for the given key or a null
    686      * value is explicitly associated with the key.
    687      *
    688      * @param key a String, or null
    689      * @return a CharSequence value, or null
    690      */
    691     @Override
    692     @Nullable
    693     public CharSequence getCharSequence(@Nullable String key) {
    694         return super.getCharSequence(key);
    695     }
    696 
    697     /**
    698      * Returns the value associated with the given key, or defaultValue if
    699      * no mapping of the desired type exists for the given key or if a null
    700      * value is explicitly associatd with the given key.
    701      *
    702      * @param key a String, or null
    703      * @param defaultValue Value to return if key does not exist or if a null
    704      *     value is associated with the given key.
    705      * @return the CharSequence value associated with the given key, or defaultValue
    706      *     if no valid CharSequence object is currently mapped to that key.
    707      */
    708     @Override
    709     public CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) {
    710         return super.getCharSequence(key, defaultValue);
    711     }
    712 
    713     /**
    714      * Returns the value associated with the given key, or null if
    715      * no mapping of the desired type exists for the given key or a null
    716      * value is explicitly associated with the key.
    717      *
    718      * @param key a String, or null
    719      * @return a Size value, or null
    720      */
    721     @Nullable
    722     public Size getSize(@Nullable String key) {
    723         unparcel();
    724         final Object o = mMap.get(key);
    725         try {
    726             return (Size) o;
    727         } catch (ClassCastException e) {
    728             typeWarning(key, o, "Size", e);
    729             return null;
    730         }
    731     }
    732 
    733     /**
    734      * Returns the value associated with the given key, or null if
    735      * no mapping of the desired type exists for the given key or a null
    736      * value is explicitly associated with the key.
    737      *
    738      * @param key a String, or null
    739      * @return a Size value, or null
    740      */
    741     @Nullable
    742     public SizeF getSizeF(@Nullable String key) {
    743         unparcel();
    744         final Object o = mMap.get(key);
    745         try {
    746             return (SizeF) o;
    747         } catch (ClassCastException e) {
    748             typeWarning(key, o, "SizeF", e);
    749             return null;
    750         }
    751     }
    752 
    753     /**
    754      * Returns the value associated with the given key, or null if
    755      * no mapping of the desired type exists for the given key or a null
    756      * value is explicitly associated with the key.
    757      *
    758      * @param key a String, or null
    759      * @return a Bundle value, or null
    760      */
    761     @Nullable
    762     public Bundle getBundle(@Nullable String key) {
    763         unparcel();
    764         Object o = mMap.get(key);
    765         if (o == null) {
    766             return null;
    767         }
    768         try {
    769             return (Bundle) o;
    770         } catch (ClassCastException e) {
    771             typeWarning(key, o, "Bundle", e);
    772             return null;
    773         }
    774     }
    775 
    776     /**
    777      * Returns the value associated with the given key, or null if
    778      * no mapping of the desired type exists for the given key or a null
    779      * value is explicitly associated with the key.
    780      *
    781      * @param key a String, or null
    782      * @return a Parcelable value, or null
    783      */
    784     @Nullable
    785     public <T extends Parcelable> T getParcelable(@Nullable String key) {
    786         unparcel();
    787         Object o = mMap.get(key);
    788         if (o == null) {
    789             return null;
    790         }
    791         try {
    792             return (T) o;
    793         } catch (ClassCastException e) {
    794             typeWarning(key, o, "Parcelable", e);
    795             return null;
    796         }
    797     }
    798 
    799     /**
    800      * Returns the value associated with the given key, or null if
    801      * no mapping of the desired type exists for the given key or a null
    802      * value is explicitly associated with the key.
    803      *
    804      * @param key a String, or null
    805      * @return a Parcelable[] value, or null
    806      */
    807     @Nullable
    808     public Parcelable[] getParcelableArray(@Nullable String key) {
    809         unparcel();
    810         Object o = mMap.get(key);
    811         if (o == null) {
    812             return null;
    813         }
    814         try {
    815             return (Parcelable[]) o;
    816         } catch (ClassCastException e) {
    817             typeWarning(key, o, "Parcelable[]", e);
    818             return null;
    819         }
    820     }
    821 
    822     /**
    823      * Returns the value associated with the given key, or null if
    824      * no mapping of the desired type exists for the given key or a null
    825      * value is explicitly associated with the key.
    826      *
    827      * @param key a String, or null
    828      * @return an ArrayList<T> value, or null
    829      */
    830     @Nullable
    831     public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) {
    832         unparcel();
    833         Object o = mMap.get(key);
    834         if (o == null) {
    835             return null;
    836         }
    837         try {
    838             return (ArrayList<T>) o;
    839         } catch (ClassCastException e) {
    840             typeWarning(key, o, "ArrayList", e);
    841             return null;
    842         }
    843     }
    844 
    845     /**
    846      * Returns the value associated with the given key, or null if
    847      * no mapping of the desired type exists for the given key or a null
    848      * value is explicitly associated with the key.
    849      *
    850      * @param key a String, or null
    851      *
    852      * @return a SparseArray of T values, or null
    853      */
    854     @Nullable
    855     public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(@Nullable String key) {
    856         unparcel();
    857         Object o = mMap.get(key);
    858         if (o == null) {
    859             return null;
    860         }
    861         try {
    862             return (SparseArray<T>) o;
    863         } catch (ClassCastException e) {
    864             typeWarning(key, o, "SparseArray", e);
    865             return null;
    866         }
    867     }
    868 
    869     /**
    870      * Returns the value associated with the given key, or null if
    871      * no mapping of the desired type exists for the given key or a null
    872      * value is explicitly associated with the key.
    873      *
    874      * @param key a String, or null
    875      * @return a Serializable value, or null
    876      */
    877     @Override
    878     @Nullable
    879     public Serializable getSerializable(@Nullable String key) {
    880         return super.getSerializable(key);
    881     }
    882 
    883     /**
    884      * Returns the value associated with the given key, or null if
    885      * no mapping of the desired type exists for the given key or a null
    886      * value is explicitly associated with the key.
    887      *
    888      * @param key a String, or null
    889      * @return an ArrayList<String> value, or null
    890      */
    891     @Override
    892     @Nullable
    893     public ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
    894         return super.getIntegerArrayList(key);
    895     }
    896 
    897     /**
    898      * Returns the value associated with the given key, or null if
    899      * no mapping of the desired type exists for the given key or a null
    900      * value is explicitly associated with the key.
    901      *
    902      * @param key a String, or null
    903      * @return an ArrayList<String> value, or null
    904      */
    905     @Override
    906     @Nullable
    907     public ArrayList<String> getStringArrayList(@Nullable String key) {
    908         return super.getStringArrayList(key);
    909     }
    910 
    911     /**
    912      * Returns the value associated with the given key, or null if
    913      * no mapping of the desired type exists for the given key or a null
    914      * value is explicitly associated with the key.
    915      *
    916      * @param key a String, or null
    917      * @return an ArrayList<CharSequence> value, or null
    918      */
    919     @Override
    920     @Nullable
    921     public ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) {
    922         return super.getCharSequenceArrayList(key);
    923     }
    924 
    925     /**
    926      * Returns the value associated with the given key, or null if
    927      * no mapping of the desired type exists for the given key or a null
    928      * value is explicitly associated with the key.
    929      *
    930      * @param key a String, or null
    931      * @return a byte[] value, or null
    932      */
    933     @Override
    934     @Nullable
    935     public byte[] getByteArray(@Nullable String key) {
    936         return super.getByteArray(key);
    937     }
    938 
    939     /**
    940      * Returns the value associated with the given key, or null if
    941      * no mapping of the desired type exists for the given key or a null
    942      * value is explicitly associated with the key.
    943      *
    944      * @param key a String, or null
    945      * @return a short[] value, or null
    946      */
    947     @Override
    948     @Nullable
    949     public short[] getShortArray(@Nullable String key) {
    950         return super.getShortArray(key);
    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 char[] value, or null
    960      */
    961     @Override
    962     @Nullable
    963     public char[] getCharArray(@Nullable String key) {
    964         return super.getCharArray(key);
    965     }
    966 
    967     /**
    968      * Returns the value associated with the given key, or null if
    969      * no mapping of the desired type exists for the given key or a null
    970      * value is explicitly associated with the key.
    971      *
    972      * @param key a String, or null
    973      * @return a float[] value, or null
    974      */
    975     @Override
    976     @Nullable
    977     public float[] getFloatArray(@Nullable String key) {
    978         return super.getFloatArray(key);
    979     }
    980 
    981     /**
    982      * Returns the value associated with the given key, or null if
    983      * no mapping of the desired type exists for the given key or a null
    984      * value is explicitly associated with the key.
    985      *
    986      * @param key a String, or null
    987      * @return a CharSequence[] value, or null
    988      */
    989     @Override
    990     @Nullable
    991     public CharSequence[] getCharSequenceArray(@Nullable String key) {
    992         return super.getCharSequenceArray(key);
    993     }
    994 
    995     /**
    996      * Returns the value associated with the given key, or null if
    997      * no mapping of the desired type exists for the given key or a null
    998      * value is explicitly associated with the key.
    999      *
   1000      * @param key a String, or null
   1001      * @return an IBinder value, or null
   1002      */
   1003     @Nullable
   1004     public IBinder getBinder(@Nullable String key) {
   1005         unparcel();
   1006         Object o = mMap.get(key);
   1007         if (o == null) {
   1008             return null;
   1009         }
   1010         try {
   1011             return (IBinder) o;
   1012         } catch (ClassCastException e) {
   1013             typeWarning(key, o, "IBinder", e);
   1014             return null;
   1015         }
   1016     }
   1017 
   1018     /**
   1019      * Returns the value associated with the given key, or null if
   1020      * no mapping of the desired type exists for the given key or a null
   1021      * value is explicitly associated with the key.
   1022      *
   1023      * @param key a String, or null
   1024      * @return an IBinder value, or null
   1025      *
   1026      * @deprecated
   1027      * @hide This is the old name of the function.
   1028      */
   1029     @Deprecated
   1030     @Nullable
   1031     public IBinder getIBinder(@Nullable String key) {
   1032         unparcel();
   1033         Object o = mMap.get(key);
   1034         if (o == null) {
   1035             return null;
   1036         }
   1037         try {
   1038             return (IBinder) o;
   1039         } catch (ClassCastException e) {
   1040             typeWarning(key, o, "IBinder", e);
   1041             return null;
   1042         }
   1043     }
   1044 
   1045     public static final Parcelable.Creator<Bundle> CREATOR =
   1046         new Parcelable.Creator<Bundle>() {
   1047         @Override
   1048         public Bundle createFromParcel(Parcel in) {
   1049             return in.readBundle();
   1050         }
   1051 
   1052         @Override
   1053         public Bundle[] newArray(int size) {
   1054             return new Bundle[size];
   1055         }
   1056     };
   1057 
   1058     /**
   1059      * Report the nature of this Parcelable's contents
   1060      */
   1061     @Override
   1062     public int describeContents() {
   1063         int mask = 0;
   1064         if (hasFileDescriptors()) {
   1065             mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
   1066         }
   1067         return mask;
   1068     }
   1069 
   1070     /**
   1071      * Writes the Bundle contents to a Parcel, typically in order for
   1072      * it to be passed through an IBinder connection.
   1073      * @param parcel The parcel to copy this bundle to.
   1074      */
   1075     @Override
   1076     public void writeToParcel(Parcel parcel, int flags) {
   1077         final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
   1078         try {
   1079             super.writeToParcelInner(parcel, flags);
   1080         } finally {
   1081             parcel.restoreAllowFds(oldAllowFds);
   1082         }
   1083     }
   1084 
   1085     /**
   1086      * Reads the Parcel contents into this Bundle, typically in order for
   1087      * it to be passed through an IBinder connection.
   1088      * @param parcel The parcel to overwrite this bundle from.
   1089      */
   1090     public void readFromParcel(Parcel parcel) {
   1091         super.readFromParcelInner(parcel);
   1092         mHasFds = mParcelledData.hasFileDescriptors();
   1093         mFdsKnown = true;
   1094     }
   1095 
   1096     @Override
   1097     public synchronized String toString() {
   1098         if (mParcelledData != null) {
   1099             if (mParcelledData == EMPTY_PARCEL) {
   1100                 return "Bundle[EMPTY_PARCEL]";
   1101             } else {
   1102                 return "Bundle[mParcelledData.dataSize=" +
   1103                         mParcelledData.dataSize() + "]";
   1104             }
   1105         }
   1106         return "Bundle[" + mMap.toString() + "]";
   1107     }
   1108 
   1109 }
   1110