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.util.ArrayMap;
     20 import android.util.Size;
     21 import android.util.SizeF;
     22 import android.util.SparseArray;
     23 
     24 import java.io.Serializable;
     25 import java.util.ArrayList;
     26 import java.util.List;
     27 import java.util.Set;
     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                             if ((array[n].describeContents()
    215                                     & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
    216                                 fdFound = true;
    217                                 break;
    218                             }
    219                         }
    220                     } else if (obj instanceof SparseArray) {
    221                         SparseArray<? extends Parcelable> array =
    222                                 (SparseArray<? extends Parcelable>) obj;
    223                         for (int n = array.size() - 1; n >= 0; n--) {
    224                             if ((array.valueAt(n).describeContents()
    225                                     & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
    226                                 fdFound = true;
    227                                 break;
    228                             }
    229                         }
    230                     } else if (obj instanceof ArrayList) {
    231                         ArrayList array = (ArrayList) obj;
    232                         // an ArrayList here might contain either Strings or
    233                         // Parcelables; only look inside for Parcelables
    234                         if (!array.isEmpty() && (array.get(0) instanceof Parcelable)) {
    235                             for (int n = array.size() - 1; n >= 0; n--) {
    236                                 Parcelable p = (Parcelable) array.get(n);
    237                                 if (p != null && ((p.describeContents()
    238                                         & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
    239                                     fdFound = true;
    240                                     break;
    241                                 }
    242                             }
    243                         }
    244                     }
    245                 }
    246             }
    247 
    248             mHasFds = fdFound;
    249             mFdsKnown = true;
    250         }
    251         return mHasFds;
    252     }
    253 
    254     /**
    255      * Inserts a Boolean value into the mapping of this Bundle, replacing
    256      * any existing value for the given key.  Either key or value may be null.
    257      *
    258      * @param key a String, or null
    259      * @param value a Boolean, or null
    260      */
    261     @Override
    262     public void putBoolean(String key, boolean value) {
    263         super.putBoolean(key, value);
    264     }
    265 
    266     /**
    267      * Inserts a byte value into the mapping of this Bundle, replacing
    268      * any existing value for the given key.
    269      *
    270      * @param key a String, or null
    271      * @param value a byte
    272      */
    273     @Override
    274     public void putByte(String key, byte value) {
    275         super.putByte(key, value);
    276     }
    277 
    278     /**
    279      * Inserts a char value into the mapping of this Bundle, replacing
    280      * any existing value for the given key.
    281      *
    282      * @param key a String, or null
    283      * @param value a char, or null
    284      */
    285     @Override
    286     public void putChar(String key, char value) {
    287         super.putChar(key, value);
    288     }
    289 
    290     /**
    291      * Inserts a short value into the mapping of this Bundle, replacing
    292      * any existing value for the given key.
    293      *
    294      * @param key a String, or null
    295      * @param value a short
    296      */
    297     @Override
    298     public void putShort(String key, short value) {
    299         super.putShort(key, value);
    300     }
    301 
    302     /**
    303      * Inserts a float value into the mapping of this Bundle, replacing
    304      * any existing value for the given key.
    305      *
    306      * @param key a String, or null
    307      * @param value a float
    308      */
    309     @Override
    310     public void putFloat(String key, float value) {
    311         super.putFloat(key, value);
    312     }
    313 
    314     /**
    315      * Inserts a CharSequence value into the mapping of this Bundle, replacing
    316      * any existing value for the given key.  Either key or value may be null.
    317      *
    318      * @param key a String, or null
    319      * @param value a CharSequence, or null
    320      */
    321     @Override
    322     public void putCharSequence(String key, CharSequence value) {
    323         super.putCharSequence(key, value);
    324     }
    325 
    326     /**
    327      * Inserts a Parcelable value into the mapping of this Bundle, replacing
    328      * any existing value for the given key.  Either key or value may be null.
    329      *
    330      * @param key a String, or null
    331      * @param value a Parcelable object, or null
    332      */
    333     public void putParcelable(String key, Parcelable value) {
    334         unparcel();
    335         mMap.put(key, value);
    336         mFdsKnown = false;
    337     }
    338 
    339     /**
    340      * Inserts a Size 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 Size object, or null
    345      */
    346     public void putSize(String key, Size value) {
    347         unparcel();
    348         mMap.put(key, value);
    349     }
    350 
    351     /**
    352      * Inserts a SizeF value into the mapping of this Bundle, replacing
    353      * any existing value for the given key.  Either key or value may be null.
    354      *
    355      * @param key a String, or null
    356      * @param value a SizeF object, or null
    357      */
    358     public void putSizeF(String key, SizeF value) {
    359         unparcel();
    360         mMap.put(key, value);
    361     }
    362 
    363     /**
    364      * Inserts an array of Parcelable values into the mapping of this Bundle,
    365      * replacing any existing value for the given key.  Either key or value may
    366      * be null.
    367      *
    368      * @param key a String, or null
    369      * @param value an array of Parcelable objects, or null
    370      */
    371     public void putParcelableArray(String key, Parcelable[] value) {
    372         unparcel();
    373         mMap.put(key, value);
    374         mFdsKnown = false;
    375     }
    376 
    377     /**
    378      * Inserts a List of Parcelable values into the mapping of this Bundle,
    379      * replacing any existing value for the given key.  Either key or value may
    380      * be null.
    381      *
    382      * @param key a String, or null
    383      * @param value an ArrayList of Parcelable objects, or null
    384      */
    385     public void putParcelableArrayList(String key,
    386             ArrayList<? extends Parcelable> value) {
    387         unparcel();
    388         mMap.put(key, value);
    389         mFdsKnown = false;
    390     }
    391 
    392     /** {@hide} */
    393     public void putParcelableList(String key, List<? extends Parcelable> value) {
    394         unparcel();
    395         mMap.put(key, value);
    396         mFdsKnown = false;
    397     }
    398 
    399     /**
    400      * Inserts a SparceArray of Parcelable values into the mapping of this
    401      * Bundle, replacing any existing value for the given key.  Either key
    402      * or value may be null.
    403      *
    404      * @param key a String, or null
    405      * @param value a SparseArray of Parcelable objects, or null
    406      */
    407     public void putSparseParcelableArray(String key,
    408             SparseArray<? extends Parcelable> value) {
    409         unparcel();
    410         mMap.put(key, value);
    411         mFdsKnown = false;
    412     }
    413 
    414     /**
    415      * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
    416      * any existing value for the given key.  Either key or value may be null.
    417      *
    418      * @param key a String, or null
    419      * @param value an ArrayList<Integer> object, or null
    420      */
    421     @Override
    422     public void putIntegerArrayList(String key, ArrayList<Integer> value) {
    423         super.putIntegerArrayList(key, value);
    424     }
    425 
    426     /**
    427      * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
    428      * any existing value for the given key.  Either key or value may be null.
    429      *
    430      * @param key a String, or null
    431      * @param value an ArrayList<String> object, or null
    432      */
    433     @Override
    434     public void putStringArrayList(String key, ArrayList<String> value) {
    435         super.putStringArrayList(key, value);
    436     }
    437 
    438     /**
    439      * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
    440      * any existing value for the given key.  Either key or value may be null.
    441      *
    442      * @param key a String, or null
    443      * @param value an ArrayList<CharSequence> object, or null
    444      */
    445     @Override
    446     public void putCharSequenceArrayList(String key, ArrayList<CharSequence> value) {
    447         super.putCharSequenceArrayList(key, value);
    448     }
    449 
    450     /**
    451      * Inserts a Serializable value into the mapping of this Bundle, replacing
    452      * any existing value for the given key.  Either key or value may be null.
    453      *
    454      * @param key a String, or null
    455      * @param value a Serializable object, or null
    456      */
    457     @Override
    458     public void putSerializable(String key, Serializable value) {
    459         super.putSerializable(key, value);
    460     }
    461 
    462     /**
    463      * Inserts a boolean array value into the mapping of this Bundle, replacing
    464      * any existing value for the given key.  Either key or value may be null.
    465      *
    466      * @param key a String, or null
    467      * @param value a boolean array object, or null
    468      */
    469     @Override
    470     public void putBooleanArray(String key, boolean[] value) {
    471         super.putBooleanArray(key, value);
    472     }
    473 
    474     /**
    475      * Inserts a byte array value into the mapping of this Bundle, replacing
    476      * any existing value for the given key.  Either key or value may be null.
    477      *
    478      * @param key a String, or null
    479      * @param value a byte array object, or null
    480      */
    481     @Override
    482     public void putByteArray(String key, byte[] value) {
    483         super.putByteArray(key, value);
    484     }
    485 
    486     /**
    487      * Inserts a short array value into the mapping of this Bundle, replacing
    488      * any existing value for the given key.  Either key or value may be null.
    489      *
    490      * @param key a String, or null
    491      * @param value a short array object, or null
    492      */
    493     @Override
    494     public void putShortArray(String key, short[] value) {
    495         super.putShortArray(key, value);
    496     }
    497 
    498     /**
    499      * Inserts a char array value into the mapping of this Bundle, replacing
    500      * any existing value for the given key.  Either key or value may be null.
    501      *
    502      * @param key a String, or null
    503      * @param value a char array object, or null
    504      */
    505     @Override
    506     public void putCharArray(String key, char[] value) {
    507         super.putCharArray(key, value);
    508     }
    509 
    510     /**
    511      * Inserts a float array value into the mapping of this Bundle, replacing
    512      * any existing value for the given key.  Either key or value may be null.
    513      *
    514      * @param key a String, or null
    515      * @param value a float array object, or null
    516      */
    517     @Override
    518     public void putFloatArray(String key, float[] value) {
    519         super.putFloatArray(key, value);
    520     }
    521 
    522     /**
    523      * Inserts a CharSequence array value into the mapping of this Bundle, replacing
    524      * any existing value for the given key.  Either key or value may be null.
    525      *
    526      * @param key a String, or null
    527      * @param value a CharSequence array object, or null
    528      */
    529     @Override
    530     public void putCharSequenceArray(String key, CharSequence[] value) {
    531         super.putCharSequenceArray(key, value);
    532     }
    533 
    534     /**
    535      * Inserts a Bundle value into the mapping of this Bundle, replacing
    536      * any existing value for the given key.  Either key or value may be null.
    537      *
    538      * @param key a String, or null
    539      * @param value a Bundle object, or null
    540      */
    541     public void putBundle(String key, Bundle value) {
    542         unparcel();
    543         mMap.put(key, value);
    544     }
    545 
    546     /**
    547      * Inserts an {@link IBinder} value into the mapping of this Bundle, replacing
    548      * any existing value for the given key.  Either key or value may be null.
    549      *
    550      * <p class="note">You should be very careful when using this function.  In many
    551      * places where Bundles are used (such as inside of Intent objects), the Bundle
    552      * can live longer inside of another process than the process that had originally
    553      * created it.  In that case, the IBinder you supply here will become invalid
    554      * when your process goes away, and no longer usable, even if a new process is
    555      * created for you later on.</p>
    556      *
    557      * @param key a String, or null
    558      * @param value an IBinder object, or null
    559      */
    560     public void putBinder(String key, IBinder value) {
    561         unparcel();
    562         mMap.put(key, value);
    563     }
    564 
    565     /**
    566      * Inserts an IBinder value into the mapping of this Bundle, replacing
    567      * any existing value for the given key.  Either key or value may be null.
    568      *
    569      * @param key a String, or null
    570      * @param value an IBinder object, or null
    571      *
    572      * @deprecated
    573      * @hide This is the old name of the function.
    574      */
    575     @Deprecated
    576     public void putIBinder(String key, IBinder value) {
    577         unparcel();
    578         mMap.put(key, value);
    579     }
    580 
    581     /**
    582      * Returns the value associated with the given key, or false if
    583      * no mapping of the desired type exists for the given key.
    584      *
    585      * @param key a String
    586      * @return a boolean value
    587      */
    588     @Override
    589     public boolean getBoolean(String key) {
    590         return super.getBoolean(key);
    591     }
    592 
    593     /**
    594      * Returns the value associated with the given key, or defaultValue if
    595      * no mapping of the desired type exists for the given key.
    596      *
    597      * @param key a String
    598      * @param defaultValue Value to return if key does not exist
    599      * @return a boolean value
    600      */
    601     @Override
    602     public boolean getBoolean(String key, boolean defaultValue) {
    603         return super.getBoolean(key, defaultValue);
    604     }
    605 
    606     /**
    607      * Returns the value associated with the given key, or (byte) 0 if
    608      * no mapping of the desired type exists for the given key.
    609      *
    610      * @param key a String
    611      * @return a byte value
    612      */
    613     @Override
    614     public byte getByte(String key) {
    615         return super.getByte(key);
    616     }
    617 
    618     /**
    619      * Returns the value associated with the given key, or defaultValue if
    620      * no mapping of the desired type exists for the given key.
    621      *
    622      * @param key a String
    623      * @param defaultValue Value to return if key does not exist
    624      * @return a byte value
    625      */
    626     @Override
    627     public Byte getByte(String key, byte defaultValue) {
    628         return super.getByte(key, defaultValue);
    629     }
    630 
    631     /**
    632      * Returns the value associated with the given key, or (char) 0 if
    633      * no mapping of the desired type exists for the given key.
    634      *
    635      * @param key a String
    636      * @return a char value
    637      */
    638     @Override
    639     public char getChar(String key) {
    640         return super.getChar(key);
    641     }
    642 
    643     /**
    644      * Returns the value associated with the given key, or defaultValue if
    645      * no mapping of the desired type exists for the given key.
    646      *
    647      * @param key a String
    648      * @param defaultValue Value to return if key does not exist
    649      * @return a char value
    650      */
    651     @Override
    652     public char getChar(String key, char defaultValue) {
    653         return super.getChar(key, defaultValue);
    654     }
    655 
    656     /**
    657      * Returns the value associated with the given key, or (short) 0 if
    658      * no mapping of the desired type exists for the given key.
    659      *
    660      * @param key a String
    661      * @return a short value
    662      */
    663     @Override
    664     public short getShort(String key) {
    665         return super.getShort(key);
    666     }
    667 
    668     /**
    669      * Returns the value associated with the given key, or defaultValue if
    670      * no mapping of the desired type exists for the given key.
    671      *
    672      * @param key a String
    673      * @param defaultValue Value to return if key does not exist
    674      * @return a short value
    675      */
    676     @Override
    677     public short getShort(String key, short defaultValue) {
    678         return super.getShort(key, defaultValue);
    679     }
    680 
    681     /**
    682      * Returns the value associated with the given key, or 0.0f if
    683      * no mapping of the desired type exists for the given key.
    684      *
    685      * @param key a String
    686      * @return a float value
    687      */
    688     @Override
    689     public float getFloat(String key) {
    690         return super.getFloat(key);
    691     }
    692 
    693     /**
    694      * Returns the value associated with the given key, or defaultValue if
    695      * no mapping of the desired type exists for the given key.
    696      *
    697      * @param key a String
    698      * @param defaultValue Value to return if key does not exist
    699      * @return a float value
    700      */
    701     @Override
    702     public float getFloat(String key, float defaultValue) {
    703         return super.getFloat(key, defaultValue);
    704     }
    705 
    706     /**
    707      * Returns the value associated with the given key, or null if
    708      * no mapping of the desired type exists for the given key or a null
    709      * value is explicitly associated with the key.
    710      *
    711      * @param key a String, or null
    712      * @return a CharSequence value, or null
    713      */
    714     @Override
    715     public CharSequence getCharSequence(String key) {
    716         return super.getCharSequence(key);
    717     }
    718 
    719     /**
    720      * Returns the value associated with the given key, or defaultValue if
    721      * no mapping of the desired type exists for the given key or if a null
    722      * value is explicitly associatd with the given key.
    723      *
    724      * @param key a String, or null
    725      * @param defaultValue Value to return if key does not exist or if a null
    726      *     value is associated with the given key.
    727      * @return the CharSequence value associated with the given key, or defaultValue
    728      *     if no valid CharSequence object is currently mapped to that key.
    729      */
    730     @Override
    731     public CharSequence getCharSequence(String key, CharSequence defaultValue) {
    732         return super.getCharSequence(key, defaultValue);
    733     }
    734 
    735     /**
    736      * Returns the value associated with the given key, or null if
    737      * no mapping of the desired type exists for the given key or a null
    738      * value is explicitly associated with the key.
    739      *
    740      * @param key a String, or null
    741      * @return a Size value, or null
    742      */
    743     public Size getSize(String key) {
    744         unparcel();
    745         final Object o = mMap.get(key);
    746         try {
    747             return (Size) o;
    748         } catch (ClassCastException e) {
    749             typeWarning(key, o, "Size", e);
    750             return null;
    751         }
    752     }
    753 
    754     /**
    755      * Returns the value associated with the given key, or null if
    756      * no mapping of the desired type exists for the given key or a null
    757      * value is explicitly associated with the key.
    758      *
    759      * @param key a String, or null
    760      * @return a Size value, or null
    761      */
    762     public SizeF getSizeF(String key) {
    763         unparcel();
    764         final Object o = mMap.get(key);
    765         try {
    766             return (SizeF) o;
    767         } catch (ClassCastException e) {
    768             typeWarning(key, o, "SizeF", e);
    769             return null;
    770         }
    771     }
    772 
    773     /**
    774      * Returns the value associated with the given key, or null if
    775      * no mapping of the desired type exists for the given key or a null
    776      * value is explicitly associated with the key.
    777      *
    778      * @param key a String, or null
    779      * @return a Bundle value, or null
    780      */
    781     public Bundle getBundle(String key) {
    782         unparcel();
    783         Object o = mMap.get(key);
    784         if (o == null) {
    785             return null;
    786         }
    787         try {
    788             return (Bundle) o;
    789         } catch (ClassCastException e) {
    790             typeWarning(key, o, "Bundle", e);
    791             return null;
    792         }
    793     }
    794 
    795     /**
    796      * Returns the value associated with the given key, or null if
    797      * no mapping of the desired type exists for the given key or a null
    798      * value is explicitly associated with the key.
    799      *
    800      * @param key a String, or null
    801      * @return a Parcelable value, or null
    802      */
    803     public <T extends Parcelable> T getParcelable(String key) {
    804         unparcel();
    805         Object o = mMap.get(key);
    806         if (o == null) {
    807             return null;
    808         }
    809         try {
    810             return (T) o;
    811         } catch (ClassCastException e) {
    812             typeWarning(key, o, "Parcelable", e);
    813             return null;
    814         }
    815     }
    816 
    817     /**
    818      * Returns the value associated with the given key, or null if
    819      * no mapping of the desired type exists for the given key or a null
    820      * value is explicitly associated with the key.
    821      *
    822      * @param key a String, or null
    823      * @return a Parcelable[] value, or null
    824      */
    825     public Parcelable[] getParcelableArray(String key) {
    826         unparcel();
    827         Object o = mMap.get(key);
    828         if (o == null) {
    829             return null;
    830         }
    831         try {
    832             return (Parcelable[]) o;
    833         } catch (ClassCastException e) {
    834             typeWarning(key, o, "Parcelable[]", e);
    835             return null;
    836         }
    837     }
    838 
    839     /**
    840      * Returns the value associated with the given key, or null if
    841      * no mapping of the desired type exists for the given key or a null
    842      * value is explicitly associated with the key.
    843      *
    844      * @param key a String, or null
    845      * @return an ArrayList<T> value, or null
    846      */
    847     public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String key) {
    848         unparcel();
    849         Object o = mMap.get(key);
    850         if (o == null) {
    851             return null;
    852         }
    853         try {
    854             return (ArrayList<T>) o;
    855         } catch (ClassCastException e) {
    856             typeWarning(key, o, "ArrayList", e);
    857             return null;
    858         }
    859     }
    860 
    861     /**
    862      * Returns the value associated with the given key, or null if
    863      * no mapping of the desired type exists for the given key or a null
    864      * value is explicitly associated with the key.
    865      *
    866      * @param key a String, or null
    867      *
    868      * @return a SparseArray of T values, or null
    869      */
    870     public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(String key) {
    871         unparcel();
    872         Object o = mMap.get(key);
    873         if (o == null) {
    874             return null;
    875         }
    876         try {
    877             return (SparseArray<T>) o;
    878         } catch (ClassCastException e) {
    879             typeWarning(key, o, "SparseArray", e);
    880             return null;
    881         }
    882     }
    883 
    884     /**
    885      * Returns the value associated with the given key, or null if
    886      * no mapping of the desired type exists for the given key or a null
    887      * value is explicitly associated with the key.
    888      *
    889      * @param key a String, or null
    890      * @return a Serializable value, or null
    891      */
    892     @Override
    893     public Serializable getSerializable(String key) {
    894         return super.getSerializable(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     public ArrayList<Integer> getIntegerArrayList(String key) {
    907         return super.getIntegerArrayList(key);
    908     }
    909 
    910     /**
    911      * Returns the value associated with the given key, or null if
    912      * no mapping of the desired type exists for the given key or a null
    913      * value is explicitly associated with the key.
    914      *
    915      * @param key a String, or null
    916      * @return an ArrayList<String> value, or null
    917      */
    918     @Override
    919     public ArrayList<String> getStringArrayList(String key) {
    920         return super.getStringArrayList(key);
    921     }
    922 
    923     /**
    924      * Returns the value associated with the given key, or null if
    925      * no mapping of the desired type exists for the given key or a null
    926      * value is explicitly associated with the key.
    927      *
    928      * @param key a String, or null
    929      * @return an ArrayList<CharSequence> value, or null
    930      */
    931     @Override
    932     public ArrayList<CharSequence> getCharSequenceArrayList(String key) {
    933         return super.getCharSequenceArrayList(key);
    934     }
    935 
    936     /**
    937      * Returns the value associated with the given key, or null if
    938      * no mapping of the desired type exists for the given key or a null
    939      * value is explicitly associated with the key.
    940      *
    941      * @param key a String, or null
    942      * @return a boolean[] value, or null
    943      */
    944     @Override
    945     public boolean[] getBooleanArray(String key) {
    946         return super.getBooleanArray(key);
    947     }
    948 
    949     /**
    950      * Returns the value associated with the given key, or null if
    951      * no mapping of the desired type exists for the given key or a null
    952      * value is explicitly associated with the key.
    953      *
    954      * @param key a String, or null
    955      * @return a byte[] value, or null
    956      */
    957     @Override
    958     public byte[] getByteArray(String key) {
    959         return super.getByteArray(key);
    960     }
    961 
    962     /**
    963      * Returns the value associated with the given key, or null if
    964      * no mapping of the desired type exists for the given key or a null
    965      * value is explicitly associated with the key.
    966      *
    967      * @param key a String, or null
    968      * @return a short[] value, or null
    969      */
    970     @Override
    971     public short[] getShortArray(String key) {
    972         return super.getShortArray(key);
    973     }
    974 
    975     /**
    976      * Returns the value associated with the given key, or null if
    977      * no mapping of the desired type exists for the given key or a null
    978      * value is explicitly associated with the key.
    979      *
    980      * @param key a String, or null
    981      * @return a char[] value, or null
    982      */
    983     @Override
    984     public char[] getCharArray(String key) {
    985         return super.getCharArray(key);
    986     }
    987 
    988     /**
    989      * Returns the value associated with the given key, or null if
    990      * no mapping of the desired type exists for the given key or a null
    991      * value is explicitly associated with the key.
    992      *
    993      * @param key a String, or null
    994      * @return a float[] value, or null
    995      */
    996     @Override
    997     public float[] getFloatArray(String key) {
    998         return super.getFloatArray(key);
    999     }
   1000 
   1001     /**
   1002      * Returns the value associated with the given key, or null if
   1003      * no mapping of the desired type exists for the given key or a null
   1004      * value is explicitly associated with the key.
   1005      *
   1006      * @param key a String, or null
   1007      * @return a CharSequence[] value, or null
   1008      */
   1009     @Override
   1010     public CharSequence[] getCharSequenceArray(String key) {
   1011         return super.getCharSequenceArray(key);
   1012     }
   1013 
   1014     /**
   1015      * Returns the value associated with the given key, or null if
   1016      * no mapping of the desired type exists for the given key or a null
   1017      * value is explicitly associated with the key.
   1018      *
   1019      * @param key a String, or null
   1020      * @return an IBinder value, or null
   1021      */
   1022     public IBinder getBinder(String key) {
   1023         unparcel();
   1024         Object o = mMap.get(key);
   1025         if (o == null) {
   1026             return null;
   1027         }
   1028         try {
   1029             return (IBinder) o;
   1030         } catch (ClassCastException e) {
   1031             typeWarning(key, o, "IBinder", e);
   1032             return null;
   1033         }
   1034     }
   1035 
   1036     /**
   1037      * Returns the value associated with the given key, or null if
   1038      * no mapping of the desired type exists for the given key or a null
   1039      * value is explicitly associated with the key.
   1040      *
   1041      * @param key a String, or null
   1042      * @return an IBinder value, or null
   1043      *
   1044      * @deprecated
   1045      * @hide This is the old name of the function.
   1046      */
   1047     @Deprecated
   1048     public IBinder getIBinder(String key) {
   1049         unparcel();
   1050         Object o = mMap.get(key);
   1051         if (o == null) {
   1052             return null;
   1053         }
   1054         try {
   1055             return (IBinder) o;
   1056         } catch (ClassCastException e) {
   1057             typeWarning(key, o, "IBinder", e);
   1058             return null;
   1059         }
   1060     }
   1061 
   1062     public static final Parcelable.Creator<Bundle> CREATOR =
   1063         new Parcelable.Creator<Bundle>() {
   1064         @Override
   1065         public Bundle createFromParcel(Parcel in) {
   1066             return in.readBundle();
   1067         }
   1068 
   1069         @Override
   1070         public Bundle[] newArray(int size) {
   1071             return new Bundle[size];
   1072         }
   1073     };
   1074 
   1075     /**
   1076      * Report the nature of this Parcelable's contents
   1077      */
   1078     @Override
   1079     public int describeContents() {
   1080         int mask = 0;
   1081         if (hasFileDescriptors()) {
   1082             mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
   1083         }
   1084         return mask;
   1085     }
   1086 
   1087     /**
   1088      * Writes the Bundle contents to a Parcel, typically in order for
   1089      * it to be passed through an IBinder connection.
   1090      * @param parcel The parcel to copy this bundle to.
   1091      */
   1092     @Override
   1093     public void writeToParcel(Parcel parcel, int flags) {
   1094         final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
   1095         try {
   1096             super.writeToParcelInner(parcel, flags);
   1097         } finally {
   1098             parcel.restoreAllowFds(oldAllowFds);
   1099         }
   1100     }
   1101 
   1102     /**
   1103      * Reads the Parcel contents into this Bundle, typically in order for
   1104      * it to be passed through an IBinder connection.
   1105      * @param parcel The parcel to overwrite this bundle from.
   1106      */
   1107     public void readFromParcel(Parcel parcel) {
   1108         super.readFromParcelInner(parcel);
   1109         mHasFds = mParcelledData.hasFileDescriptors();
   1110         mFdsKnown = true;
   1111     }
   1112 
   1113     @Override
   1114     public synchronized String toString() {
   1115         if (mParcelledData != null) {
   1116             if (mParcelledData == EMPTY_PARCEL) {
   1117                 return "Bundle[EMPTY_PARCEL]";
   1118             } else {
   1119                 return "Bundle[mParcelledData.dataSize=" +
   1120                         mParcelledData.dataSize() + "]";
   1121             }
   1122         }
   1123         return "Bundle[" + mMap.toString() + "]";
   1124     }
   1125 
   1126 }
   1127