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.server.wifi.aware; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyBoolean; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.anyString; 25 import static org.mockito.ArgumentMatchers.eq; 26 import static org.mockito.Mockito.doNothing; 27 import static org.mockito.Mockito.doThrow; 28 import static org.mockito.Mockito.inOrder; 29 import static org.mockito.Mockito.mock; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.Manifest; 34 import android.app.AppOpsManager; 35 import android.content.Context; 36 import android.content.pm.PackageManager; 37 import android.net.wifi.aware.Characteristics; 38 import android.net.wifi.aware.ConfigRequest; 39 import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback; 40 import android.net.wifi.aware.IWifiAwareEventCallback; 41 import android.net.wifi.aware.IWifiAwareMacAddressProvider; 42 import android.net.wifi.aware.PublishConfig; 43 import android.net.wifi.aware.SubscribeConfig; 44 import android.os.HandlerThread; 45 import android.os.IBinder; 46 import android.os.RemoteException; 47 import android.os.test.TestLooper; 48 import android.util.SparseArray; 49 import android.util.SparseIntArray; 50 51 import androidx.test.filters.SmallTest; 52 53 import com.android.server.wifi.FrameworkFacade; 54 import com.android.server.wifi.util.WifiPermissionsUtil; 55 import com.android.server.wifi.util.WifiPermissionsWrapper; 56 57 import org.junit.Before; 58 import org.junit.Test; 59 import org.mockito.ArgumentCaptor; 60 import org.mockito.InOrder; 61 import org.mockito.Mock; 62 import org.mockito.MockitoAnnotations; 63 64 import java.lang.reflect.Field; 65 import java.util.ArrayList; 66 import java.util.List; 67 import java.util.Map; 68 69 70 /** 71 * Unit test harness for WifiAwareStateManager. 72 */ 73 @SmallTest 74 public class WifiAwareServiceImplTest { 75 private static final int MAX_LENGTH = 255; 76 77 private WifiAwareServiceImplSpy mDut; 78 private int mDefaultUid = 1500; 79 private String mPackageName = "some.package"; 80 private TestLooper mMockLooper; 81 82 @Mock 83 private Context mContextMock; 84 @Mock 85 private HandlerThread mHandlerThreadMock; 86 @Mock 87 private PackageManager mPackageManagerMock; 88 @Mock 89 private WifiAwareStateManager mAwareStateManagerMock; 90 @Mock 91 private WifiAwareShellCommand mWifiAwareShellCommandMock; 92 @Mock 93 private IBinder mBinderMock; 94 @Mock 95 private IWifiAwareEventCallback mCallbackMock; 96 @Mock 97 private IWifiAwareDiscoverySessionCallback mSessionCallbackMock; 98 @Mock private WifiAwareMetrics mAwareMetricsMock; 99 @Mock private WifiPermissionsUtil mWifiPermissionsUtil; 100 @Mock private WifiPermissionsWrapper mPermissionsWrapperMock; 101 @Mock 102 FrameworkFacade mFrameworkFacade; 103 104 /** 105 * Using instead of spy to avoid native crash failures - possibly due to 106 * spy's copying of state. 107 */ 108 private class WifiAwareServiceImplSpy extends WifiAwareServiceImpl { 109 public int fakeUid; 110 WifiAwareServiceImplSpy(Context context)111 WifiAwareServiceImplSpy(Context context) { 112 super(context); 113 } 114 115 /** 116 * Return the fake UID instead of the real one: pseudo-spy 117 * implementation. 118 */ 119 @Override getMockableCallingUid()120 public int getMockableCallingUid() { 121 return fakeUid; 122 } 123 } 124 125 /** 126 * Initializes mocks. 127 */ 128 @Before setup()129 public void setup() throws Exception { 130 MockitoAnnotations.initMocks(this); 131 mMockLooper = new TestLooper(); 132 133 when(mHandlerThreadMock.getLooper()).thenReturn(mMockLooper.getLooper()); 134 doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContextMock), any(), 135 anyBoolean(), any()); 136 137 AppOpsManager appOpsMock = mock(AppOpsManager.class); 138 when(mContextMock.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(appOpsMock); 139 140 when(mContextMock.getApplicationContext()).thenReturn(mContextMock); 141 when(mContextMock.getPackageManager()).thenReturn(mPackageManagerMock); 142 when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)) 143 .thenReturn(true); 144 when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)) 145 .thenReturn(true); 146 when(mAwareStateManagerMock.getCharacteristics()).thenReturn(getCharacteristics()); 147 148 mDut = new WifiAwareServiceImplSpy(mContextMock); 149 mDut.fakeUid = mDefaultUid; 150 mDut.start(mHandlerThreadMock, mAwareStateManagerMock, mWifiAwareShellCommandMock, 151 mAwareMetricsMock, mWifiPermissionsUtil, mPermissionsWrapperMock, mFrameworkFacade, 152 mock(WifiAwareNativeManager.class), mock(WifiAwareNativeApi.class), 153 mock(WifiAwareNativeCallback.class)); 154 verify(mAwareStateManagerMock).start(eq(mContextMock), any(), eq(mAwareMetricsMock), 155 eq(mWifiPermissionsUtil), eq(mPermissionsWrapperMock), any()); 156 } 157 158 /** 159 * Validate isUsageEnabled() function 160 */ 161 @Test testIsUsageEnabled()162 public void testIsUsageEnabled() { 163 mDut.isUsageEnabled(); 164 165 verify(mAwareStateManagerMock).isUsageEnabled(); 166 } 167 168 169 /** 170 * Validate connect() - returns and uses a client ID. 171 */ 172 @Test testConnect()173 public void testConnect() { 174 doConnect(); 175 } 176 177 /** 178 * Validate connect() when a non-null config is passed. 179 */ 180 @Test testConnectWithConfig()181 public void testConnectWithConfig() { 182 ConfigRequest configRequest = new ConfigRequest.Builder().setMasterPreference(55).build(); 183 String callingPackage = "com.google.somePackage"; 184 185 mDut.connect(mBinderMock, callingPackage, mCallbackMock, 186 configRequest, false); 187 188 verify(mAwareStateManagerMock).connect(anyInt(), anyInt(), anyInt(), 189 eq(callingPackage), eq(mCallbackMock), eq(configRequest), eq(false)); 190 } 191 192 /** 193 * Validate disconnect() - correct pass-through args. 194 * 195 * @throws Exception 196 */ 197 @Test testDisconnect()198 public void testDisconnect() throws Exception { 199 int clientId = doConnect(); 200 201 mDut.disconnect(clientId, mBinderMock); 202 203 verify(mAwareStateManagerMock).disconnect(clientId); 204 validateInternalStateCleanedUp(clientId); 205 } 206 207 /** 208 * Validate that security exception thrown when attempting operation using 209 * an invalid client ID. 210 */ 211 @Test(expected = SecurityException.class) testFailOnInvalidClientId()212 public void testFailOnInvalidClientId() { 213 mDut.disconnect(-1, mBinderMock); 214 } 215 216 /** 217 * Validate that security exception thrown when attempting operation using a 218 * client ID which was already cleared-up. 219 */ 220 @Test(expected = SecurityException.class) testFailOnClearedUpClientId()221 public void testFailOnClearedUpClientId() throws Exception { 222 int clientId = doConnect(); 223 224 mDut.disconnect(clientId, mBinderMock); 225 226 verify(mAwareStateManagerMock).disconnect(clientId); 227 validateInternalStateCleanedUp(clientId); 228 229 mDut.disconnect(clientId, mBinderMock); 230 } 231 232 /** 233 * Validate that trying to use a client ID from a UID which is different 234 * from the one that created it fails - and that the internal state is not 235 * modified so that a valid call (from the correct UID) will subsequently 236 * succeed. 237 */ 238 @Test testFailOnAccessClientIdFromWrongUid()239 public void testFailOnAccessClientIdFromWrongUid() throws Exception { 240 int clientId = doConnect(); 241 242 mDut.fakeUid = mDefaultUid + 1; 243 244 /* 245 * Not using thrown.expect(...) since want to test that subsequent 246 * access works. 247 */ 248 boolean failsAsExpected = false; 249 try { 250 mDut.disconnect(clientId, mBinderMock); 251 } catch (SecurityException e) { 252 failsAsExpected = true; 253 } 254 255 mDut.fakeUid = mDefaultUid; 256 257 PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("valid.value") 258 .build(); 259 mDut.publish(mPackageName, clientId, publishConfig, mSessionCallbackMock); 260 261 verify(mAwareStateManagerMock).publish(clientId, publishConfig, mSessionCallbackMock); 262 assertTrue("SecurityException for invalid access from wrong UID thrown", failsAsExpected); 263 } 264 265 /** 266 * Validate that the RTT feature support is checked when attempting a Publish with ranging. 267 */ 268 @Test(expected = IllegalArgumentException.class) testFailOnPublishRangingWithoutRttFeature()269 public void testFailOnPublishRangingWithoutRttFeature() throws Exception { 270 when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn( 271 false); 272 273 PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid") 274 .setRangingEnabled(true).build(); 275 int clientId = doConnect(); 276 IWifiAwareDiscoverySessionCallback mockCallback = mock( 277 IWifiAwareDiscoverySessionCallback.class); 278 279 mDut.publish(mPackageName, clientId, publishConfig, mockCallback); 280 } 281 282 /** 283 * Validate that the RTT feature support is checked when attempting a Subscribe with ranging. 284 */ 285 @Test(expected = IllegalArgumentException.class) testFailOnSubscribeRangingWithoutRttFeature()286 public void testFailOnSubscribeRangingWithoutRttFeature() throws Exception { 287 when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn( 288 false); 289 290 SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName( 291 "something.valid").setMaxDistanceMm(100).build(); 292 int clientId = doConnect(); 293 IWifiAwareDiscoverySessionCallback mockCallback = mock( 294 IWifiAwareDiscoverySessionCallback.class); 295 296 mDut.subscribe(mPackageName, clientId, subscribeConfig, mockCallback); 297 } 298 299 300 /** 301 * Validates that on binder death we get a disconnect(). 302 */ 303 @Test testBinderDeath()304 public void testBinderDeath() throws Exception { 305 ArgumentCaptor<IBinder.DeathRecipient> deathRecipient = ArgumentCaptor 306 .forClass(IBinder.DeathRecipient.class); 307 308 int clientId = doConnect(); 309 310 verify(mBinderMock).linkToDeath(deathRecipient.capture(), eq(0)); 311 deathRecipient.getValue().binderDied(); 312 verify(mAwareStateManagerMock).disconnect(clientId); 313 validateInternalStateCleanedUp(clientId); 314 } 315 316 /** 317 * Validates that sequential connect() calls return increasing client IDs. 318 */ 319 @Test testClientIdIncrementing()320 public void testClientIdIncrementing() { 321 int loopCount = 100; 322 323 InOrder inOrder = inOrder(mAwareStateManagerMock); 324 ArgumentCaptor<Integer> clientIdCaptor = ArgumentCaptor.forClass(Integer.class); 325 326 int prevId = 0; 327 for (int i = 0; i < loopCount; ++i) { 328 mDut.connect(mBinderMock, "", mCallbackMock, null, false); 329 inOrder.verify(mAwareStateManagerMock).connect(clientIdCaptor.capture(), anyInt(), 330 anyInt(), any(), eq(mCallbackMock), any(), eq(false)); 331 int id = clientIdCaptor.getValue(); 332 if (i != 0) { 333 assertTrue("Client ID incrementing", id > prevId); 334 } 335 prevId = id; 336 } 337 } 338 339 /** 340 * Validate terminateSession() - correct pass-through args. 341 */ 342 @Test testTerminateSession()343 public void testTerminateSession() { 344 int sessionId = 1024; 345 int clientId = doConnect(); 346 347 mDut.terminateSession(clientId, sessionId); 348 349 verify(mAwareStateManagerMock).terminateSession(clientId, sessionId); 350 } 351 352 /** 353 * Validate publish() - correct pass-through args. 354 */ 355 @Test testPublish()356 public void testPublish() { 357 PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid") 358 .setRangingEnabled(true).build(); 359 int clientId = doConnect(); 360 IWifiAwareDiscoverySessionCallback mockCallback = mock( 361 IWifiAwareDiscoverySessionCallback.class); 362 363 mDut.publish(mPackageName, clientId, publishConfig, mockCallback); 364 365 verify(mAwareStateManagerMock).publish(clientId, publishConfig, mockCallback); 366 } 367 368 /** 369 * Validate that publish() verifies the input PublishConfig and fails on an invalid service 370 * name. 371 */ 372 @Test(expected = IllegalArgumentException.class) testPublishInvalidServiceName()373 public void testPublishInvalidServiceName() { 374 doBadPublishConfiguration("Including invalid characters - spaces", null, null); 375 } 376 377 /** 378 * Validate that publish() verifies the input PublishConfig and fails on a "very long" 379 * service name. 380 */ 381 @Test(expected = IllegalArgumentException.class) testPublishServiceNameTooLong()382 public void testPublishServiceNameTooLong() { 383 byte[] byteArray = new byte[MAX_LENGTH + 1]; 384 for (int i = 0; i < MAX_LENGTH + 1; ++i) { 385 byteArray[i] = 'a'; 386 } 387 doBadPublishConfiguration(new String(byteArray), null, null); 388 } 389 390 /** 391 * Validate that publish() verifies the input PublishConfig and fails on a "very long" ssi. 392 */ 393 @Test(expected = IllegalArgumentException.class) testPublishSsiTooLong()394 public void testPublishSsiTooLong() { 395 doBadPublishConfiguration("correctservicename", new byte[MAX_LENGTH + 1], null); 396 } 397 398 /** 399 * Validate that publish() verifies the input PublishConfig and fails on a "very long" match 400 * filter. 401 */ 402 @Test(expected = IllegalArgumentException.class) testPublishMatchFilterTooLong()403 public void testPublishMatchFilterTooLong() { 404 doBadPublishConfiguration("correctservicename", null, new byte[MAX_LENGTH + 1]); 405 } 406 407 /** 408 * Validate that publish() verifies the input PublishConfig and fails on a bad match filter - 409 * invalid LV. 410 */ 411 @Test(expected = IllegalArgumentException.class) testPublishMatchFilterBadLv()412 public void testPublishMatchFilterBadLv() { 413 byte[] badLv = { 0, 1, 127, 2, 126, 125, 3 }; 414 doBadPublishConfiguration("correctservicename", null, badLv); 415 } 416 417 /** 418 * Validate updatePublish() - correct pass-through args. 419 */ 420 @Test testUpdatePublish()421 public void testUpdatePublish() { 422 int sessionId = 1232; 423 PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid") 424 .build(); 425 int clientId = doConnect(); 426 427 mDut.updatePublish(clientId, sessionId, publishConfig); 428 429 verify(mAwareStateManagerMock).updatePublish(clientId, sessionId, publishConfig); 430 } 431 432 /** 433 * Validate updatePublish() error checking. 434 */ 435 @Test(expected = IllegalArgumentException.class) testUpdatePublishInvalid()436 public void testUpdatePublishInvalid() { 437 int sessionId = 1232; 438 PublishConfig publishConfig = new PublishConfig.Builder() 439 .setServiceName("something with spaces").build(); 440 int clientId = doConnect(); 441 442 mDut.updatePublish(clientId, sessionId, publishConfig); 443 444 verify(mAwareStateManagerMock).updatePublish(clientId, sessionId, publishConfig); 445 } 446 447 /** 448 * Validate subscribe() - correct pass-through args. 449 */ 450 @Test testSubscribe()451 public void testSubscribe() { 452 SubscribeConfig subscribeConfig = new SubscribeConfig.Builder() 453 .setServiceName("something.valid").setMaxDistanceMm(100).build(); 454 int clientId = doConnect(); 455 IWifiAwareDiscoverySessionCallback mockCallback = mock( 456 IWifiAwareDiscoverySessionCallback.class); 457 458 mDut.subscribe(mPackageName, clientId, subscribeConfig, mockCallback); 459 460 verify(mAwareStateManagerMock).subscribe(clientId, subscribeConfig, mockCallback); 461 } 462 463 /** 464 * Validate that subscribe() verifies the input SubscribeConfig and fails on an invalid service 465 * name. 466 */ 467 @Test(expected = IllegalArgumentException.class) testSubscribeInvalidServiceName()468 public void testSubscribeInvalidServiceName() { 469 doBadSubscribeConfiguration("Including invalid characters - spaces", null, null); 470 } 471 472 /** 473 * Validate that subscribe() verifies the input SubscribeConfig and fails on a "very long" 474 * service name. 475 */ 476 @Test(expected = IllegalArgumentException.class) testSubscribeServiceNameTooLong()477 public void testSubscribeServiceNameTooLong() { 478 byte[] byteArray = new byte[MAX_LENGTH + 1]; 479 for (int i = 0; i < MAX_LENGTH + 1; ++i) { 480 byteArray[i] = 'a'; 481 } 482 doBadSubscribeConfiguration(new String(byteArray), null, null); 483 } 484 485 /** 486 * Validate that subscribe() verifies the input SubscribeConfig and fails on a "very long" ssi. 487 */ 488 @Test(expected = IllegalArgumentException.class) testSubscribeSsiTooLong()489 public void testSubscribeSsiTooLong() { 490 doBadSubscribeConfiguration("correctservicename", new byte[MAX_LENGTH + 1], null); 491 } 492 493 /** 494 * Validate that subscribe() verifies the input SubscribeConfig and fails on a "very long" match 495 * filter. 496 */ 497 @Test(expected = IllegalArgumentException.class) testSubscribeMatchFilterTooLong()498 public void testSubscribeMatchFilterTooLong() { 499 doBadSubscribeConfiguration("correctservicename", null, new byte[MAX_LENGTH + 1]); 500 } 501 502 /** 503 * Validate that subscribe() verifies the input SubscribeConfig and fails on a bad match filter 504 * - invalid LV. 505 */ 506 @Test(expected = IllegalArgumentException.class) testSubscribeMatchFilterBadLv()507 public void testSubscribeMatchFilterBadLv() { 508 byte[] badLv = { 0, 1, 127, 2, 126, 125, 3 }; 509 doBadSubscribeConfiguration("correctservicename", null, badLv); 510 } 511 512 /** 513 * Validate updateSubscribe() error checking. 514 */ 515 @Test(expected = IllegalArgumentException.class) testUpdateSubscribeInvalid()516 public void testUpdateSubscribeInvalid() { 517 int sessionId = 1232; 518 SubscribeConfig subscribeConfig = new SubscribeConfig.Builder() 519 .setServiceName("something.valid") 520 .setServiceSpecificInfo(new byte[MAX_LENGTH + 1]).build(); 521 int clientId = doConnect(); 522 523 mDut.updateSubscribe(clientId, sessionId, subscribeConfig); 524 525 verify(mAwareStateManagerMock).updateSubscribe(clientId, sessionId, subscribeConfig); 526 } 527 528 /** 529 * Validate updateSubscribe() validates configuration. 530 */ 531 @Test testUpdateSubscribe()532 public void testUpdateSubscribe() { 533 int sessionId = 1232; 534 SubscribeConfig subscribeConfig = new SubscribeConfig.Builder() 535 .setServiceName("something.valid").build(); 536 int clientId = doConnect(); 537 538 mDut.updateSubscribe(clientId, sessionId, subscribeConfig); 539 540 verify(mAwareStateManagerMock).updateSubscribe(clientId, sessionId, subscribeConfig); 541 } 542 543 /** 544 * Validate sendMessage() - correct pass-through args. 545 */ 546 @Test testSendMessage()547 public void testSendMessage() { 548 int sessionId = 2394; 549 int peerId = 2032; 550 byte[] message = new byte[MAX_LENGTH]; 551 int messageId = 2043; 552 int clientId = doConnect(); 553 554 mDut.sendMessage(clientId, sessionId, peerId, message, messageId, 0); 555 556 verify(mAwareStateManagerMock).sendMessage(clientId, sessionId, peerId, message, messageId, 557 0); 558 } 559 560 /** 561 * Validate sendMessage() validates that message length is correct. 562 */ 563 @Test(expected = IllegalArgumentException.class) testSendMessageTooLong()564 public void testSendMessageTooLong() { 565 int sessionId = 2394; 566 int peerId = 2032; 567 byte[] message = new byte[MAX_LENGTH + 1]; 568 int messageId = 2043; 569 int clientId = doConnect(); 570 571 mDut.sendMessage(clientId, sessionId, peerId, message, messageId, 0); 572 573 verify(mAwareStateManagerMock).sendMessage(clientId, sessionId, peerId, message, messageId, 574 0); 575 } 576 577 @Test testRequestMacAddress()578 public void testRequestMacAddress() { 579 int uid = 1005; 580 List<Integer> list = new ArrayList<>(); 581 IWifiAwareMacAddressProvider callback = new IWifiAwareMacAddressProvider() { // dummy 582 @Override 583 public void macAddress(Map peerIdToMacMap) throws RemoteException { 584 // empty 585 } 586 587 @Override 588 public IBinder asBinder() { 589 return null; 590 } 591 }; 592 593 mDut.requestMacAddresses(uid, list, callback); 594 595 verify(mAwareStateManagerMock).requestMacAddresses(uid, list, callback); 596 } 597 598 @Test(expected = SecurityException.class) testRequestMacAddressWithoutPermission()599 public void testRequestMacAddressWithoutPermission() { 600 doThrow(new SecurityException()).when(mContextMock).enforceCallingOrSelfPermission( 601 eq(Manifest.permission.NETWORK_STACK), anyString()); 602 603 mDut.requestMacAddresses(1005, new ArrayList<>(), new IWifiAwareMacAddressProvider() { 604 @Override 605 public void macAddress(Map peerIdToMacMap) throws RemoteException { 606 } 607 608 @Override 609 public IBinder asBinder() { 610 return null; 611 } 612 }); 613 } 614 615 /* 616 * Utilities 617 */ 618 619 /* 620 * Tests of internal state of WifiAwareServiceImpl: very limited (not usually 621 * a good idea). However, these test that the internal state is cleaned-up 622 * appropriately. Alternatively would cause issues with memory leaks or 623 * information leak between sessions. 624 */ validateInternalStateCleanedUp(int clientId)625 private void validateInternalStateCleanedUp(int clientId) throws Exception { 626 int uidEntry = getInternalStateUid(clientId); 627 assertEquals(-1, uidEntry); 628 629 IBinder.DeathRecipient dr = getInternalStateDeathRecipient(clientId); 630 assertEquals(null, dr); 631 } 632 doBadPublishConfiguration(String serviceName, byte[] ssi, byte[] matchFilter)633 private void doBadPublishConfiguration(String serviceName, byte[] ssi, byte[] matchFilter) 634 throws IllegalArgumentException { 635 // using the hidden constructor since may be passing invalid parameters which would be 636 // caught by the Builder. Want to test whether service side will catch invalidly 637 // constructed configs. 638 PublishConfig publishConfig = new PublishConfig(serviceName.getBytes(), ssi, matchFilter, 639 PublishConfig.PUBLISH_TYPE_UNSOLICITED, 0, true, false); 640 int clientId = doConnect(); 641 IWifiAwareDiscoverySessionCallback mockCallback = mock( 642 IWifiAwareDiscoverySessionCallback.class); 643 644 mDut.publish(mPackageName, clientId, publishConfig, mockCallback); 645 646 verify(mAwareStateManagerMock).publish(clientId, publishConfig, mockCallback); 647 } 648 doBadSubscribeConfiguration(String serviceName, byte[] ssi, byte[] matchFilter)649 private void doBadSubscribeConfiguration(String serviceName, byte[] ssi, byte[] matchFilter) 650 throws IllegalArgumentException { 651 // using the hidden constructor since may be passing invalid parameters which would be 652 // caught by the Builder. Want to test whether service side will catch invalidly 653 // constructed configs. 654 SubscribeConfig subscribeConfig = new SubscribeConfig(serviceName.getBytes(), ssi, 655 matchFilter, SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE, 0, true, false, 0, false, 0); 656 int clientId = doConnect(); 657 IWifiAwareDiscoverySessionCallback mockCallback = mock( 658 IWifiAwareDiscoverySessionCallback.class); 659 660 mDut.subscribe(mPackageName, clientId, subscribeConfig, mockCallback); 661 662 verify(mAwareStateManagerMock).subscribe(clientId, subscribeConfig, mockCallback); 663 } 664 doConnect()665 private int doConnect() { 666 String callingPackage = "com.google.somePackage"; 667 668 mDut.connect(mBinderMock, callingPackage, mCallbackMock, null, false); 669 670 ArgumentCaptor<Integer> clientId = ArgumentCaptor.forClass(Integer.class); 671 verify(mAwareStateManagerMock).connect(clientId.capture(), anyInt(), anyInt(), 672 eq(callingPackage), eq(mCallbackMock), eq(new ConfigRequest.Builder().build()), 673 eq(false)); 674 675 return clientId.getValue(); 676 } 677 getCharacteristics()678 private static Characteristics getCharacteristics() { 679 Capabilities cap = new Capabilities(); 680 cap.maxConcurrentAwareClusters = 1; 681 cap.maxPublishes = 2; 682 cap.maxSubscribes = 2; 683 cap.maxServiceNameLen = MAX_LENGTH; 684 cap.maxMatchFilterLen = MAX_LENGTH; 685 cap.maxTotalMatchFilterLen = 255; 686 cap.maxServiceSpecificInfoLen = MAX_LENGTH; 687 cap.maxExtendedServiceSpecificInfoLen = MAX_LENGTH; 688 cap.maxNdiInterfaces = 1; 689 cap.maxNdpSessions = 1; 690 cap.maxAppInfoLen = 255; 691 cap.maxQueuedTransmitMessages = 6; 692 return cap.toPublicCharacteristics(); 693 } 694 getInternalStateUid(int clientId)695 private int getInternalStateUid(int clientId) throws Exception { 696 Field field = WifiAwareServiceImpl.class.getDeclaredField("mUidByClientId"); 697 field.setAccessible(true); 698 @SuppressWarnings("unchecked") 699 SparseIntArray uidByClientId = (SparseIntArray) field.get(mDut); 700 701 return uidByClientId.get(clientId, -1); 702 } 703 getInternalStateDeathRecipient(int clientId)704 private IBinder.DeathRecipient getInternalStateDeathRecipient(int clientId) throws Exception { 705 Field field = WifiAwareServiceImpl.class.getDeclaredField("mDeathRecipientsByClientId"); 706 field.setAccessible(true); 707 @SuppressWarnings("unchecked") 708 SparseArray<IBinder.DeathRecipient> deathRecipientsByClientId = 709 (SparseArray<IBinder.DeathRecipient>) field.get(mDut); 710 711 return deathRecipientsByClientId.get(clientId); 712 } 713 } 714