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