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