• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.system.OsConstants.MAP_SHARED;
20 import static android.system.OsConstants.PROT_READ;
21 import static android.system.OsConstants.PROT_WRITE;
22 
23 import android.hardware.tests.baz.V1_0.IBase;
24 import android.hardware.tests.baz.V1_0.IBaz;
25 import android.hardware.tests.baz.V1_0.IBaz.MyHandle;
26 import android.hardware.tests.baz.V1_0.IBaz.NestedStruct;
27 import android.hardware.tests.baz.V1_0.IBazCallback;
28 import android.hardware.tests.baz.V1_0.IQuux;
29 import android.hardware.tests.memory.V2_0.IMemoryInterface;
30 import android.hardware.tests.memory.V2_0.TwoMemory;
31 import android.hardware.tests.safeunion.V1_0.ISafeUnion;
32 import android.hardware.tests.safeunion.V1_0.ISafeUnion.HandleTypeSafeUnion;
33 import android.hardware.tests.safeunion.V1_0.ISafeUnion.InterfaceTypeSafeUnion;
34 import android.hardware.tests.safeunion.V1_0.ISafeUnion.LargeSafeUnion;
35 import android.hardware.tests.safeunion.V1_0.ISafeUnion.SmallSafeUnion;
36 import android.hidl.manager.V1_0.IServiceManager;
37 import android.os.DeadObjectException;
38 import android.os.HidlMemory;
39 import android.os.HidlMemoryUtil;
40 import android.os.HidlSupport;
41 import android.os.HwBinder;
42 import android.os.HwParcel;
43 import android.os.IBinder;
44 import android.os.IHwBinder;
45 import android.os.NativeHandle;
46 import android.os.RemoteException;
47 import android.os.SharedMemory;
48 import android.system.ErrnoException;
49 import android.system.Os;
50 import android.util.Log;
51 import java.io.File;
52 import java.io.FileDescriptor;
53 import java.io.FileInputStream;
54 import java.io.FileOutputStream;
55 import java.io.IOException;
56 import java.nio.ByteBuffer;
57 import java.nio.DirectByteBuffer;
58 import java.util.ArrayList;
59 import java.util.Arrays;
60 import java.util.NoSuchElementException;
61 import java.util.Objects;
62 
63 public final class HidlTestJava {
64     private static final String TAG = "HidlTestJava";
65 
main(String[] args)66     public static void main(String[] args) {
67         int exitCode = 1;
68         try {
69             exitCode = new HidlTestJava().run(args);
70         } catch (Exception e) {
71             e.printStackTrace();
72             Log.e(TAG, "Error ", e);
73         }
74         System.exit(exitCode);
75     }
76 
run(String[] args)77     public int run(String[] args) throws RemoteException, IOException, ErrnoException {
78         HwBinder.setTrebleTestingOverride(true);
79 
80         if (args[0].equals("-c")) {
81             client();
82         } else if (args[0].equals("-s")) {
83             server();
84         } else {
85             Log.e(TAG, "Usage: HidlTestJava  -c(lient) | -s(erver)");
86             System.err.printf("Usage: HidlTestJava  -c(lient) | -s(erver)\n");
87             return 1;
88         }
89 
90         return 0;
91     }
92 
93     final class HidlDeathRecipient implements HwBinder.DeathRecipient {
94         final Object mLock = new Object();
95         boolean mCalled = false;
96         long mCookie = 0;
97 
98         @Override
serviceDied(long cookie)99         public void serviceDied(long cookie) {
100             synchronized (mLock) {
101                 mCalled = true;
102                 mCookie = cookie;
103                 mLock.notify();
104             }
105         }
106 
cookieMatches(long cookie)107         public boolean cookieMatches(long cookie) {
108             synchronized (mLock) {
109                 return mCookie == cookie;
110             }
111         }
112 
waitUntilServiceDied(long timeoutMillis)113         public boolean waitUntilServiceDied(long timeoutMillis) {
114             synchronized(mLock) {
115                 while (!mCalled) {
116                     try {
117                         mLock.wait(timeoutMillis);
118                     } catch (InterruptedException e) {
119                         continue; // Spin for another loop
120                     }
121                     break; // got notified or timeout hit
122                 }
123                 return mCalled;
124             }
125         }
126     };
127 
ExpectTrue(boolean x)128     private void ExpectTrue(boolean x) {
129         if (x) {
130             return;
131         }
132 
133         throw new RuntimeException();
134     }
135 
ExpectFalse(boolean x)136     private void ExpectFalse(boolean x) {
137         ExpectTrue(!x);
138     }
139 
Expect(String result, String s)140     private void Expect(String result, String s) {
141         if (result.equals(s)) {
142             return;
143         }
144 
145         System.err.printf("Expected '%s', got '%s'\n", s, result);
146         Log.e(TAG, "Expected '" + s + "', got '" + result + "'");
147         throw new RuntimeException();
148     }
149 
150     // .equals and HidlSupport.interfacesEqual should have the same behavior.
ExpectEqual(android.hidl.base.V1_0.IBase l, android.hidl.base.V1_0.IBase r)151     private void ExpectEqual(android.hidl.base.V1_0.IBase l, android.hidl.base.V1_0.IBase r) {
152         ExpectTrue(Objects.equals(l, r));
153         ExpectTrue(Objects.equals(r, l));
154         ExpectTrue(HidlSupport.interfacesEqual(l, r));
155         ExpectTrue(HidlSupport.interfacesEqual(r, l));
156     }
ExpectNotEqual(android.hidl.base.V1_0.IBase l, android.hidl.base.V1_0.IBase r)157     private void ExpectNotEqual(android.hidl.base.V1_0.IBase l, android.hidl.base.V1_0.IBase r) {
158         ExpectFalse(Objects.equals(l, r));
159         ExpectFalse(Objects.equals(r, l));
160         ExpectFalse(HidlSupport.interfacesEqual(l, r));
161         ExpectFalse(HidlSupport.interfacesEqual(r, l));
162     }
163 
164     class BazCallback extends IBazCallback.Stub {
165         private boolean mCalled;
166 
BazCallback()167         public BazCallback() {
168             mCalled = false;
169         }
170 
wasCalled()171         boolean wasCalled() {
172             return mCalled;
173         }
174 
heyItsMe(IBazCallback cb)175         public void heyItsMe(IBazCallback cb) throws RemoteException {
176             mCalled = true;
177 
178             cb.heyItsMe(null);
179         }
180 
hey()181         public void hey() {
182             mCalled = true;
183         }
184 
equals(Object other)185         @Override public boolean equals(Object other) {
186             return other != null && other.getClass() == BazCallback.class &&
187                 ((BazCallback) other).mCalled == mCalled;
188         }
hashCode()189         @Override public int hashCode() { return mCalled ? 1 : 0; }
190     }
191 
numberToEnglish(int x)192     private String numberToEnglish(int x) {
193         final String[] kDigits = {
194             "zero",
195             "one",
196             "two",
197             "three",
198             "four",
199             "five",
200             "six",
201             "seven",
202             "eight",
203             "nine",
204         };
205 
206         if (x < 0) {
207             return "negative " + numberToEnglish(-x);
208         }
209 
210         if (x < 10) {
211             return kDigits[x];
212         }
213 
214         if (x <= 15) {
215             final String[] kSpecialTens = {
216                 "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
217             };
218 
219             return kSpecialTens[x - 10];
220         }
221 
222         if (x < 20) {
223             return kDigits[x % 10] + "teen";
224         }
225 
226         if (x < 100) {
227             final String[] kDecades = {
228                 "twenty", "thirty", "forty", "fifty", "sixty", "seventy",
229                 "eighty", "ninety",
230             };
231 
232             return kDecades[x / 10 - 2] + kDigits[x % 10];
233         }
234 
235         return "positively huge!";
236     }
237 
ExpectDeepEq(Object l, Object r)238     private void ExpectDeepEq(Object l, Object r) {
239         ExpectTrue(HidlSupport.deepEquals(l, r));
240         ExpectTrue(HidlSupport.deepHashCode(l) == HidlSupport.deepHashCode(r));
241     }
242 
ExpectDeepNe(Object l, Object r)243     private void ExpectDeepNe(Object l, Object r) {
244         ExpectTrue(!HidlSupport.deepEquals(l, r));
245     }
246 
runClientMemoryTests()247     private void runClientMemoryTests() throws RemoteException, IOException, ErrnoException {
248         IMemoryInterface memoryInterface = IMemoryInterface.getService();
249 
250         {
251             HidlMemory hidlMem = HidlMemoryUtil.byteArrayToHidlMemory(
252                     new byte[]{0x00, 0x12, 0x34, 0x56});
253             memoryInterface.bitwiseNot(hidlMem);
254             byte[] result = HidlMemoryUtil.hidlMemoryToByteArray(hidlMem);
255 
256             ExpectTrue(Arrays.equals(result,
257                     new byte[]{(byte) 0xFF, (byte) 0xED, (byte) 0xCB, (byte) 0xA9}));
258 
259             hidlMem.close();
260         }
261 
262         {
263             HidlMemory hidlMem = memoryInterface.getTestMem();
264             byte[] data = HidlMemoryUtil.hidlMemoryToByteArray(hidlMem);
265             for (int i = 0; i < 8; ++i) {
266                 ExpectTrue(data[i] == (byte) i);
267             }
268             hidlMem.close();
269         }
270 
271         {
272             TwoMemory in = new TwoMemory();
273             in.mem1 = HidlMemoryUtil.byteArrayToHidlMemory(new byte[]{10, 11, 12, 13});
274             in.mem2 = HidlMemoryUtil.byteArrayToHidlMemory(new byte[]{2, 4, 6, 8});
275             TwoMemory out = memoryInterface.getSumDiff(in);
276             ExpectTrue(Arrays.equals(HidlMemoryUtil.hidlMemoryToByteArray(out.mem1),
277                     new byte[]{12, 15, 18, 21}));
278             ExpectTrue(Arrays.equals(HidlMemoryUtil.hidlMemoryToByteArray(out.mem2),
279                     new byte[]{8, 7, 6, 5}));
280             in.mem1.close();
281             in.mem2.close();
282             out.mem1.close();
283             out.mem2.close();
284         }
285     }
286 
runClientSafeUnionTests()287     private void runClientSafeUnionTests() throws RemoteException, IOException {
288         ISafeUnion safeunionInterface = ISafeUnion.getService();
289 
290         {
291             // SafeUnionNoInitTest
292             LargeSafeUnion safeUnion = safeunionInterface.newLargeSafeUnion();
293             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.noinit);
294         }
295         {
296             // SafeUnionSimpleTest
297             LargeSafeUnion safeUnion = safeunionInterface.newLargeSafeUnion();
298 
299             safeUnion = safeunionInterface.setA(safeUnion, (byte) -5);
300             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.a);
301             ExpectTrue(safeUnion.a() == (byte) -5);
302 
303             safeUnion = safeunionInterface.setD(safeUnion, Long.MAX_VALUE);
304             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.d);
305             ExpectTrue(safeUnion.d() == Long.MAX_VALUE);
306         }
307         {
308             // SafeUnionArrayLikeTypesTest
309             long[] testArray = new long[] {1, -2, 3, -4, 5};
310             ArrayList<Long> testVector = new ArrayList<Long>(Arrays.asList(Long.MAX_VALUE));
311 
312             LargeSafeUnion safeUnion = safeunionInterface.newLargeSafeUnion();
313             safeUnion = safeunionInterface.setF(safeUnion, testArray);
314             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.f);
315             ExpectDeepEq(testArray, safeUnion.f());
316 
317             safeUnion = safeunionInterface.newLargeSafeUnion();
318             safeUnion = safeunionInterface.setI(safeUnion, testVector);
319             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.i);
320             ExpectDeepEq(testVector, safeUnion.i());
321         }
322         {
323             // SafeUnionStringTypeTest
324             String testString = "This is an inordinately long test string.";
325 
326             LargeSafeUnion safeUnion = safeunionInterface.newLargeSafeUnion();
327             safeUnion = safeunionInterface.setG(safeUnion, testString);
328             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.g);
329             ExpectDeepEq(testString, safeUnion.g());
330         }
331         {
332             // SafeUnionNestedTest
333             SmallSafeUnion smallSafeUnion = new SmallSafeUnion();
334             smallSafeUnion.a((byte) 1);
335 
336             LargeSafeUnion safeUnion = safeunionInterface.newLargeSafeUnion();
337             safeUnion = safeunionInterface.setL(safeUnion, smallSafeUnion);
338             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.l);
339             ExpectTrue(safeUnion.l().getDiscriminator() == SmallSafeUnion.hidl_discriminator.a);
340             ExpectTrue(safeUnion.l().a() == (byte) 1);
341         }
342         {
343             // SafeUnionEnumTest
344             LargeSafeUnion safeUnion = safeunionInterface.newLargeSafeUnion();
345             safeUnion = safeunionInterface.setM(safeUnion, ISafeUnion.BitField.V1);
346             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.m);
347             ExpectTrue(safeUnion.m() == ISafeUnion.BitField.V1);
348         }
349         {
350             // SafeUnionBitFieldTest
351             LargeSafeUnion safeUnion = safeunionInterface.newLargeSafeUnion();
352             safeUnion = safeunionInterface.setN(safeUnion, ISafeUnion.BitField.V1);
353             ExpectTrue(safeUnion.getDiscriminator() == LargeSafeUnion.hidl_discriminator.n);
354             ExpectTrue(safeUnion.n() == ISafeUnion.BitField.V1);
355         }
356         {
357             // SafeUnionInterfaceNullNativeHandleTest
358             InterfaceTypeSafeUnion safeUnion = new InterfaceTypeSafeUnion();
359 
360             safeUnion = safeunionInterface.setInterfaceF(safeUnion, null);
361             ExpectTrue(safeUnion.getDiscriminator() == InterfaceTypeSafeUnion.hidl_discriminator.f);
362             ExpectTrue(safeUnion.f() == null);
363         }
364         {
365             // SafeUnionInterfaceTest
366             byte[] testArray = new byte[] {-1, -2, -3, 0, 1, 2, 3};
367             ArrayList<String> testVector = new ArrayList(Arrays.asList("So", "Many", "Words"));
368             String testStringA = "Hello";
369             String testStringB = "World";
370 
371             ArrayList<NativeHandle> testHandlesVector = new ArrayList<>();
372             for (int i = 0; i < 128; i++) {
373                 testHandlesVector.add(new NativeHandle());
374             }
375 
376             InterfaceTypeSafeUnion safeUnion = safeunionInterface.newInterfaceTypeSafeUnion();
377             safeUnion = safeunionInterface.setInterfaceB(safeUnion, testArray);
378             ExpectTrue(safeUnion.getDiscriminator() == InterfaceTypeSafeUnion.hidl_discriminator.b);
379             ExpectDeepEq(testArray, safeUnion.b());
380 
381             IServiceManager anInterface = IServiceManager.getService();
382             safeUnion.c(anInterface);
383             ExpectTrue(safeUnion.getDiscriminator() == InterfaceTypeSafeUnion.hidl_discriminator.c);
384             ExpectTrue(HidlSupport.interfacesEqual(anInterface, safeUnion.c()));
385 
386             safeUnion = safeunionInterface.setInterfaceD(safeUnion, testStringA);
387             ExpectTrue(safeUnion.getDiscriminator() == InterfaceTypeSafeUnion.hidl_discriminator.d);
388             Expect(testStringA, safeUnion.d());
389 
390             safeUnion = safeunionInterface.setInterfaceE(safeUnion, testVector);
391             ExpectTrue(safeUnion.getDiscriminator() == InterfaceTypeSafeUnion.hidl_discriminator.e);
392             ExpectDeepEq(testVector, safeUnion.e());
393 
394             safeUnion = safeunionInterface.setInterfaceG(safeUnion, testHandlesVector);
395             ExpectTrue(safeUnion.getDiscriminator() == InterfaceTypeSafeUnion.hidl_discriminator.g);
396             ExpectTrue(safeUnion.g().size() == testHandlesVector.size());
397 
398             for (int i = 0; i < testHandlesVector.size(); i++) {
399                 ExpectFalse(safeUnion.g().get(i).hasSingleFileDescriptor());
400             }
401         }
402         {
403             // SafeUnionNullNativeHandleTest
404             HandleTypeSafeUnion safeUnion = new HandleTypeSafeUnion();
405 
406             safeUnion = safeunionInterface.setHandleA(safeUnion, null);
407             ExpectTrue(safeUnion.getDiscriminator() == HandleTypeSafeUnion.hidl_discriminator.a);
408             ExpectTrue(safeUnion.a() == null);
409         }
410         {
411             // SafeUnionDefaultNativeHandleTest
412             NativeHandle[] testHandlesArray = new NativeHandle[5];
413             for (int i = 0; i < testHandlesArray.length; i++) {
414                 testHandlesArray[i] = new NativeHandle();
415             }
416 
417             ArrayList<NativeHandle> testHandlesList = new ArrayList<NativeHandle>(
418                 Arrays.asList(testHandlesArray));
419 
420             HandleTypeSafeUnion safeUnion = safeunionInterface.newHandleTypeSafeUnion();
421             safeUnion = safeunionInterface.setHandleA(safeUnion, new NativeHandle());
422             ExpectTrue(safeUnion.getDiscriminator() == HandleTypeSafeUnion.hidl_discriminator.a);
423             ExpectFalse(safeUnion.a().hasSingleFileDescriptor());
424 
425             safeUnion = safeunionInterface.setHandleB(safeUnion, testHandlesArray);
426             ExpectTrue(safeUnion.getDiscriminator() == HandleTypeSafeUnion.hidl_discriminator.b);
427             ExpectTrue(safeUnion.b().length == testHandlesArray.length);
428 
429             for (int i = 0; i < testHandlesArray.length; i++) {
430                 ExpectFalse(safeUnion.b()[i].hasSingleFileDescriptor());
431             }
432 
433             safeUnion = safeunionInterface.setHandleC(safeUnion, testHandlesList);
434             ExpectTrue(safeUnion.getDiscriminator() == HandleTypeSafeUnion.hidl_discriminator.c);
435             ExpectTrue(safeUnion.c().size() == testHandlesList.size());
436 
437             for (int i = 0; i < testHandlesList.size(); i++) {
438                 ExpectFalse(safeUnion.c().get(i).hasSingleFileDescriptor());
439             }
440         }
441         {
442             // SafeUnionNativeHandleWithFdTest
443             final String testFileName = "/data/local/tmp/SafeUnionNativeHandleWithFdTest";
444             final String[] testStrings = {"This ", "is ", "so ", "much ", "data!\n"};
445             File file = new File(testFileName);
446 
447             if (file.exists()) { ExpectTrue(file.delete()); }
448             ExpectTrue(file.createNewFile());
449 
450             StringBuilder builder = new StringBuilder();
451             for (String testString : testStrings) {
452                 builder.append(testString);
453             }
454             final String goldenResult = builder.toString();
455 
456             ArrayList<NativeHandle> testHandlesList = new ArrayList<NativeHandle>();
457             FileOutputStream fos = new FileOutputStream(file);
458             for (int i = 0; i < testStrings.length; i++) {
459                 testHandlesList.add(new NativeHandle(fos.getFD(), false /*own*/));
460             }
461 
462             HandleTypeSafeUnion safeUnion = safeunionInterface.newHandleTypeSafeUnion();
463             safeUnion = safeunionInterface.setHandleC(safeUnion, testHandlesList);
464             for (int i = 0; i < safeUnion.c().size(); i++) {
465                 ExpectTrue(safeUnion.c().get(i).hasSingleFileDescriptor());
466 
467                 // If you want to copy it out of the binder buffer or save it, it needs to be duped.
468                 // This isn't necessary for the test since it is kept open for the binder window.
469                 NativeHandle handle = safeUnion.c().get(i);
470                 if (i%2 == 0) handle = handle.dup();
471 
472                 // Original fd is duped if not dup'd above
473                 FileDescriptor resultFd = handle.getFileDescriptor();
474                 ExpectTrue(resultFd.getInt$() != fos.getFD().getInt$());
475 
476                 FileOutputStream otherFos = new FileOutputStream(resultFd);
477                 otherFos.write(testStrings[i].getBytes());
478                 otherFos.flush();
479 
480                 otherFos.close();
481 
482                 if (i%2 == 0) handle.close();
483             }
484 
485             byte[] resultData = new byte[(int) file.length()];
486             FileInputStream fis = new FileInputStream(file);
487             fis.read(resultData);
488 
489             String result = new String(resultData);
490             Expect(result, goldenResult);
491 
492             fis.close();
493             fos.close();
494             ExpectTrue(file.delete());
495         }
496         {
497             // SafeUnionEqualityTest
498             LargeSafeUnion one = safeunionInterface.newLargeSafeUnion();
499             LargeSafeUnion two = safeunionInterface.newLargeSafeUnion();
500             ExpectTrue(one.equals(two));
501 
502             one = safeunionInterface.setA(one, (byte) 1);
503             ExpectFalse(one.equals(two));
504 
505             two = safeunionInterface.setB(two, (byte) 1);
506             ExpectFalse(one.equals(two));
507 
508             two = safeunionInterface.setA(two, (byte) 2);
509             ExpectFalse(one.equals(two));
510 
511             two = safeunionInterface.setA(two, (byte) 1);
512             ExpectTrue(one.equals(two));
513         }
514         {
515             // SafeUnionDeepEqualityTest
516             ArrayList<Long> testVectorA = new ArrayList(Arrays.asList(1L, 2L, 3L));
517             ArrayList<Long> testVectorB = new ArrayList(Arrays.asList(2L, 1L, 3L));
518 
519             LargeSafeUnion one = safeunionInterface.newLargeSafeUnion();
520             LargeSafeUnion two = safeunionInterface.newLargeSafeUnion();
521 
522             one = safeunionInterface.setI(one, testVectorA);
523             two = safeunionInterface.setI(two, testVectorB);
524             ExpectFalse(one.equals(two));
525 
526             two = safeunionInterface.setI(two, (ArrayList<Long>) testVectorA.clone());
527             ExpectTrue(one.equals(two));
528         }
529         {
530             // SafeUnionHashCodeTest
531             ArrayList<Boolean> testVector =
532                 new ArrayList(Arrays.asList(true, false, false, true, true));
533 
534             LargeSafeUnion one = safeunionInterface.newLargeSafeUnion();
535             LargeSafeUnion two = safeunionInterface.newLargeSafeUnion();
536 
537             one = safeunionInterface.setH(one, testVector);
538             two = safeunionInterface.setA(two, (byte) -5);
539             ExpectFalse(one.hashCode() == two.hashCode());
540 
541             two = safeunionInterface.setH(two, (ArrayList<Boolean>) testVector.clone());
542             ExpectTrue(one.hashCode() == two.hashCode());
543         }
544     }
545 
client()546     private void client() throws RemoteException, IOException, ErrnoException {
547 
548         ExpectDeepEq(null, null);
549         ExpectDeepNe(null, new String());
550         ExpectDeepNe(new String(), null);
551         ExpectDeepEq(new String(), new String());
552         ExpectDeepEq("hey", "hey");
553 
554         ExpectDeepEq(new int[]{1,2}, new int[]{1,2});
555         ExpectDeepNe(new int[]{1,2}, new int[]{1,3});
556         ExpectDeepNe(new int[]{1,2}, new int[]{1,2,3});
557         ExpectDeepEq(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,4}});
558         ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,5}});
559         ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2,3},{4,5,6}});
560         ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,4,5}});
561 
562         ExpectDeepEq(new Integer[]{1,2}, new Integer[]{1,2});
563         ExpectDeepNe(new Integer[]{1,2}, new Integer[]{1,3});
564         ExpectDeepNe(new Integer[]{1,2}, new Integer[]{1,2,3});
565         ExpectDeepEq(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,4}});
566         ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,5}});
567         ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2,3},{4,5,6}});
568         ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,4,5}});
569 
570         ExpectDeepEq(new ArrayList(Arrays.asList(1, 2)),
571                      new ArrayList(Arrays.asList(1, 2)));
572         ExpectDeepNe(new ArrayList(Arrays.asList(1, 2)),
573                      new ArrayList(Arrays.asList(1, 2, 3)));
574 
575         ExpectDeepEq(new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})),
576                      new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})));
577         ExpectDeepNe(new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})),
578                      new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,5})));
579 
580         ExpectDeepEq(new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})),
581                      new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})));
582         ExpectDeepNe(new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})),
583                      new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,5})));
584 
585         ExpectDeepEq(new ArrayList[]{new ArrayList(Arrays.asList(1,2)),
586                                      new ArrayList(Arrays.asList(3,4))},
587                      new ArrayList[]{new ArrayList(Arrays.asList(1,2)),
588                                      new ArrayList(Arrays.asList(3,4))});
589 
590         {
591             // Test proper exceptions are thrown
592             try {
593                 IBase proxy = IBase.getService("this-doesn't-exist");
594                 // this should never run
595                 ExpectTrue(false);
596             } catch (Exception e) {
597                 ExpectTrue(e instanceof NoSuchElementException);
598             }
599         }
600 
601         {
602             // Test proper exceptions are thrown
603             try {
604                 // not in manifest, so won't wait
605                 IBase proxy = IBase.getService("this-doesn't-exist", true /*retry*/);
606                 // this should never run
607                 ExpectTrue(false);
608             } catch (Exception e) {
609                 ExpectTrue(e instanceof NoSuchElementException);
610             }
611         }
612 
613         {
614             // Test access through base interface binder.
615             IBase baseProxy = IBase.getService();
616             baseProxy.someBaseMethod();
617 
618             IBaz bazProxy = IBaz.castFrom(baseProxy);
619             ExpectTrue(bazProxy != null);
620 
621             // IQuux is completely unrelated to IBase/IBaz, so the following
622             // should fail, i.e. return null.
623             IQuux quuxProxy = IQuux.castFrom(baseProxy);
624             ExpectTrue(quuxProxy == null);
625         }
626 
627         {
628             // Test waiting API
629             IBase baseProxyA = IBaz.getService(true /* retry */);
630             ExpectTrue(baseProxyA != null);
631             IBase baseProxyB = IBaz.getService(false /* retry */);
632             ExpectTrue(baseProxyB != null);
633         }
634 
635         IBaz proxy = IBaz.getService();
636 
637         proxy.ping();
638 
639         proxy.someBaseMethod();
640 
641         {
642             Expect(proxy.interfaceDescriptor(), IBaz.kInterfaceName);
643         }
644 
645         {
646             // Tests calling a two-way method with oneway enabled.
647             IHwBinder binder = proxy.asBinder();
648             HwParcel request = new HwParcel();
649             HwParcel reply = new HwParcel();
650 
651             request.writeInterfaceToken(IBaz.kInterfaceName);
652             request.writeInt64(1234);
653             // IBaz::doThatAndReturnSomething is not oneway but we call it using FLAG_ONEWAY.
654             binder.transact(19 /*doThatAndReturnSomething*/, request, reply, IBinder.FLAG_ONEWAY);
655 
656             try {
657                 reply.verifySuccess();
658                 // This should never run.
659                 ExpectTrue(false);
660             } catch (Exception e) {
661                 ExpectTrue(e instanceof RemoteException);
662             }
663 
664             proxy.ping();
665         }
666 
667         {
668             // Tests calling a oneway method with oneway disabled.
669             IHwBinder binder = proxy.asBinder();
670             HwParcel request = new HwParcel();
671             HwParcel reply = new HwParcel();
672 
673             request.writeInterfaceToken(IBaz.kInterfaceName);
674             request.writeFloat(1.0f);
675             // IBaz::doThis is oneway but we call it without using FLAG_ONEWAY.
676             // This does not raise an exception in C++ because
677             // IPCThreadState::executeCommand for BR_TRANSACTION sends an empty
678             // reply for two-way transactions if the transaction itself did not
679             // send a reply.
680             try {
681                 binder.transact(18 /*doThis*/, request, reply, 0 /* Not FLAG_ONEWAY */);
682                 ExpectTrue(!proxy.isJava());
683             } catch (RemoteException e) {
684                 ExpectTrue(proxy.isJava());
685             }
686 
687             proxy.ping();
688         }
689 
690         {
691             IBase.Foo foo = new IBase.Foo();
692             foo.x = 1;
693 
694             for (int i = 0; i < 5; ++i) {
695                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
696                 bar.z = 1.0f + (float)i * 0.01f;
697                 bar.s = "Hello, world " + i;
698                 foo.aaa.add(bar);
699             }
700 
701             foo.y.z = 3.14f;
702             foo.y.s = "Lorem ipsum...";
703 
704             IBase.Foo result = proxy.someOtherBaseMethod(foo);
705             ExpectTrue(result.equals(foo));
706         }
707 
708         {
709             IBase.Foo[] inputArray = new IBase.Foo[2];
710 
711             IBase.Foo foo = new IBase.Foo();
712             foo.x = 1;
713 
714             for (int i = 0; i < 5; ++i) {
715                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
716                 bar.z = 1.0f + (float)i * 0.01f;
717                 bar.s = "Hello, world " + i;
718                 foo.aaa.add(bar);
719             }
720 
721             foo.y.z = 3.14f;
722             foo.y.s = "Lorem ipsum...";
723 
724             inputArray[0] = foo;
725 
726             foo = new IBase.Foo();
727             foo.x = 2;
728 
729             for (int i = 0; i < 3; ++i) {
730                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
731                 bar.z = 2.0f - (float)i * 0.01f;
732                 bar.s = "Lorem ipsum " + i;
733                 foo.aaa.add(bar);
734             }
735 
736             foo.y.z = 1.1414f;
737             foo.y.s = "Et tu brute?";
738 
739             inputArray[1] = foo;
740 
741             IBase.Foo[] expectedOutputArray = new IBase.Foo[2];
742             expectedOutputArray[0] = inputArray[1];
743             expectedOutputArray[1] = inputArray[0];
744 
745             IBase.Foo[] outputArray = proxy.someMethodWithFooArrays(inputArray);
746 
747             ExpectTrue(java.util.Objects.deepEquals(outputArray, expectedOutputArray));
748         }
749 
750         {
751             ArrayList<IBase.Foo> inputVec = new ArrayList<IBase.Foo>();
752 
753             IBase.Foo foo = new IBase.Foo();
754             foo.x = 1;
755 
756             for (int i = 0; i < 5; ++i) {
757                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
758                 bar.z = 1.0f + (float)i * 0.01f;
759                 bar.s = "Hello, world " + i;
760                 foo.aaa.add(bar);
761             }
762 
763             foo.y.z = 3.14f;
764             foo.y.s = "Lorem ipsum...";
765 
766             inputVec.add(foo);
767 
768             foo = new IBase.Foo();
769             foo.x = 2;
770 
771             for (int i = 0; i < 3; ++i) {
772                 IBase.Foo.Bar bar = new IBase.Foo.Bar();
773                 bar.z = 2.0f - (float)i * 0.01f;
774                 bar.s = "Lorem ipsum " + i;
775                 foo.aaa.add(bar);
776             }
777 
778             foo.y.z = 1.1414f;
779             foo.y.s = "Et tu brute?";
780 
781             inputVec.add(foo);
782 
783             ArrayList<IBase.Foo> expectedOutputVec = new ArrayList<IBase.Foo>();
784             expectedOutputVec.add(inputVec.get(1));
785             expectedOutputVec.add(inputVec.get(0));
786 
787             ArrayList<IBase.Foo> outputVec =
788                 proxy.someMethodWithFooVectors(inputVec);
789 
790             ExpectTrue(java.util.Objects.deepEquals(outputVec, expectedOutputVec));
791         }
792 
793         {
794             IBase.VectorOfArray in = new IBase.VectorOfArray();
795 
796             int k = 0;
797             for (int i = 0; i < 3; ++i) {
798                 byte[] mac = new byte[6];
799                 for (int j = 0; j < 6; ++j, ++k) {
800                     mac[j] = (byte)k;
801                 }
802 
803                 in.addresses.add(mac);
804             }
805 
806             IBase.VectorOfArray expectedOut = new IBase.VectorOfArray();
807             int n = in.addresses.size();
808 
809             for (int i = 0; i < n; ++i) {
810                 expectedOut.addresses.add(in.addresses.get(n - 1 - i));
811             }
812 
813             IBase.VectorOfArray out = proxy.someMethodWithVectorOfArray(in);
814             ExpectTrue(out.equals(expectedOut));
815         }
816 
817         {
818             ArrayList<byte[]> in = new ArrayList<byte[]>();
819 
820             int k = 0;
821             for (int i = 0; i < 3; ++i) {
822                 byte[] mac = new byte[6];
823                 for (int j = 0; j < 6; ++j, ++k) {
824                     mac[j] = (byte)k;
825                 }
826 
827                 in.add(mac);
828             }
829 
830             ArrayList<byte[]> expectedOut = new ArrayList<byte[]>();
831 
832             int n = in.size();
833             for (int i = 0; i < n; ++i) {
834                 expectedOut.add(in.get(n - 1 - i));
835             }
836 
837             ArrayList<byte[]> out = proxy.someMethodTakingAVectorOfArray(in);
838 
839             ExpectTrue(out.size() == expectedOut.size());
840             for  (int i = 0; i < n; ++i) {
841                 ExpectTrue(java.util.Objects.deepEquals(out.get(i), expectedOut.get(i)));
842             }
843         }
844 
845         {
846             IBase.StringMatrix5x3 in = new IBase.StringMatrix5x3();
847             IBase.StringMatrix3x5 expectedOut = new IBase.StringMatrix3x5();
848 
849             for (int i = 0; i < 5; ++i) {
850                 for (int j = 0; j < 3; ++j) {
851                     in.s[i][j] = numberToEnglish(3 * i + j + 1);
852                     expectedOut.s[j][i] = in.s[i][j];
853                 }
854             }
855 
856             IBase.StringMatrix3x5 out = proxy.transpose(in);
857 
858             // [[1 2 3] [4 5 6] [7 8 9] [10 11 12] [13 14 15]]^T
859             // = [[1 4 7 10 13] [2 5 8 11 14] [3 6 9 12 15]]
860             ExpectTrue(out.equals(expectedOut));
861         }
862 
863         {
864             String[][] in = new String[5][3];
865             String[][] expectedOut = new String[3][5];
866             for (int i = 0; i < 5; ++i) {
867                 for (int j = 0; j < 3; ++j) {
868                     in[i][j] = numberToEnglish(3 * i + j + 1);
869                     expectedOut[j][i] = in[i][j];
870                 }
871             }
872 
873             String[][] out = proxy.transpose2(in);
874 
875             // [[1 2 3] [4 5 6] [7 8 9] [10 11 12] [13 14 15]]^T
876             // = [[1 4 7 10 13] [2 5 8 11 14] [3 6 9 12 15]]
877             ExpectTrue(java.util.Arrays.deepEquals(out, expectedOut));
878         }
879 
880         ExpectTrue(proxy.someBoolMethod(true) == false);
881 
882         {
883             boolean[] someBoolArray = new boolean[3];
884             someBoolArray[0] = true;
885             someBoolArray[1] = false;
886             someBoolArray[2] = true;
887 
888             boolean[] resultArray = proxy.someBoolArrayMethod(someBoolArray);
889             ExpectTrue(resultArray[0] == false);
890             ExpectTrue(resultArray[1] == true);
891             ExpectTrue(resultArray[2] == false);
892 
893             ArrayList<Boolean> someBoolVec = new ArrayList<Boolean>();
894             someBoolVec.add(true);
895             someBoolVec.add(false);
896             someBoolVec.add(true);
897 
898             ArrayList<Boolean> resultVec = proxy.someBoolVectorMethod(someBoolVec);
899             ExpectTrue(resultVec.get(0) == false);
900             ExpectTrue(resultVec.get(1) == true);
901             ExpectTrue(resultVec.get(2) == false);
902         }
903 
904         proxy.doThis(1.0f);
905 
906         ExpectTrue(proxy.doThatAndReturnSomething(1) == 666);
907         ExpectTrue(proxy.doQuiteABit(1, 2L, 3.0f, 4.0) == 666.5);
908 
909         {
910             int[] paramArray = new int[15];
911             int[] expectedOutArray = new int[32];
912             ArrayList<Integer> paramVec = new ArrayList<Integer>();
913             ArrayList<Integer> expectedOutVec = new ArrayList<Integer>();
914 
915             for (int i = 0; i < paramArray.length; ++i) {
916                 paramArray[i] = i;
917                 paramVec.add(i);
918 
919                 expectedOutArray[i] = 2 * i;
920                 expectedOutArray[15 + i] = i;
921 
922                 expectedOutVec.add(2 * i);
923             }
924 
925             expectedOutArray[30] = 1;
926             expectedOutArray[31] = 2;
927 
928 
929             int[] outArray = proxy.doSomethingElse(paramArray);
930             ExpectTrue(java.util.Objects.deepEquals(outArray, expectedOutArray));
931 
932             ArrayList<Integer> outVec = proxy.mapThisVector(paramVec);
933             ExpectTrue(java.util.Objects.equals(outVec, expectedOutVec));
934         }
935 
936         Expect(proxy.doStuffAndReturnAString(), "Hello, world!");
937 
938         BazCallback cb = new BazCallback();
939         ExpectTrue(!cb.wasCalled());
940         proxy.callMe(cb);
941         ExpectTrue(cb.wasCalled());
942 
943         ExpectTrue(proxy.useAnEnum(IBaz.SomeEnum.goober) == IBaz.SomeEnum.quux);
944 
945         {
946             String[] stringArray = new String[3];
947             stringArray[0] = "one";
948             stringArray[1] = "two";
949             stringArray[2] = "three";
950 
951             String[] expectedOutArray = new String[2];
952             expectedOutArray[0] = "Hello";
953             expectedOutArray[1] = "World";
954 
955             String[] outArray = proxy.haveSomeStrings(stringArray);
956             ExpectTrue(java.util.Arrays.deepEquals(outArray, expectedOutArray));
957 
958             ArrayList<String> stringVec = new ArrayList<String>();
959             stringVec.add("one");
960             stringVec.add("two");
961             stringVec.add("three");
962 
963             ArrayList<String> expectedOutVec = new ArrayList<String>();
964             expectedOutVec.add("Hello");
965             expectedOutVec.add("World");
966 
967             ExpectTrue(expectedOutVec.equals(proxy.haveAStringVec(stringVec)));
968         }
969 
970         {
971             ArrayList<Byte> bytes = new ArrayList<Byte>();
972             bytes.add(IBaz.BitField.V1);
973             bytes.add(IBaz.BitField.V2);
974             ExpectTrue(bytes.equals(proxy.repeatBitfieldVec(bytes)));
975         }
976 
977         proxy.returnABunchOfStrings(
978                 new IBaz.returnABunchOfStringsCallback() {
979                     @Override
980                     public void onValues(String a, String b, String c) {
981                         Expect(a, "Eins");
982                         Expect(b, "Zwei");
983                         Expect(c, "Drei");
984                     }
985                 });
986 
987         proxy.returnABunchOfStrings((a,b,c) -> Expect(a + b + c, "EinsZweiDrei"));
988 
989         proxy.callMeLater(new BazCallback());
990         System.gc();
991         proxy.iAmFreeNow();
992 
993         {
994             IBaz.T t1 = new IBaz.T();
995             IBaz.T t2 = new IBaz.T();
996             for (int i = 0; i < 5; i++) {
997                 for (int j = 0; j < 3; j++) {
998                     t1.matrix5x3[i][j] = t2.matrix5x3[i][j] = (i + 1) * (j + 1);
999                 }
1000             }
1001             ExpectTrue(t1.equals(t2));
1002             ExpectTrue(t1.hashCode() == t2.hashCode());
1003             t2.matrix5x3[4][2] = -60;
1004             ExpectTrue(!t1.equals(t2));
1005         }
1006 
1007         // server currently only implements this in C++
1008         if (!proxy.isJava()) {
1009             ArrayList<NestedStruct> structs = proxy.getNestedStructs();
1010             ExpectTrue(structs.size() == 5);
1011             ExpectTrue(structs.get(1).matrices.size() == 6);
1012         }
1013 
1014         {
1015             IBaz.Everything e = new IBaz.Everything();
1016             Expect(e.toString(),
1017                 "{.number = 0, .anotherNumber = 0, .s = , " +
1018                 ".vs = [], .multidimArray = [[null, null], [null, null]], " +
1019                 ".sArray = [null, null, null], .anotherStruct = {.first = , .last = }, .bf = }");
1020             e.s = "string!";
1021             e.number = 127;
1022             e.anotherNumber = 100;
1023             e.vs.addAll(Arrays.asList("One", "Two", "Three"));
1024             for (int i = 0; i < e.multidimArray.length; i++)
1025                 for (int j = 0; j < e.multidimArray[i].length; j++)
1026                     e.multidimArray[i][j] = Integer.toString(i) + Integer.toString(j);
1027             e.bf = IBaz.BitField.VALL;
1028             e.anotherStruct.first = "James";
1029             e.anotherStruct.last = "Bond";
1030             Expect(e.toString(),
1031                 "{.number = 127, .anotherNumber = 100, .s = string!, " +
1032                 ".vs = [One, Two, Three], .multidimArray = [[00, 01], [10, 11]], " +
1033                 ".sArray = [null, null, null], .anotherStruct = {.first = James, .last = Bond}, " +
1034                 ".bf = V0 | V1 | V2 | V3 | VALL}");
1035             Expect(IBaz.BitField.toString(IBaz.BitField.VALL), "VALL");
1036             Expect(IBaz.BitField.toString((byte)(IBaz.BitField.V0 | IBaz.BitField.V2)), "0x5");
1037             Expect(IBaz.BitField.dumpBitfield(IBaz.BitField.VALL), "V0 | V1 | V2 | V3 | VALL");
1038             Expect(IBaz.BitField.dumpBitfield((byte)(IBaz.BitField.V1 | IBaz.BitField.V3 | 0xF0)),
1039                 "V1 | V3 | 0xf0");
1040 
1041             Expect(proxy.toString(), IBaz.kInterfaceName + "@Proxy");
1042         }
1043 
1044         {
1045             // Ensure that native parcel is cleared even if the corresponding
1046             // Java object isn't GC'd.
1047             ArrayList<Integer> data4K = new ArrayList<>(1024);
1048             for (int i = 0; i < 1024; i++) {
1049                 data4K.add(i);
1050             }
1051 
1052             for (int i = 0; i < 1024; i++) {
1053                 // If they are not properly cleaned up, these calls will put 4MB of data in
1054                 // kernel binder buffer, and will fail.
1055                 try {
1056                     proxy.mapThisVector(data4K);
1057                 } catch (RemoteException ex) {
1058                     throw new RuntimeException("Failed at call #" + Integer.toString(i), ex);
1059                 }
1060             }
1061         }
1062 
1063         {
1064             // TestArrays
1065             IBase.LotsOfPrimitiveArrays in = new IBase.LotsOfPrimitiveArrays();
1066 
1067             for (int i = 0; i < 128; ++i) {
1068                 in.byte1[i] = (byte)i;
1069                 in.boolean1[i] = (i & 4) != 0;
1070                 in.double1[i] = i;
1071             }
1072 
1073             int m = 0;
1074             for (int i = 0; i < 8; ++i) {
1075                 for (int j = 0; j < 128; ++j, ++m) {
1076                     in.byte2[i][j] = (byte)m;
1077                     in.boolean2[i][j] = (m & 4) != 0;
1078                     in.double2[i][j] = m;
1079                 }
1080             }
1081 
1082             m = 0;
1083             for (int i = 0; i < 8; ++i) {
1084                 for (int j = 0; j < 16; ++j) {
1085                     for (int k = 0; k < 128; ++k, ++m) {
1086                         in.byte3[i][j][k] = (byte)m;
1087                         in.boolean3[i][j][k] = (m & 4) != 0;
1088                         in.double3[i][j][k] = m;
1089                     }
1090                 }
1091             }
1092 
1093             IBase.LotsOfPrimitiveArrays out = proxy.testArrays(in);
1094             ExpectTrue(in.equals(out));
1095         }
1096 
1097         {
1098             // testByteVecs
1099 
1100             ArrayList<byte[]> in = new ArrayList<byte[]>();
1101 
1102             int k = 0;
1103             for (int i = 0; i < 8; ++i) {
1104                 byte[] elem = new byte[128];
1105                 for (int j = 0; j < 128; ++j, ++k) {
1106                     elem[j] = (byte)k;
1107                 }
1108                 in.add(elem);
1109             }
1110 
1111             ArrayList<byte[]> out = proxy.testByteVecs(in);
1112 
1113             ExpectDeepEq(in, out);
1114         }
1115 
1116         {
1117             // testByteVecs w/ mismatched element lengths.
1118 
1119             ArrayList<byte[]> in = new ArrayList<byte[]>();
1120 
1121             int k = 0;
1122             for (int i = 0; i < 8; ++i) {
1123                 byte[] elem = new byte[128 - i];
1124                 for (int j = 0; j < (128 - i); ++j, ++k) {
1125                     elem[j] = (byte)k;
1126                 }
1127                 in.add(elem);
1128             }
1129 
1130             boolean failedAsItShould = false;
1131 
1132             try {
1133                 ArrayList<byte[]> out = proxy.testByteVecs(in);
1134             }
1135             catch (IllegalArgumentException e) {
1136                 failedAsItShould = true;
1137             }
1138 
1139             ExpectTrue(failedAsItShould);
1140         }
1141 
1142         {
1143             // testBooleanVecs
1144 
1145             ArrayList<boolean[]> in = new ArrayList<boolean[]>();
1146 
1147             int k = 0;
1148             for (int i = 0; i < 8; ++i) {
1149                 boolean[] elem = new boolean[128];
1150                 for (int j = 0; j < 128; ++j, ++k) {
1151                     elem[j] = (k & 4) != 0;
1152                 }
1153                 in.add(elem);
1154             }
1155 
1156             ArrayList<boolean[]> out = proxy.testBooleanVecs(in);
1157             ExpectDeepEq(in, out);
1158         }
1159 
1160         {
1161             // testDoubleVecs
1162 
1163             ArrayList<double[]> in = new ArrayList<double[]>();
1164 
1165             int k = 0;
1166             for (int i = 0; i < 8; ++i) {
1167                 double[] elem = new double[128];
1168                 for (int j = 0; j < 128; ++j, ++k) {
1169                     elem[j] = k;
1170                 }
1171                 in.add(elem);
1172             }
1173 
1174             ArrayList<double[]> out = proxy.testDoubleVecs(in);
1175             ExpectDeepEq(in, out);
1176         }
1177         {
1178             // testProxyEquals
1179             // TODO(b/68727931): test passthrough services as well.
1180 
1181             IBase proxy1 = IBase.getService();
1182             IBase proxy2 = IBase.getService();
1183             IBaz proxy3 = IBaz.getService();
1184             IBazCallback callback1 = new BazCallback();
1185             IBazCallback callback2 = new BazCallback();
1186             IServiceManager manager = IServiceManager.getService();
1187 
1188             // test hwbinder proxies
1189             ExpectEqual(proxy1, proxy2); // same proxy class
1190             ExpectEqual(proxy1, proxy3); // different proxy class
1191 
1192             // negative tests
1193             ExpectNotEqual(proxy1, null);
1194             ExpectNotEqual(proxy1, callback1); // proxy != stub
1195             ExpectNotEqual(proxy1, manager);
1196 
1197             // HidlSupport.interfacesEqual use overridden .equals for stubs
1198             ExpectEqual(callback1, callback1);
1199             ExpectEqual(callback1, callback2);
1200             callback1.hey();
1201             ExpectNotEqual(callback1, callback2);
1202             callback2.hey();
1203             ExpectEqual(callback1, callback2);
1204 
1205             // test hash for proxies
1206             java.util.HashSet<IBase> set = new java.util.HashSet<>();
1207             set.add(proxy1);
1208             ExpectTrue(set.contains(proxy1)); // hash is stable
1209             ExpectTrue(set.contains(proxy2));
1210             ExpectFalse(set.contains(manager));
1211         }
1212         {
1213             IBaz baz = IBaz.getService();
1214             ExpectTrue(baz != null);
1215             IBaz.StructWithInterface swi = new IBaz.StructWithInterface();
1216             swi.iface = IServiceManager.getService();
1217             swi.number = 12345678;
1218             IBaz.StructWithInterface swi_back = baz.haveSomeStructWithInterface(swi);
1219             ExpectTrue(swi_back != null);
1220             ExpectTrue(swi_back.iface != null);
1221             ExpectTrue(HidlSupport.interfacesEqual(swi.iface, swi_back.iface));
1222             ExpectTrue(swi_back.number == 12345678);
1223         }
1224 
1225         runClientSafeUnionTests();
1226 
1227         // currently no Java implementation of this
1228         if (!proxy.isJava()) {
1229             runClientMemoryTests();
1230         }
1231 
1232         // --- DEATH RECIPIENT TESTING ---
1233         // This must always be done last, since it will kill the native server process
1234         HidlDeathRecipient recipient1 = new HidlDeathRecipient();
1235         HidlDeathRecipient recipient2 = new HidlDeathRecipient();
1236 
1237         final int cookie1 = 0x1481;
1238         final int cookie2 = 0x1482;
1239         final int cookie3 = 0x1483;
1240         ExpectTrue(proxy.linkToDeath(recipient1, cookie1));
1241 
1242         ExpectTrue(proxy.linkToDeath(recipient1, cookie3));
1243         ExpectTrue(proxy.unlinkToDeath(recipient1));
1244 
1245         ExpectTrue(proxy.linkToDeath(recipient2, cookie2));
1246         ExpectTrue(proxy.unlinkToDeath(recipient2));
1247         try {
1248             proxy.dieNow();
1249         } catch (DeadObjectException e) {
1250             // Expected
1251         }
1252         ExpectTrue(recipient1.waitUntilServiceDied(2000 /*timeoutMillis*/));
1253         ExpectTrue(!recipient2.waitUntilServiceDied(2000 /*timeoutMillis*/));
1254         ExpectTrue(recipient1.cookieMatches(cookie1));
1255         Log.d(TAG, "OK, exiting");
1256     }
1257 
1258     class Baz extends IBaz.Stub {
1259         // from IBase
isJava()1260         public boolean isJava() {
1261             Log.d(TAG, "Baz isJava");
1262             return true;
1263         }
1264 
someBaseMethod()1265         public void someBaseMethod() {
1266             Log.d(TAG, "Baz someBaseMethod");
1267         }
1268 
someOtherBaseMethod(IBase.Foo foo)1269         public IBase.Foo someOtherBaseMethod(IBase.Foo foo) {
1270             Log.d(TAG, "Baz someOtherBaseMethod " + foo.toString());
1271             return foo;
1272         }
1273 
someMethodWithFooArrays(IBase.Foo[] fooInput)1274         public IBase.Foo[] someMethodWithFooArrays(IBase.Foo[] fooInput) {
1275             Log.d(TAG, "Baz someMethodWithFooArrays " + Arrays.toString(fooInput));
1276 
1277             IBase.Foo[] fooOutput = new IBase.Foo[2];
1278             fooOutput[0] = fooInput[1];
1279             fooOutput[1] = fooInput[0];
1280 
1281             return fooOutput;
1282         }
1283 
someMethodWithFooVectors( ArrayList<IBase.Foo> fooInput)1284         public ArrayList<IBase.Foo> someMethodWithFooVectors(
1285                 ArrayList<IBase.Foo> fooInput) {
1286             Log.d(TAG, "Baz someMethodWithFooVectors " + fooInput.toString());
1287 
1288             ArrayList<IBase.Foo> fooOutput = new ArrayList<IBase.Foo>();
1289             fooOutput.add(fooInput.get(1));
1290             fooOutput.add(fooInput.get(0));
1291 
1292             return fooOutput;
1293         }
1294 
someMethodWithVectorOfArray( IBase.VectorOfArray in)1295         public IBase.VectorOfArray someMethodWithVectorOfArray(
1296                 IBase.VectorOfArray in) {
1297             Log.d(TAG, "Baz someMethodWithVectorOfArray " + in.toString());
1298 
1299             IBase.VectorOfArray out = new IBase.VectorOfArray();
1300             int n = in.addresses.size();
1301             for (int i = 0; i < n; ++i) {
1302                 out.addresses.add(in.addresses.get(n - i - 1));
1303             }
1304 
1305             return out;
1306         }
1307 
someMethodTakingAVectorOfArray( ArrayList<byte[ ]> in)1308         public ArrayList<byte[/* 6 */]> someMethodTakingAVectorOfArray(
1309                 ArrayList<byte[/* 6 */]> in) {
1310             Log.d(TAG, "Baz someMethodTakingAVectorOfArray");
1311 
1312             int n = in.size();
1313             ArrayList<byte[]> out = new ArrayList<byte[]>();
1314             for (int i = 0; i < n; ++i) {
1315                 out.add(in.get(n - i - 1));
1316             }
1317 
1318             return out;
1319         }
1320 
transpose(IBase.StringMatrix5x3 in)1321         public IBase.StringMatrix3x5 transpose(IBase.StringMatrix5x3 in) {
1322             Log.d(TAG, "Baz transpose " + in.toString());
1323 
1324             IBase.StringMatrix3x5 out = new IBase.StringMatrix3x5();
1325             for (int i = 0; i < 3; ++i) {
1326                 for (int j = 0; j < 5; ++j) {
1327                     out.s[i][j] = in.s[j][i];
1328                 }
1329             }
1330 
1331             return out;
1332         }
1333 
transpose2(String[][] in)1334         public String[][] transpose2(String[][] in) {
1335             Log.d(TAG, "Baz transpose2 " + Arrays.deepToString(in));
1336 
1337             String[][] out = new String[3][5];
1338             for (int i = 0; i < 3; ++i) {
1339                 for (int j = 0; j < 5; ++j) {
1340                     out[i][j] = in[j][i];
1341                 }
1342             }
1343 
1344             return out;
1345         }
1346 
someBoolMethod(boolean x)1347         public boolean someBoolMethod(boolean x) {
1348             Log.d(TAG, "Baz someBoolMethod(" + x + ")");
1349 
1350             return !x;
1351         }
1352 
someBoolArrayMethod(boolean[] x)1353         public boolean[] someBoolArrayMethod(boolean[] x) {
1354             Log.d(TAG, "Baz someBoolArrayMethod(" + Arrays.toString(x) + ")");
1355 
1356             boolean[] out = new boolean[4];
1357             out[0] = !x[0];
1358             out[1] = !x[1];
1359             out[2] = !x[2];
1360             out[3] = true;
1361 
1362             return out;
1363         }
1364 
someBoolVectorMethod(ArrayList<Boolean> x)1365         public ArrayList<Boolean> someBoolVectorMethod(ArrayList<Boolean> x) {
1366             Log.d(TAG, "Baz someBoolVectorMethod(" + x.toString() + ")");
1367 
1368             ArrayList<Boolean> out = new ArrayList<Boolean>();
1369             for (int i = 0; i < x.size(); ++i) {
1370                 out.add(!x.get(i));
1371             }
1372 
1373             return out;
1374         }
1375 
doThis(float param)1376         public void doThis(float param) {
1377             Log.d(TAG, "Baz doThis " + param);
1378         }
1379 
doThatAndReturnSomething(long param)1380         public int doThatAndReturnSomething(long param) {
1381             Log.d(TAG, "Baz doThatAndReturnSomething " + param);
1382             return 666;
1383         }
1384 
doQuiteABit(int a, long b, float c, double d)1385         public double doQuiteABit(int a, long b, float c, double d) {
1386             Log.d(TAG, "Baz doQuiteABit " + a + ", " + b + ", " + c + ", " + d);
1387             return 666.5;
1388         }
1389 
doSomethingElse(int[] param)1390         public int[] doSomethingElse(int[] param) {
1391             Log.d(TAG, "Baz doSomethingElse " + Arrays.toString(param));
1392 
1393             int[] something = new int[32];
1394             for (int i = 0; i < 15; ++i) {
1395                 something[i] = 2 * param[i];
1396                 something[15 + i] = param[i];
1397             }
1398             something[30] = 1;
1399             something[31] = 2;
1400 
1401             return something;
1402         }
1403 
doStuffAndReturnAString()1404         public String doStuffAndReturnAString() {
1405             Log.d(TAG, "doStuffAndReturnAString");
1406             return "Hello, world!";
1407         }
1408 
mapThisVector(ArrayList<Integer> param)1409         public ArrayList<Integer> mapThisVector(ArrayList<Integer> param) {
1410             Log.d(TAG, "mapThisVector " + param.toString());
1411 
1412             ArrayList<Integer> out = new ArrayList<Integer>();
1413 
1414             for (int i = 0; i < param.size(); ++i) {
1415                 out.add(2 * param.get(i));
1416             }
1417 
1418             return out;
1419         }
1420 
takeAMask(byte bf, byte first, IBase.MyMask second, byte third, takeAMaskCallback cb)1421         public void takeAMask(byte bf, byte first, IBase.MyMask second, byte third,
1422                 takeAMaskCallback cb) {
1423             cb.onValues(bf, (byte) (bf | first), (byte) (second.value & bf), (byte) (bf & third));
1424         }
1425 
testArrays(LotsOfPrimitiveArrays in)1426         public LotsOfPrimitiveArrays testArrays(LotsOfPrimitiveArrays in) {
1427             return in;
1428         }
1429 
testByteVecs(ArrayList<byte[]> in)1430         public ArrayList<byte[]> testByteVecs(ArrayList<byte[]> in) {
1431             return in;
1432         }
1433 
testBooleanVecs(ArrayList<boolean[]> in)1434         public ArrayList<boolean[]> testBooleanVecs(ArrayList<boolean[]> in) {
1435             return in;
1436         }
1437 
testDoubleVecs(ArrayList<double[]> in)1438         public ArrayList<double[]> testDoubleVecs(ArrayList<double[]> in) {
1439             return in;
1440         }
1441 
returnABitField()1442         public byte returnABitField() {
1443             return 0;
1444         }
1445 
size(int size)1446         public int size(int size) {
1447             return size;
1448         }
1449 
1450         @Override
getNestedStructs()1451         public ArrayList<NestedStruct> getNestedStructs() throws RemoteException {
1452             return new ArrayList<>();
1453         }
1454 
1455         class BazCallback extends IBazCallback.Stub {
heyItsMe(IBazCallback cb)1456             public void heyItsMe(IBazCallback cb) {
1457                 Log.d(TAG, "SERVER: heyItsMe");
1458             }
1459 
hey()1460             public void hey() {
1461                 Log.d(TAG, "SERVER: hey");
1462             }
1463         }
1464 
callMe(IBazCallback cb)1465         public void callMe(IBazCallback cb) throws RemoteException {
1466             Log.d(TAG, "callMe");
1467             cb.heyItsMe(new BazCallback());
1468         }
1469 
1470         private IBazCallback mStoredCallback;
callMeLater(IBazCallback cb)1471         public void callMeLater(IBazCallback cb) {
1472             mStoredCallback = cb;
1473         }
1474 
iAmFreeNow()1475         public void iAmFreeNow() throws RemoteException {
1476             if (mStoredCallback != null) {
1477                 mStoredCallback.hey();
1478             }
1479         }
1480 
dieNow()1481         public void dieNow() { System.exit(0); }
1482 
useAnEnum(byte zzz)1483         public byte useAnEnum(byte zzz) {
1484             Log.d(TAG, "useAnEnum " + zzz);
1485             return SomeEnum.quux;
1486         }
1487 
haveSomeStrings(String[] array)1488         public String[] haveSomeStrings(String[] array) {
1489             Log.d(TAG, "haveSomeStrings ["
1490                         + "\"" + array[0] + "\", "
1491                         + "\"" + array[1] + "\", "
1492                         + "\"" + array[2] + "\"]");
1493 
1494             String[] result = new String[2];
1495             result[0] = "Hello";
1496             result[1] = "World";
1497 
1498             return result;
1499         }
1500 
haveAStringVec(ArrayList<String> vector)1501         public ArrayList<String> haveAStringVec(ArrayList<String> vector) {
1502             Log.d(TAG, "haveAStringVec ["
1503                         + "\"" + vector.get(0) + "\", "
1504                         + "\"" + vector.get(1) + "\", "
1505                         + "\"" + vector.get(2) + "\"]");
1506 
1507             ArrayList<String> result = new ArrayList<String>();
1508             result.add("Hello");
1509             result.add("World");
1510 
1511             return result;
1512         }
1513 
repeatBitfieldVec(ArrayList<Byte> vector)1514         public ArrayList<Byte> repeatBitfieldVec(ArrayList<Byte> vector) { return vector; }
1515 
returnABunchOfStrings(returnABunchOfStringsCallback cb)1516         public void returnABunchOfStrings(returnABunchOfStringsCallback cb) {
1517             cb.onValues("Eins", "Zwei", "Drei");
1518         }
1519 
haveSomeStructWithInterface(StructWithInterface swi)1520         public StructWithInterface haveSomeStructWithInterface(StructWithInterface swi) {
1521             return swi;
1522         }
1523     }
1524 
1525     class SafeUnion extends ISafeUnion.Stub {
1526         @Override
newLargeSafeUnion()1527         public LargeSafeUnion newLargeSafeUnion() {
1528             Log.d(TAG, "SERVER: newLargeSafeUnion");
1529             return new LargeSafeUnion();
1530         }
1531 
1532         @Override
setA(LargeSafeUnion safeUnion, byte a)1533         public LargeSafeUnion setA(LargeSafeUnion safeUnion, byte a) {
1534             Log.d(TAG, "SERVER: setA(" + a + ")");
1535             safeUnion.a(a);
1536 
1537             return safeUnion;
1538         }
1539 
1540         @Override
setB(LargeSafeUnion safeUnion, short b)1541         public LargeSafeUnion setB(LargeSafeUnion safeUnion, short b) {
1542             Log.d(TAG, "SERVER: setB(" + b + ")");
1543             safeUnion.b(b);
1544 
1545             return safeUnion;
1546         }
1547 
1548         @Override
setC(LargeSafeUnion safeUnion, int c)1549         public LargeSafeUnion setC(LargeSafeUnion safeUnion, int c) {
1550             Log.d(TAG, "SERVER: setC(" + c + ")");
1551             safeUnion.c(c);
1552 
1553             return safeUnion;
1554         }
1555 
1556         @Override
setD(LargeSafeUnion safeUnion, long d)1557         public LargeSafeUnion setD(LargeSafeUnion safeUnion, long d) {
1558             Log.d(TAG, "SERVER: setD(" + d + ")");
1559             safeUnion.d(d);
1560 
1561             return safeUnion;
1562         }
1563 
1564         @Override
setE(LargeSafeUnion safeUnion, byte[ ] e)1565         public LargeSafeUnion setE(LargeSafeUnion safeUnion, byte[/* 13 */] e) {
1566             Log.d(TAG, "SERVER: setE(" + Arrays.toString(e) + ")");
1567             safeUnion.e(e);
1568 
1569             return safeUnion;
1570         }
1571 
1572         @Override
setF(LargeSafeUnion safeUnion, long[ ] f)1573         public LargeSafeUnion setF(LargeSafeUnion safeUnion, long[/* 5 */] f) {
1574             Log.d(TAG, "SERVER: setF(" + Arrays.toString(f) + ")");
1575             safeUnion.f(f);
1576 
1577             return safeUnion;
1578         }
1579 
1580         @Override
setG(LargeSafeUnion safeUnion, String g)1581         public LargeSafeUnion setG(LargeSafeUnion safeUnion, String g) {
1582             Log.d(TAG, "SERVER: setG(" + g + ")");
1583             safeUnion.g(g);
1584 
1585             return safeUnion;
1586         }
1587 
1588         @Override
setH(LargeSafeUnion safeUnion, ArrayList<Boolean> h)1589         public LargeSafeUnion setH(LargeSafeUnion safeUnion, ArrayList<Boolean> h) {
1590             Log.d(TAG, "SERVER: setH(" + h + ")");
1591             safeUnion.h(h);
1592 
1593             return safeUnion;
1594         }
1595 
1596         @Override
setI(LargeSafeUnion safeUnion, ArrayList<Long> i)1597         public LargeSafeUnion setI(LargeSafeUnion safeUnion, ArrayList<Long> i) {
1598             Log.d(TAG, "SERVER: setI(" + i + ")");
1599             safeUnion.i(i);
1600 
1601             return safeUnion;
1602         }
1603 
1604         @Override
setJ(LargeSafeUnion safeUnion, ISafeUnion.J j)1605         public LargeSafeUnion setJ(LargeSafeUnion safeUnion, ISafeUnion.J j) {
1606             Log.d(TAG, "SERVER: setJ(" + j + ")");
1607             safeUnion.j(j);
1608 
1609             return safeUnion;
1610         }
1611 
1612         @Override
setK(LargeSafeUnion safeUnion, LargeSafeUnion.K k)1613         public LargeSafeUnion setK(LargeSafeUnion safeUnion, LargeSafeUnion.K k) {
1614             Log.d(TAG, "SERVER: setK(" + k + ")");
1615             safeUnion.k(k);
1616 
1617             return safeUnion;
1618         }
1619 
1620         @Override
setL(LargeSafeUnion safeUnion, SmallSafeUnion l)1621         public LargeSafeUnion setL(LargeSafeUnion safeUnion, SmallSafeUnion l) {
1622             Log.d(TAG, "SERVER: setL(" + l + ")");
1623             safeUnion.l(l);
1624 
1625             return safeUnion;
1626         }
1627 
1628         @Override
setM(LargeSafeUnion safeUnion, byte m)1629         public LargeSafeUnion setM(LargeSafeUnion safeUnion, byte m) {
1630             Log.d(TAG, "SERVER: setM(" + m + ")");
1631             safeUnion.m(m);
1632 
1633             return safeUnion;
1634         }
1635 
1636         @Override
setN(LargeSafeUnion safeUnion, byte n)1637         public LargeSafeUnion setN(LargeSafeUnion safeUnion, byte n) {
1638             Log.d(TAG, "SERVER: setN(" + n + ")");
1639             safeUnion.n(n);
1640 
1641             return safeUnion;
1642         }
1643 
1644         @Override
newInterfaceTypeSafeUnion()1645         public InterfaceTypeSafeUnion newInterfaceTypeSafeUnion() {
1646             Log.d(TAG, "SERVER: newInterfaceTypeSafeUnion");
1647             return new InterfaceTypeSafeUnion();
1648         }
1649 
1650         @Override
setInterfaceA(InterfaceTypeSafeUnion safeUnion, int a)1651         public InterfaceTypeSafeUnion setInterfaceA(InterfaceTypeSafeUnion safeUnion, int a) {
1652             Log.d(TAG, "SERVER: setInterfaceA(" + a + ")");
1653             safeUnion.a(a);
1654 
1655             return safeUnion;
1656         }
1657 
1658         @Override
setInterfaceB( InterfaceTypeSafeUnion safeUnion, byte[ ] b)1659         public InterfaceTypeSafeUnion setInterfaceB(
1660             InterfaceTypeSafeUnion safeUnion, byte[/* 7 */] b) {
1661             Log.d(TAG, "SERVER: setInterfaceB(" + Arrays.toString(b) + ")");
1662             safeUnion.b(b);
1663 
1664             return safeUnion;
1665         }
1666 
1667         @Override
setInterfaceC( InterfaceTypeSafeUnion safeUnion, android.hidl.base.V1_0.IBase c)1668         public InterfaceTypeSafeUnion setInterfaceC(
1669                 InterfaceTypeSafeUnion safeUnion, android.hidl.base.V1_0.IBase c) {
1670             Log.d(TAG, "SERVER: setInterfaceC(" + c + ")");
1671             safeUnion.c(c);
1672 
1673             return safeUnion;
1674         }
1675 
1676         @Override
setInterfaceD(InterfaceTypeSafeUnion safeUnion, String d)1677         public InterfaceTypeSafeUnion setInterfaceD(InterfaceTypeSafeUnion safeUnion, String d) {
1678             Log.d(TAG, "SERVER: setInterfaceD(" + d + ")");
1679             safeUnion.d(d);
1680 
1681             return safeUnion;
1682         }
1683 
1684         @Override
setInterfaceE( InterfaceTypeSafeUnion safeUnion, ArrayList<String> e)1685         public InterfaceTypeSafeUnion setInterfaceE(
1686             InterfaceTypeSafeUnion safeUnion, ArrayList<String> e) {
1687             Log.d(TAG, "SERVER: setInterfaceE(" + e + ")");
1688             safeUnion.e(e);
1689 
1690             return safeUnion;
1691         }
1692 
1693         @Override
setInterfaceF( InterfaceTypeSafeUnion safeUnion, NativeHandle f)1694         public InterfaceTypeSafeUnion setInterfaceF(
1695             InterfaceTypeSafeUnion safeUnion, NativeHandle f) {
1696             Log.d(TAG, "SERVER: setInterfaceF(" + f + ")");
1697             safeUnion.f(f);
1698 
1699             return safeUnion;
1700         }
1701 
1702         @Override
setInterfaceG( InterfaceTypeSafeUnion safeUnion, ArrayList<NativeHandle> g)1703         public InterfaceTypeSafeUnion setInterfaceG(
1704             InterfaceTypeSafeUnion safeUnion, ArrayList<NativeHandle> g) {
1705             Log.d(TAG, "SERVER: setInterfaceG(" + g + ")");
1706             safeUnion.g(g);
1707 
1708             return safeUnion;
1709         }
1710 
1711         @Override
newHandleTypeSafeUnion()1712         public HandleTypeSafeUnion newHandleTypeSafeUnion() {
1713             Log.d(TAG, "SERVER: newHandleTypeSafeUnion");
1714             return new HandleTypeSafeUnion();
1715         }
1716 
1717         @Override
setHandleA(HandleTypeSafeUnion safeUnion, NativeHandle a)1718         public HandleTypeSafeUnion setHandleA(HandleTypeSafeUnion safeUnion, NativeHandle a) {
1719             Log.d(TAG, "SERVER: setHandleA(" + a + ")");
1720             safeUnion.a(a);
1721 
1722             return safeUnion;
1723         }
1724 
1725         @Override
setHandleB(HandleTypeSafeUnion safeUnion, NativeHandle[] b)1726         public HandleTypeSafeUnion setHandleB(HandleTypeSafeUnion safeUnion, NativeHandle[] b) {
1727             Log.d(TAG, "SERVER: setHandleB(" + Arrays.toString(b) + ")");
1728             safeUnion.b(b);
1729 
1730             return safeUnion;
1731         }
1732 
1733         @Override
setHandleC(HandleTypeSafeUnion safeUnion, ArrayList<NativeHandle> c)1734         public HandleTypeSafeUnion setHandleC(HandleTypeSafeUnion safeUnion,
1735                                               ArrayList<NativeHandle> c) {
1736             Log.d(TAG, "SERVER: setHandleC(" + c + ")");
1737             safeUnion.c(c);
1738 
1739             return safeUnion;
1740         }
1741     }
1742 
server()1743     private void server() throws RemoteException {
1744         HwBinder.configureRpcThreadpool(1, true);
1745 
1746         Baz baz = new Baz();
1747         baz.registerAsService("default");
1748 
1749         try {
1750             IBaz.getService("default");
1751             throw new RuntimeException("Java in-process enabled");
1752         } catch (NoSuchElementException e) {
1753             // as expected
1754         }
1755 
1756         SafeUnion safeunionInterface = new SafeUnion();
1757         safeunionInterface.registerAsService("default");
1758 
1759         HwBinder.joinRpcThreadpool();
1760     }
1761 }
1762