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