Home | History | Annotate | Download | only in tests
      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 
     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 
     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 
     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 
    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 
    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 
    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", "Crdoba");
    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 
    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 
    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 
    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 
    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 
    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         final List<String> utf8_queries_and_nulls = Arrays.asList(
    635               "typical string",
    636               null,
    637               "",
    638               "\0\0\0",
    639               null,
    640               // Java doesn't handle unicode code points above U+FFFF well.
    641               new String(Character.toChars(0x1F701)) + "\u03A9");
    642         try {
    643             for (String query : utf8_queries) {
    644                 String response = service.RepeatUtf8CppString(query);
    645                 if (!query.equals(response)) {
    646                     mLog.logAndThrow("Repeat request with '" + query + "'" +
    647                                      " of length " + query.length() +
    648                                      " responded with '" + response + "'" +
    649                                      " of length " + response.length());
    650                 }
    651             }
    652             {
    653                 String[] input = (String[])utf8_queries.toArray();
    654                 String echoed[] = new String[input.length];
    655                 String[] reversed = service.ReverseUtf8CppString(input, echoed);
    656                 if (!Arrays.equals(input, echoed)) {
    657                     mLog.logAndThrow("Failed to echo utf8 input array back.");
    658                 }
    659                 if (input.length != reversed.length) {
    660                     mLog.logAndThrow("Reversed utf8 array is the wrong size.");
    661                 }
    662                 for (int i = 0; i < input.length; ++i) {
    663                     int j = reversed.length - (1 + i);
    664                     if (!input[i].equals(reversed[j])) {
    665                         mLog.logAndThrow(
    666                                 "input[" + i + "] = " + input[i] +
    667                                 " but reversed value = " + reversed[j]);
    668                     }
    669                 }
    670             }
    671             {
    672                 String[] input = (String[])utf8_queries_and_nulls.toArray();
    673                 String echoed[] = new String[input.length];
    674                 String[] reversed = service.ReverseNullableUtf8CppString(input,
    675                     echoed);
    676                 if (!Arrays.equals(input, echoed)) {
    677                     mLog.logAndThrow("Failed to echo utf8 input array back.");
    678                 }
    679                 if (input.length != reversed.length) {
    680                     mLog.logAndThrow("Reversed utf8 array is the wrong size.");
    681                 }
    682                 for (int i = 0; i < input.length; ++i) {
    683                     int j = reversed.length - (1 + i);
    684                     if (input[i] == null && reversed[j] == null) {
    685                         continue;
    686                     }
    687 
    688                     if (!input[i].equals(reversed[j])) {
    689                         mLog.logAndThrow(
    690                                 "input[" + i + "] = " + input[i] +
    691                                 " but reversed value = " + reversed[j]);
    692                     }
    693                 }
    694             }
    695         } catch (RemoteException ex) {
    696             mLog.log(ex.toString());
    697             mLog.logAndThrow("Service failed to handle utf8 strings.");
    698         }
    699         mLog.log("...UTF8 annotations work.");
    700     }
    701 
    702     @Override
    703     protected void onCreate(Bundle savedInstanceState) {
    704         super.onCreate(savedInstanceState);
    705         Log.i(TAG, "Starting!");
    706         try {
    707           init();
    708           ITestService service = getService();
    709           checkPrimitiveRepeat(service);
    710           checkArrayReversal(service);
    711           checkBinderExchange(service);
    712           checkListReversal(service);
    713           checkSimpleParcelables(service);
    714           checkPersistableBundles(service);
    715           checkFileDescriptorPassing(service);
    716           checkServiceSpecificExceptions(service);
    717           checkUtf8Strings(service);
    718           new NullableTests(service, mLog).runTests();
    719 
    720           mLog.log(mSuccessSentinel);
    721         } catch (TestFailException e) {
    722             mLog.log(mFailureSentinel);
    723             throw new RuntimeException(e);
    724         } finally {
    725             if (mLog != null) {
    726                 mLog.close();
    727             }
    728         }
    729     }
    730 }
    731