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