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