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