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.assertTrue;
21 
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.os.Parcel;
25 import android.os.ParcelFileDescriptor;
26 import android.os.Parcelable;
27 import android.test.AndroidTestCase;
28 import android.text.Spannable;
29 import android.text.SpannableString;
30 import android.text.style.ForegroundColorSpan;
31 import android.util.SparseArray;
32 
33 import java.io.File;
34 import java.io.FileDescriptor;
35 import java.io.FileNotFoundException;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Set;
39 
40 public class BundleTest extends AndroidTestCase {
41 
42     private static final boolean BOOLEANKEYVALUE = false;
43 
44     private static final int INTKEYVALUE = 20;
45 
46     private static final String INTKEY = "intkey";
47 
48     private static final String BOOLEANKEY = "booleankey";
49 
50     public static final String KEY = "Bruce Lee";
51 
52     private static final String KEY2 = "key2";
53 
54     private Spannable mSpannable;
55 
56     private Bundle mBundle;
57 
58     @Override
setUp()59     protected void setUp() throws Exception {
60         super.setUp();
61 
62         mBundle = new Bundle();
63         mSpannable = new SpannableString("foo bar");
64         mSpannable.setSpan(new ForegroundColorSpan(0x123456), 0, 3, 0);
65     }
66 
testBundle()67     public void testBundle() {
68         final Bundle b1 = new Bundle();
69         assertTrue(b1.isEmpty());
70         b1.putBoolean(KEY, true);
71         assertFalse(b1.isEmpty());
72 
73         final Bundle b2 = new Bundle(b1);
74         assertTrue(b2.getBoolean(KEY));
75 
76         new Bundle(1024);
77         new Bundle(getClass().getClassLoader());
78     }
79 
testEmptyStream()80     public void testEmptyStream() {
81         Parcel p = Parcel.obtain();
82         p.unmarshall(new byte[] {}, 0, 0);
83         Bundle b = p.readBundle();
84         assertTrue(b.isEmpty());
85         mBundle.putBoolean("android", true);
86         p.unmarshall(new byte[] {}, 0, 0);
87         mBundle.readFromParcel(p);
88         assertTrue(mBundle.isEmpty());
89     }
90 
91     // first put sth into tested Bundle, it shouldn't be empty, then clear it and it should be empty
testClear()92     public void testClear() {
93         mBundle.putBoolean("android", true);
94         mBundle.putBoolean(KEY, true);
95         assertFalse(mBundle.isEmpty());
96         mBundle.clear();
97         assertTrue(mBundle.isEmpty());
98     }
99 
100     // first clone the tested Bundle, then compare the original Bundle with the
101     // cloned Bundle, they should equal
testClone()102     public void testClone() {
103         mBundle.putBoolean(BOOLEANKEY, BOOLEANKEYVALUE);
104         mBundle.putInt(INTKEY, INTKEYVALUE);
105         Bundle cloneBundle = (Bundle) mBundle.clone();
106         assertEquals(mBundle.size(), cloneBundle.size());
107         assertEquals(mBundle.getBoolean(BOOLEANKEY), cloneBundle.getBoolean(BOOLEANKEY));
108         assertEquals(mBundle.getInt(INTKEY), cloneBundle.getInt(INTKEY));
109     }
110 
111     // containsKey would return false if nothing has been put into the Bundle,
112     // else containsKey would return true if any putXXX has been called before
testContainsKey()113     public void testContainsKey() {
114         assertFalse(mBundle.containsKey(KEY));
115         mBundle.putBoolean(KEY, true);
116         assertTrue(mBundle.containsKey(KEY));
117         roundtrip();
118         assertTrue(mBundle.containsKey(KEY));
119     }
120 
121     // get would return null if nothing has been put into the Bundle,else get
122     // would return the value set by putXXX
testGet()123     public void testGet() {
124         assertNull(mBundle.get(KEY));
125         mBundle.putBoolean(KEY, true);
126         assertNotNull(mBundle.get(KEY));
127         roundtrip();
128         assertNotNull(mBundle.get(KEY));
129     }
130 
testGetBoolean1()131     public void testGetBoolean1() {
132         assertFalse(mBundle.getBoolean(KEY));
133         mBundle.putBoolean(KEY, true);
134         assertTrue(mBundle.getBoolean(KEY));
135         roundtrip();
136         assertTrue(mBundle.getBoolean(KEY));
137     }
138 
testGetBoolean2()139     public void testGetBoolean2() {
140         assertTrue(mBundle.getBoolean(KEY, true));
141         mBundle.putBoolean(KEY, false);
142         assertFalse(mBundle.getBoolean(KEY, true));
143         roundtrip();
144         assertFalse(mBundle.getBoolean(KEY, true));
145     }
146 
testGetBooleanArray()147     public void testGetBooleanArray() {
148         assertNull(mBundle.getBooleanArray(KEY));
149         mBundle.putBooleanArray(KEY, new boolean[] {
150                 true, false, true
151         });
152         boolean[] booleanArray = mBundle.getBooleanArray(KEY);
153         assertNotNull(booleanArray);
154         assertEquals(3, booleanArray.length);
155         assertEquals(true, booleanArray[0]);
156         assertEquals(false, booleanArray[1]);
157         assertEquals(true, booleanArray[2]);
158         roundtrip();
159         booleanArray = mBundle.getBooleanArray(KEY);
160         assertNotNull(booleanArray);
161         assertEquals(3, booleanArray.length);
162         assertEquals(true, booleanArray[0]);
163         assertEquals(false, booleanArray[1]);
164         assertEquals(true, booleanArray[2]);
165     }
166 
testGetBundle()167     public void testGetBundle() {
168         assertNull(mBundle.getBundle(KEY));
169         final Bundle bundle = new Bundle();
170         mBundle.putBundle(KEY, bundle);
171         assertTrue(bundle.equals(mBundle.getBundle(KEY)));
172         roundtrip();
173         assertBundleEquals(bundle, mBundle.getBundle(KEY));
174     }
175 
testGetByte1()176     public void testGetByte1() {
177         final byte b = 7;
178 
179         assertEquals(0, mBundle.getByte(KEY));
180         mBundle.putByte(KEY, b);
181         assertEquals(b, mBundle.getByte(KEY));
182         roundtrip();
183         assertEquals(b, mBundle.getByte(KEY));
184     }
185 
testGetByte2()186     public void testGetByte2() {
187         final byte b1 = 6;
188         final byte b2 = 7;
189 
190         assertEquals((Byte)b1, mBundle.getByte(KEY, b1));
191         mBundle.putByte(KEY, b2);
192         assertEquals((Byte)b2, mBundle.getByte(KEY, b1));
193         roundtrip();
194         assertEquals((Byte)b2, mBundle.getByte(KEY, b1));
195     }
196 
testGetByteArray()197     public void testGetByteArray() {
198         assertNull(mBundle.getByteArray(KEY));
199         mBundle.putByteArray(KEY, new byte[] {
200                 1, 2, 3
201         });
202         byte[] byteArray = mBundle.getByteArray(KEY);
203         assertNotNull(byteArray);
204         assertEquals(3, byteArray.length);
205         assertEquals(1, byteArray[0]);
206         assertEquals(2, byteArray[1]);
207         assertEquals(3, byteArray[2]);
208         roundtrip();
209         byteArray = mBundle.getByteArray(KEY);
210         assertNotNull(byteArray);
211         assertEquals(3, byteArray.length);
212         assertEquals(1, byteArray[0]);
213         assertEquals(2, byteArray[1]);
214         assertEquals(3, byteArray[2]);
215     }
216 
testGetChar1()217     public void testGetChar1() {
218         final char c = 'l';
219 
220         assertEquals((char)0, mBundle.getChar(KEY));
221         mBundle.putChar(KEY, c);
222         assertEquals(c, mBundle.getChar(KEY));
223         roundtrip();
224         assertEquals(c, mBundle.getChar(KEY));
225     }
226 
testGetChar2()227     public void testGetChar2() {
228         final char c1 = 'l';
229         final char c2 = 'i';
230 
231         assertEquals(c1, mBundle.getChar(KEY, c1));
232         mBundle.putChar(KEY, c2);
233         assertEquals(c2, mBundle.getChar(KEY, c1));
234         roundtrip();
235         assertEquals(c2, mBundle.getChar(KEY, c1));
236     }
237 
testGetCharArray()238     public void testGetCharArray() {
239         assertNull(mBundle.getCharArray(KEY));
240         mBundle.putCharArray(KEY, new char[] {
241                 'h', 'i'
242         });
243         char[] charArray = mBundle.getCharArray(KEY);
244         assertEquals('h', charArray[0]);
245         assertEquals('i', charArray[1]);
246         roundtrip();
247         charArray = mBundle.getCharArray(KEY);
248         assertEquals('h', charArray[0]);
249         assertEquals('i', charArray[1]);
250     }
251 
testGetCharSequence()252     public void testGetCharSequence() {
253         final CharSequence cS = "Bruce Lee";
254 
255         assertNull(mBundle.getCharSequence(KEY));
256         assertNull(mBundle.getCharSequence(KEY2));
257         mBundle.putCharSequence(KEY, cS);
258         mBundle.putCharSequence(KEY2, mSpannable);
259         assertEquals(cS, mBundle.getCharSequence(KEY));
260         assertSpannableEquals(mSpannable, mBundle.getCharSequence(KEY2));
261         roundtrip();
262         assertEquals(cS, mBundle.getCharSequence(KEY));
263         assertSpannableEquals(mSpannable, mBundle.getCharSequence(KEY2));
264     }
265 
testGetCharSequenceArray()266     public void testGetCharSequenceArray() {
267         assertNull(mBundle.getCharSequenceArray(KEY));
268         mBundle.putCharSequenceArray(KEY, new CharSequence[] {
269                 "one", "two", "three", mSpannable
270         });
271         CharSequence[] ret = mBundle.getCharSequenceArray(KEY);
272         assertEquals(4, ret.length);
273         assertEquals("one", ret[0]);
274         assertEquals("two", ret[1]);
275         assertEquals("three", ret[2]);
276         assertSpannableEquals(mSpannable, ret[3]);
277         roundtrip();
278         ret = mBundle.getCharSequenceArray(KEY);
279         assertEquals(4, ret.length);
280         assertEquals("one", ret[0]);
281         assertEquals("two", ret[1]);
282         assertEquals("three", ret[2]);
283         assertSpannableEquals(mSpannable, ret[3]);
284     }
285 
testGetCharSequenceArrayList()286     public void testGetCharSequenceArrayList() {
287         assertNull(mBundle.getCharSequenceArrayList(KEY));
288         final ArrayList<CharSequence> list = new ArrayList<CharSequence>();
289         list.add("one");
290         list.add("two");
291         list.add("three");
292         list.add(mSpannable);
293         mBundle.putCharSequenceArrayList(KEY, list);
294         roundtrip();
295         ArrayList<CharSequence> ret = mBundle.getCharSequenceArrayList(KEY);
296         assertEquals(4, ret.size());
297         assertEquals("one", ret.get(0));
298         assertEquals("two", ret.get(1));
299         assertEquals("three", ret.get(2));
300         assertSpannableEquals(mSpannable, ret.get(3));
301         roundtrip();
302         ret = mBundle.getCharSequenceArrayList(KEY);
303         assertEquals(4, ret.size());
304         assertEquals("one", ret.get(0));
305         assertEquals("two", ret.get(1));
306         assertEquals("three", ret.get(2));
307         assertSpannableEquals(mSpannable, ret.get(3));
308     }
309 
testGetDouble1()310     public void testGetDouble1() {
311         final double d = 10.07;
312 
313         assertEquals(0.0, mBundle.getDouble(KEY));
314         mBundle.putDouble(KEY, d);
315         assertEquals(d, mBundle.getDouble(KEY));
316         roundtrip();
317         assertEquals(d, mBundle.getDouble(KEY));
318     }
319 
testGetDouble2()320     public void testGetDouble2() {
321         final double d1 = 10.06;
322         final double d2 = 10.07;
323 
324         assertEquals(d1, mBundle.getDouble(KEY, d1));
325         mBundle.putDouble(KEY, d2);
326         assertEquals(d2, mBundle.getDouble(KEY, d1));
327         roundtrip();
328         assertEquals(d2, mBundle.getDouble(KEY, d1));
329     }
330 
testGetDoubleArray()331     public void testGetDoubleArray() {
332         assertNull(mBundle.getDoubleArray(KEY));
333         mBundle.putDoubleArray(KEY, new double[] {
334                 10.06, 10.07
335         });
336         double[] doubleArray = mBundle.getDoubleArray(KEY);
337         assertEquals(10.06, doubleArray[0]);
338         assertEquals(10.07, doubleArray[1]);
339         roundtrip();
340         doubleArray = mBundle.getDoubleArray(KEY);
341         assertEquals(10.06, doubleArray[0]);
342         assertEquals(10.07, doubleArray[1]);
343     }
344 
testGetFloat1()345     public void testGetFloat1() {
346         final float f = 10.07f;
347 
348         assertEquals(0.0f, mBundle.getFloat(KEY));
349         mBundle.putFloat(KEY, f);
350         assertEquals(f, mBundle.getFloat(KEY));
351         roundtrip();
352         assertEquals(f, mBundle.getFloat(KEY));
353     }
354 
testGetFloat2()355     public void testGetFloat2() {
356         final float f1 = 10.06f;
357         final float f2 = 10.07f;
358 
359         assertEquals(f1, mBundle.getFloat(KEY, f1));
360         mBundle.putFloat(KEY, f2);
361         assertEquals(f2, mBundle.getFloat(KEY, f1));
362         roundtrip();
363         assertEquals(f2, mBundle.getFloat(KEY, f1));
364     }
365 
testGetFloatArray()366     public void testGetFloatArray() {
367         assertNull(mBundle.getFloatArray(KEY));
368         mBundle.putFloatArray(KEY, new float[] {
369                 10.06f, 10.07f
370         });
371         float[] floatArray = mBundle.getFloatArray(KEY);
372         assertEquals(10.06f, floatArray[0]);
373         assertEquals(10.07f, floatArray[1]);
374         roundtrip();
375         floatArray = mBundle.getFloatArray(KEY);
376         assertEquals(10.06f, floatArray[0]);
377         assertEquals(10.07f, floatArray[1]);
378     }
379 
testGetInt1()380     public void testGetInt1() {
381         final int i = 1007;
382 
383         assertEquals(0, mBundle.getInt(KEY));
384         mBundle.putInt(KEY, i);
385         assertEquals(i, mBundle.getInt(KEY));
386         roundtrip();
387         assertEquals(i, mBundle.getInt(KEY));
388     }
389 
testGetInt2()390     public void testGetInt2() {
391         final int i1 = 1006;
392         final int i2 = 1007;
393 
394         assertEquals(i1, mBundle.getInt(KEY, i1));
395         mBundle.putInt(KEY, i2);
396         assertEquals(i2, mBundle.getInt(KEY, i2));
397         roundtrip();
398         assertEquals(i2, mBundle.getInt(KEY, i2));
399     }
400 
testGetIntArray()401     public void testGetIntArray() {
402         assertNull(mBundle.getIntArray(KEY));
403         mBundle.putIntArray(KEY, new int[] {
404                 1006, 1007
405         });
406         int[] intArray = mBundle.getIntArray(KEY);
407         assertEquals(1006, intArray[0]);
408         assertEquals(1007, intArray[1]);
409         roundtrip();
410         intArray = mBundle.getIntArray(KEY);
411         assertEquals(1006, intArray[0]);
412         assertEquals(1007, intArray[1]);
413     }
414 
415     // getIntegerArrayList should only return the IntegerArrayList set by putIntegerArrayLis
testGetIntegerArrayList()416     public void testGetIntegerArrayList() {
417         final int i1 = 1006;
418         final int i2 = 1007;
419 
420         assertNull(mBundle.getIntegerArrayList(KEY));
421         final ArrayList<Integer> arrayList = new ArrayList<Integer>();
422         arrayList.add(i1);
423         arrayList.add(i2);
424         mBundle.putIntegerArrayList(KEY, arrayList);
425         ArrayList<Integer> retArrayList = mBundle.getIntegerArrayList(KEY);
426         assertNotNull(retArrayList);
427         assertEquals(2, retArrayList.size());
428         assertEquals((Integer)i1, retArrayList.get(0));
429         assertEquals((Integer)i2, retArrayList.get(1));
430         roundtrip();
431         retArrayList = mBundle.getIntegerArrayList(KEY);
432         assertNotNull(retArrayList);
433         assertEquals(2, retArrayList.size());
434         assertEquals((Integer)i1, retArrayList.get(0));
435         assertEquals((Integer)i2, retArrayList.get(1));
436     }
437 
testGetLong1()438     public void testGetLong1() {
439         final long l = 1007;
440 
441         assertEquals(0, mBundle.getLong(KEY));
442         mBundle.putLong(KEY, l);
443         assertEquals(l, mBundle.getLong(KEY));
444         roundtrip();
445         assertEquals(l, mBundle.getLong(KEY));
446     }
447 
testGetLong2()448     public void testGetLong2() {
449         final long l1 = 1006;
450         final long l2 = 1007;
451 
452         assertEquals(l1, mBundle.getLong(KEY, l1));
453         mBundle.putLong(KEY, l2);
454         assertEquals(l2, mBundle.getLong(KEY, l2));
455         roundtrip();
456         assertEquals(l2, mBundle.getLong(KEY, l2));
457     }
458 
testGetLongArray()459     public void testGetLongArray() {
460         assertNull(mBundle.getLongArray(KEY));
461         mBundle.putLongArray(KEY, new long[] {
462                 1006, 1007
463         });
464         long[] longArray = mBundle.getLongArray(KEY);
465         assertEquals(1006, longArray[0]);
466         assertEquals(1007, longArray[1]);
467         roundtrip();
468         longArray = mBundle.getLongArray(KEY);
469         assertEquals(1006, longArray[0]);
470         assertEquals(1007, longArray[1]);
471     }
472 
testGetParcelable()473     public void testGetParcelable() {
474         assertNull(mBundle.getParcelable(KEY));
475         final Bundle bundle = new Bundle();
476         mBundle.putParcelable(KEY, bundle);
477         assertTrue(bundle.equals(mBundle.getParcelable(KEY)));
478         roundtrip();
479         assertBundleEquals(bundle, (Bundle) mBundle.getParcelable(KEY));
480     }
481 
482     // getParcelableArray should only return the ParcelableArray set by putParcelableArray
testGetParcelableArray()483     public void testGetParcelableArray() {
484         assertNull(mBundle.getParcelableArray(KEY));
485         final Bundle bundle1 = new Bundle();
486         final Bundle bundle2 = new Bundle();
487         mBundle.putParcelableArray(KEY, new Bundle[] {
488                 bundle1, bundle2
489         });
490         Parcelable[] parcelableArray = mBundle.getParcelableArray(KEY);
491         assertEquals(2, parcelableArray.length);
492         assertTrue(bundle1.equals(parcelableArray[0]));
493         assertTrue(bundle2.equals(parcelableArray[1]));
494         roundtrip();
495         parcelableArray = mBundle.getParcelableArray(KEY);
496         assertEquals(2, parcelableArray.length);
497         assertBundleEquals(bundle1, (Bundle) parcelableArray[0]);
498         assertBundleEquals(bundle2, (Bundle) parcelableArray[1]);
499     }
500 
501     // getParcelableArrayList should only return the parcelableArrayList set by putParcelableArrayList
testGetParcelableArrayList()502     public void testGetParcelableArrayList() {
503         assertNull(mBundle.getParcelableArrayList(KEY));
504         final ArrayList<Parcelable> parcelableArrayList = new ArrayList<Parcelable>();
505         final Bundle bundle1 = new Bundle();
506         final Bundle bundle2 = new Bundle();
507         parcelableArrayList.add(bundle1);
508         parcelableArrayList.add(bundle2);
509         mBundle.putParcelableArrayList(KEY, parcelableArrayList);
510         ArrayList<Parcelable> ret = mBundle.getParcelableArrayList(KEY);
511         assertEquals(2, ret.size());
512         assertTrue(bundle1.equals(ret.get(0)));
513         assertTrue(bundle2.equals(ret.get(1)));
514         roundtrip();
515         ret = mBundle.getParcelableArrayList(KEY);
516         assertEquals(2, ret.size());
517         assertBundleEquals(bundle1, (Bundle) ret.get(0));
518         assertBundleEquals(bundle2, (Bundle) ret.get(1));
519     }
520 
testGetSerializableWithString()521     public void testGetSerializableWithString() {
522         assertNull(mBundle.getSerializable(KEY));
523         String s = "android";
524         mBundle.putSerializable(KEY, s);
525         assertEquals(s, mBundle.getSerializable(KEY));
526         roundtrip();
527         assertEquals(s, mBundle.getSerializable(KEY));
528     }
529 
testGetSerializableWithStringArray()530     public void testGetSerializableWithStringArray() {
531         assertNull(mBundle.getSerializable(KEY));
532         String[] strings = new String[]{"first", "last"};
533         mBundle.putSerializable(KEY, strings);
534         assertEquals(Arrays.asList(strings),
535                 Arrays.asList((String[]) mBundle.getSerializable(KEY)));
536         roundtrip();
537         assertEquals(Arrays.asList(strings),
538                 Arrays.asList((String[]) mBundle.getSerializable(KEY)));
539     }
540 
testGetSerializableWithMultiDimensionalObjectArray()541     public void testGetSerializableWithMultiDimensionalObjectArray() {
542         assertNull(mBundle.getSerializable(KEY));
543         Object[][] objects = new Object[][] {
544                 {"string", 1L}
545         };
546         mBundle.putSerializable(KEY, objects);
547         assertEquals(Arrays.asList(objects[0]),
548                 Arrays.asList(((Object[][]) mBundle.getSerializable(KEY))[0]));
549         roundtrip();
550         assertEquals(Arrays.asList(objects[0]),
551                 Arrays.asList(((Object[][]) mBundle.getSerializable(KEY))[0]));
552     }
553 
testGetShort1()554     public void testGetShort1() {
555         final short s = 1007;
556 
557         assertEquals(0, mBundle.getShort(KEY));
558         mBundle.putShort(KEY, s);
559         assertEquals(s, mBundle.getShort(KEY));
560         roundtrip();
561         assertEquals(s, mBundle.getShort(KEY));
562     }
563 
testGetShort2()564     public void testGetShort2() {
565         final short s1 = 1006;
566         final short s2 = 1007;
567 
568         assertEquals(s1, mBundle.getShort(KEY, s1));
569         mBundle.putShort(KEY, s2);
570         assertEquals(s2, mBundle.getShort(KEY, s1));
571         roundtrip();
572         assertEquals(s2, mBundle.getShort(KEY, s1));
573     }
574 
testGetShortArray()575     public void testGetShortArray() {
576         final short s1 = 1006;
577         final short s2 = 1007;
578 
579         assertNull(mBundle.getShortArray(KEY));
580         mBundle.putShortArray(KEY, new short[] {
581                 s1, s2
582         });
583         short[] shortArray = mBundle.getShortArray(KEY);
584         assertEquals(s1, shortArray[0]);
585         assertEquals(s2, shortArray[1]);
586         roundtrip();
587         shortArray = mBundle.getShortArray(KEY);
588         assertEquals(s1, shortArray[0]);
589         assertEquals(s2, shortArray[1]);
590     }
591 
592     // getSparseParcelableArray should only return the SparseArray<Parcelable>
593     // set by putSparseParcelableArray
testGetSparseParcelableArray()594     public void testGetSparseParcelableArray() {
595         assertNull(mBundle.getSparseParcelableArray(KEY));
596         final SparseArray<Parcelable> sparseArray = new SparseArray<Parcelable>();
597         final Bundle bundle = new Bundle();
598         final Intent intent = new Intent();
599         sparseArray.put(1006, bundle);
600         sparseArray.put(1007, intent);
601         mBundle.putSparseParcelableArray(KEY, sparseArray);
602         SparseArray<Parcelable> ret = mBundle.getSparseParcelableArray(KEY);
603         assertEquals(2, ret.size());
604         assertNull(ret.get(1008));
605         assertTrue(bundle.equals(ret.get(1006)));
606         assertTrue(intent.equals(ret.get(1007)));
607         roundtrip();
608         ret = mBundle.getSparseParcelableArray(KEY);
609         assertEquals(2, ret.size());
610         assertNull(ret.get(1008));
611         assertBundleEquals(bundle, (Bundle) ret.get(1006));
612         assertIntentEquals(intent, (Intent) ret.get(1007));
613     }
614 
testGetString()615     public void testGetString() {
616         assertNull(mBundle.getString(KEY));
617         mBundle.putString(KEY, "android");
618         assertEquals("android", mBundle.getString(KEY));
619         roundtrip();
620         assertEquals("android", mBundle.getString(KEY));
621     }
622 
testGetStringArray()623     public void testGetStringArray() {
624         assertNull(mBundle.getStringArray(KEY));
625         mBundle.putStringArray(KEY, new String[] {
626                 "one", "two", "three"
627         });
628         String[] ret = mBundle.getStringArray(KEY);
629         assertEquals("one", ret[0]);
630         assertEquals("two", ret[1]);
631         assertEquals("three", ret[2]);
632         roundtrip();
633         ret = mBundle.getStringArray(KEY);
634         assertEquals("one", ret[0]);
635         assertEquals("two", ret[1]);
636         assertEquals("three", ret[2]);
637     }
638 
639     // getStringArrayList should only return the StringArrayList set by putStringArrayList
testGetStringArrayList()640     public void testGetStringArrayList() {
641         assertNull(mBundle.getStringArrayList(KEY));
642         final ArrayList<String> stringArrayList = new ArrayList<String>();
643         stringArrayList.add("one");
644         stringArrayList.add("two");
645         stringArrayList.add("three");
646         mBundle.putStringArrayList(KEY, stringArrayList);
647         ArrayList<String> ret = mBundle.getStringArrayList(KEY);
648         assertEquals(3, ret.size());
649         assertEquals("one", ret.get(0));
650         assertEquals("two", ret.get(1));
651         assertEquals("three", ret.get(2));
652         roundtrip();
653         ret = mBundle.getStringArrayList(KEY);
654         assertEquals(3, ret.size());
655         assertEquals("one", ret.get(0));
656         assertEquals("two", ret.get(1));
657         assertEquals("three", ret.get(2));
658     }
659 
testKeySet()660     public void testKeySet() {
661         Set<String> setKey = mBundle.keySet();
662         assertFalse(setKey.contains("one"));
663         assertFalse(setKey.contains("two"));
664         mBundle.putBoolean("one", true);
665         mBundle.putChar("two", 't');
666         setKey = mBundle.keySet();
667         assertEquals(2, setKey.size());
668         assertTrue(setKey.contains("one"));
669         assertTrue(setKey.contains("two"));
670         assertFalse(setKey.contains("three"));
671         roundtrip();
672         setKey = mBundle.keySet();
673         assertEquals(2, setKey.size());
674         assertTrue(setKey.contains("one"));
675         assertTrue(setKey.contains("two"));
676         assertFalse(setKey.contains("three"));
677     }
678 
679     // same as hasFileDescriptors, the only difference is that describeContents
680     // return 0 if no fd and return 1 if has fd for the tested Bundle
681 
testDescribeContents()682     public void testDescribeContents() {
683         assertTrue((mBundle.describeContents()
684                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) == 0);
685 
686         final Parcel parcel = Parcel.obtain();
687         try {
688             mBundle.putParcelable("foo", ParcelFileDescriptor.open(
689                     new File("/system"), ParcelFileDescriptor.MODE_READ_ONLY));
690         } catch (FileNotFoundException e) {
691             throw new RuntimeException("can't open /system", e);
692         }
693         assertTrue((mBundle.describeContents()
694                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0);
695         mBundle.writeToParcel(parcel, 0);
696         mBundle.clear();
697         assertTrue((mBundle.describeContents()
698                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) == 0);
699         parcel.setDataPosition(0);
700         mBundle.readFromParcel(parcel);
701         assertTrue((mBundle.describeContents()
702                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0);
703         ParcelFileDescriptor pfd = (ParcelFileDescriptor)mBundle.getParcelable("foo");
704         assertTrue((mBundle.describeContents()
705                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0);
706     }
707 
708     // case 1: The default bundle doesn't has FileDescriptor.
709     // case 2: The tested Bundle should has FileDescriptor
710     //  if it read data from a Parcel object, which is created with a FileDescriptor.
711     // case 3: The tested Bundle should has FileDescriptor
712     //  if put a Parcelable object, which is created with a FileDescriptor, into it.
testHasFileDescriptors()713     public void testHasFileDescriptors() {
714         assertFalse(mBundle.hasFileDescriptors());
715 
716         final Parcel parcel = Parcel.obtain();
717         assertFalse(parcel.hasFileDescriptors());
718         try {
719             mBundle.putParcelable("foo", ParcelFileDescriptor.open(
720                     new File("/system"), ParcelFileDescriptor.MODE_READ_ONLY));
721         } catch (FileNotFoundException e) {
722             throw new RuntimeException("can't open /system", e);
723         }
724         assertTrue(mBundle.hasFileDescriptors());
725         mBundle.writeToParcel(parcel, 0);
726         assertTrue(parcel.hasFileDescriptors());
727         mBundle.clear();
728         assertFalse(mBundle.hasFileDescriptors());
729         parcel.setDataPosition(0);
730         mBundle.readFromParcel(parcel);
731         assertTrue(mBundle.hasFileDescriptors());
732         ParcelFileDescriptor pfd = (ParcelFileDescriptor)mBundle.getParcelable("foo");
733         assertTrue(mBundle.hasFileDescriptors());
734     }
735 
testHasFileDescriptorsOnNullValuedCollection()736     public void testHasFileDescriptorsOnNullValuedCollection() {
737         assertFalse(mBundle.hasFileDescriptors());
738 
739         mBundle.putParcelableArray("foo", new Parcelable[1]);
740         assertFalse(mBundle.hasFileDescriptors());
741         mBundle.clear();
742 
743         SparseArray<Parcelable> sparseArray = new SparseArray<Parcelable>();
744         sparseArray.put(0, null);
745         mBundle.putSparseParcelableArray("bar", sparseArray);
746         assertFalse(mBundle.hasFileDescriptors());
747         mBundle.clear();
748 
749         ArrayList<Parcelable> arrayList = new ArrayList<Parcelable>();
750         arrayList.add(null);
751         mBundle.putParcelableArrayList("baz", arrayList);
752         assertFalse(mBundle.hasFileDescriptors());
753         mBundle.clear();
754     }
755 
testSetClassLoader()756     public void testSetClassLoader() {
757         mBundle.setClassLoader(new MockClassLoader());
758     }
759 
760     // Write the bundle(A) to a parcel(B), and then create a bundle(C) from B.
761     // C should be same as A.
testWriteToParcel()762     public void testWriteToParcel() {
763         final String li = "Bruce Li";
764 
765         mBundle.putString(KEY, li);
766         final Parcel parcel = Parcel.obtain();
767         mBundle.writeToParcel(parcel, 0);
768         parcel.setDataPosition(0);
769         final Bundle bundle = Bundle.CREATOR.createFromParcel(parcel);
770         assertEquals(li, bundle.getString(KEY));
771     }
772 
773     // test the size should be right after add/remove key-value pair of the Bundle.
testSize()774     public void testSize() {
775         assertEquals(0, mBundle.size());
776         mBundle.putBoolean("one", true);
777         assertEquals(1, mBundle.size());
778 
779         mBundle.putBoolean("two", true);
780         assertEquals(2, mBundle.size());
781 
782         mBundle.putBoolean("three", true);
783         assertEquals(3, mBundle.size());
784 
785         mBundle.putBoolean("four", true);
786         mBundle.putBoolean("five", true);
787         assertEquals(5, mBundle.size());
788         mBundle.remove("six");
789         assertEquals(5, mBundle.size());
790 
791         mBundle.remove("one");
792         assertEquals(4, mBundle.size());
793         mBundle.remove("one");
794         assertEquals(4, mBundle.size());
795 
796         mBundle.remove("two");
797         assertEquals(3, mBundle.size());
798 
799         mBundle.remove("three");
800         mBundle.remove("four");
801         mBundle.remove("five");
802         assertEquals(0, mBundle.size());
803     }
804 
805     // The return value of toString() should not be null.
testToString()806     public void testToString() {
807         assertNotNull(mBundle.toString());
808         mBundle.putString("foo", "this test is so stupid");
809         assertNotNull(mBundle.toString());
810     }
811 
812     // The tested Bundle should hold mappings from the given after putAll be invoked.
testPutAll()813     public void testPutAll() {
814         assertEquals(0, mBundle.size());
815 
816         final Bundle map = new Bundle();
817         map.putBoolean(KEY, true);
818         assertEquals(1, map.size());
819         mBundle.putAll(map);
820         assertEquals(1, mBundle.size());
821     }
822 
roundtrip()823     private void roundtrip() {
824         Parcel out = Parcel.obtain();
825         mBundle.writeToParcel(out, 0);
826         Parcel in = roundtripParcel(out);
827         mBundle = in.readBundle();
828     }
829 
roundtripParcel(Parcel out)830     private Parcel roundtripParcel(Parcel out) {
831         byte[] buf = out.marshall();
832         Parcel in = Parcel.obtain();
833         in.unmarshall(buf, 0, buf.length);
834         in.setDataPosition(0);
835         return in;
836     }
837 
assertBundleEquals(Bundle expected, Bundle observed)838     private void assertBundleEquals(Bundle expected, Bundle observed) {
839         assertEquals(expected.size(), observed.size());
840         for (String key : expected.keySet()) {
841             assertEquals(expected.get(key), observed.get(key));
842         }
843     }
844 
assertIntentEquals(Intent expected, Intent observed)845     private void assertIntentEquals(Intent expected, Intent observed) {
846         assertEquals(expected.toUri(0), observed.toUri(0));
847     }
848 
assertSpannableEquals(Spannable expected, CharSequence observed)849     private void assertSpannableEquals(Spannable expected, CharSequence observed) {
850         final Spannable observedSpan = (Spannable) observed;
851         assertEquals(expected.toString(), observed.toString());
852         Object[] expectedSpans = expected.getSpans(0, expected.length(), Object.class);
853         Object[] observedSpans = observedSpan.getSpans(0, observedSpan.length(), Object.class);
854         assertEquals(expectedSpans.length, observedSpans.length);
855         for (int i = 0; i < expectedSpans.length; i++) {
856             // Can't compare values of arbitrary objects
857             assertEquals(expectedSpans[i].getClass(), observedSpans[i].getClass());
858         }
859     }
860 
testHasFileDescriptor()861     public void testHasFileDescriptor() throws Exception {
862         final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
863         try {
864             final ParcelFileDescriptor fd = pipe[0];
865 
866             assertNotHaveFd(Bundle.EMPTY);
867             assertNotHaveFd(new Bundle());
868 
869             assertNotHaveFd(buildBundle("a", 1));
870 
871             assertHasFd(buildBundle("a", 1, fd));
872             assertHasFd(buildBundle("a", 1, new Parcelable[]{fd}));
873             assertHasFd(buildBundle("a", 1, buildBundle(new Parcelable[]{fd})));
874             assertNotHaveFd(buildBundle("a", 1, buildBundle(1)));
875 
876             Bundle nested1 = buildBundle(fd, buildBundle(1));
877             assertHasFd(nested1); // Outer bundle has an FD.
878             assertNotHaveFd(nested1.getParcelable("key-1")); // But inner bundle doesn't.
879 
880             Bundle nested2 = buildBundle(1, buildBundle(fd));
881             assertHasFd(nested2);
882             assertHasFd(nested2.getParcelable("key-1"));
883 
884             // More tricky case.  Create a parcel with mixed objects.
885             Parcel p = Parcel.obtain();
886             p.writeParcelable(fd, 0);
887             p.writeInt(123);
888             p.writeParcelable(buildBundle(1), 0);
889 
890             // Now the parcel has an FD.
891             p.setDataPosition(0);
892             assertTrue(p.hasFileDescriptors());
893 
894             // Note even though the entire parcel has an FD, the inner bundle doesn't.
895             assertEquals(ParcelFileDescriptor.class,
896                     p.readParcelable(getClass().getClassLoader()).getClass());
897             assertEquals(123, p.readInt());
898             assertNotHaveFd(p.readParcelable(Bundle.class.getClassLoader()));
899         } finally {
900             pipe[0].close();
901             pipe[1].close();
902         }
903     }
904 
testBundleLengthNotAlignedByFour()905     public void testBundleLengthNotAlignedByFour() {
906         mBundle.putBoolean(KEY, true);
907         assertEquals(1, mBundle.size());
908         Parcel p = Parcel.obtain();
909         final int lengthPos = p.dataPosition();
910         mBundle.writeToParcel(p, 0);
911         p.setDataPosition(lengthPos);
912         final int length = p.readInt();
913         assertTrue(length != 0);
914         assertTrue(length % 4 == 0);
915         // Corrupt the bundle length so it is not aligned by 4.
916         p.setDataPosition(lengthPos);
917         p.writeInt(length - 1);
918         p.setDataPosition(0);
919         final Bundle b = new Bundle();
920         try {
921             b.readFromParcel(p);
922             fail("Failed to get an IllegalStateException");
923         } catch (IllegalStateException e) {
924             // Expect IllegalStateException here.
925         }
926     }
927 
928     /** Create a Bundle with values, with autogenerated keys. */
buildBundle(Object... values)929     private static Bundle buildBundle(Object... values) {
930         final Bundle result = new Bundle();
931 
932         for (int i = 0; i < values.length; i++) {
933             final String key = "key-" + i;
934 
935             final Object value = values[i];
936             if (value == null) {
937                 result.putString(key, null);
938 
939             } else if (value instanceof String) {
940                 result.putString(key, (String) value);
941 
942             } else if (value instanceof Integer) {
943                 result.putInt(key, (Integer) value);
944 
945             } else if (value instanceof Parcelable) {
946                 result.putParcelable(key, (Parcelable) value);
947 
948             } else if (value instanceof Parcelable[]) {
949                 result.putParcelableArray(key, (Parcelable[]) value);
950 
951             } else {
952                 fail("Unsupported value type: " + value.getClass());
953             }
954         }
955         return result;
956     }
957 
cloneBundle(Bundle b)958     private static Bundle cloneBundle(Bundle b) {
959         return new Bundle(b);
960     }
961 
cloneBundleViaParcel(Bundle b)962     private static Bundle cloneBundleViaParcel(Bundle b) {
963         final Parcel p = Parcel.obtain();
964         try {
965             p.writeParcelable(b, 0);
966 
967             p.setDataPosition(0);
968 
969             return p.readParcelable(Bundle.class.getClassLoader());
970         } finally {
971             p.recycle();
972         }
973     }
974 
assertHasFd(Bundle b)975     private static void assertHasFd(Bundle b) {
976         assertTrue(b.hasFileDescriptors());
977 
978         // Make sure cloned ones have the same result.
979         assertTrue(cloneBundle(b).hasFileDescriptors());
980         assertTrue(cloneBundleViaParcel(b).hasFileDescriptors());
981     }
982 
assertNotHaveFd(Bundle b)983     private static void assertNotHaveFd(Bundle b) {
984         assertFalse(b.hasFileDescriptors());
985 
986         // Make sure cloned ones have the same result.
987         assertFalse(cloneBundle(b).hasFileDescriptors());
988         assertFalse(cloneBundleViaParcel(b).hasFileDescriptors());
989     }
990 
991     class MockClassLoader extends ClassLoader {
MockClassLoader()992         MockClassLoader() {
993             super();
994         }
995     }
996 }