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