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