• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os.cts;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertThrows;
21 import static org.mockito.Mockito.spy;
22 import static org.mockito.Mockito.verify;
23 
24 import android.app.Service;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.ServiceConnection;
29 import android.content.pm.Signature;
30 import android.os.BadParcelableException;
31 import android.os.Binder;
32 import android.os.Bundle;
33 import android.os.IBinder;
34 import android.os.IInterface;
35 import android.os.Parcel;
36 import android.os.ParcelFileDescriptor;
37 import android.os.Parcelable;
38 import android.platform.test.annotations.AsbSecurityTest;
39 import android.test.AndroidTestCase;
40 import android.util.Log;
41 import android.util.SparseArray;
42 import android.util.SparseBooleanArray;
43 
44 import com.android.compatibility.common.util.ApiTest;
45 
46 import com.google.common.util.concurrent.AbstractFuture;
47 
48 import java.io.FileDescriptor;
49 import java.io.Serializable;
50 import java.util.ArrayList;
51 import java.util.Arrays;
52 import java.util.Collection;
53 import java.util.HashMap;
54 import java.util.HashSet;
55 import java.util.Map;
56 import java.util.Set;
57 import java.util.concurrent.ExecutionException;
58 import java.util.concurrent.TimeUnit;
59 import java.util.concurrent.TimeoutException;
60 
61 public class ParcelTest extends AndroidTestCase {
62 
testObtain()63     public void testObtain() {
64         Parcel p1 = Parcel.obtain();
65         assertNotNull(p1);
66         Parcel p2 = Parcel.obtain();
67         assertNotNull(p2);
68         Parcel p3 = Parcel.obtain();
69         assertNotNull(p3);
70         Parcel p4 = Parcel.obtain();
71         assertNotNull(p4);
72         Parcel p5 = Parcel.obtain();
73         assertNotNull(p5);
74         Parcel p6 = Parcel.obtain();
75         assertNotNull(p6);
76         Parcel p7 = Parcel.obtain();
77         assertNotNull(p7);
78 
79         p1.recycle();
80         p2.recycle();
81         p3.recycle();
82         p4.recycle();
83         p5.recycle();
84         p6.recycle();
85         p7.recycle();
86     }
87 
testAppendFrom()88     public void testAppendFrom() {
89         Parcel p;
90         Parcel p2;
91         int d1;
92         int d2;
93 
94         p = Parcel.obtain();
95         d1 = p.dataPosition();
96         p.writeInt(7);
97         p.writeInt(5);
98         d2 = p.dataPosition();
99         p2 = Parcel.obtain();
100         p2.appendFrom(p, d1, d2 - d1);
101         p2.setDataPosition(0);
102         assertEquals(7, p2.readInt());
103         assertEquals(5, p2.readInt());
104         p2.recycle();
105         p.recycle();
106     }
107 
testDataAvail()108     public void testDataAvail() {
109         Parcel p;
110 
111         p = Parcel.obtain();
112         p.writeInt(7); // size 4
113         p.writeInt(5); // size 4
114         p.writeLong(7L); // size 8
115         p.writeString("7L"); // size 12
116         p.setDataPosition(0);
117         assertEquals(p.dataSize(), p.dataAvail());
118         p.readInt();
119         assertEquals(p.dataSize() - p.dataPosition(), p.dataAvail());
120         p.readInt();
121         assertEquals(p.dataSize() - p.dataPosition(), p.dataAvail());
122         p.readLong();
123         assertEquals(p.dataSize() - p.dataPosition(), p.dataAvail());
124         p.readString();
125         assertEquals(p.dataSize() - p.dataPosition(), p.dataAvail());
126         p.recycle();
127     }
128 
testDataCapacity()129     public void testDataCapacity() {
130         Parcel p;
131 
132         p = Parcel.obtain();
133         assertEquals(0, p.dataCapacity());
134         p.writeInt(7); // size 4
135         int dC1 = p.dataCapacity();
136         p.writeDouble(2.19);
137         int dC2 = p.dataCapacity();
138         assertTrue(dC2 >= dC1);
139         p.recycle();
140     }
141 
testSetDataCapacity()142     public void testSetDataCapacity() {
143         Parcel p;
144 
145         p = Parcel.obtain();
146         assertEquals(0, p.dataCapacity());
147         p.setDataCapacity(2);
148         assertEquals(2, p.dataCapacity());
149         p.setDataCapacity(1);
150         assertEquals(2, p.dataCapacity());
151         p.setDataCapacity(3);
152         assertEquals(3, p.dataCapacity());
153         p.recycle();
154     }
155 
testDataPosition()156     public void testDataPosition() {
157         Parcel p;
158 
159         p = Parcel.obtain();
160         assertEquals(0, p.dataPosition());
161         p.writeInt(7); // size 4
162         int dP1 = p.dataPosition();
163         p.writeLong(7L); // size 8
164         int dP2 = p.dataPosition();
165         assertTrue(dP2 > dP1);
166         p.recycle();
167     }
168 
testSetDataPosition()169     public void testSetDataPosition() {
170         Parcel p;
171 
172         p = Parcel.obtain();
173         assertEquals(0, p.dataSize());
174         assertEquals(0, p.dataPosition());
175         p.setDataPosition(4);
176         assertEquals(4, p.dataPosition());
177         p.setDataPosition(7);
178         assertEquals(7, p.dataPosition());
179         p.setDataPosition(0);
180         p.writeInt(7);
181         assertEquals(4, p.dataSize());
182         p.setDataPosition(4);
183         assertEquals(4, p.dataPosition());
184         p.setDataPosition(7);
185         assertEquals(7, p.dataPosition());
186         p.recycle();
187     }
188 
testDataSize()189     public void testDataSize() {
190         Parcel p;
191 
192         p = Parcel.obtain();
193         assertEquals(0, p.dataSize());
194         p.writeInt(7); // size 4
195         assertEquals(4, p.dataSize());
196         p.writeInt(5); // size 4
197         assertEquals(8, p.dataSize());
198         p.writeLong(7L); // size 8
199         assertEquals(16, p.dataSize());
200         p.recycle();
201     }
202 
testSetDataSize()203     public void testSetDataSize() {
204         Parcel p;
205 
206         p = Parcel.obtain();
207         assertEquals(0, p.dataSize());
208         p.setDataSize(5);
209         assertEquals(5, p.dataSize());
210         p.setDataSize(3);
211         assertEquals(3, p.dataSize());
212 
213         p.writeInt(3);
214         assertEquals(4, p.dataSize());
215         p.setDataSize(5);
216         assertEquals(5, p.dataSize());
217         p.setDataSize(3);
218         assertEquals(3, p.dataSize());
219         p.recycle();
220     }
221 
testObtainWithBinder()222     public void testObtainWithBinder() {
223         Parcel p = Parcel.obtain(new Binder("anything"));
224         // testing does not throw an exception, Parcel still works
225 
226         final int kTest = 17;
227         p.writeInt(kTest);
228         p.setDataPosition(0);
229         assertEquals(kTest, p.readInt());
230 
231         p.recycle();
232     }
233 
testEnforceInterface()234     public void testEnforceInterface() {
235         Parcel p;
236         String s = "IBinder interface token";
237 
238         p = Parcel.obtain();
239         p.writeInterfaceToken(s);
240         p.setDataPosition(0);
241         try {
242             p.enforceInterface("");
243             fail("Should throw an SecurityException");
244         } catch (SecurityException e) {
245             //expected
246         }
247         p.recycle();
248 
249         p = Parcel.obtain();
250         p.writeInterfaceToken(s);
251         p.setDataPosition(0);
252         p.enforceInterface(s);
253         p.recycle();
254     }
255 
testEnforceNoDataAvail()256     public void testEnforceNoDataAvail(){
257         final Parcel p = Parcel.obtain();
258         p.writeInt(1);
259         p.writeString("test");
260 
261         p.setDataPosition(0);
262         p.readInt();
263         Throwable error = assertThrows(BadParcelableException.class, () -> p.enforceNoDataAvail());
264         assertTrue(error.getMessage().contains("Parcel data not fully consumed"));
265 
266         p.readString();
267         p.enforceNoDataAvail();
268         p.recycle();
269     }
270 
testMarshall()271     public void testMarshall() {
272         final byte[] c = {Byte.MAX_VALUE, (byte) 111, (byte) 11, (byte) 1, (byte) 0,
273                     (byte) -1, (byte) -11, (byte) -111, Byte.MIN_VALUE};
274 
275         Parcel p1 = Parcel.obtain();
276         p1.writeByteArray(c);
277         p1.setDataPosition(0);
278         byte[] d1 = p1.marshall();
279 
280         Parcel p2 = Parcel.obtain();
281         p2.unmarshall(d1, 0, d1.length);
282         p2.setDataPosition(0);
283         byte[] d2 = new byte[c.length];
284         p2.readByteArray(d2);
285 
286         for (int i = 0; i < c.length; i++) {
287             assertEquals(c[i], d2[i]);
288         }
289 
290         p1.recycle();
291         p2.recycle();
292     }
293 
294     @SuppressWarnings("unchecked")
testReadValue()295     public void testReadValue() {
296         Parcel p;
297         MockClassLoader mcl = new MockClassLoader();
298 
299         // test null
300         p = Parcel.obtain();
301         p.writeValue(null);
302         p.setDataPosition(0);
303         assertNull(p.readValue(mcl));
304         p.recycle();
305 
306         // test String
307         p = Parcel.obtain();
308         p.writeValue("String");
309         p.setDataPosition(0);
310         assertEquals("String", p.readValue(mcl));
311         p.recycle();
312 
313         // test Integer
314         p = Parcel.obtain();
315         p.writeValue(Integer.MAX_VALUE);
316         p.setDataPosition(0);
317         assertEquals(Integer.MAX_VALUE, p.readValue(mcl));
318         p.recycle();
319 
320         // test Map
321         HashMap map = new HashMap();
322         HashMap map2;
323         map.put("string", "String");
324         map.put("int", Integer.MAX_VALUE);
325         map.put("boolean", true);
326         p = Parcel.obtain();
327         p.writeValue(map);
328         p.setDataPosition(0);
329         map2 = (HashMap) p.readValue(mcl);
330         assertNotNull(map2);
331         assertEquals(map.size(), map2.size());
332         assertEquals("String", map.get("string"));
333         assertEquals(Integer.MAX_VALUE, map.get("int"));
334         assertEquals(true, map.get("boolean"));
335         p.recycle();
336 
337         // test Bundle
338         Bundle bundle = new Bundle();
339         bundle.putBoolean("boolean", true);
340         bundle.putInt("int", Integer.MAX_VALUE);
341         bundle.putString("string", "String");
342         Bundle bundle2;
343         p = Parcel.obtain();
344         p.writeValue(bundle);
345         p.setDataPosition(0);
346         bundle2 = (Bundle) p.readValue(mcl);
347         assertNotNull(bundle2);
348         assertEquals(true, bundle2.getBoolean("boolean"));
349         assertEquals(Integer.MAX_VALUE, bundle2.getInt("int"));
350         assertEquals("String", bundle2.getString("string"));
351         p.recycle();
352 
353         // test Parcelable
354         final String signatureString  = "1234567890abcdef";
355         Signature s = new Signature(signatureString);
356         p = Parcel.obtain();
357         p.writeValue(s);
358         p.setDataPosition(0);
359         assertEquals(s, p.readValue(mcl));
360         p.recycle();
361 
362         // test Short
363         p = Parcel.obtain();
364         p.writeValue(Short.MAX_VALUE);
365         p.setDataPosition(0);
366         assertEquals(Short.MAX_VALUE, p.readValue(mcl));
367         p.recycle();
368 
369         // test Long
370         p = Parcel.obtain();
371         p.writeValue(Long.MAX_VALUE);
372         p.setDataPosition(0);
373         assertEquals(Long.MAX_VALUE, p.readValue(mcl));
374         p.recycle();
375 
376         // test Float
377         p = Parcel.obtain();
378         p.writeValue(Float.MAX_VALUE);
379         p.setDataPosition(0);
380         assertEquals(Float.MAX_VALUE, p.readValue(mcl));
381         p.recycle();
382 
383         // test Double
384         p = Parcel.obtain();
385         p.writeValue(Double.MAX_VALUE);
386         p.setDataPosition(0);
387         assertEquals(Double.MAX_VALUE, p.readValue(mcl));
388         p.recycle();
389 
390         // test Boolean
391         p = Parcel.obtain();
392         p.writeValue(true);
393         p.writeValue(false);
394         p.setDataPosition(0);
395         assertTrue((Boolean) p.readValue(mcl));
396         assertFalse((Boolean) p.readValue(mcl));
397         p.recycle();
398 
399         // test CharSequence
400         p = Parcel.obtain();
401         p.writeValue((CharSequence) "CharSequence");
402         p.setDataPosition(0);
403         assertEquals("CharSequence", p.readValue(mcl));
404         p.recycle();
405 
406         // test List
407         ArrayList arrayList2 = new ArrayList();
408         arrayList2.add(Integer.MAX_VALUE);
409         arrayList2.add(true);
410         arrayList2.add(Long.MAX_VALUE);
411         ArrayList arrayList = new ArrayList();
412         p = Parcel.obtain();
413         p.writeValue(arrayList2);
414         p.setDataPosition(0);
415         assertEquals(0, arrayList.size());
416         arrayList = (ArrayList) p.readValue(mcl);
417         assertEquals(3, arrayList.size());
418         for (int i = 0; i < arrayList.size(); i++) {
419             assertEquals(arrayList.get(i), arrayList2.get(i));
420         }
421         p.recycle();
422 
423         // test SparseArray
424         SparseArray<Object> sparseArray = new SparseArray<Object>();
425         sparseArray.put(3, "String");
426         sparseArray.put(2, Long.MAX_VALUE);
427         sparseArray.put(4, Float.MAX_VALUE);
428         sparseArray.put(0, Integer.MAX_VALUE);
429         sparseArray.put(1, true);
430         sparseArray.put(10, true);
431         SparseArray<Object> sparseArray2;
432         p = Parcel.obtain();
433         p.writeValue(sparseArray);
434         p.setDataPosition(0);
435         sparseArray2 = (SparseArray<Object>) p.readValue(mcl);
436         assertNotNull(sparseArray2);
437         assertEquals(sparseArray.size(), sparseArray2.size());
438         assertEquals(sparseArray.get(0), sparseArray2.get(0));
439         assertEquals(sparseArray.get(1), sparseArray2.get(1));
440         assertEquals(sparseArray.get(2), sparseArray2.get(2));
441         assertEquals(sparseArray.get(3), sparseArray2.get(3));
442         assertEquals(sparseArray.get(4), sparseArray2.get(4));
443         assertEquals(sparseArray.get(10), sparseArray2.get(10));
444         p.recycle();
445 
446         // test boolean[]
447         boolean[] booleanArray  = {true, false, true, false};
448         boolean[] booleanArray2 = new boolean[booleanArray.length];
449         p = Parcel.obtain();
450         p.writeValue(booleanArray);
451         p.setDataPosition(0);
452         booleanArray2 = (boolean[]) p.readValue(mcl);
453         for (int i = 0; i < booleanArray.length; i++) {
454             assertEquals(booleanArray[i], booleanArray2[i]);
455         }
456         p.recycle();
457 
458         // test byte[]
459         byte[] byteArray = {Byte.MAX_VALUE, (byte) 111, (byte) 11, (byte) 1, (byte) 0,
460                 (byte) -1, (byte) -11, (byte) -111, Byte.MIN_VALUE};
461         byte[] byteArray2 = new byte[byteArray.length];
462         p = Parcel.obtain();
463         p.writeValue(byteArray);
464         p.setDataPosition(0);
465         byteArray2 = (byte[]) p.readValue(mcl);
466         for (int i = 0; i < byteArray.length; i++) {
467             assertEquals(byteArray[i], byteArray2[i]);
468         }
469         p.recycle();
470 
471         // test string[]
472         String[] stringArray = {"",
473                 "a",
474                 "Hello, Android!",
475                 "A long string that is used to test the api readStringArray(),"};
476         String[] stringArray2 = new String[stringArray.length];
477         p = Parcel.obtain();
478         p.writeValue(stringArray);
479         p.setDataPosition(0);
480         stringArray2 = (String[]) p.readValue(mcl);
481         for (int i = 0; i < stringArray.length; i++) {
482             assertEquals(stringArray[i], stringArray2[i]);
483         }
484         p.recycle();
485 
486         // test IBinder
487         Binder binder;
488         Binder binder2 = new Binder();
489         p = Parcel.obtain();
490         p.writeValue(binder2);
491         p.setDataPosition(0);
492         binder = (Binder) p.readValue(mcl);
493         assertEquals(binder2, binder);
494         p.recycle();
495 
496         // test Parcelable[]
497         Signature[] signatures = {new Signature("1234"),
498                 new Signature("ABCD"),
499                 new Signature("abcd")};
500         Parcelable[] signatures2;
501         p = Parcel.obtain();
502         p.writeValue(signatures);
503         p.setDataPosition(0);
504         signatures2 = (Parcelable[]) p.readValue(mcl);
505         for (int i = 0; i < signatures.length; i++) {
506             assertEquals(signatures[i], signatures2[i]);
507         }
508         p.recycle();
509 
510         // test Object
511         Object[] objects = new Object[5];
512         objects[0] = Integer.MAX_VALUE;
513         objects[1] = true;
514         objects[2] = Long.MAX_VALUE;
515         objects[3] = "String";
516         objects[4] = Float.MAX_VALUE;
517         Object[] objects2;
518         p = Parcel.obtain();
519         p.writeValue(objects);
520         p.setDataPosition(0);
521         objects2 = (Object[]) p.readValue(mcl);
522         assertNotNull(objects2);
523         for (int i = 0; i < objects2.length; i++) {
524             assertEquals(objects[i], objects2[i]);
525         }
526         p.recycle();
527 
528         // test int[]
529         int[] intArray = {111, 11, 1, 0, -1, -11, -111};
530         int[] intArray2 = new int[intArray.length];
531         p = Parcel.obtain();
532         p.writeValue(intArray);
533         p.setDataPosition(0);
534         intArray2= (int[]) p.readValue(mcl);
535         assertNotNull(intArray2);
536         for (int i = 0; i < intArray2.length; i++) {
537             assertEquals(intArray[i], intArray2[i]);
538         }
539         p.recycle();
540 
541         // test long[]
542         long[] longArray = {111L, 11L, 1L, 0L, -1L, -11L, -111L};
543         long[] longArray2 = new long[longArray.length];
544         p = Parcel.obtain();
545         p.writeValue(longArray);
546         p.setDataPosition(0);
547         longArray2= (long[]) p.readValue(mcl);
548         assertNotNull(longArray2);
549         for (int i = 0; i < longArray2.length; i++) {
550             assertEquals(longArray[i], longArray2[i]);
551         }
552         p.recycle();
553 
554         // test byte
555         p = Parcel.obtain();
556         p.writeValue(Byte.MAX_VALUE);
557         p.setDataPosition(0);
558         assertEquals(Byte.MAX_VALUE, p.readValue(mcl));
559         p.recycle();
560 
561         // test Serializable
562         p = Parcel.obtain();
563         p.writeValue((Serializable) "Serializable");
564         p.setDataPosition(0);
565         assertEquals("Serializable", p.readValue(mcl));
566         p.recycle();
567     }
568 
testReadByte()569     public void testReadByte() {
570         Parcel p;
571 
572         p = Parcel.obtain();
573         p.writeByte((byte) 0);
574         p.setDataPosition(0);
575         assertEquals((byte) 0, p.readByte());
576         p.recycle();
577 
578         p = Parcel.obtain();
579         p.writeByte((byte) 1);
580         p.setDataPosition(0);
581         assertEquals((byte) 1, p.readByte());
582         p.recycle();
583 
584         p = Parcel.obtain();
585         p.writeByte((byte) -1);
586         p.setDataPosition(0);
587         assertEquals((byte) -1, p.readByte());
588         p.recycle();
589 
590         p = Parcel.obtain();
591         p.writeByte(Byte.MAX_VALUE);
592         p.setDataPosition(0);
593         assertEquals(Byte.MAX_VALUE, p.readByte());
594         p.recycle();
595 
596         p = Parcel.obtain();
597         p.writeByte(Byte.MIN_VALUE);
598         p.setDataPosition(0);
599         assertEquals(Byte.MIN_VALUE, p.readByte());
600         p.recycle();
601 
602         p = Parcel.obtain();
603         p.writeByte(Byte.MAX_VALUE);
604         p.writeByte((byte) 11);
605         p.writeByte((byte) 1);
606         p.writeByte((byte) 0);
607         p.writeByte((byte) -1);
608         p.writeByte((byte) -11);
609         p.writeByte(Byte.MIN_VALUE);
610         p.setDataPosition(0);
611         assertEquals(Byte.MAX_VALUE, p.readByte());
612         assertEquals((byte) 11, p.readByte());
613         assertEquals((byte) 1, p.readByte());
614         assertEquals((byte) 0, p.readByte());
615         assertEquals((byte) -1, p.readByte());
616         assertEquals((byte) -11, p.readByte());
617         assertEquals(Byte.MIN_VALUE, p.readByte());
618         p.recycle();
619     }
620 
testReadByteArray()621     public void testReadByteArray() {
622         Parcel p;
623 
624         byte[] a = {(byte) 21};
625         byte[] b = new byte[a.length];
626 
627         byte[] c = {Byte.MAX_VALUE, (byte) 111, (byte) 11, (byte) 1, (byte) 0,
628                     (byte) -1, (byte) -11, (byte) -111, Byte.MIN_VALUE};
629         byte[] d = new byte[c.length];
630 
631         // test write null
632         p = Parcel.obtain();
633         p.writeByteArray(null);
634         p.setDataPosition(0);
635         try {
636             p.readByteArray(null);
637             fail("Should throw a RuntimeException");
638         } catch (RuntimeException e) {
639             //expected
640         }
641 
642         p.setDataPosition(0);
643         try {
644             p.readByteArray(b);
645             fail("Should throw a RuntimeException");
646         } catch (RuntimeException e) {
647             //expected
648         }
649         p.recycle();
650 
651         // test write byte array with length: 1
652         p = Parcel.obtain();
653         p.writeByteArray(a);
654         p.setDataPosition(0);
655         try {
656             p.readByteArray(d);
657             fail("Should throw a RuntimeException");
658         } catch (RuntimeException e) {
659             //expected
660         }
661 
662         p.setDataPosition(0);
663         p.readByteArray(b);
664         for (int i = 0; i < a.length; i++) {
665             assertEquals(a[i], b[i]);
666         }
667         p.recycle();
668 
669         // test write byte array with length: 9
670         p = Parcel.obtain();
671         p.writeByteArray(c);
672         p.setDataPosition(0);
673         try {
674             p.readByteArray(b);
675             fail("Should throw a RuntimeException");
676         } catch (RuntimeException e) {
677             //expected
678         }
679 
680         p.setDataPosition(0);
681         p.readByteArray(d);
682         for (int i = 0; i < c.length; i++) {
683             assertEquals(c[i], d[i]);
684         }
685         p.recycle();
686 
687         // Test array bounds checks (null already checked above).
688         p = Parcel.obtain();
689         try {
690             p.writeByteArray(c, -1, 1); // Negative offset.
691             fail();
692         } catch (RuntimeException expected) {
693         }
694         try {
695             p.writeByteArray(c, 0, -1); // Negative count.
696             fail();
697         } catch (RuntimeException expected) {
698         }
699         try {
700             p.writeByteArray(c, c.length + 1, 1); // High offset.
701             fail();
702         } catch (RuntimeException expected) {
703         }
704         try {
705             p.writeByteArray(c, 0, c.length + 1); // High count.
706             fail();
707         } catch (RuntimeException expected) {
708         }
709         p.recycle();
710     }
711 
testWriteBlob()712     public void testWriteBlob() {
713         Parcel p;
714 
715         byte[] shortBytes = {(byte) 21};
716         // Create a byte array with 70 KiB to make sure it is large enough to be saved into Android
717         // Shared Memory. The native blob inplace limit is 16 KiB. Also make it larger than the
718         // IBinder.MAX_IPC_SIZE which is 64 KiB.
719         byte[] largeBytes = new byte[70 * 1024];
720         for (int i = 0; i < largeBytes.length; i++) {
721             largeBytes[i] = (byte) (i / Byte.MAX_VALUE);
722         }
723         // test write null
724         p = Parcel.obtain();
725         p.writeBlob(null, 0, 2);
726         p.setDataPosition(0);
727         byte[] outputBytes = p.readBlob();
728         assertNull(outputBytes);
729         p.recycle();
730 
731         // test write short bytes
732         p = Parcel.obtain();
733         p.writeBlob(shortBytes, 0, 1);
734         p.setDataPosition(0);
735         assertEquals(shortBytes[0], p.readBlob()[0]);
736         p.recycle();
737 
738         // test write large bytes
739         p = Parcel.obtain();
740         p.writeBlob(largeBytes, 0, largeBytes.length);
741         p.setDataPosition(0);
742         outputBytes = p.readBlob();
743         for (int i = 0; i < largeBytes.length; i++) {
744             assertEquals(largeBytes[i], outputBytes[i]);
745         }
746         p.recycle();
747     }
748 
testWriteByteArray()749     public void testWriteByteArray() {
750         Parcel p;
751 
752         byte[] a = {(byte) 21};
753         byte[] b = new byte[a.length];
754 
755         byte[] c = {Byte.MAX_VALUE, (byte) 111, (byte) 11, (byte) 1, (byte) 0,
756                     (byte) -1, (byte) -11, (byte) -111, Byte.MIN_VALUE};
757         byte[] d = new byte[c.length - 2];
758 
759         // test write null
760         p = Parcel.obtain();
761         p.writeByteArray(null, 0, 2);
762         p.setDataPosition(0);
763         try {
764             p.readByteArray(null);
765             fail("Should throw a RuntimeException");
766         } catch (RuntimeException e) {
767             //expected
768         }
769 
770         p.setDataPosition(0);
771         try {
772             p.readByteArray(b);
773             fail("Should throw a RuntimeException");
774         } catch (RuntimeException e) {
775             //expected
776         }
777         p.recycle();
778 
779         // test with wrong offset and length
780         p = Parcel.obtain();
781         try {
782             p.writeByteArray(a, 0, 2);
783             fail("Should throw a ArrayIndexOutOfBoundsException");
784         } catch (ArrayIndexOutOfBoundsException e) {
785             //expected
786         }
787         p.recycle();
788 
789         p = Parcel.obtain();
790         try {
791             p.writeByteArray(a, -1, 1);
792             fail("Should throw a ArrayIndexOutOfBoundsException");
793         } catch (ArrayIndexOutOfBoundsException e) {
794             //expected
795         }
796         p.recycle();
797 
798         p = Parcel.obtain();
799         try {
800             p.writeByteArray(a, 0, -1);
801             fail("Should throw a ArrayIndexOutOfBoundsException");
802         } catch (ArrayIndexOutOfBoundsException e) {
803             //expected
804         }
805         p.recycle();
806 
807         // test write byte array with length: 1
808         p = Parcel.obtain();
809         p.writeByteArray(a, 0 , 1);
810         p.setDataPosition(0);
811         try {
812             p.readByteArray(d);
813             fail("Should throw a RuntimeException");
814         } catch (RuntimeException e) {
815             //expected
816         }
817 
818         p.setDataPosition(0);
819         p.readByteArray(b);
820         for (int i = 0; i < a.length; i++) {
821             assertEquals(a[i], b[i]);
822         }
823         p.recycle();
824 
825         // test write byte array with offset: 1, length: 7
826         p = Parcel.obtain();
827         p.writeByteArray(c, 1, 7);
828         p.setDataPosition(0);
829         try {
830             p.readByteArray(b);
831             fail("Should throw a RuntimeException");
832         } catch (RuntimeException e) {
833             //expected
834         }
835 
836         d = new byte[c.length - 2];
837         p.setDataPosition(0);
838         p.readByteArray(d);
839         for (int i = 0; i < d.length; i++) {
840             Log.d("Trace", "i=" + i + " d[i]=" + d[i]);
841         }
842         for (int i = 0; i < 7; i++) {
843             assertEquals(c[i + 1], d[i]);
844         }
845         p.recycle();
846     }
847 
testCreateByteArray()848     public void testCreateByteArray() {
849         Parcel p;
850 
851         byte[] a = {(byte) 21};
852         byte[] b;
853 
854         byte[] c = {Byte.MAX_VALUE, (byte) 111, (byte) 11, (byte) 1, (byte) 0,
855                     (byte) -1, (byte) -11, (byte) -111, Byte.MIN_VALUE};
856         byte[] d;
857 
858         byte[] e = {};
859         byte[] f;
860 
861         // test write null
862         p = Parcel.obtain();
863         p.writeByteArray(null);
864         p.setDataPosition(0);
865         b = p.createByteArray();
866         assertNull(b);
867         p.recycle();
868 
869         // test write byte array with length: 0
870         p = Parcel.obtain();
871         p.writeByteArray(e);
872         p.setDataPosition(0);
873         f = p.createByteArray();
874         assertNotNull(f);
875         assertEquals(0, f.length);
876         p.recycle();
877 
878         // test write byte array with length: 1
879         p = Parcel.obtain();
880         p.writeByteArray(a);
881         p.setDataPosition(0);
882         b = p.createByteArray();
883         assertNotNull(b);
884         for (int i = 0; i < a.length; i++) {
885             assertEquals(a[i], b[i]);
886         }
887         p.recycle();
888 
889         // test write byte array with length: 9
890         p = Parcel.obtain();
891         p.writeByteArray(c);
892         p.setDataPosition(0);
893         d = p.createByteArray();
894         assertNotNull(d);
895         for (int i = 0; i < c.length; i++) {
896             assertEquals(c[i], d[i]);
897         }
898         p.recycle();
899     }
900 
testReadCharArray()901     public void testReadCharArray() {
902         Parcel p;
903 
904         char[] a = {'a'};
905         char[] b = new char[a.length];
906 
907         char[] c = {'a', Character.MAX_VALUE, Character.MIN_VALUE, Character.MAX_SURROGATE, Character.MIN_SURROGATE,
908                     Character.MAX_HIGH_SURROGATE, Character.MAX_LOW_SURROGATE,
909                     Character.MIN_HIGH_SURROGATE, Character.MIN_LOW_SURROGATE};
910         char[] d = new char[c.length];
911 
912         // test write null
913         p = Parcel.obtain();
914         p.writeCharArray(null);
915         p.setDataPosition(0);
916         try {
917             p.readCharArray(null);
918             fail("Should throw a RuntimeException");
919         } catch (RuntimeException e) {
920             //expected
921         }
922 
923         p.setDataPosition(0);
924         try {
925             p.readCharArray(b);
926             fail("Should throw a RuntimeException");
927         } catch (RuntimeException e) {
928             //expected
929         }
930         p.recycle();
931 
932         // test write char array with length: 1
933         p = Parcel.obtain();
934         p.writeCharArray(a);
935         p.setDataPosition(0);
936         try {
937             p.readCharArray(d);
938             fail("Should throw a RuntimeException");
939         } catch (RuntimeException e) {
940             //expected
941         }
942 
943         p.setDataPosition(0);
944         p.readCharArray(b);
945         for (int i = 0; i < a.length; i++) {
946             assertEquals(a[i], b[i]);
947         }
948         p.recycle();
949 
950         // test write char array with length: 9
951         p = Parcel.obtain();
952         p.writeCharArray(c);
953         p.setDataPosition(0);
954         try {
955             p.readCharArray(b);
956             fail("Should throw a RuntimeException");
957         } catch (RuntimeException e) {
958             //expected
959         }
960 
961         p.setDataPosition(0);
962         p.readCharArray(d);
963         for (int i = 0; i < c.length; i++) {
964             assertEquals(c[i], d[i]);
965         }
966         p.recycle();
967     }
968 
testCreateCharArray()969     public void testCreateCharArray() {
970         Parcel p;
971 
972         char[] a = {'a'};
973         char[] b;
974 
975         char[] c = {'a', Character.MAX_VALUE, Character.MIN_VALUE, Character.MAX_SURROGATE, Character.MIN_SURROGATE,
976                     Character.MAX_HIGH_SURROGATE, Character.MAX_LOW_SURROGATE,
977                     Character.MIN_HIGH_SURROGATE, Character.MIN_LOW_SURROGATE};
978         char[] d;
979 
980         char[] e = {};
981         char[] f;
982 
983         // test write null
984         p = Parcel.obtain();
985         p.writeCharArray(null);
986         p.setDataPosition(0);
987         b = p.createCharArray();
988         assertNull(b);
989         p.recycle();
990 
991         // test write char array with length: 1
992         p = Parcel.obtain();
993         p.writeCharArray(e);
994         p.setDataPosition(0);
995         f = p.createCharArray();
996         assertNotNull(e);
997         assertEquals(0, f.length);
998         p.recycle();
999 
1000         // test write char array with length: 1
1001         p = Parcel.obtain();
1002         p.writeCharArray(a);
1003         p.setDataPosition(0);
1004         b = p.createCharArray();
1005         assertNotNull(b);
1006         for (int i = 0; i < a.length; i++) {
1007             assertEquals(a[i], b[i]);
1008         }
1009         p.recycle();
1010 
1011         // test write char array with length: 9
1012         p = Parcel.obtain();
1013         p.writeCharArray(c);
1014         p.setDataPosition(0);
1015         d = p.createCharArray();
1016         assertNotNull(d);
1017         for (int i = 0; i < c.length; i++) {
1018             assertEquals(c[i], d[i]);
1019         }
1020         p.recycle();
1021     }
1022 
testReadInt()1023     public void testReadInt() {
1024         Parcel p;
1025 
1026         p = Parcel.obtain();
1027         p.writeInt(0);
1028         p.setDataPosition(0);
1029         assertEquals(0, p.readInt());
1030         p.recycle();
1031 
1032         p = Parcel.obtain();
1033         p.writeInt(1);
1034         p.setDataPosition(0);
1035         assertEquals(1, p.readInt());
1036         p.recycle();
1037 
1038         p = Parcel.obtain();
1039         p.writeInt(-1);
1040         p.setDataPosition(0);
1041         assertEquals(-1, p.readInt());
1042         p.recycle();
1043 
1044         p = Parcel.obtain();
1045         p.writeInt(Integer.MAX_VALUE);
1046         p.setDataPosition(0);
1047         assertEquals(Integer.MAX_VALUE, p.readInt());
1048         p.recycle();
1049 
1050         p = Parcel.obtain();
1051         p.writeInt(Integer.MIN_VALUE);
1052         p.setDataPosition(0);
1053         assertEquals(Integer.MIN_VALUE, p.readInt());
1054         p.recycle();
1055 
1056         p = Parcel.obtain();
1057         p.writeInt(Integer.MAX_VALUE);
1058         p.writeInt(11);
1059         p.writeInt(1);
1060         p.writeInt(0);
1061         p.writeInt(-1);
1062         p.writeInt(-11);
1063         p.writeInt(Integer.MIN_VALUE);
1064         p.setDataPosition(0);
1065         assertEquals(Integer.MAX_VALUE, p.readInt());
1066         assertEquals(11, p.readInt());
1067         assertEquals(1, p.readInt());
1068         assertEquals(0, p.readInt());
1069         assertEquals(-1, p.readInt());
1070         assertEquals(-11, p.readInt());
1071         assertEquals(Integer.MIN_VALUE, p.readInt());
1072         p.recycle();
1073     }
1074 
testReadIntArray()1075     public void testReadIntArray() {
1076         Parcel p;
1077 
1078         int[] a = {21};
1079         int[] b = new int[a.length];
1080 
1081         int[] c = {Integer.MAX_VALUE, 111, 11, 1, 0, -1, -11, -111, Integer.MIN_VALUE};
1082         int[] d = new int[c.length];
1083 
1084         // test write null
1085         p = Parcel.obtain();
1086         p.writeIntArray(null);
1087         p.setDataPosition(0);
1088         try {
1089             p.readIntArray(null);
1090             fail("Should throw a RuntimeException");
1091         } catch (RuntimeException e) {
1092             //expected
1093         }
1094 
1095         p.setDataPosition(0);
1096         try {
1097             p.readIntArray(b);
1098             fail("Should throw a RuntimeException");
1099         } catch (RuntimeException e) {
1100             //expected
1101         }
1102         p.recycle();
1103 
1104         // test write int array with length: 1
1105         p = Parcel.obtain();
1106         p.writeIntArray(a);
1107         p.setDataPosition(0);
1108         try {
1109             p.readIntArray(d);
1110             fail("Should throw a RuntimeException");
1111         } catch (RuntimeException e) {
1112             //expected
1113         }
1114 
1115         p.setDataPosition(0);
1116         p.readIntArray(b);
1117         for (int i = 0; i < a.length; i++) {
1118             assertEquals(a[i], b[i]);
1119         }
1120         p.recycle();
1121 
1122         // test write int array with length: 9
1123         p = Parcel.obtain();
1124         p.writeIntArray(c);
1125         p.setDataPosition(0);
1126         try {
1127             p.readIntArray(b);
1128             fail("Should throw a RuntimeException");
1129         } catch (RuntimeException e) {
1130             //expected
1131         }
1132 
1133         p.setDataPosition(0);
1134         p.readIntArray(d);
1135         for (int i = 0; i < c.length; i++) {
1136             assertEquals(c[i], d[i]);
1137         }
1138         p.recycle();
1139     }
1140 
testCreateIntArray()1141     public void testCreateIntArray() {
1142         Parcel p;
1143 
1144         int[] a = {21};
1145         int[] b;
1146 
1147         int[] c = {Integer.MAX_VALUE, 111, 11, 1, 0, -1, -11, -111, Integer.MIN_VALUE};
1148         int[] d;
1149 
1150         int[] e = {};
1151         int[] f;
1152 
1153         // test write null
1154         p = Parcel.obtain();
1155         p.writeIntArray(null);
1156         p.setDataPosition(0);
1157         b = p.createIntArray();
1158         assertNull(b);
1159         p.recycle();
1160 
1161         // test write int array with length: 0
1162         p = Parcel.obtain();
1163         p.writeIntArray(e);
1164         p.setDataPosition(0);
1165         f = p.createIntArray();
1166         assertNotNull(e);
1167         assertEquals(0, f.length);
1168         p.recycle();
1169 
1170         // test write int array with length: 1
1171         p = Parcel.obtain();
1172         p.writeIntArray(a);
1173         p.setDataPosition(0);
1174         b = p.createIntArray();
1175         assertNotNull(b);
1176         for (int i = 0; i < a.length; i++) {
1177             assertEquals(a[i], b[i]);
1178         }
1179         p.recycle();
1180 
1181         // test write int array with length: 9
1182         p = Parcel.obtain();
1183         p.writeIntArray(c);
1184         p.setDataPosition(0);
1185         d = p.createIntArray();
1186         assertNotNull(d);
1187         for (int i = 0; i < c.length; i++) {
1188             assertEquals(c[i], d[i]);
1189         }
1190         p.recycle();
1191     }
1192 
testReadLong()1193     public void testReadLong() {
1194         Parcel p;
1195 
1196         p = Parcel.obtain();
1197         p.writeLong(0L);
1198         p.setDataPosition(0);
1199         assertEquals(0, p.readLong());
1200         p.recycle();
1201 
1202         p = Parcel.obtain();
1203         p.writeLong(1L);
1204         p.setDataPosition(0);
1205         assertEquals(1, p.readLong());
1206         p.recycle();
1207 
1208         p = Parcel.obtain();
1209         p.writeLong(-1L);
1210         p.setDataPosition(0);
1211         assertEquals(-1L, p.readLong());
1212         p.recycle();
1213 
1214         p = Parcel.obtain();
1215         p.writeLong(Long.MAX_VALUE);
1216         p.writeLong(11L);
1217         p.writeLong(1L);
1218         p.writeLong(0L);
1219         p.writeLong(-1L);
1220         p.writeLong(-11L);
1221         p.writeLong(Long.MIN_VALUE);
1222         p.setDataPosition(0);
1223         assertEquals(Long.MAX_VALUE, p.readLong());
1224         assertEquals(11L, p.readLong());
1225         assertEquals(1L, p.readLong());
1226         assertEquals(0L, p.readLong());
1227         assertEquals(-1L, p.readLong());
1228         assertEquals(-11L, p.readLong());
1229         assertEquals(Long.MIN_VALUE, p.readLong());
1230         p.recycle();
1231     }
1232 
testReadLongArray()1233     public void testReadLongArray() {
1234         Parcel p;
1235 
1236         long[] a = {21L};
1237         long[] b = new long[a.length];
1238 
1239         long[] c = {Long.MAX_VALUE, 111L, 11L, 1L, 0L, -1L, -11L, -111L, Long.MIN_VALUE};
1240         long[] d = new long[c.length];
1241 
1242         // test write null
1243         p = Parcel.obtain();
1244         p.writeLongArray(null);
1245         p.setDataPosition(0);
1246         try {
1247             p.readLongArray(null);
1248             fail("Should throw a RuntimeException");
1249         } catch (RuntimeException e) {
1250             //expected
1251         }
1252 
1253         p.setDataPosition(0);
1254         try {
1255             p.readLongArray(b);
1256             fail("Should throw a RuntimeException");
1257         } catch (RuntimeException e) {
1258             //expected
1259         }
1260         p.recycle();
1261 
1262         // test write long array with length: 1
1263         p = Parcel.obtain();
1264         p.writeLongArray(a);
1265         p.setDataPosition(0);
1266         try {
1267             p.readLongArray(d);
1268             fail("Should throw a RuntimeException");
1269         } catch (RuntimeException e) {
1270             //expected
1271         }
1272 
1273         p.setDataPosition(0);
1274         p.readLongArray(b);
1275         for (int i = 0; i < a.length; i++) {
1276             assertEquals(a[i], b[i]);
1277         }
1278         p.recycle();
1279 
1280         // test write long array with length: 9
1281         p = Parcel.obtain();
1282         p.writeLongArray(c);
1283         p.setDataPosition(0);
1284         try {
1285             p.readLongArray(b);
1286             fail("Should throw a RuntimeException");
1287         } catch (RuntimeException e) {
1288             //expected
1289         }
1290 
1291         p.setDataPosition(0);
1292         p.readLongArray(d);
1293         for (int i = 0; i < c.length; i++) {
1294             assertEquals(c[i], d[i]);
1295         }
1296         p.recycle();
1297     }
1298 
testCreateLongArray()1299     public void testCreateLongArray() {
1300         Parcel p;
1301 
1302         long[] a = {21L};
1303         long[] b;
1304 
1305         long[] c = {Long.MAX_VALUE, 111L, 11L, 1L, 0L, -1L, -11L, -111L, Long.MIN_VALUE};
1306         long[] d;
1307 
1308         long[] e = {};
1309         long[] f;
1310 
1311         // test write null
1312         p = Parcel.obtain();
1313         p.writeLongArray(null);
1314         p.setDataPosition(0);
1315         b = p.createLongArray();
1316         assertNull(b);
1317         p.recycle();
1318 
1319         // test write long array with length: 0
1320         p = Parcel.obtain();
1321         p.writeLongArray(e);
1322         p.setDataPosition(0);
1323         f = p.createLongArray();
1324         assertNotNull(e);
1325         assertEquals(0, f.length);
1326         p.recycle();
1327 
1328         // test write long array with length: 1
1329         p = Parcel.obtain();
1330         p.writeLongArray(a);
1331         p.setDataPosition(0);
1332         b = p.createLongArray();
1333         assertNotNull(b);
1334         for (int i = 0; i < a.length; i++) {
1335             assertEquals(a[i], b[i]);
1336         }
1337         p.recycle();
1338 
1339         // test write long array with length: 9
1340         p = Parcel.obtain();
1341         p.writeLongArray(c);
1342         p.setDataPosition(0);
1343         d = p.createLongArray();
1344         assertNotNull(d);
1345         for (int i = 0; i < c.length; i++) {
1346             assertEquals(c[i], d[i]);
1347         }
1348         p.recycle();
1349     }
1350 
testReadFloat()1351     public void testReadFloat() {
1352         Parcel p;
1353 
1354         p = Parcel.obtain();
1355         p.writeFloat(.0f);
1356         p.setDataPosition(0);
1357         assertEquals(.0f, p.readFloat());
1358         p.recycle();
1359 
1360         p = Parcel.obtain();
1361         p.writeFloat(0.1f);
1362         p.setDataPosition(0);
1363         assertEquals(0.1f, p.readFloat());
1364         p.recycle();
1365 
1366         p = Parcel.obtain();
1367         p.writeFloat(-1.1f);
1368         p.setDataPosition(0);
1369         assertEquals(-1.1f, p.readFloat());
1370         p.recycle();
1371 
1372         p = Parcel.obtain();
1373         p.writeFloat(Float.MAX_VALUE);
1374         p.setDataPosition(0);
1375         assertEquals(Float.MAX_VALUE, p.readFloat());
1376         p.recycle();
1377 
1378         p = Parcel.obtain();
1379         p.writeFloat(Float.MIN_VALUE);
1380         p.setDataPosition(0);
1381         assertEquals(Float.MIN_VALUE, p.readFloat());
1382         p.recycle();
1383 
1384         p = Parcel.obtain();
1385         p.writeFloat(Float.MAX_VALUE);
1386         p.writeFloat(1.1f);
1387         p.writeFloat(0.1f);
1388         p.writeFloat(.0f);
1389         p.writeFloat(-0.1f);
1390         p.writeFloat(-1.1f);
1391         p.writeFloat(Float.MIN_VALUE);
1392         p.setDataPosition(0);
1393         assertEquals(Float.MAX_VALUE, p.readFloat());
1394         assertEquals(1.1f, p.readFloat());
1395         assertEquals(0.1f, p.readFloat());
1396         assertEquals(.0f, p.readFloat());
1397         assertEquals(-0.1f, p.readFloat());
1398         assertEquals(-1.1f, p.readFloat());
1399         assertEquals(Float.MIN_VALUE, p.readFloat());
1400         p.recycle();
1401     }
1402 
testReadFloatArray()1403     public void testReadFloatArray() {
1404         Parcel p;
1405 
1406         float[] a = {2.1f};
1407         float[] b = new float[a.length];
1408 
1409         float[] c = {Float.MAX_VALUE, 11.1f, 1.1f, 0.1f, .0f, -0.1f, -1.1f, -11.1f, Float.MIN_VALUE};
1410         float[] d = new float[c.length];
1411 
1412         // test write null
1413         p = Parcel.obtain();
1414         p.writeFloatArray(null);
1415         p.setDataPosition(0);
1416         try {
1417             p.readFloatArray(null);
1418             fail("Should throw a RuntimeException");
1419         } catch (RuntimeException e) {
1420             //expected
1421         }
1422 
1423         p.setDataPosition(0);
1424         try {
1425             p.readFloatArray(b);
1426             fail("Should throw a RuntimeException");
1427         } catch (RuntimeException e) {
1428             //expected
1429         }
1430         p.recycle();
1431 
1432         // test write float array with length: 1
1433         p = Parcel.obtain();
1434         p.writeFloatArray(a);
1435         p.setDataPosition(0);
1436         try {
1437             p.readFloatArray(d);
1438             fail("Should throw a RuntimeException");
1439         } catch (RuntimeException e) {
1440             //expected
1441         }
1442 
1443         p.setDataPosition(0);
1444         p.readFloatArray(b);
1445         for (int i = 0; i < a.length; i++) {
1446             assertEquals(a[i], b[i]);
1447         }
1448         p.recycle();
1449 
1450         // test write float array with length: 9
1451         p = Parcel.obtain();
1452         p.writeFloatArray(c);
1453         p.setDataPosition(0);
1454         try {
1455             p.readFloatArray(b);
1456             fail("Should throw a RuntimeException");
1457         } catch (RuntimeException e) {
1458             //expected
1459         }
1460 
1461         p.setDataPosition(0);
1462         p.readFloatArray(d);
1463         for (int i = 0; i < c.length; i++) {
1464             assertEquals(c[i], d[i]);
1465         }
1466         p.recycle();
1467     }
1468 
testCreateFloatArray()1469     public void testCreateFloatArray() {
1470         Parcel p;
1471 
1472         float[] a = {2.1f};
1473         float[] b;
1474 
1475         float[] c = {Float.MAX_VALUE, 11.1f, 1.1f, 0.1f, .0f, -0.1f, -1.1f, -11.1f, Float.MIN_VALUE};
1476         float[] d;
1477 
1478         float[] e = {};
1479         float[] f;
1480 
1481         // test write null
1482         p = Parcel.obtain();
1483         p.writeFloatArray(null);
1484         p.setDataPosition(0);
1485         b = p.createFloatArray();
1486         assertNull(b);
1487         p.recycle();
1488 
1489         // test write float array with length: 0
1490         p = Parcel.obtain();
1491         p.writeFloatArray(e);
1492         p.setDataPosition(0);
1493         f = p.createFloatArray();
1494         assertNotNull(f);
1495         assertEquals(0, f.length);
1496         p.recycle();
1497 
1498         // test write float array with length: 1
1499         p = Parcel.obtain();
1500         p.writeFloatArray(a);
1501         p.setDataPosition(0);
1502         b = p.createFloatArray();
1503         assertNotNull(b);
1504         for (int i = 0; i < a.length; i++) {
1505             assertEquals(a[i], b[i]);
1506         }
1507         p.recycle();
1508 
1509         // test write float array with length: 9
1510         p = Parcel.obtain();
1511         p.writeFloatArray(c);
1512         p.setDataPosition(0);
1513         d = p.createFloatArray();
1514         assertNotNull(d);
1515         for (int i = 0; i < c.length; i++) {
1516             assertEquals(c[i], d[i]);
1517         }
1518         p.recycle();
1519     }
1520 
testReadDouble()1521     public void testReadDouble() {
1522         Parcel p;
1523 
1524         p = Parcel.obtain();
1525         p.writeDouble(.0d);
1526         p.setDataPosition(0);
1527         assertEquals(.0d, p.readDouble());
1528         p.recycle();
1529 
1530         p = Parcel.obtain();
1531         p.writeDouble(0.1d);
1532         p.setDataPosition(0);
1533         assertEquals(0.1d, p.readDouble());
1534         p.recycle();
1535 
1536         p = Parcel.obtain();
1537         p.writeDouble(-1.1d);
1538         p.setDataPosition(0);
1539         assertEquals(-1.1d, p.readDouble());
1540         p.recycle();
1541 
1542         p = Parcel.obtain();
1543         p.writeDouble(Double.MAX_VALUE);
1544         p.setDataPosition(0);
1545         assertEquals(Double.MAX_VALUE, p.readDouble());
1546         p.recycle();
1547 
1548         p = Parcel.obtain();
1549         p.writeDouble(Double.MIN_VALUE);
1550         p.setDataPosition(0);
1551         assertEquals(Double.MIN_VALUE, p.readDouble());
1552         p.recycle();
1553 
1554         p = Parcel.obtain();
1555         p.writeDouble(Double.MAX_VALUE);
1556         p.writeDouble(1.1d);
1557         p.writeDouble(0.1d);
1558         p.writeDouble(.0d);
1559         p.writeDouble(-0.1d);
1560         p.writeDouble(-1.1d);
1561         p.writeDouble(Double.MIN_VALUE);
1562         p.setDataPosition(0);
1563         assertEquals(Double.MAX_VALUE, p.readDouble());
1564         assertEquals(1.1d, p.readDouble());
1565         assertEquals(0.1d, p.readDouble());
1566         assertEquals(.0d, p.readDouble());
1567         assertEquals(-0.1d, p.readDouble());
1568         assertEquals(-1.1d, p.readDouble());
1569         assertEquals(Double.MIN_VALUE, p.readDouble());
1570         p.recycle();
1571     }
1572 
testReadDoubleArray()1573     public void testReadDoubleArray() {
1574         Parcel p;
1575 
1576         double[] a = {2.1d};
1577         double[] b = new double[a.length];
1578 
1579         double[] c = {Double.MAX_VALUE, 11.1d, 1.1d, 0.1d, .0d, -0.1d, -1.1d, -11.1d, Double.MIN_VALUE};
1580         double[] d = new double[c.length];
1581 
1582         // test write null
1583         p = Parcel.obtain();
1584         p.writeDoubleArray(null);
1585         p.setDataPosition(0);
1586         try {
1587             p.readDoubleArray(null);
1588             fail("Should throw a RuntimeException");
1589         } catch (RuntimeException e) {
1590             //expected
1591         }
1592 
1593         p.setDataPosition(0);
1594         try {
1595             p.readDoubleArray(b);
1596             fail("Should throw a RuntimeException");
1597         } catch (RuntimeException e) {
1598             //expected
1599         }
1600         p.recycle();
1601 
1602         // test write double array with length: 1
1603         p = Parcel.obtain();
1604         p.writeDoubleArray(a);
1605         p.setDataPosition(0);
1606         try {
1607             p.readDoubleArray(d);
1608             fail("Should throw a RuntimeException");
1609         } catch (RuntimeException e) {
1610             //expected
1611         }
1612 
1613         p.setDataPosition(0);
1614         p.readDoubleArray(b);
1615         for (int i = 0; i < a.length; i++) {
1616             assertEquals(a[i], b[i]);
1617         }
1618         p.recycle();
1619 
1620         // test write double array with length: 9
1621         p = Parcel.obtain();
1622         p.writeDoubleArray(c);
1623         p.setDataPosition(0);
1624         try {
1625             p.readDoubleArray(b);
1626             fail("Should throw a RuntimeException");
1627         } catch (RuntimeException e) {
1628             //expected
1629         }
1630 
1631         p.setDataPosition(0);
1632         p.readDoubleArray(d);
1633         for (int i = 0; i < c.length; i++) {
1634             assertEquals(c[i], d[i]);
1635         }
1636         p.recycle();
1637     }
1638 
testCreateDoubleArray()1639     public void testCreateDoubleArray() {
1640         Parcel p;
1641 
1642         double[] a = {2.1d};
1643         double[] b;
1644 
1645         double[] c = {
1646                 Double.MAX_VALUE, 11.1d, 1.1d, 0.1d, .0d, -0.1d, -1.1d, -11.1d, Double.MIN_VALUE
1647         };
1648         double[] d;
1649 
1650         double[] e = {};
1651         double[] f;
1652 
1653         // test write null
1654         p = Parcel.obtain();
1655         p.writeDoubleArray(null);
1656         p.setDataPosition(0);
1657         b = p.createDoubleArray();
1658         assertNull(b);
1659         p.recycle();
1660 
1661         // test write double array with length: 0
1662         p = Parcel.obtain();
1663         p.writeDoubleArray(e);
1664         p.setDataPosition(0);
1665         f = p.createDoubleArray();
1666         assertNotNull(f);
1667         assertEquals(0, f.length);
1668         p.recycle();
1669 
1670         // test write double array with length: 1
1671         p = Parcel.obtain();
1672         p.writeDoubleArray(a);
1673         p.setDataPosition(0);
1674         b = p.createDoubleArray();
1675         assertNotNull(b);
1676         for (int i = 0; i < a.length; i++) {
1677             assertEquals(a[i], b[i]);
1678         }
1679         p.recycle();
1680 
1681         // test write double array with length: 9
1682         p = Parcel.obtain();
1683         p.writeDoubleArray(c);
1684         p.setDataPosition(0);
1685         d = p.createDoubleArray();
1686         assertNotNull(d);
1687         for (int i = 0; i < c.length; i++) {
1688             assertEquals(c[i], d[i]);
1689         }
1690         p.recycle();
1691     }
1692 
testReadBooleanArray()1693     public void testReadBooleanArray() {
1694         Parcel p;
1695 
1696         boolean[] a = {true};
1697         boolean[] b = new boolean[a.length];
1698 
1699         boolean[] c = {true, false, true, false};
1700         boolean[] d = new boolean[c.length];
1701 
1702         // test write null
1703         p = Parcel.obtain();
1704         p.writeBooleanArray(null);
1705         p.setDataPosition(0);
1706         try {
1707             p.readIntArray(null);
1708             fail("Should throw a RuntimeException");
1709         } catch (RuntimeException e) {
1710             //expected
1711         }
1712 
1713         p.setDataPosition(0);
1714         try {
1715             p.readBooleanArray(b);
1716             fail("Should throw a RuntimeException");
1717         } catch (RuntimeException e) {
1718             //expected
1719         }
1720         p.recycle();
1721 
1722         // test write boolean array with length: 1
1723         p = Parcel.obtain();
1724         p.writeBooleanArray(a);
1725         p.setDataPosition(0);
1726         try {
1727             p.readBooleanArray(d);
1728             fail("Should throw a RuntimeException");
1729         } catch (RuntimeException e) {
1730             //expected
1731         }
1732 
1733         p.setDataPosition(0);
1734         p.readBooleanArray(b);
1735         for (int i = 0; i < a.length; i++) {
1736             assertEquals(a[i], b[i]);
1737         }
1738         p.recycle();
1739 
1740         // test write boolean array with length: 4
1741         p = Parcel.obtain();
1742         p.writeBooleanArray(c);
1743         p.setDataPosition(0);
1744         try {
1745             p.readBooleanArray(b);
1746             fail("Should throw a RuntimeException");
1747         } catch (RuntimeException e) {
1748             //expected
1749         }
1750 
1751         p.setDataPosition(0);
1752         p.readBooleanArray(d);
1753         for (int i = 0; i < c.length; i++) {
1754             assertEquals(c[i], d[i]);
1755         }
1756         p.recycle();
1757     }
1758 
testCreateBooleanArray()1759     public void testCreateBooleanArray() {
1760         Parcel p;
1761 
1762         boolean[] a = {true};
1763         boolean[] b;
1764 
1765         boolean[] c = {true, false, true, false};
1766         boolean[] d;
1767 
1768         boolean[] e = {};
1769         boolean[] f;
1770 
1771         // test write null
1772         p = Parcel.obtain();
1773         p.writeBooleanArray(null);
1774         p.setDataPosition(0);
1775         b = p.createBooleanArray();
1776         assertNull(b);
1777         p.recycle();
1778 
1779         // test write boolean array with length: 0
1780         p = Parcel.obtain();
1781         p.writeBooleanArray(e);
1782         p.setDataPosition(0);
1783         f = p.createBooleanArray();
1784         assertNotNull(f);
1785         assertEquals(0, f.length);
1786         p.recycle();
1787 
1788         // test write boolean array with length: 1
1789         p = Parcel.obtain();
1790         p.writeBooleanArray(a);
1791 
1792         p.setDataPosition(0);
1793         b = p.createBooleanArray();
1794         assertNotNull(b);
1795         for (int i = 0; i < a.length; i++) {
1796             assertEquals(a[i], b[i]);
1797         }
1798         p.recycle();
1799 
1800         // test write boolean array with length: 4
1801         p = Parcel.obtain();
1802         p.writeBooleanArray(c);
1803         p.setDataPosition(0);
1804         d = p.createBooleanArray();
1805         assertNotNull(d);
1806         for (int i = 0; i < c.length; i++) {
1807             assertEquals(c[i], d[i]);
1808         }
1809         p.recycle();
1810     }
1811 
testReadString()1812     public void testReadString() {
1813         Parcel p;
1814         final String string = "Hello, Android!";
1815 
1816         // test write null
1817         p = Parcel.obtain();
1818         p.writeString(null);
1819         p.setDataPosition(0);
1820         assertNull(p.readString());
1821         p.recycle();
1822 
1823         p = Parcel.obtain();
1824         p.writeString("");
1825         p.setDataPosition(0);
1826         assertEquals("", p.readString());
1827         p.recycle();
1828 
1829         p = Parcel.obtain();
1830         p.writeString("a");
1831         p.setDataPosition(0);
1832         assertEquals("a", p.readString());
1833         p.recycle();
1834 
1835         p = Parcel.obtain();
1836         p.writeString(string);
1837         p.setDataPosition(0);
1838         assertEquals(string, p.readString());
1839         p.recycle();
1840 
1841         p = Parcel.obtain();
1842         p.writeString(string);
1843         p.writeString("a");
1844         p.writeString("");
1845         p.setDataPosition(0);
1846         assertEquals(string, p.readString());
1847         assertEquals("a", p.readString());
1848         assertEquals("", p.readString());
1849         p.recycle();
1850     }
1851 
testReadStringArray()1852     public void testReadStringArray() {
1853         Parcel p;
1854 
1855         String[] a = {"21"};
1856         String[] b = new String[a.length];
1857 
1858         String[] c = {"",
1859                 "a",
1860                 "Hello, Android!",
1861                 "A long string that is used to test the api readStringArray(),"};
1862         String[] d = new String[c.length];
1863 
1864         // test write null
1865         p = Parcel.obtain();
1866         p.writeStringArray(null);
1867         p.setDataPosition(0);
1868         try {
1869             p.readStringArray(null);
1870             fail("Should throw a RuntimeException");
1871         } catch (RuntimeException e) {
1872             //expected
1873         }
1874 
1875         p.setDataPosition(0);
1876         try {
1877             p.readStringArray(b);
1878             fail("Should throw a RuntimeException");
1879         } catch (RuntimeException e) {
1880             //expected
1881         }
1882         p.recycle();
1883 
1884         // test write String array with length: 1
1885         p = Parcel.obtain();
1886         p.writeStringArray(a);
1887         p.setDataPosition(0);
1888         try {
1889             p.readStringArray(d);
1890             fail("Should throw a RuntimeException");
1891         } catch (RuntimeException e) {
1892             //expected
1893         }
1894 
1895         p.setDataPosition(0);
1896         p.readStringArray(b);
1897         for (int i = 0; i < a.length; i++) {
1898             assertEquals(a[i], b[i]);
1899         }
1900         p.recycle();
1901 
1902         // test write String array with length: 9
1903         p = Parcel.obtain();
1904         p.writeStringArray(c);
1905         p.setDataPosition(0);
1906         try {
1907             p.readStringArray(b);
1908             fail("Should throw a RuntimeException");
1909         } catch (RuntimeException e) {
1910             //expected
1911         }
1912 
1913         p.setDataPosition(0);
1914         p.readStringArray(d);
1915         for (int i = 0; i < c.length; i++) {
1916             assertEquals(c[i], d[i]);
1917         }
1918         p.recycle();
1919     }
1920 
testCreateStringArray()1921     public void testCreateStringArray() {
1922         Parcel p;
1923 
1924         String[] a = {"21"};
1925         String[] b;
1926 
1927         String[] c = {"",
1928                 "a",
1929                 "Hello, Android!",
1930                 "A long string that is used to test the api readStringArray(),"};
1931         String[] d;
1932 
1933         String[] e = {};
1934         String[] f;
1935 
1936         // test write null
1937         p = Parcel.obtain();
1938         p.writeStringArray(null);
1939         p.setDataPosition(0);
1940         b = p.createStringArray();
1941         assertNull(b);
1942         p.recycle();
1943 
1944         // test write String array with length: 0
1945         p = Parcel.obtain();
1946         p.writeStringArray(e);
1947         p.setDataPosition(0);
1948         f = p.createStringArray();
1949         assertNotNull(e);
1950         assertEquals(0, f.length);
1951         p.recycle();
1952 
1953         // test write String array with length: 1
1954         p = Parcel.obtain();
1955         p.writeStringArray(a);
1956         p.setDataPosition(0);
1957         b = p.createStringArray();
1958         assertNotNull(b);
1959         for (int i = 0; i < a.length; i++) {
1960             assertEquals(a[i], b[i]);
1961         }
1962         p.recycle();
1963 
1964         // test write String array with length: 9
1965         p = Parcel.obtain();
1966         p.writeStringArray(c);
1967         p.setDataPosition(0);
1968         d = p.createStringArray();
1969         assertNotNull(d);
1970         for (int i = 0; i < c.length; i++) {
1971             assertEquals(c[i], d[i]);
1972         }
1973         p.recycle();
1974     }
1975 
testReadStringList()1976     public void testReadStringList() {
1977         Parcel p;
1978 
1979         ArrayList<String> a = new ArrayList<String>();
1980         a.add("21");
1981         ArrayList<String> b = new ArrayList<String>();
1982 
1983         ArrayList<String> c = new ArrayList<String>();
1984         c.add("");
1985         c.add("a");
1986         c.add("Hello, Android!");
1987         c.add("A long string that is used to test the api readStringList(),");
1988         ArrayList<String> d = new ArrayList<String>();
1989 
1990         // test write null
1991         p = Parcel.obtain();
1992         p.writeStringList(null);
1993         p.setDataPosition(0);
1994         try {
1995             p.readStringList(null);
1996             fail("Should throw a RuntimeException");
1997         } catch (RuntimeException e) {
1998             //expected
1999         }
2000 
2001         p.setDataPosition(0);
2002         p.readStringList(b);
2003         assertTrue(0 == b.size());
2004         p.recycle();
2005 
2006         // test write String array with length: 1
2007         p = Parcel.obtain();
2008         p.writeStringList(a);
2009         p.setDataPosition(0);
2010         assertTrue(c.size() > a.size());
2011         p.readStringList(c);
2012         assertTrue(c.size() == a.size());
2013         assertEquals(a, c);
2014 
2015         p.setDataPosition(0);
2016         assertTrue(0 == b.size() && 0 != a.size());
2017         p.readStringList(b);
2018         assertEquals(a, b);
2019         p.recycle();
2020 
2021         c = new ArrayList<String>();
2022         c.add("");
2023         c.add("a");
2024         c.add("Hello, Android!");
2025         c.add("A long string that is used to test the api readStringList(),");
2026         // test write String array with length: 4
2027         p = Parcel.obtain();
2028         p.writeStringList(c);
2029         p.setDataPosition(0);
2030 
2031         assertTrue(b.size() < c.size());
2032         p.readStringList(b);
2033         assertTrue(b.size() == c.size());
2034         assertEquals(c, b);
2035 
2036         p.setDataPosition(0);
2037         assertTrue(d.size() < c.size());
2038         p.readStringList(d);
2039         assertEquals(c, d);
2040         p.recycle();
2041     }
2042 
2043     public void testCreateStringArrayList() {
2044         Parcel p;
2045 
2046         ArrayList<String> a = new ArrayList<String>();
2047         a.add("21");
2048         ArrayList<String> b;
2049 
2050         ArrayList<String> c = new ArrayList<String>();
2051         c.add("");
2052         c.add("a");
2053         c.add("Hello, Android!");
2054         c.add("A long string that is used to test the api readStringList(),");
2055         ArrayList<String> d;
2056 
2057         ArrayList<String> e = new ArrayList<String>();
2058         ArrayList<String> f = null;
2059 
2060         // test write null
2061         p = Parcel.obtain();
2062         p.writeStringList(null);
2063         p.setDataPosition(0);
2064         b = p.createStringArrayList();
2065         assertNull(b);
2066         p.recycle();
2067 
2068         // test write String array with length: 0
2069         p = Parcel.obtain();
2070         p.writeStringList(e);
2071         p.setDataPosition(0);
2072         assertNull(f);
2073         f = p.createStringArrayList();
2074         assertNotNull(f);
2075         p.recycle();
2076 
2077         // test write String array with length: 1
2078         p = Parcel.obtain();
2079         p.writeStringList(a);
2080         p.setDataPosition(0);
2081         b = p.createStringArrayList();
2082         assertEquals(a, b);
2083         p.recycle();
2084 
2085         // test write String array with length: 4
2086         p = Parcel.obtain();
2087         p.writeStringList(c);
2088         p.setDataPosition(0);
2089         d = p.createStringArrayList();
2090         assertEquals(c, d);
2091         p.recycle();
2092     }
2093 
2094     public void testReadSerializable() {
2095         Parcel p;
2096 
2097         // test write null
2098         p = Parcel.obtain();
2099         p.writeSerializable(null);
2100         p.setDataPosition(0);
2101         assertNull(p.readSerializable());
2102         p.recycle();
2103 
2104         p = Parcel.obtain();
2105         p.writeSerializable("Hello, Android!");
2106         p.setDataPosition(0);
2107         assertEquals("Hello, Android!", p.readSerializable());
2108         p.recycle();
2109     }
2110 
2111     public void testReadSerializableWithClass_whenNull(){
2112         Parcel p = Parcel.obtain();
2113         MockClassLoader mcl = new MockClassLoader();
2114         p.writeSerializable(null);
2115         p.setDataPosition(0);
2116         assertNull(p.readSerializable(mcl, Exception.class));
2117 
2118         p.setDataPosition(0);
2119         assertNull(p.readSerializable(null, Exception.class));
2120         p.recycle();
2121     }
2122 
2123     public void testReadSerializableWithClass_whenNullClassLoader(){
2124         Parcel p = Parcel.obtain();
2125         TestSubException testSubException = new TestSubException("test");
2126         p.writeSerializable(testSubException);
2127         p.setDataPosition(0);
2128         Throwable error = assertThrows(BadParcelableException.class, () ->
2129                 p.readSerializable(null, TestSubException.class));
2130         assertTrue(error.getMessage().contains("ClassNotFoundException reading a Serializable"));
2131         p.recycle();
2132     }
2133 
2134     public void testReadSerializableWithClass_whenSameClass(){
2135         Parcel p = Parcel.obtain();
2136         MockClassLoader mcl = new MockClassLoader();
2137         Throwable throwable = new Throwable("test");
2138         p.writeSerializable(throwable);
2139         p.setDataPosition(0);
2140         Object object = p.readSerializable(mcl, Throwable.class);
2141         assertTrue(object instanceof Throwable);
2142         Throwable t1 = (Throwable) object;
2143         assertEquals("test", t1.getMessage());
2144 
2145         p.setDataPosition(0);
2146         Object object1 = p.readSerializable(null, Throwable.class);
2147         assertTrue(object1 instanceof Throwable);
2148         Throwable t2 = (Throwable) object1;
2149         assertEquals("test", t2.getMessage());
2150         p.recycle();
2151     }
2152 
2153     public void testReadSerializableWithClass_whenSubClass(){
2154         Parcel p = Parcel.obtain();
2155         MockClassLoader mcl = new MockClassLoader();
2156         Exception exception = new Exception("test");
2157         p.writeSerializable(exception);
2158         p.setDataPosition(0);
2159         Object object = p.readSerializable(mcl, Throwable.class);
2160         assertTrue(object instanceof Exception);
2161         Exception e1 = (Exception) object;
2162         assertEquals("test", e1.getMessage());
2163 
2164         p.setDataPosition(0);
2165         Object object1 = p.readSerializable(null, Throwable.class);
2166         assertTrue(object1 instanceof Exception);
2167         Exception e2 = (Exception) object1;
2168         assertEquals("test", e2.getMessage());
2169 
2170         p.setDataPosition(0);
2171         Object object2 = p.readSerializable(null, Object.class);
2172         assertTrue(object1 instanceof Exception);
2173         Exception e3 = (Exception) object2;
2174         assertEquals("test", e3.getMessage());
2175 
2176         p.setDataPosition(0);
2177         assertThrows(BadParcelableException.class, () -> p.readSerializable(mcl, String.class));
2178         p.recycle();
2179     }
2180 
testReadParcelable()2181     public void testReadParcelable() {
2182         Parcel p;
2183         MockClassLoader mcl = new MockClassLoader();
2184         final String signatureString  = "1234567890abcdef";
2185         Signature s = new Signature(signatureString);
2186 
2187         // test write null
2188         p = Parcel.obtain();
2189         p.writeParcelable(null, 0);
2190         p.setDataPosition(0);
2191         assertNull(p.readParcelable(mcl));
2192         p.recycle();
2193 
2194         p = Parcel.obtain();
2195         p.writeParcelable(s, 0);
2196         p.setDataPosition(0);
2197         assertEquals(s, p.readParcelable(mcl));
2198 
2199         p.recycle();
2200     }
2201 
testReadParcelableWithClass()2202     public void testReadParcelableWithClass() {
2203         Parcel p;
2204         MockClassLoader mcl = new MockClassLoader();
2205         final String signatureString  = "1234567890abcdef";
2206         Signature s = new Signature(signatureString);
2207 
2208         p = Parcel.obtain();
2209         p.writeParcelable(s, 0);
2210         p.setDataPosition(0);
2211         assertEquals(s, p.readParcelable(mcl, Signature.class));
2212 
2213         p.setDataPosition(0);
2214         assertThrows(BadParcelableException.class, () -> p.readParcelable(mcl, Intent.class));
2215         p.recycle();
2216     }
2217 
testReadParcelableWithSubClass()2218     public void testReadParcelableWithSubClass() {
2219         Parcel p;
2220 
2221         final TestSubIntent testSubIntent = new TestSubIntent(new Intent(), "Test");
2222         p = Parcel.obtain();
2223         p.writeParcelable(testSubIntent, 0);
2224         p.setDataPosition(0);
2225         assertEquals(testSubIntent, (p.readParcelable(getClass().getClassLoader(), Intent.class)));
2226 
2227         p.setDataPosition(0);
2228         assertEquals(testSubIntent, (p.readParcelable(getClass().getClassLoader(), Object.class)));
2229         p.recycle();
2230     }
2231 
testReadParcelableCreator()2232     public void testReadParcelableCreator() {
2233         MockClassLoader mcl = new MockClassLoader();
2234         final String signatureString  = "1234567890abcdef";
2235         Signature s = new Signature(signatureString);
2236 
2237         Parcel p = Parcel.obtain();
2238         p.writeParcelableCreator(s);
2239         p.setDataPosition(0);
2240         assertSame(Signature.CREATOR, p.readParcelableCreator(mcl));
2241 
2242         p.recycle();
2243     }
2244 
testReadParcelableCreatorWithClass()2245     public void testReadParcelableCreatorWithClass() {
2246         MockClassLoader mcl = new MockClassLoader();
2247         final String signatureString  = "1234567890abcdef";
2248         Signature s = new Signature(signatureString);
2249 
2250         Parcel p = Parcel.obtain();
2251         p.writeParcelableCreator(s);
2252 
2253         p.setDataPosition(0);
2254         assertThrows(BadParcelableException.class, () -> p.readParcelableCreator(mcl, Intent.class));
2255         p.recycle();
2256     }
2257 
testReadParcelableCreatorWithSubClass()2258     public void testReadParcelableCreatorWithSubClass() {
2259         final TestSubIntent testSubIntent = new TestSubIntent(new Intent(), "1234567890abcdef");
2260 
2261         Parcel p = Parcel.obtain();
2262         p.writeParcelableCreator(testSubIntent);
2263 
2264         p.setDataPosition(0);
2265         assertSame(TestSubIntent.CREATOR,
2266                 p.readParcelableCreator(getClass().getClassLoader(), Intent.class));
2267         p.recycle();
2268     }
2269 
testReadParcelableArray()2270     public void testReadParcelableArray() {
2271         Parcel p;
2272         MockClassLoader mcl = new MockClassLoader();
2273         Signature[] s = {new Signature("1234"),
2274                 new Signature("ABCD"),
2275                 new Signature("abcd")};
2276 
2277         Signature[] s2 = {new Signature("1234"),
2278                 null,
2279                 new Signature("abcd")};
2280         Parcelable[] s3;
2281 
2282         // test write null
2283         p = Parcel.obtain();
2284         p.writeParcelableArray(null, 0);
2285         p.setDataPosition(0);
2286         assertNull(p.readParcelableArray(mcl));
2287         p.recycle();
2288 
2289         p = Parcel.obtain();
2290         p.writeParcelableArray(s, 0);
2291         p.setDataPosition(0);
2292         s3 = p.readParcelableArray(mcl);
2293         for (int i = 0; i < s.length; i++) {
2294             assertEquals(s[i], s3[i]);
2295         }
2296         p.recycle();
2297 
2298         p = Parcel.obtain();
2299         p.writeParcelableArray(s2, 0);
2300         p.setDataPosition(0);
2301         s3 = p.readParcelableArray(mcl);
2302         for (int i = 0; i < s2.length; i++) {
2303             assertEquals(s2[i], s3[i]);
2304         }
2305         p.recycle();
2306     }
2307 
testReadParcelableArrayWithClass_whenNull()2308     public void testReadParcelableArrayWithClass_whenNull() {
2309         Parcel p = Parcel.obtain();
2310         p.writeParcelableArray(null, 0);
2311         p.setDataPosition(0);
2312         assertNull(p.readParcelableArray(getClass().getClassLoader(), Intent.class));
2313         p.recycle();
2314     }
2315 
testReadParcelableArrayWithClass_whenSameClass()2316     public void testReadParcelableArrayWithClass_whenSameClass(){
2317         Parcel p = Parcel.obtain();
2318         MockClassLoader mcl = new MockClassLoader();
2319         Signature[] s = {new Signature("1234"),
2320                 null,
2321                 new Signature("abcd")
2322         };
2323         p.writeParcelableArray(s, 0);
2324         p.setDataPosition(0);
2325         Parcelable[] s1 = p.readParcelableArray(mcl, Signature.class);
2326         assertTrue(Arrays.equals(s, s1));
2327         p.recycle();
2328     }
2329 
testReadParcelableArrayWithClass_whenSubclasses()2330     public void testReadParcelableArrayWithClass_whenSubclasses() {
2331         Parcel p = Parcel.obtain();
2332         final Intent baseIntent = new Intent();
2333         Intent[] intentArray = {
2334                 new TestSubIntent(baseIntent, "1234567890abcdef"),
2335                 null,
2336                 new TestSubIntent(baseIntent, "abcdef1234567890")
2337         };
2338 
2339         p.writeParcelableArray(intentArray, 0);
2340         p.setDataPosition(0);
2341         Parcelable[] s = p.readParcelableArray(getClass().getClassLoader(), Intent.class);
2342         assertTrue(Arrays.equals(intentArray, s));
2343 
2344         p.setDataPosition(0);
2345         assertThrows(BadParcelableException.class, () -> p.readParcelableArray(
2346                 getClass().getClassLoader(), Signature.class));
2347         p.recycle();
2348     }
2349 
testReadTypedArray()2350     public void testReadTypedArray() {
2351         Parcel p;
2352         Signature[] s = {new Signature("1234"),
2353                 new Signature("ABCD"),
2354                 new Signature("abcd")};
2355 
2356         Signature[] s2 = {new Signature("1234"),
2357                 null,
2358                 new Signature("abcd")};
2359         Signature[] s3 = new Signature[3];
2360         Signature[] s4 = new Signature[4];
2361 
2362         // test write null
2363         p = Parcel.obtain();
2364         p.writeTypedArray(null, 0);
2365         p.setDataPosition(0);
2366         try {
2367             p.readTypedArray(s3, Signature.CREATOR);
2368             fail("should throw a RuntimeException");
2369         } catch (RuntimeException e) {
2370             //expected
2371         }
2372 
2373         p.setDataPosition(0);
2374         try {
2375             p.readTypedArray(null, Signature.CREATOR);
2376             fail("should throw a RuntimeException");
2377         } catch (RuntimeException e) {
2378             //expected
2379         }
2380         p.recycle();
2381 
2382         // test write not null
2383         p = Parcel.obtain();
2384         p.writeTypedArray(s, 0);
2385         p.setDataPosition(0);
2386         p.readTypedArray(s3, Signature.CREATOR);
2387         for (int i = 0; i < s.length; i++) {
2388             assertEquals(s[i], s3[i]);
2389         }
2390 
2391         p.setDataPosition(0);
2392         try {
2393             p.readTypedArray(null, Signature.CREATOR);
2394             fail("should throw a RuntimeException");
2395         } catch (RuntimeException e) {
2396             //expected
2397         }
2398 
2399         p.setDataPosition(0);
2400         try {
2401             p.readTypedArray(s4, Signature.CREATOR);
2402             fail("should throw a RuntimeException");
2403         } catch (RuntimeException e) {
2404             //expected
2405         }
2406         p.recycle();
2407 
2408         s3 = new Signature[s2.length];
2409         p = Parcel.obtain();
2410         p.writeTypedArray(s2, 0);
2411         p.setDataPosition(0);
2412         p.readTypedArray(s3, Signature.CREATOR);
2413         for (int i = 0; i < s.length; i++) {
2414             assertEquals(s2[i], s3[i]);
2415         }
2416         p.recycle();
2417     }
2418 
testReadTypedArray2()2419     public void testReadTypedArray2() {
2420         Parcel p;
2421         Signature[] s = {
2422                 new Signature("1234"), new Signature("ABCD"), new Signature("abcd")
2423         };
2424 
2425         Signature[] s2 = {
2426                 new Signature("1234"), null, new Signature("abcd")
2427         };
2428         Signature[] s3 = {
2429                 null, null, null
2430         };
2431 
2432         // test write null
2433         p = Parcel.obtain();
2434         p.writeTypedArray(null, 0);
2435         p.setDataPosition(0);
2436         p.recycle();
2437 
2438         // test write not null
2439         p = Parcel.obtain();
2440         p.writeTypedArray(s, 0);
2441         p.setDataPosition(0);
2442         p.readTypedArray(s3, Signature.CREATOR);
2443         for (int i = 0; i < s.length; i++) {
2444             assertEquals(s[i], s3[i]);
2445         }
2446         p.recycle();
2447 
2448         p = Parcel.obtain();
2449         p.writeTypedArray(s2, 0);
2450         p.setDataPosition(0);
2451         p.readTypedArray(s3, Signature.CREATOR);
2452         for (int i = 0; i < s.length; i++) {
2453             assertEquals(s2[i], s3[i]);
2454         }
2455         p.recycle();
2456     }
2457 
testCreateTypedArray()2458     public void testCreateTypedArray() {
2459         Parcel p;
2460         Signature[] s = {new Signature("1234"),
2461                 new Signature("ABCD"),
2462                 new Signature("abcd")};
2463 
2464         Signature[] s2 = {new Signature("1234"),
2465                 null,
2466                 new Signature("abcd")};
2467         Signature[] s3;
2468 
2469         // test write null
2470         p = Parcel.obtain();
2471         p.writeTypedArray(null, 0);
2472         p.setDataPosition(0);
2473         assertNull(p.createTypedArray(Signature.CREATOR));
2474         p.recycle();
2475 
2476         // test write not null
2477         p = Parcel.obtain();
2478         p.writeTypedArray(s, 0);
2479         p.setDataPosition(0);
2480         s3 = p.createTypedArray(Signature.CREATOR);
2481         for (int i = 0; i < s.length; i++) {
2482             assertEquals(s[i], s3[i]);
2483         }
2484         p.recycle();
2485 
2486         p = Parcel.obtain();
2487         p.writeTypedArray(s2, 0);
2488         p.setDataPosition(0);
2489         s3 = p.createTypedArray(Signature.CREATOR);
2490         for (int i = 0; i < s.length; i++) {
2491             assertEquals(s2[i], s3[i]);
2492         }
2493         p.recycle();
2494     }
2495 
testReadTypedList()2496     public void testReadTypedList() {
2497         Parcel p;
2498         ArrayList<Signature> s = new ArrayList<Signature>();
2499         s.add(new Signature("1234"));
2500         s.add(new Signature("ABCD"));
2501         s.add(new Signature("abcd"));
2502 
2503         ArrayList<Signature> s2 = new ArrayList<Signature>();
2504         s2.add(new Signature("1234"));
2505         s2.add(null);
2506 
2507         ArrayList<Signature> s3 = new ArrayList<Signature>();
2508 
2509         // test write null
2510         p = Parcel.obtain();
2511         p.writeTypedList(null);
2512         p.setDataPosition(0);
2513         p.readTypedList(s3, Signature.CREATOR);
2514         assertEquals(0, s3.size());
2515 
2516         p.setDataPosition(0);
2517         try {
2518             p.readTypedList(null, Signature.CREATOR);
2519             fail("should throw a RuntimeException");
2520         } catch (RuntimeException e) {
2521             //expected
2522         }
2523         p.recycle();
2524 
2525         // test write not null
2526         p = Parcel.obtain();
2527         p.writeTypedList(s);
2528         p.setDataPosition(0);
2529         p.readTypedList(s3, Signature.CREATOR);
2530         for (int i = 0; i < s.size(); i++) {
2531             assertEquals(s.get(i), s3.get(i));
2532         }
2533 
2534         p.setDataPosition(0);
2535         try {
2536             p.readTypedList(null, Signature.CREATOR);
2537             fail("should throw a RuntimeException");
2538         } catch (RuntimeException e) {
2539             //expected
2540         }
2541 
2542         p.setDataPosition(0);
2543         p.readTypedList(s2, Signature.CREATOR);
2544         assertEquals(s.size(), s2.size());
2545         for (int i = 0; i < s.size(); i++) {
2546             assertEquals(s.get(i), s2.get(i));
2547         }
2548         p.recycle();
2549 
2550         s2 = new ArrayList<Signature>();
2551         s2.add(new Signature("1234"));
2552         s2.add(null);
2553         p = Parcel.obtain();
2554         p.writeTypedList(s2);
2555         p.setDataPosition(0);
2556         p.readTypedList(s3, Signature.CREATOR);
2557         assertEquals(s3.size(), s2.size());
2558         for (int i = 0; i < s2.size(); i++) {
2559             assertEquals(s2.get(i), s3.get(i));
2560         }
2561         p.recycle();
2562     }
2563 
testWriteTypedList()2564     public void testWriteTypedList() {
2565         Parcel p = Parcel.obtain();
2566         ArrayList<SimpleParcelable> list = new ArrayList<>();
2567         SimpleParcelable spy = spy(new SimpleParcelable(42));
2568         list.add(spy);
2569         int flags = Parcelable.PARCELABLE_WRITE_RETURN_VALUE;
2570         p.writeTypedList(list, flags);
2571 
2572         verify(spy).writeToParcel(p, flags);
2573 
2574         p.setDataPosition(0);
2575         ArrayList<SimpleParcelable> read = p.createTypedArrayList(SimpleParcelable.CREATOR);
2576         assertEquals(list.size(), read.size());
2577         assertEquals(list.get(0).getValue(), read.get(0).getValue());
2578         p.recycle();
2579     }
2580 
testCreateTypedArrayList()2581     public void testCreateTypedArrayList() {
2582         Parcel p;
2583         ArrayList<Signature> s = new ArrayList<Signature>();
2584         s.add(new Signature("1234"));
2585         s.add(new Signature("ABCD"));
2586         s.add(new Signature("abcd"));
2587 
2588         ArrayList<Signature> s2 = new ArrayList<Signature>();
2589         s2.add(new Signature("1234"));
2590         s2.add(null);
2591 
2592         ArrayList<Signature> s3;
2593 
2594         // test write null
2595         p = Parcel.obtain();
2596         p.writeTypedList(null);
2597         p.setDataPosition(0);
2598         assertNull(p.createTypedArrayList(Signature.CREATOR));
2599         p.recycle();
2600 
2601         // test write not null
2602         p = Parcel.obtain();
2603         p.writeTypedList(s);
2604         p.setDataPosition(0);
2605         s3 = p.createTypedArrayList(Signature.CREATOR);
2606         for (int i = 0; i < s.size(); i++) {
2607             assertEquals(s.get(i), s3.get(i));
2608         }
2609 
2610         p = Parcel.obtain();
2611         p.writeTypedList(s2);
2612         p.setDataPosition(0);
2613         s3 = p.createTypedArrayList(Signature.CREATOR);
2614         assertEquals(s3.size(), s2.size());
2615         for (int i = 0; i < s2.size(); i++) {
2616             assertEquals(s2.get(i), s3.get(i));
2617         }
2618         p.recycle();
2619     }
2620 
testReadException()2621     public void testReadException() {
2622     }
2623 
testReadException2()2624     public void testReadException2() {
2625         Parcel p = Parcel.obtain();
2626         String msg = "testReadException2";
2627 
2628         p.writeException(new SecurityException(msg));
2629         p.setDataPosition(0);
2630         try {
2631             p.readException();
2632             fail("Should throw a SecurityException");
2633         } catch (SecurityException e) {
2634             assertEquals(msg, e.getMessage());
2635         }
2636 
2637         p.setDataPosition(0);
2638         p.writeException(new BadParcelableException(msg));
2639         p.setDataPosition(0);
2640         try {
2641             p.readException();
2642             fail("Should throw a BadParcelableException");
2643         } catch (BadParcelableException e) {
2644             assertEquals(msg, e.getMessage());
2645         }
2646 
2647         p.setDataPosition(0);
2648         p.writeException(new IllegalArgumentException(msg));
2649         p.setDataPosition(0);
2650         try {
2651             p.readException();
2652             fail("Should throw an IllegalArgumentException");
2653         } catch (IllegalArgumentException e) {
2654             assertEquals(msg, e.getMessage());
2655         }
2656 
2657         p.setDataPosition(0);
2658         p.writeException(new NullPointerException(msg));
2659         p.setDataPosition(0);
2660         try {
2661             p.readException();
2662             fail("Should throw a NullPointerException");
2663         } catch (NullPointerException e) {
2664             assertEquals(msg, e.getMessage());
2665         }
2666 
2667         p.setDataPosition(0);
2668         p.writeException(new IllegalStateException(msg));
2669         p.setDataPosition(0);
2670         try {
2671             p.readException();
2672             fail("Should throw an IllegalStateException");
2673         } catch (IllegalStateException e) {
2674             assertEquals(msg, e.getMessage());
2675         }
2676 
2677         p.setDataPosition(0);
2678         try {
2679             p.writeException(new RuntimeException());
2680             fail("Should throw an IllegalStateException");
2681         } catch (RuntimeException e) {
2682             //expected
2683         }
2684         p.recycle();
2685     }
2686 
testWriteNoException()2687     public void testWriteNoException() {
2688         Parcel p = Parcel.obtain();
2689         p.writeNoException();
2690         p.setDataPosition(0);
2691         p.readException();
2692         p.recycle();
2693     }
2694 
testWriteFileDescriptor()2695     public void testWriteFileDescriptor() {
2696         Parcel p;
2697         FileDescriptor fIn = FileDescriptor.in;
2698         ParcelFileDescriptor pfd;
2699 
2700         p = Parcel.obtain();
2701         pfd = p.readFileDescriptor();
2702         assertNull(pfd);
2703         p.recycle();
2704 
2705         p = Parcel.obtain();
2706         p.writeFileDescriptor(fIn);
2707         p.setDataPosition(0);
2708         pfd = p.readFileDescriptor();
2709         assertNotNull(pfd);
2710         assertNotNull(pfd.getFileDescriptor());
2711         p.recycle();
2712     }
2713 
testHasFileDescriptor()2714     public void testHasFileDescriptor() {
2715         Parcel p;
2716         FileDescriptor fIn = FileDescriptor.in;
2717 
2718         p = Parcel.obtain();
2719         p.writeFileDescriptor(fIn);
2720         p.setDataPosition(0);
2721         assertTrue(p.hasFileDescriptors());
2722         p.recycle();
2723 
2724         p = Parcel.obtain();
2725         p.writeInt(111);
2726         p.setDataPosition(0);
2727         assertFalse(p.hasFileDescriptors());
2728         p.recycle();
2729     }
2730 
testHasFileDescriptorInRange_outsideRange()2731     public void testHasFileDescriptorInRange_outsideRange() {
2732         Parcel p = Parcel.obtain();
2733         int i0 = p.dataPosition();
2734         p.writeInt(13);
2735         int i1 = p.dataPosition();
2736         p.writeFileDescriptor(FileDescriptor.in);
2737         int i2 = p.dataPosition();
2738         p.writeString("Tiramisu");
2739         int i3 = p.dataPosition();
2740 
2741         assertFalse(p.hasFileDescriptors(i0, i1 - i0));
2742         assertFalse(p.hasFileDescriptors(i2, i3 - i2));
2743         p.recycle();
2744     }
2745 
testHasFileDescriptorInRange_partiallyInsideRange()2746     public void testHasFileDescriptorInRange_partiallyInsideRange() {
2747         Parcel p = Parcel.obtain();
2748         int i0 = p.dataPosition();
2749         p.writeInt(13);
2750         int i1 = p.dataPosition();
2751         p.writeFileDescriptor(FileDescriptor.in);
2752         int i2 = p.dataPosition();
2753         p.writeString("Tiramisu");
2754         int i3 = p.dataPosition();
2755 
2756         // It has to contain the whole object
2757         assertFalse(p.hasFileDescriptors(i1, i2 - i1 - 1));
2758         assertFalse(p.hasFileDescriptors(i1 + 1, i2 - i1));
2759         p.recycle();
2760     }
2761 
testHasFileDescriptorInRange_insideRange()2762     public void testHasFileDescriptorInRange_insideRange() {
2763         Parcel p = Parcel.obtain();
2764         int i0 = p.dataPosition();
2765         p.writeInt(13);
2766         int i1 = p.dataPosition();
2767         p.writeFileDescriptor(FileDescriptor.in);
2768         int i2 = p.dataPosition();
2769         p.writeString("Tiramisu");
2770         int i3 = p.dataPosition();
2771 
2772         assertTrue(p.hasFileDescriptors(i0, i2 - i0));
2773         assertTrue(p.hasFileDescriptors(i1, i2 - i1));
2774         assertTrue(p.hasFileDescriptors(i1, i3 - i1));
2775         assertTrue(p.hasFileDescriptors(i0, i3 - i0));
2776         assertTrue(p.hasFileDescriptors(i0, p.dataSize()));
2777         p.recycle();
2778     }
2779 
testHasFileDescriptorInRange_zeroLength()2780     public void testHasFileDescriptorInRange_zeroLength() {
2781         Parcel p = Parcel.obtain();
2782         int i0 = p.dataPosition();
2783         p.writeInt(13);
2784         int i1 = p.dataPosition();
2785         p.writeFileDescriptor(FileDescriptor.in);
2786         int i2 = p.dataPosition();
2787         p.writeString("Tiramisu");
2788         int i3 = p.dataPosition();
2789 
2790         assertFalse(p.hasFileDescriptors(i1, 0));
2791         p.recycle();
2792     }
2793 
2794     /**
2795      * When we rewind the cursor using {@link Parcel#setDataPosition(int)} and write a FD, the
2796      * internal representation of FDs in {@link Parcel} may lose the sorted property, so we test
2797      * this case.
2798      */
testHasFileDescriptorInRange_withUnsortedFdObjects()2799     public void testHasFileDescriptorInRange_withUnsortedFdObjects() {
2800         Parcel p = Parcel.obtain();
2801         int i0 = p.dataPosition();
2802         p.writeLongArray(new long[] {0, 0, 0, 0, 0, 0});
2803         int i1 = p.dataPosition();
2804         p.writeFileDescriptor(FileDescriptor.in);
2805         p.setDataPosition(0);
2806         p.writeFileDescriptor(FileDescriptor.in);
2807         p.setDataPosition(0);
2808 
2809         assertTrue(p.hasFileDescriptors(i0, i1 - i0));
2810         p.recycle();
2811     }
2812 
testHasFileDescriptorInRange_limitOutOfBounds()2813     public void testHasFileDescriptorInRange_limitOutOfBounds() {
2814         Parcel p = Parcel.obtain();
2815         int i0 = p.dataPosition();
2816         p.writeFileDescriptor(FileDescriptor.in);
2817         int i1 = p.dataPosition();
2818 
2819         assertThrows(IllegalArgumentException.class, () -> p.hasFileDescriptors(i0, i1 - i0 + 1));
2820         assertThrows(IllegalArgumentException.class,
2821                 () -> p.hasFileDescriptors(0, p.dataSize() + 1));
2822         p.recycle();
2823     }
2824 
testHasFileDescriptorInRange_offsetOutOfBounds()2825     public void testHasFileDescriptorInRange_offsetOutOfBounds() {
2826         Parcel p = Parcel.obtain();
2827         int i0 = p.dataPosition();
2828         p.writeFileDescriptor(FileDescriptor.in);
2829         int i1 = p.dataPosition();
2830 
2831         assertThrows(IllegalArgumentException.class, () -> p.hasFileDescriptors(i1, 1));
2832         assertThrows(IllegalArgumentException.class, () -> p.hasFileDescriptors(i1 + 1, 1));
2833         p.recycle();
2834     }
2835 
testHasFileDescriptorInRange_offsetOutOfBoundsAndZeroLength()2836     public void testHasFileDescriptorInRange_offsetOutOfBoundsAndZeroLength() {
2837         Parcel p = Parcel.obtain();
2838         int i0 = p.dataPosition();
2839         p.writeFileDescriptor(FileDescriptor.in);
2840         int i1 = p.dataPosition();
2841 
2842         assertFalse(p.hasFileDescriptors(i1, 0));
2843         assertThrows(IllegalArgumentException.class, () -> p.hasFileDescriptors(i1 + 1, 0));
2844         p.recycle();
2845     }
2846 
testHasFileDescriptorInRange_zeroLengthParcel()2847     public void testHasFileDescriptorInRange_zeroLengthParcel() {
2848         Parcel p = Parcel.obtain();
2849 
2850         assertFalse(p.hasFileDescriptors(0, 0));
2851         p.recycle();
2852     }
2853 
testHasFileDescriptorInRange_negativeLength()2854     public void testHasFileDescriptorInRange_negativeLength() {
2855         Parcel p = Parcel.obtain();
2856         int i0 = p.dataPosition();
2857         p.writeFileDescriptor(FileDescriptor.in);
2858         int i1 = p.dataPosition();
2859 
2860         assertThrows(IllegalArgumentException.class, () -> p.hasFileDescriptors(i0, -1));
2861         assertThrows(IllegalArgumentException.class, () -> p.hasFileDescriptors(i0, -(i1 - i0)));
2862         p.recycle();
2863     }
2864 
testHasFileDescriptorInRange_negativeOffset()2865     public void testHasFileDescriptorInRange_negativeOffset() {
2866         Parcel p = Parcel.obtain();
2867         p.writeFileDescriptor(FileDescriptor.in);
2868 
2869         assertThrows(IllegalArgumentException.class, () -> p.hasFileDescriptors(-1, 1));
2870         p.recycle();
2871     }
2872 
testReadBundle()2873     public void testReadBundle() {
2874         Bundle bundle = new Bundle();
2875         bundle.putBoolean("boolean", true);
2876         bundle.putInt("int", Integer.MAX_VALUE);
2877         bundle.putString("string", "String");
2878 
2879         Bundle bundle2;
2880         Parcel p;
2881 
2882         // test null
2883         p = Parcel.obtain();
2884         p.writeBundle(null);
2885         p.setDataPosition(0);
2886         bundle2 = p.readBundle();
2887         assertNull(bundle2);
2888         p.recycle();
2889 
2890         // test not null
2891         bundle2 = null;
2892         p = Parcel.obtain();
2893         p.writeBundle(bundle);
2894         p.setDataPosition(0);
2895         bundle2 = p.readBundle();
2896         assertNotNull(bundle2);
2897         assertEquals(true, bundle2.getBoolean("boolean"));
2898         assertEquals(Integer.MAX_VALUE, bundle2.getInt("int"));
2899         assertEquals("String", bundle2.getString("string"));
2900         p.recycle();
2901 
2902         bundle2 = null;
2903         Parcel a = Parcel.obtain();
2904         bundle2 = new Bundle();
2905         bundle2.putString("foo", "test");
2906         a.writeBundle(bundle2);
2907         a.setDataPosition(0);
2908         bundle.readFromParcel(a);
2909         p = Parcel.obtain();
2910         p.setDataPosition(0);
2911         p.writeBundle(bundle);
2912         p.setDataPosition(0);
2913         bundle2 = p.readBundle();
2914         assertNotNull(bundle2);
2915         assertFalse(true == bundle2.getBoolean("boolean"));
2916         assertFalse(Integer.MAX_VALUE == bundle2.getInt("int"));
2917         assertFalse("String".equals( bundle2.getString("string")));
2918         a.recycle();
2919         p.recycle();
2920     }
2921 
testReadBundle2()2922     public void testReadBundle2() {
2923         Bundle b = new Bundle();
2924         b.putBoolean("boolean", true);
2925         b.putInt("int", Integer.MAX_VALUE);
2926         b.putString("string", "String");
2927 
2928         Bundle u;
2929         Parcel p;
2930         MockClassLoader m = new MockClassLoader();
2931 
2932         p = Parcel.obtain();
2933         p.writeBundle(null);
2934         p.setDataPosition(0);
2935         u = p.readBundle(m);
2936         assertNull(u);
2937         p.recycle();
2938 
2939         u = null;
2940         p = Parcel.obtain();
2941         p.writeBundle(b);
2942         p.setDataPosition(0);
2943         u = p.readBundle(m);
2944         assertNotNull(u);
2945         assertEquals(true, b.getBoolean("boolean"));
2946         assertEquals(Integer.MAX_VALUE, b.getInt("int"));
2947         assertEquals("String", b.getString("string"));
2948         p.recycle();
2949     }
2950 
testWriteArray()2951     public void testWriteArray() {
2952         Parcel p;
2953         MockClassLoader mcl = new MockClassLoader();
2954 
2955         p = Parcel.obtain();
2956         p.writeArray(null);
2957         p.setDataPosition(0);
2958         assertNull(p.readArray(mcl));
2959         p.recycle();
2960 
2961         Object[] objects = new Object[5];
2962         objects[0] = Integer.MAX_VALUE;
2963         objects[1] = true;
2964         objects[2] = Long.MAX_VALUE;
2965         objects[3] = "String";
2966         objects[4] = Float.MAX_VALUE;
2967         Object[] objects2;
2968 
2969         p = Parcel.obtain();
2970         p.writeArray(objects);
2971         p.setDataPosition(0);
2972         objects2 = p.readArray(mcl);
2973         assertNotNull(objects2);
2974         for (int i = 0; i < objects2.length; i++) {
2975             assertEquals(objects[i], objects2[i]);
2976         }
2977         p.recycle();
2978     }
2979 
testReadArrayWithClass_whenNull()2980     public void testReadArrayWithClass_whenNull(){
2981         Parcel p = Parcel.obtain();
2982         MockClassLoader mcl = new MockClassLoader();
2983 
2984         p.writeArray(null);
2985         p.setDataPosition(0);
2986         assertNull(p.readArray(mcl, Intent.class));
2987         p.recycle();
2988     }
2989 
testReadArrayWithClass_whenNonParcelableClass()2990     public void testReadArrayWithClass_whenNonParcelableClass(){
2991         Parcel p = Parcel.obtain();
2992         MockClassLoader mcl = new MockClassLoader();
2993 
2994         String[] sArray = {"1234", null, "4321"};
2995         p.writeArray(sArray);
2996 
2997         p.setDataPosition(0);
2998         Object[] objects = p.readArray(mcl, String.class);
2999         assertTrue(Arrays.equals(sArray, objects));
3000         p.setDataPosition(0);
3001         assertThrows(BadParcelableException.class, () -> p.readArray(
3002                 getClass().getClassLoader(), Intent.class));
3003         p.recycle();
3004     }
3005 
testReadArrayWithClass_whenSameClass()3006     public void testReadArrayWithClass_whenSameClass(){
3007         Parcel p = Parcel.obtain();
3008         MockClassLoader mcl = new MockClassLoader();
3009 
3010         Signature[] s = {new Signature("1234"),
3011                 null,
3012                 new Signature("abcd")};
3013         p.writeArray(s);
3014 
3015         p.setDataPosition(0);
3016         Object[] s1 = p.readArray(mcl, Signature.class);
3017         assertTrue(Arrays.equals(s, s1));
3018 
3019         p.setDataPosition(0);
3020         assertThrows(BadParcelableException.class, () -> p.readArray(
3021                 getClass().getClassLoader(), Intent.class));
3022         p.recycle();
3023     }
3024 
testReadArrayWithClass_whenSubclasses()3025     public void testReadArrayWithClass_whenSubclasses(){
3026         final Parcel p = Parcel.obtain();
3027         final Intent baseIntent = new Intent();
3028         Intent[] intentArray = {
3029             new TestSubIntent(baseIntent, "1234567890abcdef"),
3030             null,
3031             new TestSubIntent(baseIntent, "abcdef1234567890")
3032         };
3033         p.writeArray(intentArray);
3034 
3035         p.setDataPosition(0);
3036         Object[] objects = p.readArray(getClass().getClassLoader(), Intent.class);
3037         assertTrue(Arrays.equals(intentArray, objects));
3038 
3039         p.setDataPosition(0);
3040         assertThrows(BadParcelableException.class, () -> p.readArray(
3041                 getClass().getClassLoader(), Signature.class));
3042         p.recycle();
3043     }
3044 
testReadArrayList()3045     public void testReadArrayList() {
3046         Parcel p;
3047         MockClassLoader mcl = new MockClassLoader();
3048 
3049         p = Parcel.obtain();
3050         p.writeArray(null);
3051         p.setDataPosition(0);
3052         assertNull(p.readArrayList(mcl));
3053         p.recycle();
3054 
3055         Object[] objects = new Object[5];
3056         objects[0] = Integer.MAX_VALUE;
3057         objects[1] = true;
3058         objects[2] = Long.MAX_VALUE;
3059         objects[3] = "String";
3060         objects[4] = Float.MAX_VALUE;
3061         ArrayList<?> objects2;
3062 
3063         p = Parcel.obtain();
3064         p.writeArray(objects);
3065         p.setDataPosition(0);
3066         objects2 = p.readArrayList(mcl);
3067         assertNotNull(objects2);
3068         for (int i = 0; i < objects2.size(); i++) {
3069             assertEquals(objects[i], objects2.get(i));
3070         }
3071         p.recycle();
3072     }
3073 
testReadArrayListWithClass_whenNull()3074     public void testReadArrayListWithClass_whenNull(){
3075         Parcel p = Parcel.obtain();
3076         MockClassLoader mcl = new MockClassLoader();
3077 
3078         p.writeArray(null);
3079         p.setDataPosition(0);
3080         assertNull(p.readArrayList(mcl, Intent.class));
3081         p.recycle();
3082     }
3083 
testReadArrayListWithClass_whenNonParcelableClass()3084     public void testReadArrayListWithClass_whenNonParcelableClass(){
3085         Parcel p = Parcel.obtain();
3086         MockClassLoader mcl = new MockClassLoader();
3087 
3088         ArrayList<String> sArrayList = new ArrayList<>();
3089         sArrayList.add("1234");
3090         sArrayList.add(null);
3091         sArrayList.add("4321");
3092 
3093         p.writeList(sArrayList);
3094         p.setDataPosition(0);
3095         ArrayList<String> s1 = p.readArrayList(mcl, String.class);
3096         assertEquals(sArrayList, s1);
3097         p.setDataPosition(0);
3098         assertThrows(BadParcelableException.class, () -> p.readArray(mcl, Intent.class));
3099         p.recycle();
3100     }
3101 
testReadArrayListWithClass_whenSameClass()3102     public void testReadArrayListWithClass_whenSameClass(){
3103         final Parcel p = Parcel.obtain();
3104         MockClassLoader mcl = new MockClassLoader();
3105 
3106         ArrayList<Signature> s = new ArrayList<>();
3107         s.add(new Signature("1234567890abcdef"));
3108         s.add(null);
3109         s.add(new Signature("abcdef1234567890"));
3110 
3111         p.writeList(s);
3112         p.setDataPosition(0);
3113         ArrayList<Signature> s1 = p.readArrayList(mcl, Signature.class);
3114         assertEquals(s, s1);
3115 
3116         p.setDataPosition(0);
3117         assertThrows(BadParcelableException.class, () -> p.readArray(mcl, Intent.class));
3118         p.recycle();
3119     }
3120 
testReadArrayListWithClass_whenSubclasses()3121     public void testReadArrayListWithClass_whenSubclasses(){
3122         final Parcel p = Parcel.obtain();
3123         final Intent baseIntent = new Intent();
3124 
3125         ArrayList<Intent> intentArrayList = new ArrayList<>();
3126         intentArrayList.add(new TestSubIntent(baseIntent, "1234567890abcdef"));
3127         intentArrayList.add(null);
3128         intentArrayList.add(new TestSubIntent(baseIntent, "abcdef1234567890"));
3129 
3130         p.writeList(intentArrayList);
3131         p.setDataPosition(0);
3132         ArrayList<Intent> objects = p.readArrayList(getClass().getClassLoader(), Intent.class);
3133         assertEquals(intentArrayList, objects);
3134 
3135         p.setDataPosition(0);
3136         ArrayList<Intent> objects1 = p.readArrayList(
3137                 getClass().getClassLoader(), TestSubIntent.class);
3138         assertEquals(intentArrayList, objects1);
3139 
3140         p.setDataPosition(0);
3141         assertThrows(BadParcelableException.class, () -> p.readArray(
3142                 getClass().getClassLoader(), Signature.class));
3143         p.recycle();
3144     }
3145 
3146     @SuppressWarnings("unchecked")
testWriteSparseArray()3147     public void testWriteSparseArray() {
3148         Parcel p;
3149         MockClassLoader mcl = new MockClassLoader();
3150 
3151         p = Parcel.obtain();
3152         p.writeSparseArray(null);
3153         p.setDataPosition(0);
3154         assertNull(p.readSparseArray(mcl));
3155         p.recycle();
3156 
3157         SparseArray<Object> sparseArray = new SparseArray<Object>();
3158         sparseArray.put(3, "String");
3159         sparseArray.put(2, Long.MAX_VALUE);
3160         sparseArray.put(4, Float.MAX_VALUE);
3161         sparseArray.put(0, Integer.MAX_VALUE);
3162         sparseArray.put(1, true);
3163         sparseArray.put(10, true);
3164         SparseArray<Object> sparseArray2;
3165 
3166         p = Parcel.obtain();
3167         p.writeSparseArray(sparseArray);
3168         p.setDataPosition(0);
3169         sparseArray2 = p.readSparseArray(mcl);
3170         assertNotNull(sparseArray2);
3171         assertEquals(sparseArray.size(), sparseArray2.size());
3172         assertEquals(sparseArray.get(0), sparseArray2.get(0));
3173         assertEquals(sparseArray.get(1), sparseArray2.get(1));
3174         assertEquals(sparseArray.get(2), sparseArray2.get(2));
3175         assertEquals(sparseArray.get(3), sparseArray2.get(3));
3176         assertEquals(sparseArray.get(4), sparseArray2.get(4));
3177         assertEquals(sparseArray.get(10), sparseArray2.get(10));
3178         p.recycle();
3179     }
3180 
testReadSparseArrayWithClass_whenNull()3181     public void testReadSparseArrayWithClass_whenNull(){
3182         Parcel p = Parcel.obtain();
3183         MockClassLoader mcl = new MockClassLoader();
3184 
3185         p.writeSparseArray(null);
3186         p.setDataPosition(0);
3187         assertNull(p.readSparseArray(mcl, Intent.class));
3188         p.recycle();
3189     }
3190 
testReadSparseArrayWithClass_whenNonParcelableClass()3191     public void testReadSparseArrayWithClass_whenNonParcelableClass(){
3192         Parcel p = Parcel.obtain();
3193         MockClassLoader mcl = new MockClassLoader();
3194 
3195         SparseArray<String> s = new SparseArray<>();
3196         s.put(0, "1234567890abcdef");
3197         s.put(2, null);
3198         s.put(3, "abcdef1234567890");
3199         p.writeSparseArray(s);
3200 
3201         p.setDataPosition(0);
3202         SparseArray<String> s1 = p.readSparseArray(mcl, String.class);
3203         assertNotNull(s1);
3204         assertTrue(s.contentEquals(s1));
3205 
3206         p.setDataPosition(0);
3207         assertThrows(BadParcelableException.class, () -> p.readSparseArray(
3208                 getClass().getClassLoader(), Intent.class));
3209         p.recycle();
3210     }
3211 
testReadSparseArrayWithClass_whenSameClass()3212     public void testReadSparseArrayWithClass_whenSameClass(){
3213         Parcel p = Parcel.obtain();
3214         MockClassLoader mcl = new MockClassLoader();
3215 
3216         SparseArray<Signature> s = new SparseArray<>();
3217         s.put(0, new Signature("1234567890abcdef"));
3218         s.put(2, null);
3219         s.put(3, new Signature("abcdef1234567890"));
3220         p.writeSparseArray(s);
3221 
3222         p.setDataPosition(0);
3223         SparseArray<Signature> s1 = p.readSparseArray(mcl, Signature.class);
3224         assertNotNull(s1);
3225         assertTrue(s.contentEquals(s1));
3226 
3227         p.setDataPosition(0);
3228         assertThrows(BadParcelableException.class, () -> p.readSparseArray(
3229                 getClass().getClassLoader(), Intent.class));
3230         p.recycle();
3231     }
3232 
testReadSparseArrayWithClass_whenSubclasses()3233     public void testReadSparseArrayWithClass_whenSubclasses(){
3234         final Parcel p = Parcel.obtain();
3235         final Intent baseIntent = new Intent();
3236         SparseArray<Intent> intentArray = new SparseArray<>();
3237         intentArray.put(0, new TestSubIntent(baseIntent, "1234567890abcdef"));
3238         intentArray.put(3, new TestSubIntent(baseIntent, "1234567890abcdef"));
3239         p.writeSparseArray(intentArray);
3240 
3241         p.setDataPosition(0);
3242         SparseArray<Intent> sparseArray = p.readSparseArray(
3243                 getClass().getClassLoader(), Intent.class);
3244         assertNotNull(sparseArray);
3245         assertTrue(intentArray.contentEquals(sparseArray));
3246 
3247         p.setDataPosition(0);
3248         SparseArray<Intent> sparseArray1 = p.readSparseArray(
3249                 getClass().getClassLoader(), TestSubIntent.class);
3250         assertNotNull(sparseArray1);
3251         assertTrue(intentArray.contentEquals(sparseArray1));
3252 
3253         p.setDataPosition(0);
3254         assertThrows(BadParcelableException.class, () -> p.readSparseArray(
3255                 getClass().getClassLoader(), Signature.class));
3256         p.recycle();
3257     }
3258 
testWriteSparseBooleanArray()3259     public void testWriteSparseBooleanArray() {
3260         Parcel p;
3261 
3262         p = Parcel.obtain();
3263         p.writeSparseArray(null);
3264         p.setDataPosition(0);
3265         assertNull(p.readSparseBooleanArray());
3266         p.recycle();
3267 
3268         SparseBooleanArray sparseBooleanArray = new SparseBooleanArray();
3269         sparseBooleanArray.put(3, true);
3270         sparseBooleanArray.put(2, false);
3271         sparseBooleanArray.put(4, false);
3272         sparseBooleanArray.put(0, true);
3273         sparseBooleanArray.put(1, true);
3274         sparseBooleanArray.put(10, true);
3275         SparseBooleanArray sparseBoolanArray2;
3276 
3277         p = Parcel.obtain();
3278         p.writeSparseBooleanArray(sparseBooleanArray);
3279         p.setDataPosition(0);
3280         sparseBoolanArray2 = p.readSparseBooleanArray();
3281         assertNotNull(sparseBoolanArray2);
3282         assertEquals(sparseBooleanArray.size(), sparseBoolanArray2.size());
3283         assertEquals(sparseBooleanArray.get(0), sparseBoolanArray2.get(0));
3284         assertEquals(sparseBooleanArray.get(1), sparseBoolanArray2.get(1));
3285         assertEquals(sparseBooleanArray.get(2), sparseBoolanArray2.get(2));
3286         assertEquals(sparseBooleanArray.get(3), sparseBoolanArray2.get(3));
3287         assertEquals(sparseBooleanArray.get(4), sparseBoolanArray2.get(4));
3288         assertEquals(sparseBooleanArray.get(10), sparseBoolanArray2.get(10));
3289         p.recycle();
3290     }
3291 
testWriteStrongBinder()3292     public void testWriteStrongBinder() {
3293         Parcel p;
3294         Binder binder;
3295         Binder binder2 = new Binder();
3296 
3297         p = Parcel.obtain();
3298         p.writeStrongBinder(null);
3299         p.setDataPosition(0);
3300         assertNull(p.readStrongBinder());
3301         p.recycle();
3302 
3303         p = Parcel.obtain();
3304         p.writeStrongBinder(binder2);
3305         p.setDataPosition(0);
3306         binder = (Binder) p.readStrongBinder();
3307         assertEquals(binder2, binder);
3308         p.recycle();
3309     }
3310 
testWriteStrongInterface()3311     public void testWriteStrongInterface() {
3312         Parcel p;
3313         MockIInterface mockInterface = new MockIInterface();
3314         MockIInterface mockIInterface2 = new MockIInterface();
3315 
3316         p = Parcel.obtain();
3317         p.writeStrongInterface(null);
3318         p.setDataPosition(0);
3319         assertNull(p.readStrongBinder());
3320         p.recycle();
3321 
3322         p = Parcel.obtain();
3323         p.writeStrongInterface(mockInterface);
3324         p.setDataPosition(0);
3325         mockIInterface2.binder = (Binder) p.readStrongBinder();
3326         assertEquals(mockInterface.binder, mockIInterface2.binder);
3327         p.recycle();
3328     }
3329 
testWriteBinderArray()3330     public void testWriteBinderArray() {
3331         Parcel p;
3332         IBinder[] ibinder2 = {new Binder(), new Binder()};
3333         IBinder[] ibinder3 = new IBinder[2];
3334         IBinder[] ibinder4 = new IBinder[3];
3335 
3336         p = Parcel.obtain();
3337         p.writeBinderArray(null);
3338         p.setDataPosition(0);
3339         try {
3340             p.readBinderArray(null);
3341             fail("Should throw a RuntimeException");
3342         } catch (RuntimeException e) {
3343             //expected
3344         }
3345 
3346         p.setDataPosition(0);
3347         try {
3348             p.readBinderArray(ibinder3);
3349             fail("Should throw a RuntimeException");
3350         } catch (RuntimeException e) {
3351             //expected
3352         }
3353 
3354         p.setDataPosition(0);
3355         try {
3356             p.readBinderArray(ibinder2);
3357             fail("Should throw a RuntimeException");
3358         } catch (RuntimeException e) {
3359             //expected
3360         }
3361         p.recycle();
3362 
3363         p = Parcel.obtain();
3364         p.writeBinderArray(ibinder2);
3365         p.setDataPosition(0);
3366         try {
3367             p.readBinderArray(null);
3368             fail("Should throw a RuntimeException");
3369         } catch (RuntimeException e) {
3370             //expected
3371         }
3372 
3373         p.setDataPosition(0);
3374         try {
3375             p.readBinderArray(ibinder4);
3376             fail("Should throw a RuntimeException");
3377         } catch (RuntimeException e) {
3378             //expected
3379         }
3380 
3381         p.setDataPosition(0);
3382         p.readBinderArray(ibinder3);
3383         assertNotNull(ibinder3);
3384         for (int i = 0; i < ibinder3.length; i++) {
3385             assertNotNull(ibinder3[i]);
3386             assertEquals(ibinder2[i], ibinder3[i]);
3387         }
3388         p.recycle();
3389     }
3390 
testCreateBinderArray()3391     public void testCreateBinderArray() {
3392         Parcel p;
3393         IBinder[] ibinder  = {};
3394         IBinder[] ibinder2 = {new Binder(), new Binder()};
3395         IBinder[] ibinder3;
3396         IBinder[] ibinder4;
3397 
3398         p = Parcel.obtain();
3399         p.writeBinderArray(null);
3400         p.setDataPosition(0);
3401         ibinder3 = p.createBinderArray();
3402         assertNull(ibinder3);
3403         p.recycle();
3404 
3405         p = Parcel.obtain();
3406         p.writeBinderArray(ibinder);
3407         p.setDataPosition(0);
3408         ibinder4 = p.createBinderArray();
3409         assertNotNull(ibinder4);
3410         assertEquals(0, ibinder4.length);
3411         p.recycle();
3412 
3413         p = Parcel.obtain();
3414         p.writeBinderArray(ibinder2);
3415         p.setDataPosition(0);
3416         ibinder3 = p.createBinderArray();
3417         assertNotNull(ibinder3);
3418         for (int i = 0; i < ibinder3.length; i++) {
3419             assertNotNull(ibinder3[i]);
3420             assertEquals(ibinder2[i], ibinder3[i]);
3421         }
3422         p.recycle();
3423     }
3424 
testWriteBinderList()3425     public void testWriteBinderList() {
3426         Parcel p;
3427         ArrayList<IBinder> arrayList = new ArrayList<IBinder>();
3428         ArrayList<IBinder> arrayList2 = new ArrayList<IBinder>();
3429         arrayList2.add(new Binder());
3430         arrayList2.add(new Binder());
3431         ArrayList<IBinder> arrayList3 = new ArrayList<IBinder>();
3432         arrayList3.add(new Binder());
3433         arrayList3.add(new Binder());
3434         arrayList3.add(new Binder());
3435 
3436         p = Parcel.obtain();
3437         p.writeBinderList(null);
3438         p.setDataPosition(0);
3439         try {
3440             p.readBinderList(null);
3441             fail("Should throw a RuntimeException");
3442         } catch (RuntimeException e) {
3443             //expected
3444         }
3445         p.setDataPosition(0);
3446         assertEquals(0, arrayList.size());
3447         p.readBinderList(arrayList);
3448         assertEquals(0, arrayList.size());
3449         p.recycle();
3450 
3451         p = Parcel.obtain();
3452         p.writeBinderList(arrayList2);
3453         p.setDataPosition(0);
3454         assertEquals(0, arrayList.size());
3455         p.readBinderList(arrayList);
3456         assertEquals(2, arrayList.size());
3457         assertEquals(arrayList2, arrayList);
3458         p.recycle();
3459 
3460         p = Parcel.obtain();
3461         p.writeBinderList(arrayList2);
3462         p.setDataPosition(0);
3463         assertEquals(3, arrayList3.size());
3464         p.readBinderList(arrayList3);
3465         assertEquals(2, arrayList3.size());
3466         assertEquals(arrayList2, arrayList3);
3467         p.recycle();
3468     }
3469 
testCreateBinderArrayList()3470     public void testCreateBinderArrayList() {
3471         Parcel p;
3472         ArrayList<IBinder> arrayList = new ArrayList<IBinder>();
3473         ArrayList<IBinder> arrayList2 = new ArrayList<IBinder>();
3474         arrayList2.add(new Binder());
3475         arrayList2.add(new Binder());
3476         ArrayList<IBinder> arrayList3;
3477         ArrayList<IBinder> arrayList4;
3478 
3479         p = Parcel.obtain();
3480         p.writeBinderList(null);
3481         p.setDataPosition(0);
3482         arrayList3 = p.createBinderArrayList();
3483         assertNull(arrayList3);
3484         p.recycle();
3485 
3486         p = Parcel.obtain();
3487         p.writeBinderList(arrayList);
3488         p.setDataPosition(0);
3489         arrayList3 = p.createBinderArrayList();
3490         assertNotNull(arrayList3);
3491         assertEquals(0, arrayList3.size());
3492         p.recycle();
3493 
3494         p = Parcel.obtain();
3495         p.writeBinderList(arrayList2);
3496         p.setDataPosition(0);
3497         arrayList4 = p.createBinderArrayList();
3498         assertNotNull(arrayList4);
3499         assertEquals(arrayList2, arrayList4);
3500         p.recycle();
3501     }
3502 
testInterfaceArray()3503     public void testInterfaceArray() {
3504         Parcel p;
3505         MockIInterface[] iface2 = {new MockIInterface(), new MockIInterface(), null};
3506         MockIInterface[] iface3 = new MockIInterface[iface2.length];
3507         MockIInterface[] iface4 = new MockIInterface[iface2.length + 1];
3508 
3509         p = Parcel.obtain();
3510         p.writeInterfaceArray(null);
3511         p.setDataPosition(0);
3512         try {
3513             // input array shouldn't be null
3514             p.readInterfaceArray(null, null);
3515             fail("Should throw a RuntimeException");
3516         } catch (RuntimeException e) {
3517             // expected
3518         }
3519 
3520         p.setDataPosition(0);
3521         try {
3522             // can't read null array
3523             p.readInterfaceArray(iface3, MockIInterface::asInterface);
3524             fail("Should throw a RuntimeException");
3525         } catch (RuntimeException e) {
3526             // expected
3527         }
3528 
3529         p.setDataPosition(0);
3530         // null if parcel has null array
3531         assertNull(p.createInterfaceArray(MockIInterface[]::new, MockIInterface::asInterface));
3532         p.recycle();
3533 
3534         p = Parcel.obtain();
3535         p.writeInterfaceArray(iface2);
3536         p.setDataPosition(0);
3537         try {
3538             // input array shouldn't be null
3539             p.readInterfaceArray(null, null);
3540             fail("Should throw a RuntimeException");
3541         } catch (RuntimeException e) {
3542             // expected
3543         }
3544 
3545         p.setDataPosition(0);
3546         try {
3547             // input array should be the same size
3548             p.readInterfaceArray(iface4, MockIInterface::asInterface);
3549             fail("Should throw a RuntimeException");
3550         } catch (RuntimeException e) {
3551             // expected
3552         }
3553 
3554         p.setDataPosition(0);
3555         try {
3556             // asInterface shouldn't be null
3557             p.readInterfaceArray(iface3, null);
3558             fail("Should throw a RuntimeException");
3559         } catch (RuntimeException e) {
3560             // expected
3561         }
3562 
3563         p.setDataPosition(0);
3564         // read into input array with the exact size
3565         p.readInterfaceArray(iface3, MockIInterface::asInterface);
3566         for (int i = 0; i < iface3.length; i++) {
3567             assertEquals(iface2[i], iface3[i]);
3568         }
3569 
3570         p.setDataPosition(0);
3571         try {
3572             // newArray/asInterface shouldn't be null
3573             p.createInterfaceArray(null, null);
3574             fail("Should throw a RuntimeException");
3575         } catch (RuntimeException e) {
3576             // expected
3577         }
3578 
3579         p.setDataPosition(0);
3580         // create a new array from parcel
3581         MockIInterface[] iface5 =
3582             p.createInterfaceArray(MockIInterface[]::new, MockIInterface::asInterface);
3583         assertNotNull(iface5);
3584         assertEquals(iface2.length, iface5.length);
3585         for (int i = 0; i < iface5.length; i++) {
3586             assertEquals(iface2[i], iface5[i]);
3587         }
3588         p.recycle();
3589     }
3590 
testInterfaceList()3591     public void testInterfaceList() {
3592         Parcel p;
3593         ArrayList<MockIInterface> arrayList = new ArrayList<>();
3594         ArrayList<MockIInterface> arrayList2 = new ArrayList<>();
3595         ArrayList<MockIInterface> arrayList3;
3596         arrayList.add(new MockIInterface());
3597         arrayList.add(new MockIInterface());
3598         arrayList.add(null);
3599 
3600         p = Parcel.obtain();
3601         p.writeInterfaceList(null);
3602         p.setDataPosition(0);
3603         try {
3604             // input list shouldn't be null
3605             p.readInterfaceList(null, null);
3606             fail("Should throw a RuntimeException");
3607         } catch (RuntimeException e) {
3608             // expected
3609         }
3610 
3611         p.setDataPosition(0);
3612         arrayList2.clear();
3613         arrayList2.add(null);
3614         try {
3615             // can't read null list into non-empty list
3616             p.readInterfaceList(arrayList2, MockIInterface::asInterface);
3617             fail("Should throw a RuntimeException");
3618         } catch (RuntimeException e) {
3619             // expected
3620         }
3621 
3622         p.setDataPosition(0);
3623         arrayList2.clear();
3624         // read null list into empty list
3625         p.readInterfaceList(arrayList2, MockIInterface::asInterface);
3626         assertEquals(0, arrayList2.size());
3627 
3628         p.setDataPosition(0);
3629         // null if parcel has null list
3630         arrayList3 = p.createInterfaceArrayList(MockIInterface::asInterface);
3631         assertNull(arrayList3);
3632         p.recycle();
3633 
3634         p = Parcel.obtain();
3635         p.writeInterfaceList(arrayList);
3636         p.setDataPosition(0);
3637         try {
3638             // input list shouldn't be null
3639             p.readInterfaceList(null, null);
3640             fail("Should throw a RuntimeException");
3641         } catch (RuntimeException e) {
3642             // expected
3643         }
3644 
3645         p.setDataPosition(0);
3646         arrayList2.clear();
3647         try {
3648             // asInterface shouldn't be null
3649             p.readInterfaceList(arrayList2, null);
3650             fail("Should throw a RuntimeException");
3651         } catch (RuntimeException e) {
3652             //expected
3653         }
3654 
3655         p.setDataPosition(0);
3656         arrayList2.clear();
3657         // fill a list with parcel
3658         p.readInterfaceList(arrayList2, MockIInterface::asInterface);
3659         assertEquals(arrayList, arrayList2);
3660 
3661         p.setDataPosition(0);
3662         arrayList2.clear();
3663         // add one more item
3664         for (int i=0; i<arrayList.size() + 1; i++) {
3665             arrayList2.add(null);
3666         }
3667         // extra item should be discarded after read
3668         p.readInterfaceList(arrayList2, MockIInterface::asInterface);
3669         assertEquals(arrayList, arrayList2);
3670 
3671         p.setDataPosition(0);
3672         // create a new ArrayList from parcel
3673         arrayList3 = p.createInterfaceArrayList(MockIInterface::asInterface);
3674         assertEquals(arrayList, arrayList3);
3675         p.recycle();
3676     }
3677 
testFixedArray()3678     public void testFixedArray() {
3679         Parcel p = Parcel.obtain();
3680 
3681         //  test int[2][3]
3682         int[][] ints = new int[][] {{1,2,3}, {4,5,6}};
3683         p.writeFixedArray(ints, 0, new int[]{2, 3});
3684         p.setDataPosition(0);
3685         assertArrayEquals(ints, p.createFixedArray(int[][].class, new int[]{2, 3}));
3686         int[][] readInts = new int[2][3];
3687         p.setDataPosition(0);
3688         p.readFixedArray(readInts);
3689         assertArrayEquals(ints, readInts);
3690 
3691         // test Parcelable[2][3]
3692         p.setDataPosition(0);
3693         Signature[][] signatures = {
3694             {new Signature("1234"), new Signature("ABCD"), new Signature("abcd")},
3695             {new Signature("5678"), new Signature("EFAB"), new Signature("efab")}};
3696         p.writeFixedArray(signatures, 0, new int[]{2, 3});
3697         p.setDataPosition(0);
3698         assertArrayEquals(signatures, p.createFixedArray(Signature[][].class, Signature.CREATOR, new int[]{2, 3}));
3699         Signature[][] readSignatures = new Signature[2][3];
3700         p.setDataPosition(0);
3701         p.readFixedArray(readSignatures, Signature.CREATOR);
3702         assertArrayEquals(signatures, readSignatures);
3703 
3704         // test IInterface[2][3]
3705         p.setDataPosition(0);
3706         MockIInterface[][] interfaces = {
3707             {new MockIInterface(), new MockIInterface(), new MockIInterface()},
3708             {new MockIInterface(), new MockIInterface(), new MockIInterface()}};
3709         p.writeFixedArray(interfaces, 0, new int[]{2, 3});
3710         p.setDataPosition(0);
3711         MockIInterface[][] interfacesRead = p.createFixedArray(MockIInterface[][].class,
3712             MockIInterface::asInterface, new int[]{2, 3});
3713         assertEquals(2, interfacesRead.length);
3714         assertEquals(3, interfacesRead[0].length);
3715         MockIInterface[][] mockInterfaces = new MockIInterface[2][3];
3716         p.setDataPosition(0);
3717         p.readFixedArray(mockInterfaces, MockIInterface::asInterface);
3718         assertArrayEquals(interfaces, mockInterfaces);
3719 
3720         // test null
3721         p.setDataPosition(0);
3722         int[][] nullInts = null;
3723         p.writeFixedArray(nullInts, 0, new int[]{2, 3});
3724         p.setDataPosition(0);
3725         assertNull(p.createFixedArray(int[][].class, new int[]{2, 3}));
3726 
3727         // reject wrong dimensions when writing
3728         p.setDataPosition(0);
3729         assertThrows(BadParcelableException.class,
3730             () -> p.writeFixedArray(new int[3][2], 0, new int[]{2, 2}));
3731         assertThrows(BadParcelableException.class,
3732             () -> p.writeFixedArray(new int[3], 0, new int[]{3, 2}));
3733         assertThrows(BadParcelableException.class,
3734             () -> p.writeFixedArray(new int[3][2], 0, new int[]{3}));
3735 
3736         // reject wrong dimensions when reading
3737         p.setDataPosition(0);
3738         p.writeFixedArray(new int[2][3], 0, new int[]{2, 3});
3739         p.setDataPosition(0);
3740         assertThrows(BadParcelableException.class, () -> p.createFixedArray(int[][].class, 1, 3));
3741         assertThrows(BadParcelableException.class, () -> p.createFixedArray(int[][].class, 2, 2));
3742 
3743         p.recycle();
3744     }
3745 
3746     @SuppressWarnings("unchecked")
testWriteMap()3747     public void testWriteMap() {
3748         Parcel p;
3749         MockClassLoader mcl = new MockClassLoader();
3750         HashMap map = new HashMap();
3751         HashMap map2 = new HashMap();
3752 
3753         p = Parcel.obtain();
3754         p.writeMap(null);
3755         p.setDataPosition(0);
3756         assertEquals(0, map2.size());
3757         p.readMap(map2, mcl);
3758         assertEquals(0, map2.size());
3759         p.recycle();
3760 
3761         map.put("string", "String");
3762         map.put("int", Integer.MAX_VALUE);
3763         map.put("boolean", true);
3764         p = Parcel.obtain();
3765         p.writeMap(map);
3766         p.setDataPosition(0);
3767         assertEquals(0, map2.size());
3768         p.readMap(map2, mcl);
3769         assertEquals(3, map2.size());
3770         assertEquals("String", map.get("string"));
3771         assertEquals(Integer.MAX_VALUE, map.get("int"));
3772         assertEquals(true, map.get("boolean"));
3773         p.recycle();
3774     }
3775 
testReadMapWithClass_whenNull()3776     public void testReadMapWithClass_whenNull() {
3777         Parcel p = Parcel.obtain();
3778         MockClassLoader mcl = new MockClassLoader();
3779         p.writeMap(null);
3780         HashMap<String, Intent> map = new HashMap<>();
3781 
3782         p.setDataPosition(0);
3783         p.readMap(map, mcl, String.class, Intent.class);
3784         assertEquals(0, map.size());
3785 
3786         p.recycle();
3787     }
3788 
testReadMapWithClass_whenMismatchingClass()3789     public void testReadMapWithClass_whenMismatchingClass() {
3790         Parcel p = Parcel.obtain();
3791         ClassLoader loader = getClass().getClassLoader();
3792         HashMap<Signature, TestSubIntent> map = new HashMap<>();
3793 
3794         Intent baseIntent = new Intent();
3795         map.put(new Signature("1234"), new TestSubIntent(
3796                 baseIntent, "test_intent1"));
3797         map.put(new Signature("4321"), new TestSubIntent(
3798                 baseIntent, "test_intent2"));
3799         p.writeMap(map);
3800 
3801         p.setDataPosition(0);
3802         assertThrows(BadParcelableException.class, () ->
3803                 p.readMap(new HashMap<Intent, TestSubIntent>(), loader,
3804                         Intent.class, TestSubIntent.class));
3805 
3806         p.setDataPosition(0);
3807         assertThrows(BadParcelableException.class, () ->
3808                 p.readMap(new HashMap<Signature, Signature>(), loader,
3809                         Signature.class, Signature.class));
3810         p.recycle();
3811     }
3812 
testReadMapWithClass_whenSameClass()3813     public void testReadMapWithClass_whenSameClass() {
3814         Parcel p = Parcel.obtain();
3815         ClassLoader loader = getClass().getClassLoader();
3816         HashMap<String, TestSubIntent> map = new HashMap<>();
3817         HashMap<String, TestSubIntent> map2 = new HashMap<>();
3818 
3819         Intent baseIntent = new Intent();
3820         map.put("key1", new TestSubIntent(
3821                 baseIntent, "test_intent1"));
3822         map.put("key2", new TestSubIntent(
3823                 baseIntent, "test_intent2"));
3824         p.writeMap(map);
3825         p.setDataPosition(0);
3826         p.readMap(map2, loader, String.class, TestSubIntent.class);
3827         assertEquals(map, map2);
3828 
3829         p.recycle();
3830     }
3831 
testReadMapWithClass_whenSubClass()3832     public void testReadMapWithClass_whenSubClass() {
3833         Parcel p = Parcel.obtain();
3834         ClassLoader loader = getClass().getClassLoader();
3835         HashMap<TestSubIntent, TestSubIntent> map = new HashMap<>();
3836 
3837         Intent baseIntent = new Intent();
3838         map.put(new TestSubIntent(baseIntent, "test_intent_key1"), new TestSubIntent(
3839                 baseIntent, "test_intent_val1"));
3840         p.writeMap(map);
3841         p.setDataPosition(0);
3842         HashMap<Intent, Intent> map2 = new HashMap<>();
3843         p.readMap(map2, loader, Intent.class, TestSubIntent.class);
3844         assertEquals(map, map2);
3845 
3846         p.setDataPosition(0);
3847         HashMap<Intent, Intent> map3 = new HashMap<>();
3848         p.readMap(map3, loader, TestSubIntent.class, Intent.class);
3849         assertEquals(map, map3);
3850 
3851         p.recycle();
3852     }
3853 
3854     @SuppressWarnings("unchecked")
testReadHashMap()3855     public void testReadHashMap() {
3856         Parcel p;
3857         MockClassLoader mcl = new MockClassLoader();
3858         HashMap map = new HashMap();
3859         HashMap map2;
3860 
3861         p = Parcel.obtain();
3862         p.writeMap(null);
3863         p.setDataPosition(0);
3864         map2 = p.readHashMap(mcl);
3865         assertNull(map2);
3866         p.recycle();
3867 
3868         map.put("string", "String");
3869         map.put("int", Integer.MAX_VALUE);
3870         map.put("boolean", true);
3871         map2 = null;
3872         p = Parcel.obtain();
3873         p.writeMap(map);
3874         p.setDataPosition(0);
3875         map2 = p.readHashMap(mcl);
3876         assertNotNull(map2);
3877         assertEquals(3, map2.size());
3878         assertEquals("String", map.get("string"));
3879         assertEquals(Integer.MAX_VALUE, map.get("int"));
3880         assertEquals(true, map.get("boolean"));
3881         p.recycle();
3882     }
3883 
testReadHashMapWithClass_whenNull()3884     public void testReadHashMapWithClass_whenNull() {
3885         Parcel p = Parcel.obtain();
3886         MockClassLoader mcl = new MockClassLoader();
3887         p.writeMap(null);
3888         p.setDataPosition(0);
3889         assertNull(p.readHashMap(mcl, String.class, Intent.class));
3890 
3891         p.setDataPosition(0);
3892         assertNull(p.readHashMap(null, String.class, Intent.class));
3893         p.recycle();
3894     }
3895 
testReadHashMapWithClass_whenMismatchingClass()3896     public void testReadHashMapWithClass_whenMismatchingClass() {
3897         Parcel p = Parcel.obtain();
3898         ClassLoader loader = getClass().getClassLoader();
3899         HashMap<Signature, TestSubIntent> map = new HashMap<>();
3900 
3901         Intent baseIntent = new Intent();
3902         map.put(new Signature("1234"), new TestSubIntent(
3903                 baseIntent, "test_intent1"));
3904         map.put(new Signature("4321"), new TestSubIntent(
3905                 baseIntent, "test_intent2"));
3906         p.writeMap(map);
3907 
3908         p.setDataPosition(0);
3909         assertThrows(BadParcelableException.class, () ->
3910                 p.readHashMap(loader, Intent.class, TestSubIntent.class));
3911 
3912         p.setDataPosition(0);
3913         assertThrows(BadParcelableException.class, () ->
3914                 p.readHashMap(loader, Signature.class, Signature.class));
3915         p.recycle();
3916     }
3917 
testReadHashMapWithClass_whenSameClass()3918     public void testReadHashMapWithClass_whenSameClass() {
3919         Parcel p = Parcel.obtain();
3920         ClassLoader loader = getClass().getClassLoader();
3921         HashMap<String, TestSubIntent> map = new HashMap<>();
3922 
3923         Intent baseIntent = new Intent();
3924         map.put("key1", new TestSubIntent(
3925                 baseIntent, "test_intent1"));
3926         map.put("key2", new TestSubIntent(
3927                 baseIntent, "test_intent2"));
3928 
3929         p.writeMap(map);
3930         p.setDataPosition(0);
3931         HashMap<String, TestSubIntent> map2 = p.readHashMap(loader, String.class,
3932                 TestSubIntent.class);
3933         assertEquals(map, map2);
3934 
3935         p.setDataPosition(0);
3936         HashMap<Object, Intent> map3 = p.readHashMap(loader, String.class,
3937                 TestSubIntent.class);
3938         assertEquals(map, map3);
3939 
3940         p.recycle();
3941     }
3942 
testReadHashMapWithClass_whenSubClass()3943     public void testReadHashMapWithClass_whenSubClass() {
3944         Parcel p = Parcel.obtain();
3945         ClassLoader loader = getClass().getClassLoader();
3946         HashMap<TestSubIntent, TestSubIntent> map = new HashMap<>();
3947 
3948         Intent baseIntent = new Intent();
3949         TestSubIntent test_intent_key1 = new TestSubIntent(baseIntent, "test_intent_key1");
3950         map.put(test_intent_key1, new TestSubIntent(
3951                 baseIntent, "test_intent_val1"));
3952         p.writeMap(map);
3953         p.setDataPosition(0);
3954         HashMap<Intent, Intent> map2 = p.readHashMap(loader, Intent.class, TestSubIntent.class);
3955         assertEquals(map, map2);
3956 
3957         p.setDataPosition(0);
3958         HashMap<Intent, Intent> map3 = p.readHashMap(loader, TestSubIntent.class, Intent.class);
3959         assertEquals(map, map3);
3960         p.recycle();
3961     }
3962 
3963     @SuppressWarnings("unchecked")
testReadList()3964     public void testReadList() {
3965         Parcel p;
3966         MockClassLoader mcl = new MockClassLoader();
3967         ArrayList arrayList = new ArrayList();
3968 
3969         p = Parcel.obtain();
3970         p.writeList(null);
3971         p.setDataPosition(0);
3972         assertEquals(0, arrayList.size());
3973         p.readList(arrayList, mcl);
3974         assertEquals(0, arrayList.size());
3975         p.recycle();
3976 
3977         ArrayList arrayList2 = new ArrayList();
3978         arrayList2.add(Integer.MAX_VALUE);
3979         arrayList2.add(true);
3980         arrayList2.add(Long.MAX_VALUE);
3981         arrayList2.add("String");
3982         arrayList2.add(Float.MAX_VALUE);
3983 
3984         p = Parcel.obtain();
3985         p.writeList(arrayList2);
3986         p.setDataPosition(0);
3987         assertEquals(0, arrayList.size());
3988         p.readList(arrayList, mcl);
3989         assertEquals(5, arrayList.size());
3990         for (int i = 0; i < arrayList.size(); i++) {
3991             assertEquals(arrayList.get(i), arrayList2.get(i));
3992         }
3993 
3994         p.recycle();
3995     }
3996 
3997     @SuppressWarnings("unchecked")
testReadListWithClass()3998     public void testReadListWithClass() {
3999         Parcel p;
4000         MockClassLoader mcl = new MockClassLoader();
4001         ArrayList<Signature> arrayList = new ArrayList();
4002         ArrayList<Signature> parcelableArrayList = new ArrayList();
4003         final String s1  = "1234567890abcdef";
4004         final String s2  = "abcdef1234567890";
4005         parcelableArrayList.add(new Signature(s1));
4006         parcelableArrayList.add(new Signature(s2));
4007 
4008         p = Parcel.obtain();
4009         p.writeList(parcelableArrayList);
4010         p.setDataPosition(0);
4011         assertEquals(0, arrayList.size());
4012         p.readList(arrayList, mcl, Signature.class);
4013         assertEquals(2, arrayList.size());
4014         for (int i = 0; i < arrayList.size(); i++) {
4015             assertEquals(arrayList.get(i), parcelableArrayList.get(i));
4016         }
4017 
4018         p.setDataPosition(0);
4019         assertThrows(BadParcelableException.class, () -> p.readList(new ArrayList(), mcl, Intent.class));
4020 
4021         p.setDataPosition(0);
4022         assertThrows(BadParcelableException.class, () -> p.readList(new ArrayList(), mcl, Integer.class));
4023         p.recycle();
4024 
4025         ArrayList<String> stringArrayList = new ArrayList();
4026         stringArrayList.add(s1);
4027         stringArrayList.add(s2);
4028         Parcel p1 = Parcel.obtain();
4029         p1.writeList(stringArrayList);
4030 
4031         p1.setDataPosition(0);
4032         assertThrows(BadParcelableException.class, () -> p1.readList(new ArrayList(), mcl, Integer.class));
4033         p1.recycle();
4034     }
4035 
4036     @SuppressWarnings("unchecked")
testReadListWithSubClass()4037     public void testReadListWithSubClass() {
4038         Parcel p;
4039         ArrayList<Intent> arrayList = new ArrayList();
4040         ArrayList<Intent> arrayList2 = new ArrayList();
4041         ArrayList<Intent> parcelableArrayList = new ArrayList();
4042         final Intent baseIntent = new Intent();
4043         final TestSubIntent testSubIntent = new TestSubIntent(baseIntent, "1234567890abcdef");
4044         final TestSubIntent testSubIntent1 = new TestSubIntent(baseIntent, "abcdef1234567890");
4045         parcelableArrayList.add(testSubIntent);
4046         parcelableArrayList.add(testSubIntent1);
4047 
4048         p = Parcel.obtain();
4049         p.writeList(parcelableArrayList);
4050         p.setDataPosition(0);
4051         assertEquals(0, arrayList.size());
4052         p.readList(arrayList, getClass().getClassLoader(), Intent.class);
4053         assertEquals(2, arrayList.size());
4054         for (int i = 0; i < arrayList.size(); i++) {
4055             assertEquals(arrayList.get(i), parcelableArrayList.get(i));
4056         }
4057 
4058         p.setDataPosition(0);
4059         assertEquals(0, arrayList2.size());
4060         p.readList(arrayList2, getClass().getClassLoader(), TestSubIntent.class);
4061         assertEquals(2, arrayList2.size());
4062         for (int i = 0; i < arrayList2.size(); i++) {
4063             assertEquals(arrayList2.get(i), parcelableArrayList.get(i));
4064         }
4065 
4066         p.recycle();
4067     }
4068 
testBinderDataProtection()4069     public void testBinderDataProtection() {
4070         Parcel p;
4071         IBinder b = new Binder();
4072 
4073         p = Parcel.obtain();
4074         final int firstIntPos = p.dataPosition();
4075         p.writeInt(1);
4076         p.writeStrongBinder(b);
4077         final int secondIntPos = p.dataPosition();
4078         p.writeInt(2);
4079         p.writeStrongBinder(b);
4080         final int thirdIntPos = p.dataPosition();
4081         p.writeInt(3);
4082 
4083         for (int pos = 0; pos <= thirdIntPos; pos++) {
4084             p.setDataPosition(pos);
4085             int value = p.readInt();
4086 
4087             // WARNING: this is using unstable APIs: these positions aren't guaranteed
4088             if (firstIntPos - 4 <= pos && pos <= firstIntPos) continue;
4089             if (secondIntPos - 4 <= pos && pos <= secondIntPos) continue;
4090             if (thirdIntPos - 4 <= pos && pos <= thirdIntPos) continue;
4091 
4092             // All other read attempts cross into protected data and will return 0
4093             assertEquals(0, value);
4094         }
4095 
4096         p.recycle();
4097     }
4098 
testBinderDataProtectionIncrements()4099     public void testBinderDataProtectionIncrements() {
4100         Parcel p;
4101         IBinder b = new Binder();
4102 
4103         p = Parcel.obtain();
4104         final int firstIntPos = p.dataPosition();
4105         p.writeInt(1);
4106         p.writeStrongBinder(b);
4107         final int secondIntPos = p.dataPosition();
4108         p.writeInt(2);
4109         p.writeStrongBinder(b);
4110         final int thirdIntPos = p.dataPosition();
4111         p.writeInt(3);
4112         final int end = p.dataPosition();
4113 
4114         p.setDataPosition(0);
4115         int pos;
4116         do {
4117             pos = p.dataPosition();
4118             int value = p.readInt();
4119 
4120             // WARNING: this is using unstable APIs: these positions aren't guaranteed
4121             if (firstIntPos - 4 <= pos && pos <= firstIntPos) continue;
4122             if (secondIntPos - 4 <= pos && pos <= secondIntPos) continue;
4123             if (thirdIntPos - 4 <= pos && pos <= thirdIntPos) continue;
4124 
4125             assertEquals(0, value);
4126         } while(pos < end);
4127 
4128         p.recycle();
4129     }
4130 
4131     private class MockClassLoader extends ClassLoader {
MockClassLoader()4132         public MockClassLoader() {
4133             super();
4134         }
4135     }
4136 
4137     private static class MockIInterface implements IInterface {
4138         public Binder binder;
4139         private static final String DESCRIPTOR = "MockIInterface";
MockIInterface()4140         public MockIInterface() {
4141             binder = new Binder();
4142             binder.attachInterface(this, DESCRIPTOR);
4143         }
4144 
asBinder()4145         public IBinder asBinder() {
4146             return binder;
4147         }
4148 
asInterface(IBinder binder)4149         public static MockIInterface asInterface(IBinder binder) {
4150             if (binder != null) {
4151                 IInterface iface = binder.queryLocalInterface(DESCRIPTOR);
4152                 if (iface != null && iface instanceof MockIInterface) {
4153                     return (MockIInterface) iface;
4154                 }
4155             }
4156             return null;
4157         }
4158     }
4159 
4160     private static boolean parcelableWithBadCreatorInitializerHasRun;
4161     private static boolean invalidCreatorIntializerHasRun;
4162 
4163     /**
4164      * A class that would be Parcelable except that it doesn't have a CREATOR field declared to be
4165      * of the correct type.
4166      */
4167     @SuppressWarnings({"unused", "ParcelableCreator"}) // Referenced via reflection only
4168     private static class ParcelableWithBadCreator implements Parcelable {
4169 
4170         static {
4171             ParcelTest.parcelableWithBadCreatorInitializerHasRun = true;
4172         }
4173 
4174         private static class InvalidCreator
4175                 implements Parcelable.Creator<ParcelableWithBadCreator> {
4176 
4177             static {
4178                 invalidCreatorIntializerHasRun = true;
4179             }
4180 
4181             @Override
createFromParcel(Parcel source)4182             public ParcelableWithBadCreator createFromParcel(Parcel source) {
4183                 return null;
4184             }
4185 
4186             @Override
newArray(int size)4187             public ParcelableWithBadCreator[] newArray(int size) {
4188                 return new ParcelableWithBadCreator[0];
4189             }
4190 
4191         }
4192 
4193         // Invalid declaration: Must be declared as Parcelable.Creator or a subclass.
4194         public static Object CREATOR = new InvalidCreator();
4195 
4196         @Override
describeContents()4197         public int describeContents() {
4198             return 0;
4199         }
4200 
4201         @Override
writeToParcel(Parcel dest, int flags)4202         public void writeToParcel(Parcel dest, int flags) {
4203 
4204         }
4205     }
4206 
4207     // http://b/1171613
testBadStream_invalidCreator()4208     public void testBadStream_invalidCreator() {
4209         Parcel parcel = Parcel.obtain();
4210         // Create an invalid stream by manipulating the Parcel.
4211         parcel.writeString(getClass().getName() + "$ParcelableWithBadCreator");
4212         byte[] badData = parcel.marshall();
4213         parcel.recycle();
4214 
4215         // Now try to read the bad data.
4216         parcel = Parcel.obtain();
4217         parcel.unmarshall(badData, 0, badData.length);
4218         parcel.setDataPosition(0);
4219         try {
4220             parcel.readParcelable(getClass().getClassLoader());
4221             fail();
4222         } catch (BadParcelableException expected) {
4223         } finally {
4224             parcel.recycle();
4225         }
4226 
4227         assertFalse(invalidCreatorIntializerHasRun);
4228         assertFalse(parcelableWithBadCreatorInitializerHasRun);
4229     }
4230 
4231     private static boolean doesNotImplementParcelableInitializerHasRun;
4232 
4233     /** A class that would be Parcelable except that it does not implement Parcelable. */
4234     @SuppressWarnings("unused") // Referenced via reflection only
4235     private static class DoesNotImplementParcelable {
4236 
4237         static {
4238             doesNotImplementParcelableInitializerHasRun = true;
4239         }
4240 
4241         public static Parcelable.Creator<Object> CREATOR = new Parcelable.Creator<Object>() {
4242             @Override
4243             public Object createFromParcel(Parcel source) {
4244                 return new DoesNotImplementParcelable();
4245             }
4246 
4247             @Override
4248             public Object[] newArray(int size) {
4249                 return new Object[size];
4250             }
4251         };
4252     }
4253 
4254     // http://b/1171613
testBadStream_objectDoesNotImplementParcelable()4255     public void testBadStream_objectDoesNotImplementParcelable() {
4256         Parcel parcel = Parcel.obtain();
4257         // Create an invalid stream by manipulating the Parcel.
4258         parcel.writeString(getClass().getName() + "$DoesNotImplementParcelable");
4259         byte[] badData = parcel.marshall();
4260         parcel.recycle();
4261 
4262         // Now try to read the bad data.
4263         parcel = Parcel.obtain();
4264         parcel.unmarshall(badData, 0, badData.length);
4265         parcel.setDataPosition(0);
4266         try {
4267             parcel.readParcelable(getClass().getClassLoader());
4268             fail();
4269         } catch (BadParcelableException expected) {
4270         } finally {
4271             parcel.recycle();
4272         }
4273 
4274         assertFalse(doesNotImplementParcelableInitializerHasRun);
4275     }
4276 
4277     public static class SimpleParcelable implements Parcelable {
4278         private final int value;
4279 
SimpleParcelable(int value)4280         public SimpleParcelable(int value) {
4281             this.value = value;
4282         }
4283 
SimpleParcelable(Parcel in)4284         private SimpleParcelable(Parcel in) {
4285             this.value = in.readInt();
4286         }
4287 
getValue()4288         public int getValue() {
4289             return value;
4290         }
4291 
4292         @Override
describeContents()4293         public int describeContents() {
4294             return 0;
4295         }
4296 
4297         @Override
writeToParcel(Parcel out, int flags)4298         public void writeToParcel(Parcel out, int flags) {
4299             out.writeInt(value);
4300         }
4301 
4302         public static Parcelable.Creator<SimpleParcelable> CREATOR =
4303                 new Parcelable.Creator<SimpleParcelable>() {
4304 
4305             @Override
4306             public SimpleParcelable createFromParcel(Parcel source) {
4307                 return new SimpleParcelable(source);
4308             }
4309 
4310             @Override
4311             public SimpleParcelable[] newArray(int size) {
4312                 return new SimpleParcelable[size];
4313             }
4314         };
4315     }
4316 
testReadWriteParcellableList()4317     public void testReadWriteParcellableList() {
4318         Parcel parcel = Parcel.obtain();
4319 
4320         ArrayList<SimpleParcelable> list = new ArrayList<>();
4321         list.add(new SimpleParcelable(57));
4322 
4323         // Writing a |null| list to a parcel should work, and reading it back
4324         // from a parcel should clear the target list.
4325         parcel.writeParcelableList(null, 0);
4326         parcel.setDataPosition(0);
4327         parcel.readParcelableList(list, SimpleParcelable.class.getClassLoader());
4328         assertEquals(0, list.size());
4329 
4330         list.clear();
4331         list.add(new SimpleParcelable(42));
4332         list.add(new SimpleParcelable(56));
4333 
4334         parcel.setDataPosition(0);
4335         parcel.writeParcelableList(list, 0);
4336 
4337         // Populate the list with a value, we will later assert that the
4338         // value has been removed.
4339         list.clear();
4340         list.add(new SimpleParcelable(100));
4341 
4342         parcel.setDataPosition(0);
4343         parcel.readParcelableList(list, SimpleParcelable.class.getClassLoader());
4344 
4345         assertEquals(2, list.size());
4346         assertEquals(42, list.get(0).getValue());
4347         assertEquals(56, list.get(1).getValue());
4348     }
4349 
testReadParcelableListWithClass_whenNull()4350     public void testReadParcelableListWithClass_whenNull(){
4351         final Parcel p = Parcel.obtain();
4352         ArrayList<Intent> list = new ArrayList<>();
4353         list.add(new Intent("test"));
4354 
4355         p.writeParcelableList(null, 0);
4356         p.setDataPosition(0);
4357         p.readParcelableList(list, getClass().getClassLoader(), Intent.class);
4358         assertEquals(0, list.size());
4359         p.recycle();
4360     }
4361 
testReadParcelableListWithClass_whenMismatchingClass()4362     public void testReadParcelableListWithClass_whenMismatchingClass(){
4363         final Parcel p = Parcel.obtain();
4364         ArrayList<Signature> list = new ArrayList<>();
4365         ArrayList<Intent> list1 = new ArrayList<>();
4366         list.add(new Signature("1234"));
4367         p.writeParcelableList(list, 0);
4368         p.setDataPosition(0);
4369         assertThrows(BadParcelableException.class, () ->
4370                 p.readParcelableList(list1, getClass().getClassLoader(), Intent.class));
4371 
4372         p.recycle();
4373     }
4374 
testReadParcelableListWithClass_whenSameClass()4375     public void testReadParcelableListWithClass_whenSameClass(){
4376         final Parcel p = Parcel.obtain();
4377         ArrayList<Signature> list = new ArrayList<>();
4378         ArrayList<Signature> list1 = new ArrayList<>();
4379         list.add(new Signature("1234"));
4380         list.add(new Signature("4321"));
4381         p.writeParcelableList(list, 0);
4382         p.setDataPosition(0);
4383         p.readParcelableList(list1, getClass().getClassLoader(), Signature.class);
4384 
4385         assertEquals(list, list1);
4386         p.recycle();
4387     }
4388 
testReadParcelableListWithClass_whenSubClass()4389     public void testReadParcelableListWithClass_whenSubClass(){
4390         final Parcel p = Parcel.obtain();
4391         final Intent baseIntent = new Intent();
4392 
4393         ArrayList<Intent> intentArrayList = new ArrayList<>();
4394         ArrayList<Intent> intentArrayList1 = new ArrayList<>();
4395         ArrayList<Intent> intentArrayList2 = new ArrayList<>();
4396 
4397         intentArrayList.add(new TestSubIntent(baseIntent, "1234567890abcdef"));
4398         intentArrayList.add(null);
4399         intentArrayList.add(new TestSubIntent(baseIntent, "abcdef1234567890"));
4400 
4401         p.writeParcelableList(intentArrayList, 0);
4402         p.setDataPosition(0);
4403         p.readParcelableList(intentArrayList1, getClass().getClassLoader(), Intent.class);
4404         assertEquals(intentArrayList, intentArrayList1);
4405 
4406         p.setDataPosition(0);
4407         p.readParcelableList(intentArrayList2, getClass().getClassLoader(), TestSubIntent.class);
4408         assertEquals(intentArrayList, intentArrayList2);
4409         p.recycle();
4410     }
4411 
4412     // http://b/35384981
testCreateArrayWithTruncatedParcel()4413     public void testCreateArrayWithTruncatedParcel() {
4414         Parcel parcel = Parcel.obtain();
4415         parcel.writeByteArray(new byte[] { 'a', 'b' });
4416         byte[] marshalled = parcel.marshall();
4417 
4418         // Test that createByteArray returns null with a truncated parcel.
4419         parcel = Parcel.obtain();
4420         parcel.unmarshall(marshalled, 0, marshalled.length);
4421         parcel.setDataPosition(0);
4422         // Shorten the data size by 2 to remove padding at the end of the array.
4423         parcel.setDataSize(marshalled.length - 2);
4424         assertNull(parcel.createByteArray());
4425 
4426         // Test that readByteArray returns null with a truncated parcel.
4427         parcel = Parcel.obtain();
4428         parcel.unmarshall(marshalled, 0, marshalled.length);
4429         parcel.setDataSize(marshalled.length - 2);
4430         try {
4431             parcel.readByteArray(new byte[2]);
4432             fail();
4433         } catch (RuntimeException expected) {
4434         }
4435     }
4436 
testMaliciousMapWrite()4437     public void testMaliciousMapWrite() {
4438         class MaliciousMap<K, V> extends HashMap<K, V> {
4439             public int fakeSize = 0;
4440             public boolean armed = false;
4441 
4442             class FakeEntrySet extends HashSet<Entry<K, V>> {
4443                 public FakeEntrySet(Collection<? extends Entry<K, V>> c) {
4444                     super(c);
4445                 }
4446 
4447                 @Override
4448                 public int size() {
4449                     if (armed) {
4450                         // Only return fake size on next call, to mitigate unexpected behavior.
4451                         armed = false;
4452                         return fakeSize;
4453                     } else {
4454                         return super.size();
4455                     }
4456                 }
4457             }
4458 
4459             @Override
4460             public Set<Map.Entry<K, V>> entrySet() {
4461                 return new FakeEntrySet(super.entrySet());
4462             }
4463         }
4464 
4465         Parcel parcel = Parcel.obtain();
4466 
4467         // Fake having more Map entries than there really are
4468         MaliciousMap map = new MaliciousMap<String, String>();
4469         map.fakeSize = 1;
4470         map.armed = true;
4471         try {
4472             parcel.writeMap(map);
4473             fail("Should have thrown a BadParcelableException");
4474         } catch (BadParcelableException bpe) {
4475             // good
4476         }
4477 
4478         // Fake having fewer Map entries than there really are
4479         map = new MaliciousMap<String, String>();
4480         map.put("key", "value");
4481         map.fakeSize = 0;
4482         map.armed = true;
4483         try {
4484             parcel.writeMap(map);
4485             fail("Should have thrown a BadParcelableException");
4486         } catch (BadParcelableException bpe) {
4487             // good
4488         }
4489     }
4490 
4491     public static class ParcelExceptionConnection extends AbstractFuture<IParcelExceptionService>
4492             implements ServiceConnection {
4493         @Override
onServiceConnected(ComponentName name, IBinder service)4494         public void onServiceConnected(ComponentName name, IBinder service) {
4495             set(IParcelExceptionService.Stub.asInterface(service));
4496         }
4497 
4498         @Override
onServiceDisconnected(ComponentName name)4499         public void onServiceDisconnected(ComponentName name) {
4500         }
4501 
4502         @Override
get()4503         public IParcelExceptionService get() throws InterruptedException, ExecutionException {
4504             try {
4505                 return get(5, TimeUnit.SECONDS);
4506             } catch (TimeoutException e) {
4507                 throw new RuntimeException(e);
4508             }
4509         }
4510     }
4511 
testExceptionOverwritesObject()4512     public void testExceptionOverwritesObject() throws Exception {
4513         final Intent intent = new Intent();
4514         intent.setComponent(new ComponentName(
4515                 "android.os.cts", "android.os.cts.ParcelExceptionService"));
4516 
4517         final ParcelExceptionConnection connection = new ParcelExceptionConnection();
4518 
4519         mContext.startService(intent);
4520         assertTrue(mContext.bindService(intent, connection,
4521                 Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE));
4522 
4523 
4524         Parcel data = Parcel.obtain();
4525         Parcel reply = Parcel.obtain();
4526         data.writeInterfaceToken("android.os.cts.IParcelExceptionService");
4527         IParcelExceptionService service = connection.get();
4528         try {
4529             assertTrue("Transaction failed", service.asBinder().transact(
4530                     IParcelExceptionService.Stub.TRANSACTION_writeBinderThrowException, data, reply,
4531                     0));
4532         } catch (Exception e) {
4533             fail("Exception caught from transaction: " + e);
4534         }
4535         reply.setDataPosition(0);
4536         assertTrue("Exception should have occurred on service-side",
4537                 reply.readExceptionCode() != 0);
4538         assertNull("Binder should have been overwritten by the exception",
4539                 reply.readStrongBinder());
4540     }
4541 
4542     private static class TestSubIntent extends Intent {
4543         private final String mString;
4544 
TestSubIntent(Intent baseIntent, String s)4545         public TestSubIntent(Intent baseIntent, String s) {
4546             super(baseIntent);
4547             mString = s;
4548         }
4549 
writeToParcel(Parcel dest, int parcelableFlags)4550         public void writeToParcel(Parcel dest, int parcelableFlags) {
4551             super.writeToParcel(dest, parcelableFlags);
4552             dest.writeString(mString);
4553         }
4554 
TestSubIntent(Parcel in)4555         TestSubIntent(Parcel in) {
4556             readFromParcel(in);
4557             mString = in.readString();
4558         }
4559 
4560         public static final Creator<TestSubIntent> CREATOR = new Creator<TestSubIntent>() {
4561             public TestSubIntent createFromParcel(Parcel source) {
4562                 return new TestSubIntent(source);
4563             }
4564 
4565             @Override
4566             public TestSubIntent[] newArray(int size) {
4567                 return new TestSubIntent[size];
4568             }
4569         };
4570 
4571         @Override
equals(Object obj)4572         public boolean equals(Object obj) {
4573             final TestSubIntent other = (TestSubIntent) obj;
4574             return mString.equals(other.mString);
4575         }
4576 
4577         @Override
hashCode()4578         public int hashCode() {
4579             return mString.hashCode();
4580         }
4581     }
4582 
4583     private static class TestSubException extends Exception{
TestSubException(String msg)4584         public TestSubException(String msg) {
4585             super(msg);
4586         }
4587     }
4588 
4589     public static class ParcelObjectFreeService extends Service {
4590 
4591         @Override
onBind(Intent intent)4592         public IBinder onBind(Intent intent) {
4593             return new Binder();
4594         }
4595 
4596         @Override
onCreate()4597         public void onCreate() {
4598             super.onCreate();
4599 
4600             Parcel parcel = Parcel.obtain();
4601 
4602             // Construct parcel with object in it.
4603             parcel.writeInt(1);
4604             final int pos = parcel.dataPosition();
4605             parcel.writeStrongBinder(new Binder());
4606 
4607             // wipe out the object by setting data size
4608             parcel.setDataSize(pos);
4609 
4610             // recycle the parcel. This should not cause a native segfault
4611             parcel.recycle();
4612         }
4613 
4614         public static class Connection extends AbstractFuture<IBinder>
4615                 implements ServiceConnection {
4616 
4617             @Override
onServiceConnected(ComponentName name, IBinder service)4618             public void onServiceConnected(ComponentName name, IBinder service) {
4619                 set(service);
4620             }
4621 
4622             @Override
onServiceDisconnected(ComponentName name)4623             public void onServiceDisconnected(ComponentName name) {
4624             }
4625 
4626             @Override
get()4627             public IBinder get() throws InterruptedException, ExecutionException {
4628                 try {
4629                     return get(5, TimeUnit.SECONDS);
4630                 } catch (TimeoutException e) {
4631                     return null;
4632                 }
4633             }
4634         }
4635     }
4636 
testObjectDoubleFree()4637     public void testObjectDoubleFree() throws Exception {
4638 
4639         final Intent intent = new Intent();
4640         intent.setComponent(new ComponentName(
4641                 "android.os.cts", "android.os.cts.ParcelTest$ParcelObjectFreeService"));
4642 
4643         final ParcelObjectFreeService.Connection connection =
4644                 new ParcelObjectFreeService.Connection();
4645 
4646         mContext.startService(intent);
4647         assertTrue(mContext.bindService(intent, connection,
4648                 Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE));
4649 
4650         assertNotNull("Service should have started without crashing.", connection.get());
4651     }
4652 
4653     @AsbSecurityTest(cveBugId = 140419401)
testObjectResize()4654     public void testObjectResize() throws Exception {
4655         Parcel p;
4656         IBinder b1 = new Binder();
4657         IBinder b2 = new Binder();
4658 
4659         p = Parcel.obtain();
4660         p.writeStrongBinder(b1);
4661         p.setDataSize(0);
4662         p.writeStrongBinder(b2);
4663 
4664         p.setDataPosition(0);
4665         assertEquals("Object in parcel should match the binder written after the resize", b2,
4666                 p.readStrongBinder());
4667         p.recycle();
4668 
4669         p = Parcel.obtain();
4670         p.writeStrongBinder(b1);
4671         final int secondBinderPos = p.dataPosition();
4672         p.writeStrongBinder(b1);
4673         p.setDataSize(secondBinderPos);
4674         p.writeStrongBinder(b2);
4675 
4676         p.setDataPosition(0);
4677         assertEquals("Object at the start of the parcel parcel should match the first binder", b1,
4678                 p.readStrongBinder());
4679         assertEquals("Object in parcel should match the binder written after the resize", b2,
4680                 p.readStrongBinder());
4681         p.recycle();
4682     }
4683 
testFlags()4684     public void testFlags() {
4685         Parcel p;
4686 
4687         p = Parcel.obtain();
4688         assertEquals(0, p.getFlags());
4689         p.setPropagateAllowBlocking();
4690         assertEquals(Parcel.FLAG_PROPAGATE_ALLOW_BLOCKING, p.getFlags());
4691 
4692         // recycle / obtain should clear the flag.
4693         p.recycle();
4694         p = Parcel.obtain();
4695         assertEquals(0, p.getFlags());
4696     }
4697 
4698     public static class SimpleParcelableWithoutNestedCreator implements Parcelable {
4699         private final int value;
4700 
SimpleParcelableWithoutNestedCreator(int value)4701         public SimpleParcelableWithoutNestedCreator(int value) {
4702             this.value = value;
4703         }
4704 
SimpleParcelableWithoutNestedCreator(Parcel in)4705         private SimpleParcelableWithoutNestedCreator(Parcel in) {
4706             this.value = in.readInt();
4707         }
4708 
getValue()4709         public int getValue() {
4710             return value;
4711         }
4712 
4713         @Override
describeContents()4714         public int describeContents() {
4715             return 0;
4716         }
4717 
4718         @Override
writeToParcel(Parcel out, int flags)4719         public void writeToParcel(Parcel out, int flags) {
4720             out.writeInt(value);
4721         }
4722 
4723         public static Parcelable.Creator<SimpleParcelableWithoutNestedCreator> CREATOR =
4724                 new SimpleParcelableWithoutNestedCreatorCreator();
4725     }
4726 
4727     public static class SimpleParcelableWithoutNestedCreatorCreator implements
4728             Parcelable.Creator<SimpleParcelableWithoutNestedCreator> {
4729         @Override
createFromParcel(Parcel source)4730         public SimpleParcelableWithoutNestedCreator createFromParcel(Parcel source) {
4731             return new SimpleParcelableWithoutNestedCreator(source);
4732         }
4733 
4734         @Override
newArray(int size)4735         public SimpleParcelableWithoutNestedCreator[] newArray(int size) {
4736             return new SimpleParcelableWithoutNestedCreator[size];
4737         }
4738     }
4739 
4740     // http://b/232589966
testReadParcelableWithoutNestedCreator()4741     public void testReadParcelableWithoutNestedCreator() {
4742         Parcel p = Parcel.obtain();
4743         p.writeParcelable(new SimpleParcelableWithoutNestedCreator(1), 0);
4744         p.setDataPosition(0);
4745         // First time checks the type of the creator using reflection
4746         SimpleParcelableWithoutNestedCreator parcelable =
4747                 p.readParcelable(getClass().getClassLoader(),
4748                         SimpleParcelableWithoutNestedCreator.class);
4749         assertEquals(1, parcelable.value);
4750         p.recycle();
4751 
4752         p = Parcel.obtain();
4753         p.writeParcelable(new SimpleParcelableWithoutNestedCreator(2), 0);
4754         p.setDataPosition(0);
4755         // Second time tries to read it from a cache
4756         parcelable =
4757                 p.readParcelable(getClass().getClassLoader(),
4758                         SimpleParcelableWithoutNestedCreator.class);
4759         assertEquals(2, parcelable.value);
4760         p.recycle();
4761     }
4762 
4763     @ApiTest(apis = {"android.os.Parcel#writeTypedSparseArray(android.utilSparseArray, int)",
4764             "android.os.Parcel#createTypedSparseArray(android.os.Parcelable.Creator)"})
testCreateTypedSparseArray()4765     public void testCreateTypedSparseArray() {
4766         Parcel p;
4767         SparseArray<Signature> s = new SparseArray<>();
4768         s.append(1, new Signature("1234"));
4769         s.append(2, new Signature("ABCD"));
4770         s.append(3, new Signature("abcd"));
4771 
4772         SparseArray<Signature> s2 = new SparseArray<>();
4773         s2.append(1, new Signature("1234"));
4774         s2.append(2, null);
4775         s2.append(3, new Signature("abcd"));
4776         SparseArray<Signature> s3;
4777 
4778         // test write null
4779         p = Parcel.obtain();
4780         p.writeTypedSparseArray(null, 0);
4781         p.setDataPosition(0);
4782         assertNull(p.createTypedSparseArray(Signature.CREATOR));
4783         p.recycle();
4784 
4785         // test write not null
4786         p = Parcel.obtain();
4787         p.writeTypedSparseArray(s, 0);
4788         p.setDataPosition(0);
4789         s3 = p.createTypedSparseArray(Signature.CREATOR);
4790         assertNotNull(s3);
4791         assertEquals(s3.size(), s.size());
4792         for (int i = 0; i < s.size(); i++) {
4793             assertEquals(s3.keyAt(i), s.keyAt(i));
4794             assertEquals(s3.valueAt(i), s.valueAt(i));
4795         }
4796         p.recycle();
4797 
4798         p = Parcel.obtain();
4799         p.writeTypedSparseArray(s2, 0);
4800         p.setDataPosition(0);
4801         s3 = p.createTypedSparseArray(Signature.CREATOR);
4802         assertNotNull(s3);
4803         assertEquals(s3.size(), s2.size());
4804         for (int i = 0; i < s.size(); i++) {
4805             assertEquals(s3.keyAt(i), s2.keyAt(i));
4806             assertEquals(s3.valueAt(i), s2.valueAt(i));
4807         }
4808         p.recycle();
4809     }
4810 }
4811