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