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 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(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, or null
272     */
273    @Override
274    public void putChar(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(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(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(String key, 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(String key, 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(String key, 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(String key, 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(String key, 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(String key,
374            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(String key,
396            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(String key, 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(String key, 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(String key, ArrayList<CharSequence> value) {
435        super.putCharSequenceArrayList(key, value);
436    }
437
438    /**
439     * Inserts a Serializable 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 a Serializable object, or null
444     */
445    @Override
446    public void putSerializable(String key, Serializable value) {
447        super.putSerializable(key, value);
448    }
449
450    /**
451     * Inserts a byte array 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 byte array object, or null
456     */
457    @Override
458    public void putByteArray(String key, byte[] value) {
459        super.putByteArray(key, value);
460    }
461
462    /**
463     * Inserts a short 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 short array object, or null
468     */
469    @Override
470    public void putShortArray(String key, short[] value) {
471        super.putShortArray(key, value);
472    }
473
474    /**
475     * Inserts a char 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 char array object, or null
480     */
481    @Override
482    public void putCharArray(String key, char[] value) {
483        super.putCharArray(key, value);
484    }
485
486    /**
487     * Inserts a float 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 float array object, or null
492     */
493    @Override
494    public void putFloatArray(String key, float[] value) {
495        super.putFloatArray(key, value);
496    }
497
498    /**
499     * Inserts a CharSequence 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 CharSequence array object, or null
504     */
505    @Override
506    public void putCharSequenceArray(String key, CharSequence[] value) {
507        super.putCharSequenceArray(key, value);
508    }
509
510    /**
511     * Inserts a Bundle 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 Bundle object, or null
516     */
517    public void putBundle(String key, Bundle value) {
518        unparcel();
519        mMap.put(key, value);
520    }
521
522    /**
523     * Inserts an {@link IBinder} 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     * <p class="note">You should be very careful when using this function.  In many
527     * places where Bundles are used (such as inside of Intent objects), the Bundle
528     * can live longer inside of another process than the process that had originally
529     * created it.  In that case, the IBinder you supply here will become invalid
530     * when your process goes away, and no longer usable, even if a new process is
531     * created for you later on.</p>
532     *
533     * @param key a String, or null
534     * @param value an IBinder object, or null
535     */
536    public void putBinder(String key, IBinder value) {
537        unparcel();
538        mMap.put(key, value);
539    }
540
541    /**
542     * Inserts an IBinder value into the mapping of this Bundle, replacing
543     * any existing value for the given key.  Either key or value may be null.
544     *
545     * @param key a String, or null
546     * @param value an IBinder object, or null
547     *
548     * @deprecated
549     * @hide This is the old name of the function.
550     */
551    @Deprecated
552    public void putIBinder(String key, IBinder value) {
553        unparcel();
554        mMap.put(key, value);
555    }
556
557    /**
558     * Returns the value associated with the given key, or (byte) 0 if
559     * no mapping of the desired type exists for the given key.
560     *
561     * @param key a String
562     * @return a byte value
563     */
564    @Override
565    public byte getByte(String key) {
566        return super.getByte(key);
567    }
568
569    /**
570     * Returns the value associated with the given key, or defaultValue if
571     * no mapping of the desired type exists for the given key.
572     *
573     * @param key a String
574     * @param defaultValue Value to return if key does not exist
575     * @return a byte value
576     */
577    @Override
578    public Byte getByte(String key, byte defaultValue) {
579        return super.getByte(key, defaultValue);
580    }
581
582    /**
583     * Returns the value associated with the given key, or (char) 0 if
584     * no mapping of the desired type exists for the given key.
585     *
586     * @param key a String
587     * @return a char value
588     */
589    @Override
590    public char getChar(String key) {
591        return super.getChar(key);
592    }
593
594    /**
595     * Returns the value associated with the given key, or defaultValue if
596     * no mapping of the desired type exists for the given key.
597     *
598     * @param key a String
599     * @param defaultValue Value to return if key does not exist
600     * @return a char value
601     */
602    @Override
603    public char getChar(String key, char defaultValue) {
604        return super.getChar(key, defaultValue);
605    }
606
607    /**
608     * Returns the value associated with the given key, or (short) 0 if
609     * no mapping of the desired type exists for the given key.
610     *
611     * @param key a String
612     * @return a short value
613     */
614    @Override
615    public short getShort(String key) {
616        return super.getShort(key);
617    }
618
619    /**
620     * Returns the value associated with the given key, or defaultValue if
621     * no mapping of the desired type exists for the given key.
622     *
623     * @param key a String
624     * @param defaultValue Value to return if key does not exist
625     * @return a short value
626     */
627    @Override
628    public short getShort(String key, short defaultValue) {
629        return super.getShort(key, defaultValue);
630    }
631
632    /**
633     * Returns the value associated with the given key, or 0.0f if
634     * no mapping of the desired type exists for the given key.
635     *
636     * @param key a String
637     * @return a float value
638     */
639    @Override
640    public float getFloat(String key) {
641        return super.getFloat(key);
642    }
643
644    /**
645     * Returns the value associated with the given key, or defaultValue if
646     * no mapping of the desired type exists for the given key.
647     *
648     * @param key a String
649     * @param defaultValue Value to return if key does not exist
650     * @return a float value
651     */
652    @Override
653    public float getFloat(String key, float defaultValue) {
654        return super.getFloat(key, defaultValue);
655    }
656
657    /**
658     * Returns the value associated with the given key, or null if
659     * no mapping of the desired type exists for the given key or a null
660     * value is explicitly associated with the key.
661     *
662     * @param key a String, or null
663     * @return a CharSequence value, or null
664     */
665    @Override
666    public CharSequence getCharSequence(String key) {
667        return super.getCharSequence(key);
668    }
669
670    /**
671     * Returns the value associated with the given key, or defaultValue if
672     * no mapping of the desired type exists for the given key or if a null
673     * value is explicitly associatd with the given key.
674     *
675     * @param key a String, or null
676     * @param defaultValue Value to return if key does not exist or if a null
677     *     value is associated with the given key.
678     * @return the CharSequence value associated with the given key, or defaultValue
679     *     if no valid CharSequence object is currently mapped to that key.
680     */
681    @Override
682    public CharSequence getCharSequence(String key, CharSequence defaultValue) {
683        return super.getCharSequence(key, defaultValue);
684    }
685
686    /**
687     * Returns the value associated with the given key, or null if
688     * no mapping of the desired type exists for the given key or a null
689     * value is explicitly associated with the key.
690     *
691     * @param key a String, or null
692     * @return a Size value, or null
693     */
694    public Size getSize(String key) {
695        unparcel();
696        final Object o = mMap.get(key);
697        try {
698            return (Size) o;
699        } catch (ClassCastException e) {
700            typeWarning(key, o, "Size", e);
701            return null;
702        }
703    }
704
705    /**
706     * Returns the value associated with the given key, or null if
707     * no mapping of the desired type exists for the given key or a null
708     * value is explicitly associated with the key.
709     *
710     * @param key a String, or null
711     * @return a Size value, or null
712     */
713    public SizeF getSizeF(String key) {
714        unparcel();
715        final Object o = mMap.get(key);
716        try {
717            return (SizeF) o;
718        } catch (ClassCastException e) {
719            typeWarning(key, o, "SizeF", e);
720            return null;
721        }
722    }
723
724    /**
725     * Returns the value associated with the given key, or null if
726     * no mapping of the desired type exists for the given key or a null
727     * value is explicitly associated with the key.
728     *
729     * @param key a String, or null
730     * @return a Bundle value, or null
731     */
732    public Bundle getBundle(String key) {
733        unparcel();
734        Object o = mMap.get(key);
735        if (o == null) {
736            return null;
737        }
738        try {
739            return (Bundle) o;
740        } catch (ClassCastException e) {
741            typeWarning(key, o, "Bundle", e);
742            return null;
743        }
744    }
745
746    /**
747     * Returns the value associated with the given key, or null if
748     * no mapping of the desired type exists for the given key or a null
749     * value is explicitly associated with the key.
750     *
751     * @param key a String, or null
752     * @return a Parcelable value, or null
753     */
754    public <T extends Parcelable> T getParcelable(String key) {
755        unparcel();
756        Object o = mMap.get(key);
757        if (o == null) {
758            return null;
759        }
760        try {
761            return (T) o;
762        } catch (ClassCastException e) {
763            typeWarning(key, o, "Parcelable", e);
764            return null;
765        }
766    }
767
768    /**
769     * Returns the value associated with the given key, or null if
770     * no mapping of the desired type exists for the given key or a null
771     * value is explicitly associated with the key.
772     *
773     * @param key a String, or null
774     * @return a Parcelable[] value, or null
775     */
776    public Parcelable[] getParcelableArray(String key) {
777        unparcel();
778        Object o = mMap.get(key);
779        if (o == null) {
780            return null;
781        }
782        try {
783            return (Parcelable[]) o;
784        } catch (ClassCastException e) {
785            typeWarning(key, o, "Parcelable[]", e);
786            return null;
787        }
788    }
789
790    /**
791     * Returns the value associated with the given key, or null if
792     * no mapping of the desired type exists for the given key or a null
793     * value is explicitly associated with the key.
794     *
795     * @param key a String, or null
796     * @return an ArrayList<T> value, or null
797     */
798    public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String key) {
799        unparcel();
800        Object o = mMap.get(key);
801        if (o == null) {
802            return null;
803        }
804        try {
805            return (ArrayList<T>) o;
806        } catch (ClassCastException e) {
807            typeWarning(key, o, "ArrayList", e);
808            return null;
809        }
810    }
811
812    /**
813     * Returns the value associated with the given key, or null if
814     * no mapping of the desired type exists for the given key or a null
815     * value is explicitly associated with the key.
816     *
817     * @param key a String, or null
818     *
819     * @return a SparseArray of T values, or null
820     */
821    public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(String key) {
822        unparcel();
823        Object o = mMap.get(key);
824        if (o == null) {
825            return null;
826        }
827        try {
828            return (SparseArray<T>) o;
829        } catch (ClassCastException e) {
830            typeWarning(key, o, "SparseArray", e);
831            return null;
832        }
833    }
834
835    /**
836     * Returns the value associated with the given key, or null if
837     * no mapping of the desired type exists for the given key or a null
838     * value is explicitly associated with the key.
839     *
840     * @param key a String, or null
841     * @return a Serializable value, or null
842     */
843    @Override
844    public Serializable getSerializable(String key) {
845        return super.getSerializable(key);
846    }
847
848    /**
849     * Returns the value associated with the given key, or null if
850     * no mapping of the desired type exists for the given key or a null
851     * value is explicitly associated with the key.
852     *
853     * @param key a String, or null
854     * @return an ArrayList<String> value, or null
855     */
856    @Override
857    public ArrayList<Integer> getIntegerArrayList(String key) {
858        return super.getIntegerArrayList(key);
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     * @return an ArrayList<String> value, or null
868     */
869    @Override
870    public ArrayList<String> getStringArrayList(String key) {
871        return super.getStringArrayList(key);
872    }
873
874    /**
875     * Returns the value associated with the given key, or null if
876     * no mapping of the desired type exists for the given key or a null
877     * value is explicitly associated with the key.
878     *
879     * @param key a String, or null
880     * @return an ArrayList<CharSequence> value, or null
881     */
882    @Override
883    public ArrayList<CharSequence> getCharSequenceArrayList(String key) {
884        return super.getCharSequenceArrayList(key);
885    }
886
887    /**
888     * Returns the value associated with the given key, or null if
889     * no mapping of the desired type exists for the given key or a null
890     * value is explicitly associated with the key.
891     *
892     * @param key a String, or null
893     * @return a byte[] value, or null
894     */
895    @Override
896    public byte[] getByteArray(String key) {
897        return super.getByteArray(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 short[] value, or null
907     */
908    @Override
909    public short[] getShortArray(String key) {
910        return super.getShortArray(key);
911    }
912
913    /**
914     * Returns the value associated with the given key, or null if
915     * no mapping of the desired type exists for the given key or a null
916     * value is explicitly associated with the key.
917     *
918     * @param key a String, or null
919     * @return a char[] value, or null
920     */
921    @Override
922    public char[] getCharArray(String key) {
923        return super.getCharArray(key);
924    }
925
926    /**
927     * Returns the value associated with the given key, or null if
928     * no mapping of the desired type exists for the given key or a null
929     * value is explicitly associated with the key.
930     *
931     * @param key a String, or null
932     * @return a float[] value, or null
933     */
934    @Override
935    public float[] getFloatArray(String key) {
936        return super.getFloatArray(key);
937    }
938
939    /**
940     * Returns the value associated with the given key, or null if
941     * no mapping of the desired type exists for the given key or a null
942     * value is explicitly associated with the key.
943     *
944     * @param key a String, or null
945     * @return a CharSequence[] value, or null
946     */
947    @Override
948    public CharSequence[] getCharSequenceArray(String key) {
949        return super.getCharSequenceArray(key);
950    }
951
952    /**
953     * Returns the value associated with the given key, or null if
954     * no mapping of the desired type exists for the given key or a null
955     * value is explicitly associated with the key.
956     *
957     * @param key a String, or null
958     * @return an IBinder value, or null
959     */
960    public IBinder getBinder(String key) {
961        unparcel();
962        Object o = mMap.get(key);
963        if (o == null) {
964            return null;
965        }
966        try {
967            return (IBinder) o;
968        } catch (ClassCastException e) {
969            typeWarning(key, o, "IBinder", e);
970            return null;
971        }
972    }
973
974    /**
975     * Returns the value associated with the given key, or null if
976     * no mapping of the desired type exists for the given key or a null
977     * value is explicitly associated with the key.
978     *
979     * @param key a String, or null
980     * @return an IBinder value, or null
981     *
982     * @deprecated
983     * @hide This is the old name of the function.
984     */
985    @Deprecated
986    public IBinder getIBinder(String key) {
987        unparcel();
988        Object o = mMap.get(key);
989        if (o == null) {
990            return null;
991        }
992        try {
993            return (IBinder) o;
994        } catch (ClassCastException e) {
995            typeWarning(key, o, "IBinder", e);
996            return null;
997        }
998    }
999
1000    public static final Parcelable.Creator<Bundle> CREATOR =
1001        new Parcelable.Creator<Bundle>() {
1002        @Override
1003        public Bundle createFromParcel(Parcel in) {
1004            return in.readBundle();
1005        }
1006
1007        @Override
1008        public Bundle[] newArray(int size) {
1009            return new Bundle[size];
1010        }
1011    };
1012
1013    /**
1014     * Report the nature of this Parcelable's contents
1015     */
1016    @Override
1017    public int describeContents() {
1018        int mask = 0;
1019        if (hasFileDescriptors()) {
1020            mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
1021        }
1022        return mask;
1023    }
1024
1025    /**
1026     * Writes the Bundle contents to a Parcel, typically in order for
1027     * it to be passed through an IBinder connection.
1028     * @param parcel The parcel to copy this bundle to.
1029     */
1030    @Override
1031    public void writeToParcel(Parcel parcel, int flags) {
1032        final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
1033        try {
1034            super.writeToParcelInner(parcel, flags);
1035        } finally {
1036            parcel.restoreAllowFds(oldAllowFds);
1037        }
1038    }
1039
1040    /**
1041     * Reads the Parcel contents into this Bundle, typically in order for
1042     * it to be passed through an IBinder connection.
1043     * @param parcel The parcel to overwrite this bundle from.
1044     */
1045    public void readFromParcel(Parcel parcel) {
1046        super.readFromParcelInner(parcel);
1047        mHasFds = mParcelledData.hasFileDescriptors();
1048        mFdsKnown = true;
1049    }
1050
1051    @Override
1052    public synchronized String toString() {
1053        if (mParcelledData != null) {
1054            if (mParcelledData == EMPTY_PARCEL) {
1055                return "Bundle[EMPTY_PARCEL]";
1056            } else {
1057                return "Bundle[mParcelledData.dataSize=" +
1058                        mParcelledData.dataSize() + "]";
1059            }
1060        }
1061        return "Bundle[" + mMap.toString() + "]";
1062    }
1063
1064}
1065