Bundle.java revision 5ef33984d0cc50bf4654b0d8e9557ac34d44fddd
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.util.ArrayMap;
20import android.util.Size;
21import android.util.SizeF;
22import android.util.SparseArray;
23
24import java.io.Serializable;
25import java.util.ArrayList;
26import java.util.List;
27import java.util.Set;
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     * 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