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