OSDN Git Service

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