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.util.ArrayMap;
20 import android.util.Size;
21 import android.util.SizeF;
22 import android.util.SparseArray;
23 
24 import java.io.Serializable;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Set;
28 
29 /**
30  * A mapping from String values to various Parcelable types.
31  *
32  */
33 public 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      */
Bundle()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      */
Bundle(Parcel parcelledData)60     Bundle(Parcel parcelledData) {
61         super(parcelledData);
62 
63         mHasFds = mParcelledData.hasFileDescriptors();
64         mFdsKnown = true;
65     }
66 
Bundle(Parcel parcelledData, int length)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      */
Bundle(ClassLoader loader)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      */
Bundle(int capacity)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      */
Bundle(Bundle b)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      */
Bundle(PersistableBundle b)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      */
forPair(String key, String value)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
setClassLoader(ClassLoader loader)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
getClassLoader()144     public ClassLoader getClassLoader() {
145         return super.getClassLoader();
146     }
147 
148     /** @hide */
setAllowFds(boolean allowFds)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
clone()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
clear()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      */
putAll(Bundle bundle)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      */
hasFileDescriptors()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
putByte(String key, byte value)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
putChar(String key, char value)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
putShort(String key, short value)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
putFloat(String key, float value)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
putCharSequence(String key, CharSequence value)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      */
putParcelable(String key, Parcelable value)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      */
putSize(String key, Size value)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      */
putSizeF(String key, SizeF value)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      */
putParcelableArray(String key, Parcelable[] value)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      */
putParcelableArrayList(String key, ArrayList<? extends Parcelable> value)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} */
putParcelableList(String key, List<? extends Parcelable> value)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      */
putSparseParcelableArray(String key, SparseArray<? extends Parcelable> value)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
putIntegerArrayList(String key, ArrayList<Integer> value)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
putStringArrayList(String key, ArrayList<String> value)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
putCharSequenceArrayList(String key, ArrayList<CharSequence> value)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
putSerializable(String key, Serializable value)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
putByteArray(String key, byte[] value)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
putShortArray(String key, short[] value)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
putCharArray(String key, char[] value)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
putFloatArray(String key, float[] value)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
putCharSequenceArray(String key, CharSequence[] value)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      */
putBundle(String key, Bundle value)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      */
putBinder(String key, IBinder value)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
putIBinder(String key, IBinder value)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
getByte(String key)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
getByte(String key, byte defaultValue)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
getChar(String key)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
getChar(String key, char defaultValue)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
getShort(String key)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
getShort(String key, short defaultValue)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
getFloat(String key)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
getFloat(String key, float defaultValue)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
getCharSequence(String key)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
getCharSequence(String key, CharSequence defaultValue)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      */
getSize(String key)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      */
getSizeF(String key)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      */
getBundle(String key)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      */
getParcelable(String key)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      */
getParcelableArray(String key)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      */
getParcelableArrayList(String key)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      */
getSparseParcelableArray(String key)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
getSerializable(String key)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
getIntegerArrayList(String key)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
getStringArrayList(String key)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
getCharSequenceArrayList(String key)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
getByteArray(String key)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
getShortArray(String key)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
getCharArray(String key)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
getFloatArray(String key)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
getCharSequenceArray(String key)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      */
getBinder(String key)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
getIBinder(String key)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
describeContents()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
writeToParcel(Parcel parcel, int flags)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      */
readFromParcel(Parcel parcel)1045     public void readFromParcel(Parcel parcel) {
1046         super.readFromParcelInner(parcel);
1047         mHasFds = mParcelledData.hasFileDescriptors();
1048         mFdsKnown = true;
1049     }
1050 
1051     @Override
toString()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