1 /* 2 * Copyright (C) 2008 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.cts; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertArrayEquals; 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertNotNull; 25 import static org.junit.Assert.assertNotSame; 26 import static org.junit.Assert.assertNull; 27 import static org.junit.Assert.assertSame; 28 import static org.junit.Assert.assertThrows; 29 import static org.junit.Assert.assertTrue; 30 import static org.junit.Assert.fail; 31 32 import static java.util.Collections.singletonList; 33 34 import android.content.Intent; 35 import android.os.Bundle; 36 import android.os.Parcel; 37 import android.os.ParcelFileDescriptor; 38 import android.os.Parcelable; 39 import android.platform.test.annotations.AppModeSdkSandbox; 40 import android.platform.test.annotations.DisabledOnRavenwood; 41 import android.platform.test.ravenwood.RavenwoodRule; 42 import android.text.Spannable; 43 import android.text.SpannableString; 44 import android.text.style.ForegroundColorSpan; 45 import android.util.SparseArray; 46 47 import org.junit.After; 48 import org.junit.Before; 49 import org.junit.Rule; 50 import org.junit.Test; 51 52 import java.io.File; 53 import java.io.FileDescriptor; 54 import java.io.FileNotFoundException; 55 import java.io.IOException; 56 import java.io.ObjectInputStream; 57 import java.io.Serializable; 58 import java.util.ArrayList; 59 import java.util.Arrays; 60 import java.util.Objects; 61 import java.util.Set; 62 import java.util.concurrent.Callable; 63 64 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).") 65 public class BundleTest { 66 @Rule public RavenwoodRule mRavenwood = new RavenwoodRule(); 67 68 private static final boolean BOOLEANKEYVALUE = false; 69 private static final int INTKEYVALUE = 20; 70 private static final String INTKEY = "intkey"; 71 private static final String BOOLEANKEY = "booleankey"; 72 73 /** Keys should be in hash code order */ 74 private static final String KEY1 = "key1"; 75 private static final String KEY2 = "key2"; 76 77 private Bundle mBundle; 78 private Spannable mSpannable; 79 80 @Before setUp()81 public void setUp() throws Exception { 82 mBundle = new Bundle(); 83 mBundle.setClassLoader(getClass().getClassLoader()); 84 } 85 initSpannable()86 private void initSpannable() { 87 mSpannable = new SpannableString("foo bar"); 88 mSpannable.setSpan(new ForegroundColorSpan(0x123456), 0, 3, 0); 89 } 90 91 @After tearDown()92 public void tearDown() throws Exception { 93 CustomParcelable.sDeserialized = false; 94 CustomSerializable.sDeserialized = false; 95 } 96 97 @Test testBundle()98 public void testBundle() { 99 final Bundle b1 = new Bundle(); 100 assertTrue(b1.isEmpty()); 101 b1.putBoolean(KEY1, true); 102 assertFalse(b1.isEmpty()); 103 104 final Bundle b2 = new Bundle(b1); 105 assertTrue(b2.getBoolean(KEY1)); 106 107 new Bundle(1024); 108 new Bundle(getClass().getClassLoader()); 109 } 110 111 @Test testEmptyStream()112 public void testEmptyStream() { 113 Parcel p = Parcel.obtain(); 114 p.unmarshall(new byte[] {}, 0, 0); 115 Bundle b = p.readBundle(); 116 assertTrue(b.isEmpty()); 117 mBundle.putBoolean("android", true); 118 p.unmarshall(new byte[] {}, 0, 0); 119 mBundle.readFromParcel(p); 120 assertTrue(mBundle.isEmpty()); 121 } 122 123 // first put sth into tested Bundle, it shouldn't be empty, then clear it and it should be empty 124 @Test testClear()125 public void testClear() { 126 mBundle.putBoolean("android", true); 127 mBundle.putBoolean(KEY1, true); 128 assertFalse(mBundle.isEmpty()); 129 mBundle.clear(); 130 assertTrue(mBundle.isEmpty()); 131 } 132 133 // first clone the tested Bundle, then compare the original Bundle with the 134 // cloned Bundle, they should equal 135 @Test testClone()136 public void testClone() { 137 mBundle.putBoolean(BOOLEANKEY, BOOLEANKEYVALUE); 138 mBundle.putInt(INTKEY, INTKEYVALUE); 139 Bundle cloneBundle = (Bundle) mBundle.clone(); 140 assertEquals(mBundle.size(), cloneBundle.size()); 141 assertEquals(mBundle.getBoolean(BOOLEANKEY), cloneBundle.getBoolean(BOOLEANKEY)); 142 assertEquals(mBundle.getInt(INTKEY), cloneBundle.getInt(INTKEY)); 143 } 144 145 // containsKey would return false if nothing has been put into the Bundle, 146 // else containsKey would return true if any putXXX has been called before 147 @Test testContainsKey()148 public void testContainsKey() { 149 assertFalse(mBundle.containsKey(KEY1)); 150 mBundle.putBoolean(KEY1, true); 151 assertTrue(mBundle.containsKey(KEY1)); 152 roundtrip(); 153 assertTrue(mBundle.containsKey(KEY1)); 154 } 155 156 // get would return null if nothing has been put into the Bundle,else get 157 // would return the value set by putXXX 158 @Test testGet()159 public void testGet() { 160 assertNull(mBundle.get(KEY1)); 161 mBundle.putBoolean(KEY1, true); 162 assertNotNull(mBundle.get(KEY1)); 163 roundtrip(); 164 assertNotNull(mBundle.get(KEY1)); 165 } 166 167 @Test testGetBoolean1()168 public void testGetBoolean1() { 169 assertFalse(mBundle.getBoolean(KEY1)); 170 mBundle.putBoolean(KEY1, true); 171 assertTrue(mBundle.getBoolean(KEY1)); 172 roundtrip(); 173 assertTrue(mBundle.getBoolean(KEY1)); 174 } 175 176 @Test testGetBoolean2()177 public void testGetBoolean2() { 178 assertTrue(mBundle.getBoolean(KEY1, true)); 179 mBundle.putBoolean(KEY1, false); 180 assertFalse(mBundle.getBoolean(KEY1, true)); 181 roundtrip(); 182 assertFalse(mBundle.getBoolean(KEY1, true)); 183 } 184 185 @Test testGetBooleanArray()186 public void testGetBooleanArray() { 187 assertNull(mBundle.getBooleanArray(KEY1)); 188 mBundle.putBooleanArray(KEY1, new boolean[] { 189 true, false, true 190 }); 191 boolean[] booleanArray = mBundle.getBooleanArray(KEY1); 192 assertNotNull(booleanArray); 193 assertEquals(3, booleanArray.length); 194 assertEquals(true, booleanArray[0]); 195 assertEquals(false, booleanArray[1]); 196 assertEquals(true, booleanArray[2]); 197 roundtrip(); 198 booleanArray = mBundle.getBooleanArray(KEY1); 199 assertNotNull(booleanArray); 200 assertEquals(3, booleanArray.length); 201 assertEquals(true, booleanArray[0]); 202 assertEquals(false, booleanArray[1]); 203 assertEquals(true, booleanArray[2]); 204 } 205 206 @Test testGetBundle()207 public void testGetBundle() { 208 assertNull(mBundle.getBundle(KEY1)); 209 final Bundle bundle = new Bundle(); 210 mBundle.putBundle(KEY1, bundle); 211 assertTrue(bundle.equals(mBundle.getBundle(KEY1))); 212 roundtrip(); 213 assertBundleEquals(bundle, mBundle.getBundle(KEY1)); 214 } 215 216 @Test testGetByte1()217 public void testGetByte1() { 218 final byte b = 7; 219 220 assertEquals(0, mBundle.getByte(KEY1)); 221 mBundle.putByte(KEY1, b); 222 assertEquals(b, mBundle.getByte(KEY1)); 223 roundtrip(); 224 assertEquals(b, mBundle.getByte(KEY1)); 225 } 226 227 @Test testGetByte2()228 public void testGetByte2() { 229 final byte b1 = 6; 230 final byte b2 = 7; 231 232 assertEquals((Byte)b1, mBundle.getByte(KEY1, b1)); 233 mBundle.putByte(KEY1, b2); 234 assertEquals((Byte)b2, mBundle.getByte(KEY1, b1)); 235 roundtrip(); 236 assertEquals((Byte)b2, mBundle.getByte(KEY1, b1)); 237 } 238 239 @Test testGetByteArray()240 public void testGetByteArray() { 241 assertNull(mBundle.getByteArray(KEY1)); 242 mBundle.putByteArray(KEY1, new byte[] { 243 1, 2, 3 244 }); 245 byte[] byteArray = mBundle.getByteArray(KEY1); 246 assertNotNull(byteArray); 247 assertEquals(3, byteArray.length); 248 assertEquals(1, byteArray[0]); 249 assertEquals(2, byteArray[1]); 250 assertEquals(3, byteArray[2]); 251 roundtrip(); 252 byteArray = mBundle.getByteArray(KEY1); 253 assertNotNull(byteArray); 254 assertEquals(3, byteArray.length); 255 assertEquals(1, byteArray[0]); 256 assertEquals(2, byteArray[1]); 257 assertEquals(3, byteArray[2]); 258 } 259 260 @Test testGetChar1()261 public void testGetChar1() { 262 final char c = 'l'; 263 264 assertEquals((char)0, mBundle.getChar(KEY1)); 265 mBundle.putChar(KEY1, c); 266 assertEquals(c, mBundle.getChar(KEY1)); 267 roundtrip(); 268 assertEquals(c, mBundle.getChar(KEY1)); 269 } 270 271 @Test testGetChar2()272 public void testGetChar2() { 273 final char c1 = 'l'; 274 final char c2 = 'i'; 275 276 assertEquals(c1, mBundle.getChar(KEY1, c1)); 277 mBundle.putChar(KEY1, c2); 278 assertEquals(c2, mBundle.getChar(KEY1, c1)); 279 roundtrip(); 280 assertEquals(c2, mBundle.getChar(KEY1, c1)); 281 } 282 283 @Test testGetCharArray()284 public void testGetCharArray() { 285 assertNull(mBundle.getCharArray(KEY1)); 286 mBundle.putCharArray(KEY1, new char[] { 287 'h', 'i' 288 }); 289 char[] charArray = mBundle.getCharArray(KEY1); 290 assertEquals('h', charArray[0]); 291 assertEquals('i', charArray[1]); 292 roundtrip(); 293 charArray = mBundle.getCharArray(KEY1); 294 assertEquals('h', charArray[0]); 295 assertEquals('i', charArray[1]); 296 } 297 298 @Test 299 @DisabledOnRavenwood(blockedBy = SpannableString.class) testGetCharSequence()300 public void testGetCharSequence() { 301 initSpannable(); 302 final CharSequence cS = "Bruce Lee"; 303 304 assertNull(mBundle.getCharSequence(KEY1)); 305 assertNull(mBundle.getCharSequence(KEY2)); 306 mBundle.putCharSequence(KEY1, cS); 307 mBundle.putCharSequence(KEY2, mSpannable); 308 assertEquals(cS, mBundle.getCharSequence(KEY1)); 309 assertSpannableEquals(mSpannable, mBundle.getCharSequence(KEY2)); 310 roundtrip(); 311 assertEquals(cS, mBundle.getCharSequence(KEY1)); 312 assertSpannableEquals(mSpannable, mBundle.getCharSequence(KEY2)); 313 } 314 315 @Test 316 @DisabledOnRavenwood(blockedBy = SpannableString.class) testGetCharSequenceArray()317 public void testGetCharSequenceArray() { 318 initSpannable(); 319 assertNull(mBundle.getCharSequenceArray(KEY1)); 320 mBundle.putCharSequenceArray(KEY1, new CharSequence[] { 321 "one", "two", "three", mSpannable 322 }); 323 CharSequence[] ret = mBundle.getCharSequenceArray(KEY1); 324 assertEquals(4, ret.length); 325 assertEquals("one", ret[0]); 326 assertEquals("two", ret[1]); 327 assertEquals("three", ret[2]); 328 assertSpannableEquals(mSpannable, ret[3]); 329 roundtrip(); 330 ret = mBundle.getCharSequenceArray(KEY1); 331 assertEquals(4, ret.length); 332 assertEquals("one", ret[0]); 333 assertEquals("two", ret[1]); 334 assertEquals("three", ret[2]); 335 assertSpannableEquals(mSpannable, ret[3]); 336 } 337 338 @Test 339 @DisabledOnRavenwood(blockedBy = SpannableString.class) testGetCharSequenceArrayList()340 public void testGetCharSequenceArrayList() { 341 initSpannable(); 342 assertNull(mBundle.getCharSequenceArrayList(KEY1)); 343 final ArrayList<CharSequence> list = new ArrayList<CharSequence>(); 344 list.add("one"); 345 list.add("two"); 346 list.add("three"); 347 list.add(mSpannable); 348 mBundle.putCharSequenceArrayList(KEY1, list); 349 roundtrip(); 350 ArrayList<CharSequence> ret = mBundle.getCharSequenceArrayList(KEY1); 351 assertEquals(4, ret.size()); 352 assertEquals("one", ret.get(0)); 353 assertEquals("two", ret.get(1)); 354 assertEquals("three", ret.get(2)); 355 assertSpannableEquals(mSpannable, ret.get(3)); 356 roundtrip(); 357 ret = mBundle.getCharSequenceArrayList(KEY1); 358 assertEquals(4, ret.size()); 359 assertEquals("one", ret.get(0)); 360 assertEquals("two", ret.get(1)); 361 assertEquals("three", ret.get(2)); 362 assertSpannableEquals(mSpannable, ret.get(3)); 363 } 364 365 @Test testGetDouble1()366 public void testGetDouble1() { 367 final double d = 10.07; 368 369 assertEquals(0.0, mBundle.getDouble(KEY1), 0.0); 370 mBundle.putDouble(KEY1, d); 371 assertEquals(d, mBundle.getDouble(KEY1), 0.0); 372 roundtrip(); 373 assertEquals(d, mBundle.getDouble(KEY1), 0.0); 374 } 375 376 @Test testGetDouble2()377 public void testGetDouble2() { 378 final double d1 = 10.06; 379 final double d2 = 10.07; 380 381 assertEquals(d1, mBundle.getDouble(KEY1, d1), 0.0); 382 mBundle.putDouble(KEY1, d2); 383 assertEquals(d2, mBundle.getDouble(KEY1, d1), 0.0); 384 roundtrip(); 385 assertEquals(d2, mBundle.getDouble(KEY1, d1), 0.0); 386 } 387 388 @Test testGetDoubleArray()389 public void testGetDoubleArray() { 390 assertNull(mBundle.getDoubleArray(KEY1)); 391 mBundle.putDoubleArray(KEY1, new double[] { 392 10.06, 10.07 393 }); 394 double[] doubleArray = mBundle.getDoubleArray(KEY1); 395 assertEquals(10.06, doubleArray[0], 0.0); 396 assertEquals(10.07, doubleArray[1], 0.0); 397 roundtrip(); 398 doubleArray = mBundle.getDoubleArray(KEY1); 399 assertEquals(10.06, doubleArray[0], 0.0); 400 assertEquals(10.07, doubleArray[1], 0.0); 401 } 402 403 @Test testGetFloat1()404 public void testGetFloat1() { 405 final float f = 10.07f; 406 407 assertEquals(0.0f, mBundle.getFloat(KEY1), 0.0f); 408 mBundle.putFloat(KEY1, f); 409 assertEquals(f, mBundle.getFloat(KEY1), 0.0f); 410 roundtrip(); 411 assertEquals(f, mBundle.getFloat(KEY1), 0.0f); 412 } 413 414 @Test testGetFloat2()415 public void testGetFloat2() { 416 final float f1 = 10.06f; 417 final float f2 = 10.07f; 418 419 assertEquals(f1, mBundle.getFloat(KEY1, f1), 0.0f); 420 mBundle.putFloat(KEY1, f2); 421 assertEquals(f2, mBundle.getFloat(KEY1, f1), 0.0f); 422 roundtrip(); 423 assertEquals(f2, mBundle.getFloat(KEY1, f1), 0.0f); 424 } 425 426 @Test testGetFloatArray()427 public void testGetFloatArray() { 428 assertNull(mBundle.getFloatArray(KEY1)); 429 mBundle.putFloatArray(KEY1, new float[] { 430 10.06f, 10.07f 431 }); 432 float[] floatArray = mBundle.getFloatArray(KEY1); 433 assertEquals(10.06f, floatArray[0], 0.0f); 434 assertEquals(10.07f, floatArray[1], 0.0f); 435 roundtrip(); 436 floatArray = mBundle.getFloatArray(KEY1); 437 assertEquals(10.06f, floatArray[0], 0.0f); 438 assertEquals(10.07f, floatArray[1], 0.0f); 439 } 440 441 @Test testGetInt1()442 public void testGetInt1() { 443 final int i = 1007; 444 445 assertEquals(0, mBundle.getInt(KEY1)); 446 mBundle.putInt(KEY1, i); 447 assertEquals(i, mBundle.getInt(KEY1)); 448 roundtrip(); 449 assertEquals(i, mBundle.getInt(KEY1)); 450 } 451 452 @Test testGetInt2()453 public void testGetInt2() { 454 final int i1 = 1006; 455 final int i2 = 1007; 456 457 assertEquals(i1, mBundle.getInt(KEY1, i1)); 458 mBundle.putInt(KEY1, i2); 459 assertEquals(i2, mBundle.getInt(KEY1, i2)); 460 roundtrip(); 461 assertEquals(i2, mBundle.getInt(KEY1, i2)); 462 } 463 464 @Test testGetIntArray()465 public void testGetIntArray() { 466 assertNull(mBundle.getIntArray(KEY1)); 467 mBundle.putIntArray(KEY1, new int[] { 468 1006, 1007 469 }); 470 int[] intArray = mBundle.getIntArray(KEY1); 471 assertEquals(1006, intArray[0]); 472 assertEquals(1007, intArray[1]); 473 roundtrip(); 474 intArray = mBundle.getIntArray(KEY1); 475 assertEquals(1006, intArray[0]); 476 assertEquals(1007, intArray[1]); 477 } 478 479 // getIntegerArrayList should only return the IntegerArrayList set by putIntegerArrayLis 480 @Test testGetIntegerArrayList()481 public void testGetIntegerArrayList() { 482 final int i1 = 1006; 483 final int i2 = 1007; 484 485 assertNull(mBundle.getIntegerArrayList(KEY1)); 486 final ArrayList<Integer> arrayList = new ArrayList<Integer>(); 487 arrayList.add(i1); 488 arrayList.add(i2); 489 mBundle.putIntegerArrayList(KEY1, arrayList); 490 ArrayList<Integer> retArrayList = mBundle.getIntegerArrayList(KEY1); 491 assertNotNull(retArrayList); 492 assertEquals(2, retArrayList.size()); 493 assertEquals((Integer)i1, retArrayList.get(0)); 494 assertEquals((Integer)i2, retArrayList.get(1)); 495 roundtrip(); 496 retArrayList = mBundle.getIntegerArrayList(KEY1); 497 assertNotNull(retArrayList); 498 assertEquals(2, retArrayList.size()); 499 assertEquals((Integer)i1, retArrayList.get(0)); 500 assertEquals((Integer)i2, retArrayList.get(1)); 501 } 502 503 @Test testGetLong1()504 public void testGetLong1() { 505 final long l = 1007; 506 507 assertEquals(0, mBundle.getLong(KEY1)); 508 mBundle.putLong(KEY1, l); 509 assertEquals(l, mBundle.getLong(KEY1)); 510 roundtrip(); 511 assertEquals(l, mBundle.getLong(KEY1)); 512 } 513 514 @Test testGetLong2()515 public void testGetLong2() { 516 final long l1 = 1006; 517 final long l2 = 1007; 518 519 assertEquals(l1, mBundle.getLong(KEY1, l1)); 520 mBundle.putLong(KEY1, l2); 521 assertEquals(l2, mBundle.getLong(KEY1, l2)); 522 roundtrip(); 523 assertEquals(l2, mBundle.getLong(KEY1, l2)); 524 } 525 526 @Test testGetLongArray()527 public void testGetLongArray() { 528 assertNull(mBundle.getLongArray(KEY1)); 529 mBundle.putLongArray(KEY1, new long[] { 530 1006, 1007 531 }); 532 long[] longArray = mBundle.getLongArray(KEY1); 533 assertEquals(1006, longArray[0]); 534 assertEquals(1007, longArray[1]); 535 roundtrip(); 536 longArray = mBundle.getLongArray(KEY1); 537 assertEquals(1006, longArray[0]); 538 assertEquals(1007, longArray[1]); 539 } 540 541 @Test testGetParcelable()542 public void testGetParcelable() { 543 assertNull(mBundle.getParcelable(KEY1)); 544 final Bundle bundle = new Bundle(); 545 mBundle.putParcelable(KEY1, bundle); 546 assertTrue(bundle.equals(mBundle.getParcelable(KEY1))); 547 roundtrip(); 548 assertBundleEquals(bundle, (Bundle) mBundle.getParcelable(KEY1)); 549 } 550 551 @Test testGetParcelableTypeSafe_withMismatchingType_returnsNull()552 public void testGetParcelableTypeSafe_withMismatchingType_returnsNull() { 553 mBundle.putParcelable(KEY1, new CustomParcelable(42, "don't panic")); 554 roundtrip(); 555 assertNull(mBundle.getParcelable(KEY1, Intent.class)); 556 assertFalse(CustomParcelable.sDeserialized); 557 } 558 559 @Test testGetParcelableTypeSafe_withMatchingType_returnsObject()560 public void testGetParcelableTypeSafe_withMatchingType_returnsObject() { 561 final CustomParcelable original = new CustomParcelable(42, "don't panic"); 562 mBundle.putParcelable(KEY1, original); 563 roundtrip(); 564 assertEquals(original, mBundle.getParcelable(KEY1, CustomParcelable.class)); 565 } 566 567 @Test testGetParcelableTypeSafe_withBaseType_returnsObject()568 public void testGetParcelableTypeSafe_withBaseType_returnsObject() { 569 final CustomParcelable original = new CustomParcelable(42, "don't panic"); 570 mBundle.putParcelable(KEY1, original); 571 roundtrip(); 572 assertEquals(original, mBundle.getParcelable(KEY1, Parcelable.class)); 573 } 574 575 // getParcelableArray should only return the ParcelableArray set by putParcelableArray 576 @Test testGetParcelableArray()577 public void testGetParcelableArray() { 578 assertNull(mBundle.getParcelableArray(KEY1)); 579 final Bundle bundle1 = new Bundle(); 580 final Bundle bundle2 = new Bundle(); 581 mBundle.putParcelableArray(KEY1, new Bundle[] { 582 bundle1, bundle2 583 }); 584 Parcelable[] parcelableArray = mBundle.getParcelableArray(KEY1); 585 assertEquals(2, parcelableArray.length); 586 assertTrue(bundle1.equals(parcelableArray[0])); 587 assertTrue(bundle2.equals(parcelableArray[1])); 588 roundtrip(); 589 parcelableArray = mBundle.getParcelableArray(KEY1); 590 assertEquals(2, parcelableArray.length); 591 assertBundleEquals(bundle1, (Bundle) parcelableArray[0]); 592 assertBundleEquals(bundle2, (Bundle) parcelableArray[1]); 593 } 594 595 @Test testGetParcelableArrayTypeSafe_withMismatchingType_returnsNull()596 public void testGetParcelableArrayTypeSafe_withMismatchingType_returnsNull() { 597 mBundle.putParcelableArray(KEY1, new CustomParcelable[] { 598 new CustomParcelable(42, "don't panic") 599 }); 600 roundtrip(); 601 assertNull(mBundle.getParcelableArray(KEY1, Intent.class)); 602 assertFalse(CustomParcelable.sDeserialized); 603 } 604 605 @Test testGetParcelableArrayTypeSafe_withMatchingType_returnsObject()606 public void testGetParcelableArrayTypeSafe_withMatchingType_returnsObject() { 607 final CustomParcelable[] original = new CustomParcelable[] { 608 new CustomParcelable(42, "don't panic"), 609 new CustomParcelable(1961, "off we go") 610 }; 611 mBundle.putParcelableArray(KEY1, original); 612 roundtrip(); 613 assertArrayEquals(original, mBundle.getParcelableArray(KEY1, CustomParcelable.class)); 614 } 615 616 @Test testGetParcelableArrayTypeSafe_withBaseType_returnsObject()617 public void testGetParcelableArrayTypeSafe_withBaseType_returnsObject() { 618 final CustomParcelable[] original = new CustomParcelable[] { 619 new CustomParcelable(42, "don't panic"), 620 new CustomParcelable(1961, "off we go") 621 }; 622 mBundle.putParcelableArray(KEY1, original); 623 roundtrip(); 624 assertArrayEquals(original, mBundle.getParcelableArray(KEY1, Parcelable.class)); 625 } 626 627 // getParcelableArrayList should only return the parcelableArrayList set by putParcelableArrayList 628 @Test testGetParcelableArrayList()629 public void testGetParcelableArrayList() { 630 assertNull(mBundle.getParcelableArrayList(KEY1)); 631 final ArrayList<Parcelable> parcelableArrayList = new ArrayList<Parcelable>(); 632 final Bundle bundle1 = new Bundle(); 633 final Bundle bundle2 = new Bundle(); 634 parcelableArrayList.add(bundle1); 635 parcelableArrayList.add(bundle2); 636 mBundle.putParcelableArrayList(KEY1, parcelableArrayList); 637 ArrayList<Parcelable> ret = mBundle.getParcelableArrayList(KEY1); 638 assertEquals(2, ret.size()); 639 assertTrue(bundle1.equals(ret.get(0))); 640 assertTrue(bundle2.equals(ret.get(1))); 641 roundtrip(); 642 ret = mBundle.getParcelableArrayList(KEY1); 643 assertEquals(2, ret.size()); 644 assertBundleEquals(bundle1, (Bundle) ret.get(0)); 645 assertBundleEquals(bundle2, (Bundle) ret.get(1)); 646 } 647 648 @Test testGetParcelableArrayListTypeSafe_withMismatchingType_returnsNull()649 public void testGetParcelableArrayListTypeSafe_withMismatchingType_returnsNull() { 650 final ArrayList<CustomParcelable> originalObjects = new ArrayList<>(); 651 originalObjects.add(new CustomParcelable(42, "don't panic")); 652 mBundle.putParcelableArrayList(KEY1, originalObjects); 653 roundtrip(); 654 assertNull(mBundle.getParcelableArrayList(KEY1, Intent.class)); 655 assertFalse(CustomParcelable.sDeserialized); 656 } 657 658 @Test testGetParcelableArrayListTypeSafe_withMatchingType_returnsObject()659 public void testGetParcelableArrayListTypeSafe_withMatchingType_returnsObject() { 660 final ArrayList<CustomParcelable> original = new ArrayList<>(); 661 original.add(new CustomParcelable(42, "don't panic")); 662 original.add(new CustomParcelable(1961, "off we go")); 663 mBundle.putParcelableArrayList(KEY1, original); 664 roundtrip(); 665 assertEquals(original, mBundle.getParcelableArrayList(KEY1, CustomParcelable.class)); 666 } 667 668 @Test testGetParcelableArrayListTypeSafe_withMismatchingTypeAndDifferentReturnType_returnsNull()669 public void testGetParcelableArrayListTypeSafe_withMismatchingTypeAndDifferentReturnType_returnsNull() { 670 final ArrayList<CustomParcelable> originalObjects = new ArrayList<>(); 671 originalObjects.add(new CustomParcelable(42, "don't panic")); 672 mBundle.putParcelableArrayList(KEY1, originalObjects); 673 roundtrip(); 674 ArrayList<Parcelable> result = mBundle.getParcelableArrayList(KEY1, Intent.class); 675 assertNull(result); 676 assertFalse(CustomParcelable.sDeserialized); 677 } 678 679 @Test testGetParcelableArrayListTypeSafe_withMatchingTypeAndDifferentReturnType__returnsObject()680 public void testGetParcelableArrayListTypeSafe_withMatchingTypeAndDifferentReturnType__returnsObject() { 681 final ArrayList<CustomParcelable> original = new ArrayList<>(); 682 original.add(new CustomParcelable(42, "don't panic")); 683 original.add(new CustomParcelable(1961, "off we go")); 684 mBundle.putParcelableArrayList(KEY1, original); 685 roundtrip(); 686 ArrayList<Parcelable> result = mBundle.getParcelableArrayList(KEY1, CustomParcelable.class); 687 assertEquals(original, result); 688 } 689 690 @Test testGetParcelableArrayListTypeSafe_withBaseType_returnsObject()691 public void testGetParcelableArrayListTypeSafe_withBaseType_returnsObject() { 692 final ArrayList<CustomParcelable> original = new ArrayList<>(); 693 original.add(new CustomParcelable(42, "don't panic")); 694 original.add(new CustomParcelable(1961, "off we go")); 695 mBundle.putParcelableArrayList(KEY1, original); 696 roundtrip(); 697 assertEquals(original, mBundle.getParcelableArrayList(KEY1, Parcelable.class)); 698 } 699 700 @Test testGetSerializableTypeSafe_withMismatchingType_returnsNull()701 public void testGetSerializableTypeSafe_withMismatchingType_returnsNull() { 702 mBundle.putSerializable(KEY1, new CustomSerializable()); 703 roundtrip(); 704 assertNull(mBundle.getSerializable(KEY1, AnotherSerializable.class)); 705 assertFalse(CustomSerializable.sDeserialized); 706 } 707 708 @Test testGetSerializableTypeSafe_withMatchingType_returnsObject()709 public void testGetSerializableTypeSafe_withMatchingType_returnsObject() { 710 mBundle.putSerializable(KEY1, new CustomSerializable()); 711 roundtrip(); 712 assertNotNull(mBundle.getSerializable(KEY1, CustomSerializable.class)); 713 assertTrue(CustomSerializable.sDeserialized); 714 } 715 716 @Test testGetSerializableTypeSafe_withBaseType_returnsObject()717 public void testGetSerializableTypeSafe_withBaseType_returnsObject() { 718 mBundle.putSerializable(KEY1, new CustomSerializable()); 719 roundtrip(); 720 assertNotNull(mBundle.getSerializable(KEY1, Serializable.class)); 721 assertTrue(CustomSerializable.sDeserialized); 722 } 723 724 @Test testGetSerializableWithString()725 public void testGetSerializableWithString() { 726 assertNull(mBundle.getSerializable(KEY1)); 727 String s = "android"; 728 mBundle.putSerializable(KEY1, s); 729 assertEquals(s, mBundle.getSerializable(KEY1)); 730 roundtrip(); 731 assertEquals(s, mBundle.getSerializable(KEY1)); 732 } 733 734 @Test testGetSerializableWithStringArray()735 public void testGetSerializableWithStringArray() { 736 assertNull(mBundle.getSerializable(KEY1)); 737 String[] strings = new String[]{"first", "last"}; 738 mBundle.putSerializable(KEY1, strings); 739 assertEquals(Arrays.asList(strings), 740 Arrays.asList((String[]) mBundle.getSerializable(KEY1))); 741 roundtrip(); 742 assertEquals(Arrays.asList(strings), 743 Arrays.asList((String[]) mBundle.getSerializable(KEY1))); 744 } 745 746 @Test testGetSerializableWithMultiDimensionalObjectArray()747 public void testGetSerializableWithMultiDimensionalObjectArray() { 748 assertNull(mBundle.getSerializable(KEY1)); 749 Object[][] objects = new Object[][] { 750 {"string", 1L} 751 }; 752 mBundle.putSerializable(KEY1, objects); 753 assertEquals(Arrays.asList(objects[0]), 754 Arrays.asList(((Object[][]) mBundle.getSerializable(KEY1))[0])); 755 roundtrip(); 756 assertEquals(Arrays.asList(objects[0]), 757 Arrays.asList(((Object[][]) mBundle.getSerializable(KEY1))[0])); 758 } 759 760 @Test testGetShort1()761 public void testGetShort1() { 762 final short s = 1007; 763 764 assertEquals(0, mBundle.getShort(KEY1)); 765 mBundle.putShort(KEY1, s); 766 assertEquals(s, mBundle.getShort(KEY1)); 767 roundtrip(); 768 assertEquals(s, mBundle.getShort(KEY1)); 769 } 770 771 @Test testGetShort2()772 public void testGetShort2() { 773 final short s1 = 1006; 774 final short s2 = 1007; 775 776 assertEquals(s1, mBundle.getShort(KEY1, s1)); 777 mBundle.putShort(KEY1, s2); 778 assertEquals(s2, mBundle.getShort(KEY1, s1)); 779 roundtrip(); 780 assertEquals(s2, mBundle.getShort(KEY1, s1)); 781 } 782 783 @Test testGetShortArray()784 public void testGetShortArray() { 785 final short s1 = 1006; 786 final short s2 = 1007; 787 788 assertNull(mBundle.getShortArray(KEY1)); 789 mBundle.putShortArray(KEY1, new short[] { 790 s1, s2 791 }); 792 short[] shortArray = mBundle.getShortArray(KEY1); 793 assertEquals(s1, shortArray[0]); 794 assertEquals(s2, shortArray[1]); 795 roundtrip(); 796 shortArray = mBundle.getShortArray(KEY1); 797 assertEquals(s1, shortArray[0]); 798 assertEquals(s2, shortArray[1]); 799 } 800 801 // getSparseParcelableArray should only return the SparseArray<Parcelable> 802 // set by putSparseParcelableArray 803 @Test testGetSparseParcelableArray()804 public void testGetSparseParcelableArray() { 805 assertNull(mBundle.getSparseParcelableArray(KEY1)); 806 final SparseArray<Parcelable> sparseArray = new SparseArray<Parcelable>(); 807 final Bundle bundle = new Bundle(); 808 final CustomParcelable custom = new CustomParcelable(42, "example"); 809 sparseArray.put(1006, bundle); 810 sparseArray.put(1007, custom); 811 mBundle.putSparseParcelableArray(KEY1, sparseArray); 812 SparseArray<Parcelable> ret = mBundle.getSparseParcelableArray(KEY1); 813 assertEquals(2, ret.size()); 814 assertNull(ret.get(1008)); 815 assertTrue(bundle.equals(ret.get(1006))); 816 assertTrue(custom.equals(ret.get(1007))); 817 roundtrip(); 818 ret = mBundle.getSparseParcelableArray(KEY1); 819 assertEquals(2, ret.size()); 820 assertNull(ret.get(1008)); 821 assertBundleEquals(bundle, (Bundle) ret.get(1006)); 822 assertEquals(custom, (CustomParcelable) ret.get(1007)); 823 } 824 825 @Test testGetSparseParcelableArrayTypeSafe_withMismatchingType_returnsNull()826 public void testGetSparseParcelableArrayTypeSafe_withMismatchingType_returnsNull() { 827 final SparseArray<CustomParcelable> originalObjects = new SparseArray<>(); 828 originalObjects.put(42, new CustomParcelable(42, "don't panic")); 829 mBundle.putSparseParcelableArray(KEY1, originalObjects); 830 roundtrip(); 831 assertNull(mBundle.getSparseParcelableArray(KEY1, Intent.class)); 832 assertFalse(CustomParcelable.sDeserialized); 833 } 834 835 @Test testGetSparseParcelableArrayTypeSafe_withMatchingType_returnsObject()836 public void testGetSparseParcelableArrayTypeSafe_withMatchingType_returnsObject() { 837 final SparseArray<CustomParcelable> original = new SparseArray<>(); 838 original.put(42, new CustomParcelable(42, "don't panic")); 839 original.put(1961, new CustomParcelable(1961, "off we go")); 840 mBundle.putSparseParcelableArray(KEY1, original); 841 roundtrip(); 842 assertTrue(original.contentEquals(mBundle.getSparseParcelableArray(KEY1, CustomParcelable.class))); 843 } 844 845 @Test testGetSparseParcelableArrayTypeSafe_withMismatchingTypeAndDifferentReturnType_returnsNull()846 public void testGetSparseParcelableArrayTypeSafe_withMismatchingTypeAndDifferentReturnType_returnsNull() { 847 final SparseArray<CustomParcelable> originalObjects = new SparseArray<>(); 848 originalObjects.put(42, new CustomParcelable(42, "don't panic")); 849 mBundle.putSparseParcelableArray(KEY1, originalObjects); 850 roundtrip(); 851 SparseArray<Parcelable> result = mBundle.getSparseParcelableArray(KEY1, Intent.class); 852 assertNull(result); 853 assertFalse(CustomParcelable.sDeserialized); 854 } 855 856 @Test testGetSparseParcelableArrayTypeSafe_withMatchingTypeAndDifferentReturnType_returnsObject()857 public void testGetSparseParcelableArrayTypeSafe_withMatchingTypeAndDifferentReturnType_returnsObject() { 858 final SparseArray<CustomParcelable> original = new SparseArray<>(); 859 original.put(42, new CustomParcelable(42, "don't panic")); 860 original.put(1961, new CustomParcelable(1961, "off we go")); 861 mBundle.putSparseParcelableArray(KEY1, original); 862 roundtrip(); 863 SparseArray<Parcelable> result = mBundle.getSparseParcelableArray(KEY1, 864 CustomParcelable.class); 865 assertTrue(original.contentEquals(result)); 866 } 867 868 @Test testGetSparseParcelableArrayTypeSafe_withBaseType_returnsObject()869 public void testGetSparseParcelableArrayTypeSafe_withBaseType_returnsObject() { 870 final SparseArray<CustomParcelable> original = new SparseArray<>(); 871 original.put(42, new CustomParcelable(42, "don't panic")); 872 original.put(1961, new CustomParcelable(1961, "off we go")); 873 mBundle.putSparseParcelableArray(KEY1, original); 874 roundtrip(); 875 assertTrue(original.contentEquals(mBundle.getSparseParcelableArray(KEY1, Parcelable.class))); 876 } 877 878 @Test testGetSparseParcelableArrayTypeSafe_withMixedTypes_returnsObject()879 public void testGetSparseParcelableArrayTypeSafe_withMixedTypes_returnsObject() { 880 final SparseArray<Parcelable> original = new SparseArray<>(); 881 original.put(42, new CustomParcelable(42, "don't panic")); 882 original.put(1961, new ComposedParcelable(21, new CustomParcelable(21, "off we go"))); 883 mBundle.putSparseParcelableArray(KEY1, original); 884 roundtrip(); 885 final SparseArray<Parcelable> received = mBundle.getSparseParcelableArray(KEY1, Parcelable.class); 886 assertEquals(original.size(), received.size()); 887 assertEquals(original.get(42), received.get(42)); 888 assertEquals((ComposedParcelable) original.get(1961), 889 (ComposedParcelable) received.get(1961)); 890 } 891 892 @Test testGetString()893 public void testGetString() { 894 assertNull(mBundle.getString(KEY1)); 895 mBundle.putString(KEY1, "android"); 896 assertEquals("android", mBundle.getString(KEY1)); 897 roundtrip(); 898 assertEquals("android", mBundle.getString(KEY1)); 899 } 900 901 @Test testGetStringArray()902 public void testGetStringArray() { 903 assertNull(mBundle.getStringArray(KEY1)); 904 mBundle.putStringArray(KEY1, new String[] { 905 "one", "two", "three" 906 }); 907 String[] ret = mBundle.getStringArray(KEY1); 908 assertEquals("one", ret[0]); 909 assertEquals("two", ret[1]); 910 assertEquals("three", ret[2]); 911 roundtrip(); 912 ret = mBundle.getStringArray(KEY1); 913 assertEquals("one", ret[0]); 914 assertEquals("two", ret[1]); 915 assertEquals("three", ret[2]); 916 } 917 918 // getStringArrayList should only return the StringArrayList set by putStringArrayList 919 @Test testGetStringArrayList()920 public void testGetStringArrayList() { 921 assertNull(mBundle.getStringArrayList(KEY1)); 922 final ArrayList<String> stringArrayList = new ArrayList<String>(); 923 stringArrayList.add("one"); 924 stringArrayList.add("two"); 925 stringArrayList.add("three"); 926 mBundle.putStringArrayList(KEY1, stringArrayList); 927 ArrayList<String> ret = mBundle.getStringArrayList(KEY1); 928 assertEquals(3, ret.size()); 929 assertEquals("one", ret.get(0)); 930 assertEquals("two", ret.get(1)); 931 assertEquals("three", ret.get(2)); 932 roundtrip(); 933 ret = mBundle.getStringArrayList(KEY1); 934 assertEquals(3, ret.size()); 935 assertEquals("one", ret.get(0)); 936 assertEquals("two", ret.get(1)); 937 assertEquals("three", ret.get(2)); 938 } 939 940 @Test testKeySet()941 public void testKeySet() { 942 Set<String> setKey = mBundle.keySet(); 943 assertFalse(setKey.contains("one")); 944 assertFalse(setKey.contains("two")); 945 mBundle.putBoolean("one", true); 946 mBundle.putChar("two", 't'); 947 setKey = mBundle.keySet(); 948 assertEquals(2, setKey.size()); 949 assertTrue(setKey.contains("one")); 950 assertTrue(setKey.contains("two")); 951 assertFalse(setKey.contains("three")); 952 roundtrip(); 953 setKey = mBundle.keySet(); 954 assertEquals(2, setKey.size()); 955 assertTrue(setKey.contains("one")); 956 assertTrue(setKey.contains("two")); 957 assertFalse(setKey.contains("three")); 958 } 959 960 // same as hasFileDescriptors, the only difference is that describeContents 961 // return 0 if no fd and return 1 if has fd for the tested Bundle 962 963 @Test testDescribeContents()964 public void testDescribeContents() { 965 assertTrue((mBundle.describeContents() 966 & Parcelable.CONTENTS_FILE_DESCRIPTOR) == 0); 967 968 final Parcel parcel = Parcel.obtain(); 969 try { 970 mBundle.putParcelable("foo", ParcelFileDescriptor.open( 971 new File("/dev/zero"), ParcelFileDescriptor.MODE_READ_ONLY)); 972 } catch (FileNotFoundException e) { 973 throw new RuntimeException("can't open /dev/zero", e); 974 } 975 assertTrue((mBundle.describeContents() 976 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0); 977 mBundle.writeToParcel(parcel, 0); 978 mBundle.clear(); 979 assertTrue((mBundle.describeContents() 980 & Parcelable.CONTENTS_FILE_DESCRIPTOR) == 0); 981 parcel.setDataPosition(0); 982 mBundle.readFromParcel(parcel); 983 assertTrue((mBundle.describeContents() 984 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0); 985 ParcelFileDescriptor pfd = (ParcelFileDescriptor)mBundle.getParcelable("foo"); 986 assertTrue((mBundle.describeContents() 987 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0); 988 } 989 990 // case 1: The default bundle doesn't has FileDescriptor. 991 // case 2: The tested Bundle should has FileDescriptor 992 // if it read data from a Parcel object, which is created with a FileDescriptor. 993 // case 3: The tested Bundle should has FileDescriptor 994 // if put a Parcelable object, which is created with a FileDescriptor, into it. 995 @Test testHasFileDescriptors_withParcelFdItem()996 public void testHasFileDescriptors_withParcelFdItem() { 997 assertFalse(mBundle.hasFileDescriptors()); 998 999 final Parcel parcel = Parcel.obtain(); 1000 assertFalse(parcel.hasFileDescriptors()); 1001 try { 1002 mBundle.putParcelable("foo", ParcelFileDescriptor.open( 1003 new File("/dev/zero"), ParcelFileDescriptor.MODE_READ_ONLY)); 1004 } catch (FileNotFoundException e) { 1005 throw new RuntimeException("can't open /dev/zero", e); 1006 } 1007 assertTrue(mBundle.hasFileDescriptors()); 1008 mBundle.writeToParcel(parcel, 0); 1009 assertTrue(parcel.hasFileDescriptors()); 1010 mBundle.clear(); 1011 assertFalse(mBundle.hasFileDescriptors()); 1012 parcel.setDataPosition(0); 1013 mBundle.readFromParcel(parcel); 1014 assertTrue(mBundle.hasFileDescriptors()); // Checks the parcel 1015 1016 // Remove item to trigger deserialization and remove flag FLAG_HAS_FDS_KNOWN such that next 1017 // query triggers flag computation from lazy value 1018 mBundle.remove("unexistent"); 1019 assertTrue(mBundle.hasFileDescriptors()); // Checks the lazy value 1020 1021 // Trigger flag computation 1022 mBundle.remove("unexistent"); 1023 ParcelFileDescriptor pfd = mBundle.getParcelable("foo"); // Extracts the lazy value 1024 assertTrue(mBundle.hasFileDescriptors()); // Checks the object 1025 1026 // Now, check the lazy value returns false 1027 mBundle.clear(); 1028 mBundle.putParcelable(KEY1, new CustomParcelable(13, "Tiramisu")); 1029 roundtrip(); 1030 // Trigger flag computation 1031 mBundle.putParcelable("random", new CustomParcelable(13, "Tiramisu")); 1032 assertFalse(mBundle.hasFileDescriptors()); // Checks the lazy value 1033 } 1034 1035 @Test testHasFileDescriptors_withParcelable()1036 public void testHasFileDescriptors_withParcelable() throws Exception { 1037 assertTrue(mBundle.isEmpty()); 1038 assertFalse(mBundle.hasFileDescriptors()); 1039 1040 mBundle.putParcelable("key", ParcelFileDescriptor.dup(FileDescriptor.in)); 1041 assertTrue(mBundle.hasFileDescriptors()); 1042 1043 mBundle.putParcelable("key", new CustomParcelable(13, "Tiramisu")); 1044 assertFalse(mBundle.hasFileDescriptors()); 1045 } 1046 1047 @Test testHasFileDescriptors_withStringArray()1048 public void testHasFileDescriptors_withStringArray() throws Exception { 1049 assertTrue(mBundle.isEmpty()); 1050 assertFalse(mBundle.hasFileDescriptors()); 1051 1052 mBundle.putStringArray("key", new String[] { "string" }); 1053 assertFalse(mBundle.hasFileDescriptors()); 1054 } 1055 1056 @Test testHasFileDescriptors_withSparseArray()1057 public void testHasFileDescriptors_withSparseArray() throws Exception { 1058 assertTrue(mBundle.isEmpty()); 1059 assertFalse(mBundle.hasFileDescriptors()); 1060 1061 SparseArray<Parcelable> fdArray = new SparseArray<>(); 1062 fdArray.append(0, ParcelFileDescriptor.dup(FileDescriptor.in)); 1063 mBundle.putSparseParcelableArray("key", fdArray); 1064 assertTrue(mBundle.hasFileDescriptors()); 1065 1066 SparseArray<Parcelable> noFdArray = new SparseArray<>(); 1067 noFdArray.append(0, new CustomParcelable(13, "Tiramisu")); 1068 mBundle.putSparseParcelableArray("key", noFdArray); 1069 assertFalse(mBundle.hasFileDescriptors()); 1070 1071 SparseArray<Parcelable> emptyArray = new SparseArray<>(); 1072 mBundle.putSparseParcelableArray("key", emptyArray); 1073 assertFalse(mBundle.hasFileDescriptors()); 1074 } 1075 1076 @Test testHasFileDescriptors_withParcelableArray()1077 public void testHasFileDescriptors_withParcelableArray() throws Exception { 1078 assertTrue(mBundle.isEmpty()); 1079 assertFalse(mBundle.hasFileDescriptors()); 1080 1081 mBundle.putParcelableArray("key", 1082 new Parcelable[] { ParcelFileDescriptor.dup(FileDescriptor.in) }); 1083 assertTrue(mBundle.hasFileDescriptors()); 1084 1085 mBundle.putParcelableArray("key", 1086 new Parcelable[] { new CustomParcelable(13, "Tiramisu") }); 1087 assertFalse(mBundle.hasFileDescriptors()); 1088 } 1089 1090 @Test testHasFileDescriptorsOnNullValuedCollection()1091 public void testHasFileDescriptorsOnNullValuedCollection() { 1092 assertFalse(mBundle.hasFileDescriptors()); 1093 1094 mBundle.putParcelableArray("foo", new Parcelable[1]); 1095 assertFalse(mBundle.hasFileDescriptors()); 1096 mBundle.clear(); 1097 1098 SparseArray<Parcelable> sparseArray = new SparseArray<Parcelable>(); 1099 sparseArray.put(0, null); 1100 mBundle.putSparseParcelableArray("bar", sparseArray); 1101 assertFalse(mBundle.hasFileDescriptors()); 1102 mBundle.clear(); 1103 1104 ArrayList<Parcelable> arrayList = new ArrayList<Parcelable>(); 1105 arrayList.add(null); 1106 mBundle.putParcelableArrayList("baz", arrayList); 1107 assertFalse(mBundle.hasFileDescriptors()); 1108 mBundle.clear(); 1109 } 1110 1111 @SuppressWarnings("unchecked") 1112 @Test testHasFileDescriptors_withNestedContainers()1113 public void testHasFileDescriptors_withNestedContainers() throws IOException { 1114 // Purposely omitting generic types here, this is still "valid" app code after all. 1115 ArrayList nested = new ArrayList( 1116 Arrays.asList(Arrays.asList(ParcelFileDescriptor.dup(FileDescriptor.in)))); 1117 mBundle.putParcelableArrayList("list", nested); 1118 assertTrue(mBundle.hasFileDescriptors()); 1119 1120 roundtrip(/* parcel */ false); 1121 assertTrue(mBundle.hasFileDescriptors()); 1122 1123 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1124 mBundle.remove("unexistent"); // Removes cached value (removes FLAG_HAS_FDS_KNOWN) 1125 assertTrue(mBundle.hasFileDescriptors()); // Checks lazy value 1126 } 1127 1128 @Test testHasFileDescriptors_withOriginalParcelContainingFdButNotItems()1129 public void testHasFileDescriptors_withOriginalParcelContainingFdButNotItems() throws IOException { 1130 mBundle.putParcelable("fd", ParcelFileDescriptor.dup(FileDescriptor.in)); 1131 mBundle.putParcelable("parcelable", new CustomParcelable(13, "Tiramisu")); 1132 assertTrue(mBundle.hasFileDescriptors()); 1133 1134 roundtrip(/* parcel */ false); 1135 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1136 assertTrue(mBundle.hasFileDescriptors()); 1137 mBundle.remove("fd"); 1138 1139 // Will check the item's specific range in the original parcel 1140 assertFalse(mBundle.hasFileDescriptors()); 1141 } 1142 1143 @Test testHasFileDescriptors_withOriginalParcelAndItemsContainingFd()1144 public void testHasFileDescriptors_withOriginalParcelAndItemsContainingFd() throws IOException { 1145 mBundle.putParcelable("fd", ParcelFileDescriptor.dup(FileDescriptor.in)); 1146 mBundle.putParcelable("parcelable", new CustomParcelable(13, "Tiramisu")); 1147 assertTrue(mBundle.hasFileDescriptors()); 1148 1149 roundtrip(/* parcel */ false); 1150 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1151 assertTrue(mBundle.hasFileDescriptors()); 1152 mBundle.remove("parcelable"); 1153 1154 // Will check the item's specific range in the original parcel 1155 assertTrue(mBundle.hasFileDescriptors()); 1156 } 1157 1158 @Test testSetClassLoader()1159 public void testSetClassLoader() { 1160 mBundle.setClassLoader(new MockClassLoader()); 1161 } 1162 1163 // Write the bundle(A) to a parcel(B), and then create a bundle(C) from B. 1164 // C should be same as A. 1165 @Test testWriteToParcel()1166 public void testWriteToParcel() { 1167 final String li = "Bruce Li"; 1168 1169 mBundle.putString(KEY1, li); 1170 final Parcel parcel = Parcel.obtain(); 1171 mBundle.writeToParcel(parcel, 0); 1172 parcel.setDataPosition(0); 1173 final Bundle bundle = Bundle.CREATOR.createFromParcel(parcel); 1174 assertEquals(li, bundle.getString(KEY1)); 1175 } 1176 1177 // test the size should be right after add/remove key-value pair of the Bundle. 1178 @Test testSize()1179 public void testSize() { 1180 assertEquals(0, mBundle.size()); 1181 mBundle.putBoolean("one", true); 1182 assertEquals(1, mBundle.size()); 1183 1184 mBundle.putBoolean("two", true); 1185 assertEquals(2, mBundle.size()); 1186 1187 mBundle.putBoolean("three", true); 1188 assertEquals(3, mBundle.size()); 1189 1190 mBundle.putBoolean("four", true); 1191 mBundle.putBoolean("five", true); 1192 assertEquals(5, mBundle.size()); 1193 mBundle.remove("six"); 1194 assertEquals(5, mBundle.size()); 1195 1196 mBundle.remove("one"); 1197 assertEquals(4, mBundle.size()); 1198 mBundle.remove("one"); 1199 assertEquals(4, mBundle.size()); 1200 1201 mBundle.remove("two"); 1202 assertEquals(3, mBundle.size()); 1203 1204 mBundle.remove("three"); 1205 mBundle.remove("four"); 1206 mBundle.remove("five"); 1207 assertEquals(0, mBundle.size()); 1208 } 1209 1210 // The return value of toString() should not be null. 1211 @Test testToString()1212 public void testToString() { 1213 assertNotNull(mBundle.toString()); 1214 mBundle.putString("foo", "this test is so stupid"); 1215 assertNotNull(mBundle.toString()); 1216 } 1217 1218 // The tested Bundle should hold mappings from the given after putAll be invoked. 1219 @Test testPutAll()1220 public void testPutAll() { 1221 assertEquals(0, mBundle.size()); 1222 1223 final Bundle map = new Bundle(); 1224 map.putBoolean(KEY1, true); 1225 assertEquals(1, map.size()); 1226 mBundle.putAll(map); 1227 assertEquals(1, mBundle.size()); 1228 } 1229 roundtrip()1230 private void roundtrip() { 1231 roundtrip(/* parcel */ true); 1232 } 1233 roundtrip(boolean parcel)1234 private void roundtrip(boolean parcel) { 1235 mBundle = roundtrip(mBundle, parcel); 1236 } 1237 roundtrip(Bundle bundle)1238 private Bundle roundtrip(Bundle bundle) { 1239 return roundtrip(bundle, /* parcel */ true); 1240 } 1241 roundtrip(Bundle bundle, boolean parcel)1242 private Bundle roundtrip(Bundle bundle, boolean parcel) { 1243 Parcel p = Parcel.obtain(); 1244 bundle.writeToParcel(p, 0); 1245 if (parcel) { 1246 p = roundtripParcel(p); 1247 } 1248 p.setDataPosition(0); 1249 return p.readBundle(bundle.getClassLoader()); 1250 } 1251 roundtripParcel(Parcel out)1252 private Parcel roundtripParcel(Parcel out) { 1253 byte[] buf = out.marshall(); 1254 Parcel in = Parcel.obtain(); 1255 in.unmarshall(buf, 0, buf.length); 1256 in.setDataPosition(0); 1257 return in; 1258 } 1259 assertBundleEquals(Bundle expected, Bundle observed)1260 private void assertBundleEquals(Bundle expected, Bundle observed) { 1261 assertEquals(expected.size(), observed.size()); 1262 for (String key : expected.keySet()) { 1263 assertEquals(expected.get(key), observed.get(key)); 1264 } 1265 } 1266 assertSpannableEquals(Spannable expected, CharSequence observed)1267 private void assertSpannableEquals(Spannable expected, CharSequence observed) { 1268 final Spannable observedSpan = (Spannable) observed; 1269 assertEquals(expected.toString(), observed.toString()); 1270 Object[] expectedSpans = expected.getSpans(0, expected.length(), Object.class); 1271 Object[] observedSpans = observedSpan.getSpans(0, observedSpan.length(), Object.class); 1272 assertEquals(expectedSpans.length, observedSpans.length); 1273 for (int i = 0; i < expectedSpans.length; i++) { 1274 // Can't compare values of arbitrary objects 1275 assertEquals(expectedSpans[i].getClass(), observedSpans[i].getClass()); 1276 } 1277 } 1278 1279 @Test testHasFileDescriptor()1280 public void testHasFileDescriptor() throws Exception { 1281 final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); 1282 try { 1283 final ParcelFileDescriptor fd = pipe[0]; 1284 1285 assertNotHaveFd(Bundle.EMPTY); 1286 assertNotHaveFd(new Bundle()); 1287 1288 assertNotHaveFd(buildBundle("a", 1)); 1289 1290 assertHasFd(buildBundle("a", 1, fd)); 1291 assertHasFd(buildBundle("a", 1, new Parcelable[]{fd})); 1292 assertHasFd(buildBundle("a", 1, buildBundle(new Parcelable[]{fd}))); 1293 assertNotHaveFd(buildBundle("a", 1, buildBundle(1))); 1294 1295 Bundle nested1 = buildBundle(fd, buildBundle(1)); 1296 assertHasFd(nested1); // Outer bundle has an FD. 1297 assertNotHaveFd(nested1.getParcelable("key-1")); // But inner bundle doesn't. 1298 1299 Bundle nested2 = buildBundle(1, buildBundle(fd)); 1300 assertHasFd(nested2); 1301 assertHasFd(nested2.getParcelable("key-1")); 1302 1303 // More tricky case. Create a parcel with mixed objects. 1304 Parcel p = Parcel.obtain(); 1305 p.writeParcelable(fd, 0); 1306 p.writeInt(123); 1307 p.writeParcelable(buildBundle(1), 0); 1308 1309 // Now the parcel has an FD. 1310 p.setDataPosition(0); 1311 assertTrue(p.hasFileDescriptors()); 1312 1313 // Note even though the entire parcel has an FD, the inner bundle doesn't. 1314 assertEquals(ParcelFileDescriptor.class, 1315 p.readParcelable(getClass().getClassLoader()).getClass()); 1316 assertEquals(123, p.readInt()); 1317 assertNotHaveFd(p.readParcelable(Bundle.class.getClassLoader())); 1318 } finally { 1319 pipe[0].close(); 1320 pipe[1].close(); 1321 } 1322 } 1323 1324 @Test testBundleLengthNotAlignedByFour()1325 public void testBundleLengthNotAlignedByFour() { 1326 mBundle.putBoolean(KEY1, true); 1327 assertEquals(1, mBundle.size()); 1328 Parcel p = Parcel.obtain(); 1329 final int lengthPos = p.dataPosition(); 1330 mBundle.writeToParcel(p, 0); 1331 p.setDataPosition(lengthPos); 1332 final int length = p.readInt(); 1333 assertTrue(length != 0); 1334 assertTrue(length % 4 == 0); 1335 // Corrupt the bundle length so it is not aligned by 4. 1336 p.setDataPosition(lengthPos); 1337 p.writeInt(length - 1); 1338 p.setDataPosition(0); 1339 final Bundle b = new Bundle(); 1340 try { 1341 b.readFromParcel(p); 1342 fail("Failed to get an IllegalStateException"); 1343 } catch (IllegalStateException e) { 1344 // Expect IllegalStateException here. 1345 } 1346 } 1347 1348 @Test testGetCustomParcelable()1349 public void testGetCustomParcelable() { 1350 Parcelable parcelable = new CustomParcelable(13, "Tiramisu"); 1351 mBundle.putParcelable(KEY1, parcelable); 1352 assertEquals(parcelable, mBundle.getParcelable(KEY1)); 1353 assertEquals(1, mBundle.size()); 1354 roundtrip(); 1355 assertNotSame(parcelable, mBundle.getParcelable(KEY1)); 1356 assertEquals(parcelable, mBundle.getParcelable(KEY1)); 1357 assertEquals(1, mBundle.size()); 1358 } 1359 1360 @Test testGetNestedParcelable()1361 public void testGetNestedParcelable() { 1362 Parcelable nested = new CustomParcelable(13, "Tiramisu"); 1363 ComposedParcelable parcelable = new ComposedParcelable(26, nested); 1364 mBundle.putParcelable(KEY1, parcelable); 1365 assertEquals(parcelable, mBundle.getParcelable(KEY1)); 1366 assertEquals(1, mBundle.size()); 1367 roundtrip(); 1368 ComposedParcelable reconstructed = mBundle.getParcelable(KEY1); 1369 assertNotSame(parcelable, reconstructed); 1370 assertEquals(parcelable, reconstructed); 1371 assertNotSame(nested, reconstructed.parcelable); 1372 assertEquals(nested, reconstructed.parcelable); 1373 assertEquals(1, mBundle.size()); 1374 } 1375 1376 @Test testItemDeserializationIndependence()1377 public void testItemDeserializationIndependence() { 1378 Parcelable parcelable = new CustomParcelable(13, "Tiramisu"); 1379 Parcelable bomb = new CustomParcelable(13, "Tiramisu").setThrowsDuringDeserialization(true); 1380 mBundle.putParcelable(KEY1, parcelable); 1381 mBundle.putParcelable(KEY2, bomb); 1382 assertEquals(parcelable, mBundle.getParcelable(KEY1)); 1383 assertEquals(bomb, mBundle.getParcelable(KEY2)); 1384 assertEquals(2, mBundle.size()); 1385 roundtrip(); 1386 assertEquals(2, mBundle.size()); 1387 Parcelable reParcelable = mBundle.getParcelable(KEY1); 1388 // Passed if it didn't throw 1389 assertNotSame(parcelable, reParcelable); 1390 assertEquals(parcelable, reParcelable); 1391 assertThrows(RuntimeException.class, () -> mBundle.getParcelable(KEY2)); 1392 assertEquals(2, mBundle.size()); 1393 } 1394 1395 @Test testLazyValueReserialization()1396 public void testLazyValueReserialization() { 1397 Parcelable parcelable = new CustomParcelable(13, "Tiramisu"); 1398 mBundle.putParcelable(KEY1, parcelable); 1399 mBundle.putString(KEY2, "value"); 1400 roundtrip(); 1401 assertEquals("value", mBundle.getString(KEY2)); 1402 // Since we haven't retrieved KEY1, its value is still a lazy value inside bundle 1403 roundtrip(); 1404 assertEquals(parcelable, mBundle.getParcelable(KEY1)); 1405 assertEquals("value", mBundle.getString(KEY2)); 1406 } 1407 1408 @Test testPutAll_withLazyValues()1409 public void testPutAll_withLazyValues() { 1410 Parcelable parcelable = new CustomParcelable(13, "Tiramisu"); 1411 mBundle.putParcelable(KEY1, parcelable); 1412 roundtrip(); 1413 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1414 Bundle copy = new Bundle(); 1415 copy.putAll(mBundle); 1416 assertEquals(parcelable, copy.getParcelable(KEY1)); 1417 // Here we're verifying that LazyValue caches the deserialized object, hence they are the 1418 // same instance 1419 assertSame(copy.getParcelable(KEY1), mBundle.getParcelable(KEY1)); 1420 assertEquals(1, copy.size()); 1421 } 1422 1423 @Test testDeepCopy_withLazyValues()1424 public void testDeepCopy_withLazyValues() { 1425 Parcelable parcelable = new CustomParcelable(13, "Tiramisu"); 1426 mBundle.putParcelable(KEY1, parcelable); 1427 roundtrip(); 1428 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1429 Bundle copy = mBundle.deepCopy(); 1430 assertEquals(parcelable, copy.getParcelable(KEY1)); 1431 // Here we're verifying that LazyValue caches the deserialized object, hence they are the 1432 // same instance 1433 assertSame(copy.getParcelable(KEY1), mBundle.getParcelable(KEY1)); 1434 assertEquals(1, copy.size()); 1435 } 1436 1437 @Test testDeepCopy_withNestedParcelable()1438 public void testDeepCopy_withNestedParcelable() { 1439 Parcelable nested = new CustomParcelable(13, "Tiramisu"); 1440 ComposedParcelable parcelable = new ComposedParcelable(26, nested); 1441 mBundle.putParcelable(KEY1, parcelable); 1442 roundtrip(); 1443 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1444 Bundle copy = mBundle.deepCopy(); 1445 ComposedParcelable reconstructed = copy.getParcelable(KEY1); 1446 assertEquals(parcelable, reconstructed); 1447 assertSame(copy.getParcelable(KEY1), mBundle.getParcelable(KEY1)); 1448 assertEquals(nested, reconstructed.parcelable); 1449 assertEquals(1, copy.size()); 1450 } 1451 1452 @Test testDeepCopy_withNestedBundleAndLazyValues()1453 public void testDeepCopy_withNestedBundleAndLazyValues() { 1454 Parcelable parcelable = new CustomParcelable(13, "Tiramisu"); 1455 Bundle inner = new Bundle(); 1456 inner.putParcelable(KEY1, parcelable); 1457 inner = roundtrip(inner); 1458 inner.setClassLoader(getClass().getClassLoader()); 1459 inner.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1460 mBundle.putParcelable(KEY1, inner); 1461 Bundle copy = mBundle.deepCopy(); 1462 assertEquals(parcelable, copy.getBundle(KEY1).getParcelable(KEY1)); 1463 assertNotSame(mBundle.getBundle(KEY1), copy.getBundle(KEY1)); 1464 assertSame(mBundle.getBundle(KEY1).getParcelable(KEY1), 1465 copy.getBundle(KEY1).getParcelable(KEY1)); 1466 assertEquals(1, copy.getBundle(KEY1).size()); 1467 assertEquals(1, copy.size()); 1468 } 1469 1470 @Test testGetParcelable_isLazy()1471 public void testGetParcelable_isLazy() { 1472 mBundle.putParcelable(KEY1, new CustomParcelable(13, "Tiramisu")); 1473 roundtrip(); 1474 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1475 assertThat(CustomParcelable.sDeserialized).isFalse(); 1476 mBundle.getParcelable(KEY1); 1477 assertThat(CustomParcelable.sDeserialized).isTrue(); 1478 } 1479 1480 @Test testGetParcelableArray_isLazy()1481 public void testGetParcelableArray_isLazy() { 1482 mBundle.putParcelableArray(KEY1, new Parcelable[] {new CustomParcelable(13, "Tiramisu")}); 1483 roundtrip(); 1484 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1485 assertThat(CustomParcelable.sDeserialized).isFalse(); 1486 mBundle.getParcelableArray(KEY1); 1487 assertThat(CustomParcelable.sDeserialized).isTrue(); 1488 } 1489 1490 @Test testGetParcelableArrayList_isLazy()1491 public void testGetParcelableArrayList_isLazy() { 1492 mBundle.putParcelableArrayList(KEY1, 1493 new ArrayList<>(singletonList(new CustomParcelable(13, "Tiramisu")))); 1494 roundtrip(); 1495 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1496 assertThat(CustomParcelable.sDeserialized).isFalse(); 1497 mBundle.getParcelableArrayList(KEY1); 1498 assertThat(CustomParcelable.sDeserialized).isTrue(); 1499 } 1500 1501 @Test testGetSparseParcelableArray_isLazy()1502 public void testGetSparseParcelableArray_isLazy() { 1503 SparseArray<Parcelable> container = new SparseArray<>(); 1504 container.put(0, new CustomParcelable(13, "Tiramisu")); 1505 mBundle.putSparseParcelableArray(KEY1, container); 1506 roundtrip(); 1507 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1508 assertThat(CustomParcelable.sDeserialized).isFalse(); 1509 mBundle.getSparseParcelableArray(KEY1); 1510 assertThat(CustomParcelable.sDeserialized).isTrue(); 1511 } 1512 1513 @Test testGetSerializable_isLazy()1514 public void testGetSerializable_isLazy() { 1515 mBundle.putSerializable(KEY1, new CustomSerializable()); 1516 roundtrip(); 1517 mBundle.isEmpty(); // Triggers partial deserialization (leaving lazy values) 1518 assertThat(CustomSerializable.sDeserialized).isFalse(); 1519 mBundle.getSerializable(KEY1); 1520 assertThat(CustomSerializable.sDeserialized).isTrue(); 1521 } 1522 1523 public static class CustomSerializable implements Serializable { 1524 public static boolean sDeserialized = false; 1525 readObject(ObjectInputStream in)1526 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 1527 in.defaultReadObject(); 1528 sDeserialized = true; 1529 } 1530 } 1531 1532 public static class AnotherSerializable implements Serializable { 1533 } 1534 1535 public static class CustomParcelable implements Parcelable { 1536 public static boolean sDeserialized = false; 1537 1538 public final int integer; 1539 public final String string; 1540 public boolean throwsDuringDeserialization; 1541 CustomParcelable(int integer, String string)1542 public CustomParcelable(int integer, String string) { 1543 this.integer = integer; 1544 this.string = string; 1545 } 1546 CustomParcelable(Parcel in)1547 protected CustomParcelable(Parcel in) { 1548 integer = in.readInt(); 1549 string = in.readString(); 1550 throwsDuringDeserialization = in.readBoolean(); 1551 if (throwsDuringDeserialization) { 1552 throw new RuntimeException(); 1553 } 1554 sDeserialized = true; 1555 } 1556 setThrowsDuringDeserialization( boolean throwsDuringDeserialization)1557 public CustomParcelable setThrowsDuringDeserialization( 1558 boolean throwsDuringDeserialization) { 1559 this.throwsDuringDeserialization = throwsDuringDeserialization; 1560 return this; 1561 } 1562 1563 @Override describeContents()1564 public int describeContents() { 1565 return 0; 1566 } 1567 1568 @Override writeToParcel(Parcel out, int flags)1569 public void writeToParcel(Parcel out, int flags) { 1570 out.writeInt(integer); 1571 out.writeString(string); 1572 out.writeBoolean(throwsDuringDeserialization); 1573 } 1574 1575 @Override equals(Object other)1576 public boolean equals(Object other) { 1577 if (this == other) { 1578 return true; 1579 } 1580 if (!(other instanceof CustomParcelable)) { 1581 return false; 1582 } 1583 CustomParcelable that = (CustomParcelable) other; 1584 return integer == that.integer 1585 && throwsDuringDeserialization == that.throwsDuringDeserialization 1586 && string.equals(that.string); 1587 } 1588 1589 @Override hashCode()1590 public int hashCode() { 1591 return Objects.hash(integer, string, throwsDuringDeserialization); 1592 } 1593 1594 public static final Creator<CustomParcelable> CREATOR = new Creator<CustomParcelable>() { 1595 @Override 1596 public CustomParcelable createFromParcel(Parcel in) { 1597 return new CustomParcelable(in); 1598 } 1599 @Override 1600 public CustomParcelable[] newArray(int size) { 1601 return new CustomParcelable[size]; 1602 } 1603 }; 1604 } 1605 1606 public static class ComposedParcelable implements Parcelable { 1607 public final int integer; 1608 public final Parcelable parcelable; 1609 ComposedParcelable(int integer, Parcelable parcelable)1610 public ComposedParcelable(int integer, Parcelable parcelable) { 1611 this.integer = integer; 1612 this.parcelable = parcelable; 1613 } 1614 ComposedParcelable(Parcel in)1615 protected ComposedParcelable(Parcel in) { 1616 integer = in.readInt(); 1617 parcelable = in.readParcelable(getClass().getClassLoader()); 1618 } 1619 1620 @Override describeContents()1621 public int describeContents() { 1622 return 0; 1623 } 1624 1625 @Override writeToParcel(Parcel out, int flags)1626 public void writeToParcel(Parcel out, int flags) { 1627 out.writeInt(integer); 1628 out.writeParcelable(parcelable, flags); 1629 } 1630 1631 @Override equals(Object other)1632 public boolean equals(Object other) { 1633 if (this == other) { 1634 return true; 1635 } 1636 if (!(other instanceof ComposedParcelable)) { 1637 return false; 1638 } 1639 ComposedParcelable that = (ComposedParcelable) other; 1640 return integer == that.integer && Objects.equals(parcelable, that.parcelable); 1641 } 1642 1643 @Override hashCode()1644 public int hashCode() { 1645 return Objects.hash(integer, parcelable); 1646 } 1647 1648 public static final Creator<ComposedParcelable> CREATOR = 1649 new Creator<ComposedParcelable>() { 1650 @Override 1651 public ComposedParcelable createFromParcel(Parcel in) { 1652 return new ComposedParcelable(in); 1653 } 1654 @Override 1655 public ComposedParcelable[] newArray(int size) { 1656 return new ComposedParcelable[size]; 1657 } 1658 }; 1659 } 1660 1661 /** Create a Bundle with values, with autogenerated keys. */ buildBundle(Object... values)1662 private static Bundle buildBundle(Object... values) { 1663 final Bundle result = new Bundle(); 1664 1665 for (int i = 0; i < values.length; i++) { 1666 final String key = "key-" + i; 1667 1668 final Object value = values[i]; 1669 if (value == null) { 1670 result.putString(key, null); 1671 1672 } else if (value instanceof String) { 1673 result.putString(key, (String) value); 1674 1675 } else if (value instanceof Integer) { 1676 result.putInt(key, (Integer) value); 1677 1678 } else if (value instanceof Parcelable) { 1679 result.putParcelable(key, (Parcelable) value); 1680 1681 } else if (value instanceof Parcelable[]) { 1682 result.putParcelableArray(key, (Parcelable[]) value); 1683 1684 } else { 1685 fail("Unsupported value type: " + value.getClass()); 1686 } 1687 } 1688 return result; 1689 } 1690 cloneBundle(Bundle b)1691 private static Bundle cloneBundle(Bundle b) { 1692 return new Bundle(b); 1693 } 1694 cloneBundleViaParcel(Bundle b)1695 private static Bundle cloneBundleViaParcel(Bundle b) { 1696 final Parcel p = Parcel.obtain(); 1697 try { 1698 p.writeParcelable(b, 0); 1699 1700 p.setDataPosition(0); 1701 1702 return p.readParcelable(Bundle.class.getClassLoader()); 1703 } finally { 1704 p.recycle(); 1705 } 1706 } 1707 assertHasFd(Bundle b)1708 private static void assertHasFd(Bundle b) { 1709 assertTrue(b.hasFileDescriptors()); 1710 1711 // Make sure cloned ones have the same result. 1712 assertTrue(cloneBundle(b).hasFileDescriptors()); 1713 assertTrue(cloneBundleViaParcel(b).hasFileDescriptors()); 1714 } 1715 assertNotHaveFd(Bundle b)1716 private static void assertNotHaveFd(Bundle b) { 1717 assertFalse(b.hasFileDescriptors()); 1718 1719 // Make sure cloned ones have the same result. 1720 assertFalse(cloneBundle(b).hasFileDescriptors()); 1721 assertFalse(cloneBundleViaParcel(b).hasFileDescriptors()); 1722 } 1723 1724 class MockClassLoader extends ClassLoader { MockClassLoader()1725 MockClassLoader() { 1726 super(); 1727 } 1728 } 1729 uncheck(Callable<T> runnable)1730 private static <T> T uncheck(Callable<T> runnable) { 1731 try { 1732 return runnable.call(); 1733 } catch (Exception e) { 1734 throw new AssertionError(e); 1735 } 1736 } 1737 } 1738