1 /* 2 * Copyright (C) 2018 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.binder.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotEquals; 22 import static org.junit.Assert.assertTrue; 23 24 import android.os.IBinder; 25 import android.os.ParcelFileDescriptor; 26 import android.os.Process; 27 import android.os.RemoteException; 28 import android.util.Log; 29 30 import androidx.test.InstrumentationRegistry; 31 32 import org.junit.Assert; 33 import org.junit.Before; 34 import org.junit.Test; 35 import org.junit.runner.RunWith; 36 import org.junit.runners.Parameterized; 37 38 import test_package.Bar; 39 import test_package.Foo; 40 import test_package.IEmpty; 41 import test_package.ITest; 42 import test_package.RegularPolygon; 43 44 import java.io.FileInputStream; 45 import java.io.FileOutputStream; 46 import java.io.IOException; 47 import java.util.Arrays; 48 import java.util.Collection; 49 50 @RunWith(Parameterized.class) 51 public class JavaClientTest { 52 private final String TAG = "JavaClientTest"; 53 54 private Class mServiceClass; 55 private ITest mInterface; 56 private String mExpectedName; 57 private boolean mShouldBeRemote; 58 JavaClientTest(Class serviceClass, String expectedName, boolean shouldBeRemote)59 public JavaClientTest(Class serviceClass, String expectedName, boolean shouldBeRemote) { 60 mServiceClass = serviceClass; 61 mExpectedName = expectedName; 62 mShouldBeRemote = shouldBeRemote; 63 } 64 65 @Parameterized.Parameters( name = "{0}" ) data()66 public static Collection<Object[]> data() { 67 // For local interfaces, this test will parcel the data locally. 68 // Whenever possible, the desired service should be accessed directly 69 // in order to avoid this additional overhead. 70 return Arrays.asList(new Object[][] { 71 {NativeService.Local.class, "CPP", false /*shouldBeRemote*/}, 72 {JavaService.Local.class, "JAVA", false /*shouldBeRemote*/}, 73 {NativeService.Remote.class, "CPP", true /*shouldBeRemote*/}, 74 {JavaService.Remote.class, "JAVA", true /*shouldBeRemote*/}, 75 }); 76 } 77 78 @Before setUp()79 public void setUp() { 80 Log.e(TAG, "Setting up"); 81 82 SyncTestServiceConnection connection = new SyncTestServiceConnection( 83 InstrumentationRegistry.getTargetContext(), mServiceClass); 84 85 mInterface = connection.get(); 86 assertNotEquals(null, mInterface); 87 } 88 89 @Test testSanityCheckSource()90 public void testSanityCheckSource() throws RemoteException { 91 String name = mInterface.GetName(); 92 93 Log.i(TAG, "Service GetName: " + name); 94 assertEquals(mExpectedName, name); 95 } 96 97 @Test testTrivial()98 public void testTrivial() throws RemoteException { 99 mInterface.TestVoidReturn(); 100 mInterface.TestOneway(); 101 } 102 checkDump(String expected, String[] args)103 private void checkDump(String expected, String[] args) throws RemoteException, IOException { 104 ParcelFileDescriptor[] sockets = ParcelFileDescriptor.createReliableSocketPair(); 105 ParcelFileDescriptor socketIn = sockets[0]; 106 ParcelFileDescriptor socketOut = sockets[1]; 107 108 mInterface.asBinder().dump(socketIn.getFileDescriptor(), args); 109 socketIn.close(); 110 111 FileInputStream fileInputStream = new ParcelFileDescriptor.AutoCloseInputStream(socketOut); 112 113 byte[] expectedBytes = expected.getBytes(); 114 byte[] input = new byte[expectedBytes.length]; 115 116 assertEquals(input.length, fileInputStream.read(input)); 117 Assert.assertArrayEquals(input, expectedBytes); 118 } 119 120 @Test testDump()121 public void testDump() throws RemoteException, IOException { 122 checkDump("", new String[]{}); 123 checkDump("", new String[]{"", ""}); 124 checkDump("Hello World!", new String[]{"Hello ", "World!"}); 125 checkDump("ABC", new String[]{"A", "B", "C"}); 126 } 127 128 @Test testCallingInfo()129 public void testCallingInfo() throws RemoteException { 130 mInterface.CacheCallingInfoFromOneway(); 131 132 assertEquals(Process.myPid(), mInterface.GiveMeMyCallingPid()); 133 assertEquals(Process.myUid(), mInterface.GiveMeMyCallingUid()); 134 135 if (mShouldBeRemote) { 136 // PID is hidden from oneway calls 137 assertEquals(0, mInterface.GiveMeMyCallingPidFromOneway()); 138 } else { 139 assertEquals(Process.myPid(), mInterface.GiveMeMyCallingPidFromOneway()); 140 } 141 142 assertEquals(Process.myUid(), mInterface.GiveMeMyCallingUidFromOneway()); 143 } 144 145 @Test testRepeatPrimitives()146 public void testRepeatPrimitives() throws RemoteException { 147 assertEquals(1, mInterface.RepeatInt(1)); 148 assertEquals(2, mInterface.RepeatLong(2)); 149 assertEquals(1.0f, mInterface.RepeatFloat(1.0f), 0.0f); 150 assertEquals(2.0, mInterface.RepeatDouble(2.0), 0.0); 151 assertEquals(true, mInterface.RepeatBoolean(true)); 152 assertEquals('a', mInterface.RepeatChar('a')); 153 assertEquals((byte)3, mInterface.RepeatByte((byte)3)); 154 } 155 156 @Test testRepeatBinder()157 public void testRepeatBinder() throws RemoteException { 158 IBinder binder = mInterface.asBinder(); 159 160 assertEquals(binder, mInterface.RepeatBinder(binder)); 161 assertEquals(binder, mInterface.RepeatNullableBinder(binder)); 162 assertEquals(null, mInterface.RepeatNullableBinder(null)); 163 } 164 165 private static class Empty extends IEmpty.Stub { 166 @Override getInterfaceVersion()167 public int getInterfaceVersion() { return Empty.VERSION; } 168 } 169 170 @Test testRepeatInterface()171 public void testRepeatInterface() throws RemoteException { 172 IEmpty empty = new Empty(); 173 174 assertEquals(empty, mInterface.RepeatInterface(empty)); 175 assertEquals(empty, mInterface.RepeatNullableInterface(empty)); 176 assertEquals(null, mInterface.RepeatNullableInterface(null)); 177 } 178 179 private static interface IRepeatFd { repeat(ParcelFileDescriptor fd)180 ParcelFileDescriptor repeat(ParcelFileDescriptor fd) throws RemoteException; 181 } 182 checkFdRepeated(IRepeatFd transformer)183 private void checkFdRepeated(IRepeatFd transformer) throws RemoteException, IOException { 184 ParcelFileDescriptor[] sockets = ParcelFileDescriptor.createReliableSocketPair(); 185 ParcelFileDescriptor socketIn = sockets[0]; 186 ParcelFileDescriptor socketOut = sockets[1]; 187 188 ParcelFileDescriptor repeatFd = transformer.repeat(socketIn); 189 190 boolean isNativeRemote = mInterface.GetName().equals("CPP"); 191 try { 192 socketOut.checkError(); 193 194 // Either native didn't properly call detach, or native properly handles detach, and 195 // we should change the test to enforce that socket comms work. 196 assertFalse("Native doesn't implement comm fd but did not get detach.", isNativeRemote); 197 } catch (ParcelFileDescriptor.FileDescriptorDetachedException e) { 198 assertTrue("Detach, so remote should be native", isNativeRemote); 199 } 200 201 // Both backends support these. 202 socketIn.checkError(); 203 repeatFd.checkError(); 204 205 FileOutputStream repeatFdStream = new ParcelFileDescriptor.AutoCloseOutputStream(repeatFd); 206 String testData = "asdf"; 207 byte[] output = testData.getBytes(); 208 repeatFdStream.write(output); 209 repeatFdStream.close(); 210 211 FileInputStream fileInputStream = new ParcelFileDescriptor.AutoCloseInputStream(socketOut); 212 byte[] input = new byte[output.length]; 213 214 assertEquals(input.length, fileInputStream.read(input)); 215 Assert.assertArrayEquals(input, output); 216 } 217 218 @Test testRepeatFd()219 public void testRepeatFd() throws RemoteException, IOException { 220 checkFdRepeated((fd) -> mInterface.RepeatFd(fd)); 221 } 222 223 @Test testRepeatNullableFd()224 public void testRepeatNullableFd() throws RemoteException, IOException { 225 checkFdRepeated((fd) -> mInterface.RepeatNullableFd(fd)); 226 assertEquals(null, mInterface.RepeatNullableFd(null)); 227 } 228 229 @Test testRepeatString()230 public void testRepeatString() throws RemoteException { 231 assertEquals("", mInterface.RepeatString("")); 232 assertEquals("a", mInterface.RepeatString("a")); 233 assertEquals("foo", mInterface.RepeatString("foo")); 234 } 235 236 @Test testRepeatNullableString()237 public void testRepeatNullableString() throws RemoteException { 238 assertEquals(null, mInterface.RepeatNullableString(null)); 239 assertEquals("", mInterface.RepeatNullableString("")); 240 assertEquals("a", mInterface.RepeatNullableString("a")); 241 assertEquals("foo", mInterface.RepeatNullableString("foo")); 242 } 243 assertPolygonEquals(RegularPolygon lhs, RegularPolygon rhs)244 public void assertPolygonEquals(RegularPolygon lhs, RegularPolygon rhs) { 245 assertEquals(lhs.name, rhs.name); 246 assertEquals(lhs.numSides, rhs.numSides); 247 assertEquals(lhs.sideLength, rhs.sideLength, 0.0f); 248 } assertPolygonEquals(RegularPolygon[] lhs, RegularPolygon[] rhs)249 public void assertPolygonEquals(RegularPolygon[] lhs, RegularPolygon[] rhs) { 250 assertEquals(lhs.length, rhs.length); 251 for (int i = 0; i < lhs.length; i++) { 252 assertPolygonEquals(lhs[i], rhs[i]); 253 } 254 } 255 256 @Test testRepeatPolygon()257 public void testRepeatPolygon() throws RemoteException { 258 RegularPolygon polygon = new RegularPolygon(); 259 polygon.name = "hexagon"; 260 polygon.numSides = 6; 261 polygon.sideLength = 1.0f; 262 263 RegularPolygon result = mInterface.RepeatPolygon(polygon); 264 265 assertPolygonEquals(polygon, result); 266 } 267 268 @Test testInsAndOuts()269 public void testInsAndOuts() throws RemoteException { 270 RegularPolygon polygon = new RegularPolygon(); 271 mInterface.RenamePolygon(polygon, "Jerry"); 272 assertEquals("Jerry", polygon.name); 273 } 274 275 @Test testArrays()276 public void testArrays() throws RemoteException { 277 { 278 boolean[] value = {}; 279 boolean[] out1 = new boolean[value.length]; 280 boolean[] out2 = mInterface.RepeatBooleanArray(value, out1); 281 282 Assert.assertArrayEquals(value, out1); 283 Assert.assertArrayEquals(value, out2); 284 } 285 { 286 boolean[] value = {false, true, false}; 287 boolean[] out1 = new boolean[value.length]; 288 boolean[] out2 = mInterface.RepeatBooleanArray(value, out1); 289 290 Assert.assertArrayEquals(value, out1); 291 Assert.assertArrayEquals(value, out2); 292 } 293 { 294 byte[] value = {1, 2, 3}; 295 byte[] out1 = new byte[value.length]; 296 byte[] out2 = mInterface.RepeatByteArray(value, out1); 297 298 Assert.assertArrayEquals(value, out1); 299 Assert.assertArrayEquals(value, out2); 300 } 301 { 302 char[] value = {'h', 'a', '!'}; 303 char[] out1 = new char[value.length]; 304 char[] out2 = mInterface.RepeatCharArray(value, out1); 305 306 Assert.assertArrayEquals(value, out1); 307 Assert.assertArrayEquals(value, out2); 308 } 309 { 310 int[] value = {1, 2, 3}; 311 int[] out1 = new int[value.length]; 312 int[] out2 = mInterface.RepeatIntArray(value, out1); 313 314 Assert.assertArrayEquals(value, out1); 315 Assert.assertArrayEquals(value, out2); 316 } 317 { 318 long[] value = {1, 2, 3}; 319 long[] out1 = new long[value.length]; 320 long[] out2 = mInterface.RepeatLongArray(value, out1); 321 322 Assert.assertArrayEquals(value, out1); 323 Assert.assertArrayEquals(value, out2); 324 } 325 { 326 float[] value = {1.0f, 2.0f, 3.0f}; 327 float[] out1 = new float[value.length]; 328 float[] out2 = mInterface.RepeatFloatArray(value, out1); 329 330 Assert.assertArrayEquals(value, out1, 0.0f); 331 Assert.assertArrayEquals(value, out2, 0.0f); 332 } 333 { 334 double[] value = {1.0, 2.0, 3.0}; 335 double[] out1 = new double[value.length]; 336 double[] out2 = mInterface.RepeatDoubleArray(value, out1); 337 338 Assert.assertArrayEquals(value, out1, 0.0); 339 Assert.assertArrayEquals(value, out2, 0.0); 340 } 341 { 342 String[] value = {"", "aoeu", "lol", "brb"}; 343 String[] out1 = new String[value.length]; 344 String[] out2 = mInterface.RepeatStringArray(value, out1); 345 346 Assert.assertArrayEquals(value, out1); 347 Assert.assertArrayEquals(value, out2); 348 } 349 { 350 351 RegularPolygon septagon = new RegularPolygon(); 352 septagon.name = "septagon"; 353 septagon.numSides = 7; 354 septagon.sideLength = 1.0f; 355 356 RegularPolygon[] value = {septagon, new RegularPolygon(), new RegularPolygon()}; 357 RegularPolygon[] out1 = new RegularPolygon[value.length]; 358 RegularPolygon[] out2 = mInterface.RepeatRegularPolygonArray(value, out1); 359 360 assertPolygonEquals(value, out1); 361 assertPolygonEquals(value, out2); 362 } 363 } 364 365 @Test testNullableArrays()366 public void testNullableArrays() throws RemoteException { 367 { 368 boolean[] emptyValue = {}; 369 boolean[] value = {false, true, false}; 370 Assert.assertArrayEquals(null, mInterface.RepeatNullableBooleanArray(null)); 371 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableBooleanArray(emptyValue)); 372 Assert.assertArrayEquals(value, mInterface.RepeatNullableBooleanArray(value)); 373 } 374 { 375 byte[] emptyValue = {}; 376 byte[] value = {1, 2, 3}; 377 Assert.assertArrayEquals(null, mInterface.RepeatNullableByteArray(null)); 378 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableByteArray(emptyValue)); 379 Assert.assertArrayEquals(value, mInterface.RepeatNullableByteArray(value)); 380 } 381 { 382 char[] emptyValue = {}; 383 char[] value = {'h', 'a', '!'}; 384 Assert.assertArrayEquals(null, mInterface.RepeatNullableCharArray(null)); 385 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableCharArray(emptyValue)); 386 Assert.assertArrayEquals(value, mInterface.RepeatNullableCharArray(value)); 387 } 388 { 389 int[] emptyValue = {}; 390 int[] value = {1, 2, 3}; 391 Assert.assertArrayEquals(null, mInterface.RepeatNullableIntArray(null)); 392 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableIntArray(emptyValue)); 393 Assert.assertArrayEquals(value, mInterface.RepeatNullableIntArray(value)); 394 } 395 { 396 long[] emptyValue = {}; 397 long[] value = {1, 2, 3}; 398 Assert.assertArrayEquals(null, mInterface.RepeatNullableLongArray(null)); 399 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableLongArray(emptyValue)); 400 Assert.assertArrayEquals(value, mInterface.RepeatNullableLongArray(value)); 401 } 402 { 403 float[] emptyValue = {}; 404 float[] value = {1.0f, 2.0f, 3.0f}; 405 Assert.assertArrayEquals(null, mInterface.RepeatNullableFloatArray(null), 0.0f); 406 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableFloatArray(emptyValue), 0.0f); 407 Assert.assertArrayEquals(value, mInterface.RepeatNullableFloatArray(value), 0.0f); 408 } 409 { 410 double[] emptyValue = {}; 411 double[] value = {1.0, 2.0, 3.0}; 412 Assert.assertArrayEquals(null, mInterface.RepeatNullableDoubleArray(null), 0.0); 413 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableDoubleArray(emptyValue), 0.0); 414 Assert.assertArrayEquals(value, mInterface.RepeatNullableDoubleArray(value), 0.0); 415 } 416 { 417 String[] emptyValue = {}; 418 String[] value = {"", "aoeu", null, "brb"}; 419 Assert.assertArrayEquals(null, mInterface.RepeatNullableStringArray(null)); 420 Assert.assertArrayEquals(emptyValue, mInterface.RepeatNullableStringArray(emptyValue)); 421 Assert.assertArrayEquals(value, mInterface.RepeatNullableStringArray(value)); 422 } 423 { 424 String[] emptyValue = {}; 425 String[] value = {"", "aoeu", null, "brb"}; 426 String[] out1 = new String[value.length]; 427 String[] out2 = mInterface.DoubleRepeatNullableStringArray(value, out1); 428 429 Assert.assertArrayEquals(value, out1); 430 Assert.assertArrayEquals(value, out2); 431 } 432 } 433 434 @Test testGetLastItem()435 public void testGetLastItem() throws RemoteException { 436 Foo foo = new Foo(); 437 foo.d = new Bar(); 438 foo.e = new Bar(); 439 foo.f = 15; 440 441 assertEquals(foo.f, mInterface.getF(foo)); 442 } 443 444 @Test testRepeatFoo()445 public void testRepeatFoo() throws RemoteException { 446 Foo foo = new Foo(); 447 448 foo.a = "NEW FOO"; 449 foo.b = 57; 450 451 foo.d = new Bar(); 452 foo.d.b = "a"; 453 454 foo.e = new Bar(); 455 foo.e.d = 99; 456 457 Foo repeatedFoo = mInterface.repeatFoo(foo); 458 459 assertEquals(foo.a, repeatedFoo.a); 460 assertEquals(foo.b, repeatedFoo.b); 461 assertEquals(foo.d.b, repeatedFoo.d.b); 462 assertEquals(foo.e.d, repeatedFoo.e.d); 463 } 464 465 @Test testRenameFoo()466 public void testRenameFoo() throws RemoteException { 467 Foo foo = new Foo(); 468 foo.d = new Bar(); 469 foo.e = new Bar(); 470 mInterface.renameFoo(foo, "MYFOO"); 471 assertEquals("MYFOO", foo.a); 472 } 473 @Test testRenameBar()474 public void testRenameBar() throws RemoteException { 475 Foo foo = new Foo(); 476 foo.d = new Bar(); 477 foo.e = new Bar(); 478 mInterface.renameBar(foo, "MYBAR"); 479 assertEquals("MYBAR", foo.d.a); 480 } 481 } 482