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