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