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.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotEquals;
22 import static org.junit.Assert.assertTrue;
23 
24 import android.os.IBinder;
25 import android.os.ParcelFileDescriptor;
26 import android.os.Process;
27 import android.os.RemoteException;
28 import android.util.Log;
29 
30 import androidx.test.InstrumentationRegistry;
31 
32 import org.junit.Assert;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.junit.runners.Parameterized;
37 
38 import test_package.Bar;
39 import test_package.ByteEnum;
40 import test_package.Foo;
41 import test_package.IEmpty;
42 import test_package.ITest;
43 import test_package.IntEnum;
44 import test_package.LongEnum;
45 import test_package.RegularPolygon;
46 
47 import java.io.FileInputStream;
48 import java.io.FileOutputStream;
49 import java.io.IOException;
50 import java.util.Arrays;
51 import java.util.Collection;
52 import java.util.List;
53 import java.util.ArrayList;
54 import java.util.function.BiPredicate;
55 
56 @RunWith(Parameterized.class)
57 public class JavaClientTest {
58     private final String TAG = "JavaClientTest";
59 
60     private Class mServiceClass;
61     private ITest mInterface;
62     private String mExpectedName;
63     private boolean mShouldBeRemote;
64     private boolean mShouldBeOld;
65 
JavaClientTest(Class serviceClass, String expectedName, boolean shouldBeRemote, boolean shouldBeOld)66     public JavaClientTest(Class serviceClass, String expectedName, boolean shouldBeRemote, boolean shouldBeOld) {
67         mServiceClass = serviceClass;
68         mExpectedName = expectedName;
69         mShouldBeRemote = shouldBeRemote;
70         mShouldBeOld = shouldBeOld;
71     }
72 
73     @Parameterized.Parameters( name = "{0}" )
data()74     public static Collection<Object[]> data() {
75         // For local interfaces, this test will parcel the data locally.
76         // Whenever possible, the desired service should be accessed directly
77         // in order to avoid this additional overhead.
78         return Arrays.asList(new Object[][] {
79                 {NativeService.Local.class, "CPP", false /*shouldBeRemote*/, false /*shouldBeOld*/},
80                 {JavaService.Local.class, "JAVA", false /*shouldBeRemote*/, false /*shouldBeOld*/},
81                 {NativeService.Remote.class, "CPP", true /*shouldBeRemote*/, false /*shouldBeOld*/},
82                 {NativeService.RemoteOld.class, "CPP", true /*shouldBeRemote*/, true /*shouldBeOld*/},
83                 {JavaService.Remote.class, "JAVA", true /*shouldBeRemote*/, false /*shouldBeOld*/},
84             });
85     }
86 
87     @Before
setUp()88     public void setUp() {
89         Log.e(TAG, "Setting up");
90 
91         SyncTestServiceConnection connection = new SyncTestServiceConnection(
92             InstrumentationRegistry.getTargetContext(), mServiceClass);
93 
94         mInterface = connection.get();
95         assertNotEquals(null, mInterface);
96     }
97 
98     @Test
testSanityCheckSource()99     public void testSanityCheckSource() throws RemoteException {
100         String name = mInterface.GetName();
101 
102         Log.i(TAG, "Service GetName: " + name);
103         assertEquals(mExpectedName, name);
104     }
105 
106     @Test
testTrivial()107     public void testTrivial() throws RemoteException {
108         mInterface.TestVoidReturn();
109         mInterface.TestOneway();
110     }
111 
checkDump(String expected, String[] args)112     private void checkDump(String expected, String[] args) throws RemoteException, IOException {
113         ParcelFileDescriptor[] sockets = ParcelFileDescriptor.createReliableSocketPair();
114         ParcelFileDescriptor socketIn = sockets[0];
115         ParcelFileDescriptor socketOut = sockets[1];
116 
117         mInterface.asBinder().dump(socketIn.getFileDescriptor(), args);
118         socketIn.close();
119 
120         FileInputStream fileInputStream = new ParcelFileDescriptor.AutoCloseInputStream(socketOut);
121 
122         byte[] expectedBytes = expected.getBytes();
123         byte[] input = new byte[expectedBytes.length];
124 
125         assertEquals(input.length, fileInputStream.read(input));
126         Assert.assertArrayEquals(input, expectedBytes);
127     }
128 
129     @Test
testDump()130     public void testDump() throws RemoteException, IOException {
131         checkDump("", new String[]{});
132         checkDump("", new String[]{"", ""});
133         checkDump("Hello World!", new String[]{"Hello ", "World!"});
134         checkDump("ABC", new String[]{"A", "B", "C"});
135     }
136 
137     @Test
testCallingInfo()138     public void testCallingInfo() throws RemoteException {
139       mInterface.CacheCallingInfoFromOneway();
140 
141       assertEquals(Process.myPid(), mInterface.GiveMeMyCallingPid());
142       assertEquals(Process.myUid(), mInterface.GiveMeMyCallingUid());
143 
144       if (mShouldBeRemote) {
145         // PID is hidden from oneway calls
146         assertEquals(0, mInterface.GiveMeMyCallingPidFromOneway());
147       } else {
148         assertEquals(Process.myPid(), mInterface.GiveMeMyCallingPidFromOneway());
149       }
150 
151       assertEquals(Process.myUid(), mInterface.GiveMeMyCallingUidFromOneway());
152     }
153 
154     @Test
testRepeatPrimitives()155     public void testRepeatPrimitives() throws RemoteException {
156         assertEquals(1, mInterface.RepeatInt(1));
157         assertEquals(2, mInterface.RepeatLong(2));
158         assertEquals(1.0f, mInterface.RepeatFloat(1.0f), 0.0f);
159         assertEquals(2.0, mInterface.RepeatDouble(2.0), 0.0);
160         assertEquals(true, mInterface.RepeatBoolean(true));
161         assertEquals('a', mInterface.RepeatChar('a'));
162         assertEquals((byte)3, mInterface.RepeatByte((byte)3));
163         assertEquals(ByteEnum.FOO, mInterface.RepeatByteEnum(ByteEnum.FOO));
164         assertEquals(IntEnum.FOO, mInterface.RepeatIntEnum(IntEnum.FOO));
165         assertEquals(LongEnum.FOO, mInterface.RepeatLongEnum(LongEnum.FOO));
166     }
167 
168     @Test
testRepeatBinder()169     public void testRepeatBinder() throws RemoteException {
170         IBinder binder = mInterface.asBinder();
171 
172         assertEquals(binder, mInterface.RepeatBinder(binder));
173         assertEquals(binder, mInterface.RepeatNullableBinder(binder));
174         assertEquals(null, mInterface.RepeatNullableBinder(null));
175     }
176 
177     private static class Empty extends IEmpty.Stub {
178         @Override
getInterfaceVersion()179         public int getInterfaceVersion() { return Empty.VERSION; }
180 
181         @Override
getInterfaceHash()182         public String getInterfaceHash() { return Empty.HASH; }
183     }
184 
185     @Test
testRepeatInterface()186     public void testRepeatInterface() throws RemoteException {
187         IEmpty empty = new Empty();
188 
189         assertEquals(empty, mInterface.RepeatInterface(empty));
190         assertEquals(empty, mInterface.RepeatNullableInterface(empty));
191         assertEquals(null, mInterface.RepeatNullableInterface(null));
192     }
193 
194     private static interface IRepeatFd {
repeat(ParcelFileDescriptor fd)195         ParcelFileDescriptor repeat(ParcelFileDescriptor fd) throws RemoteException;
196     }
197 
checkFdRepeated(IRepeatFd transformer)198     private void checkFdRepeated(IRepeatFd transformer) throws RemoteException, IOException {
199         ParcelFileDescriptor[] sockets = ParcelFileDescriptor.createReliableSocketPair();
200         ParcelFileDescriptor socketIn = sockets[0];
201         ParcelFileDescriptor socketOut = sockets[1];
202 
203         ParcelFileDescriptor repeatFd = transformer.repeat(socketIn);
204 
205         boolean isNativeRemote = mInterface.GetName().equals("CPP");
206         try {
207             socketOut.checkError();
208 
209             // Either native didn't properly call detach, or native properly handles detach, and
210             // we should change the test to enforce that socket comms work.
211             assertFalse("Native doesn't implement comm fd but did not get detach.", isNativeRemote);
212         } catch (ParcelFileDescriptor.FileDescriptorDetachedException e) {
213             assertTrue("Detach, so remote should be native", isNativeRemote);
214         }
215 
216         // Both backends support these.
217         socketIn.checkError();
218         repeatFd.checkError();
219 
220         checkInOutSockets(repeatFd, socketOut);
221     }
222 
223     @Test
testRepeatFd()224     public void testRepeatFd() throws RemoteException, IOException {
225         checkFdRepeated((fd) -> mInterface.RepeatFd(fd));
226     }
227 
228     @Test
testRepeatNullableFd()229     public void testRepeatNullableFd() throws RemoteException, IOException {
230         checkFdRepeated((fd) -> mInterface.RepeatNullableFd(fd));
231         assertEquals(null, mInterface.RepeatNullableFd(null));
232     }
233 
checkInOutSockets(ParcelFileDescriptor in, ParcelFileDescriptor out)234     private void checkInOutSockets(ParcelFileDescriptor in, ParcelFileDescriptor out) throws IOException {
235         FileOutputStream repeatFdStream = new ParcelFileDescriptor.AutoCloseOutputStream(in);
236         String testData = "asdf";
237         byte[] output = testData.getBytes();
238         repeatFdStream.write(output);
239         repeatFdStream.close();
240 
241         FileInputStream fileInputStream = new ParcelFileDescriptor.AutoCloseInputStream(out);
242         byte[] input = new byte[output.length];
243 
244         assertEquals(input.length, fileInputStream.read(input));
245         Assert.assertArrayEquals(input, output);
246     }
247 
248     @Test
testRepeatFdArray()249     public void testRepeatFdArray() throws RemoteException, IOException {
250         ParcelFileDescriptor[] sockets1 = ParcelFileDescriptor.createReliableSocketPair();
251         ParcelFileDescriptor[] sockets2 = ParcelFileDescriptor.createReliableSocketPair();
252         ParcelFileDescriptor[] inputs = {sockets1[0], sockets2[0]};
253         ParcelFileDescriptor[] repeatFdArray = new ParcelFileDescriptor[inputs.length];
254         mInterface.RepeatFdArray(inputs, repeatFdArray);
255 
256         checkInOutSockets(repeatFdArray[0], sockets1[1]);
257         checkInOutSockets(repeatFdArray[1], sockets2[1]);
258     }
259 
260     @Test
testRepeatString()261     public void testRepeatString() throws RemoteException {
262         assertEquals("", mInterface.RepeatString(""));
263         assertEquals("a", mInterface.RepeatString("a"));
264         assertEquals("foo", mInterface.RepeatString("foo"));
265     }
266 
267     @Test
testRepeatNullableString()268     public void testRepeatNullableString() throws RemoteException {
269         assertEquals(null, mInterface.RepeatNullableString(null));
270         assertEquals("", mInterface.RepeatNullableString(""));
271         assertEquals("a", mInterface.RepeatNullableString("a"));
272         assertEquals("foo", mInterface.RepeatNullableString("foo"));
273     }
274 
assertPolygonEquals(RegularPolygon lhs, RegularPolygon rhs)275     public void assertPolygonEquals(RegularPolygon lhs, RegularPolygon rhs) {
276         assertEquals(lhs.name, rhs.name);
277         assertEquals(lhs.numSides, rhs.numSides);
278         assertEquals(lhs.sideLength, rhs.sideLength, 0.0f);
279     }
assertPolygonEquals(RegularPolygon[] lhs, RegularPolygon[] rhs)280     public void assertPolygonEquals(RegularPolygon[] lhs, RegularPolygon[] rhs) {
281         assertEquals(lhs.length, rhs.length);
282         for (int i = 0; i < lhs.length; i++) {
283             assertPolygonEquals(lhs[i], rhs[i]);
284         }
285     }
286 
287     @Test
testRepeatPolygon()288     public void testRepeatPolygon() throws RemoteException {
289         RegularPolygon polygon = new RegularPolygon();
290         polygon.name = "hexagon";
291         polygon.numSides = 6;
292         polygon.sideLength = 1.0f;
293 
294         RegularPolygon result = mInterface.RepeatPolygon(polygon);
295 
296         assertPolygonEquals(polygon, result);
297     }
298 
299     @Test
testRepeatUnexpectedNullPolygon()300     public void testRepeatUnexpectedNullPolygon() throws RemoteException {
301         try {
302            RegularPolygon result = mInterface.RepeatPolygon(null);
303         } catch (NullPointerException e) {
304            // non-@nullable C++ result can't handle null Polygon
305            return;
306         }
307         // Java always works w/ nullptr
308         assertEquals("JAVA", mExpectedName);
309     }
310 
311     @Test
testRepeatNullNullablePolygon()312     public void testRepeatNullNullablePolygon() throws RemoteException {
313         RegularPolygon result = mInterface.RepeatNullablePolygon(null);
314         assertEquals(null, result);
315     }
316 
317     @Test
testRepeatPresentNullablePolygon()318     public void testRepeatPresentNullablePolygon() throws RemoteException {
319         RegularPolygon polygon = new RegularPolygon();
320         polygon.name = "septagon";
321         polygon.numSides = 7;
322         polygon.sideLength = 9.0f;
323 
324         RegularPolygon result = mInterface.RepeatNullablePolygon(polygon);
325 
326         assertPolygonEquals(polygon, result);
327     }
328 
329     @Test
testInsAndOuts()330     public void testInsAndOuts() throws RemoteException {
331         RegularPolygon polygon = new RegularPolygon();
332         mInterface.RenamePolygon(polygon, "Jerry");
333         assertEquals("Jerry", polygon.name);
334     }
335 
336     @Test
testArrays()337     public void testArrays() throws RemoteException {
338         {
339             boolean[] value = {};
340             boolean[] out1 = new boolean[value.length];
341             boolean[] out2 = mInterface.RepeatBooleanArray(value, out1);
342 
343             Assert.assertArrayEquals(value, out1);
344             Assert.assertArrayEquals(value, out2);
345         }
346         {
347             boolean[] value = {false, true, false};
348             boolean[] out1 = new boolean[value.length];
349             boolean[] out2 = mInterface.RepeatBooleanArray(value, out1);
350 
351             Assert.assertArrayEquals(value, out1);
352             Assert.assertArrayEquals(value, out2);
353         }
354         {
355             byte[] value = {1, 2, 3};
356             byte[] out1 = new byte[value.length];
357             byte[] out2 = mInterface.RepeatByteArray(value, out1);
358 
359             Assert.assertArrayEquals(value, out1);
360             Assert.assertArrayEquals(value, out2);
361         }
362         {
363             char[] value = {'h', 'a', '!'};
364             char[] out1 = new char[value.length];
365             char[] out2 = mInterface.RepeatCharArray(value, out1);
366 
367             Assert.assertArrayEquals(value, out1);
368             Assert.assertArrayEquals(value, out2);
369         }
370         {
371             int[] value = {1, 2, 3};
372             int[] out1 = new int[value.length];
373             int[] out2 = mInterface.RepeatIntArray(value, out1);
374 
375             Assert.assertArrayEquals(value, out1);
376             Assert.assertArrayEquals(value, out2);
377         }
378         {
379             long[] value = {1, 2, 3};
380             long[] out1 = new long[value.length];
381             long[] out2 = mInterface.RepeatLongArray(value, out1);
382 
383             Assert.assertArrayEquals(value, out1);
384             Assert.assertArrayEquals(value, out2);
385         }
386         {
387             float[] value = {1.0f, 2.0f, 3.0f};
388             float[] out1 = new float[value.length];
389             float[] out2 = mInterface.RepeatFloatArray(value, out1);
390 
391             Assert.assertArrayEquals(value, out1, 0.0f);
392             Assert.assertArrayEquals(value, out2, 0.0f);
393         }
394         {
395             double[] value = {1.0, 2.0, 3.0};
396             double[] out1 = new double[value.length];
397             double[] out2 = mInterface.RepeatDoubleArray(value, out1);
398 
399             Assert.assertArrayEquals(value, out1, 0.0);
400             Assert.assertArrayEquals(value, out2, 0.0);
401         }
402         {
403             byte[] value = {ByteEnum.FOO, ByteEnum.BAR};
404             byte[] out1 = new byte[value.length];
405             byte[] out2 = mInterface.RepeatByteEnumArray(value, out1);
406 
407             Assert.assertArrayEquals(value, out1);
408             Assert.assertArrayEquals(value, out2);
409         }
410         {
411             int[] value = {IntEnum.FOO, IntEnum.BAR};
412             int[] out1 = new int[value.length];
413             int[] out2 = mInterface.RepeatIntEnumArray(value, out1);
414 
415             Assert.assertArrayEquals(value, out1);
416             Assert.assertArrayEquals(value, out2);
417         }
418         {
419             long[] value = {LongEnum.FOO, LongEnum.BAR};
420             long[] out1 = new long[value.length];
421             long[] out2 = mInterface.RepeatLongEnumArray(value, out1);
422 
423             Assert.assertArrayEquals(value, out1);
424             Assert.assertArrayEquals(value, out2);
425         }
426         {
427             String[] value = {"", "aoeu", "lol", "brb"};
428             String[] out1 = new String[value.length];
429             String[] out2 = mInterface.RepeatStringArray(value, out1);
430 
431             Assert.assertArrayEquals(value, out1);
432             Assert.assertArrayEquals(value, out2);
433         }
434         {
435 
436             RegularPolygon septagon = new RegularPolygon();
437             septagon.name = "septagon";
438             septagon.numSides = 7;
439             septagon.sideLength = 1.0f;
440 
441             RegularPolygon[] value = {septagon, new RegularPolygon(), new RegularPolygon()};
442             RegularPolygon[] out1 = new RegularPolygon[value.length];
443             RegularPolygon[] out2 = mInterface.RepeatRegularPolygonArray(value, out1);
444 
445             assertPolygonEquals(value, out1);
446             assertPolygonEquals(value, out2);
447         }
448     }
449 
450     @Test
testLists()451     public void testLists() throws RemoteException {
452         {
453             List<String> value = Arrays.asList("", "aoeu", "lol", "brb");
454             List<String> out1 = new ArrayList<>();
455             List<String> out2 = mInterface.Repeat2StringList(value, out1);
456 
457             List<String> expected = new ArrayList<>();
458             expected.addAll(value);
459             expected.addAll(value);
460             String[] expectedArray = expected.toArray(new String[0]);
461 
462             Assert.assertArrayEquals(expectedArray, out1.toArray(new String[0]));
463             Assert.assertArrayEquals(expectedArray, out2.toArray(new String[0]));
464         }
465         {
466             RegularPolygon septagon = new RegularPolygon();
467             septagon.name = "septagon";
468             septagon.numSides = 7;
469             septagon.sideLength = 1.0f;
470 
471             List<RegularPolygon> value = Arrays.asList(septagon, new RegularPolygon(), new RegularPolygon());
472             List<RegularPolygon> out1 = new ArrayList<>();
473             List<RegularPolygon> out2 = mInterface.Repeat2RegularPolygonList(value, out1);
474 
475             List<RegularPolygon> expected = new ArrayList<>();
476             expected.addAll(value);
477             expected.addAll(value);
478             RegularPolygon[] expectedArray = expected.toArray(new RegularPolygon[0]);
479 
480             assertPolygonEquals(expectedArray, out1.toArray(new RegularPolygon[0]));
481             assertPolygonEquals(expectedArray, out1.toArray(new RegularPolygon[0]));
482         }
483     }
484 
485     @Test
testNullableArrays()486     public void testNullableArrays() throws RemoteException {
487         {
488             boolean[] emptyValue = {};
489             boolean[] value = {false, true, false};
490             Assert.assertArrayEquals(null, mInterface.RepeatNullableBooleanArray(null));
491             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableBooleanArray(emptyValue));
492             Assert.assertArrayEquals(value, mInterface.RepeatNullableBooleanArray(value));
493         }
494         {
495             byte[] emptyValue = {};
496             byte[] value = {1, 2, 3};
497             Assert.assertArrayEquals(null, mInterface.RepeatNullableByteArray(null));
498             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableByteArray(emptyValue));
499             Assert.assertArrayEquals(value, mInterface.RepeatNullableByteArray(value));
500         }
501         {
502             char[] emptyValue = {};
503             char[] value = {'h', 'a', '!'};
504             Assert.assertArrayEquals(null, mInterface.RepeatNullableCharArray(null));
505             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableCharArray(emptyValue));
506             Assert.assertArrayEquals(value, mInterface.RepeatNullableCharArray(value));
507         }
508         {
509             int[] emptyValue = {};
510             int[] value = {1, 2, 3};
511             Assert.assertArrayEquals(null, mInterface.RepeatNullableIntArray(null));
512             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableIntArray(emptyValue));
513             Assert.assertArrayEquals(value, mInterface.RepeatNullableIntArray(value));
514         }
515         {
516             long[] emptyValue = {};
517             long[] value = {1, 2, 3};
518             Assert.assertArrayEquals(null, mInterface.RepeatNullableLongArray(null));
519             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableLongArray(emptyValue));
520             Assert.assertArrayEquals(value, mInterface.RepeatNullableLongArray(value));
521         }
522         {
523             float[] emptyValue = {};
524             float[] value = {1.0f, 2.0f, 3.0f};
525             Assert.assertArrayEquals(null, mInterface.RepeatNullableFloatArray(null), 0.0f);
526             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableFloatArray(emptyValue), 0.0f);
527             Assert.assertArrayEquals(value, mInterface.RepeatNullableFloatArray(value), 0.0f);
528         }
529         {
530             double[] emptyValue = {};
531             double[] value = {1.0, 2.0, 3.0};
532             Assert.assertArrayEquals(null, mInterface.RepeatNullableDoubleArray(null), 0.0);
533             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableDoubleArray(emptyValue), 0.0);
534             Assert.assertArrayEquals(value, mInterface.RepeatNullableDoubleArray(value), 0.0);
535         }
536         {
537             byte[] emptyValue = {};
538             byte[] value = {ByteEnum.FOO, ByteEnum.BAR};
539             Assert.assertArrayEquals(null, mInterface.RepeatNullableByteEnumArray(null));
540             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableByteEnumArray(emptyValue));
541             Assert.assertArrayEquals(value, mInterface.RepeatNullableByteEnumArray(value));
542         }
543         {
544             int[] emptyValue = {};
545             int[] value = {IntEnum.FOO, IntEnum.BAR};
546             Assert.assertArrayEquals(null, mInterface.RepeatNullableIntEnumArray(null));
547             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableIntEnumArray(emptyValue));
548             Assert.assertArrayEquals(value, mInterface.RepeatNullableIntEnumArray(value));
549         }
550         {
551             long[] emptyValue = {};
552             long[] value = {LongEnum.FOO, LongEnum.BAR};
553             Assert.assertArrayEquals(null, mInterface.RepeatNullableLongEnumArray(null));
554             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableLongEnumArray(emptyValue));
555             Assert.assertArrayEquals(value, mInterface.RepeatNullableLongEnumArray(value));
556         }
557         {
558             String[] emptyValue = {};
559             String[] value = {"", "aoeu", null, "brb"};
560             Assert.assertArrayEquals(null, mInterface.RepeatNullableStringArray(null));
561             Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableStringArray(emptyValue));
562             Assert.assertArrayEquals(value, mInterface.RepeatNullableStringArray(value));
563         }
564         {
565             String[] emptyValue = {};
566             String[] value = {"", "aoeu", null, "brb"};
567             String[] out1 = new String[value.length];
568             String[] out2 = mInterface.DoubleRepeatNullableStringArray(value, out1);
569 
570             Assert.assertArrayEquals(value, out1);
571             Assert.assertArrayEquals(value, out2);
572         }
573     }
574 
575     @Test
testGetLastItem()576     public void testGetLastItem() throws RemoteException {
577         Foo foo = new Foo();
578         foo.d = new Bar();
579         foo.e = new Bar();
580         foo.f = 15;
581         foo.shouldContainTwoByteFoos = new byte[]{};
582         foo.shouldContainTwoIntFoos = new int[]{};
583         foo.shouldContainTwoLongFoos = new long[]{};
584 
585         assertEquals(foo.f, mInterface.getF(foo));
586     }
587 
588     @Test
testRepeatFoo()589     public void testRepeatFoo() throws RemoteException {
590         Foo foo = new Foo();
591 
592         foo.a = "NEW FOO";
593         foo.b = 57;
594 
595         foo.d = new Bar();
596         foo.d.b = "a";
597 
598         foo.e = new Bar();
599         foo.e.d = 99;
600 
601         foo.shouldBeByteBar = ByteEnum.BAR;
602         foo.shouldBeIntBar = IntEnum.BAR;
603         foo.shouldBeLongBar = LongEnum.BAR;
604 
605         foo.shouldContainTwoByteFoos = new byte[]{ByteEnum.FOO, ByteEnum.FOO};
606         foo.shouldContainTwoIntFoos = new int[]{IntEnum.FOO, IntEnum.FOO};
607         foo.shouldContainTwoLongFoos = new long[]{LongEnum.FOO, LongEnum.FOO};
608 
609         Foo repeatedFoo = mInterface.repeatFoo(foo);
610 
611         assertEquals(foo.a, repeatedFoo.a);
612         assertEquals(foo.b, repeatedFoo.b);
613         assertEquals(foo.d.b, repeatedFoo.d.b);
614         assertEquals(foo.e.d, repeatedFoo.e.d);
615         assertEquals(foo.shouldBeByteBar, repeatedFoo.shouldBeByteBar);
616         assertEquals(foo.shouldBeIntBar, repeatedFoo.shouldBeIntBar);
617         assertEquals(foo.shouldBeLongBar, repeatedFoo.shouldBeLongBar);
618         Assert.assertArrayEquals(foo.shouldContainTwoByteFoos, repeatedFoo.shouldContainTwoByteFoos);
619         Assert.assertArrayEquals(foo.shouldContainTwoIntFoos, repeatedFoo.shouldContainTwoIntFoos);
620         Assert.assertArrayEquals(foo.shouldContainTwoLongFoos, repeatedFoo.shouldContainTwoLongFoos);
621     }
622 
623     @Test
testNewField()624     public void testNewField() throws RemoteException {
625         Foo foo = new Foo();
626         foo.d = new Bar();
627         foo.e = new Bar();
628         foo.shouldContainTwoByteFoos = new byte[]{};
629         foo.shouldContainTwoIntFoos = new int[]{};
630         foo.shouldContainTwoLongFoos = new long[]{};
631         foo.g = new String[]{"a", "b", "c"};
632         Foo newFoo = mInterface.repeatFoo(foo);
633         if (mShouldBeOld) {
634             assertEquals(null, newFoo.g);
635         } else {
636             Assert.assertArrayEquals(foo.g, newFoo.g);
637         }
638     }
639     @Test
testRenameFoo()640     public void testRenameFoo() throws RemoteException {
641         Foo foo = new Foo();
642         foo.d = new Bar();
643         foo.e = new Bar();
644         foo.shouldContainTwoByteFoos = new byte[]{};
645         foo.shouldContainTwoIntFoos = new int[]{};
646         foo.shouldContainTwoLongFoos = new long[]{};
647         mInterface.renameFoo(foo, "MYFOO");
648         assertEquals("MYFOO", foo.a);
649     }
650     @Test
testRenameBar()651     public void testRenameBar() throws RemoteException {
652         Foo foo = new Foo();
653         foo.d = new Bar();
654         foo.e = new Bar();
655         foo.shouldContainTwoByteFoos = new byte[]{};
656         foo.shouldContainTwoIntFoos = new int[]{};
657         foo.shouldContainTwoLongFoos = new long[]{};
658         mInterface.renameBar(foo, "MYBAR");
659         assertEquals("MYBAR", foo.d.a);
660     }
661 
662     @Test
testRepeatStringNullableLater()663     public void testRepeatStringNullableLater() throws RemoteException {
664         // see notes in native NdkBinderTest_Aidl RepeatStringNullableLater
665         boolean handlesNull = !mShouldBeOld || mExpectedName == "JAVA";
666         try {
667             assertEquals(null, mInterface.RepeatStringNullableLater(null));
668             assertTrue("should reach here if null is handled", handlesNull);
669         } catch (NullPointerException e) {
670             assertFalse("should reach here if null isn't handled", handlesNull);
671         }
672         assertEquals("", mInterface.RepeatStringNullableLater(""));
673         assertEquals("a", mInterface.RepeatStringNullableLater("a"));
674         assertEquals("foo", mInterface.RepeatStringNullableLater("foo"));
675     }
676 }
677