WifiAwareDataPathStateManagerTest.java revision db3c9d35a7f08de03beec81e801d917a5375f63e
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 17package com.android.server.wifi.aware; 18 19import static android.hardware.wifi.V1_0.NanDataPathChannelCfg.REQUEST_CHANNEL_SETUP; 20 21import static org.hamcrest.core.IsEqual.equalTo; 22import static org.junit.Assert.assertTrue; 23import static org.mockito.Matchers.any; 24import static org.mockito.Matchers.anyBoolean; 25import static org.mockito.Matchers.anyInt; 26import static org.mockito.Matchers.anyShort; 27import static org.mockito.Matchers.anyString; 28import static org.mockito.Matchers.eq; 29import static org.mockito.Mockito.inOrder; 30import static org.mockito.Mockito.mock; 31import static org.mockito.Mockito.verify; 32import static org.mockito.Mockito.verifyNoMoreInteractions; 33import static org.mockito.Mockito.when; 34 35import android.app.test.TestAlarmManager; 36import android.content.Context; 37import android.net.ConnectivityManager; 38import android.net.LinkProperties; 39import android.net.NetworkCapabilities; 40import android.net.NetworkFactory; 41import android.net.NetworkInfo; 42import android.net.NetworkMisc; 43import android.net.NetworkRequest; 44import android.net.wifi.aware.AttachCallback; 45import android.net.wifi.aware.ConfigRequest; 46import android.net.wifi.aware.DiscoverySession; 47import android.net.wifi.aware.DiscoverySessionCallback; 48import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback; 49import android.net.wifi.aware.IWifiAwareEventCallback; 50import android.net.wifi.aware.IWifiAwareManager; 51import android.net.wifi.aware.PeerHandle; 52import android.net.wifi.aware.PublishConfig; 53import android.net.wifi.aware.PublishDiscoverySession; 54import android.net.wifi.aware.SubscribeConfig; 55import android.net.wifi.aware.SubscribeDiscoverySession; 56import android.net.wifi.aware.WifiAwareManager; 57import android.net.wifi.aware.WifiAwareSession; 58import android.os.Handler; 59import android.os.IBinder; 60import android.os.INetworkManagementService; 61import android.os.Message; 62import android.os.Messenger; 63import android.os.test.TestLooper; 64import android.test.suitebuilder.annotation.SmallTest; 65import android.util.Pair; 66 67import com.android.internal.util.AsyncChannel; 68 69import libcore.util.HexEncoding; 70 71import org.json.JSONObject; 72import org.junit.Before; 73import org.junit.Rule; 74import org.junit.Test; 75import org.junit.rules.ErrorCollector; 76import org.mockito.ArgumentCaptor; 77import org.mockito.InOrder; 78import org.mockito.Mock; 79import org.mockito.MockitoAnnotations; 80 81import java.lang.reflect.Field; 82import java.util.Arrays; 83 84/** 85 * Unit test harness for WifiAwareDataPathStateManager class. 86 */ 87@SmallTest 88public class WifiAwareDataPathStateManagerTest { 89 private static final String sAwareInterfacePrefix = "aware_data"; 90 91 private TestLooper mMockLooper; 92 private Handler mMockLooperHandler; 93 private WifiAwareStateManager mDut; 94 @Mock private WifiAwareNativeApi mMockNative; 95 @Mock private Context mMockContext; 96 @Mock private IWifiAwareManager mMockAwareService; 97 @Mock private ConnectivityManager mMockCm; 98 @Mock private INetworkManagementService mMockNwMgt; 99 @Mock private WifiAwareDataPathStateManager.NetworkInterfaceWrapper mMockNetworkInterface; 100 @Mock private IWifiAwareEventCallback mMockCallback; 101 @Mock IWifiAwareDiscoverySessionCallback mMockSessionCallback; 102 TestAlarmManager mAlarmManager; 103 104 @Rule 105 public ErrorCollector collector = new ErrorCollector(); 106 107 /** 108 * Initialize mocks. 109 */ 110 @Before 111 public void setUp() throws Exception { 112 MockitoAnnotations.initMocks(this); 113 114 mAlarmManager = new TestAlarmManager(); 115 when(mMockContext.getSystemService(Context.ALARM_SERVICE)) 116 .thenReturn(mAlarmManager.getAlarmManager()); 117 118 when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mMockCm); 119 120 mMockLooper = new TestLooper(); 121 mMockLooperHandler = new Handler(mMockLooper.getLooper()); 122 123 mDut = new WifiAwareStateManager(); 124 mDut.setNative(mMockNative); 125 mDut.start(mMockContext, mMockLooper.getLooper()); 126 mDut.startLate(); 127 128 when(mMockNative.getCapabilities(anyShort())).thenReturn(true); 129 when(mMockNative.enableAndConfigure(anyShort(), any(ConfigRequest.class), anyBoolean(), 130 anyBoolean())).thenReturn(true); 131 when(mMockNative.disable(anyShort())).thenReturn(true); 132 when(mMockNative.publish(anyShort(), anyInt(), any(PublishConfig.class))).thenReturn(true); 133 when(mMockNative.subscribe(anyShort(), anyInt(), any(SubscribeConfig.class))) 134 .thenReturn(true); 135 when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(byte[].class), 136 any(byte[].class), anyInt())).thenReturn(true); 137 when(mMockNative.stopPublish(anyShort(), anyInt())).thenReturn(true); 138 when(mMockNative.stopSubscribe(anyShort(), anyInt())).thenReturn(true); 139 when(mMockNative.createAwareNetworkInterface(anyShort(), anyString())).thenReturn(true); 140 when(mMockNative.deleteAwareNetworkInterface(anyShort(), anyString())).thenReturn(true); 141 when(mMockNative.initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(), 142 any(byte[].class), anyString(), any(byte[].class))).thenReturn(true); 143 when(mMockNative.respondToDataPathRequest(anyShort(), anyBoolean(), anyInt(), anyString(), 144 any(byte[].class))).thenReturn(true); 145 when(mMockNative.endDataPath(anyShort(), anyInt())).thenReturn(true); 146 147 when(mMockNetworkInterface.configureAgentProperties( 148 any(WifiAwareDataPathStateManager.AwareNetworkRequestInformation.class), 149 anyString(), anyInt(), any(NetworkInfo.class), any(NetworkCapabilities.class), 150 any(LinkProperties.class))).thenReturn(true); 151 152 installDataPathStateManagerMocks(); 153 } 154 155 /** 156 * Validates that creating and deleting all interfaces works based on capabilities. 157 */ 158 @Test 159 public void testCreateDeleteAllInterfaces() throws Exception { 160 final int numNdis = 3; 161 final int failCreateInterfaceIndex = 1; 162 163 Capabilities capabilities = new Capabilities(); 164 capabilities.maxNdiInterfaces = numNdis; 165 166 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 167 ArgumentCaptor<String> interfaceName = ArgumentCaptor.forClass(String.class); 168 InOrder inOrder = inOrder(mMockNative); 169 170 // (1) get capabilities 171 mDut.queryCapabilities(); 172 mMockLooper.dispatchAll(); 173 inOrder.verify(mMockNative).getCapabilities(transactionId.capture()); 174 mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities); 175 mMockLooper.dispatchAll(); 176 177 // (2) create all interfaces 178 mDut.createAllDataPathInterfaces(); 179 mMockLooper.dispatchAll(); 180 for (int i = 0; i < numNdis; ++i) { 181 inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), 182 interfaceName.capture()); 183 collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i, 184 equalTo(interfaceName.getValue())); 185 mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); 186 mMockLooper.dispatchAll(); 187 } 188 189 // (3) delete all interfaces [one unsuccessfully] - note that will not necessarily be 190 // done sequentially 191 boolean[] done = new boolean[numNdis]; 192 Arrays.fill(done, false); 193 mDut.deleteAllDataPathInterfaces(); 194 mMockLooper.dispatchAll(); 195 for (int i = 0; i < numNdis; ++i) { 196 inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(), 197 interfaceName.capture()); 198 int interfaceIndex = Integer.valueOf( 199 interfaceName.getValue().substring(sAwareInterfacePrefix.length())); 200 done[interfaceIndex] = true; 201 if (interfaceIndex == failCreateInterfaceIndex) { 202 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), false, 0); 203 } else { 204 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0); 205 } 206 mMockLooper.dispatchAll(); 207 } 208 for (int i = 0; i < numNdis; ++i) { 209 collector.checkThat("interface deleted -- " + i, done[i], equalTo(true)); 210 } 211 212 // (4) create all interfaces (should get a delete for the one which couldn't delete earlier) 213 mDut.createAllDataPathInterfaces(); 214 mMockLooper.dispatchAll(); 215 for (int i = 0; i < numNdis; ++i) { 216 if (i == failCreateInterfaceIndex) { 217 inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(), 218 interfaceName.capture()); 219 collector.checkThat("interface delete pre-create -- " + i, 220 sAwareInterfacePrefix + i, equalTo(interfaceName.getValue())); 221 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0); 222 mMockLooper.dispatchAll(); 223 } 224 inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), 225 interfaceName.capture()); 226 collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i, 227 equalTo(interfaceName.getValue())); 228 mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); 229 mMockLooper.dispatchAll(); 230 } 231 232 verifyNoMoreInteractions(mMockNative); 233 } 234 235 /* 236 * Initiator tests 237 */ 238 239 /** 240 * Validate the success flow of the Initiator: using session network specifier with a non-null 241 * token. 242 */ 243 @Test 244 public void testDataPathInitiatorMacTokenSuccess() throws Exception { 245 testDataPathInitiatorUtility(false, true, true, true); 246 } 247 248 /** 249 * Validate the fail flow of the Initiator: using session network specifier with a null 250 * token. 251 */ 252 @Test(expected = IllegalArgumentException.class) 253 public void testDataPathInitiatorMacNoTokenFail() throws Exception { 254 testDataPathInitiatorUtility(false, true, false, true); 255 } 256 257 /** 258 * Validate the fail flow of the Initiator: using session network specifier with a 0 259 * peer ID. 260 */ 261 @Test(expected = IllegalArgumentException.class) 262 public void testDataPathInitiatorNoMacFail() throws Exception { 263 testDataPathInitiatorUtility(false, false, true, true); 264 } 265 266 /** 267 * Validate the success flow of the Initiator: using a direct network specifier with a non-null 268 * peer mac and non-null token. 269 */ 270 @Test 271 public void testDataPathInitiatorDirectMacTokenSuccess() throws Exception { 272 testDataPathInitiatorUtility(true, true, true, true); 273 } 274 275 /** 276 * Validate the fail flow of the Initiator: using a direct network specifier with a non-null 277 * peer mac and null token. 278 */ 279 @Test(expected = IllegalArgumentException.class) 280 public void testDataPathInitiatorDirectMacNoTokenFail() throws Exception { 281 testDataPathInitiatorUtility(true, true, false, true); 282 } 283 284 /** 285 * Validate the fail flow of the Initiator: using a direct network specifier with a null peer 286 * mac and non-null token. 287 */ 288 @Test(expected = IllegalArgumentException.class) 289 public void testDataPathInitiatorDirectNoMacTokenFail() throws Exception { 290 testDataPathInitiatorUtility(true, false, true, true); 291 } 292 293 /** 294 * Validate the fail flow of the Initiator: using a direct network specifier with a null peer 295 * mac and null token. 296 */ 297 @Test(expected = IllegalArgumentException.class) 298 public void testDataPathInitiatorDirectNoMacNoTokenFail() throws Exception { 299 testDataPathInitiatorUtility(true, false, false, true); 300 } 301 302 /** 303 * Validate the fail flow of the Initiator: use a session network specifier with a non-null 304 * token, but don't get a confirmation. 305 */ 306 @Test 307 public void testDataPathInitiatorNoConfirmationTimeoutFail() throws Exception { 308 testDataPathInitiatorUtility(false, true, true, false); 309 } 310 311 /** 312 * Validate the fail flow of a mis-configured request: Publisher as Initiator 313 */ 314 @Test 315 public void testDataPathInitiatorOnPublisherError() throws Exception { 316 testDataPathInitiatorResponderMismatchUtility(true); 317 } 318 319 /* 320 * Responder tests 321 */ 322 323 /** 324 * Validate the success flow of the Responder: using session network specifier with a non-null 325 * token. 326 */ 327 @Test 328 public void testDataPathResonderMacTokenSuccess() throws Exception { 329 testDataPathResponderUtility(false, true, true, true); 330 } 331 332 /** 333 * Validate the success flow of the Responder: using session network specifier with a null 334 * token. 335 */ 336 @Test 337 public void testDataPathResonderMacNoTokenSuccess() throws Exception { 338 testDataPathResponderUtility(false, true, false, true); 339 } 340 341 /** 342 * Validate the success flow of the Responder: using session network specifier with a 343 * token and no peer ID (i.e. 0). 344 */ 345 @Test 346 public void testDataPathResonderMacTokenNoPeerIdSuccess() throws Exception { 347 testDataPathResponderUtility(false, false, true, true); 348 } 349 350 /** 351 * Validate the success flow of the Responder: using session network specifier with a null 352 * token and no peer ID (i.e. 0). 353 */ 354 @Test 355 public void testDataPathResonderMacTokenNoPeerIdNoTokenSuccess() throws Exception { 356 testDataPathResponderUtility(false, false, false, true); 357 } 358 359 /** 360 * Validate the success flow of the Responder: using a direct network specifier with a non-null 361 * peer mac and non-null token. 362 */ 363 @Test 364 public void testDataPathResonderDirectMacTokenSuccess() throws Exception { 365 testDataPathResponderUtility(true, true, true, true); 366 } 367 368 /** 369 * Validate the success flow of the Responder: using a direct network specifier with a non-null 370 * peer mac and null token. 371 */ 372 @Test 373 public void testDataPathResonderDirectMacNoTokenSuccess() throws Exception { 374 testDataPathResponderUtility(true, true, false, true); 375 } 376 377 /** 378 * Validate the success flow of the Responder: using a direct network specifier with a null peer 379 * mac and non-null token. 380 */ 381 @Test 382 public void testDataPathResonderDirectNoMacTokenSuccess() throws Exception { 383 testDataPathResponderUtility(true, false, true, true); 384 } 385 386 /** 387 * Validate the success flow of the Responder: using a direct network specifier with a null peer 388 * mac and null token. 389 */ 390 @Test 391 public void testDataPathResonderDirectNoMacNoTokenSuccess() throws Exception { 392 testDataPathResponderUtility(true, false, false, true); 393 } 394 395 /** 396 * Validate the fail flow of the Responder: use a session network specifier with a non-null 397 * token, but don't get a confirmation. 398 */ 399 @Test 400 public void testDataPathResponderNoConfirmationTimeoutFail() throws Exception { 401 testDataPathResponderUtility(false, true, true, false); 402 } 403 404 /** 405 * Validate the fail flow of a mis-configured request: Subscriber as Responder 406 */ 407 @Test 408 public void testDataPathResponderOnSubscriberError() throws Exception { 409 testDataPathInitiatorResponderMismatchUtility(false); 410 } 411 412 /* 413 * Utilities 414 */ 415 416 private void testDataPathInitiatorResponderMismatchUtility(boolean doPublish) throws Exception { 417 final int clientId = 123; 418 final int pubSubId = 11234; 419 final int ndpId = 2; 420 final String token = "some token"; 421 final PeerHandle peerHandle = new PeerHandle(1341234); 422 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 423 424 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 425 426 // (0) initialize 427 Pair<Integer, Messenger> res = initDataPathEndPoint(clientId, pubSubId, peerHandle, 428 peerDiscoveryMac, inOrder, doPublish); 429 430 // (1) request network 431 NetworkRequest nr = getSessionNetworkRequest(clientId, res.first, peerHandle, token, 432 doPublish); 433 434 // corrupt the network specifier: reverse the role (so it's mis-matched) 435 JSONObject jsonObject = new JSONObject(nr.networkCapabilities.getNetworkSpecifier()); 436 jsonObject.put(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE, 437 1 - jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)); 438 nr.networkCapabilities.setNetworkSpecifier(jsonObject.toString()); 439 440 Message reqNetworkMsg = Message.obtain(); 441 reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; 442 reqNetworkMsg.obj = nr; 443 reqNetworkMsg.arg1 = 0; 444 res.second.send(reqNetworkMsg); 445 mMockLooper.dispatchAll(); 446 447 // consequences of failure: 448 // Responder (publisher): responds with a rejection to any data-path requests 449 // Initiator (subscribe): doesn't initiate (i.e. no HAL requests) 450 if (doPublish) { 451 // (2) get request & respond 452 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, token.getBytes()); 453 mMockLooper.dispatchAll(); 454 inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false), 455 eq(ndpId), eq(""), eq(new byte[0])); 456 } 457 458 verifyNoMoreInteractions(mMockNative, mMockCm); 459 } 460 461 private void testDataPathInitiatorUtility(boolean useDirect, boolean provideMac, 462 boolean provideToken, boolean getConfirmation) throws Exception { 463 final int clientId = 123; 464 final int pubSubId = 11234; 465 final PeerHandle peerHandle = new PeerHandle(1341234); 466 final int ndpId = 2; 467 final String token = "some token"; 468 final String peerToken = "let's go!"; 469 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 470 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 471 472 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 473 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 474 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 475 476 // (0) initialize 477 Pair<Integer, Messenger> res = initDataPathEndPoint(clientId, pubSubId, peerHandle, 478 peerDiscoveryMac, inOrder, false); 479 480 // (1) request network 481 NetworkRequest nr; 482 if (useDirect) { 483 nr = getDirectNetworkRequest(clientId, 484 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, 485 provideMac ? peerDiscoveryMac : null, provideToken ? token : null); 486 } else { 487 nr = getSessionNetworkRequest(clientId, res.first, provideMac ? peerHandle : null, 488 provideToken ? token : null, false); 489 } 490 491 Message reqNetworkMsg = Message.obtain(); 492 reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; 493 reqNetworkMsg.obj = nr; 494 reqNetworkMsg.arg1 = 0; 495 res.second.send(reqNetworkMsg); 496 mMockLooper.dispatchAll(); 497 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), 498 eq(useDirect ? 0 : peerHandle.peerId), 499 eq(REQUEST_CHANNEL_SETUP), eq(2437), eq(peerDiscoveryMac), 500 eq(sAwareInterfacePrefix + "0"), eq(token.getBytes())); 501 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId); 502 mMockLooper.dispatchAll(); 503 504 // (2) get confirmation OR timeout 505 if (getConfirmation) { 506 mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, 507 peerToken.getBytes()); 508 mMockLooper.dispatchAll(); 509 inOrder.verify(mMockCm).registerNetworkAgent(messengerCaptor.capture(), 510 any(NetworkInfo.class), any(LinkProperties.class), 511 any(NetworkCapabilities.class), 512 anyInt(), any(NetworkMisc.class)); 513 } else { 514 assertTrue(mAlarmManager.dispatch( 515 WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG)); 516 mMockLooper.dispatchAll(); 517 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 518 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 519 mMockLooper.dispatchAll(); 520 } 521 522 // (3) end data-path (unless didn't get confirmation) 523 if (getConfirmation) { 524 Message endNetworkReqMsg = Message.obtain(); 525 endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 526 endNetworkReqMsg.obj = nr; 527 res.second.send(endNetworkReqMsg); 528 529 Message endNetworkUsageMsg = Message.obtain(); 530 endNetworkUsageMsg.what = AsyncChannel.CMD_CHANNEL_DISCONNECTED; 531 messengerCaptor.getValue().send(endNetworkUsageMsg); 532 533 mMockLooper.dispatchAll(); 534 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 535 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 536 mMockLooper.dispatchAll(); 537 } 538 539 verifyNoMoreInteractions(mMockNative, mMockCm); 540 } 541 542 private void testDataPathResponderUtility(boolean useDirect, boolean provideMac, 543 boolean provideToken, boolean getConfirmation) throws Exception { 544 final int clientId = 123; 545 final int pubSubId = 11234; 546 final PeerHandle peerHandle = new PeerHandle(1341234); 547 final int ndpId = 2; 548 final String token = "some token"; 549 final String peerToken = "let's go!"; 550 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 551 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 552 553 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 554 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 555 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 556 557 // (0) initialize 558 Pair<Integer, Messenger> res = initDataPathEndPoint(clientId, pubSubId, peerHandle, 559 peerDiscoveryMac, inOrder, true); 560 561 // (1) request network 562 NetworkRequest nr; 563 if (useDirect) { 564 nr = getDirectNetworkRequest(clientId, 565 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, 566 provideMac ? peerDiscoveryMac : null, provideToken ? token : null); 567 } else { 568 nr = getSessionNetworkRequest(clientId, res.first, provideMac ? peerHandle : null, 569 provideToken ? token : null, true); 570 } 571 572 Message reqNetworkMsg = Message.obtain(); 573 reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; 574 reqNetworkMsg.obj = nr; 575 reqNetworkMsg.arg1 = 0; 576 res.second.send(reqNetworkMsg); 577 mMockLooper.dispatchAll(); 578 579 // (2) get request & respond 580 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, token.getBytes()); 581 mMockLooper.dispatchAll(); 582 inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true), 583 eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(new byte[0])); 584 mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0); 585 mMockLooper.dispatchAll(); 586 587 // (3) get confirmation OR timeout 588 if (getConfirmation) { 589 mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, 590 peerToken.getBytes()); 591 mMockLooper.dispatchAll(); 592 inOrder.verify(mMockCm).registerNetworkAgent(messengerCaptor.capture(), 593 any(NetworkInfo.class), any(LinkProperties.class), 594 any(NetworkCapabilities.class), 595 anyInt(), any(NetworkMisc.class)); 596 } else { 597 assertTrue(mAlarmManager.dispatch( 598 WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG)); 599 mMockLooper.dispatchAll(); 600 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 601 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 602 mMockLooper.dispatchAll(); 603 } 604 605 // (4) end data-path (unless didn't get confirmation) 606 if (getConfirmation) { 607 Message endNetworkMsg = Message.obtain(); 608 endNetworkMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 609 endNetworkMsg.obj = nr; 610 res.second.send(endNetworkMsg); 611 612 Message endNetworkUsageMsg = Message.obtain(); 613 endNetworkUsageMsg.what = AsyncChannel.CMD_CHANNEL_DISCONNECTED; 614 messengerCaptor.getValue().send(endNetworkUsageMsg); 615 616 mMockLooper.dispatchAll(); 617 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 618 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 619 mMockLooper.dispatchAll(); 620 } 621 622 verifyNoMoreInteractions(mMockNative, mMockCm); 623 } 624 625 private void installDataPathStateManagerMocks() throws Exception { 626 Field field = WifiAwareStateManager.class.getDeclaredField("mDataPathMgr"); 627 field.setAccessible(true); 628 Object mDataPathMgr = field.get(mDut); 629 630 field = WifiAwareDataPathStateManager.class.getDeclaredField("mNwService"); 631 field.setAccessible(true); 632 field.set(mDataPathMgr, mMockNwMgt); 633 634 field = WifiAwareDataPathStateManager.class.getDeclaredField("mNiWrapper"); 635 field.setAccessible(true); 636 field.set(mDataPathMgr, mMockNetworkInterface); 637 } 638 639 private NetworkRequest getSessionNetworkRequest(int clientId, int sessionId, 640 PeerHandle peerHandle, String token, boolean doPublish) 641 throws Exception { 642 final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mMockAwareService); 643 final ConfigRequest configRequest = new ConfigRequest.Builder().build(); 644 final PublishConfig publishConfig = new PublishConfig.Builder().build(); 645 final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); 646 647 ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass( 648 WifiAwareSession.class); 649 ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor 650 .forClass(IWifiAwareEventCallback.class); 651 ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor 652 .forClass(IWifiAwareDiscoverySessionCallback.class); 653 ArgumentCaptor<DiscoverySession> discoverySession = ArgumentCaptor 654 .forClass(DiscoverySession.class); 655 656 AttachCallback mockCallback = mock(AttachCallback.class); 657 DiscoverySessionCallback mockSessionCallback = mock( 658 DiscoverySessionCallback.class); 659 660 mgr.attach(mMockLooperHandler, configRequest, mockCallback, null); 661 verify(mMockAwareService).connect(any(IBinder.class), anyString(), 662 clientProxyCallback.capture(), eq(configRequest), eq(false)); 663 clientProxyCallback.getValue().onConnectSuccess(clientId); 664 mMockLooper.dispatchAll(); 665 verify(mockCallback).onAttached(sessionCaptor.capture()); 666 if (doPublish) { 667 sessionCaptor.getValue().publish(publishConfig, mockSessionCallback, 668 mMockLooperHandler); 669 verify(mMockAwareService).publish(eq(clientId), eq(publishConfig), 670 sessionProxyCallback.capture()); 671 } else { 672 sessionCaptor.getValue().subscribe(subscribeConfig, mockSessionCallback, 673 mMockLooperHandler); 674 verify(mMockAwareService).subscribe(eq(clientId), eq(subscribeConfig), 675 sessionProxyCallback.capture()); 676 } 677 sessionProxyCallback.getValue().onSessionStarted(sessionId); 678 mMockLooper.dispatchAll(); 679 if (doPublish) { 680 verify(mockSessionCallback).onPublishStarted( 681 (PublishDiscoverySession) discoverySession.capture()); 682 } else { 683 verify(mockSessionCallback).onSubscribeStarted( 684 (SubscribeDiscoverySession) discoverySession.capture()); 685 } 686 687 String ns = discoverySession.getValue().createNetworkSpecifier(peerHandle, 688 (token == null) ? null : token.getBytes()); 689 690 NetworkCapabilities nc = new NetworkCapabilities(); 691 nc.clearAll(); 692 nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE); 693 nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN).addCapability( 694 NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 695 nc.setNetworkSpecifier(ns); 696 nc.setLinkUpstreamBandwidthKbps(1); 697 nc.setLinkDownstreamBandwidthKbps(1); 698 nc.setSignalStrength(1); 699 700 return new NetworkRequest(nc, 0, 0, NetworkRequest.Type.NONE); 701 } 702 703 private NetworkRequest getDirectNetworkRequest(int clientId, int role, byte[] peer, 704 String token) throws Exception { 705 final ConfigRequest configRequest = new ConfigRequest.Builder().build(); 706 final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mMockAwareService); 707 708 ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass( 709 WifiAwareSession.class); 710 ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor 711 .forClass(IWifiAwareEventCallback.class); 712 713 AttachCallback mockCallback = mock(AttachCallback.class); 714 715 mgr.attach(mMockLooperHandler, configRequest, mockCallback, null); 716 verify(mMockAwareService).connect(any(IBinder.class), anyString(), 717 clientProxyCallback.capture(), eq(configRequest), eq(false)); 718 clientProxyCallback.getValue().onConnectSuccess(clientId); 719 mMockLooper.dispatchAll(); 720 verify(mockCallback).onAttached(sessionCaptor.capture()); 721 722 String ns = sessionCaptor.getValue().createNetworkSpecifier(role, peer, 723 (token == null) ? null : token.getBytes()); 724 NetworkCapabilities nc = new NetworkCapabilities(); 725 nc.clearAll(); 726 nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE); 727 nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN).addCapability( 728 NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 729 nc.setNetworkSpecifier(ns); 730 nc.setLinkUpstreamBandwidthKbps(1); 731 nc.setLinkDownstreamBandwidthKbps(1); 732 nc.setSignalStrength(1); 733 734 return new NetworkRequest(nc, 0, 0, NetworkRequest.Type.REQUEST); 735 } 736 737 private Pair<Integer, Messenger> initDataPathEndPoint(int clientId, int pubSubId, 738 PeerHandle peerHandle, byte[] peerDiscoveryMac, InOrder inOrder, 739 boolean doPublish) 740 throws Exception { 741 final int uid = 1000; 742 final int pid = 2000; 743 final String callingPackage = "com.android.somePackage"; 744 final String someMsg = "some arbitrary message from peer"; 745 final ConfigRequest configRequest = new ConfigRequest.Builder().build(); 746 final PublishConfig publishConfig = new PublishConfig.Builder().build(); 747 final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); 748 749 Capabilities capabilities = new Capabilities(); 750 capabilities.maxNdiInterfaces = 1; 751 752 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 753 ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class); 754 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 755 ArgumentCaptor<String> strCaptor = ArgumentCaptor.forClass(String.class); 756 757 // (0) start/registrations 758 inOrder.verify(mMockCm).registerNetworkFactory(messengerCaptor.capture(), 759 strCaptor.capture()); 760 collector.checkThat("factory name", "WIFI_AWARE_FACTORY", equalTo(strCaptor.getValue())); 761 762 // (1) get capabilities 763 mDut.queryCapabilities(); 764 mMockLooper.dispatchAll(); 765 inOrder.verify(mMockNative).getCapabilities(transactionId.capture()); 766 mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities); 767 mMockLooper.dispatchAll(); 768 769 // (2) enable usage (creates interfaces) 770 mDut.enableUsage(); 771 mMockLooper.dispatchAll(); 772 inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), 773 strCaptor.capture()); 774 collector.checkThat("interface created -- 0", sAwareInterfacePrefix + 0, 775 equalTo(strCaptor.getValue())); 776 mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); 777 mMockLooper.dispatchAll(); 778 779 // (3) create client & session & rx message 780 mDut.connect(clientId, uid, pid, callingPackage, mMockCallback, configRequest, false); 781 mMockLooper.dispatchAll(); 782 inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), 783 eq(configRequest), eq(false), eq(true)); 784 mDut.onConfigSuccessResponse(transactionId.getValue()); 785 mMockLooper.dispatchAll(); 786 inOrder.verify(mMockCallback).onConnectSuccess(clientId); 787 if (doPublish) { 788 mDut.publish(clientId, publishConfig, mMockSessionCallback); 789 } else { 790 mDut.subscribe(clientId, subscribeConfig, mMockSessionCallback); 791 } 792 mMockLooper.dispatchAll(); 793 if (doPublish) { 794 inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig)); 795 } else { 796 inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), 797 eq(subscribeConfig)); 798 } 799 mDut.onSessionConfigSuccessResponse(transactionId.getValue(), doPublish, pubSubId); 800 mMockLooper.dispatchAll(); 801 inOrder.verify(mMockSessionCallback).onSessionStarted(sessionId.capture()); 802 mDut.onMessageReceivedNotification(pubSubId, peerHandle.peerId, peerDiscoveryMac, 803 someMsg.getBytes()); 804 mMockLooper.dispatchAll(); 805 inOrder.verify(mMockSessionCallback).onMessageReceived(peerHandle.peerId, 806 someMsg.getBytes()); 807 808 return new Pair<>(sessionId.getValue(), messengerCaptor.getValue()); 809 } 810} 811