1 /*
2  * Copyright (C) 2016 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 com.android.commands.hidl_test_java;
18 
19 import android.hardware.tests.baz.V1_0.IBase;
20 import android.hardware.tests.baz.V1_0.IBaz;
21 import android.hardware.tests.baz.V1_0.IQuux;
22 import android.hardware.tests.baz.V1_0.IBaz.NestedStruct;
23 import android.hardware.tests.baz.V1_0.IBazCallback;
24 import android.os.HwBinder;
25 import android.os.RemoteException;
26 import android.os.HidlSupport;
27 import android.util.Log;
28 
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 
32 public final class HidlTestJava {
33     private static final String TAG = "HidlTestJava";
34 
main(String[] args)35     public static void main(String[] args) {
36         int exitCode = 1;
37         try {
38             exitCode = new HidlTestJava().run(args);
39         } catch (Exception e) {
40             e.printStackTrace();
41             Log.e(TAG, "Error ", e);
42         }
43         System.exit(exitCode);
44     }
45 
run(String[] args)46     public int run(String[] args) throws RemoteException {
47         if (args[0].equals("-c")) {
48             client();
49         } else if (args[0].equals("-s")) {
50             server();
51         } else {
52             Log.e(TAG, "Usage: HidlTestJava  -c(lient) | -s(erver)");
53             System.err.printf("Usage: HidlTestJava  -c(lient) | -s(erver)\n");
54             return 1;
55         }
56 
57         return 0;
58     }
59 
60     final class HidlDeathRecipient implements HwBinder.DeathRecipient {
61         final Object mLock = new Object();
62         boolean mCalled = false;
63         long mCookie = 0;
64 
65         @Override
serviceDied(long cookie)66         public void serviceDied(long cookie) {
67             synchronized (mLock) {
68                 mCalled = true;
69                 mCookie = cookie;
70                 mLock.notify();
71             }
72         }
73 
cookieMatches(long cookie)74         public boolean cookieMatches(long cookie) {
75             synchronized (mLock) {
76                 return mCookie == cookie;
77             }
78         }
79 
waitUntilServiceDied(long timeoutMillis)80         public boolean waitUntilServiceDied(long timeoutMillis) {
81             synchronized(mLock) {
82                 while (!mCalled) {
83                     try {
84                         mLock.wait(timeoutMillis);
85                     } catch (InterruptedException e) {
86                         continue; // Spin for another loop
87                     }
88                     break; // got notified or timeout hit
89                 }
90                 return mCalled;
91             }
92         }
93     };
94 
ExpectTrue(boolean x)95     private void ExpectTrue(boolean x) {
96         if (x) {
97             return;
98         }
99 
100         throw new RuntimeException();
101     }
102 
ExpectFalse(boolean x)103     private void ExpectFalse(boolean x) {
104         ExpectTrue(!x);
105     }
106 
Expect(String result, String s)107     private void Expect(String result, String s) {
108         if (result.equals(s)) {
109             return;
110         }
111 
112         System.err.printf("Expected '%s', got '%s'\n", s, result);
113         Log.e(TAG, "Expected '" + s + "', got '" + result + "'");
114         throw new RuntimeException();
115     }
116 
117     class BazCallback extends IBazCallback.Stub {
118         private boolean mCalled;
119 
BazCallback()120         public BazCallback() {
121             mCalled = false;
122         }
123 
wasCalled()124         boolean wasCalled() {
125             return mCalled;
126         }
127 
heyItsMe(IBazCallback cb)128         public void heyItsMe(IBazCallback cb) throws RemoteException {
129             mCalled = true;
130 
131             cb.heyItsMe(null);
132         }
133 
hey()134         public void hey() {
135             mCalled = true;
136         }
137     }
138 
numberToEnglish(int x)139     private String numberToEnglish(int x) {
140         final String[] kDigits = {
141             "zero",
142             "one",
143             "two",
144             "three",
145             "four",
146             "five",
147             "six",
148             "seven",
149             "eight",
150             "nine",
151         };
152 
153         if (x < 0) {
154             return "negative " + numberToEnglish(-x);
155         }
156 
157         if (x < 10) {
158             return kDigits[x];
159         }
160 
161         if (x <= 15) {
162             final String[] kSpecialTens = {
163                 "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
164             };
165 
166             return kSpecialTens[x - 10];
167         }
168 
169         if (x < 20) {
170             return kDigits[x % 10] + "teen";
171         }
172 
173         if (x < 100) {
174             final String[] kDecades = {
175                 "twenty", "thirty", "forty", "fifty", "sixty", "seventy",
176                 "eighty", "ninety",
177             };
178 
179             return kDecades[x / 10 - 2] + kDigits[x % 10];
180         }
181 
182         return "positively huge!";
183     }
184 
ExpectDeepEq(Object l, Object r)185     private void ExpectDeepEq(Object l, Object r) {
186         ExpectTrue(HidlSupport.deepEquals(l, r));
187         ExpectTrue(HidlSupport.deepHashCode(l) == HidlSupport.deepHashCode(r));
188     }
189 
ExpectDeepNe(Object l, Object r)190     private void ExpectDeepNe(Object l, Object r) {
191         ExpectTrue(!HidlSupport.deepEquals(l, r));
192     }
193 
client()194     private void client() throws RemoteException {
195 
196         ExpectDeepEq(null, null);
197         ExpectDeepNe(null, new String());
198         ExpectDeepNe(new String(), null);
199         ExpectDeepEq(new String(), new String());
200         ExpectDeepEq("hey", "hey");
201 
202         ExpectDeepEq(new int[]{1,2}, new int[]{1,2});
203         ExpectDeepNe(new int[]{1,2}, new int[]{1,3});
204         ExpectDeepNe(new int[]{1,2}, new int[]{1,2,3});
205         ExpectDeepEq(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,4}});
206         ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,5}});
207         ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2,3},{4,5,6}});
208         ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,4,5}});
209 
210         ExpectDeepEq(new Integer[]{1,2}, new Integer[]{1,2});
211         ExpectDeepNe(new Integer[]{1,2}, new Integer[]{1,3});
212         ExpectDeepNe(new Integer[]{1,2}, new Integer[]{1,2,3});
213         ExpectDeepEq(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,4}});
214         ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,5}});
215         ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2,3},{4,5,6}});
216         ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,4,5}});
217 
218         ExpectDeepEq(new ArrayList(Arrays.asList(1, 2)),
219                      new ArrayList(Arrays.asList(1, 2)));
220         ExpectDeepNe(new ArrayList(Arrays.asList(1, 2)),
221                      new ArrayList(Arrays.asList(1, 2, 3)));
222 
223         ExpectDeepEq(new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})),
224                      new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})));
225         ExpectDeepNe(new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})),
226                      new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,5})));
227 
228         ExpectDeepEq(new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})),
229                      new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})));
230         ExpectDeepNe(new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})),
231                      new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,5})));
232 
233         ExpectDeepEq(new ArrayList[]{new ArrayList(Arrays.asList(1,2)),
234                                      new ArrayList(Arrays.asList(3,4))},
235                      new ArrayList[]{new ArrayList(Arrays.asList(1,2)),
236                                      new ArrayList(Arrays.asList(3,4))});
237 
238 
239         {
240             // Test access through base interface binder.
241             IBase baseProxy = IBase.getService("baz");
242             baseProxy.someBaseMethod();
243 
244             IBaz bazProxy = IBaz.castFrom(baseProxy);
245             ExpectTrue(bazProxy != null);
246 
247             // IQuux is completely unrelated to IBase/IBaz, so the following
248             // should fail, i.e. return null.
249             IQuux quuxProxy = IQuux.castFrom(baseProxy);
250             ExpectTrue(quuxProxy == null);
251         }
252 
253         IBaz proxy = IBaz.getService("baz");
254         proxy.someBaseMethod();
255 
256         {
257             Expect(proxy.interfaceDescriptor(), IBaz.kInterfaceName);
258         }
259 
260         {
261             IBase.Foo foo = new IBase.Foo();
262             foo.x = 1;
263 
264             for (int i = 0; i < 5; ++i) {
265                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
266                 bar.z = 1.0f + (float)i * 0.01f;
267                 bar.s = "Hello, world " + i;
268                 foo.aaa.add(bar);
269             }
270 
271             foo.y.z = 3.14f;
272             foo.y.s = "Lorem ipsum...";
273 
274             IBase.Foo result = proxy.someOtherBaseMethod(foo);
275             ExpectTrue(result.equals(foo));
276         }
277 
278         {
279             IBase.Foo[] inputArray = new IBase.Foo[2];
280 
281             IBase.Foo foo = new IBase.Foo();
282             foo.x = 1;
283 
284             for (int i = 0; i < 5; ++i) {
285                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
286                 bar.z = 1.0f + (float)i * 0.01f;
287                 bar.s = "Hello, world " + i;
288                 foo.aaa.add(bar);
289             }
290 
291             foo.y.z = 3.14f;
292             foo.y.s = "Lorem ipsum...";
293 
294             inputArray[0] = foo;
295 
296             foo = new IBase.Foo();
297             foo.x = 2;
298 
299             for (int i = 0; i < 3; ++i) {
300                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
301                 bar.z = 2.0f - (float)i * 0.01f;
302                 bar.s = "Lorem ipsum " + i;
303                 foo.aaa.add(bar);
304             }
305 
306             foo.y.z = 1.1414f;
307             foo.y.s = "Et tu brute?";
308 
309             inputArray[1] = foo;
310 
311             IBase.Foo[] expectedOutputArray = new IBase.Foo[2];
312             expectedOutputArray[0] = inputArray[1];
313             expectedOutputArray[1] = inputArray[0];
314 
315             IBase.Foo[] outputArray = proxy.someMethodWithFooArrays(inputArray);
316 
317             ExpectTrue(java.util.Objects.deepEquals(outputArray, expectedOutputArray));
318         }
319 
320         {
321             ArrayList<IBase.Foo> inputVec = new ArrayList<IBase.Foo>();
322 
323             IBase.Foo foo = new IBase.Foo();
324             foo.x = 1;
325 
326             for (int i = 0; i < 5; ++i) {
327                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
328                 bar.z = 1.0f + (float)i * 0.01f;
329                 bar.s = "Hello, world " + i;
330                 foo.aaa.add(bar);
331             }
332 
333             foo.y.z = 3.14f;
334             foo.y.s = "Lorem ipsum...";
335 
336             inputVec.add(foo);
337 
338             foo = new IBase.Foo();
339             foo.x = 2;
340 
341             for (int i = 0; i < 3; ++i) {
342                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
343                 bar.z = 2.0f - (float)i * 0.01f;
344                 bar.s = "Lorem ipsum " + i;
345                 foo.aaa.add(bar);
346             }
347 
348             foo.y.z = 1.1414f;
349             foo.y.s = "Et tu brute?";
350 
351             inputVec.add(foo);
352 
353             ArrayList<IBase.Foo> expectedOutputVec = new ArrayList<IBase.Foo>();
354             expectedOutputVec.add(inputVec.get(1));
355             expectedOutputVec.add(inputVec.get(0));
356 
357             ArrayList<IBase.Foo> outputVec =
358                 proxy.someMethodWithFooVectors(inputVec);
359 
360             ExpectTrue(java.util.Objects.deepEquals(outputVec, expectedOutputVec));
361         }
362 
363         {
364             IBase.VectorOfArray in = new IBase.VectorOfArray();
365 
366             int k = 0;
367             for (int i = 0; i < 3; ++i) {
368                 byte[] mac = new byte[6];
369                 for (int j = 0; j < 6; ++j, ++k) {
370                     mac[j] = (byte)k;
371                 }
372 
373                 in.addresses.add(mac);
374             }
375 
376             IBase.VectorOfArray expectedOut = new IBase.VectorOfArray();
377             int n = in.addresses.size();
378 
379             for (int i = 0; i < n; ++i) {
380                 expectedOut.addresses.add(in.addresses.get(n - 1 - i));
381             }
382 
383             IBase.VectorOfArray out = proxy.someMethodWithVectorOfArray(in);
384             ExpectTrue(out.equals(expectedOut));
385         }
386 
387         {
388             ArrayList<byte[]> in = new ArrayList<byte[]>();
389 
390             int k = 0;
391             for (int i = 0; i < 3; ++i) {
392                 byte[] mac = new byte[6];
393                 for (int j = 0; j < 6; ++j, ++k) {
394                     mac[j] = (byte)k;
395                 }
396 
397                 in.add(mac);
398             }
399 
400             ArrayList<byte[]> expectedOut = new ArrayList<byte[]>();
401 
402             int n = in.size();
403             for (int i = 0; i < n; ++i) {
404                 expectedOut.add(in.get(n - 1 - i));
405             }
406 
407             ArrayList<byte[]> out = proxy.someMethodTakingAVectorOfArray(in);
408 
409             ExpectTrue(out.size() == expectedOut.size());
410             for  (int i = 0; i < n; ++i) {
411                 ExpectTrue(java.util.Objects.deepEquals(out.get(i), expectedOut.get(i)));
412             }
413         }
414 
415         {
416             IBase.StringMatrix5x3 in = new IBase.StringMatrix5x3();
417             IBase.StringMatrix3x5 expectedOut = new IBase.StringMatrix3x5();
418 
419             for (int i = 0; i < 5; ++i) {
420                 for (int j = 0; j < 3; ++j) {
421                     in.s[i][j] = numberToEnglish(3 * i + j + 1);
422                     expectedOut.s[j][i] = in.s[i][j];
423                 }
424             }
425 
426             IBase.StringMatrix3x5 out = proxy.transpose(in);
427 
428             // [[1 2 3] [4 5 6] [7 8 9] [10 11 12] [13 14 15]]^T
429             // = [[1 4 7 10 13] [2 5 8 11 14] [3 6 9 12 15]]
430             ExpectTrue(out.equals(expectedOut));
431         }
432 
433         {
434             String[][] in = new String[5][3];
435             String[][] expectedOut = new String[3][5];
436             for (int i = 0; i < 5; ++i) {
437                 for (int j = 0; j < 3; ++j) {
438                     in[i][j] = numberToEnglish(3 * i + j + 1);
439                     expectedOut[j][i] = in[i][j];
440                 }
441             }
442 
443             String[][] out = proxy.transpose2(in);
444 
445             // [[1 2 3] [4 5 6] [7 8 9] [10 11 12] [13 14 15]]^T
446             // = [[1 4 7 10 13] [2 5 8 11 14] [3 6 9 12 15]]
447             ExpectTrue(java.util.Arrays.deepEquals(out, expectedOut));
448         }
449 
450         ExpectTrue(proxy.someBoolMethod(true) == false);
451 
452         {
453             boolean[] someBoolArray = new boolean[3];
454             someBoolArray[0] = true;
455             someBoolArray[1] = false;
456             someBoolArray[2] = true;
457 
458             boolean[] resultArray = proxy.someBoolArrayMethod(someBoolArray);
459             ExpectTrue(resultArray[0] == false);
460             ExpectTrue(resultArray[1] == true);
461             ExpectTrue(resultArray[2] == false);
462 
463             ArrayList<Boolean> someBoolVec = new ArrayList<Boolean>();
464             someBoolVec.add(true);
465             someBoolVec.add(false);
466             someBoolVec.add(true);
467 
468             ArrayList<Boolean> resultVec = proxy.someBoolVectorMethod(someBoolVec);
469             ExpectTrue(resultVec.get(0) == false);
470             ExpectTrue(resultVec.get(1) == true);
471             ExpectTrue(resultVec.get(2) == false);
472         }
473 
474         proxy.doThis(1.0f);
475 
476         ExpectTrue(proxy.doThatAndReturnSomething(1) == 666);
477         ExpectTrue(proxy.doQuiteABit(1, 2L, 3.0f, 4.0) == 666.5);
478 
479         {
480             int[] paramArray = new int[15];
481             int[] expectedOutArray = new int[32];
482             ArrayList<Integer> paramVec = new ArrayList<Integer>();
483             ArrayList<Integer> expectedOutVec = new ArrayList<Integer>();
484 
485             for (int i = 0; i < paramArray.length; ++i) {
486                 paramArray[i] = i;
487                 paramVec.add(i);
488 
489                 expectedOutArray[i] = 2 * i;
490                 expectedOutArray[15 + i] = i;
491 
492                 expectedOutVec.add(2 * i);
493             }
494 
495             expectedOutArray[30] = 1;
496             expectedOutArray[31] = 2;
497 
498 
499             int[] outArray = proxy.doSomethingElse(paramArray);
500             ExpectTrue(java.util.Objects.deepEquals(outArray, expectedOutArray));
501 
502             ArrayList<Integer> outVec = proxy.mapThisVector(paramVec);
503             java.util.Objects.equals(outVec, expectedOutVec);
504 
505         }
506 
507         Expect(proxy.doStuffAndReturnAString(), "Hello, world!");
508 
509         BazCallback cb = new BazCallback();
510         ExpectTrue(!cb.wasCalled());
511         proxy.callMe(cb);
512         ExpectTrue(cb.wasCalled());
513 
514         ExpectTrue(proxy.useAnEnum(IBaz.SomeEnum.goober) == -64);
515 
516         {
517             String[] stringArray = new String[3];
518             stringArray[0] = "one";
519             stringArray[1] = "two";
520             stringArray[2] = "three";
521 
522             String[] expectedOutArray = new String[2];
523             expectedOutArray[0] = "Hello";
524             expectedOutArray[1] = "World";
525 
526             String[] outArray = proxy.haveSomeStrings(stringArray);
527             ExpectTrue(java.util.Arrays.deepEquals(outArray, expectedOutArray));
528 
529             ArrayList<String> stringVec = new ArrayList<String>();
530             stringVec.add("one");
531             stringVec.add("two");
532             stringVec.add("three");
533 
534             ArrayList<String> expectedOutVec = new ArrayList<String>();
535             expectedOutVec.add("Hello");
536             expectedOutVec.add("World");
537 
538             ExpectTrue(expectedOutVec.equals(proxy.haveAStringVec(stringVec)));
539         }
540 
541         proxy.returnABunchOfStrings(
542                 new IBaz.returnABunchOfStringsCallback() {
543                     @Override
544                     public void onValues(String a, String b, String c) {
545                         Expect(a, "Eins");
546                         Expect(b, "Zwei");
547                         Expect(c, "Drei");
548                     }
549                 });
550 
551         proxy.returnABunchOfStrings((a,b,c) -> Expect(a + b + c, "EinsZweiDrei"));
552 
553         proxy.callMeLater(new BazCallback());
554         System.gc();
555         proxy.iAmFreeNow();
556 
557         {
558             IBaz.T t1 = new IBaz.T();
559             IBaz.T t2 = new IBaz.T();
560             for (int i = 0; i < 5; i++) {
561                 for (int j = 0; j < 3; j++) {
562                     t1.matrix5x3[i][j] = t2.matrix5x3[i][j] = (i + 1) * (j + 1);
563                 }
564             }
565             ExpectTrue(t1.equals(t2));
566             ExpectTrue(t1.hashCode() == t2.hashCode());
567             t2.matrix5x3[4][2] = -60;
568             ExpectTrue(!t1.equals(t2));
569         }
570 
571         ArrayList<NestedStruct> structs = proxy.getNestedStructs();
572         ExpectTrue(structs.size() == 5);
573         ExpectTrue(structs.get(1).matrices.size() == 6);
574 
575         {
576             IBaz.Everything e = new IBaz.Everything();
577             Expect(e.toString(),
578                 "{.number = 0, .anotherNumber = 0, .s = , " +
579                 ".vs = [], .multidimArray = [[null, null], [null, null]], " +
580                 ".sArray = [null, null, null], .anotherStruct = {.first = , .last = }, .bf = }");
581             e.s = "string!";
582             e.number = 127;
583             e.anotherNumber = 100;
584             e.vs.addAll(Arrays.asList("One", "Two", "Three"));
585             for (int i = 0; i < e.multidimArray.length; i++)
586                 for (int j = 0; j < e.multidimArray[i].length; j++)
587                     e.multidimArray[i][j] = Integer.toString(i) + Integer.toString(j);
588             e.bf = IBaz.BitField.VALL;
589             e.anotherStruct.first = "James";
590             e.anotherStruct.last = "Bond";
591             Expect(e.toString(),
592                 "{.number = 127, .anotherNumber = 100, .s = string!, " +
593                 ".vs = [One, Two, Three], .multidimArray = [[00, 01], [10, 11]], " +
594                 ".sArray = [null, null, null], .anotherStruct = {.first = James, .last = Bond}, " +
595                 ".bf = V0 | V1 | V2 | V3 | VALL}");
596             Expect(IBaz.BitField.toString(IBaz.BitField.VALL), "VALL");
597             Expect(IBaz.BitField.toString((byte)(IBaz.BitField.V0 | IBaz.BitField.V2)), "0x5");
598             Expect(IBaz.BitField.dumpBitfield(IBaz.BitField.VALL), "V0 | V1 | V2 | V3 | VALL");
599             Expect(IBaz.BitField.dumpBitfield((byte)(IBaz.BitField.V1 | IBaz.BitField.V3 | 0xF0)),
600                 "V1 | V3 | 0xf0");
601 
602             Expect(proxy.toString(), IBaz.kInterfaceName + "@Proxy");
603         }
604 
605         {
606             // Ensure that native parcel is cleared even if the corresponding
607             // Java object isn't GC'd.
608             ArrayList<Integer> data4K = new ArrayList<>(1024);
609             for (int i = 0; i < 1024; i++) {
610                 data4K.add(i);
611             }
612 
613             for (int i = 0; i < 1024; i++) {
614                 // If they are not properly cleaned up, these calls will put 4MB of data in
615                 // kernel binder buffer, and will fail.
616                 try {
617                     proxy.mapThisVector(data4K);
618                 } catch (RemoteException ex) {
619                     throw new RuntimeException("Failed at call #" + Integer.toString(i), ex);
620                 }
621             }
622         }
623 
624         // --- DEATH RECIPIENT TESTING ---
625         // This must always be done last, since it will kill the native server process
626         HidlDeathRecipient recipient1 = new HidlDeathRecipient();
627         HidlDeathRecipient recipient2 = new HidlDeathRecipient();
628 
629         final int cookie1 = 0x1481;
630         final int cookie2 = 0x1482;
631         ExpectTrue(proxy.linkToDeath(recipient1, cookie1));
632         ExpectTrue(proxy.linkToDeath(recipient2, cookie2));
633         ExpectTrue(proxy.unlinkToDeath(recipient2));
634         try {
635             proxy.dieNow();
636         } catch (RemoteException e) {
637             // Expected
638         }
639         ExpectTrue(recipient1.waitUntilServiceDied(2000 /*timeoutMillis*/));
640         ExpectTrue(!recipient2.waitUntilServiceDied(2000 /*timeoutMillis*/));
641         ExpectTrue(recipient1.cookieMatches(cookie1));
642         Log.d(TAG, "OK, exiting");
643 
644     }
645 
646     class Baz extends IBaz.Stub {
647         // from IBase
someBaseMethod()648         public void someBaseMethod() {
649             Log.d(TAG, "Baz someBaseMethod");
650         }
651 
someOtherBaseMethod(IBase.Foo foo)652         public IBase.Foo someOtherBaseMethod(IBase.Foo foo) {
653             Log.d(TAG, "Baz someOtherBaseMethod " + foo.toString());
654             return foo;
655         }
656 
someMethodWithFooArrays(IBase.Foo[] fooInput)657         public IBase.Foo[] someMethodWithFooArrays(IBase.Foo[] fooInput) {
658             Log.d(TAG, "Baz someMethodWithFooArrays " + fooInput.toString());
659 
660             IBase.Foo[] fooOutput = new IBase.Foo[2];
661             fooOutput[0] = fooInput[1];
662             fooOutput[1] = fooInput[0];
663 
664             return fooOutput;
665         }
666 
someMethodWithFooVectors( ArrayList<IBase.Foo> fooInput)667         public ArrayList<IBase.Foo> someMethodWithFooVectors(
668                 ArrayList<IBase.Foo> fooInput) {
669             Log.d(TAG, "Baz someMethodWithFooVectors " + fooInput.toString());
670 
671             ArrayList<IBase.Foo> fooOutput = new ArrayList<IBase.Foo>();
672             fooOutput.add(fooInput.get(1));
673             fooOutput.add(fooInput.get(0));
674 
675             return fooOutput;
676         }
677 
someMethodWithVectorOfArray( IBase.VectorOfArray in)678         public IBase.VectorOfArray someMethodWithVectorOfArray(
679                 IBase.VectorOfArray in) {
680             Log.d(TAG, "Baz someMethodWithVectorOfArray " + in.toString());
681 
682             IBase.VectorOfArray out = new IBase.VectorOfArray();
683             int n = in.addresses.size();
684             for (int i = 0; i < n; ++i) {
685                 out.addresses.add(in.addresses.get(n - i - 1));
686             }
687 
688             return out;
689         }
690 
someMethodTakingAVectorOfArray( ArrayList<byte[ ]> in)691         public ArrayList<byte[/* 6 */]> someMethodTakingAVectorOfArray(
692                 ArrayList<byte[/* 6 */]> in) {
693             Log.d(TAG, "Baz someMethodTakingAVectorOfArray");
694 
695             int n = in.size();
696             ArrayList<byte[]> out = new ArrayList<byte[]>();
697             for (int i = 0; i < n; ++i) {
698                 out.add(in.get(n - i - 1));
699             }
700 
701             return out;
702         }
703 
transpose(IBase.StringMatrix5x3 in)704         public IBase.StringMatrix3x5 transpose(IBase.StringMatrix5x3 in) {
705             Log.d(TAG, "Baz transpose " + in.toString());
706 
707             IBase.StringMatrix3x5 out = new IBase.StringMatrix3x5();
708             for (int i = 0; i < 3; ++i) {
709                 for (int j = 0; j < 5; ++j) {
710                     out.s[i][j] = in.s[j][i];
711                 }
712             }
713 
714             return out;
715         }
716 
transpose2(String[][] in)717         public String[][] transpose2(String[][] in) {
718             Log.d(TAG, "Baz transpose2 " + in.toString());
719 
720             String[][] out = new String[3][5];
721             for (int i = 0; i < 3; ++i) {
722                 for (int j = 0; j < 5; ++j) {
723                     out[i][j] = in[j][i];
724                 }
725             }
726 
727             return out;
728         }
729 
someBoolMethod(boolean x)730         public boolean someBoolMethod(boolean x) {
731             Log.d(TAG, "Baz someBoolMethod(" + x + ")");
732 
733             return !x;
734         }
735 
someBoolArrayMethod(boolean[] x)736         public boolean[] someBoolArrayMethod(boolean[] x) {
737             Log.d(TAG, "Baz someBoolArrayMethod("
738                     + x.toString() + ")");
739 
740             boolean[] out = new boolean[4];
741             out[0] = !x[0];
742             out[1] = !x[1];
743             out[2] = !x[2];
744             out[3] = true;
745 
746             return out;
747         }
748 
someBoolVectorMethod(ArrayList<Boolean> x)749         public ArrayList<Boolean> someBoolVectorMethod(ArrayList<Boolean> x) {
750             Log.d(TAG, "Baz someBoolVectorMethod(" + x.toString() + ")");
751 
752             ArrayList<Boolean> out = new ArrayList<Boolean>();
753             for (int i = 0; i < x.size(); ++i) {
754                 out.add(!x.get(i));
755             }
756 
757             return out;
758         }
759 
doThis(float param)760         public void doThis(float param) {
761             Log.d(TAG, "Baz doThis " + param);
762         }
763 
doThatAndReturnSomething(long param)764         public int doThatAndReturnSomething(long param) {
765             Log.d(TAG, "Baz doThatAndReturnSomething " + param);
766             return 666;
767         }
768 
doQuiteABit(int a, long b, float c, double d)769         public double doQuiteABit(int a, long b, float c, double d) {
770             Log.d(TAG, "Baz doQuiteABit " + a + ", " + b + ", " + c + ", " + d);
771             return 666.5;
772         }
773 
doSomethingElse(int[] param)774         public int[] doSomethingElse(int[] param) {
775             Log.d(TAG, "Baz doSomethingElse " + param.toString());
776 
777             int[] something = new int[32];
778             for (int i = 0; i < 15; ++i) {
779                 something[i] = 2 * param[i];
780                 something[15 + i] = param[i];
781             }
782             something[30] = 1;
783             something[31] = 2;
784 
785             return something;
786         }
787 
doStuffAndReturnAString()788         public String doStuffAndReturnAString() {
789             Log.d(TAG, "doStuffAndReturnAString");
790             return "Hello, world!";
791         }
792 
mapThisVector(ArrayList<Integer> param)793         public ArrayList<Integer> mapThisVector(ArrayList<Integer> param) {
794             Log.d(TAG, "mapThisVector " + param.toString());
795 
796             ArrayList<Integer> out = new ArrayList<Integer>();
797 
798             for (int i = 0; i < param.size(); ++i) {
799                 out.add(2 * param.get(i));
800             }
801 
802             return out;
803         }
804 
takeAMask(byte bf, byte first, IBase.MyMask second, byte third, takeAMaskCallback cb)805         public void takeAMask(byte bf, byte first, IBase.MyMask second, byte third,
806                 takeAMaskCallback cb) {
807             cb.onValues(bf, (byte)(bf | first),
808                     (byte)(second.value & bf), (byte)((bf | bf) & third));
809         }
810 
returnABitField()811         public byte returnABitField() {
812             return 0;
813         }
814 
size(int size)815         public int size(int size) {
816             return size;
817         }
818 
819         @Override
getNestedStructs()820         public ArrayList<NestedStruct> getNestedStructs() throws RemoteException {
821             return new ArrayList<>();
822         }
823 
824         class BazCallback extends IBazCallback.Stub {
heyItsMe(IBazCallback cb)825             public void heyItsMe(IBazCallback cb) {
826                 Log.d(TAG, "SERVER: heyItsMe");
827             }
828 
hey()829             public void hey() {
830                 Log.d(TAG, "SERVER: hey");
831             }
832         }
833 
callMe(IBazCallback cb)834         public void callMe(IBazCallback cb) throws RemoteException {
835             Log.d(TAG, "callMe");
836             cb.heyItsMe(new BazCallback());
837         }
838 
839         private IBazCallback mStoredCallback;
callMeLater(IBazCallback cb)840         public void callMeLater(IBazCallback cb) {
841             mStoredCallback = cb;
842         }
843 
iAmFreeNow()844         public void iAmFreeNow() throws RemoteException {
845             if (mStoredCallback != null) {
846                 mStoredCallback.hey();
847             }
848         }
849 
dieNow()850         public void dieNow() {
851             // Not tested in Java
852         }
853 
useAnEnum(byte zzz)854         public byte useAnEnum(byte zzz) {
855             Log.d(TAG, "useAnEnum " + zzz);
856             return SomeEnum.quux;
857         }
858 
haveSomeStrings(String[] array)859         public String[] haveSomeStrings(String[] array) {
860             Log.d(TAG, "haveSomeStrings ["
861                         + "\"" + array[0] + "\", "
862                         + "\"" + array[1] + "\", "
863                         + "\"" + array[2] + "\"]");
864 
865             String[] result = new String[2];
866             result[0] = "Hello";
867             result[1] = "World";
868 
869             return result;
870         }
871 
haveAStringVec(ArrayList<String> vector)872         public ArrayList<String> haveAStringVec(ArrayList<String> vector) {
873             Log.d(TAG, "haveAStringVec ["
874                         + "\"" + vector.get(0) + "\", "
875                         + "\"" + vector.get(1) + "\", "
876                         + "\"" + vector.get(2) + "\"]");
877 
878             ArrayList<String> result = new ArrayList<String>();
879             result.add("Hello");
880             result.add("World");
881 
882             return result;
883         }
884 
returnABunchOfStrings(returnABunchOfStringsCallback cb)885         public void returnABunchOfStrings(returnABunchOfStringsCallback cb) {
886             cb.onValues("Eins", "Zwei", "Drei");
887         }
888     }
889 
server()890     private void server() throws RemoteException {
891         Baz baz = new Baz();
892         baz.registerAsService("baz");
893 
894         try {
895             Thread.sleep(20000);
896         } catch (InterruptedException e) {
897         }
898     }
899 }
900