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