1 /* 2 * Copyright (C) 2015, 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 android.aidl.tests; 18 19 import android.aidl.tests.SimpleParcelable; 20 import android.aidl.tests.TestFailException; 21 import android.aidl.tests.TestLogger; 22 import android.app.Activity; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.os.ServiceSpecificException; 26 import android.os.Bundle; 27 import android.os.IBinder; 28 import android.os.PersistableBundle; 29 import android.os.RemoteException; 30 import android.os.ServiceManager; 31 import android.util.Log; 32 import java.io.File; 33 import java.io.FileDescriptor; 34 import java.io.FileInputStream; 35 import java.io.FileOutputStream; 36 import java.io.IOException; 37 import java.util.ArrayList; 38 import java.util.Arrays; 39 import java.util.Collections; 40 import java.util.List; 41 import java.util.Map; 42 import java.util.HashMap; 43 44 // Generated 45 import android.aidl.tests.INamedCallback; 46 import android.aidl.tests.ITestService; 47 48 public class TestServiceClient extends Activity { 49 private static final String TAG = "TestServiceClient"; 50 51 private TestLogger mLog; 52 private String mSuccessSentinel; 53 private String mFailureSentinel; 54 init()55 private void init() { 56 Intent intent = getIntent(); 57 mLog = new TestLogger(this); 58 mLog.log("Reading sentinels from intent..."); 59 mSuccessSentinel = intent.getStringExtra("sentinel.success"); 60 mFailureSentinel = intent.getStringExtra("sentinel.failure"); 61 if (mSuccessSentinel == null || mFailureSentinel == null) { 62 String message = "Failed to read intent extra input."; 63 Log.e(TAG, message); 64 mLog.close(); 65 throw new RuntimeException(message); 66 } 67 } 68 getService()69 private ITestService getService() throws TestFailException { 70 IBinder service = new ServiceManager().getService( 71 ITestService.class.getName()); 72 if (service == null) { 73 mLog.logAndThrow("Failed to obtain binder..."); 74 } 75 ITestService ret = ITestService.Stub.asInterface(service); 76 if (ret == null) { 77 mLog.logAndThrow("Failed to cast IBinder instance."); 78 } 79 return ret; 80 } 81 checkPrimitiveRepeat(ITestService service)82 private void checkPrimitiveRepeat(ITestService service) 83 throws TestFailException { 84 mLog.log("Checking that service can repeat primitives back..."); 85 try { 86 { 87 boolean query = true; 88 boolean response = service.RepeatBoolean(query); 89 if (query != response) { 90 mLog.logAndThrow("Repeat with " + query + 91 " responded " + response); 92 } 93 } 94 { 95 char query = 'A'; 96 char response = service.RepeatChar(query); 97 if (query != response) { 98 mLog.logAndThrow("Repeat with " + query + 99 " responded " + response); 100 } 101 } 102 { 103 byte query = -128; 104 byte response = service.RepeatByte(query); 105 if (query != response) { 106 mLog.logAndThrow("Repeat with " + query + 107 " responded " + response); 108 } 109 } 110 { 111 int query = 1 << 30; 112 int response = service.RepeatInt(query); 113 if (query != response) { 114 mLog.logAndThrow("Repeat with " + query + 115 " responded " + response); 116 } 117 } 118 { 119 int query[] = {ITestService.TEST_CONSTANT, 120 ITestService.TEST_CONSTANT2, 121 ITestService.TEST_CONSTANT3, 122 ITestService.TEST_CONSTANT4, 123 ITestService.TEST_CONSTANT5, 124 ITestService.TEST_CONSTANT6, 125 ITestService.TEST_CONSTANT7, 126 ITestService.TEST_CONSTANT8}; 127 for (int i = 0; i < query.length; i++) { 128 int response = service.RepeatInt(query[i]); 129 if (query[i] != response) { 130 mLog.logAndThrow("Repeat with " + query[i] + 131 " responded " + response); 132 } 133 } 134 } 135 { 136 long query = 1L << 60; 137 long response = service.RepeatLong(query); 138 if (query != response) { 139 mLog.logAndThrow("Repeat with " + query + 140 " responded " + response); 141 } 142 } 143 { 144 float query = 1.0f/3.0f; 145 float response = service.RepeatFloat(query); 146 if (query != response) { 147 mLog.logAndThrow("Repeat with " + query + 148 " responded " + response); 149 } 150 } 151 { 152 double query = 1.0/3.0; 153 double response = service.RepeatDouble(query); 154 if (query != response) { 155 mLog.logAndThrow("Repeat with " + query + 156 " responded " + response); 157 } 158 } 159 { 160 Map<String, Object> query = new HashMap<String, Object>(); 161 query.put("first_val", new Byte((byte)-128)); 162 query.put("second_val", new Integer(1<<30)); 163 query.put("third_val", "OHAI"); 164 Object response = service.RepeatMap(query); 165 if (!query.equals(response)) { 166 mLog.logAndThrow("Repeat with " + query + 167 " responded " + response); 168 } 169 } 170 171 List<String> queries = Arrays.asList( 172 "not empty", "", "\0", 173 ITestService.STRING_TEST_CONSTANT, 174 ITestService.STRING_TEST_CONSTANT2); 175 for (String query : queries) { 176 String response = service.RepeatString(query); 177 if (!query.equals(response)) { 178 mLog.logAndThrow("Repeat request with '" + query + "'" + 179 " of length " + query.length() + 180 " responded with '" + response + "'" + 181 " of length " + response.length()); 182 } 183 } 184 } catch (RemoteException ex) { 185 mLog.log(ex.toString()); 186 mLog.logAndThrow("Service failed to repeat a primitive back."); 187 } 188 mLog.log("...Basic primitive repeating works."); 189 } 190 checkArrayReversal(ITestService service)191 private void checkArrayReversal(ITestService service) 192 throws TestFailException { 193 mLog.log("Checking that service can reverse and return arrays..."); 194 try { 195 { 196 boolean[] input = {true, false, false, false}; 197 boolean echoed[] = new boolean[input.length]; 198 boolean[] reversed = service.ReverseBoolean(input, echoed); 199 if (!Arrays.equals(input, echoed)) { 200 mLog.logAndThrow("Failed to echo input array back."); 201 } 202 if (input.length != reversed.length) { 203 mLog.logAndThrow("Reversed array is the wrong size."); 204 } 205 for (int i = 0; i < input.length; ++i) { 206 int j = reversed.length - (1 + i); 207 if (input[i] != reversed[j]) { 208 mLog.logAndThrow( 209 "input[" + i + "] = " + input[i] + 210 " but reversed value = " + reversed[j]); 211 } 212 } 213 } 214 { 215 byte[] input = {0, 1, 2}; 216 byte echoed[] = new byte[input.length]; 217 byte[] reversed = service.ReverseByte(input, echoed); 218 if (!Arrays.equals(input, echoed)) { 219 mLog.logAndThrow("Failed to echo input array back."); 220 } 221 if (input.length != reversed.length) { 222 mLog.logAndThrow("Reversed array is the wrong size."); 223 } 224 for (int i = 0; i < input.length; ++i) { 225 int j = reversed.length - (1 + i); 226 if (input[i] != reversed[j]) { 227 mLog.logAndThrow( 228 "input[" + i + "] = " + input[i] + 229 " but reversed value = " + reversed[j]); 230 } 231 } 232 } 233 { 234 char[] input = {'A', 'B', 'C', 'D', 'E'}; 235 char echoed[] = new char[input.length]; 236 char[] reversed = service.ReverseChar(input, echoed); 237 if (!Arrays.equals(input, echoed)) { 238 mLog.logAndThrow("Failed to echo input array back."); 239 } 240 if (input.length != reversed.length) { 241 mLog.logAndThrow("Reversed array is the wrong size."); 242 } 243 for (int i = 0; i < input.length; ++i) { 244 int j = reversed.length - (1 + i); 245 if (input[i] != reversed[j]) { 246 mLog.logAndThrow( 247 "input[" + i + "] = " + input[i] + 248 " but reversed value = " + reversed[j]); 249 } 250 } 251 } 252 { 253 int[] input = {-1, 0, 1, 2, 3, 4, 5, 6}; 254 int echoed[] = new int[input.length]; 255 int[] reversed = service.ReverseInt(input, echoed); 256 if (!Arrays.equals(input, echoed)) { 257 mLog.logAndThrow("Failed to echo input array back."); 258 } 259 if (input.length != reversed.length) { 260 mLog.logAndThrow("Reversed array is the wrong size."); 261 } 262 for (int i = 0; i < input.length; ++i) { 263 int j = reversed.length - (1 + i); 264 if (input[i] != reversed[j]) { 265 mLog.logAndThrow( 266 "input[" + i + "] = " + input[i] + 267 " but reversed value = " + reversed[j]); 268 } 269 } 270 } 271 { 272 long[] input = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8}; 273 long echoed[] = new long[input.length]; 274 long[] reversed = service.ReverseLong(input, echoed); 275 if (!Arrays.equals(input, echoed)) { 276 mLog.logAndThrow("Failed to echo input array back."); 277 } 278 if (input.length != reversed.length) { 279 mLog.logAndThrow("Reversed array is the wrong size."); 280 } 281 for (int i = 0; i < input.length; ++i) { 282 int j = reversed.length - (1 + i); 283 if (input[i] != reversed[j]) { 284 mLog.logAndThrow( 285 "input[" + i + "] = " + input[i] + 286 " but reversed value = " + reversed[j]); 287 } 288 } 289 } 290 { 291 float[] input = {0.0f, 1.0f, -0.3f}; 292 float echoed[] = new float[input.length]; 293 float[] reversed = service.ReverseFloat(input, echoed); 294 if (!Arrays.equals(input, echoed)) { 295 mLog.logAndThrow("Failed to echo input array back."); 296 } 297 if (input.length != reversed.length) { 298 mLog.logAndThrow("Reversed array is the wrong size."); 299 } 300 for (int i = 0; i < input.length; ++i) { 301 int j = reversed.length - (1 + i); 302 if (input[i] != reversed[j]) { 303 mLog.logAndThrow( 304 "input[" + i + "] = " + input[i] + 305 " but reversed value = " + reversed[j]); 306 } 307 } 308 } 309 { 310 double[] input = {-1.0, -4.0, -2.0}; 311 double echoed[] = new double[input.length]; 312 double[] reversed = service.ReverseDouble(input, echoed); 313 if (!Arrays.equals(input, echoed)) { 314 mLog.logAndThrow("Failed to echo input array back."); 315 } 316 if (input.length != reversed.length) { 317 mLog.logAndThrow("Reversed array is the wrong size."); 318 } 319 for (int i = 0; i < input.length; ++i) { 320 int j = reversed.length - (1 + i); 321 if (input[i] != reversed[j]) { 322 mLog.logAndThrow( 323 "input[" + i + "] = " + input[i] + 324 " but reversed value = " + reversed[j]); 325 } 326 } 327 } 328 { 329 String[] input = {"For", "relaxing", "times"}; 330 String echoed[] = new String[input.length]; 331 String[] reversed = service.ReverseString(input, echoed); 332 if (!Arrays.equals(input, echoed)) { 333 mLog.logAndThrow("Failed to echo input array back."); 334 } 335 if (input.length != reversed.length) { 336 mLog.logAndThrow("Reversed array is the wrong size."); 337 } 338 for (int i = 0; i < input.length; ++i) { 339 int j = reversed.length - (1 + i); 340 if (!input[i].equals(reversed[j])) { 341 mLog.logAndThrow( 342 "input[" + i + "] = " + input[i] + 343 " but reversed value = " + reversed[j]); 344 } 345 } 346 } 347 } catch (RemoteException ex) { 348 mLog.log(ex.toString()); 349 mLog.logAndThrow("Service failed to reverse an array."); 350 } 351 mLog.log("...service can reverse and return arrays."); 352 } 353 checkBinderExchange( ITestService service)354 private void checkBinderExchange( 355 ITestService service) throws TestFailException { 356 mLog.log("Checking exchange of binders..."); 357 try { 358 INamedCallback got = service.GetOtherTestService("Smythe"); 359 mLog.log("Received test service"); 360 String name = got.GetName(); 361 362 if (!name.equals("Smythe")) { 363 mLog.logAndThrow("Tried to get service with name 'Smythe'" + 364 " and found service with name '" + name + "'"); 365 } 366 367 if (!service.VerifyName(got, "Smythe")) { 368 mLog.logAndThrow("Test service could not verify name of 'Smythe'"); 369 } 370 } catch (RemoteException ex) { 371 mLog.log(ex.toString()); 372 mLog.logAndThrow("Service failed to exchange binders."); 373 } 374 mLog.log("...Exchange of binders works"); 375 } 376 checkListReversal(ITestService service)377 private void checkListReversal(ITestService service) 378 throws TestFailException { 379 mLog.log("Checking that service can reverse and return lists..."); 380 try { 381 { 382 List<String> input = Arrays.asList("Walk", "into", "Córdoba"); 383 List<String> echoed = new ArrayList<String>(); 384 List<String> reversed = service.ReverseStringList(input, echoed); 385 if (!input.equals(echoed)) { 386 mLog.logAndThrow("Failed to echo input List<String> back."); 387 } 388 Collections.reverse(input); 389 if (!input.equals(reversed)) { 390 mLog.logAndThrow("Reversed list is not correct."); 391 } 392 } 393 } catch (RemoteException ex) { 394 mLog.log(ex.toString()); 395 mLog.logAndThrow("Service failed to reverse an List<String>."); 396 } 397 mLog.log("...service can reverse and return lists."); 398 } 399 checkSimpleParcelables(ITestService service)400 private void checkSimpleParcelables(ITestService service) 401 throws TestFailException { 402 mLog.log("Checking that service can repeat and reverse SimpleParcelable objects..."); 403 try { 404 { 405 SimpleParcelable input = new SimpleParcelable("foo", 42); 406 SimpleParcelable out_param = new SimpleParcelable(); 407 SimpleParcelable returned = 408 service.RepeatSimpleParcelable(input, out_param); 409 if (!input.equals(out_param)) { 410 mLog.log(input.toString() + " != " + out_param.toString()); 411 mLog.logAndThrow("out param SimpleParcelable was not equivalent"); 412 } 413 if (!input.equals(returned)) { 414 mLog.log(input.toString() + " != " + returned.toString()); 415 mLog.logAndThrow("returned SimpleParcelable was not equivalent"); 416 } 417 } 418 { 419 SimpleParcelable[] input = new SimpleParcelable[3]; 420 input[0] = new SimpleParcelable("a", 1); 421 input[1] = new SimpleParcelable("b", 2); 422 input[2] = new SimpleParcelable("c", 3); 423 SimpleParcelable[] repeated = new SimpleParcelable[3]; 424 SimpleParcelable[] reversed = service.ReverseSimpleParcelables( 425 input, repeated); 426 if (!Arrays.equals(input, repeated)) { 427 mLog.logAndThrow( 428 "Repeated list of SimpleParcelable objects did not match."); 429 } 430 if (input.length != reversed.length) { 431 mLog.logAndThrow( 432 "Reversed list of SimpleParcelable objects had wrong length."); 433 } 434 for (int i = 0, k = input.length - 1; 435 i < input.length; 436 ++i, --k) { 437 if (!input[i].equals(reversed[k])) { 438 mLog.log(input[i].toString() + " != " + 439 reversed[k].toString()); 440 mLog.logAndThrow("reversed SimpleParcelable was not equivalent"); 441 } 442 } 443 } 444 } catch (Exception ex) { 445 mLog.log(ex.toString()); 446 mLog.logAndThrow("Service failed to handle SimpleParcelable objects."); 447 } 448 mLog.log("...service can manipulate SimpleParcelable objects."); 449 } 450 checkPersistableBundles(ITestService service)451 private void checkPersistableBundles(ITestService service) 452 throws TestFailException { 453 mLog.log("Checking that service can repeat and reverse PersistableBundle objects..."); 454 try { 455 { 456 PersistableBundle emptyBundle = new PersistableBundle(); 457 PersistableBundle returned = service.RepeatPersistableBundle(emptyBundle); 458 if (emptyBundle.size() != 0 || returned.size() != 0) { 459 mLog.log(emptyBundle.toString() + " != " + returned.toString()); 460 mLog.logAndThrow("returned empty PersistableBundle object was not equivalent"); 461 } 462 mLog.log("...service can repeat and reverse empty PersistableBundle objects..."); 463 } 464 { 465 final String testBoolKey = new String("testBool"); 466 final String testIntKey = new String("testInt"); 467 final String testNestedIntKey = new String("testNestedInt"); 468 final String testLongKey = new String("testLong"); 469 final String testDoubleKey = new String("testDouble"); 470 final String testStringKey = new String("testString"); 471 final String testBoolArrayKey = new String("testBoolArray"); 472 final String testIntArrayKey = new String("testIntArray"); 473 final String testLongArrayKey = new String("testLongArray"); 474 final String testDoubleArrayKey = new String("testDoubleArray"); 475 final String testStringArrayKey = new String("testStringArray"); 476 final String testPersistableBundleKey = new String("testPersistableBundle"); 477 PersistableBundle nonEmptyBundle = new PersistableBundle(); 478 nonEmptyBundle.putBoolean(testBoolKey, false); 479 nonEmptyBundle.putInt(testIntKey, 33); 480 nonEmptyBundle.putLong(testLongKey, 34359738368L); 481 nonEmptyBundle.putDouble(testDoubleKey, 1.1); 482 nonEmptyBundle.putString(testStringKey, new String("Woot!")); 483 nonEmptyBundle.putBooleanArray(testBoolArrayKey, new boolean[] {true, false, true}); 484 nonEmptyBundle.putIntArray(testIntArrayKey, new int[] {33, 44, 55, 142}); 485 nonEmptyBundle.putLongArray( 486 testLongArrayKey, new long[] {34L, 8371L, 34359738375L}); 487 nonEmptyBundle.putDoubleArray(testDoubleArrayKey, new double[] {2.2, 5.4}); 488 nonEmptyBundle.putStringArray(testStringArrayKey, new String[] {"hello", "world!"}); 489 PersistableBundle testNestedPersistableBundle = new PersistableBundle(); 490 testNestedPersistableBundle.putInt(testNestedIntKey, 345); 491 nonEmptyBundle.putPersistableBundle( 492 testPersistableBundleKey, testNestedPersistableBundle); 493 PersistableBundle returned = service.RepeatPersistableBundle(nonEmptyBundle); 494 if (returned.size() != nonEmptyBundle.size() 495 || returned.getBoolean(testBoolKey) != nonEmptyBundle.getBoolean(testBoolKey) 496 || returned.getInt(testIntKey) != nonEmptyBundle.getInt(testIntKey) 497 || returned.getLong(testLongKey) != nonEmptyBundle.getLong(testLongKey) 498 || returned.getDouble(testDoubleKey) != nonEmptyBundle.getDouble(testDoubleKey) 499 || !returned.getString(testStringKey) 500 .equals(nonEmptyBundle.getString(testStringKey)) 501 || !Arrays.equals(nonEmptyBundle.getBooleanArray(testBoolArrayKey), 502 returned.getBooleanArray(testBoolArrayKey)) 503 || !Arrays.equals(nonEmptyBundle.getIntArray(testIntArrayKey), 504 returned.getIntArray(testIntArrayKey)) 505 || !Arrays.equals(nonEmptyBundle.getLongArray(testLongArrayKey), 506 returned.getLongArray(testLongArrayKey)) 507 || !Arrays.equals(nonEmptyBundle.getDoubleArray(testDoubleArrayKey), 508 returned.getDoubleArray(testDoubleArrayKey)) 509 || !Arrays.equals(nonEmptyBundle.getStringArray(testStringArrayKey), 510 returned.getStringArray(testStringArrayKey))) { 511 PersistableBundle temp = 512 returned.getPersistableBundle(testPersistableBundleKey); 513 if (temp == null 514 || temp.getInt(testNestedIntKey) 515 != testNestedPersistableBundle.getInt(testNestedIntKey)) { 516 mLog.log(nonEmptyBundle.toString() + " != " + returned.toString()); 517 mLog.logAndThrow("returned non-empty PersistableBundle " + 518 "object was not equivalent"); 519 } 520 } 521 mLog.log("...service can repeat and reverse non-empty " + 522 "PersistableBundle objects..."); 523 } 524 { 525 PersistableBundle[] input = new PersistableBundle[3]; 526 PersistableBundle first = new PersistableBundle(); 527 PersistableBundle second = new PersistableBundle(); 528 PersistableBundle third = new PersistableBundle(); 529 final String testIntKey = new String("testInt"); 530 final String testLongKey = new String("testLong"); 531 final String testDoubleKey = new String("testDouble"); 532 first.putInt(testIntKey, 1231); 533 second.putLong(testLongKey, 222222L); 534 third.putDouble(testDoubleKey, 10.8); 535 input[0] = first; 536 input[1] = second; 537 input[2] = third; 538 final int original_input_size = input.length; 539 PersistableBundle[] repeated = new PersistableBundle[input.length]; 540 PersistableBundle[] reversed = service.ReversePersistableBundles(input, repeated); 541 if (input.length != repeated.length || input.length != original_input_size) { 542 mLog.logAndThrow("Repeated list of PersistableBundle objects had " + 543 "wrong length."); 544 } 545 if (input[0].getInt(testIntKey) != repeated[0].getInt(testIntKey) 546 || input[1].getLong(testLongKey) != repeated[1].getLong(testLongKey) 547 || input[2].getDouble(testDoubleKey) != repeated[2].getDouble(testDoubleKey)) { 548 mLog.logAndThrow("Repeated list of PersistableBundle objects did not match."); 549 } 550 if (input.length != reversed.length || input.length != original_input_size) { 551 mLog.logAndThrow("Reversed list of PersistableBundle objects had " + 552 "wrong length."); 553 } 554 if (input[0].getInt(testIntKey) != reversed[2].getInt(testIntKey) 555 || input[1].getLong(testLongKey) != reversed[1].getLong(testLongKey) 556 || input[2].getDouble(testDoubleKey) != reversed[0].getDouble(testDoubleKey)) { 557 mLog.logAndThrow("reversed PersistableBundle objects were not equivalent"); 558 } 559 mLog.log("...service can repeat and reverse arrays of " + 560 "non-empty PersistableBundle objects..."); 561 } 562 } catch (Exception ex) { 563 mLog.log(ex.toString()); 564 mLog.logAndThrow("Service failed to handle PersistableBundle objects."); 565 } 566 mLog.log("...service can manipulate PersistableBundle objects."); 567 } 568 checkFileDescriptorPassing(ITestService service)569 private void checkFileDescriptorPassing(ITestService service) 570 throws TestFailException { 571 mLog.log("Checking that service can receive and return file descriptors..."); 572 try { 573 FileOutputStream fileOutputStream = 574 openFileOutput("test-dummy", Context.MODE_PRIVATE); 575 576 FileDescriptor descriptor = fileOutputStream.getFD(); 577 FileDescriptor journeyed = service.RepeatFileDescriptor(descriptor); 578 fileOutputStream.close(); 579 580 FileOutputStream journeyedStream = new FileOutputStream(journeyed); 581 582 String testData = "FrazzleSnazzleFlimFlamFlibbityGumboChops"; 583 byte[] output = testData.getBytes(); 584 journeyedStream.write(output); 585 journeyedStream.close(); 586 587 FileInputStream fileInputStream = openFileInput("test-dummy"); 588 byte[] input = new byte[output.length]; 589 if (fileInputStream.read(input) != input.length) { 590 mLog.logAndThrow("Read short count from file"); 591 } 592 593 if (!Arrays.equals(input, output)) { 594 mLog.logAndThrow("Read incorrect data"); 595 } 596 } catch (RemoteException ex) { 597 mLog.log(ex.toString()); 598 mLog.logAndThrow("Service failed to repeat a file descriptor."); 599 } catch (IOException ex) { 600 mLog.log(ex.toString()); 601 mLog.logAndThrow("Exception while operating on temporary file"); 602 } 603 mLog.log("...service can receive and return file descriptors."); 604 } 605 checkServiceSpecificExceptions( ITestService service)606 private void checkServiceSpecificExceptions( 607 ITestService service) throws TestFailException { 608 mLog.log("Checking application exceptions..."); 609 for (int i = -1; i < 2; ++i) { 610 try { 611 service.ThrowServiceException(i); 612 } catch (RemoteException ex) { 613 mLog.logAndThrow("Service threw RemoteException: " + 614 ex.toString()); 615 } catch (ServiceSpecificException ex) { 616 if (ex.errorCode != i) { 617 mLog.logAndThrow("Service threw wrong error code: " + i); 618 } 619 } 620 } 621 mLog.log("...application exceptions work"); 622 } 623 checkUtf8Strings(ITestService service)624 private void checkUtf8Strings(ITestService service) 625 throws TestFailException { 626 mLog.log("Checking that service can work with UTF8 strings..."); 627 // Note that Java's underlying encoding is UTF16. 628 final List<String> utf8_queries = Arrays.asList( 629 "typical string", 630 "", 631 "\0\0\0", 632 // Java doesn't handle unicode code points above U+FFFF well. 633 new String(Character.toChars(0x1F701)) + "\u03A9"); 634 try { 635 for (String query : utf8_queries) { 636 String response = service.RepeatUtf8CppString(query); 637 if (!query.equals(response)) { 638 mLog.logAndThrow("Repeat request with '" + query + "'" + 639 " of length " + query.length() + 640 " responded with '" + response + "'" + 641 " of length " + response.length()); 642 } 643 } 644 { 645 String[] input = (String[])utf8_queries.toArray(); 646 String echoed[] = new String[input.length]; 647 String[] reversed = service.ReverseUtf8CppString(input, echoed); 648 if (!Arrays.equals(input, echoed)) { 649 mLog.logAndThrow("Failed to echo utf8 input array back."); 650 } 651 if (input.length != reversed.length) { 652 mLog.logAndThrow("Reversed utf8 array is the wrong size."); 653 } 654 for (int i = 0; i < input.length; ++i) { 655 int j = reversed.length - (1 + i); 656 if (!input[i].equals(reversed[j])) { 657 mLog.logAndThrow( 658 "input[" + i + "] = " + input[i] + 659 " but reversed value = " + reversed[j]); 660 } 661 } 662 } 663 } catch (RemoteException ex) { 664 mLog.log(ex.toString()); 665 mLog.logAndThrow("Service failed to handle utf8 strings."); 666 } 667 mLog.log("...UTF8 annotations work."); 668 } 669 670 @Override onCreate(Bundle savedInstanceState)671 protected void onCreate(Bundle savedInstanceState) { 672 super.onCreate(savedInstanceState); 673 Log.i(TAG, "Starting!"); 674 try { 675 init(); 676 ITestService service = getService(); 677 checkPrimitiveRepeat(service); 678 checkArrayReversal(service); 679 checkBinderExchange(service); 680 checkListReversal(service); 681 checkSimpleParcelables(service); 682 checkPersistableBundles(service); 683 checkFileDescriptorPassing(service); 684 checkServiceSpecificExceptions(service); 685 checkUtf8Strings(service); 686 new NullableTests(service, mLog).runTests(); 687 688 mLog.log(mSuccessSentinel); 689 } catch (TestFailException e) { 690 mLog.log(mFailureSentinel); 691 throw new RuntimeException(e); 692 } finally { 693 if (mLog != null) { 694 mLog.close(); 695 } 696 } 697 } 698 } 699