Bundle.java revision a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9d
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
17package android.os;
18
19import android.annotation.Nullable;
20import android.util.ArrayMap;
21import android.util.Size;
22import android.util.SizeF;
23import android.util.SparseArray;
24
25import java.io.Serializable;
26import java.util.ArrayList;
27import java.util.List;
28
29/**
30 * A mapping from String values to various Parcelable types.
31 *
32 */
33public 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     * Filter values in Bundle to only basic types.
256     * @hide
257     */
258    public void filterValues() {
259        unparcel();
260        if (mMap != null) {
261            for (int i = mMap.size() - 1; i >= 0; i--) {
262                Object value = mMap.valueAt(i);
263                if (PersistableBundle.isValidType(value)) {
264                    continue;
265                }
266                if (value instanceof Bundle) {
267                    ((Bundle)value).filterValues();
268                }
269                if (value.getClass().getName().startsWith("android.")) {
270                    continue;
271                }
272                mMap.removeAt(i);
273            }
274        }
275    }
276
277    /**
278     * Inserts a byte value into the mapping of this Bundle, replacing
279     * any existing value for the given key.
280     *
281     * @param key a String, or null
282     * @param value a byte
283     */
284    @Override
285    public void putByte(@Nullable String key, byte value) {
286        super.putByte(key, value);
287    }
288
289    /**
290     * Inserts a char value into the mapping of this Bundle, replacing
291     * any existing value for the given key.
292     *
293     * @param key a String, or null
294     * @param value a char
295     */
296    @Override
297    public void putChar(@Nullable String key, char value) {
298        super.putChar(key, value);
299    }
300
301    /**
302     * Inserts a short value into the mapping of this Bundle, replacing
303     * any existing value for the given key.
304     *
305     * @param key a String, or null
306     * @param value a short
307     */
308    @Override
309    public void putShort(@Nullable String key, short value) {
310        super.putShort(key, value);
311    }
312
313    /**
314     * Inserts a float value into the mapping of this Bundle, replacing
315     * any existing value for the given key.
316     *
317     * @param key a String, or null
318     * @param value a float
319     */
320    @Override
321    public void putFloat(@Nullable String key, float value) {
322        super.putFloat(key, value);
323    }
324
325    /**
326     * Inserts a CharSequence value into the mapping of this Bundle, replacing
327     * any existing value for the given key.  Either key or value may be null.
328     *
329     * @param key a String, or null
330     * @param value a CharSequence, or null
331     */
332    @Override
333    public void putCharSequence(@Nullable String key, @Nullable CharSequence value) {
334        super.putCharSequence(key, value);
335    }
336
337    /**
338     * Inserts a Parcelable value into the mapping of this Bundle, replacing
339     * any existing value for the given key.  Either key or value may be null.
340     *
341     * @param key a String, or null
342     * @param value a Parcelable object, or null
343     */
344    public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
345        unparcel();
346        mMap.put(key, value);
347        mFdsKnown = false;
348    }
349
350    /**
351     * Inserts a Size value into the mapping of this Bundle, replacing
352     * any existing value for the given key.  Either key or value may be null.
353     *
354     * @param key a String, or null
355     * @param value a Size object, or null
356     */
357    public void putSize(@Nullable String key, @Nullable Size value) {
358        unparcel();
359        mMap.put(key, value);
360    }
361
362    /**
363     * Inserts a SizeF value into the mapping of this Bundle, replacing
364     * any existing value for the given key.  Either key or value may be null.
365     *
366     * @param key a String, or null
367     * @param value a SizeF object, or null
368     */
369    public void putSizeF(@Nullable String key, @Nullable SizeF value) {
370        unparcel();
371        mMap.put(key, value);
372    }
373
374    /**
375     * Inserts an array of Parcelable values into the mapping of this Bundle,
376     * replacing any existing value for the given key.  Either key or value may
377     * be null.
378     *
379     * @param key a String, or null
380     * @param value an array of Parcelable objects, or null
381     */
382    public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
383        unparcel();
384        mMap.put(key, value);
385        mFdsKnown = false;
386    }
387
388    /**
389     * Inserts a List of Parcelable values into the mapping of this Bundle,
390     * replacing any existing value for the given key.  Either key or value may
391     * be null.
392     *
393     * @param key a String, or null
394     * @param value an ArrayList of Parcelable objects, or null
395     */
396    public void putParcelableArrayList(@Nullable String key,
397            @Nullable ArrayList<? extends Parcelable> value) {
398        unparcel();
399        mMap.put(key, value);
400        mFdsKnown = false;
401    }
402
403    /** {@hide} */
404    public void putParcelableList(String key, List<? extends Parcelable> value) {
405        unparcel();
406        mMap.put(key, value);
407        mFdsKnown = false;
408    }
409
410    /**
411     * Inserts a SparceArray of Parcelable values into the mapping of this
412     * Bundle, replacing any existing value for the given key.  Either key
413     * or value may be null.
414     *
415     * @param key a String, or null
416     * @param value a SparseArray of Parcelable objects, or null
417     */
418    public void putSparseParcelableArray(@Nullable String key,
419            @Nullable SparseArray<? extends Parcelable> value) {
420        unparcel();
421        mMap.put(key, value);
422        mFdsKnown = false;
423    }
424
425    /**
426     * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
427     * any existing value for the given key.  Either key or value may be null.
428     *
429     * @param key a String, or null
430     * @param value an ArrayList<Integer> object, or null
431     */
432    @Override
433    public void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
434        super.putIntegerArrayList(key, value);
435    }
436
437    /**
438     * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
439     * any existing value for the given key.  Either key or value may be null.
440     *
441     * @param key a String, or null
442     * @param value an ArrayList<String> object, or null
443     */
444    @Override
445    public void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
446        super.putStringArrayList(key, value);
447    }
448
449    /**
450     * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
451     * any existing value for the given key.  Either key or value may be null.
452     *
453     * @param key a String, or null
454     * @param value an ArrayList<CharSequence> object, or null
455     */
456    @Override
457    public void putCharSequenceArrayList(@Nullable String key,
458            @Nullable ArrayList<CharSequence> value) {
459        super.putCharSequenceArrayList(key, value);
460    }
461
462    /**
463     * Inserts a Serializable 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 Serializable object, or null
468     */
469    @Override
470    public void putSerializable(@Nullable String key, @Nullable Serializable value) {
471        super.putSerializable(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(@Nullable String key, @Nullable 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(@Nullable String key, @Nullable 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(@Nullable String key, @Nullable 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(@Nullable String key, @Nullable 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(@Nullable String key, @Nullable 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(@Nullable String key, @Nullable 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(@Nullable String key, @Nullable 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(@Nullable String key, @Nullable IBinder value) {
577        unparcel();
578        mMap.put(key, value);
579    }
580
581    /**
582     * Returns the value associated with the given key, or (byte) 0 if
583     * no mapping of the desired type exists for the given key.
584     *
585     * @param key a String
586     * @return a byte value
587     */
588    @Override
589    public byte getByte(String key) {
590        return super.getByte(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 byte value
600     */
601    @Override
602    public Byte getByte(String key, byte defaultValue) {
603        return super.getByte(key, defaultValue);
604    }
605
606    /**
607     * Returns the value associated with the given key, or (char) 0 if
608     * no mapping of the desired type exists for the given key.
609     *
610     * @param key a String
611     * @return a char value
612     */
613    @Override
614    public char getChar(String key) {
615        return super.getChar(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 char value
625     */
626    @Override
627    public char getChar(String key, char defaultValue) {
628        return super.getChar(key, defaultValue);
629    }
630
631    /**
632     * Returns the value associated with the given key, or (short) 0 if
633     * no mapping of the desired type exists for the given key.
634     *
635     * @param key a String
636     * @return a short value
637     */
638    @Override
639    public short getShort(String key) {
640        return super.getShort(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 short value
650     */
651    @Override
652    public short getShort(String key, short defaultValue) {
653        return super.getShort(key, defaultValue);
654    }
655
656    /**
657     * Returns the value associated with the given key, or 0.0f if
658     * no mapping of the desired type exists for the given key.
659     *
660     * @param key a String
661     * @return a float value
662     */
663    @Override
664    public float getFloat(String key) {
665        return super.getFloat(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 float value
675     */
676    @Override
677    public float getFloat(String key, float defaultValue) {
678        return super.getFloat(key, defaultValue);
679    }
680
681    /**
682     * Returns the value associated with the given key, or null if
683     * no mapping of the desired type exists for the given key or a null
684     * value is explicitly associated with the key.
685     *
686     * @param key a String, or null
687     * @return a CharSequence value, or null
688     */
689    @Override
690    @Nullable
691    public CharSequence getCharSequence(@Nullable String key) {
692        return super.getCharSequence(key);
693    }
694
695    /**
696     * Returns the value associated with the given key, or defaultValue if
697     * no mapping of the desired type exists for the given key or if a null
698     * value is explicitly associatd with the given key.
699     *
700     * @param key a String, or null
701     * @param defaultValue Value to return if key does not exist or if a null
702     *     value is associated with the given key.
703     * @return the CharSequence value associated with the given key, or defaultValue
704     *     if no valid CharSequence object is currently mapped to that key.
705     */
706    @Override
707    public CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) {
708        return super.getCharSequence(key, defaultValue);
709    }
710
711    /**
712     * Returns the value associated with the given key, or null if
713     * no mapping of the desired type exists for the given key or a null
714     * value is explicitly associated with the key.
715     *
716     * @param key a String, or null
717     * @return a Size value, or null
718     */
719    @Nullable
720    public Size getSize(@Nullable String key) {
721        unparcel();
722        final Object o = mMap.get(key);
723        try {
724            return (Size) o;
725        } catch (ClassCastException e) {
726            typeWarning(key, o, "Size", e);
727            return null;
728        }
729    }
730
731    /**
732     * Returns the value associated with the given key, or null if
733     * no mapping of the desired type exists for the given key or a null
734     * value is explicitly associated with the key.
735     *
736     * @param key a String, or null
737     * @return a Size value, or null
738     */
739    @Nullable
740    public SizeF getSizeF(@Nullable String key) {
741        unparcel();
742        final Object o = mMap.get(key);
743        try {
744            return (SizeF) o;
745        } catch (ClassCastException e) {
746            typeWarning(key, o, "SizeF", e);
747            return null;
748        }
749    }
750
751    /**
752     * Returns the value associated with the given key, or null if
753     * no mapping of the desired type exists for the given key or a null
754     * value is explicitly associated with the key.
755     *
756     * @param key a String, or null
757     * @return a Bundle value, or null
758     */
759    @Nullable
760    public Bundle getBundle(@Nullable String key) {
761        unparcel();
762        Object o = mMap.get(key);
763        if (o == null) {
764            return null;
765        }
766        try {
767            return (Bundle) o;
768        } catch (ClassCastException e) {
769            typeWarning(key, o, "Bundle", e);
770            return null;
771        }
772    }
773
774    /**
775     * Returns the value associated with the given key, or null if
776     * no mapping of the desired type exists for the given key or a null
777     * value is explicitly associated with the key.
778     *
779     * @param key a String, or null
780     * @return a Parcelable value, or null
781     */
782    @Nullable
783    public <T extends Parcelable> T getParcelable(@Nullable String key) {
784        unparcel();
785        Object o = mMap.get(key);
786        if (o == null) {
787            return null;
788        }
789        try {
790            return (T) o;
791        } catch (ClassCastException e) {
792            typeWarning(key, o, "Parcelable", e);
793            return null;
794        }
795    }
796
797    /**
798     * Returns the value associated with the given key, or null if
799     * no mapping of the desired type exists for the given key or a null
800     * value is explicitly associated with the key.
801     *
802     * @param key a String, or null
803     * @return a Parcelable[] value, or null
804     */
805    @Nullable
806    public Parcelable[] getParcelableArray(@Nullable String key) {
807        unparcel();
808        Object o = mMap.get(key);
809        if (o == null) {
810            return null;
811        }
812        try {
813            return (Parcelable[]) o;
814        } catch (ClassCastException e) {
815            typeWarning(key, o, "Parcelable[]", e);
816            return null;
817        }
818    }
819
820    /**
821     * Returns the value associated with the given key, or null if
822     * no mapping of the desired type exists for the given key or a null
823     * value is explicitly associated with the key.
824     *
825     * @param key a String, or null
826     * @return an ArrayList<T> value, or null
827     */
828    @Nullable
829    public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) {
830        unparcel();
831        Object o = mMap.get(key);
832        if (o == null) {
833            return null;
834        }
835        try {
836            return (ArrayList<T>) o;
837        } catch (ClassCastException e) {
838            typeWarning(key, o, "ArrayList", e);
839            return null;
840        }
841    }
842
843    /**
844     * Returns the value associated with the given key, or null if
845     * no mapping of the desired type exists for the given key or a null
846     * value is explicitly associated with the key.
847     *
848     * @param key a String, or null
849     *
850     * @return a SparseArray of T values, or null
851     */
852    @Nullable
853    public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(@Nullable String key) {
854        unparcel();
855        Object o = mMap.get(key);
856        if (o == null) {
857            return null;
858        }
859        try {
860            return (SparseArray<T>) o;
861        } catch (ClassCastException e) {
862            typeWarning(key, o, "SparseArray", e);
863            return null;
864        }
865    }
866
867    /**
868     * Returns the value associated with the given key, or null if
869     * no mapping of the desired type exists for the given key or a null
870     * value is explicitly associated with the key.
871     *
872     * @param key a String, or null
873     * @return a Serializable value, or null
874     */
875    @Override
876    @Nullable
877    public Serializable getSerializable(@Nullable String key) {
878        return super.getSerializable(key);
879    }
880
881    /**
882     * Returns the value associated with the given key, or null if
883     * no mapping of the desired type exists for the given key or a null
884     * value is explicitly associated with the key.
885     *
886     * @param key a String, or null
887     * @return an ArrayList<String> value, or null
888     */
889    @Override
890    @Nullable
891    public ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
892        return super.getIntegerArrayList(key);
893    }
894
895    /**
896     * Returns the value associated with the given key, or null if
897     * no mapping of the desired type exists for the given key or a null
898     * value is explicitly associated with the key.
899     *
900     * @param key a String, or null
901     * @return an ArrayList<String> value, or null
902     */
903    @Override
904    @Nullable
905    public ArrayList<String> getStringArrayList(@Nullable String key) {
906        return super.getStringArrayList(key);
907    }
908
909    /**
910     * Returns the value associated with the given key, or null if
911     * no mapping of the desired type exists for the given key or a null
912     * value is explicitly associated with the key.
913     *
914     * @param key a String, or null
915     * @return an ArrayList<CharSequence> value, or null
916     */
917    @Override
918    @Nullable
919    public ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) {
920        return super.getCharSequenceArrayList(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 a byte[] value, or null
930     */
931    @Override
932    @Nullable
933    public byte[] getByteArray(@Nullable String key) {
934        return super.getByteArray(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 a short[] value, or null
944     */
945    @Override
946    @Nullable
947    public short[] getShortArray(@Nullable String key) {
948        return super.getShortArray(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 a char[] value, or null
958     */
959    @Override
960    @Nullable
961    public char[] getCharArray(@Nullable String key) {
962        return super.getCharArray(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 a float[] value, or null
972     */
973    @Override
974    @Nullable
975    public float[] getFloatArray(@Nullable String key) {
976        return super.getFloatArray(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 CharSequence[] value, or null
986     */
987    @Override
988    @Nullable
989    public CharSequence[] getCharSequenceArray(@Nullable String key) {
990        return super.getCharSequenceArray(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 an IBinder value, or null
1000     */
1001    @Nullable
1002    public IBinder getBinder(@Nullable String key) {
1003        unparcel();
1004        Object o = mMap.get(key);
1005        if (o == null) {
1006            return null;
1007        }
1008        try {
1009            return (IBinder) o;
1010        } catch (ClassCastException e) {
1011            typeWarning(key, o, "IBinder", e);
1012            return null;
1013        }
1014    }
1015
1016    /**
1017     * Returns the value associated with the given key, or null if
1018     * no mapping of the desired type exists for the given key or a null
1019     * value is explicitly associated with the key.
1020     *
1021     * @param key a String, or null
1022     * @return an IBinder value, or null
1023     *
1024     * @deprecated
1025     * @hide This is the old name of the function.
1026     */
1027    @Deprecated
1028    @Nullable
1029    public IBinder getIBinder(@Nullable String key) {
1030        unparcel();
1031        Object o = mMap.get(key);
1032        if (o == null) {
1033            return null;
1034        }
1035        try {
1036            return (IBinder) o;
1037        } catch (ClassCastException e) {
1038            typeWarning(key, o, "IBinder", e);
1039            return null;
1040        }
1041    }
1042
1043    public static final Parcelable.Creator<Bundle> CREATOR =
1044        new Parcelable.Creator<Bundle>() {
1045        @Override
1046        public Bundle createFromParcel(Parcel in) {
1047            return in.readBundle();
1048        }
1049
1050        @Override
1051        public Bundle[] newArray(int size) {
1052            return new Bundle[size];
1053        }
1054    };
1055
1056    /**
1057     * Report the nature of this Parcelable's contents
1058     */
1059    @Override
1060    public int describeContents() {
1061        int mask = 0;
1062        if (hasFileDescriptors()) {
1063            mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
1064        }
1065        return mask;
1066    }
1067
1068    /**
1069     * Writes the Bundle contents to a Parcel, typically in order for
1070     * it to be passed through an IBinder connection.
1071     * @param parcel The parcel to copy this bundle to.
1072     */
1073    @Override
1074    public void writeToParcel(Parcel parcel, int flags) {
1075        final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
1076        try {
1077            super.writeToParcelInner(parcel, flags);
1078        } finally {
1079            parcel.restoreAllowFds(oldAllowFds);
1080        }
1081    }
1082
1083    /**
1084     * Reads the Parcel contents into this Bundle, typically in order for
1085     * it to be passed through an IBinder connection.
1086     * @param parcel The parcel to overwrite this bundle from.
1087     */
1088    public void readFromParcel(Parcel parcel) {
1089        super.readFromParcelInner(parcel);
1090        mHasFds = mParcelledData.hasFileDescriptors();
1091        mFdsKnown = true;
1092    }
1093
1094    @Override
1095    public synchronized String toString() {
1096        if (mParcelledData != null) {
1097            if (mParcelledData == EMPTY_PARCEL) {
1098                return "Bundle[EMPTY_PARCEL]";
1099            } else {
1100                return "Bundle[mParcelledData.dataSize=" +
1101                        mParcelledData.dataSize() + "]";
1102            }
1103        }
1104        return "Bundle[" + mMap.toString() + "]";
1105    }
1106
1107}
1108