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