• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Bundle filterValues() {
313         unparcel();
314         Bundle bundle = this;
315         if (mMap != null) {
316             ArrayMap<String, Object> map = mMap;
317             for (int i = map.size() - 1; i >= 0; i--) {
318                 Object value = map.valueAt(i);
319                 if (PersistableBundle.isValidType(value)) {
320                     continue;
321                 }
322                 if (value instanceof Bundle) {
323                     Bundle newBundle = ((Bundle)value).filterValues();
324                     if (newBundle != value) {
325                         if (map == mMap) {
326                             // The filter had to generate a new bundle, but we have not yet
327                             // created a new one here.  Do that now.
328                             bundle = new Bundle(this);
329                             // Note the ArrayMap<> constructor is guaranteed to generate
330                             // a new object with items in the same order as the original.
331                             map = bundle.mMap;
332                         }
333                         // Replace this current entry with the new child bundle.
334                         map.setValueAt(i, newBundle);
335                     }
336                     continue;
337                 }
338                 if (value.getClass().getName().startsWith("android.")) {
339                     continue;
340                 }
341                 if (map == mMap) {
342                     // This is the first time we have had to remove something, that means we
343                     // need to switch to a new Bundle.
344                     bundle = new Bundle(this);
345                     // Note the ArrayMap<> constructor is guaranteed to generate
346                     // a new object with items in the same order as the original.
347                     map = bundle.mMap;
348                 }
349                 map.removeAt(i);
350             }
351         }
352         mFlags |= FLAG_HAS_FDS_KNOWN;
353         mFlags &= ~FLAG_HAS_FDS;
354         return bundle;
355     }
356 
357     /**
358      * Inserts a byte 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 byte
363      */
364     @Override
putByte(@ullable String key, byte value)365     public void putByte(@Nullable String key, byte value) {
366         super.putByte(key, value);
367     }
368 
369     /**
370      * Inserts a char 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 char
375      */
376     @Override
putChar(@ullable String key, char value)377     public void putChar(@Nullable String key, char value) {
378         super.putChar(key, value);
379     }
380 
381     /**
382      * Inserts a short 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 short
387      */
388     @Override
putShort(@ullable String key, short value)389     public void putShort(@Nullable String key, short value) {
390         super.putShort(key, value);
391     }
392 
393     /**
394      * Inserts a float 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 float
399      */
400     @Override
putFloat(@ullable String key, float value)401     public void putFloat(@Nullable String key, float value) {
402         super.putFloat(key, value);
403     }
404 
405     /**
406      * Inserts a CharSequence value into the mapping of this Bundle, replacing
407      * any existing value for the given key.  Either key or value may be null.
408      *
409      * @param key a String, or null
410      * @param value a CharSequence, or null
411      */
412     @Override
putCharSequence(@ullable String key, @Nullable CharSequence value)413     public void putCharSequence(@Nullable String key, @Nullable CharSequence value) {
414         super.putCharSequence(key, value);
415     }
416 
417     /**
418      * Inserts a Parcelable value into the mapping of this Bundle, replacing
419      * any existing value for the given key.  Either key or value may be null.
420      *
421      * @param key a String, or null
422      * @param value a Parcelable object, or null
423      */
putParcelable(@ullable String key, @Nullable Parcelable value)424     public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
425         unparcel();
426         mMap.put(key, value);
427         mFlags &= ~FLAG_HAS_FDS_KNOWN;
428     }
429 
430     /**
431      * Inserts a Size value into the mapping of this Bundle, replacing
432      * any existing value for the given key.  Either key or value may be null.
433      *
434      * @param key a String, or null
435      * @param value a Size object, or null
436      */
putSize(@ullable String key, @Nullable Size value)437     public void putSize(@Nullable String key, @Nullable Size value) {
438         unparcel();
439         mMap.put(key, value);
440     }
441 
442     /**
443      * Inserts a SizeF value into the mapping of this Bundle, replacing
444      * any existing value for the given key.  Either key or value may be null.
445      *
446      * @param key a String, or null
447      * @param value a SizeF object, or null
448      */
putSizeF(@ullable String key, @Nullable SizeF value)449     public void putSizeF(@Nullable String key, @Nullable SizeF value) {
450         unparcel();
451         mMap.put(key, value);
452     }
453 
454     /**
455      * Inserts an array of Parcelable values into the mapping of this Bundle,
456      * replacing any existing value for the given key.  Either key or value may
457      * be null.
458      *
459      * @param key a String, or null
460      * @param value an array of Parcelable objects, or null
461      */
putParcelableArray(@ullable String key, @Nullable Parcelable[] value)462     public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
463         unparcel();
464         mMap.put(key, value);
465         mFlags &= ~FLAG_HAS_FDS_KNOWN;
466     }
467 
468     /**
469      * Inserts a List of Parcelable values into the mapping of this Bundle,
470      * replacing any existing value for the given key.  Either key or value may
471      * be null.
472      *
473      * @param key a String, or null
474      * @param value an ArrayList of Parcelable objects, or null
475      */
putParcelableArrayList(@ullable String key, @Nullable ArrayList<? extends Parcelable> value)476     public void putParcelableArrayList(@Nullable String key,
477             @Nullable ArrayList<? extends Parcelable> value) {
478         unparcel();
479         mMap.put(key, value);
480         mFlags &= ~FLAG_HAS_FDS_KNOWN;
481     }
482 
483     /** {@hide} */
putParcelableList(String key, List<? extends Parcelable> value)484     public void putParcelableList(String key, List<? extends Parcelable> value) {
485         unparcel();
486         mMap.put(key, value);
487         mFlags &= ~FLAG_HAS_FDS_KNOWN;
488     }
489 
490     /**
491      * Inserts a SparceArray of Parcelable values into the mapping of this
492      * Bundle, replacing any existing value for the given key.  Either key
493      * or value may be null.
494      *
495      * @param key a String, or null
496      * @param value a SparseArray of Parcelable objects, or null
497      */
putSparseParcelableArray(@ullable String key, @Nullable SparseArray<? extends Parcelable> value)498     public void putSparseParcelableArray(@Nullable String key,
499             @Nullable SparseArray<? extends Parcelable> value) {
500         unparcel();
501         mMap.put(key, value);
502         mFlags &= ~FLAG_HAS_FDS_KNOWN;
503     }
504 
505     /**
506      * Inserts an ArrayList<Integer> 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<Integer> object, or null
511      */
512     @Override
putIntegerArrayList(@ullable String key, @Nullable ArrayList<Integer> value)513     public void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
514         super.putIntegerArrayList(key, value);
515     }
516 
517     /**
518      * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
519      * any existing value for the given key.  Either key or value may be null.
520      *
521      * @param key a String, or null
522      * @param value an ArrayList<String> object, or null
523      */
524     @Override
putStringArrayList(@ullable String key, @Nullable ArrayList<String> value)525     public void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
526         super.putStringArrayList(key, value);
527     }
528 
529     /**
530      * Inserts an ArrayList<CharSequence> 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<CharSequence> object, or null
535      */
536     @Override
putCharSequenceArrayList(@ullable String key, @Nullable ArrayList<CharSequence> value)537     public void putCharSequenceArrayList(@Nullable String key,
538             @Nullable ArrayList<CharSequence> value) {
539         super.putCharSequenceArrayList(key, value);
540     }
541 
542     /**
543      * Inserts a Serializable 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 Serializable object, or null
548      */
549     @Override
putSerializable(@ullable String key, @Nullable Serializable value)550     public void putSerializable(@Nullable String key, @Nullable Serializable value) {
551         super.putSerializable(key, value);
552     }
553 
554     /**
555      * Inserts a byte 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 byte array object, or null
560      */
561     @Override
putByteArray(@ullable String key, @Nullable byte[] value)562     public void putByteArray(@Nullable String key, @Nullable byte[] value) {
563         super.putByteArray(key, value);
564     }
565 
566     /**
567      * Inserts a short 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 short array object, or null
572      */
573     @Override
putShortArray(@ullable String key, @Nullable short[] value)574     public void putShortArray(@Nullable String key, @Nullable short[] value) {
575         super.putShortArray(key, value);
576     }
577 
578     /**
579      * Inserts a char 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 char array object, or null
584      */
585     @Override
putCharArray(@ullable String key, @Nullable char[] value)586     public void putCharArray(@Nullable String key, @Nullable char[] value) {
587         super.putCharArray(key, value);
588     }
589 
590     /**
591      * Inserts a float 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 float array object, or null
596      */
597     @Override
putFloatArray(@ullable String key, @Nullable float[] value)598     public void putFloatArray(@Nullable String key, @Nullable float[] value) {
599         super.putFloatArray(key, value);
600     }
601 
602     /**
603      * Inserts a CharSequence 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 CharSequence array object, or null
608      */
609     @Override
putCharSequenceArray(@ullable String key, @Nullable CharSequence[] value)610     public void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
611         super.putCharSequenceArray(key, value);
612     }
613 
614     /**
615      * Inserts a Bundle 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 Bundle object, or null
620      */
putBundle(@ullable String key, @Nullable Bundle value)621     public void putBundle(@Nullable String key, @Nullable Bundle value) {
622         unparcel();
623         mMap.put(key, value);
624     }
625 
626     /**
627      * Inserts an {@link IBinder} 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      * <p class="note">You should be very careful when using this function.  In many
631      * places where Bundles are used (such as inside of Intent objects), the Bundle
632      * can live longer inside of another process than the process that had originally
633      * created it.  In that case, the IBinder you supply here will become invalid
634      * when your process goes away, and no longer usable, even if a new process is
635      * created for you later on.</p>
636      *
637      * @param key a String, or null
638      * @param value an IBinder object, or null
639      */
putBinder(@ullable String key, @Nullable IBinder value)640     public void putBinder(@Nullable String key, @Nullable IBinder value) {
641         unparcel();
642         mMap.put(key, value);
643     }
644 
645     /**
646      * Inserts an IBinder value into the mapping of this Bundle, replacing
647      * any existing value for the given key.  Either key or value may be null.
648      *
649      * @param key a String, or null
650      * @param value an IBinder object, or null
651      *
652      * @deprecated
653      * @hide This is the old name of the function.
654      */
655     @Deprecated
putIBinder(@ullable String key, @Nullable IBinder value)656     public void putIBinder(@Nullable String key, @Nullable IBinder value) {
657         unparcel();
658         mMap.put(key, value);
659     }
660 
661     /**
662      * Returns the value associated with the given key, or (byte) 0 if
663      * no mapping of the desired type exists for the given key.
664      *
665      * @param key a String
666      * @return a byte value
667      */
668     @Override
getByte(String key)669     public byte getByte(String key) {
670         return super.getByte(key);
671     }
672 
673     /**
674      * Returns the value associated with the given key, or defaultValue if
675      * no mapping of the desired type exists for the given key.
676      *
677      * @param key a String
678      * @param defaultValue Value to return if key does not exist
679      * @return a byte value
680      */
681     @Override
getByte(String key, byte defaultValue)682     public Byte getByte(String key, byte defaultValue) {
683         return super.getByte(key, defaultValue);
684     }
685 
686     /**
687      * Returns the value associated with the given key, or (char) 0 if
688      * no mapping of the desired type exists for the given key.
689      *
690      * @param key a String
691      * @return a char value
692      */
693     @Override
getChar(String key)694     public char getChar(String key) {
695         return super.getChar(key);
696     }
697 
698     /**
699      * Returns the value associated with the given key, or defaultValue if
700      * no mapping of the desired type exists for the given key.
701      *
702      * @param key a String
703      * @param defaultValue Value to return if key does not exist
704      * @return a char value
705      */
706     @Override
getChar(String key, char defaultValue)707     public char getChar(String key, char defaultValue) {
708         return super.getChar(key, defaultValue);
709     }
710 
711     /**
712      * Returns the value associated with the given key, or (short) 0 if
713      * no mapping of the desired type exists for the given key.
714      *
715      * @param key a String
716      * @return a short value
717      */
718     @Override
getShort(String key)719     public short getShort(String key) {
720         return super.getShort(key);
721     }
722 
723     /**
724      * Returns the value associated with the given key, or defaultValue if
725      * no mapping of the desired type exists for the given key.
726      *
727      * @param key a String
728      * @param defaultValue Value to return if key does not exist
729      * @return a short value
730      */
731     @Override
getShort(String key, short defaultValue)732     public short getShort(String key, short defaultValue) {
733         return super.getShort(key, defaultValue);
734     }
735 
736     /**
737      * Returns the value associated with the given key, or 0.0f if
738      * no mapping of the desired type exists for the given key.
739      *
740      * @param key a String
741      * @return a float value
742      */
743     @Override
getFloat(String key)744     public float getFloat(String key) {
745         return super.getFloat(key);
746     }
747 
748     /**
749      * Returns the value associated with the given key, or defaultValue if
750      * no mapping of the desired type exists for the given key.
751      *
752      * @param key a String
753      * @param defaultValue Value to return if key does not exist
754      * @return a float value
755      */
756     @Override
getFloat(String key, float defaultValue)757     public float getFloat(String key, float defaultValue) {
758         return super.getFloat(key, defaultValue);
759     }
760 
761     /**
762      * Returns the value associated with the given key, or null if
763      * no mapping of the desired type exists for the given key or a null
764      * value is explicitly associated with the key.
765      *
766      * @param key a String, or null
767      * @return a CharSequence value, or null
768      */
769     @Override
770     @Nullable
getCharSequence(@ullable String key)771     public CharSequence getCharSequence(@Nullable String key) {
772         return super.getCharSequence(key);
773     }
774 
775     /**
776      * Returns the value associated with the given key, or defaultValue if
777      * no mapping of the desired type exists for the given key or if a null
778      * value is explicitly associatd with the given key.
779      *
780      * @param key a String, or null
781      * @param defaultValue Value to return if key does not exist or if a null
782      *     value is associated with the given key.
783      * @return the CharSequence value associated with the given key, or defaultValue
784      *     if no valid CharSequence object is currently mapped to that key.
785      */
786     @Override
getCharSequence(@ullable String key, CharSequence defaultValue)787     public CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) {
788         return super.getCharSequence(key, defaultValue);
789     }
790 
791     /**
792      * Returns the value associated with the given key, or null if
793      * no mapping of the desired type exists for the given key or a null
794      * value is explicitly associated with the key.
795      *
796      * @param key a String, or null
797      * @return a Size value, or null
798      */
799     @Nullable
getSize(@ullable String key)800     public Size getSize(@Nullable String key) {
801         unparcel();
802         final Object o = mMap.get(key);
803         try {
804             return (Size) o;
805         } catch (ClassCastException e) {
806             typeWarning(key, o, "Size", e);
807             return null;
808         }
809     }
810 
811     /**
812      * Returns the value associated with the given key, or null if
813      * no mapping of the desired type exists for the given key or a null
814      * value is explicitly associated with the key.
815      *
816      * @param key a String, or null
817      * @return a Size value, or null
818      */
819     @Nullable
getSizeF(@ullable String key)820     public SizeF getSizeF(@Nullable String key) {
821         unparcel();
822         final Object o = mMap.get(key);
823         try {
824             return (SizeF) o;
825         } catch (ClassCastException e) {
826             typeWarning(key, o, "SizeF", e);
827             return null;
828         }
829     }
830 
831     /**
832      * Returns the value associated with the given key, or null if
833      * no mapping of the desired type exists for the given key or a null
834      * value is explicitly associated with the key.
835      *
836      * @param key a String, or null
837      * @return a Bundle value, or null
838      */
839     @Nullable
getBundle(@ullable String key)840     public Bundle getBundle(@Nullable String key) {
841         unparcel();
842         Object o = mMap.get(key);
843         if (o == null) {
844             return null;
845         }
846         try {
847             return (Bundle) o;
848         } catch (ClassCastException e) {
849             typeWarning(key, o, "Bundle", e);
850             return null;
851         }
852     }
853 
854     /**
855      * Returns the value associated with the given key, or null if
856      * no mapping of the desired type exists for the given key or a null
857      * value is explicitly associated with the key.
858      *
859      * @param key a String, or null
860      * @return a Parcelable value, or null
861      */
862     @Nullable
getParcelable(@ullable String key)863     public <T extends Parcelable> T getParcelable(@Nullable String key) {
864         unparcel();
865         Object o = mMap.get(key);
866         if (o == null) {
867             return null;
868         }
869         try {
870             return (T) o;
871         } catch (ClassCastException e) {
872             typeWarning(key, o, "Parcelable", e);
873             return null;
874         }
875     }
876 
877     /**
878      * Returns the value associated with the given key, or null if
879      * no mapping of the desired type exists for the given key or a null
880      * value is explicitly associated with the key.
881      *
882      * @param key a String, or null
883      * @return a Parcelable[] value, or null
884      */
885     @Nullable
getParcelableArray(@ullable String key)886     public Parcelable[] getParcelableArray(@Nullable String key) {
887         unparcel();
888         Object o = mMap.get(key);
889         if (o == null) {
890             return null;
891         }
892         try {
893             return (Parcelable[]) o;
894         } catch (ClassCastException e) {
895             typeWarning(key, o, "Parcelable[]", e);
896             return null;
897         }
898     }
899 
900     /**
901      * Returns the value associated with the given key, or null if
902      * no mapping of the desired type exists for the given key or a null
903      * value is explicitly associated with the key.
904      *
905      * @param key a String, or null
906      * @return an ArrayList<T> value, or null
907      */
908     @Nullable
getParcelableArrayList(@ullable String key)909     public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) {
910         unparcel();
911         Object o = mMap.get(key);
912         if (o == null) {
913             return null;
914         }
915         try {
916             return (ArrayList<T>) o;
917         } catch (ClassCastException e) {
918             typeWarning(key, o, "ArrayList", 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      *
930      * @return a SparseArray of T values, or null
931      */
932     @Nullable
getSparseParcelableArray(@ullable String key)933     public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(@Nullable String key) {
934         unparcel();
935         Object o = mMap.get(key);
936         if (o == null) {
937             return null;
938         }
939         try {
940             return (SparseArray<T>) o;
941         } catch (ClassCastException e) {
942             typeWarning(key, o, "SparseArray", 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      * @return a Serializable value, or null
954      */
955     @Override
956     @Nullable
getSerializable(@ullable String key)957     public Serializable getSerializable(@Nullable String key) {
958         return super.getSerializable(key);
959     }
960 
961     /**
962      * Returns the value associated with the given key, or null if
963      * no mapping of the desired type exists for the given key or a null
964      * value is explicitly associated with the key.
965      *
966      * @param key a String, or null
967      * @return an ArrayList<String> value, or null
968      */
969     @Override
970     @Nullable
getIntegerArrayList(@ullable String key)971     public ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
972         return super.getIntegerArrayList(key);
973     }
974 
975     /**
976      * Returns the value associated with the given key, or null if
977      * no mapping of the desired type exists for the given key or a null
978      * value is explicitly associated with the key.
979      *
980      * @param key a String, or null
981      * @return an ArrayList<String> value, or null
982      */
983     @Override
984     @Nullable
getStringArrayList(@ullable String key)985     public ArrayList<String> getStringArrayList(@Nullable String key) {
986         return super.getStringArrayList(key);
987     }
988 
989     /**
990      * Returns the value associated with the given key, or null if
991      * no mapping of the desired type exists for the given key or a null
992      * value is explicitly associated with the key.
993      *
994      * @param key a String, or null
995      * @return an ArrayList<CharSequence> value, or null
996      */
997     @Override
998     @Nullable
getCharSequenceArrayList(@ullable String key)999     public ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) {
1000         return super.getCharSequenceArrayList(key);
1001     }
1002 
1003     /**
1004      * Returns the value associated with the given key, or null if
1005      * no mapping of the desired type exists for the given key or a null
1006      * value is explicitly associated with the key.
1007      *
1008      * @param key a String, or null
1009      * @return a byte[] value, or null
1010      */
1011     @Override
1012     @Nullable
getByteArray(@ullable String key)1013     public byte[] getByteArray(@Nullable String key) {
1014         return super.getByteArray(key);
1015     }
1016 
1017     /**
1018      * Returns the value associated with the given key, or null if
1019      * no mapping of the desired type exists for the given key or a null
1020      * value is explicitly associated with the key.
1021      *
1022      * @param key a String, or null
1023      * @return a short[] value, or null
1024      */
1025     @Override
1026     @Nullable
getShortArray(@ullable String key)1027     public short[] getShortArray(@Nullable String key) {
1028         return super.getShortArray(key);
1029     }
1030 
1031     /**
1032      * Returns the value associated with the given key, or null if
1033      * no mapping of the desired type exists for the given key or a null
1034      * value is explicitly associated with the key.
1035      *
1036      * @param key a String, or null
1037      * @return a char[] value, or null
1038      */
1039     @Override
1040     @Nullable
getCharArray(@ullable String key)1041     public char[] getCharArray(@Nullable String key) {
1042         return super.getCharArray(key);
1043     }
1044 
1045     /**
1046      * Returns the value associated with the given key, or null if
1047      * no mapping of the desired type exists for the given key or a null
1048      * value is explicitly associated with the key.
1049      *
1050      * @param key a String, or null
1051      * @return a float[] value, or null
1052      */
1053     @Override
1054     @Nullable
getFloatArray(@ullable String key)1055     public float[] getFloatArray(@Nullable String key) {
1056         return super.getFloatArray(key);
1057     }
1058 
1059     /**
1060      * Returns the value associated with the given key, or null if
1061      * no mapping of the desired type exists for the given key or a null
1062      * value is explicitly associated with the key.
1063      *
1064      * @param key a String, or null
1065      * @return a CharSequence[] value, or null
1066      */
1067     @Override
1068     @Nullable
getCharSequenceArray(@ullable String key)1069     public CharSequence[] getCharSequenceArray(@Nullable String key) {
1070         return super.getCharSequenceArray(key);
1071     }
1072 
1073     /**
1074      * Returns the value associated with the given key, or null if
1075      * no mapping of the desired type exists for the given key or a null
1076      * value is explicitly associated with the key.
1077      *
1078      * @param key a String, or null
1079      * @return an IBinder value, or null
1080      */
1081     @Nullable
getBinder(@ullable String key)1082     public IBinder getBinder(@Nullable String key) {
1083         unparcel();
1084         Object o = mMap.get(key);
1085         if (o == null) {
1086             return null;
1087         }
1088         try {
1089             return (IBinder) o;
1090         } catch (ClassCastException e) {
1091             typeWarning(key, o, "IBinder", e);
1092             return null;
1093         }
1094     }
1095 
1096     /**
1097      * Returns the value associated with the given key, or null if
1098      * no mapping of the desired type exists for the given key or a null
1099      * value is explicitly associated with the key.
1100      *
1101      * @param key a String, or null
1102      * @return an IBinder value, or null
1103      *
1104      * @deprecated
1105      * @hide This is the old name of the function.
1106      */
1107     @Deprecated
1108     @Nullable
getIBinder(@ullable String key)1109     public IBinder getIBinder(@Nullable String key) {
1110         unparcel();
1111         Object o = mMap.get(key);
1112         if (o == null) {
1113             return null;
1114         }
1115         try {
1116             return (IBinder) o;
1117         } catch (ClassCastException e) {
1118             typeWarning(key, o, "IBinder", e);
1119             return null;
1120         }
1121     }
1122 
1123     public static final Parcelable.Creator<Bundle> CREATOR =
1124         new Parcelable.Creator<Bundle>() {
1125         @Override
1126         public Bundle createFromParcel(Parcel in) {
1127             return in.readBundle();
1128         }
1129 
1130         @Override
1131         public Bundle[] newArray(int size) {
1132             return new Bundle[size];
1133         }
1134     };
1135 
1136     /**
1137      * Report the nature of this Parcelable's contents
1138      */
1139     @Override
describeContents()1140     public int describeContents() {
1141         int mask = 0;
1142         if (hasFileDescriptors()) {
1143             mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
1144         }
1145         return mask;
1146     }
1147 
1148     /**
1149      * Writes the Bundle contents to a Parcel, typically in order for
1150      * it to be passed through an IBinder connection.
1151      * @param parcel The parcel to copy this bundle to.
1152      */
1153     @Override
writeToParcel(Parcel parcel, int flags)1154     public void writeToParcel(Parcel parcel, int flags) {
1155         final boolean oldAllowFds = parcel.pushAllowFds((mFlags & FLAG_ALLOW_FDS) != 0);
1156         try {
1157             super.writeToParcelInner(parcel, flags);
1158         } finally {
1159             parcel.restoreAllowFds(oldAllowFds);
1160         }
1161     }
1162 
1163     /**
1164      * Reads the Parcel contents into this Bundle, typically in order for
1165      * it to be passed through an IBinder connection.
1166      * @param parcel The parcel to overwrite this bundle from.
1167      */
readFromParcel(Parcel parcel)1168     public void readFromParcel(Parcel parcel) {
1169         super.readFromParcelInner(parcel);
1170         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
1171         if (mParcelledData.hasFileDescriptors()) {
1172             mFlags |= FLAG_HAS_FDS;
1173         }
1174     }
1175 
1176     @Override
toString()1177     public synchronized String toString() {
1178         if (mParcelledData != null) {
1179             if (isEmptyParcel()) {
1180                 return "Bundle[EMPTY_PARCEL]";
1181             } else {
1182                 return "Bundle[mParcelledData.dataSize=" +
1183                         mParcelledData.dataSize() + "]";
1184             }
1185         }
1186         return "Bundle[" + mMap.toString() + "]";
1187     }
1188 }
1189