1 /*
2  * Copyright (C) 2018 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.binder.cts;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assume.assumeTrue;
25 
26 import android.os.IBinder;
27 import android.os.ParcelFileDescriptor;
28 import android.os.PersistableBundle;
29 import android.os.Process;
30 import android.os.RemoteException;
31 import android.util.Log;
32 import androidx.test.InstrumentationRegistry;
33 import java.io.FileInputStream;
34 import java.io.FileOutputStream;
35 import java.io.IOException;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Collection;
39 import java.util.List;
40 import java.util.function.BiPredicate;
41 import org.junit.Assert;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.junit.runners.Parameterized;
46 import test_package.Bar;
47 import test_package.Baz;
48 import test_package.ByteEnum;
49 import test_package.ExtendableParcelable;
50 import test_package.Foo;
51 import test_package.GenericBar;
52 import test_package.GenericFoo;
53 import test_package.ICompatTest;
54 import test_package.IEmpty;
55 import test_package.ITest;
56 import test_package.IntEnum;
57 import test_package.LongEnum;
58 import test_package.MyExt;
59 import test_package.RegularPolygon;
60 import test_package.SimpleUnion;
61 
62 @RunWith(Parameterized.class)
63 public class JavaClientTest {
64     private final String TAG = "JavaClientTest";
65 
66     private Class mServiceClass;
67     private ITest mInterface;
68     private String mExpectedName;
69     private boolean mShouldBeRemote;
70     private boolean mShouldBeOld;
71 
JavaClientTest(Class serviceClass, String expectedName, boolean shouldBeRemote, boolean shouldBeOld)72     public JavaClientTest(Class serviceClass, String expectedName, boolean shouldBeRemote, boolean shouldBeOld) {
73         mServiceClass = serviceClass;
74         mExpectedName = expectedName;
75         mShouldBeRemote = shouldBeRemote;
76         mShouldBeOld = shouldBeOld;
77     }
78 
79     @Parameterized.Parameters( name = "{0}" )
data()80     public static Collection<Object[]> data() {
81         // For local interfaces, this test will parcel the data locally.
82         // Whenever possible, the desired service should be accessed directly
83         // in order to avoid this additional overhead.
84         return Arrays.asList(new Object[][] {
85                 {NativeService.Local.class, "CPP", false /*shouldBeRemote*/, false /*shouldBeOld*/},
86                 {JavaService.Local.class, "JAVA", false /*shouldBeRemote*/, false /*shouldBeOld*/},
87                 {NativeService.Remote.class, "CPP", true /*shouldBeRemote*/, false /*shouldBeOld*/},
88                 {NativeService.RemoteOld.class, "CPP", true /*shouldBeRemote*/, true /*shouldBeOld*/},
89                 {JavaService.Remote.class, "JAVA", true /*shouldBeRemote*/, false /*shouldBeOld*/},
90             });
91     }
92 
93     @Before
setUp()94     public void setUp() {
95         Log.e(TAG, "Setting up");
96 
97         SyncTestServiceConnection connection = new SyncTestServiceConnection(
98             InstrumentationRegistry.getTargetContext(), mServiceClass);
99 
100         mInterface = connection.get();
101         assertNotEquals(null, mInterface);
102     }
103 
104     @Test
testSanityCheckSource()105     public void testSanityCheckSource() throws RemoteException {
106         String name = mInterface.GetName();
107 
108         Log.i(TAG, "Service GetName: " + name);
109         assertEquals(mExpectedName, name);
110     }
111 
112     @Test
testVoidReturn()113     public void testVoidReturn() throws RemoteException {
114         mInterface.TestVoidReturn();
115     }
116 
117     @Test
testOneway()118     public void testOneway() throws RemoteException {
119         boolean isLocalJava = !mShouldBeRemote && mExpectedName == "JAVA";
120         try {
121             mInterface.TestOneway();
122             assertFalse("local Java should throw exception", isLocalJava);
123         } catch (RemoteException e) {
124             assertTrue("only local Java should report error", isLocalJava);
125         }
126     }
127 
checkDump(String expected, String[] args)128     private void checkDump(String expected, String[] args) throws RemoteException, IOException {
129         ParcelFileDescriptor[] sockets = ParcelFileDescriptor.createReliableSocketPair();
130         ParcelFileDescriptor socketIn = sockets[0];
131         ParcelFileDescriptor socketOut = sockets[1];
132 
133         mInterface.asBinder().dump(socketIn.getFileDescriptor(), args);
134         socketIn.close();
135 
136         FileInputStream fileInputStream = new ParcelFileDescriptor.AutoCloseInputStream(socketOut);
137 
138         byte[] expectedBytes = expected.getBytes();
139         byte[] input = new byte[expectedBytes.length];
140 
141         assertEquals(input.length, fileInputStream.read(input));
142         Assert.assertArrayEquals(input, expectedBytes);
143     }
144 
145     @Test
testDump()146     public void testDump() throws RemoteException, IOException {
147         checkDump("", new String[]{});
148         checkDump("", new String[]{"", ""});
149         checkDump("Hello World!", new String[]{"Hello ", "World!"});
150         checkDump("ABC", new String[]{"A", "B", "C"});
151     }
152 
153     @Test
testCallingInfo()154     public void testCallingInfo() throws RemoteException {
155       mInterface.CacheCallingInfoFromOneway();
156 
157       assertEquals(Process.myPid(), mInterface.GiveMeMyCallingPid());
158       assertEquals(Process.myUid(), mInterface.GiveMeMyCallingUid());
159 
160       if (mShouldBeRemote) {
161         // PID is hidden from oneway calls
162         assertEquals(0, mInterface.GiveMeMyCallingPidFromOneway());
163       } else {
164         assertEquals(Process.myPid(), mInterface.GiveMeMyCallingPidFromOneway());
165       }
166 
167       assertEquals(Process.myUid(), mInterface.GiveMeMyCallingUidFromOneway());
168     }
169 
170     @Test
testRepeatPrimitives()171     public void testRepeatPrimitives() throws RemoteException {
172         assertEquals(1, mInterface.RepeatInt(1));
173         assertEquals(2, mInterface.RepeatLong(2));
174         assertEquals(1.0f, mInterface.RepeatFloat(1.0f), 0.0f);
175         assertEquals(2.0, mInterface.RepeatDouble(2.0), 0.0);
176         assertEquals(true, mInterface.RepeatBoolean(true));
177         assertEquals('a', mInterface.RepeatChar('a'));
178         assertEquals((byte)3, mInterface.RepeatByte((byte)3));
179         assertEquals(ByteEnum.FOO, mInterface.RepeatByteEnum(ByteEnum.FOO));
180         assertEquals(IntEnum.FOO, mInterface.RepeatIntEnum(IntEnum.FOO));
181         assertEquals(LongEnum.FOO, mInterface.RepeatLongEnum(LongEnum.FOO));
182     }
183 
184     @Test
testRepeatBinder()185     public void testRepeatBinder() throws RemoteException {
186         IBinder binder = mInterface.asBinder();
187 
188         assertEquals(binder, mInterface.RepeatBinder(binder));
189         assertEquals(binder, mInterface.RepeatNullableBinder(binder));
190         assertEquals(null, mInterface.RepeatNullableBinder(null));
191     }
192 
193     private static class Empty extends IEmpty.Stub {}
194 
195     @Test
testRepeatInterface()196     public void testRepeatInterface() throws RemoteException {
197         IEmpty empty = new Empty();
198 
199         assertEquals(empty, mInterface.RepeatInterface(empty));
200         assertEquals(empty, mInterface.RepeatNullableInterface(empty));
201         assertEquals(null, mInterface.RepeatNullableInterface(null));
202     }
203 
204     private static interface IRepeatFd {
repeat(ParcelFileDescriptor fd)205         ParcelFileDescriptor repeat(ParcelFileDescriptor fd) throws RemoteException;
206     }
207 
checkFdRepeated(IRepeatFd transformer)208     private void checkFdRepeated(IRepeatFd transformer) throws RemoteException, IOException {
209         ParcelFileDescriptor[] sockets = ParcelFileDescriptor.createReliableSocketPair();
210         ParcelFileDescriptor socketIn = sockets[0];
211         ParcelFileDescriptor socketOut = sockets[1];
212 
213         ParcelFileDescriptor repeatFd = transformer.repeat(socketIn);
214 
215         boolean isNativeRemote = mInterface.GetName().equals("CPP");
216         try {
217             socketOut.checkError();
218 
219             // Either native didn't properly call detach, or native properly handles detach, and
220             // we should change the test to enforce that socket comms work.
221             assertFalse("Native doesn't implement comm fd but did not get detach.", isNativeRemote);
222         } catch (ParcelFileDescriptor.FileDescriptorDetachedException e) {
223             assertTrue("Detach, so remote should be native", isNativeRemote);
224         }
225 
226         // Both backends support these.
227         socketIn.checkError();
228         repeatFd.checkError();
229 
230         checkInOutSockets(repeatFd, socketOut);
231     }
232 
233     @Test
testRepeatFd()234     public void testRepeatFd() throws RemoteException, IOException {
235         checkFdRepeated((fd) -> mInterface.RepeatFd(fd));
236     }
237 
238     @Test
testRepeatFdNull()239     public void testRepeatFdNull() throws RemoteException {
240         boolean isNativeRemote = mInterface.GetName().equals("CPP");
241 
242         try {
243             mInterface.RepeatFd(null);
244             assertFalse("Native shouldn't accept null here", isNativeRemote);
245         } catch (java.lang.NullPointerException e) {
246             assertTrue("Java should accept null here", isNativeRemote);
247         }
248     }
249 
250     @Test
testRepeatNullableFd()251     public void testRepeatNullableFd() throws RemoteException, IOException {
252         checkFdRepeated((fd) -> mInterface.RepeatNullableFd(fd));
253         assertEquals(null, mInterface.RepeatNullableFd(null));
254     }
255 
checkInOutSockets(ParcelFileDescriptor in, ParcelFileDescriptor out)256     private void checkInOutSockets(ParcelFileDescriptor in, ParcelFileDescriptor out) throws IOException {
257         FileOutputStream repeatFdStream = new ParcelFileDescriptor.AutoCloseOutputStream(in);
258         String testData = "asdf";
259         byte[] output = testData.getBytes();
260         repeatFdStream.write(output);
261         repeatFdStream.close();
262 
263         FileInputStream fileInputStream = new ParcelFileDescriptor.AutoCloseInputStream(out);
264         byte[] input = new byte[output.length];
265 
266         assertEquals(input.length, fileInputStream.read(input));
267         Assert.assertArrayEquals(input, output);
268     }
269 
270     @Test
testRepeatFdArray()271     public void testRepeatFdArray() throws RemoteException, IOException {
272         ParcelFileDescriptor[] sockets1 = ParcelFileDescriptor.createReliableSocketPair();
273         ParcelFileDescriptor[] sockets2 = ParcelFileDescriptor.createReliableSocketPair();
274         ParcelFileDescriptor[] inputs = {sockets1[0], sockets2[0]};
275         ParcelFileDescriptor[] repeatFdArray = new ParcelFileDescriptor[inputs.length];
276         mInterface.RepeatFdArray(inputs, repeatFdArray);
277 
278         checkInOutSockets(repeatFdArray[0], sockets1[1]);
279         checkInOutSockets(repeatFdArray[1], sockets2[1]);
280     }
281 
282     @Test
testRepeatString()283     public void testRepeatString() throws RemoteException {
284         assertEquals("", mInterface.RepeatString(""));
285         assertEquals("a", mInterface.RepeatString("a"));
286         assertEquals("foo", mInterface.RepeatString("foo"));
287 
288         String stringWithNulls = "a\0df";
289         assertEquals(stringWithNulls, mInterface.RepeatString(stringWithNulls));
290     }
291 
292     @Test
testRepeatNullableString()293     public void testRepeatNullableString() throws RemoteException {
294         assertEquals(null, mInterface.RepeatNullableString(null));
295         assertEquals("", mInterface.RepeatNullableString(""));
296         assertEquals("a", mInterface.RepeatNullableString("a"));
297         assertEquals("foo", mInterface.RepeatNullableString("foo"));
298     }
299 
assertPolygonEquals(RegularPolygon lhs, RegularPolygon rhs)300     public void assertPolygonEquals(RegularPolygon lhs, RegularPolygon rhs) {
301         assertEquals(lhs.name, rhs.name);
302         assertEquals(lhs.numSides, rhs.numSides);
303         assertEquals(lhs.sideLength, rhs.sideLength, 0.0f);
304     }
assertPolygonEquals(RegularPolygon[] lhs, RegularPolygon[] rhs)305     public void assertPolygonEquals(RegularPolygon[] lhs, RegularPolygon[] rhs) {
306         assertEquals(lhs.length, rhs.length);
307         for (int i = 0; i < lhs.length; i++) {
308             assertPolygonEquals(lhs[i], rhs[i]);
309         }
310     }
311 
312     @Test
testRepeatPolygon()313     public void testRepeatPolygon() throws RemoteException {
314         RegularPolygon polygon = new RegularPolygon();
315         polygon.name = "hexagon";
316         polygon.numSides = 6;
317         polygon.sideLength = 1.0f;
318 
319         RegularPolygon result = mInterface.RepeatPolygon(polygon);
320 
321         assertPolygonEquals(polygon, result);
322     }
323 
324     @Test
testRepeatUnexpectedNullPolygon()325     public void testRepeatUnexpectedNullPolygon() throws RemoteException {
326         try {
327            RegularPolygon result = mInterface.RepeatPolygon(null);
328         } catch (NullPointerException e) {
329            // non-@nullable C++ result can't handle null Polygon
330            return;
331         }
332         // Java always works w/ nullptr
333         assertEquals("JAVA", mExpectedName);
334     }
335 
336     @Test
testRepeatNullNullablePolygon()337     public void testRepeatNullNullablePolygon() throws RemoteException {
338         RegularPolygon result = mInterface.RepeatNullablePolygon(null);
339         assertEquals(null, result);
340     }
341 
342     @Test
testRepeatDefaultPersistableBundle()343     public void testRepeatDefaultPersistableBundle() throws RemoteException {
344         PersistableBundle bundle = new PersistableBundle();
345         PersistableBundle result = mInterface.RepeatPersistableBundle(bundle);
346         assertNotEquals(null, result);
347         assertEquals(bundle.size(), result.size());
348     }
349 
350     @Test
testRepeatTypesPersistableBundle()351     public void testRepeatTypesPersistableBundle() throws RemoteException {
352         PersistableBundle bundle = new PersistableBundle();
353         boolean[] boolV = {true, false, true};
354         int[] intV = {123, 111, 321};
355         long[] longV = {123, 111, 321};
356         double[] doubleV = {123, 111, 321};
357         String[] stringV = {"hello", "world", "!"};
358         bundle.putBoolean("bool", true);
359         bundle.putInt("int", 11111);
360         bundle.putLong("long", 12345);
361         bundle.putDouble("double", 54321);
362         bundle.putString("string", "cool");
363         bundle.putBooleanArray("boolv", boolV);
364         bundle.putIntArray("intv", intV);
365         bundle.putLongArray("longv", longV);
366         bundle.putDoubleArray("doublev", doubleV);
367         bundle.putStringArray("stringv", stringV);
368         PersistableBundle innerBundle = new PersistableBundle();
369         innerBundle.putBoolean("bool", true);
370         bundle.putPersistableBundle("bundle", innerBundle);
371         PersistableBundle result = mInterface.RepeatPersistableBundle(bundle);
372         assertNotEquals(null, result);
373         assertEquals(bundle.size(), result.size());
374         assertEquals(true, result.getBoolean("bool"));
375         assertEquals(11111, result.getInt("int"));
376         assertEquals(12345, result.getLong("long"));
377         assertEquals(54321, result.getDouble("double"), 0.0);
378         assertEquals("cool", result.getString("string"));
379         assertArrayEquals(boolV, result.getBooleanArray("boolv"));
380         assertArrayEquals(intV, result.getIntArray("intv"));
381         assertArrayEquals(longV, result.getLongArray("longv"));
382         // no assertArrayEquals for double
383         double[] ret = result.getDoubleArray("doublev");
384         for (int i = 0; i < doubleV.length; i++) {
385           assertEquals(doubleV[i], ret[i], 0.0);
386         }
387         assertArrayEquals(stringV, result.getStringArray("stringv"));
388         assertEquals(innerBundle.size(), result.getPersistableBundle("bundle").size());
389     }
390 
391     @Test
testEraseAllPersistableBundle()392     public void testEraseAllPersistableBundle() throws RemoteException {
393         PersistableBundle bundle = new PersistableBundle();
394         bundle.putBoolean("bool", true);
395         bundle.putInt("int", 11111);
396         bundle.putLong("long", 12345);
397         bundle.putDouble("double", 54321);
398         bundle.putString("string", "cool");
399         assertNotEquals(0, bundle.size());
400         bundle.remove("bool");
401         bundle.remove("int");
402         bundle.remove("long");
403         bundle.remove("double");
404         bundle.remove("string");
405     }
406 
407     @Test
testRepeatPresentNullablePolygon()408     public void testRepeatPresentNullablePolygon() throws RemoteException {
409         RegularPolygon polygon = new RegularPolygon();
410         polygon.name = "septagon";
411         polygon.numSides = 7;
412         polygon.sideLength = 9.0f;
413 
414         RegularPolygon result = mInterface.RepeatNullablePolygon(polygon);
415 
416         assertPolygonEquals(polygon, result);
417     }
418 
419     @Test
testInsAndOuts()420     public void testInsAndOuts() throws RemoteException {
421         RegularPolygon polygon = new RegularPolygon();
422         mInterface.RenamePolygon(polygon, "Jerry");
423         assertEquals("Jerry", polygon.name);
424     }
425 
426     @Test
testArrays()427     public void testArrays() throws RemoteException {
428         {
429             boolean[] value = {};
430             boolean[] out1 = new boolean[value.length];
431             boolean[] out2 = mInterface.RepeatBooleanArray(value, out1);
432 
433             Assert.assertArrayEquals(value, out1);
434             Assert.assertArrayEquals(value, out2);
435         }
436         {
437             boolean[] value = {false, true, false};
438             boolean[] out1 = new boolean[value.length];
439             boolean[] out2 = mInterface.RepeatBooleanArray(value, out1);
440 
441             Assert.assertArrayEquals(value, out1);
442             Assert.assertArrayEquals(value, out2);
443         }
444         {
445             byte[] value = {1, 2, 3};
446             byte[] out1 = new byte[value.length];
447             byte[] out2 = mInterface.RepeatByteArray(value, out1);
448 
449             Assert.assertArrayEquals(value, out1);
450             Assert.assertArrayEquals(value, out2);
451         }
452         {
453             char[] value = {'h', 'a', '!'};
454             char[] out1 = new char[value.length];
455             char[] out2 = mInterface.RepeatCharArray(value, out1);
456 
457             Assert.assertArrayEquals(value, out1);
458             Assert.assertArrayEquals(value, out2);
459         }
460         {
461             int[] value = {1, 2, 3};
462             int[] out1 = new int[value.length];
463             int[] out2 = mInterface.RepeatIntArray(value, out1);
464 
465             Assert.assertArrayEquals(value, out1);
466             Assert.assertArrayEquals(value, out2);
467         }
468         {
469             long[] value = {1, 2, 3};
470             long[] out1 = new long[value.length];
471             long[] out2 = mInterface.RepeatLongArray(value, out1);
472 
473             Assert.assertArrayEquals(value, out1);
474             Assert.assertArrayEquals(value, out2);
475         }
476         {
477             float[] value = {1.0f, 2.0f, 3.0f};
478             float[] out1 = new float[value.length];
479             float[] out2 = mInterface.RepeatFloatArray(value, out1);
480 
481             Assert.assertArrayEquals(value, out1, 0.0f);
482             Assert.assertArrayEquals(value, out2, 0.0f);
483         }
484         {
485             double[] value = {1.0, 2.0, 3.0};
486             double[] out1 = new double[value.length];
487             double[] out2 = mInterface.RepeatDoubleArray(value, out1);
488 
489             Assert.assertArrayEquals(value, out1, 0.0);
490             Assert.assertArrayEquals(value, out2, 0.0);
491         }
492         {
493             byte[] value = {ByteEnum.FOO, ByteEnum.BAR};
494             byte[] out1 = new byte[value.length];
495             byte[] out2 = mInterface.RepeatByteEnumArray(value, out1);
496 
497             Assert.assertArrayEquals(value, out1);
498             Assert.assertArrayEquals(value, out2);
499         }
500         {
501             int[] value = {IntEnum.FOO, IntEnum.BAR};
502             int[] out1 = new int[value.length];
503             int[] out2 = mInterface.RepeatIntEnumArray(value, out1);
504 
505             Assert.assertArrayEquals(value, out1);
506             Assert.assertArrayEquals(value, out2);
507         }
508         {
509             long[] value = {LongEnum.FOO, LongEnum.BAR};
510             long[] out1 = new long[value.length];
511             long[] out2 = mInterface.RepeatLongEnumArray(value, out1);
512 
513             Assert.assertArrayEquals(value, out1);
514             Assert.assertArrayEquals(value, out2);
515         }
516         {
517             String[] value = {"", "aoeu", "lol", "brb"};
518             String[] out1 = new String[value.length];
519             String[] out2 = mInterface.RepeatStringArray(value, out1);
520 
521             Assert.assertArrayEquals(value, out1);
522             Assert.assertArrayEquals(value, out2);
523         }
524         {
525 
526             RegularPolygon septagon = new RegularPolygon();
527             septagon.name = "septagon";
528             septagon.numSides = 7;
529             septagon.sideLength = 1.0f;
530 
531             RegularPolygon[] value = {septagon, new RegularPolygon(), new RegularPolygon()};
532             RegularPolygon[] out1 = new RegularPolygon[value.length];
533             RegularPolygon[] out2 = mInterface.RepeatRegularPolygonArray(value, out1);
534 
535             assertPolygonEquals(value, out1);
536             assertPolygonEquals(value, out2);
537         }
538     }
539 
540     @Test
testLists()541     public void testLists() throws RemoteException {
542         {
543             List<String> value = Arrays.asList("", "aoeu", "lol", "brb");
544             List<String> out1 = new ArrayList<>();
545             List<String> out2 = mInterface.Repeat2StringList(value, out1);
546 
547             List<String> expected = new ArrayList<>();
548             expected.addAll(value);
549             expected.addAll(value);
550             String[] expectedArray = expected.toArray(new String[0]);
551 
552             Assert.assertArrayEquals(expectedArray, out1.toArray(new String[0]));
553             Assert.assertArrayEquals(expectedArray, out2.toArray(new String[0]));
554         }
555         {
556             RegularPolygon septagon = new RegularPolygon();
557             septagon.name = "septagon";
558             septagon.numSides = 7;
559             septagon.sideLength = 1.0f;
560 
561             List<RegularPolygon> value = Arrays.asList(septagon, new RegularPolygon(), new RegularPolygon());
562             List<RegularPolygon> out1 = new ArrayList<>();
563             List<RegularPolygon> out2 = mInterface.Repeat2RegularPolygonList(value, out1);
564 
565             List<RegularPolygon> expected = new ArrayList<>();
566             expected.addAll(value);
567             expected.addAll(value);
568             RegularPolygon[] expectedArray = expected.toArray(new RegularPolygon[0]);
569 
570             assertPolygonEquals(expectedArray, out1.toArray(new RegularPolygon[0]));
571             assertPolygonEquals(expectedArray, out1.toArray(new RegularPolygon[0]));
572         }
573     }
574 
575     @Test
testNullableArrays()576     public void testNullableArrays() throws RemoteException {
577         {
578             boolean[] emptyValue = {};
579             boolean[] value = {false, true, false};
580             Assert.assertArrayEquals(null, mInterface.RepeatNullableBooleanArray(null));
581             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableBooleanArray(emptyValue));
582             Assert.assertArrayEquals(value, mInterface.RepeatNullableBooleanArray(value));
583         }
584         {
585             byte[] emptyValue = {};
586             byte[] value = {1, 2, 3};
587             Assert.assertArrayEquals(null, mInterface.RepeatNullableByteArray(null));
588             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableByteArray(emptyValue));
589             Assert.assertArrayEquals(value, mInterface.RepeatNullableByteArray(value));
590         }
591         {
592             char[] emptyValue = {};
593             char[] value = {'h', 'a', '!'};
594             Assert.assertArrayEquals(null, mInterface.RepeatNullableCharArray(null));
595             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableCharArray(emptyValue));
596             Assert.assertArrayEquals(value, mInterface.RepeatNullableCharArray(value));
597         }
598         {
599             int[] emptyValue = {};
600             int[] value = {1, 2, 3};
601             Assert.assertArrayEquals(null, mInterface.RepeatNullableIntArray(null));
602             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableIntArray(emptyValue));
603             Assert.assertArrayEquals(value, mInterface.RepeatNullableIntArray(value));
604         }
605         {
606             long[] emptyValue = {};
607             long[] value = {1, 2, 3};
608             Assert.assertArrayEquals(null, mInterface.RepeatNullableLongArray(null));
609             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableLongArray(emptyValue));
610             Assert.assertArrayEquals(value, mInterface.RepeatNullableLongArray(value));
611         }
612         {
613             float[] emptyValue = {};
614             float[] value = {1.0f, 2.0f, 3.0f};
615             Assert.assertArrayEquals(null, mInterface.RepeatNullableFloatArray(null), 0.0f);
616             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableFloatArray(emptyValue), 0.0f);
617             Assert.assertArrayEquals(value, mInterface.RepeatNullableFloatArray(value), 0.0f);
618         }
619         {
620             double[] emptyValue = {};
621             double[] value = {1.0, 2.0, 3.0};
622             Assert.assertArrayEquals(null, mInterface.RepeatNullableDoubleArray(null), 0.0);
623             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableDoubleArray(emptyValue), 0.0);
624             Assert.assertArrayEquals(value, mInterface.RepeatNullableDoubleArray(value), 0.0);
625         }
626         {
627             byte[] emptyValue = {};
628             byte[] value = {ByteEnum.FOO, ByteEnum.BAR};
629             Assert.assertArrayEquals(null, mInterface.RepeatNullableByteEnumArray(null));
630             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableByteEnumArray(emptyValue));
631             Assert.assertArrayEquals(value, mInterface.RepeatNullableByteEnumArray(value));
632         }
633         {
634             int[] emptyValue = {};
635             int[] value = {IntEnum.FOO, IntEnum.BAR};
636             Assert.assertArrayEquals(null, mInterface.RepeatNullableIntEnumArray(null));
637             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableIntEnumArray(emptyValue));
638             Assert.assertArrayEquals(value, mInterface.RepeatNullableIntEnumArray(value));
639         }
640         {
641             long[] emptyValue = {};
642             long[] value = {LongEnum.FOO, LongEnum.BAR};
643             Assert.assertArrayEquals(null, mInterface.RepeatNullableLongEnumArray(null));
644             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableLongEnumArray(emptyValue));
645             Assert.assertArrayEquals(value, mInterface.RepeatNullableLongEnumArray(value));
646         }
647         {
648             String[] emptyValue = {};
649             String[] value = {"", "aoeu", null, "brb"};
650             Assert.assertArrayEquals(null, mInterface.RepeatNullableStringArray(null));
651             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableStringArray(emptyValue));
652             Assert.assertArrayEquals(value, mInterface.RepeatNullableStringArray(value));
653         }
654         {
655             String[] emptyValue = {};
656             String[] value = {"", "aoeu", null, "brb"};
657             String[] out1 = new String[value.length];
658             String[] out2 = mInterface.DoubleRepeatNullableStringArray(value, out1);
659 
660             Assert.assertArrayEquals(value, out1);
661             Assert.assertArrayEquals(value, out2);
662         }
663     }
664 
665     @Test
testGetLastItem()666     public void testGetLastItem() throws RemoteException {
667         Foo foo = new Foo();
668         foo.d = new Bar();
669         foo.e = new Bar();
670         foo.f = 15;
671         foo.shouldContainTwoByteFoos = new byte[]{};
672         foo.shouldContainTwoIntFoos = new int[]{};
673         foo.shouldContainTwoLongFoos = new long[]{};
674         foo.bundle1 = new PersistableBundle();
675         foo.bundleArray = new PersistableBundle[]{};
676 
677         assertEquals(foo.f, mInterface.getF(foo));
678     }
679 
680     @Test
testRepeatFoo()681     public void testRepeatFoo() throws RemoteException {
682         Foo foo = new Foo();
683 
684         foo.a = "NEW FOO";
685         foo.b = 57;
686 
687         foo.d = new Bar();
688         foo.d.b = "a";
689 
690         foo.e = new Bar();
691         foo.e.d = 99;
692 
693         foo.shouldBeByteBar = ByteEnum.BAR;
694         foo.shouldBeIntBar = IntEnum.BAR;
695         foo.shouldBeLongBar = LongEnum.BAR;
696 
697         foo.shouldContainTwoByteFoos = new byte[]{ByteEnum.FOO, ByteEnum.FOO};
698         foo.shouldContainTwoIntFoos = new int[]{IntEnum.FOO, IntEnum.FOO};
699         foo.shouldContainTwoLongFoos = new long[]{LongEnum.FOO, LongEnum.FOO};
700 
701         foo.bundle1 = new PersistableBundle();
702         foo.bundleArray = new PersistableBundle[]{};
703 
704         foo.u = SimpleUnion.e(new byte[]{ByteEnum.FOO, ByteEnum.FOO});
705 
706         foo.shouldSetBit0AndBit2 = Foo.BIT0 | Foo.BIT2;
707         foo.shouldBeConstS1 = SimpleUnion.c(SimpleUnion.S1);
708 
709         Foo repeatedFoo = mInterface.repeatFoo(foo);
710 
711         assertEquals(foo.a, repeatedFoo.a);
712         assertEquals(foo.b, repeatedFoo.b);
713         assertEquals(foo.d.b, repeatedFoo.d.b);
714         assertEquals(foo.e.d, repeatedFoo.e.d);
715         assertEquals(foo.shouldBeByteBar, repeatedFoo.shouldBeByteBar);
716         assertEquals(foo.shouldBeIntBar, repeatedFoo.shouldBeIntBar);
717         assertEquals(foo.shouldBeLongBar, repeatedFoo.shouldBeLongBar);
718         Assert.assertArrayEquals(foo.shouldContainTwoByteFoos, repeatedFoo.shouldContainTwoByteFoos);
719         Assert.assertArrayEquals(foo.shouldContainTwoIntFoos, repeatedFoo.shouldContainTwoIntFoos);
720         Assert.assertArrayEquals(foo.shouldContainTwoLongFoos, repeatedFoo.shouldContainTwoLongFoos);
721         Assert.assertArrayEquals(foo.u.getE(), repeatedFoo.u.getE());
722         assertEquals(foo.shouldSetBit0AndBit2, repeatedFoo.shouldSetBit0AndBit2);
723         assertEquals(foo.shouldBeConstS1.getC(), repeatedFoo.shouldBeConstS1.getC());
724     }
725 
726     @Test
testRepeatGenericBar()727     public void testRepeatGenericBar() throws RemoteException {
728       GenericBar<Integer> bar = new GenericBar<Integer>();
729       bar.shouldBeGenericFoo = new GenericFoo<Integer, Bar, Integer>();
730       bar.shouldBeGenericFoo.a = 41;
731       bar.shouldBeGenericFoo.b = 42;
732       GenericBar<Integer> repeatedBar = new GenericBar<Integer>();
733       repeatedBar = mInterface.repeatGenericBar(bar);
734 
735       assertEquals(bar.a, repeatedBar.a);
736       assertEquals(bar.shouldBeGenericFoo.a, repeatedBar.shouldBeGenericFoo.a);
737       assertEquals(bar.shouldBeGenericFoo.b, repeatedBar.shouldBeGenericFoo.b);
738     }
739 
740     @Test
testNewField()741     public void testNewField() throws RemoteException {
742         Baz baz = new Baz();
743         baz.d = new String[]{"a", "b", "c"};
744         ICompatTest compatTest = ICompatTest.Stub.asInterface(mInterface.getICompatTest());
745         Baz newBaz = compatTest.repeatBaz(baz);
746         if (mShouldBeOld) {
747             assertEquals(null, newBaz.d);
748         } else {
749             Assert.assertArrayEquals(baz.d, newBaz.d);
750         }
751     }
752 
753     @Test
testGetInterfaceVersion()754     public void testGetInterfaceVersion() throws RemoteException {
755         ICompatTest compatTest = ICompatTest.Stub.asInterface(mInterface.getICompatTest());
756         if (mShouldBeOld) {
757             assertEquals(1, compatTest.getInterfaceVersion());
758         } else {
759             assertTrue(compatTest.getInterfaceVersion() >= 2);
760         }
761     }
762 
763     @Test
testGetInterfaceHash()764     public void testGetInterfaceHash() throws RemoteException {
765         ICompatTest compatTest = ICompatTest.Stub.asInterface(mInterface.getICompatTest());
766         if (mShouldBeOld) {
767             assertEquals("b663b681b3e0d66f9b5428c2f23365031b7d4ba0", compatTest.getInterfaceHash());
768         } else {
769             if (compatTest.getInterfaceVersion() == 2) {
770                 assertEquals("2740afaf3b5a0e739c44165c49633a0af87369f2",
771                         compatTest.getInterfaceHash());
772             } else {
773                 assertEquals("notfrozen", compatTest.getInterfaceHash());
774             }
775         }
776     }
777 
778     @Test
testLegacyBinder()779     public void testLegacyBinder() throws RemoteException {
780         ILegacyBinder compatTest = ILegacyBinder.Stub.asInterface(mInterface.getLegacyBinderTest());
781         assertEquals(42, compatTest.RepeatInt(42));
782     }
783 
784     @Test
testRenameFoo()785     public void testRenameFoo() throws RemoteException {
786         Foo foo = new Foo();
787         foo.d = new Bar();
788         foo.e = new Bar();
789         foo.shouldContainTwoByteFoos = new byte[]{};
790         foo.shouldContainTwoIntFoos = new int[]{};
791         foo.shouldContainTwoLongFoos = new long[]{};
792         foo.bundle1 = new PersistableBundle();
793         foo.bundleArray = new PersistableBundle[]{};
794         mInterface.renameFoo(foo, "MYFOO");
795         assertEquals("MYFOO", foo.a);
796     }
797 
798     @Test
testRenameBar()799     public void testRenameBar() throws RemoteException {
800         Foo foo = new Foo();
801         foo.d = new Bar();
802         foo.e = new Bar();
803         foo.shouldContainTwoByteFoos = new byte[]{};
804         foo.shouldContainTwoIntFoos = new int[]{};
805         foo.shouldContainTwoLongFoos = new long[]{};
806         foo.bundle1 = new PersistableBundle();
807         foo.bundleArray = new PersistableBundle[]{};
808         mInterface.renameBar(foo, "MYBAR");
809         assertEquals("MYBAR", foo.d.a);
810     }
811 
812     @Test
testRepeatStringNullableLater()813     public void testRepeatStringNullableLater() throws RemoteException {
814         // see notes in native NdkBinderTest_Aidl RepeatStringNullableLater
815         boolean handlesNull = !mShouldBeOld || mExpectedName == "JAVA";
816         ICompatTest compatTest = ICompatTest.Stub.asInterface(mInterface.getICompatTest());
817 
818         try {
819             assertEquals(null, compatTest.RepeatStringNullableLater(null));
820             assertTrue("should reach here if null is handled", handlesNull);
821         } catch (NullPointerException e) {
822             assertFalse("should reach here if null isn't handled", handlesNull);
823         }
824         assertEquals("", compatTest.RepeatStringNullableLater(""));
825         assertEquals("a", compatTest.RepeatStringNullableLater("a"));
826         assertEquals("foo", compatTest.RepeatStringNullableLater("foo"));
827     }
828 
829     @Test
testParcelableHolder()830     public void testParcelableHolder() throws RemoteException {
831         ExtendableParcelable ep = new ExtendableParcelable();
832         ep.c = 42L;
833         MyExt myext1 = new MyExt();
834         myext1.a = 42;
835         myext1.b = "mystr";
836         ep.ext.setParcelable(myext1);
837 
838         ExtendableParcelable ep2 = new ExtendableParcelable();
839         mInterface.RepeatExtendableParcelable(ep, ep2);
840         MyExt myext2 = ep2.ext.getParcelable(MyExt.class);
841         assertEquals(42L, ep2.c);
842         assertNotEquals(null, myext2);
843         assertEquals(42, myext2.a);
844         assertEquals("mystr", myext2.b);
845     }
846 
847     @Test
testEmptyParcelableHolder()848     public void testEmptyParcelableHolder() throws RemoteException {
849         ExtendableParcelable ep = new ExtendableParcelable();
850         ep.c = 42L;
851         ExtendableParcelable ep2 = new ExtendableParcelable();
852         mInterface.RepeatExtendableParcelableWithoutExtension(ep, ep2);
853         assertEquals(42L, ep2.c);
854     }
855 
856     @Test
testRepeatSimpleUnion()857     public void testRepeatSimpleUnion() throws RemoteException {
858         final int[] intArray = { 1, 2, 3 };
859         SimpleUnion origin = SimpleUnion.b(intArray);
860         SimpleUnion ret = mInterface.RepeatSimpleUnion(origin);
861         assertEquals(SimpleUnion.b, ret.getTag());
862         Assert.assertArrayEquals(intArray, ret.getB());
863     }
864 }
865