• 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 static java.util.Objects.requireNonNull;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SuppressLint;
24 import android.compat.annotation.UnsupportedAppUsage;
25 import android.util.ArrayMap;
26 import android.util.Size;
27 import android.util.SizeF;
28 import android.util.SparseArray;
29 import android.util.proto.ProtoOutputStream;
30 
31 import com.android.internal.annotations.VisibleForTesting;
32 
33 import java.io.Serializable;
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 /**
38  * A mapping from String keys to various {@link Parcelable} values.
39  *
40  * <p><b>Warning:</b> Note that {@link Bundle} is a lazy container and as such it does NOT implement
41  * {@link #equals(Object)} or {@link #hashCode()}.
42  *
43  * @see PersistableBundle
44  */
45 public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
46     @VisibleForTesting
47     static final int FLAG_HAS_FDS = 1 << 8;
48 
49     @VisibleForTesting
50     static final int FLAG_HAS_FDS_KNOWN = 1 << 9;
51 
52     @VisibleForTesting
53     static final int FLAG_ALLOW_FDS = 1 << 10;
54 
55     /** An unmodifiable {@code Bundle} that is always {@link #isEmpty() empty}. */
56     public static final Bundle EMPTY;
57 
58     /**
59      * Special extras used to denote extras have been stripped off.
60      * @hide
61      */
62     public static final Bundle STRIPPED;
63 
64     static {
65         EMPTY = new Bundle();
66         EMPTY.mMap = ArrayMap.EMPTY;
67 
68         STRIPPED = new Bundle();
69         STRIPPED.putInt("STRIPPED", 1);
70     }
71 
72     /**
73      * Constructs a new, empty Bundle.
74      */
Bundle()75     public Bundle() {
76         super();
77         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
78     }
79 
80     /**
81      * Constructs a Bundle whose data is stored as a Parcel.  The data
82      * will be unparcelled on first contact, using the assigned ClassLoader.
83      *
84      * @param parcelledData a Parcel containing a Bundle
85      *
86      * @hide
87      */
88     @VisibleForTesting
Bundle(Parcel parcelledData)89     public Bundle(Parcel parcelledData) {
90         super(parcelledData);
91         mFlags = FLAG_ALLOW_FDS;
92         maybePrefillHasFds();
93     }
94 
95     /**
96      * Constructor from a parcel for when the length is known *and is not stored in the parcel.*
97      * The other constructor that takes a parcel assumes the length is in the parcel.
98      *
99      * @hide
100      */
101     @VisibleForTesting
Bundle(Parcel parcelledData, int length)102     public Bundle(Parcel parcelledData, int length) {
103         super(parcelledData, length);
104         mFlags = FLAG_ALLOW_FDS;
105         maybePrefillHasFds();
106     }
107 
108     /**
109      * Constructs a {@link Bundle} containing a copy of {@code from}.
110      *
111      * @param from The bundle to be copied.
112      * @param deep Whether is a deep or shallow copy.
113      *
114      * @hide
115      */
Bundle(Bundle from, boolean deep)116     Bundle(Bundle from, boolean deep) {
117         super(from, deep);
118     }
119 
120     /**
121      * If {@link #mParcelledData} is not null, copy the HAS FDS bit from it because it's fast.
122      * Otherwise (if {@link #mParcelledData} is already null), leave {@link #FLAG_HAS_FDS_KNOWN}
123      * unset, because scanning a map is slower.  We'll do it lazily in
124      * {@link #hasFileDescriptors()}.
125      */
maybePrefillHasFds()126     private void maybePrefillHasFds() {
127         if (mParcelledData != null) {
128             if (mParcelledData.hasFileDescriptors()) {
129                 mFlags |= FLAG_HAS_FDS | FLAG_HAS_FDS_KNOWN;
130             } else {
131                 mFlags |= FLAG_HAS_FDS_KNOWN;
132             }
133         }
134     }
135 
136     /**
137      * Constructs a new, empty Bundle that uses a specific ClassLoader for
138      * instantiating Parcelable and Serializable objects.
139      *
140      * @param loader An explicit ClassLoader to use when instantiating objects
141      * inside of the Bundle.
142      */
Bundle(ClassLoader loader)143     public Bundle(ClassLoader loader) {
144         super(loader);
145         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
146     }
147 
148     /**
149      * Constructs a new, empty Bundle sized to hold the given number of
150      * elements. The Bundle will grow as needed.
151      *
152      * @param capacity the initial capacity of the Bundle
153      */
Bundle(int capacity)154     public Bundle(int capacity) {
155         super(capacity);
156         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
157     }
158 
159     /**
160      * Constructs a Bundle containing a copy of the mappings from the given
161      * Bundle.  Does only a shallow copy of the original Bundle -- see
162      * {@link #deepCopy()} if that is not what you want.
163      *
164      * @param b a Bundle to be copied.
165      *
166      * @see #deepCopy()
167      */
Bundle(Bundle b)168     public Bundle(Bundle b) {
169         super(b);
170         mFlags = b.mFlags;
171     }
172 
173     /**
174      * Constructs a Bundle containing a copy of the mappings from the given
175      * PersistableBundle.  Does only a shallow copy of the PersistableBundle -- see
176      * {@link PersistableBundle#deepCopy()} if you don't want that.
177      *
178      * @param b a PersistableBundle to be copied.
179      */
Bundle(PersistableBundle b)180     public Bundle(PersistableBundle b) {
181         super(b);
182         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
183     }
184 
185     /**
186      * Make a Bundle for a single key/value pair.
187      *
188      * @hide
189      */
190     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
forPair(String key, String value)191     public static Bundle forPair(String key, String value) {
192         Bundle b = new Bundle(1);
193         b.putString(key, value);
194         return b;
195     }
196 
197     /**
198      * Changes the ClassLoader this Bundle uses when instantiating objects.
199      *
200      * @param loader An explicit ClassLoader to use when instantiating objects
201      * inside of the Bundle.
202      */
203     @Override
setClassLoader(ClassLoader loader)204     public void setClassLoader(ClassLoader loader) {
205         super.setClassLoader(loader);
206     }
207 
208     /**
209      * Return the ClassLoader currently associated with this Bundle.
210      */
211     @Override
getClassLoader()212     public ClassLoader getClassLoader() {
213         return super.getClassLoader();
214     }
215 
216     /** {@hide} */
setAllowFds(boolean allowFds)217     public boolean setAllowFds(boolean allowFds) {
218         final boolean orig = (mFlags & FLAG_ALLOW_FDS) != 0;
219         if (allowFds) {
220             mFlags |= FLAG_ALLOW_FDS;
221         } else {
222             mFlags &= ~FLAG_ALLOW_FDS;
223         }
224         return orig;
225     }
226 
227     /**
228      * Mark if this Bundle is okay to "defuse." That is, it's okay for system
229      * processes to ignore any {@link BadParcelableException} encountered when
230      * unparceling it, leaving an empty bundle in its place.
231      * <p>
232      * This should <em>only</em> be set when the Bundle reaches its final
233      * destination, otherwise a system process may clobber contents that were
234      * destined for an app that could have unparceled them.
235      *
236      * @hide
237      */
setDefusable(boolean defusable)238     public void setDefusable(boolean defusable) {
239         if (defusable) {
240             mFlags |= FLAG_DEFUSABLE;
241         } else {
242             mFlags &= ~FLAG_DEFUSABLE;
243         }
244     }
245 
246     /** {@hide} */
247     @UnsupportedAppUsage
setDefusable(Bundle bundle, boolean defusable)248     public static Bundle setDefusable(Bundle bundle, boolean defusable) {
249         if (bundle != null) {
250             bundle.setDefusable(defusable);
251         }
252         return bundle;
253     }
254 
255     /**
256      * Clones the current Bundle. The internal map is cloned, but the keys and
257      * values to which it refers are copied by reference.
258      */
259     @Override
clone()260     public Object clone() {
261         return new Bundle(this);
262     }
263 
264     /**
265      * Make a deep copy of the given bundle.  Traverses into inner containers and copies
266      * them as well, so they are not shared across bundles.  Will traverse in to
267      * {@link Bundle}, {@link PersistableBundle}, {@link ArrayList}, and all types of
268      * primitive arrays.  Other types of objects (such as Parcelable or Serializable)
269      * are referenced as-is and not copied in any way.
270      */
deepCopy()271     public Bundle deepCopy() {
272         return new Bundle(this, /* deep */ true);
273     }
274 
275     /**
276      * Removes all elements from the mapping of this Bundle.
277      */
278     @Override
clear()279     public void clear() {
280         super.clear();
281         mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
282     }
283 
284     /**
285      * Removes any entry with the given key from the mapping of this Bundle.
286      *
287      * @param key a String key
288      */
remove(String key)289     public void remove(String key) {
290         super.remove(key);
291         if ((mFlags & FLAG_HAS_FDS) != 0) {
292             mFlags &= ~FLAG_HAS_FDS_KNOWN;
293         }
294     }
295 
296     /**
297      * Inserts all mappings from the given Bundle into this Bundle.
298      *
299      * @param bundle a Bundle
300      */
putAll(Bundle bundle)301     public void putAll(Bundle bundle) {
302         unparcel();
303         bundle.unparcel();
304         mOwnsLazyValues = false;
305         bundle.mOwnsLazyValues = false;
306         mMap.putAll(bundle.mMap);
307 
308         // FD state is now known if and only if both bundles already knew
309         if ((bundle.mFlags & FLAG_HAS_FDS) != 0) {
310             mFlags |= FLAG_HAS_FDS;
311         }
312         if ((bundle.mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
313             mFlags &= ~FLAG_HAS_FDS_KNOWN;
314         }
315     }
316 
317     /**
318      * Return the size of {@link #mParcelledData} in bytes if available, otherwise {@code 0}.
319      *
320      * @hide
321      */
322     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getSize()323     public int getSize() {
324         if (mParcelledData != null) {
325             return mParcelledData.dataSize();
326         } else {
327             return 0;
328         }
329     }
330 
331     /**
332      * Reports whether the bundle contains any parcelled file descriptors.
333      */
hasFileDescriptors()334     public boolean hasFileDescriptors() {
335         if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
336             Parcel p = mParcelledData;
337             mFlags = (Parcel.hasFileDescriptors((p != null) ? p : mMap))
338                     ? mFlags | FLAG_HAS_FDS
339                     : mFlags & ~FLAG_HAS_FDS;
340             mFlags |= FLAG_HAS_FDS_KNOWN;
341         }
342         return (mFlags & FLAG_HAS_FDS) != 0;
343     }
344 
345     /** {@hide} */
346     @Override
putObject(@ullable String key, @Nullable Object value)347     public void putObject(@Nullable String key, @Nullable Object value) {
348         if (value instanceof Byte) {
349             putByte(key, (Byte) value);
350         } else if (value instanceof Character) {
351             putChar(key, (Character) value);
352         } else if (value instanceof Short) {
353             putShort(key, (Short) value);
354         } else if (value instanceof Float) {
355             putFloat(key, (Float) value);
356         } else if (value instanceof CharSequence) {
357             putCharSequence(key, (CharSequence) value);
358         } else if (value instanceof Parcelable) {
359             putParcelable(key, (Parcelable) value);
360         } else if (value instanceof Size) {
361             putSize(key, (Size) value);
362         } else if (value instanceof SizeF) {
363             putSizeF(key, (SizeF) value);
364         } else if (value instanceof Parcelable[]) {
365             putParcelableArray(key, (Parcelable[]) value);
366         } else if (value instanceof ArrayList) {
367             putParcelableArrayList(key, (ArrayList) value);
368         } else if (value instanceof List) {
369             putParcelableList(key, (List) value);
370         } else if (value instanceof SparseArray) {
371             putSparseParcelableArray(key, (SparseArray) value);
372         } else if (value instanceof Serializable) {
373             putSerializable(key, (Serializable) value);
374         } else if (value instanceof byte[]) {
375             putByteArray(key, (byte[]) value);
376         } else if (value instanceof short[]) {
377             putShortArray(key, (short[]) value);
378         } else if (value instanceof char[]) {
379             putCharArray(key, (char[]) value);
380         } else if (value instanceof float[]) {
381             putFloatArray(key, (float[]) value);
382         } else if (value instanceof CharSequence[]) {
383             putCharSequenceArray(key, (CharSequence[]) value);
384         } else if (value instanceof Bundle) {
385             putBundle(key, (Bundle) value);
386         } else if (value instanceof Binder) {
387             putBinder(key, (Binder) value);
388         } else if (value instanceof IBinder) {
389             putIBinder(key, (IBinder) value);
390         } else {
391             super.putObject(key, value);
392         }
393     }
394 
395     /**
396      * Inserts a byte value into the mapping of this Bundle, replacing
397      * any existing value for the given key.
398      *
399      * @param key a String, or null
400      * @param value a byte
401      */
402     @Override
putByte(@ullable String key, byte value)403     public void putByte(@Nullable String key, byte value) {
404         super.putByte(key, value);
405     }
406 
407     /**
408      * Inserts a char value into the mapping of this Bundle, replacing
409      * any existing value for the given key.
410      *
411      * @param key a String, or null
412      * @param value a char
413      */
414     @Override
putChar(@ullable String key, char value)415     public void putChar(@Nullable String key, char value) {
416         super.putChar(key, value);
417     }
418 
419     /**
420      * Inserts a short value into the mapping of this Bundle, replacing
421      * any existing value for the given key.
422      *
423      * @param key a String, or null
424      * @param value a short
425      */
426     @Override
putShort(@ullable String key, short value)427     public void putShort(@Nullable String key, short value) {
428         super.putShort(key, value);
429     }
430 
431     /**
432      * Inserts a float value into the mapping of this Bundle, replacing
433      * any existing value for the given key.
434      *
435      * @param key a String, or null
436      * @param value a float
437      */
438     @Override
putFloat(@ullable String key, float value)439     public void putFloat(@Nullable String key, float value) {
440         super.putFloat(key, value);
441     }
442 
443     /**
444      * Inserts a CharSequence value into the mapping of this Bundle, replacing
445      * any existing value for the given key.  Either key or value may be null.
446      *
447      * @param key a String, or null
448      * @param value a CharSequence, or null
449      */
450     @Override
putCharSequence(@ullable String key, @Nullable CharSequence value)451     public void putCharSequence(@Nullable String key, @Nullable CharSequence value) {
452         super.putCharSequence(key, value);
453     }
454 
455     /**
456      * Inserts a Parcelable value into the mapping of this Bundle, replacing
457      * any existing value for the given key.  Either key or value may be null.
458      *
459      * @param key a String, or null
460      * @param value a Parcelable object, or null
461      */
putParcelable(@ullable String key, @Nullable Parcelable value)462     public void putParcelable(@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 Size value into the mapping of this Bundle, replacing
470      * any existing value for the given key.  Either key or value may be null.
471      *
472      * @param key a String, or null
473      * @param value a Size object, or null
474      */
putSize(@ullable String key, @Nullable Size value)475     public void putSize(@Nullable String key, @Nullable Size value) {
476         unparcel();
477         mMap.put(key, value);
478     }
479 
480     /**
481      * Inserts a SizeF value into the mapping of this Bundle, replacing
482      * any existing value for the given key.  Either key or value may be null.
483      *
484      * @param key a String, or null
485      * @param value a SizeF object, or null
486      */
putSizeF(@ullable String key, @Nullable SizeF value)487     public void putSizeF(@Nullable String key, @Nullable SizeF value) {
488         unparcel();
489         mMap.put(key, value);
490     }
491 
492     /**
493      * Inserts an array 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 array of Parcelable objects, or null
499      */
putParcelableArray(@ullable String key, @Nullable Parcelable[] value)500     public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
501         unparcel();
502         mMap.put(key, value);
503         mFlags &= ~FLAG_HAS_FDS_KNOWN;
504     }
505 
506     /**
507      * Inserts a List of Parcelable values into the mapping of this Bundle,
508      * replacing any existing value for the given key.  Either key or value may
509      * be null.
510      *
511      * @param key a String, or null
512      * @param value an ArrayList of Parcelable objects, or null
513      */
putParcelableArrayList(@ullable String key, @Nullable ArrayList<? extends Parcelable> value)514     public void putParcelableArrayList(@Nullable String key,
515             @Nullable ArrayList<? extends Parcelable> value) {
516         unparcel();
517         mMap.put(key, value);
518         mFlags &= ~FLAG_HAS_FDS_KNOWN;
519     }
520 
521     /** {@hide} */
522     @UnsupportedAppUsage
putParcelableList(String key, List<? extends Parcelable> value)523     public void putParcelableList(String key, List<? extends Parcelable> value) {
524         unparcel();
525         mMap.put(key, value);
526         mFlags &= ~FLAG_HAS_FDS_KNOWN;
527     }
528 
529     /**
530      * Inserts a SparceArray of Parcelable values into the mapping of this
531      * Bundle, replacing any existing value for the given key.  Either key
532      * or value may be null.
533      *
534      * @param key a String, or null
535      * @param value a SparseArray of Parcelable objects, or null
536      */
putSparseParcelableArray(@ullable String key, @Nullable SparseArray<? extends Parcelable> value)537     public void putSparseParcelableArray(@Nullable String key,
538             @Nullable SparseArray<? extends Parcelable> value) {
539         unparcel();
540         mMap.put(key, value);
541         mFlags &= ~FLAG_HAS_FDS_KNOWN;
542     }
543 
544     /**
545      * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
546      * any existing value for the given key.  Either key or value may be null.
547      *
548      * @param key a String, or null
549      * @param value an ArrayList<Integer> object, or null
550      */
551     @Override
putIntegerArrayList(@ullable String key, @Nullable ArrayList<Integer> value)552     public void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
553         super.putIntegerArrayList(key, value);
554     }
555 
556     /**
557      * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
558      * any existing value for the given key.  Either key or value may be null.
559      *
560      * @param key a String, or null
561      * @param value an ArrayList<String> object, or null
562      */
563     @Override
putStringArrayList(@ullable String key, @Nullable ArrayList<String> value)564     public void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
565         super.putStringArrayList(key, value);
566     }
567 
568     /**
569      * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
570      * any existing value for the given key.  Either key or value may be null.
571      *
572      * @param key a String, or null
573      * @param value an ArrayList<CharSequence> object, or null
574      */
575     @Override
putCharSequenceArrayList(@ullable String key, @Nullable ArrayList<CharSequence> value)576     public void putCharSequenceArrayList(@Nullable String key,
577             @Nullable ArrayList<CharSequence> value) {
578         super.putCharSequenceArrayList(key, value);
579     }
580 
581     /**
582      * Inserts a Serializable value into the mapping of this Bundle, replacing
583      * any existing value for the given key.  Either key or value may be null.
584      *
585      * @param key a String, or null
586      * @param value a Serializable object, or null
587      */
588     @Override
putSerializable(@ullable String key, @Nullable Serializable value)589     public void putSerializable(@Nullable String key, @Nullable Serializable value) {
590         super.putSerializable(key, value);
591     }
592 
593     /**
594      * Inserts a byte array value into the mapping of this Bundle, replacing
595      * any existing value for the given key.  Either key or value may be null.
596      *
597      * @param key a String, or null
598      * @param value a byte array object, or null
599      */
600     @Override
putByteArray(@ullable String key, @Nullable byte[] value)601     public void putByteArray(@Nullable String key, @Nullable byte[] value) {
602         super.putByteArray(key, value);
603     }
604 
605     /**
606      * Inserts a short array value into the mapping of this Bundle, replacing
607      * any existing value for the given key.  Either key or value may be null.
608      *
609      * @param key a String, or null
610      * @param value a short array object, or null
611      */
612     @Override
putShortArray(@ullable String key, @Nullable short[] value)613     public void putShortArray(@Nullable String key, @Nullable short[] value) {
614         super.putShortArray(key, value);
615     }
616 
617     /**
618      * Inserts a char array value into the mapping of this Bundle, replacing
619      * any existing value for the given key.  Either key or value may be null.
620      *
621      * @param key a String, or null
622      * @param value a char array object, or null
623      */
624     @Override
putCharArray(@ullable String key, @Nullable char[] value)625     public void putCharArray(@Nullable String key, @Nullable char[] value) {
626         super.putCharArray(key, value);
627     }
628 
629     /**
630      * Inserts a float array value into the mapping of this Bundle, replacing
631      * any existing value for the given key.  Either key or value may be null.
632      *
633      * @param key a String, or null
634      * @param value a float array object, or null
635      */
636     @Override
putFloatArray(@ullable String key, @Nullable float[] value)637     public void putFloatArray(@Nullable String key, @Nullable float[] value) {
638         super.putFloatArray(key, value);
639     }
640 
641     /**
642      * Inserts a CharSequence array value into the mapping of this Bundle, replacing
643      * any existing value for the given key.  Either key or value may be null.
644      *
645      * @param key a String, or null
646      * @param value a CharSequence array object, or null
647      */
648     @Override
putCharSequenceArray(@ullable String key, @Nullable CharSequence[] value)649     public void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
650         super.putCharSequenceArray(key, value);
651     }
652 
653     /**
654      * Inserts a Bundle value into the mapping of this Bundle, replacing
655      * any existing value for the given key.  Either key or value may be null.
656      *
657      * @param key a String, or null
658      * @param value a Bundle object, or null
659      */
putBundle(@ullable String key, @Nullable Bundle value)660     public void putBundle(@Nullable String key, @Nullable Bundle value) {
661         unparcel();
662         mMap.put(key, value);
663     }
664 
665     /**
666      * Inserts an {@link IBinder} value into the mapping of this Bundle, replacing
667      * any existing value for the given key.  Either key or value may be null.
668      *
669      * <p class="note">You should be very careful when using this function.  In many
670      * places where Bundles are used (such as inside of Intent objects), the Bundle
671      * can live longer inside of another process than the process that had originally
672      * created it.  In that case, the IBinder you supply here will become invalid
673      * when your process goes away, and no longer usable, even if a new process is
674      * created for you later on.</p>
675      *
676      * @param key a String, or null
677      * @param value an IBinder object, or null
678      */
putBinder(@ullable String key, @Nullable IBinder value)679     public void putBinder(@Nullable String key, @Nullable IBinder value) {
680         unparcel();
681         mMap.put(key, value);
682     }
683 
684     /**
685      * Inserts an IBinder value into the mapping of this Bundle, replacing
686      * any existing value for the given key.  Either key or value may be null.
687      *
688      * @param key a String, or null
689      * @param value an IBinder object, or null
690      *
691      * @deprecated
692      * @hide This is the old name of the function.
693      */
694     @UnsupportedAppUsage
695     @Deprecated
putIBinder(@ullable String key, @Nullable IBinder value)696     public void putIBinder(@Nullable String key, @Nullable IBinder value) {
697         unparcel();
698         mMap.put(key, value);
699     }
700 
701     /**
702      * Returns the value associated with the given key, or (byte) 0 if
703      * no mapping of the desired type exists for the given key.
704      *
705      * @param key a String
706      * @return a byte value
707      */
708     @Override
getByte(String key)709     public byte getByte(String key) {
710         return super.getByte(key);
711     }
712 
713     /**
714      * Returns the value associated with the given key, or defaultValue if
715      * no mapping of the desired type exists for the given key.
716      *
717      * @param key a String
718      * @param defaultValue Value to return if key does not exist
719      * @return a byte value
720      */
721     @Override
getByte(String key, byte defaultValue)722     public Byte getByte(String key, byte defaultValue) {
723         return super.getByte(key, defaultValue);
724     }
725 
726     /**
727      * Returns the value associated with the given key, or (char) 0 if
728      * no mapping of the desired type exists for the given key.
729      *
730      * @param key a String
731      * @return a char value
732      */
733     @Override
getChar(String key)734     public char getChar(String key) {
735         return super.getChar(key);
736     }
737 
738     /**
739      * Returns the value associated with the given key, or defaultValue if
740      * no mapping of the desired type exists for the given key.
741      *
742      * @param key a String
743      * @param defaultValue Value to return if key does not exist
744      * @return a char value
745      */
746     @Override
getChar(String key, char defaultValue)747     public char getChar(String key, char defaultValue) {
748         return super.getChar(key, defaultValue);
749     }
750 
751     /**
752      * Returns the value associated with the given key, or (short) 0 if
753      * no mapping of the desired type exists for the given key.
754      *
755      * @param key a String
756      * @return a short value
757      */
758     @Override
getShort(String key)759     public short getShort(String key) {
760         return super.getShort(key);
761     }
762 
763     /**
764      * Returns the value associated with the given key, or defaultValue if
765      * no mapping of the desired type exists for the given key.
766      *
767      * @param key a String
768      * @param defaultValue Value to return if key does not exist
769      * @return a short value
770      */
771     @Override
getShort(String key, short defaultValue)772     public short getShort(String key, short defaultValue) {
773         return super.getShort(key, defaultValue);
774     }
775 
776     /**
777      * Returns the value associated with the given key, or 0.0f if
778      * no mapping of the desired type exists for the given key.
779      *
780      * @param key a String
781      * @return a float value
782      */
783     @Override
getFloat(String key)784     public float getFloat(String key) {
785         return super.getFloat(key);
786     }
787 
788     /**
789      * Returns the value associated with the given key, or defaultValue if
790      * no mapping of the desired type exists for the given key.
791      *
792      * @param key a String
793      * @param defaultValue Value to return if key does not exist
794      * @return a float value
795      */
796     @Override
getFloat(String key, float defaultValue)797     public float getFloat(String key, float defaultValue) {
798         return super.getFloat(key, defaultValue);
799     }
800 
801     /**
802      * Returns the value associated with the given key, or null if
803      * no mapping of the desired type exists for the given key or a null
804      * value is explicitly associated with the key.
805      *
806      * @param key a String, or null
807      * @return a CharSequence value, or null
808      */
809     @Override
810     @Nullable
getCharSequence(@ullable String key)811     public CharSequence getCharSequence(@Nullable String key) {
812         return super.getCharSequence(key);
813     }
814 
815     /**
816      * Returns the value associated with the given key, or defaultValue if
817      * no mapping of the desired type exists for the given key or if a null
818      * value is explicitly associatd with the given key.
819      *
820      * @param key a String, or null
821      * @param defaultValue Value to return if key does not exist or if a null
822      *     value is associated with the given key.
823      * @return the CharSequence value associated with the given key, or defaultValue
824      *     if no valid CharSequence object is currently mapped to that key.
825      */
826     @Override
getCharSequence(@ullable String key, CharSequence defaultValue)827     public CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) {
828         return super.getCharSequence(key, defaultValue);
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 Size value, or null
838      */
839     @Nullable
getSize(@ullable String key)840     public Size getSize(@Nullable String key) {
841         unparcel();
842         final Object o = mMap.get(key);
843         try {
844             return (Size) o;
845         } catch (ClassCastException e) {
846             typeWarning(key, o, "Size", e);
847             return null;
848         }
849     }
850 
851     /**
852      * Returns the value associated with the given key, or null if
853      * no mapping of the desired type exists for the given key or a null
854      * value is explicitly associated with the key.
855      *
856      * @param key a String, or null
857      * @return a Size value, or null
858      */
859     @Nullable
getSizeF(@ullable String key)860     public SizeF getSizeF(@Nullable String key) {
861         unparcel();
862         final Object o = mMap.get(key);
863         try {
864             return (SizeF) o;
865         } catch (ClassCastException e) {
866             typeWarning(key, o, "SizeF", e);
867             return null;
868         }
869     }
870 
871     /**
872      * Returns the value associated with the given key, or null if
873      * no mapping of the desired type exists for the given key or a null
874      * value is explicitly associated with the key.
875      *
876      * @param key a String, or null
877      * @return a Bundle value, or null
878      */
879     @Nullable
getBundle(@ullable String key)880     public Bundle getBundle(@Nullable String key) {
881         unparcel();
882         Object o = mMap.get(key);
883         if (o == null) {
884             return null;
885         }
886         try {
887             return (Bundle) o;
888         } catch (ClassCastException e) {
889             typeWarning(key, o, "Bundle", e);
890             return null;
891         }
892     }
893 
894     /**
895      * Returns the value associated with the given key, or {@code null} if
896      * no mapping of the desired type exists for the given key or a {@code null}
897      * value is explicitly associated with the key.
898      *
899      * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
900      * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
901      * Otherwise, this method might throw an exception or return {@code null}.
902      *
903      * @param key a String, or {@code null}
904      * @return a Parcelable value, or {@code null}
905      *
906      * @deprecated Use the type-safer {@link #getParcelable(String, Class)} starting from Android
907      *      {@link Build.VERSION_CODES#TIRAMISU}.
908      */
909     @Deprecated
910     @Nullable
getParcelable(@ullable String key)911     public <T extends Parcelable> T getParcelable(@Nullable String key) {
912         unparcel();
913         Object o = getValue(key);
914         if (o == null) {
915             return null;
916         }
917         try {
918             return (T) o;
919         } catch (ClassCastException e) {
920             typeWarning(key, o, "Parcelable", e);
921             return null;
922         }
923     }
924 
925     /**
926      * Returns the value associated with the given key or {@code null} if:
927      * <ul>
928      *     <li>No mapping of the desired type exists for the given key.
929      *     <li>A {@code null} value is explicitly associated with the key.
930      *     <li>The object is not of type {@code clazz}.
931      * </ul>
932      *
933      * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
934      * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
935      * Otherwise, this method might throw an exception or return {@code null}.
936      *
937      * <p><b>Warning: </b> the class that implements {@link Parcelable} has to be the immediately
938      * enclosing class of the runtime type of its CREATOR field (that is,
939      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
940      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
941      * CREATOR, use the deprecated {@link #getParcelable(String)} instead.
942      *
943      * @param key a String, or {@code null}
944      * @param clazz The type of the object expected
945      * @return a Parcelable value, or {@code null}
946      */
947     @SuppressWarnings("unchecked")
948     @Nullable
getParcelable(@ullable String key, @NonNull Class<T> clazz)949     public <T> T getParcelable(@Nullable String key, @NonNull Class<T> clazz) {
950         // The reason for not using <T extends Parcelable> is because the caller could provide a
951         // super class to restrict the children that doesn't implement Parcelable itself while the
952         // children do, more details at b/210800751 (same reasoning applies here).
953         return get(key, clazz);
954     }
955 
956     /**
957      * Returns the value associated with the given key, or {@code null} if
958      * no mapping of the desired type exists for the given key or a null
959      * value is explicitly associated with the key.
960      *
961      * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
962      * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
963      * Otherwise, this method might throw an exception or return {@code null}.
964      *
965      * @param key a String, or {@code null}
966      * @return a Parcelable[] value, or {@code null}
967      *
968      * @deprecated Use the type-safer {@link #getParcelableArray(String, Class)} starting from
969      *      Android {@link Build.VERSION_CODES#TIRAMISU}.
970      */
971     @Deprecated
972     @Nullable
getParcelableArray(@ullable String key)973     public Parcelable[] getParcelableArray(@Nullable String key) {
974         unparcel();
975         Object o = getValue(key);
976         if (o == null) {
977             return null;
978         }
979         try {
980             return (Parcelable[]) o;
981         } catch (ClassCastException e) {
982             typeWarning(key, o, "Parcelable[]", e);
983             return null;
984         }
985     }
986 
987     /**
988      * Returns the value associated with the given key, or {@code null} if:
989      * <ul>
990      *     <li>No mapping of the desired type exists for the given key.
991      *     <li>A {@code null} value is explicitly associated with the key.
992      *     <li>The object is not of type {@code clazz}.
993      * </ul>
994      *
995      * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
996      * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
997      * Otherwise, this method might throw an exception or return {@code null}.
998      *
999      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
1000      * the class that implements {@link Parcelable} has to be the immediately
1001      * enclosing class of the runtime type of its CREATOR field (that is,
1002      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
1003      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
1004      * CREATOR, use the deprecated {@link #getParcelableArray(String)} instead.
1005      *
1006      * @param key a String, or {@code null}
1007      * @param clazz The type of the items inside the array. This is only verified when unparceling.
1008      * @return a Parcelable[] value, or {@code null}
1009      */
1010     @SuppressLint({"ArrayReturn", "NullableCollection"})
1011     @SuppressWarnings("unchecked")
1012     @Nullable
getParcelableArray(@ullable String key, @NonNull Class<T> clazz)1013     public <T> T[] getParcelableArray(@Nullable String key, @NonNull Class<T> clazz) {
1014         // The reason for not using <T extends Parcelable> is because the caller could provide a
1015         // super class to restrict the children that doesn't implement Parcelable itself while the
1016         // children do, more details at b/210800751 (same reasoning applies here).
1017         unparcel();
1018         try {
1019             // In Java 12, we can pass clazz.arrayType() instead of Parcelable[] and later casting.
1020             return (T[]) getValue(key, Parcelable[].class, requireNonNull(clazz));
1021         } catch (ClassCastException | BadTypeParcelableException e) {
1022             typeWarning(key, clazz.getCanonicalName() + "[]", e);
1023             return null;
1024         }
1025     }
1026 
1027     /**
1028      * Returns the value associated with the given key, or {@code null} if
1029      * no mapping of the desired type exists for the given key or a {@code null}
1030      * value is explicitly associated with the key.
1031      *
1032      * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
1033      * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
1034      * Otherwise, this method might throw an exception or return {@code null}.
1035      *
1036      * @param key a String, or {@code null}
1037      * @return an ArrayList<T> value, or {@code null}
1038      *
1039      * @deprecated Use the type-safer {@link #getParcelable(String, Class)} starting from Android
1040      *      {@link Build.VERSION_CODES#TIRAMISU}.
1041      */
1042     @Deprecated
1043     @Nullable
getParcelableArrayList(@ullable String key)1044     public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) {
1045         unparcel();
1046         Object o = getValue(key);
1047         if (o == null) {
1048             return null;
1049         }
1050         try {
1051             return (ArrayList<T>) o;
1052         } catch (ClassCastException e) {
1053             typeWarning(key, o, "ArrayList", e);
1054             return null;
1055         }
1056     }
1057 
1058     /**
1059      * Returns the value associated with the given key, or {@code null} if:
1060      * <ul>
1061      *     <li>No mapping of the desired type exists for the given key.
1062      *     <li>A {@code null} value is explicitly associated with the key.
1063      *     <li>The object is not of type {@code clazz}.
1064      * </ul>
1065      *
1066      * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
1067      * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
1068      * Otherwise, this method might throw an exception or return {@code null}.
1069      *
1070      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
1071      * the class that implements {@link Parcelable} has to be the immediately
1072      * enclosing class of the runtime type of its CREATOR field (that is,
1073      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
1074      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
1075      * CREATOR, use the deprecated {@link #getParcelableArrayList(String)} instead.
1076      *
1077      * @param key   a String, or {@code null}
1078      * @param clazz The type of the items inside the array list. This is only verified when
1079      *     unparceling.
1080      * @return an ArrayList<T> value, or {@code null}
1081      */
1082     @SuppressLint("NullableCollection")
1083     @SuppressWarnings("unchecked")
1084     @Nullable
getParcelableArrayList(@ullable String key, @NonNull Class<? extends T> clazz)1085     public <T> ArrayList<T> getParcelableArrayList(@Nullable String key,
1086             @NonNull Class<? extends T> clazz) {
1087         // The reason for not using <T extends Parcelable> is because the caller could provide a
1088         // super class to restrict the children that doesn't implement Parcelable itself while the
1089         // children do, more details at b/210800751 (same reasoning applies here).
1090         return getArrayList(key, clazz);
1091     }
1092 
1093     /**
1094      * Returns the value associated with the given key, or null if
1095      * no mapping of the desired type exists for the given key or a null
1096      * value is explicitly associated with the key.
1097      *
1098      * @param key a String, or null
1099      * @return a SparseArray of T values, or null
1100      *
1101      * @deprecated Use the type-safer {@link #getSparseParcelableArray(String, Class)} starting from
1102      *      Android {@link Build.VERSION_CODES#TIRAMISU}.
1103      */
1104     @Deprecated
1105     @Nullable
getSparseParcelableArray(@ullable String key)1106     public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(@Nullable String key) {
1107         unparcel();
1108         Object o = getValue(key);
1109         if (o == null) {
1110             return null;
1111         }
1112         try {
1113             return (SparseArray<T>) o;
1114         } catch (ClassCastException e) {
1115             typeWarning(key, o, "SparseArray", e);
1116             return null;
1117         }
1118     }
1119 
1120     /**
1121      * Returns the value associated with the given key, or {@code null} if:
1122      * <ul>
1123      *     <li>No mapping of the desired type exists for the given key.
1124      *     <li>A {@code null} value is explicitly associated with the key.
1125      *     <li>The object is not of type {@code clazz}.
1126      * </ul>
1127      *
1128      * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface,
1129      * the class that implements {@link Parcelable} has to be the immediately
1130      * enclosing class of the runtime type of its CREATOR field (that is,
1131      * {@link Class#getEnclosingClass()} has to return the parcelable implementing class),
1132      * otherwise this method might throw an exception. If the Parcelable class does not enclose the
1133      * CREATOR, use the deprecated {@link #getSparseParcelableArray(String)} instead.
1134      *
1135      * @param key a String, or null
1136      * @param clazz The type of the items inside the sparse array. This is only verified when
1137      *     unparceling.
1138      * @return a SparseArray of T values, or null
1139      */
1140     @SuppressWarnings("unchecked")
1141     @Nullable
getSparseParcelableArray(@ullable String key, @NonNull Class<? extends T> clazz)1142     public <T> SparseArray<T> getSparseParcelableArray(@Nullable String key,
1143             @NonNull Class<? extends T> clazz) {
1144         // The reason for not using <T extends Parcelable> is because the caller could provide a
1145         // super class to restrict the children that doesn't implement Parcelable itself while the
1146         // children do, more details at b/210800751 (same reasoning applies here).
1147         unparcel();
1148         try {
1149             return (SparseArray<T>) getValue(key, SparseArray.class, requireNonNull(clazz));
1150         } catch (ClassCastException | BadTypeParcelableException e) {
1151             typeWarning(key, "SparseArray<" + clazz.getCanonicalName() + ">", e);
1152             return null;
1153         }
1154     }
1155 
1156     /**
1157      * Returns the value associated with the given key, or null if
1158      * no mapping of the desired type exists for the given key or a null
1159      * value is explicitly associated with the key.
1160      *
1161      * @param key a String, or null
1162      * @return a Serializable value, or null
1163      *
1164      * @deprecated Use the type-safer {@link #getSerializable(String, Class)} starting from Android
1165      *      {@link Build.VERSION_CODES#TIRAMISU}.
1166      */
1167     @Deprecated
1168     @Override
1169     @Nullable
getSerializable(@ullable String key)1170     public Serializable getSerializable(@Nullable String key) {
1171         return super.getSerializable(key);
1172     }
1173 
1174     /**
1175      * Returns the value associated with the given key, or {@code null} if:
1176      * <ul>
1177      *     <li>No mapping of the desired type exists for the given key.
1178      *     <li>A {@code null} value is explicitly associated with the key.
1179      *     <li>The object is not of type {@code clazz}.
1180      * </ul>
1181      *
1182      * @param key   a String, or null
1183      * @param clazz The expected class of the returned type
1184      * @return a Serializable value, or null
1185      */
1186     @Nullable
getSerializable(@ullable String key, @NonNull Class<T> clazz)1187     public <T extends Serializable> T getSerializable(@Nullable String key,
1188             @NonNull Class<T> clazz) {
1189         return super.getSerializable(key, requireNonNull(clazz));
1190     }
1191 
1192     /**
1193      * Returns the value associated with the given key, or null if
1194      * no mapping of the desired type exists for the given key or a null
1195      * value is explicitly associated with the key.
1196      *
1197      * @param key a String, or null
1198      * @return an ArrayList<String> value, or null
1199      */
1200     @Override
1201     @Nullable
getIntegerArrayList(@ullable String key)1202     public ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
1203         return super.getIntegerArrayList(key);
1204     }
1205 
1206     /**
1207      * Returns the value associated with the given key, or null if
1208      * no mapping of the desired type exists for the given key or a null
1209      * value is explicitly associated with the key.
1210      *
1211      * @param key a String, or null
1212      * @return an ArrayList<String> value, or null
1213      */
1214     @Override
1215     @Nullable
getStringArrayList(@ullable String key)1216     public ArrayList<String> getStringArrayList(@Nullable String key) {
1217         return super.getStringArrayList(key);
1218     }
1219 
1220     /**
1221      * Returns the value associated with the given key, or null if
1222      * no mapping of the desired type exists for the given key or a null
1223      * value is explicitly associated with the key.
1224      *
1225      * @param key a String, or null
1226      * @return an ArrayList<CharSequence> value, or null
1227      */
1228     @Override
1229     @Nullable
getCharSequenceArrayList(@ullable String key)1230     public ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) {
1231         return super.getCharSequenceArrayList(key);
1232     }
1233 
1234     /**
1235      * Returns the value associated with the given key, or null if
1236      * no mapping of the desired type exists for the given key or a null
1237      * value is explicitly associated with the key.
1238      *
1239      * @param key a String, or null
1240      * @return a byte[] value, or null
1241      */
1242     @Override
1243     @Nullable
getByteArray(@ullable String key)1244     public byte[] getByteArray(@Nullable String key) {
1245         return super.getByteArray(key);
1246     }
1247 
1248     /**
1249      * Returns the value associated with the given key, or null if
1250      * no mapping of the desired type exists for the given key or a null
1251      * value is explicitly associated with the key.
1252      *
1253      * @param key a String, or null
1254      * @return a short[] value, or null
1255      */
1256     @Override
1257     @Nullable
getShortArray(@ullable String key)1258     public short[] getShortArray(@Nullable String key) {
1259         return super.getShortArray(key);
1260     }
1261 
1262     /**
1263      * Returns the value associated with the given key, or null if
1264      * no mapping of the desired type exists for the given key or a null
1265      * value is explicitly associated with the key.
1266      *
1267      * @param key a String, or null
1268      * @return a char[] value, or null
1269      */
1270     @Override
1271     @Nullable
getCharArray(@ullable String key)1272     public char[] getCharArray(@Nullable String key) {
1273         return super.getCharArray(key);
1274     }
1275 
1276     /**
1277      * Returns the value associated with the given key, or null if
1278      * no mapping of the desired type exists for the given key or a null
1279      * value is explicitly associated with the key.
1280      *
1281      * @param key a String, or null
1282      * @return a float[] value, or null
1283      */
1284     @Override
1285     @Nullable
getFloatArray(@ullable String key)1286     public float[] getFloatArray(@Nullable String key) {
1287         return super.getFloatArray(key);
1288     }
1289 
1290     /**
1291      * Returns the value associated with the given key, or null if
1292      * no mapping of the desired type exists for the given key or a null
1293      * value is explicitly associated with the key.
1294      *
1295      * @param key a String, or null
1296      * @return a CharSequence[] value, or null
1297      */
1298     @Override
1299     @Nullable
getCharSequenceArray(@ullable String key)1300     public CharSequence[] getCharSequenceArray(@Nullable String key) {
1301         return super.getCharSequenceArray(key);
1302     }
1303 
1304     /**
1305      * Returns the value associated with the given key, or null if
1306      * no mapping of the desired type exists for the given key or a null
1307      * value is explicitly associated with the key.
1308      *
1309      * @param key a String, or null
1310      * @return an IBinder value, or null
1311      */
1312     @Nullable
getBinder(@ullable String key)1313     public IBinder getBinder(@Nullable String key) {
1314         unparcel();
1315         Object o = mMap.get(key);
1316         if (o == null) {
1317             return null;
1318         }
1319         try {
1320             return (IBinder) o;
1321         } catch (ClassCastException e) {
1322             typeWarning(key, o, "IBinder", e);
1323             return null;
1324         }
1325     }
1326 
1327     /**
1328      * Returns the value associated with the given key, or null if
1329      * no mapping of the desired type exists for the given key or a null
1330      * value is explicitly associated with the key.
1331      *
1332      * @param key a String, or null
1333      * @return an IBinder value, or null
1334      *
1335      * @deprecated
1336      * @hide This is the old name of the function.
1337      */
1338     @UnsupportedAppUsage
1339     @Deprecated
1340     @Nullable
getIBinder(@ullable String key)1341     public IBinder getIBinder(@Nullable String key) {
1342         unparcel();
1343         Object o = mMap.get(key);
1344         if (o == null) {
1345             return null;
1346         }
1347         try {
1348             return (IBinder) o;
1349         } catch (ClassCastException e) {
1350             typeWarning(key, o, "IBinder", e);
1351             return null;
1352         }
1353     }
1354 
1355     public static final @android.annotation.NonNull Parcelable.Creator<Bundle> CREATOR =
1356         new Parcelable.Creator<Bundle>() {
1357         @Override
1358         public Bundle createFromParcel(Parcel in) {
1359             return in.readBundle();
1360         }
1361 
1362         @Override
1363         public Bundle[] newArray(int size) {
1364             return new Bundle[size];
1365         }
1366     };
1367 
1368     /**
1369      * Report the nature of this Parcelable's contents
1370      */
1371     @Override
describeContents()1372     public int describeContents() {
1373         int mask = 0;
1374         if (hasFileDescriptors()) {
1375             mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
1376         }
1377         return mask;
1378     }
1379 
1380     /**
1381      * Writes the Bundle contents to a Parcel, typically in order for
1382      * it to be passed through an IBinder connection.
1383      * @param parcel The parcel to copy this bundle to.
1384      */
1385     @Override
writeToParcel(Parcel parcel, int flags)1386     public void writeToParcel(Parcel parcel, int flags) {
1387         final boolean oldAllowFds = parcel.pushAllowFds((mFlags & FLAG_ALLOW_FDS) != 0);
1388         try {
1389             writeToParcelInner(parcel, flags);
1390         } finally {
1391             parcel.restoreAllowFds(oldAllowFds);
1392         }
1393     }
1394 
1395     /**
1396      * Reads the Parcel contents into this Bundle, typically in order for
1397      * it to be passed through an IBinder connection.
1398      * @param parcel The parcel to overwrite this bundle from.
1399      */
readFromParcel(Parcel parcel)1400     public void readFromParcel(Parcel parcel) {
1401         readFromParcelInner(parcel);
1402         mFlags = FLAG_ALLOW_FDS;
1403         maybePrefillHasFds();
1404     }
1405 
1406     /**
1407      * Returns a string representation of the {@link Bundle} that may be suitable for debugging. It
1408      * won't print the internal map if its content hasn't been unparcelled.
1409      */
1410     @Override
toString()1411     public synchronized String toString() {
1412         if (mParcelledData != null) {
1413             if (isEmptyParcel()) {
1414                 return "Bundle[EMPTY_PARCEL]";
1415             } else {
1416                 return "Bundle[mParcelledData.dataSize=" +
1417                         mParcelledData.dataSize() + "]";
1418             }
1419         }
1420         return "Bundle[" + mMap.toString() + "]";
1421     }
1422 
1423     /**
1424      * @hide
1425      */
toShortString()1426     public synchronized String toShortString() {
1427         if (mParcelledData != null) {
1428             if (isEmptyParcel()) {
1429                 return "EMPTY_PARCEL";
1430             } else {
1431                 return "mParcelledData.dataSize=" + mParcelledData.dataSize();
1432             }
1433         }
1434         return mMap.toString();
1435     }
1436 
1437     /** @hide */
dumpDebug(ProtoOutputStream proto, long fieldId)1438     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
1439         final long token = proto.start(fieldId);
1440 
1441         if (mParcelledData != null) {
1442             if (isEmptyParcel()) {
1443                 proto.write(BundleProto.PARCELLED_DATA_SIZE, 0);
1444             } else {
1445                 proto.write(BundleProto.PARCELLED_DATA_SIZE, mParcelledData.dataSize());
1446             }
1447         } else {
1448             proto.write(BundleProto.MAP_DATA, mMap.toString());
1449         }
1450 
1451         proto.end(token);
1452     }
1453 }
1454