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