1 /* 2 * Copyright (C) 2017 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; 18 19 import static com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES; 20 21 import static junit.framework.Assert.assertEquals; 22 23 import static org.hamcrest.core.IsEqual.equalTo; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertTrue; 26 import static org.mockito.Matchers.any; 27 import static org.mockito.Matchers.anyInt; 28 import static org.mockito.Matchers.anyLong; 29 import static org.mockito.Matchers.anyString; 30 import static org.mockito.Matchers.eq; 31 import static org.mockito.Mockito.doAnswer; 32 import static org.mockito.Mockito.inOrder; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.times; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.verifyNoMoreInteractions; 37 import static org.mockito.Mockito.when; 38 39 import android.app.test.MockAnswerUtil; 40 import android.hardware.wifi.V1_0.IWifi; 41 import android.hardware.wifi.V1_0.IWifiApIface; 42 import android.hardware.wifi.V1_0.IWifiChip; 43 import android.hardware.wifi.V1_0.IWifiChipEventCallback; 44 import android.hardware.wifi.V1_0.IWifiEventCallback; 45 import android.hardware.wifi.V1_0.IWifiIface; 46 import android.hardware.wifi.V1_0.IWifiNanIface; 47 import android.hardware.wifi.V1_0.IWifiP2pIface; 48 import android.hardware.wifi.V1_0.IWifiStaIface; 49 import android.hardware.wifi.V1_0.IfaceType; 50 import android.hardware.wifi.V1_0.WifiStatus; 51 import android.hardware.wifi.V1_0.WifiStatusCode; 52 import android.hidl.manager.V1_0.IServiceManager; 53 import android.hidl.manager.V1_0.IServiceNotification; 54 import android.os.IHwBinder; 55 import android.os.test.TestLooper; 56 import android.util.Log; 57 58 import org.hamcrest.core.IsNull; 59 import org.junit.After; 60 import org.junit.Before; 61 import org.junit.Rule; 62 import org.junit.Test; 63 import org.junit.rules.ErrorCollector; 64 import org.mockito.ArgumentCaptor; 65 import org.mockito.InOrder; 66 import org.mockito.Mock; 67 import org.mockito.MockitoAnnotations; 68 69 import java.io.PrintWriter; 70 import java.io.StringWriter; 71 import java.util.ArrayList; 72 import java.util.HashMap; 73 import java.util.HashSet; 74 import java.util.Map; 75 import java.util.Set; 76 77 /** 78 * Unit test harness for HalDeviceManagerTest. 79 */ 80 public class HalDeviceManagerTest { 81 private HalDeviceManager mDut; 82 @Mock IServiceManager mServiceManagerMock; 83 @Mock IWifi mWifiMock; 84 @Mock HalDeviceManager.ManagerStatusListener mManagerStatusListenerMock; 85 private TestLooper mTestLooper; 86 private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor = 87 ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class); 88 private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor = 89 ArgumentCaptor.forClass(IServiceNotification.Stub.class); 90 private ArgumentCaptor<IWifiEventCallback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass( 91 IWifiEventCallback.class); 92 private InOrder mInOrder; 93 @Rule public ErrorCollector collector = new ErrorCollector(); 94 private WifiStatus mStatusOk; 95 private WifiStatus mStatusFail; 96 97 private class HalDeviceManagerSpy extends HalDeviceManager { 98 @Override getWifiServiceMockable()99 protected IWifi getWifiServiceMockable() { 100 return mWifiMock; 101 } 102 103 @Override getServiceManagerMockable()104 protected IServiceManager getServiceManagerMockable() { 105 return mServiceManagerMock; 106 } 107 } 108 109 @Before before()110 public void before() throws Exception { 111 MockitoAnnotations.initMocks(this); 112 113 mTestLooper = new TestLooper(); 114 115 // initialize dummy status objects 116 mStatusOk = getStatus(WifiStatusCode.SUCCESS); 117 mStatusFail = getStatus(WifiStatusCode.ERROR_UNKNOWN); 118 119 when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class), 120 anyLong())).thenReturn(true); 121 when(mServiceManagerMock.registerForNotifications(anyString(), anyString(), 122 any(IServiceNotification.Stub.class))).thenReturn(true); 123 when(mServiceManagerMock.getTransport( 124 eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME))) 125 .thenReturn(IServiceManager.Transport.HWBINDER); 126 when(mWifiMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn( 127 true); 128 when(mWifiMock.registerEventCallback(any(IWifiEventCallback.class))).thenReturn(mStatusOk); 129 when(mWifiMock.start()).thenReturn(mStatusOk); 130 when(mWifiMock.stop()).thenReturn(mStatusOk); 131 132 mDut = new HalDeviceManagerSpy(); 133 } 134 135 /** 136 * Print out the dump of the device manager after each test. Not used in test validation 137 * (internal state) - but can help in debugging failed tests. 138 */ 139 @After after()140 public void after() throws Exception { 141 dumpDut("after: "); 142 } 143 144 /** 145 * Test basic startup flow: 146 * - IServiceManager registrations 147 * - IWifi registrations 148 * - IWifi startup delayed 149 * - Start Wi-Fi -> onStart 150 * - Stop Wi-Fi -> onStop 151 */ 152 @Test testStartStopFlow()153 public void testStartStopFlow() throws Exception { 154 mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock); 155 executeAndValidateInitializationSequence(); 156 executeAndValidateStartupSequence(); 157 158 // act: stop Wi-Fi 159 mDut.stop(); 160 mTestLooper.dispatchAll(); 161 162 // verify: onStop called 163 mInOrder.verify(mWifiMock).stop(); 164 mInOrder.verify(mManagerStatusListenerMock).onStatusChanged(); 165 166 verifyNoMoreInteractions(mManagerStatusListenerMock); 167 } 168 169 /** 170 * Test the service manager notification coming in after 171 * {@link HalDeviceManager#initIWifiIfNecessary()} is already invoked as a part of 172 * {@link HalDeviceManager#initialize()}. 173 */ 174 @Test testServiceRegisterationAfterInitialize()175 public void testServiceRegisterationAfterInitialize() throws Exception { 176 mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock); 177 executeAndValidateInitializationSequence(); 178 179 // This should now be ignored since IWifi is already non-null. 180 mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true); 181 182 verifyNoMoreInteractions(mManagerStatusListenerMock, mWifiMock, mServiceManagerMock); 183 } 184 185 /** 186 * Validate that multiple callback registrations are called and that duplicate ones are 187 * only called once. 188 */ 189 @Test testMultipleCallbackRegistrations()190 public void testMultipleCallbackRegistrations() throws Exception { 191 mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock); 192 executeAndValidateInitializationSequence(); 193 194 // register another 2 callbacks - one of them twice 195 HalDeviceManager.ManagerStatusListener callback1 = mock( 196 HalDeviceManager.ManagerStatusListener.class); 197 HalDeviceManager.ManagerStatusListener callback2 = mock( 198 HalDeviceManager.ManagerStatusListener.class); 199 mDut.registerStatusListener(callback2, mTestLooper.getLooper()); 200 mDut.registerStatusListener(callback1, mTestLooper.getLooper()); 201 mDut.registerStatusListener(callback2, mTestLooper.getLooper()); 202 203 // startup 204 executeAndValidateStartupSequence(); 205 206 // verify 207 verify(callback1).onStatusChanged(); 208 verify(callback2).onStatusChanged(); 209 210 verifyNoMoreInteractions(mManagerStatusListenerMock, callback1, callback2); 211 } 212 213 /** 214 * Validate IWifi death listener and registration flow. 215 */ 216 @Test testWifiDeathAndRegistration()217 public void testWifiDeathAndRegistration() throws Exception { 218 mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock); 219 executeAndValidateInitializationSequence(); 220 executeAndValidateStartupSequence(); 221 222 // act: IWifi service death 223 mDeathRecipientCaptor.getValue().serviceDied(0); 224 mTestLooper.dispatchAll(); 225 226 // verify: getting onStop 227 mInOrder.verify(mManagerStatusListenerMock).onStatusChanged(); 228 229 // act: service startup 230 mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", false); 231 232 // verify: initialization of IWifi 233 mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong()); 234 mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture()); 235 236 // act: start 237 collector.checkThat(mDut.start(), equalTo(true)); 238 mWifiEventCallbackCaptor.getValue().onStart(); 239 mTestLooper.dispatchAll(); 240 241 // verify: service and callback calls 242 mInOrder.verify(mWifiMock).start(); 243 mInOrder.verify(mManagerStatusListenerMock, times(2)).onStatusChanged(); 244 245 verifyNoMoreInteractions(mManagerStatusListenerMock); 246 } 247 248 /** 249 * Validate IWifi onFailure causes notification 250 */ 251 @Test testWifiFail()252 public void testWifiFail() throws Exception { 253 mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock); 254 executeAndValidateInitializationSequence(); 255 executeAndValidateStartupSequence(); 256 257 // act: IWifi failure 258 mWifiEventCallbackCaptor.getValue().onFailure(mStatusFail); 259 mTestLooper.dispatchAll(); 260 261 // verify: getting onStop 262 mInOrder.verify(mManagerStatusListenerMock).onStatusChanged(); 263 264 // act: start again 265 collector.checkThat(mDut.start(), equalTo(true)); 266 mWifiEventCallbackCaptor.getValue().onStart(); 267 mTestLooper.dispatchAll(); 268 269 // verify: service and callback calls 270 mInOrder.verify(mWifiMock).start(); 271 mInOrder.verify(mManagerStatusListenerMock).onStatusChanged(); 272 273 verifyNoMoreInteractions(mManagerStatusListenerMock); 274 } 275 276 /** 277 * Validate creation of STA interface from blank start-up. The remove interface. 278 */ 279 @Test testCreateStaInterfaceNoInitMode()280 public void testCreateStaInterfaceNoInitMode() throws Exception { 281 final String name = "sta0"; 282 283 BaselineChip chipMock = new BaselineChip(); 284 chipMock.initialize(); 285 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 286 mManagerStatusListenerMock); 287 executeAndValidateInitializationSequence(); 288 executeAndValidateStartupSequence(); 289 290 HalDeviceManager.InterfaceDestroyedListener idl = mock( 291 HalDeviceManager.InterfaceDestroyedListener.class); 292 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 293 HalDeviceManager.InterfaceAvailableForRequestListener.class); 294 295 IWifiStaIface iface = (IWifiStaIface) validateInterfaceSequence(chipMock, 296 false, // chipModeValid 297 -1000, // chipModeId (only used if chipModeValid is true) 298 IfaceType.STA, // ifaceTypeToCreate 299 name, // ifaceName 300 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 301 null, // tearDownList 302 idl, // destroyedListener 303 iafrl // availableListener 304 ); 305 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 306 307 // act: remove interface 308 mDut.removeIface(iface); 309 mTestLooper.dispatchAll(); 310 311 // verify: callback triggered 312 mInOrder.verify(chipMock.chip).removeStaIface(name); 313 verify(idl).onDestroyed(); 314 verify(iafrl).onAvailableForRequest(); 315 316 verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl); 317 } 318 319 /** 320 * Validate creation of AP interface from blank start-up. The remove interface. 321 */ 322 @Test testCreateApInterfaceNoInitMode()323 public void testCreateApInterfaceNoInitMode() throws Exception { 324 final String name = "ap0"; 325 326 BaselineChip chipMock = new BaselineChip(); 327 chipMock.initialize(); 328 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 329 mManagerStatusListenerMock); 330 executeAndValidateInitializationSequence(); 331 executeAndValidateStartupSequence(); 332 333 HalDeviceManager.InterfaceDestroyedListener idl = mock( 334 HalDeviceManager.InterfaceDestroyedListener.class); 335 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 336 HalDeviceManager.InterfaceAvailableForRequestListener.class); 337 338 IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, 339 false, // chipModeValid 340 -1000, // chipModeId (only used if chipModeValid is true) 341 IfaceType.AP, // ifaceTypeToCreate 342 name, // ifaceName 343 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode 344 null, // tearDownList 345 idl, // destroyedListener 346 iafrl // availableListener 347 ); 348 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 349 350 // act: remove interface 351 mDut.removeIface(iface); 352 mTestLooper.dispatchAll(); 353 354 // verify: callback triggered 355 mInOrder.verify(chipMock.chip).removeApIface(name); 356 verify(idl).onDestroyed(); 357 verify(iafrl).onAvailableForRequest(); 358 359 verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl); 360 } 361 362 /** 363 * Validate creation of P2P interface from blank start-up. The remove interface. 364 */ 365 @Test testCreateP2pInterfaceNoInitMode()366 public void testCreateP2pInterfaceNoInitMode() throws Exception { 367 final String name = "p2p0"; 368 369 BaselineChip chipMock = new BaselineChip(); 370 chipMock.initialize(); 371 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 372 mManagerStatusListenerMock); 373 executeAndValidateInitializationSequence(); 374 executeAndValidateStartupSequence(); 375 376 HalDeviceManager.InterfaceDestroyedListener idl = mock( 377 HalDeviceManager.InterfaceDestroyedListener.class); 378 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 379 HalDeviceManager.InterfaceAvailableForRequestListener.class); 380 381 IWifiP2pIface iface = (IWifiP2pIface) validateInterfaceSequence(chipMock, 382 false, // chipModeValid 383 -1000, // chipModeId (only used if chipModeValid is true) 384 IfaceType.P2P, // ifaceTypeToCreate 385 name, // ifaceName 386 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 387 null, // tearDownList 388 idl, // destroyedListener 389 iafrl // availableListener 390 ); 391 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 392 393 // act: remove interface 394 mDut.removeIface(iface); 395 mTestLooper.dispatchAll(); 396 397 // verify: callback triggered 398 mInOrder.verify(chipMock.chip).removeP2pIface(name); 399 verify(idl).onDestroyed(); 400 verify(iafrl).onAvailableForRequest(); 401 402 verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl); 403 } 404 405 /** 406 * Validate creation of NAN interface from blank start-up. The remove interface. 407 */ 408 @Test testCreateNanInterfaceNoInitMode()409 public void testCreateNanInterfaceNoInitMode() throws Exception { 410 final String name = "nan0"; 411 412 BaselineChip chipMock = new BaselineChip(); 413 chipMock.initialize(); 414 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 415 mManagerStatusListenerMock); 416 executeAndValidateInitializationSequence(); 417 executeAndValidateStartupSequence(); 418 419 HalDeviceManager.InterfaceDestroyedListener idl = mock( 420 HalDeviceManager.InterfaceDestroyedListener.class); 421 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 422 HalDeviceManager.InterfaceAvailableForRequestListener.class); 423 424 IWifiNanIface iface = (IWifiNanIface) validateInterfaceSequence(chipMock, 425 false, // chipModeValid 426 -1000, // chipModeId (only used if chipModeValid is true) 427 IfaceType.NAN, // ifaceTypeToCreate 428 name, // ifaceName 429 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 430 null, // tearDownList 431 idl, // destroyedListener 432 iafrl // availableListener 433 ); 434 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 435 436 // act: remove interface 437 mDut.removeIface(iface); 438 mTestLooper.dispatchAll(); 439 440 // verify: callback triggered 441 mInOrder.verify(chipMock.chip).removeNanIface(name); 442 verify(idl).onDestroyed(); 443 verify(iafrl).onAvailableForRequest(); 444 445 verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl); 446 } 447 448 /** 449 * Validate creation of AP interface when in STA mode - but with no interface created. Expect 450 * a change in chip mode. 451 */ 452 @Test testCreateApWithStaModeUp()453 public void testCreateApWithStaModeUp() throws Exception { 454 final String name = "ap0"; 455 456 BaselineChip chipMock = new BaselineChip(); 457 chipMock.initialize(); 458 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 459 mManagerStatusListenerMock); 460 executeAndValidateInitializationSequence(); 461 executeAndValidateStartupSequence(); 462 463 HalDeviceManager.InterfaceDestroyedListener idl = mock( 464 HalDeviceManager.InterfaceDestroyedListener.class); 465 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 466 HalDeviceManager.InterfaceAvailableForRequestListener.class); 467 468 IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, 469 true, // chipModeValid 470 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 471 IfaceType.AP, // ifaceTypeToCreate 472 name, // ifaceName 473 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode 474 null, // tearDownList 475 idl, // destroyedListener 476 iafrl // availableListener 477 ); 478 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 479 480 // act: stop Wi-Fi 481 mDut.stop(); 482 mTestLooper.dispatchAll(); 483 484 // verify: callback triggered 485 verify(idl).onDestroyed(); 486 verify(mManagerStatusListenerMock, times(2)).onStatusChanged(); 487 488 verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl); 489 } 490 491 /** 492 * Validate creation of AP interface when in AP mode - but with no interface created. Expect 493 * no change in chip mode. 494 */ 495 @Test testCreateApWithApModeUp()496 public void testCreateApWithApModeUp() throws Exception { 497 final String name = "ap0"; 498 499 BaselineChip chipMock = new BaselineChip(); 500 chipMock.initialize(); 501 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 502 mManagerStatusListenerMock); 503 executeAndValidateInitializationSequence(); 504 executeAndValidateStartupSequence(); 505 506 HalDeviceManager.InterfaceDestroyedListener idl = mock( 507 HalDeviceManager.InterfaceDestroyedListener.class); 508 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 509 HalDeviceManager.InterfaceAvailableForRequestListener.class); 510 511 IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, 512 true, // chipModeValid 513 BaselineChip.AP_CHIP_MODE_ID, // chipModeId 514 IfaceType.AP, // ifaceTypeToCreate 515 name, // ifaceName 516 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode 517 null, // tearDownList 518 idl, // destroyedListener 519 iafrl // availableListener 520 ); 521 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 522 523 // act: stop Wi-Fi 524 mDut.stop(); 525 mTestLooper.dispatchAll(); 526 527 // verify: callback triggered 528 verify(idl).onDestroyed(); 529 verify(mManagerStatusListenerMock, times(2)).onStatusChanged(); 530 531 verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl); 532 } 533 534 /** 535 * Validate AP up/down creation of AP interface when a STA already created. Expect: 536 * - STA created 537 * - P2P created 538 * - When AP requested: 539 * - STA & P2P torn down 540 * - AP created 541 * - P2P creation refused 542 * - Request STA: will tear down AP 543 * - When AP destroyed: 544 * - Get p2p available listener callback 545 * - Can create P2P when requested 546 * - Create P2P 547 * - Request NAN: will get refused 548 * - Tear down P2P: 549 * - should get nan available listener callback 550 * - Can create NAN when requested 551 */ 552 @Test testCreateSameAndDiffPriorities()553 public void testCreateSameAndDiffPriorities() throws Exception { 554 BaselineChip chipMock = new BaselineChip(); 555 chipMock.initialize(); 556 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 557 mManagerStatusListenerMock); 558 executeAndValidateInitializationSequence(); 559 executeAndValidateStartupSequence(); 560 561 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock( 562 HalDeviceManager.InterfaceDestroyedListener.class); 563 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock( 564 HalDeviceManager.InterfaceAvailableForRequestListener.class); 565 566 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock( 567 HalDeviceManager.InterfaceDestroyedListener.class); 568 569 HalDeviceManager.InterfaceDestroyedListener apDestroyedListener = mock( 570 HalDeviceManager.InterfaceDestroyedListener.class); 571 HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock( 572 HalDeviceManager.InterfaceAvailableForRequestListener.class); 573 574 HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock( 575 HalDeviceManager.InterfaceDestroyedListener.class); 576 HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock( 577 HalDeviceManager.InterfaceAvailableForRequestListener.class); 578 579 HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener2 = mock( 580 HalDeviceManager.InterfaceDestroyedListener.class); 581 582 HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock( 583 HalDeviceManager.InterfaceDestroyedListener.class); 584 HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock( 585 HalDeviceManager.InterfaceAvailableForRequestListener.class); 586 587 // Request STA 588 IWifiIface staIface = validateInterfaceSequence(chipMock, 589 false, // chipModeValid 590 -1000, // chipModeId (only used if chipModeValid is true) 591 IfaceType.STA, // ifaceTypeToCreate 592 "sta0", // ifaceName 593 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 594 null, // tearDownList 595 staDestroyedListener, // destroyedListener 596 staAvailListener // availableListener 597 ); 598 collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue()); 599 600 // register additional InterfaceDestroyedListeners - including a duplicate (verify that 601 // only called once!) 602 mDut.registerDestroyedListener(staIface, staDestroyedListener2, mTestLooper.getLooper()); 603 mDut.registerDestroyedListener(staIface, staDestroyedListener, mTestLooper.getLooper()); 604 605 // Request P2P 606 IWifiIface p2pIface = validateInterfaceSequence(chipMock, 607 true, // chipModeValid 608 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 609 IfaceType.P2P, // ifaceTypeToCreate 610 "p2p0", // ifaceName 611 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 612 null, // tearDownList 613 p2pDestroyedListener, // destroyedListener 614 p2pAvailListener // availableListener 615 ); 616 collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue()); 617 618 // Request AP 619 IWifiIface apIface = validateInterfaceSequence(chipMock, 620 true, // chipModeValid 621 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 622 IfaceType.AP, // ifaceTypeToCreate 623 "ap0", // ifaceName 624 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode 625 new IWifiIface[]{staIface, p2pIface}, // tearDownList 626 apDestroyedListener, // destroyedListener 627 apAvailListener, // availableListener 628 // destroyedInterfacesDestroyedListeners... 629 staDestroyedListener, staDestroyedListener2, p2pDestroyedListener 630 ); 631 collector.checkThat("allocated AP interface", apIface, IsNull.notNullValue()); 632 633 // Request P2P: expect failure 634 p2pIface = mDut.createP2pIface(p2pDestroyedListener, mTestLooper.getLooper()); 635 collector.checkThat("P2P can't be created", p2pIface, IsNull.nullValue()); 636 637 // Request STA: expect success 638 staIface = validateInterfaceSequence(chipMock, 639 true, // chipModeValid 640 BaselineChip.AP_CHIP_MODE_ID, // chipModeId 641 IfaceType.STA, // ifaceTypeToCreate 642 "sta0", // ifaceName 643 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 644 null, // tearDownList 645 staDestroyedListener, // destroyedListener 646 staAvailListener, // availableListener 647 apDestroyedListener // destroyedInterfacesDestroyedListeners... 648 ); 649 collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue()); 650 651 mTestLooper.dispatchAll(); 652 verify(apDestroyedListener).onDestroyed(); 653 654 // Request P2P: expect success now 655 p2pIface = validateInterfaceSequence(chipMock, 656 true, // chipModeValid 657 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 658 IfaceType.P2P, // ifaceTypeToCreate 659 "p2p0", // ifaceName 660 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 661 null, // tearDownList 662 p2pDestroyedListener2, // destroyedListener 663 p2pAvailListener // availableListener 664 ); 665 666 // Request NAN: should fail 667 IWifiIface nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper()); 668 mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener, 669 mTestLooper.getLooper()); 670 collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue()); 671 672 // Tear down P2P 673 mDut.removeIface(p2pIface); 674 mTestLooper.dispatchAll(); 675 676 verify(chipMock.chip, times(2)).removeP2pIface("p2p0"); 677 verify(p2pDestroyedListener2).onDestroyed(); 678 679 // Should now be able to request and get NAN 680 nanIface = validateInterfaceSequence(chipMock, 681 true, // chipModeValid 682 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 683 IfaceType.NAN, // ifaceTypeToCreate 684 "nan0", // ifaceName 685 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 686 null, // tearDownList 687 nanDestroyedListener, // destroyedListener 688 nanAvailListener // availableListener 689 ); 690 collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue()); 691 692 // available callback verification 693 verify(staAvailListener).onAvailableForRequest(); 694 verify(apAvailListener, times(4)).onAvailableForRequest(); 695 verify(p2pAvailListener, times(3)).onAvailableForRequest(); 696 verify(nanAvailListener).onAvailableForRequest(); 697 698 verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener, 699 staDestroyedListener2, apDestroyedListener, apAvailListener, p2pDestroyedListener, 700 nanDestroyedListener, nanAvailListener, p2pDestroyedListener2); 701 } 702 703 /** 704 * Validate P2P and NAN interactions. Expect: 705 * - STA created 706 * - NAN created 707 * - When P2P requested: 708 * - NAN torn down 709 * - P2P created 710 * - NAN creation refused 711 * - When P2P destroyed: 712 * - get nan available listener 713 * - Can create NAN when requested 714 */ 715 @Test testP2pAndNanInteractions()716 public void testP2pAndNanInteractions() throws Exception { 717 BaselineChip chipMock = new BaselineChip(); 718 chipMock.initialize(); 719 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 720 mManagerStatusListenerMock); 721 executeAndValidateInitializationSequence(); 722 executeAndValidateStartupSequence(); 723 724 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock( 725 HalDeviceManager.InterfaceDestroyedListener.class); 726 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock( 727 HalDeviceManager.InterfaceAvailableForRequestListener.class); 728 729 HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock( 730 HalDeviceManager.InterfaceDestroyedListener.class); 731 HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock( 732 HalDeviceManager.InterfaceAvailableForRequestListener.class); 733 734 HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock( 735 HalDeviceManager.InterfaceDestroyedListener.class); 736 HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = null; 737 738 // Request STA 739 IWifiIface staIface = validateInterfaceSequence(chipMock, 740 false, // chipModeValid 741 -1000, // chipModeId (only used if chipModeValid is true) 742 IfaceType.STA, // ifaceTypeToCreate 743 "sta0", // ifaceName 744 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 745 null, // tearDownList 746 staDestroyedListener, // destroyedListener 747 staAvailListener // availableListener 748 ); 749 750 // Request NAN 751 IWifiIface nanIface = validateInterfaceSequence(chipMock, 752 true, // chipModeValid 753 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 754 IfaceType.NAN, // ifaceTypeToCreate 755 "nan0", // ifaceName 756 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 757 null, // tearDownList 758 nanDestroyedListener, // destroyedListener 759 nanAvailListener // availableListener 760 ); 761 762 // Request P2P 763 IWifiIface p2pIface = validateInterfaceSequence(chipMock, 764 true, // chipModeValid 765 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 766 IfaceType.P2P, // ifaceTypeToCreate 767 "p2p0", // ifaceName 768 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 769 new IWifiIface[]{nanIface}, // tearDownList 770 p2pDestroyedListener, // destroyedListener 771 p2pAvailListener, // availableListener 772 nanDestroyedListener // destroyedInterfacesDestroyedListeners... 773 ); 774 775 // Request NAN: expect failure 776 nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper()); 777 mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener, 778 mTestLooper.getLooper()); 779 collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue()); 780 781 // Destroy P2P interface 782 boolean status = mDut.removeIface(p2pIface); 783 mInOrder.verify(chipMock.chip).removeP2pIface("p2p0"); 784 collector.checkThat("P2P removal success", status, equalTo(true)); 785 786 mTestLooper.dispatchAll(); 787 verify(p2pDestroyedListener).onDestroyed(); 788 verify(nanAvailListener).onAvailableForRequest(); 789 790 // Request NAN: expect success now 791 nanIface = validateInterfaceSequence(chipMock, 792 true, // chipModeValid 793 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 794 IfaceType.NAN, // ifaceTypeToCreate 795 "nan0", // ifaceName 796 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 797 null, // tearDownList 798 nanDestroyedListener, // destroyedListener 799 nanAvailListener // availableListener 800 ); 801 802 verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener, 803 nanDestroyedListener, nanAvailListener, p2pDestroyedListener); 804 } 805 806 /** 807 * Validates that when (for some reason) the cache is out-of-sync with the actual chip status 808 * then Wi-Fi is shut-down. 809 */ 810 @Test testCacheMismatchError()811 public void testCacheMismatchError() throws Exception { 812 BaselineChip chipMock = new BaselineChip(); 813 chipMock.initialize(); 814 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 815 mManagerStatusListenerMock); 816 executeAndValidateInitializationSequence(); 817 executeAndValidateStartupSequence(); 818 819 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock( 820 HalDeviceManager.InterfaceDestroyedListener.class); 821 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock( 822 HalDeviceManager.InterfaceAvailableForRequestListener.class); 823 824 HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock( 825 HalDeviceManager.InterfaceDestroyedListener.class); 826 HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock( 827 HalDeviceManager.InterfaceAvailableForRequestListener.class); 828 829 // Request STA 830 IWifiIface staIface = validateInterfaceSequence(chipMock, 831 false, // chipModeValid 832 -1000, // chipModeId (only used if chipModeValid is true) 833 IfaceType.STA, // ifaceTypeToCreate 834 "sta0", // ifaceName 835 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 836 null, // tearDownList 837 staDestroyedListener, // destroyedListener 838 staAvailListener // availableListener 839 ); 840 841 // Request NAN 842 IWifiIface nanIface = validateInterfaceSequence(chipMock, 843 true, // chipModeValid 844 BaselineChip.STA_CHIP_MODE_ID, // chipModeId 845 IfaceType.NAN, // ifaceTypeToCreate 846 "nan0", // ifaceName 847 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 848 null, // tearDownList 849 nanDestroyedListener, // destroyedListener 850 nanAvailListener // availableListener 851 ); 852 853 // fiddle with the "chip" by removing the STA 854 chipMock.interfaceNames.get(IfaceType.STA).remove("sta0"); 855 856 // now try to request another NAN 857 nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper()); 858 mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener, 859 mTestLooper.getLooper()); 860 collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue()); 861 862 // verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are 863 // registered (even if they seem out-of-sync to chip) 864 mTestLooper.dispatchAll(); 865 verify(mWifiMock, times(2)).stop(); 866 verify(mManagerStatusListenerMock, times(2)).onStatusChanged(); 867 verify(staDestroyedListener).onDestroyed(); 868 verify(nanDestroyedListener).onDestroyed(); 869 870 verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener, 871 nanDestroyedListener, nanAvailListener); 872 } 873 874 /** 875 * Validates that trying to allocate a STA and then another STA fails. Only one STA at a time 876 * is permitted (by baseline chip). 877 */ 878 @Test testDuplicateStaRequests()879 public void testDuplicateStaRequests() throws Exception { 880 BaselineChip chipMock = new BaselineChip(); 881 chipMock.initialize(); 882 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 883 mManagerStatusListenerMock); 884 executeAndValidateInitializationSequence(); 885 executeAndValidateStartupSequence(); 886 887 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener1 = mock( 888 HalDeviceManager.InterfaceDestroyedListener.class); 889 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener1 = mock( 890 HalDeviceManager.InterfaceAvailableForRequestListener.class); 891 892 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock( 893 HalDeviceManager.InterfaceDestroyedListener.class); 894 895 // get STA interface 896 IWifiIface staIface1 = validateInterfaceSequence(chipMock, 897 false, // chipModeValid 898 -1000, // chipModeId (only used if chipModeValid is true) 899 IfaceType.STA, // ifaceTypeToCreate 900 "sta0", // ifaceName 901 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 902 null, // tearDownList 903 staDestroyedListener1, // destroyedListener 904 staAvailListener1 // availableListener 905 ); 906 collector.checkThat("STA created", staIface1, IsNull.notNullValue()); 907 908 // get STA interface again 909 IWifiIface staIface2 = mDut.createStaIface(staDestroyedListener2, mTestLooper.getLooper()); 910 collector.checkThat("STA created", staIface2, IsNull.nullValue()); 911 912 verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener1, 913 staAvailListener1, staDestroyedListener2); 914 } 915 916 /** 917 * Validates that a duplicate registration of the same InterfaceAvailableForRequestListener 918 * listener will result in a single callback. 919 * 920 * Also validates that get an immediate call on registration if available. 921 */ 922 @Test testDuplicateAvailableRegistrations()923 public void testDuplicateAvailableRegistrations() throws Exception { 924 BaselineChip chipMock = new BaselineChip(); 925 chipMock.initialize(); 926 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 927 mManagerStatusListenerMock); 928 executeAndValidateInitializationSequence(); 929 executeAndValidateStartupSequence(); 930 931 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock( 932 HalDeviceManager.InterfaceAvailableForRequestListener.class); 933 934 // get STA interface 935 IWifiIface staIface = validateInterfaceSequence(chipMock, 936 false, // chipModeValid 937 -1000, // chipModeId (only used if chipModeValid is true) 938 IfaceType.STA, // ifaceTypeToCreate 939 "sta0", // ifaceName 940 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode 941 null, // tearDownList 942 null, // destroyedListener 943 null // availableListener 944 ); 945 collector.checkThat("STA created", staIface, IsNull.notNullValue()); 946 947 // act: register the same listener twice 948 mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener, 949 mTestLooper.getLooper()); 950 mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener, 951 mTestLooper.getLooper()); 952 mTestLooper.dispatchAll(); 953 954 // remove STA interface -> should trigger callbacks 955 mDut.removeIface(staIface); 956 mTestLooper.dispatchAll(); 957 958 // verify: only a single trigger 959 verify(staAvailListener).onAvailableForRequest(); 960 961 verifyNoMoreInteractions(staAvailListener); 962 } 963 964 /** 965 * Validate that the getSupportedIfaceTypes API works when requesting for all chips. 966 */ 967 @Test testGetSupportedIfaceTypesAll()968 public void testGetSupportedIfaceTypesAll() throws Exception { 969 BaselineChip chipMock = new BaselineChip(); 970 chipMock.initialize(); 971 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 972 mManagerStatusListenerMock); 973 executeAndValidateInitializationSequence(); 974 executeAndValidateStartupSequence(); 975 976 // try API 977 Set<Integer> results = mDut.getSupportedIfaceTypes(); 978 979 // verify results 980 Set<Integer> correctResults = new HashSet<>(); 981 correctResults.add(IfaceType.AP); 982 correctResults.add(IfaceType.STA); 983 correctResults.add(IfaceType.P2P); 984 correctResults.add(IfaceType.NAN); 985 986 assertEquals(correctResults, results); 987 } 988 989 /** 990 * Validate that the getSupportedIfaceTypes API works when requesting for a specific chip. 991 */ 992 @Test testGetSupportedIfaceTypesOneChip()993 public void testGetSupportedIfaceTypesOneChip() throws Exception { 994 BaselineChip chipMock = new BaselineChip(); 995 chipMock.initialize(); 996 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 997 mManagerStatusListenerMock); 998 executeAndValidateInitializationSequence(); 999 executeAndValidateStartupSequence(); 1000 1001 // try API 1002 Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip); 1003 1004 // verify results 1005 Set<Integer> correctResults = new HashSet<>(); 1006 correctResults.add(IfaceType.AP); 1007 correctResults.add(IfaceType.STA); 1008 correctResults.add(IfaceType.P2P); 1009 correctResults.add(IfaceType.NAN); 1010 1011 assertEquals(correctResults, results); 1012 } 1013 1014 /** 1015 * Validate that when no chip info is found an empty list is returned. 1016 */ 1017 @Test testGetSupportedIfaceTypesError()1018 public void testGetSupportedIfaceTypesError() throws Exception { 1019 // try API 1020 Set<Integer> results = mDut.getSupportedIfaceTypes(); 1021 1022 // verify results 1023 assertEquals(0, results.size()); 1024 } 1025 1026 /** 1027 * Test start HAL can retry upon failure. 1028 */ 1029 @Test testStartHalRetryUponNotAvailableFailure()1030 public void testStartHalRetryUponNotAvailableFailure() throws Exception { 1031 // Override the stubbing for mWifiMock in before(). 1032 when(mWifiMock.start()) 1033 .thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE)) 1034 .thenReturn(mStatusOk); 1035 1036 BaselineChip chipMock = new BaselineChip(); 1037 chipMock.initialize(); 1038 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 1039 mManagerStatusListenerMock); 1040 executeAndValidateInitializationSequence(); 1041 executeAndValidateStartupSequence(2, true); 1042 } 1043 1044 /** 1045 * Test start HAL fails after multiple retry failures. 1046 */ 1047 @Test testStartHalRetryFailUponMultipleNotAvailableFailures()1048 public void testStartHalRetryFailUponMultipleNotAvailableFailures() throws Exception { 1049 // Override the stubbing for mWifiMock in before(). 1050 when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE)); 1051 1052 BaselineChip chipMock = new BaselineChip(); 1053 chipMock.initialize(); 1054 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip); 1055 executeAndValidateInitializationSequence(); 1056 executeAndValidateStartupSequence(START_HAL_RETRY_TIMES + 1, false); 1057 } 1058 1059 /** 1060 * Test start HAL fails after multiple retry failures. 1061 */ 1062 @Test testStartHalRetryFailUponTrueFailure()1063 public void testStartHalRetryFailUponTrueFailure() throws Exception { 1064 // Override the stubbing for mWifiMock in before(). 1065 when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_UNKNOWN)); 1066 1067 BaselineChip chipMock = new BaselineChip(); 1068 chipMock.initialize(); 1069 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip); 1070 executeAndValidateInitializationSequence(); 1071 executeAndValidateStartupSequence(1, false); 1072 } 1073 1074 /** 1075 * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in 1076 * the VINTF. 1077 */ 1078 @Test testIsSupportedTrue()1079 public void testIsSupportedTrue() throws Exception { 1080 mInOrder = inOrder(mServiceManagerMock, mWifiMock); 1081 executeAndValidateInitializationSequence(); 1082 assertTrue(mDut.isSupported()); 1083 } 1084 1085 /** 1086 * Validate that isSupported() returns false when IServiceManager does not find the vendor HAL 1087 * daemon in the VINTF. 1088 */ 1089 @Test testIsSupportedFalse()1090 public void testIsSupportedFalse() throws Exception { 1091 when(mServiceManagerMock.getTransport( 1092 eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME))) 1093 .thenReturn(IServiceManager.Transport.EMPTY); 1094 mInOrder = inOrder(mServiceManagerMock, mWifiMock); 1095 executeAndValidateInitializationSequence(false); 1096 assertFalse(mDut.isSupported()); 1097 } 1098 1099 // utilities dumpDut(String prefix)1100 private void dumpDut(String prefix) { 1101 StringWriter sw = new StringWriter(); 1102 mDut.dump(null, new PrintWriter(sw), null); 1103 Log.e("HalDeviceManager", prefix + sw.toString()); 1104 } 1105 executeAndValidateInitializationSequence()1106 private void executeAndValidateInitializationSequence() throws Exception { 1107 executeAndValidateInitializationSequence(true); 1108 } 1109 executeAndValidateInitializationSequence(boolean isSupported)1110 private void executeAndValidateInitializationSequence(boolean isSupported) throws Exception { 1111 // act: 1112 mDut.initialize(); 1113 1114 // verify: service manager initialization sequence 1115 mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class), 1116 anyLong()); 1117 mInOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName), 1118 eq(""), mServiceNotificationCaptor.capture()); 1119 1120 // The service should already be up at this point. 1121 mInOrder.verify(mServiceManagerMock).getTransport(eq(IWifi.kInterfaceName), 1122 eq(HalDeviceManager.HAL_INSTANCE_NAME)); 1123 1124 // verify: wifi initialization sequence if vendor HAL is supported. 1125 if (isSupported) { 1126 mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong()); 1127 mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture()); 1128 // verify: onStop called as a part of initialize. 1129 mInOrder.verify(mWifiMock).stop(); 1130 collector.checkThat("isReady is true", mDut.isReady(), equalTo(true)); 1131 } else { 1132 collector.checkThat("isReady is false", mDut.isReady(), equalTo(false)); 1133 } 1134 } 1135 executeAndValidateStartupSequence()1136 private void executeAndValidateStartupSequence()throws Exception { 1137 executeAndValidateStartupSequence(1, true); 1138 } 1139 executeAndValidateStartupSequence(int numAttempts, boolean success)1140 private void executeAndValidateStartupSequence(int numAttempts, boolean success) 1141 throws Exception { 1142 // act: register listener & start Wi-Fi 1143 mDut.registerStatusListener(mManagerStatusListenerMock, mTestLooper.getLooper()); 1144 collector.checkThat(mDut.start(), equalTo(success)); 1145 1146 // verify 1147 mInOrder.verify(mWifiMock, times(numAttempts)).start(); 1148 1149 if (success) { 1150 // act: trigger onStart callback of IWifiEventCallback 1151 mWifiEventCallbackCaptor.getValue().onStart(); 1152 mTestLooper.dispatchAll(); 1153 1154 // verify: onStart called on registered listener 1155 mInOrder.verify(mManagerStatusListenerMock).onStatusChanged(); 1156 } 1157 } 1158 validateInterfaceSequence(ChipMockBase chipMock, boolean chipModeValid, int chipModeId, int ifaceTypeToCreate, String ifaceName, int finalChipMode, IWifiIface[] tearDownList, HalDeviceManager.InterfaceDestroyedListener destroyedListener, HalDeviceManager.InterfaceAvailableForRequestListener availableListener, HalDeviceManager.InterfaceDestroyedListener... destroyedInterfacesDestroyedListeners)1159 private IWifiIface validateInterfaceSequence(ChipMockBase chipMock, 1160 boolean chipModeValid, int chipModeId, 1161 int ifaceTypeToCreate, String ifaceName, int finalChipMode, IWifiIface[] tearDownList, 1162 HalDeviceManager.InterfaceDestroyedListener destroyedListener, 1163 HalDeviceManager.InterfaceAvailableForRequestListener availableListener, 1164 HalDeviceManager.InterfaceDestroyedListener... destroyedInterfacesDestroyedListeners) 1165 throws Exception { 1166 // configure chip mode response 1167 chipMock.chipModeValid = chipModeValid; 1168 chipMock.chipModeId = chipModeId; 1169 1170 IWifiIface iface = null; 1171 1172 // configure: interface to be created 1173 // act: request the interface 1174 switch (ifaceTypeToCreate) { 1175 case IfaceType.STA: 1176 iface = mock(IWifiStaIface.class); 1177 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 1178 any(IWifiIface.getNameCallback.class)); 1179 doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType( 1180 any(IWifiIface.getTypeCallback.class)); 1181 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 1182 chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class)); 1183 1184 mDut.createStaIface(destroyedListener, mTestLooper.getLooper()); 1185 break; 1186 case IfaceType.AP: 1187 iface = mock(IWifiApIface.class); 1188 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 1189 any(IWifiIface.getNameCallback.class)); 1190 doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType( 1191 any(IWifiIface.getTypeCallback.class)); 1192 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 1193 chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class)); 1194 1195 mDut.createApIface(destroyedListener, mTestLooper.getLooper()); 1196 break; 1197 case IfaceType.P2P: 1198 iface = mock(IWifiP2pIface.class); 1199 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 1200 any(IWifiIface.getNameCallback.class)); 1201 doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType( 1202 any(IWifiIface.getTypeCallback.class)); 1203 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 1204 chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class)); 1205 1206 mDut.createP2pIface(destroyedListener, mTestLooper.getLooper()); 1207 break; 1208 case IfaceType.NAN: 1209 iface = mock(IWifiNanIface.class); 1210 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 1211 any(IWifiIface.getNameCallback.class)); 1212 doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType( 1213 any(IWifiIface.getTypeCallback.class)); 1214 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 1215 chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class)); 1216 1217 mDut.createNanIface(destroyedListener, mTestLooper.getLooper()); 1218 break; 1219 } 1220 if (availableListener != null) { 1221 mDut.registerInterfaceAvailableForRequestListener(ifaceTypeToCreate, availableListener, 1222 mTestLooper.getLooper()); 1223 } 1224 1225 // validate: optional tear down of interfaces 1226 if (tearDownList != null) { 1227 for (IWifiIface tearDownIface: tearDownList) { 1228 switch (getType(tearDownIface)) { 1229 case IfaceType.STA: 1230 mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface)); 1231 break; 1232 case IfaceType.AP: 1233 mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface)); 1234 break; 1235 case IfaceType.P2P: 1236 mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface)); 1237 break; 1238 case IfaceType.NAN: 1239 mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface)); 1240 break; 1241 } 1242 } 1243 } 1244 1245 // validate: optional switch to the requested mode 1246 if (!chipModeValid || chipModeId != finalChipMode) { 1247 mInOrder.verify(chipMock.chip).configureChip(finalChipMode); 1248 } else { 1249 mInOrder.verify(chipMock.chip, times(0)).configureChip(anyInt()); 1250 } 1251 1252 // validate: create interface 1253 switch (ifaceTypeToCreate) { 1254 case IfaceType.STA: 1255 mInOrder.verify(chipMock.chip).createStaIface( 1256 any(IWifiChip.createStaIfaceCallback.class)); 1257 break; 1258 case IfaceType.AP: 1259 mInOrder.verify(chipMock.chip).createApIface( 1260 any(IWifiChip.createApIfaceCallback.class)); 1261 break; 1262 case IfaceType.P2P: 1263 mInOrder.verify(chipMock.chip).createP2pIface( 1264 any(IWifiChip.createP2pIfaceCallback.class)); 1265 break; 1266 case IfaceType.NAN: 1267 mInOrder.verify(chipMock.chip).createNanIface( 1268 any(IWifiChip.createNanIfaceCallback.class)); 1269 break; 1270 } 1271 1272 // verify: callbacks on deleted interfaces 1273 mTestLooper.dispatchAll(); 1274 for (int i = 0; i < destroyedInterfacesDestroyedListeners.length; ++i) { 1275 verify(destroyedInterfacesDestroyedListeners[i]).onDestroyed(); 1276 } 1277 1278 return iface; 1279 } 1280 getType(IWifiIface iface)1281 private int getType(IWifiIface iface) throws Exception { 1282 Mutable<Integer> typeResp = new Mutable<>(); 1283 iface.getType((WifiStatus status, int type) -> { 1284 typeResp.value = type; 1285 }); 1286 return typeResp.value; 1287 } 1288 getName(IWifiIface iface)1289 private String getName(IWifiIface iface) throws Exception { 1290 Mutable<String> nameResp = new Mutable<>(); 1291 iface.getName((WifiStatus status, String name) -> { 1292 nameResp.value = name; 1293 }); 1294 return nameResp.value; 1295 } 1296 getStatus(int code)1297 private WifiStatus getStatus(int code) { 1298 WifiStatus status = new WifiStatus(); 1299 status.code = code; 1300 return status; 1301 } 1302 1303 private static class Mutable<E> { 1304 public E value; 1305 Mutable()1306 Mutable() { 1307 value = null; 1308 } 1309 Mutable(E value)1310 Mutable(E value) { 1311 this.value = value; 1312 } 1313 } 1314 1315 // Answer objects 1316 private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments { 1317 private WifiStatus mStatus; 1318 private ArrayList<Integer> mChipIds; 1319 GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds)1320 GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) { 1321 mStatus = status; 1322 mChipIds = chipIds; 1323 } 1324 answer(IWifi.getChipIdsCallback cb)1325 public void answer(IWifi.getChipIdsCallback cb) { 1326 cb.onValues(mStatus, mChipIds); 1327 } 1328 } 1329 1330 private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments { 1331 private WifiStatus mStatus; 1332 private IWifiChip mChip; 1333 GetChipAnswer(WifiStatus status, IWifiChip chip)1334 GetChipAnswer(WifiStatus status, IWifiChip chip) { 1335 mStatus = status; 1336 mChip = chip; 1337 } 1338 answer(int chipId, IWifi.getChipCallback cb)1339 public void answer(int chipId, IWifi.getChipCallback cb) { 1340 cb.onValues(mStatus, mChip); 1341 } 1342 } 1343 1344 private class GetIdAnswer extends MockAnswerUtil.AnswerWithArguments { 1345 private ChipMockBase mChipMockBase; 1346 GetIdAnswer(ChipMockBase chipMockBase)1347 GetIdAnswer(ChipMockBase chipMockBase) { 1348 mChipMockBase = chipMockBase; 1349 } 1350 answer(IWifiChip.getIdCallback cb)1351 public void answer(IWifiChip.getIdCallback cb) { 1352 cb.onValues(mStatusOk, mChipMockBase.chipId); 1353 } 1354 } 1355 1356 private class GetAvailableModesAnswer extends MockAnswerUtil.AnswerWithArguments { 1357 private ChipMockBase mChipMockBase; 1358 GetAvailableModesAnswer(ChipMockBase chipMockBase)1359 GetAvailableModesAnswer(ChipMockBase chipMockBase) { 1360 mChipMockBase = chipMockBase; 1361 } 1362 answer(IWifiChip.getAvailableModesCallback cb)1363 public void answer(IWifiChip.getAvailableModesCallback cb) { 1364 cb.onValues(mStatusOk, mChipMockBase.availableModes); 1365 } 1366 } 1367 1368 private class GetModeAnswer extends MockAnswerUtil.AnswerWithArguments { 1369 private ChipMockBase mChipMockBase; 1370 GetModeAnswer(ChipMockBase chipMockBase)1371 GetModeAnswer(ChipMockBase chipMockBase) { 1372 mChipMockBase = chipMockBase; 1373 } 1374 answer(IWifiChip.getModeCallback cb)1375 public void answer(IWifiChip.getModeCallback cb) { 1376 cb.onValues(mChipMockBase.chipModeValid ? mStatusOk 1377 : getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId); 1378 } 1379 } 1380 1381 private class ConfigureChipAnswer extends MockAnswerUtil.AnswerWithArguments { 1382 private ChipMockBase mChipMockBase; 1383 ConfigureChipAnswer(ChipMockBase chipMockBase)1384 ConfigureChipAnswer(ChipMockBase chipMockBase) { 1385 mChipMockBase = chipMockBase; 1386 } 1387 answer(int chipMode)1388 public WifiStatus answer(int chipMode) { 1389 mChipMockBase.chipModeId = chipMode; 1390 return mStatusOk; 1391 } 1392 } 1393 1394 private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments { 1395 private ChipMockBase mChipMockBase; 1396 GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase)1397 GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) { 1398 mChipMockBase = chipMockBase; 1399 } 1400 answer(IWifiChip.getStaIfaceNamesCallback cb)1401 public void answer(IWifiChip.getStaIfaceNamesCallback cb) { 1402 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA)); 1403 } 1404 answer(IWifiChip.getApIfaceNamesCallback cb)1405 public void answer(IWifiChip.getApIfaceNamesCallback cb) { 1406 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP)); 1407 } 1408 answer(IWifiChip.getP2pIfaceNamesCallback cb)1409 public void answer(IWifiChip.getP2pIfaceNamesCallback cb) { 1410 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P)); 1411 } 1412 answer(IWifiChip.getNanIfaceNamesCallback cb)1413 public void answer(IWifiChip.getNanIfaceNamesCallback cb) { 1414 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN)); 1415 } 1416 } 1417 1418 private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 1419 private ChipMockBase mChipMockBase; 1420 GetXxxIfaceAnswer(ChipMockBase chipMockBase)1421 GetXxxIfaceAnswer(ChipMockBase chipMockBase) { 1422 mChipMockBase = chipMockBase; 1423 } 1424 answer(String name, IWifiChip.getStaIfaceCallback cb)1425 public void answer(String name, IWifiChip.getStaIfaceCallback cb) { 1426 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name); 1427 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface); 1428 } 1429 answer(String name, IWifiChip.getApIfaceCallback cb)1430 public void answer(String name, IWifiChip.getApIfaceCallback cb) { 1431 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name); 1432 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface); 1433 } 1434 answer(String name, IWifiChip.getP2pIfaceCallback cb)1435 public void answer(String name, IWifiChip.getP2pIfaceCallback cb) { 1436 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name); 1437 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface); 1438 } 1439 answer(String name, IWifiChip.getNanIfaceCallback cb)1440 public void answer(String name, IWifiChip.getNanIfaceCallback cb) { 1441 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name); 1442 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface); 1443 } 1444 } 1445 1446 private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 1447 private ChipMockBase mChipMockBase; 1448 private WifiStatus mStatus; 1449 private IWifiIface mWifiIface; 1450 CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface)1451 CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) { 1452 mChipMockBase = chipMockBase; 1453 mStatus = status; 1454 mWifiIface = wifiIface; 1455 } 1456 addInterfaceInfo(int type)1457 private void addInterfaceInfo(int type) { 1458 if (mStatus.code == WifiStatusCode.SUCCESS) { 1459 try { 1460 mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface)); 1461 mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface); 1462 } catch (Exception e) { 1463 // do nothing 1464 } 1465 } 1466 } 1467 answer(IWifiChip.createStaIfaceCallback cb)1468 public void answer(IWifiChip.createStaIfaceCallback cb) { 1469 cb.onValues(mStatus, (IWifiStaIface) mWifiIface); 1470 addInterfaceInfo(IfaceType.STA); 1471 } 1472 answer(IWifiChip.createApIfaceCallback cb)1473 public void answer(IWifiChip.createApIfaceCallback cb) { 1474 cb.onValues(mStatus, (IWifiApIface) mWifiIface); 1475 addInterfaceInfo(IfaceType.AP); 1476 } 1477 answer(IWifiChip.createP2pIfaceCallback cb)1478 public void answer(IWifiChip.createP2pIfaceCallback cb) { 1479 cb.onValues(mStatus, (IWifiP2pIface) mWifiIface); 1480 addInterfaceInfo(IfaceType.P2P); 1481 } 1482 answer(IWifiChip.createNanIfaceCallback cb)1483 public void answer(IWifiChip.createNanIfaceCallback cb) { 1484 cb.onValues(mStatus, (IWifiNanIface) mWifiIface); 1485 addInterfaceInfo(IfaceType.NAN); 1486 } 1487 } 1488 1489 private class RemoveXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 1490 private ChipMockBase mChipMockBase; 1491 private int mType; 1492 RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type)1493 RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) { 1494 mChipMockBase = chipMockBase; 1495 mType = type; 1496 } 1497 removeIface(int type, String ifname)1498 private WifiStatus removeIface(int type, String ifname) { 1499 try { 1500 if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) { 1501 return mStatusFail; 1502 } 1503 if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) { 1504 return mStatusFail; 1505 } 1506 } catch (Exception e) { 1507 return mStatusFail; 1508 } 1509 return mStatusOk; 1510 } 1511 answer(String ifname)1512 public WifiStatus answer(String ifname) { 1513 return removeIface(mType, ifname); 1514 } 1515 } 1516 1517 private class GetNameAnswer extends MockAnswerUtil.AnswerWithArguments { 1518 private String mName; 1519 GetNameAnswer(String name)1520 GetNameAnswer(String name) { 1521 mName = name; 1522 } 1523 answer(IWifiIface.getNameCallback cb)1524 public void answer(IWifiIface.getNameCallback cb) { 1525 cb.onValues(mStatusOk, mName); 1526 } 1527 } 1528 1529 private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments { 1530 private int mType; 1531 GetTypeAnswer(int type)1532 GetTypeAnswer(int type) { 1533 mType = type; 1534 } 1535 answer(IWifiIface.getTypeCallback cb)1536 public void answer(IWifiIface.getTypeCallback cb) { 1537 cb.onValues(mStatusOk, mType); 1538 } 1539 } 1540 1541 // chip configuration 1542 1543 private class ChipMockBase { 1544 public IWifiChip chip; 1545 public int chipId; 1546 public boolean chipModeValid = false; 1547 public int chipModeId = -1000; 1548 public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>(); 1549 public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>(); 1550 1551 public ArrayList<IWifiChip.ChipMode> availableModes; 1552 initialize()1553 void initialize() throws Exception { 1554 chip = mock(IWifiChip.class); 1555 1556 interfaceNames.put(IfaceType.STA, new ArrayList<>()); 1557 interfaceNames.put(IfaceType.AP, new ArrayList<>()); 1558 interfaceNames.put(IfaceType.P2P, new ArrayList<>()); 1559 interfaceNames.put(IfaceType.NAN, new ArrayList<>()); 1560 1561 interfacesByName.put(IfaceType.STA, new HashMap<>()); 1562 interfacesByName.put(IfaceType.AP, new HashMap<>()); 1563 interfacesByName.put(IfaceType.P2P, new HashMap<>()); 1564 interfacesByName.put(IfaceType.NAN, new HashMap<>()); 1565 1566 when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn( 1567 mStatusOk); 1568 when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this)); 1569 doAnswer(new GetIdAnswer(this)).when(chip).getId(any(IWifiChip.getIdCallback.class)); 1570 doAnswer(new GetModeAnswer(this)).when(chip).getMode( 1571 any(IWifiChip.getModeCallback.class)); 1572 GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this); 1573 doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames( 1574 any(IWifiChip.getStaIfaceNamesCallback.class)); 1575 doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames( 1576 any(IWifiChip.getApIfaceNamesCallback.class)); 1577 doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames( 1578 any(IWifiChip.getP2pIfaceNamesCallback.class)); 1579 doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames( 1580 any(IWifiChip.getNanIfaceNamesCallback.class)); 1581 GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this); 1582 doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(), 1583 any(IWifiChip.getStaIfaceCallback.class)); 1584 doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(), 1585 any(IWifiChip.getApIfaceCallback.class)); 1586 doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(), 1587 any(IWifiChip.getP2pIfaceCallback.class)); 1588 doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(), 1589 any(IWifiChip.getNanIfaceCallback.class)); 1590 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface( 1591 anyString()); 1592 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface( 1593 anyString()); 1594 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface( 1595 anyString()); 1596 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface( 1597 anyString()); 1598 } 1599 } 1600 1601 // emulate baseline/legacy config: 1602 // mode: STA + NAN || P2P 1603 // mode: NAN 1604 private class BaselineChip extends ChipMockBase { 1605 static final int STA_CHIP_MODE_ID = 0; 1606 static final int AP_CHIP_MODE_ID = 1; 1607 initialize()1608 void initialize() throws Exception { 1609 super.initialize(); 1610 1611 // chip Id configuration 1612 ArrayList<Integer> chipIds; 1613 chipId = 10; 1614 chipIds = new ArrayList<>(); 1615 chipIds.add(chipId); 1616 doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds( 1617 any(IWifi.getChipIdsCallback.class)); 1618 1619 doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10), 1620 any(IWifi.getChipCallback.class)); 1621 1622 // initialize dummy chip modes 1623 IWifiChip.ChipMode cm; 1624 IWifiChip.ChipIfaceCombination cic; 1625 IWifiChip.ChipIfaceCombinationLimit cicl; 1626 1627 // Mode 0: 1xSTA + 1x{P2P,NAN} 1628 // Mode 1: 1xAP 1629 availableModes = new ArrayList<>(); 1630 cm = new IWifiChip.ChipMode(); 1631 cm.id = STA_CHIP_MODE_ID; 1632 1633 cic = new IWifiChip.ChipIfaceCombination(); 1634 1635 cicl = new IWifiChip.ChipIfaceCombinationLimit(); 1636 cicl.maxIfaces = 1; 1637 cicl.types.add(IfaceType.STA); 1638 cic.limits.add(cicl); 1639 1640 cicl = new IWifiChip.ChipIfaceCombinationLimit(); 1641 cicl.maxIfaces = 1; 1642 cicl.types.add(IfaceType.P2P); 1643 cicl.types.add(IfaceType.NAN); 1644 cic.limits.add(cicl); 1645 cm.availableCombinations.add(cic); 1646 availableModes.add(cm); 1647 1648 cm = new IWifiChip.ChipMode(); 1649 cm.id = AP_CHIP_MODE_ID; 1650 cic = new IWifiChip.ChipIfaceCombination(); 1651 cicl = new IWifiChip.ChipIfaceCombinationLimit(); 1652 cicl.maxIfaces = 1; 1653 cicl.types.add(IfaceType.AP); 1654 cic.limits.add(cicl); 1655 cm.availableCombinations.add(cic); 1656 availableModes.add(cm); 1657 1658 doAnswer(new GetAvailableModesAnswer(this)).when(chip) 1659 .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class)); 1660 } 1661 } 1662 } 1663