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