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