HalDeviceManagerTest.java revision d887e5c6bf4abf2f098ea6f087e717e29c551548
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.ManagerStatusCallback mManagerStatusCallbackMock; 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, mManagerStatusCallbackMock); 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(mManagerStatusCallbackMock).onStop(); 154 155 verifyNoMoreInteractions(mManagerStatusCallbackMock); 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, mManagerStatusCallbackMock); 165 executeAndValidateInitializationSequence(); 166 167 // register another 2 callbacks - one of them twice 168 HalDeviceManager.ManagerStatusCallback callback1 = mock( 169 HalDeviceManager.ManagerStatusCallback.class); 170 HalDeviceManager.ManagerStatusCallback callback2 = mock( 171 HalDeviceManager.ManagerStatusCallback.class); 172 mDut.registerStatusCallback(callback2, mTestLooper.getLooper()); 173 mDut.registerStatusCallback(callback1, mTestLooper.getLooper()); 174 mDut.registerStatusCallback(callback2, mTestLooper.getLooper()); 175 176 // startup 177 executeAndValidateStartupSequence(); 178 179 // verify 180 verify(callback1).onStart(); 181 verify(callback2).onStart(); 182 183 verifyNoMoreInteractions(mManagerStatusCallbackMock, 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, mManagerStatusCallbackMock); 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(mManagerStatusCallbackMock).onStop(); 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(mManagerStatusCallbackMock).onStart(); 217 218 verifyNoMoreInteractions(mManagerStatusCallbackMock); 219 } 220 221 /** 222 * Validate IWifi onFailure causes notification 223 */ 224 @Test 225 public void testWifiFail() throws Exception { 226 mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusCallbackMock); 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(mManagerStatusCallbackMock).onStop(); 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(mManagerStatusCallbackMock).onStart(); 245 246 verifyNoMoreInteractions(mManagerStatusCallbackMock); 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 mManagerStatusCallbackMock); 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, false, -1000, 269 IfaceType.STA, name, BaselineChip.STA_CHIP_MODE_ID, null, idl, iafrl); 270 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 271 272 // act: remove interface 273 mDut.removeIface(iface); 274 mTestLooper.dispatchAll(); 275 276 // verify: callback triggered 277 mInOrder.verify(chipMock.chip).removeStaIface(name); 278 verify(idl).onDestroyed(); 279 280 verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl); 281 } 282 283 /** 284 * Validate creation of AP interface from blank start-up. The remove interface. 285 */ 286 @Test 287 public void testCreateApInterfaceNoInitMode() throws Exception { 288 final String name = "ap0"; 289 290 BaselineChip chipMock = new BaselineChip(); 291 chipMock.initialize(); 292 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 293 mManagerStatusCallbackMock); 294 executeAndValidateInitializationSequence(); 295 executeAndValidateStartupSequence(); 296 297 HalDeviceManager.InterfaceDestroyedListener idl = mock( 298 HalDeviceManager.InterfaceDestroyedListener.class); 299 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 300 HalDeviceManager.InterfaceAvailableForRequestListener.class); 301 302 IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, false, -1000, 303 IfaceType.AP, name, BaselineChip.AP_CHIP_MODE_ID, null, idl, iafrl); 304 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 305 306 // act: remove interface 307 mDut.removeIface(iface); 308 mTestLooper.dispatchAll(); 309 310 // verify: callback triggered 311 mInOrder.verify(chipMock.chip).removeApIface(name); 312 verify(idl).onDestroyed(); 313 314 verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl); 315 } 316 317 /** 318 * Validate creation of P2P interface from blank start-up. The remove interface. 319 */ 320 @Test 321 public void testCreateP2pInterfaceNoInitMode() throws Exception { 322 final String name = "p2p0"; 323 324 BaselineChip chipMock = new BaselineChip(); 325 chipMock.initialize(); 326 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 327 mManagerStatusCallbackMock); 328 executeAndValidateInitializationSequence(); 329 executeAndValidateStartupSequence(); 330 331 HalDeviceManager.InterfaceDestroyedListener idl = mock( 332 HalDeviceManager.InterfaceDestroyedListener.class); 333 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 334 HalDeviceManager.InterfaceAvailableForRequestListener.class); 335 336 IWifiP2pIface iface = (IWifiP2pIface) validateInterfaceSequence(chipMock, false, -1000, 337 IfaceType.P2P, name, BaselineChip.STA_CHIP_MODE_ID, null, idl, iafrl); 338 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 339 340 // act: remove interface 341 mDut.removeIface(iface); 342 mTestLooper.dispatchAll(); 343 344 // verify: callback triggered 345 mInOrder.verify(chipMock.chip).removeP2pIface(name); 346 verify(idl).onDestroyed(); 347 348 verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl); 349 } 350 351 /** 352 * Validate creation of NAN interface from blank start-up. The remove interface. 353 */ 354 @Test 355 public void testCreateNanInterfaceNoInitMode() throws Exception { 356 final String name = "nan0"; 357 358 BaselineChip chipMock = new BaselineChip(); 359 chipMock.initialize(); 360 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 361 mManagerStatusCallbackMock); 362 executeAndValidateInitializationSequence(); 363 executeAndValidateStartupSequence(); 364 365 HalDeviceManager.InterfaceDestroyedListener idl = mock( 366 HalDeviceManager.InterfaceDestroyedListener.class); 367 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 368 HalDeviceManager.InterfaceAvailableForRequestListener.class); 369 370 IWifiNanIface iface = (IWifiNanIface) validateInterfaceSequence(chipMock, false, -1000, 371 IfaceType.NAN, name, BaselineChip.STA_CHIP_MODE_ID, null, idl, iafrl); 372 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 373 374 // act: remove interface 375 mDut.removeIface(iface); 376 mTestLooper.dispatchAll(); 377 378 // verify: callback triggered 379 mInOrder.verify(chipMock.chip).removeNanIface(name); 380 verify(idl).onDestroyed(); 381 382 verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl); 383 } 384 385 /** 386 * Validate creation of AP interface when in STA mode - but with no interface created. Expect 387 * a change in chip mode. 388 */ 389 @Test 390 public void testCreateApWithStaModeUp() throws Exception { 391 final String name = "ap0"; 392 393 BaselineChip chipMock = new BaselineChip(); 394 chipMock.initialize(); 395 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 396 mManagerStatusCallbackMock); 397 executeAndValidateInitializationSequence(); 398 executeAndValidateStartupSequence(); 399 400 HalDeviceManager.InterfaceDestroyedListener idl = mock( 401 HalDeviceManager.InterfaceDestroyedListener.class); 402 HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock( 403 HalDeviceManager.InterfaceAvailableForRequestListener.class); 404 405 IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, true, 406 BaselineChip.STA_CHIP_MODE_ID, IfaceType.AP, name, 407 BaselineChip.AP_CHIP_MODE_ID, null, idl, iafrl); 408 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 409 410 // act: stop Wi-Fi 411 mDut.stop(); 412 mTestLooper.dispatchAll(); 413 414 // verify: callback triggered 415 verify(idl).onDestroyed(); 416 verify(mManagerStatusCallbackMock).onStop(); 417 418 verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl); 419 } 420 421 /** 422 * Validate creation of AP interface when in AP mode - but with no interface created. Expect 423 * no change in chip mode. 424 */ 425 @Test 426 public void testCreateApWithApModeUp() throws Exception { 427 final String name = "ap0"; 428 429 BaselineChip chipMock = new BaselineChip(); 430 chipMock.initialize(); 431 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 432 mManagerStatusCallbackMock); 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, true, 442 BaselineChip.AP_CHIP_MODE_ID, IfaceType.AP, name, 443 BaselineChip.AP_CHIP_MODE_ID, null, idl, iafrl); 444 collector.checkThat("allocated interface", iface, IsNull.notNullValue()); 445 446 // act: stop Wi-Fi 447 mDut.stop(); 448 mTestLooper.dispatchAll(); 449 450 // verify: callback triggered 451 verify(idl).onDestroyed(); 452 verify(mManagerStatusCallbackMock).onStop(); 453 454 verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl); 455 } 456 457 /** 458 * Validate AP up/down creation of AP interface when a STA already created. Expect: 459 * - STA created 460 * - P2P created 461 * - When AP requested: 462 * - STA & P2P torn down 463 * - AP created 464 * - P2P creation refused 465 * - Request STA: will tear down AP 466 * - When AP destroyed: 467 * - Get p2p available listener callback 468 * - Can create P2P when requested 469 * - Create P2P 470 * - Request NAN: will get refused 471 * - Tear down P2P: 472 * - should get nan available listener callback 473 * - Can create NAN when requested 474 */ 475 @Test 476 public void testCreateSameAndDiffPriorities() throws Exception { 477 BaselineChip chipMock = new BaselineChip(); 478 chipMock.initialize(); 479 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 480 mManagerStatusCallbackMock); 481 executeAndValidateInitializationSequence(); 482 executeAndValidateStartupSequence(); 483 484 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock( 485 HalDeviceManager.InterfaceDestroyedListener.class); 486 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock( 487 HalDeviceManager.InterfaceAvailableForRequestListener.class); 488 489 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock( 490 HalDeviceManager.InterfaceDestroyedListener.class); 491 492 HalDeviceManager.InterfaceDestroyedListener apDestroyedListener = mock( 493 HalDeviceManager.InterfaceDestroyedListener.class); 494 HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock( 495 HalDeviceManager.InterfaceAvailableForRequestListener.class); 496 497 HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock( 498 HalDeviceManager.InterfaceDestroyedListener.class); 499 HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock( 500 HalDeviceManager.InterfaceAvailableForRequestListener.class); 501 502 HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener2 = mock( 503 HalDeviceManager.InterfaceDestroyedListener.class); 504 505 HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock( 506 HalDeviceManager.InterfaceDestroyedListener.class); 507 HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock( 508 HalDeviceManager.InterfaceAvailableForRequestListener.class); 509 510 // Request STA 511 IWifiIface staIface = validateInterfaceSequence(chipMock, false, -1000, IfaceType.STA, 512 "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener, 513 staAvailListener); 514 collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue()); 515 516 // register additional InterfaceDestroyedListeners - including a duplicate (verify that 517 // only called once!) 518 mDut.registerDestroyedListener(staIface, staDestroyedListener2, mTestLooper.getLooper()); 519 mDut.registerDestroyedListener(staIface, staDestroyedListener, mTestLooper.getLooper()); 520 521 // Request P2P 522 IWifiIface p2pIface = validateInterfaceSequence(chipMock, true, 523 BaselineChip.STA_CHIP_MODE_ID, IfaceType.P2P, "p2p0", BaselineChip.STA_CHIP_MODE_ID, 524 null, p2pDestroyedListener, p2pAvailListener); 525 collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue()); 526 527 // Request AP 528 IWifiIface apIface = validateInterfaceSequence(chipMock, true, 529 BaselineChip.STA_CHIP_MODE_ID, IfaceType.AP, "ap0", BaselineChip.AP_CHIP_MODE_ID, 530 new IWifiIface[]{staIface, p2pIface}, apDestroyedListener, apAvailListener, 531 staDestroyedListener, staDestroyedListener2, p2pDestroyedListener); 532 collector.checkThat("allocated AP interface", apIface, IsNull.notNullValue()); 533 534 // Request P2P: expect failure 535 p2pIface = mDut.createP2pIface(p2pDestroyedListener, p2pAvailListener, 536 mTestLooper.getLooper()); 537 collector.checkThat("P2P can't be created", p2pIface, IsNull.nullValue()); 538 539 // Request STA: expect success 540 staIface = validateInterfaceSequence(chipMock, true, BaselineChip.AP_CHIP_MODE_ID, 541 IfaceType.STA, "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener, 542 staAvailListener, apDestroyedListener); 543 collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue()); 544 545 mTestLooper.dispatchAll(); 546 verify(apDestroyedListener).onDestroyed(); 547 verify(p2pAvailListener).onAvailableForRequest(); 548 549 // Request P2P: expect success now 550 p2pIface = validateInterfaceSequence(chipMock, true, BaselineChip.STA_CHIP_MODE_ID, 551 IfaceType.STA, "p2p0", BaselineChip.STA_CHIP_MODE_ID, null, p2pDestroyedListener2, 552 p2pAvailListener); 553 554 // Request NAN: should fail 555 IWifiIface nanIface = mDut.createNanIface(nanDestroyedListener, nanAvailListener, 556 mTestLooper.getLooper()); 557 collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue()); 558 559 // Tear down P2P 560 mDut.removeIface(p2pIface); 561 mTestLooper.dispatchAll(); 562 563 verify(chipMock.chip).removeP2pIface("p2p0"); 564 verify(p2pDestroyedListener2).onDestroyed(); 565 verify(nanAvailListener).onAvailableForRequest(); 566 567 // Should now be able to request and get NAN 568 nanIface = validateInterfaceSequence(chipMock, true, BaselineChip.STA_CHIP_MODE_ID, 569 IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID, null, nanDestroyedListener, 570 nanAvailListener); 571 collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue()); 572 573 verifyNoMoreInteractions(mManagerStatusCallbackMock, staDestroyedListener, staAvailListener, 574 staDestroyedListener2, apDestroyedListener, apAvailListener, p2pDestroyedListener, 575 nanDestroyedListener, nanAvailListener, p2pDestroyedListener2); 576 } 577 578 /** 579 * Validate P2P and NAN interactions. Expect: 580 * - STA created 581 * - NAN created 582 * - When P2P requested: 583 * - NAN torn down 584 * - P2P created 585 * - NAN creation refused 586 * - When P2P destroyed: 587 * - get nan available listener 588 * - Can create NAN when requested 589 */ 590 @Test 591 public void testP2pAndNanInteractions() throws Exception { 592 BaselineChip chipMock = new BaselineChip(); 593 chipMock.initialize(); 594 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 595 mManagerStatusCallbackMock); 596 executeAndValidateInitializationSequence(); 597 executeAndValidateStartupSequence(); 598 599 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock( 600 HalDeviceManager.InterfaceDestroyedListener.class); 601 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock( 602 HalDeviceManager.InterfaceAvailableForRequestListener.class); 603 604 HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock( 605 HalDeviceManager.InterfaceDestroyedListener.class); 606 HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock( 607 HalDeviceManager.InterfaceAvailableForRequestListener.class); 608 609 HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock( 610 HalDeviceManager.InterfaceDestroyedListener.class); 611 HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = null; 612 613 // Request STA 614 IWifiIface staIface = validateInterfaceSequence(chipMock, false, -1000, IfaceType.STA, 615 "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener, 616 staAvailListener); 617 618 // Request NAN 619 IWifiIface nanIface = validateInterfaceSequence(chipMock, true, 620 BaselineChip.STA_CHIP_MODE_ID, IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID, 621 null, nanDestroyedListener, nanAvailListener); 622 623 // Request P2P 624 IWifiIface p2pIface = validateInterfaceSequence(chipMock, true, 625 BaselineChip.STA_CHIP_MODE_ID, IfaceType.P2P, "p2p0", BaselineChip.STA_CHIP_MODE_ID, 626 new IWifiIface[]{nanIface}, p2pDestroyedListener, p2pAvailListener, 627 nanDestroyedListener); 628 629 // Request NAN: expect failure 630 nanIface = mDut.createNanIface(nanDestroyedListener, nanAvailListener, 631 mTestLooper.getLooper()); 632 collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue()); 633 634 // Destroy P2P interface 635 boolean status = mDut.removeIface(p2pIface); 636 mInOrder.verify(chipMock.chip).removeP2pIface("p2p0"); 637 collector.checkThat("P2P removal success", status, equalTo(true)); 638 639 mTestLooper.dispatchAll(); 640 verify(p2pDestroyedListener).onDestroyed(); 641 verify(nanAvailListener).onAvailableForRequest(); 642 643 // Request NAN: expect success now 644 nanIface = validateInterfaceSequence(chipMock, true, 645 BaselineChip.STA_CHIP_MODE_ID, IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID, 646 null, nanDestroyedListener, nanAvailListener); 647 648 verifyNoMoreInteractions(mManagerStatusCallbackMock, staDestroyedListener, staAvailListener, 649 nanDestroyedListener, nanAvailListener, p2pDestroyedListener); 650 } 651 652 /** 653 * Validates that when (for some reason) the cache is out-of-sync with the actual chip status 654 * then Wi-Fi is shut-down. 655 */ 656 @Test 657 public void testCacheMismatchError() throws Exception { 658 BaselineChip chipMock = new BaselineChip(); 659 chipMock.initialize(); 660 mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip, 661 mManagerStatusCallbackMock); 662 executeAndValidateInitializationSequence(); 663 executeAndValidateStartupSequence(); 664 665 HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock( 666 HalDeviceManager.InterfaceDestroyedListener.class); 667 HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock( 668 HalDeviceManager.InterfaceAvailableForRequestListener.class); 669 670 HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock( 671 HalDeviceManager.InterfaceDestroyedListener.class); 672 HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock( 673 HalDeviceManager.InterfaceAvailableForRequestListener.class); 674 675 // Request STA 676 IWifiIface staIface = validateInterfaceSequence(chipMock, false, -1000, IfaceType.STA, 677 "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener, 678 staAvailListener); 679 680 // Request NAN 681 IWifiIface nanIface = validateInterfaceSequence(chipMock, true, 682 BaselineChip.STA_CHIP_MODE_ID, IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID, 683 null, nanDestroyedListener, nanAvailListener); 684 685 // fiddle with the "chip" by removing the STA 686 chipMock.interfaceNames.get(IfaceType.STA).remove("sta0"); 687 688 // now try to request another NAN 689 nanIface = mDut.createNanIface(nanDestroyedListener, nanAvailListener, 690 mTestLooper.getLooper()); 691 collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue()); 692 693 // verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are 694 // registered (even if they seem out-of-sync to chip) 695 mTestLooper.dispatchAll(); 696 verify(mWifiMock).stop(); 697 verify(mManagerStatusCallbackMock).onStop(); 698 verify(staDestroyedListener).onDestroyed(); 699 verify(nanDestroyedListener).onDestroyed(); 700 701 verifyNoMoreInteractions(mManagerStatusCallbackMock, staDestroyedListener, staAvailListener, 702 nanDestroyedListener, nanAvailListener); 703 } 704 705 // utilities 706 private void dumpDut(String prefix) { 707 StringWriter sw = new StringWriter(); 708 mDut.dump(null, new PrintWriter(sw), null); 709 Log.e("HalDeviceManager", prefix + sw.toString()); 710 } 711 712 private void executeAndValidateInitializationSequence() throws Exception { 713 InOrder inOrder = inOrder(mServiceManagerMock, mWifiMock); 714 715 // act: 716 mDut.initialize(); 717 718 // verify: service manager initialization sequence 719 mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class), 720 anyLong()); 721 inOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName), 722 eq(""), mServiceNotificationCaptor.capture()); 723 724 // act: get the service started (which happens even when service was already up) 725 mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true); 726 727 // verify: wifi initialization sequence 728 inOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong()); 729 inOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture()); 730 } 731 732 private void executeAndValidateStartupSequence() throws Exception { 733 // act: register listener & start Wi-Fi 734 mDut.registerStatusCallback(mManagerStatusCallbackMock, mTestLooper.getLooper()); 735 mDut.start(); 736 737 // verify 738 mInOrder.verify(mWifiMock).start(); 739 740 // act: trigger onStart callback of IWifiEventCallback 741 mWifiEventCallbackCaptor.getValue().onStart(); 742 mTestLooper.dispatchAll(); 743 744 // verify: onStart called on registered listener 745 mInOrder.verify(mManagerStatusCallbackMock).onStart(); 746 } 747 748 private IWifiIface validateInterfaceSequence(ChipMockBase chipMock, 749 boolean chipModeValid, int chipModeId, 750 int ifaceTypeToCreate, String ifaceName, int finalChipMode, IWifiIface[] tearDownList, 751 HalDeviceManager.InterfaceDestroyedListener destroyedListener, 752 HalDeviceManager.InterfaceAvailableForRequestListener availableListener, 753 HalDeviceManager.InterfaceDestroyedListener... destroyedInterfacesDestroyedListeners) 754 throws Exception { 755 // configure chip mode response 756 chipMock.chipModeValid = chipModeValid; 757 chipMock.chipModeId = chipModeId; 758 759 IWifiIface iface = null; 760 761 // configure: interface to be created 762 // act: request the interface 763 switch (ifaceTypeToCreate) { 764 case IfaceType.STA: 765 iface = mock(IWifiStaIface.class); 766 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 767 any(IWifiIface.getNameCallback.class)); 768 doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType( 769 any(IWifiIface.getTypeCallback.class)); 770 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 771 chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class)); 772 773 mDut.createStaIface(destroyedListener, availableListener, mTestLooper.getLooper()); 774 break; 775 case IfaceType.AP: 776 iface = mock(IWifiApIface.class); 777 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 778 any(IWifiIface.getNameCallback.class)); 779 doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType( 780 any(IWifiIface.getTypeCallback.class)); 781 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 782 chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class)); 783 784 mDut.createApIface(destroyedListener, availableListener, mTestLooper.getLooper()); 785 break; 786 case IfaceType.P2P: 787 iface = mock(IWifiP2pIface.class); 788 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 789 any(IWifiIface.getNameCallback.class)); 790 doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType( 791 any(IWifiIface.getTypeCallback.class)); 792 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 793 chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class)); 794 795 mDut.createP2pIface(destroyedListener, availableListener, mTestLooper.getLooper()); 796 break; 797 case IfaceType.NAN: 798 iface = mock(IWifiNanIface.class); 799 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName( 800 any(IWifiIface.getNameCallback.class)); 801 doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType( 802 any(IWifiIface.getTypeCallback.class)); 803 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when( 804 chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class)); 805 806 mDut.createNanIface(destroyedListener, availableListener, mTestLooper.getLooper()); 807 break; 808 } 809 810 // validate: optional tear down of interfaces 811 if (tearDownList != null) { 812 for (IWifiIface tearDownIface: tearDownList) { 813 switch (getType(tearDownIface)) { 814 case IfaceType.STA: 815 mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface)); 816 break; 817 case IfaceType.AP: 818 mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface)); 819 break; 820 case IfaceType.P2P: 821 mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface)); 822 break; 823 case IfaceType.NAN: 824 mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface)); 825 break; 826 } 827 } 828 } 829 830 // validate: optional switch to the requested mode 831 if (!chipModeValid || chipModeId != finalChipMode) { 832 mInOrder.verify(chipMock.chip).configureChip(finalChipMode); 833 } else { 834 mInOrder.verify(chipMock.chip, times(0)).configureChip(anyInt()); 835 } 836 837 // validate: create STA 838 switch (ifaceTypeToCreate) { 839 case IfaceType.STA: 840 mInOrder.verify(chipMock.chip).createStaIface( 841 any(IWifiChip.createStaIfaceCallback.class)); 842 break; 843 case IfaceType.AP: 844 mInOrder.verify(chipMock.chip).createApIface( 845 any(IWifiChip.createApIfaceCallback.class)); 846 break; 847 case IfaceType.P2P: 848 mInOrder.verify(chipMock.chip).createP2pIface( 849 any(IWifiChip.createP2pIfaceCallback.class)); 850 break; 851 case IfaceType.NAN: 852 mInOrder.verify(chipMock.chip).createNanIface( 853 any(IWifiChip.createNanIfaceCallback.class)); 854 break; 855 } 856 857 // verify: callbacks on deleted interfaces 858 mTestLooper.dispatchAll(); 859 for (int i = 0; i < destroyedInterfacesDestroyedListeners.length; ++i) { 860 verify(destroyedInterfacesDestroyedListeners[i]).onDestroyed(); 861 } 862 863 return iface; 864 } 865 866 private int getType(IWifiIface iface) throws Exception { 867 Mutable<Integer> typeResp = new Mutable<>(); 868 iface.getType((WifiStatus status, int type) -> { 869 typeResp.value = type; 870 }); 871 return typeResp.value; 872 } 873 874 private String getName(IWifiIface iface) throws Exception { 875 Mutable<String> nameResp = new Mutable<>(); 876 iface.getName((WifiStatus status, String name) -> { 877 nameResp.value = name; 878 }); 879 return nameResp.value; 880 } 881 882 private WifiStatus getStatus(int code) { 883 WifiStatus status = new WifiStatus(); 884 status.code = code; 885 return status; 886 } 887 888 private static class Mutable<E> { 889 public E value; 890 891 Mutable() { 892 value = null; 893 } 894 895 Mutable(E value) { 896 this.value = value; 897 } 898 } 899 900 // Answer objects 901 private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments { 902 private WifiStatus mStatus; 903 private ArrayList<Integer> mChipIds; 904 905 GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) { 906 mStatus = status; 907 mChipIds = chipIds; 908 } 909 910 public void answer(IWifi.getChipIdsCallback cb) { 911 cb.onValues(mStatus, mChipIds); 912 } 913 } 914 915 private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments { 916 private WifiStatus mStatus; 917 private IWifiChip mChip; 918 919 GetChipAnswer(WifiStatus status, IWifiChip chip) { 920 mStatus = status; 921 mChip = chip; 922 } 923 924 public void answer(int chipId, IWifi.getChipCallback cb) { 925 cb.onValues(mStatus, mChip); 926 } 927 } 928 929 private class GetAvailableModesAnswer extends MockAnswerUtil.AnswerWithArguments { 930 private ChipMockBase mChipMockBase; 931 932 GetAvailableModesAnswer(ChipMockBase chipMockBase) { 933 mChipMockBase = chipMockBase; 934 } 935 936 public void answer(IWifiChip.getAvailableModesCallback cb) { 937 cb.onValues(mStatusOk, mChipMockBase.availableModes); 938 } 939 } 940 941 private class GetModeAnswer extends MockAnswerUtil.AnswerWithArguments { 942 private ChipMockBase mChipMockBase; 943 944 GetModeAnswer(ChipMockBase chipMockBase) { 945 mChipMockBase = chipMockBase; 946 } 947 948 public void answer(IWifiChip.getModeCallback cb) { 949 cb.onValues(mChipMockBase.chipModeValid ? mStatusOk 950 : getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId); 951 } 952 } 953 954 private class ConfigureChipAnswer extends MockAnswerUtil.AnswerWithArguments { 955 private ChipMockBase mChipMockBase; 956 957 ConfigureChipAnswer(ChipMockBase chipMockBase) { 958 mChipMockBase = chipMockBase; 959 } 960 961 public WifiStatus answer(int chipMode) { 962 mChipMockBase.chipModeId = chipMode; 963 return mStatusOk; 964 } 965 } 966 967 private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments { 968 private ChipMockBase mChipMockBase; 969 970 GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) { 971 mChipMockBase = chipMockBase; 972 } 973 974 public void answer(IWifiChip.getStaIfaceNamesCallback cb) { 975 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA)); 976 } 977 978 public void answer(IWifiChip.getApIfaceNamesCallback cb) { 979 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP)); 980 } 981 982 public void answer(IWifiChip.getP2pIfaceNamesCallback cb) { 983 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P)); 984 } 985 986 public void answer(IWifiChip.getNanIfaceNamesCallback cb) { 987 cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN)); 988 } 989 } 990 991 private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 992 private ChipMockBase mChipMockBase; 993 994 GetXxxIfaceAnswer(ChipMockBase chipMockBase) { 995 mChipMockBase = chipMockBase; 996 } 997 998 public void answer(String name, IWifiChip.getStaIfaceCallback cb) { 999 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name); 1000 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface); 1001 } 1002 1003 public void answer(String name, IWifiChip.getApIfaceCallback cb) { 1004 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name); 1005 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface); 1006 } 1007 1008 public void answer(String name, IWifiChip.getP2pIfaceCallback cb) { 1009 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name); 1010 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface); 1011 } 1012 1013 public void answer(String name, IWifiChip.getNanIfaceCallback cb) { 1014 IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name); 1015 cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface); 1016 } 1017 } 1018 1019 private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 1020 private ChipMockBase mChipMockBase; 1021 private WifiStatus mStatus; 1022 private IWifiIface mWifiIface; 1023 1024 CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) { 1025 mChipMockBase = chipMockBase; 1026 mStatus = status; 1027 mWifiIface = wifiIface; 1028 } 1029 1030 private void addInterfaceInfo(int type) { 1031 if (mStatus.code == WifiStatusCode.SUCCESS) { 1032 try { 1033 mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface)); 1034 mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface); 1035 } catch (Exception e) { 1036 // do nothing 1037 } 1038 } 1039 } 1040 1041 public void answer(IWifiChip.createStaIfaceCallback cb) { 1042 cb.onValues(mStatus, (IWifiStaIface) mWifiIface); 1043 addInterfaceInfo(IfaceType.STA); 1044 } 1045 1046 public void answer(IWifiChip.createApIfaceCallback cb) { 1047 cb.onValues(mStatus, (IWifiApIface) mWifiIface); 1048 addInterfaceInfo(IfaceType.AP); 1049 } 1050 1051 public void answer(IWifiChip.createP2pIfaceCallback cb) { 1052 cb.onValues(mStatus, (IWifiP2pIface) mWifiIface); 1053 addInterfaceInfo(IfaceType.P2P); 1054 } 1055 1056 public void answer(IWifiChip.createNanIfaceCallback cb) { 1057 cb.onValues(mStatus, (IWifiNanIface) mWifiIface); 1058 addInterfaceInfo(IfaceType.NAN); 1059 } 1060 } 1061 1062 private class RemoveXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 1063 private ChipMockBase mChipMockBase; 1064 private int mType; 1065 1066 RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) { 1067 mChipMockBase = chipMockBase; 1068 mType = type; 1069 } 1070 1071 private WifiStatus removeIface(int type, String ifname) { 1072 try { 1073 if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) { 1074 return mStatusFail; 1075 } 1076 if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) { 1077 return mStatusFail; 1078 } 1079 } catch (Exception e) { 1080 return mStatusFail; 1081 } 1082 return mStatusOk; 1083 } 1084 1085 public WifiStatus answer(String ifname) { 1086 return removeIface(mType, ifname); 1087 } 1088 } 1089 1090 private class GetNameAnswer extends MockAnswerUtil.AnswerWithArguments { 1091 private String mName; 1092 1093 GetNameAnswer(String name) { 1094 mName = name; 1095 } 1096 1097 public void answer(IWifiIface.getNameCallback cb) { 1098 cb.onValues(mStatusOk, mName); 1099 } 1100 } 1101 1102 private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments { 1103 private int mType; 1104 1105 GetTypeAnswer(int type) { 1106 mType = type; 1107 } 1108 1109 public void answer(IWifiIface.getTypeCallback cb) { 1110 cb.onValues(mStatusOk, mType); 1111 } 1112 } 1113 1114 // chip configuration 1115 1116 private class ChipMockBase { 1117 public IWifiChip chip; 1118 public int chipId; 1119 public boolean chipModeValid = false; 1120 public int chipModeId = -1000; 1121 public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>(); 1122 public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>(); 1123 1124 public ArrayList<IWifiChip.ChipMode> availableModes; 1125 1126 void initialize() throws Exception { 1127 chip = mock(IWifiChip.class); 1128 1129 interfaceNames.put(IfaceType.STA, new ArrayList<>()); 1130 interfaceNames.put(IfaceType.AP, new ArrayList<>()); 1131 interfaceNames.put(IfaceType.P2P, new ArrayList<>()); 1132 interfaceNames.put(IfaceType.NAN, new ArrayList<>()); 1133 1134 interfacesByName.put(IfaceType.STA, new HashMap<>()); 1135 interfacesByName.put(IfaceType.AP, new HashMap<>()); 1136 interfacesByName.put(IfaceType.P2P, new HashMap<>()); 1137 interfacesByName.put(IfaceType.NAN, new HashMap<>()); 1138 1139 when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn( 1140 mStatusOk); 1141 when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this)); 1142 doAnswer(new GetModeAnswer(this)).when(chip).getMode( 1143 any(IWifiChip.getModeCallback.class)); 1144 GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this); 1145 doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames( 1146 any(IWifiChip.getStaIfaceNamesCallback.class)); 1147 doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames( 1148 any(IWifiChip.getApIfaceNamesCallback.class)); 1149 doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames( 1150 any(IWifiChip.getP2pIfaceNamesCallback.class)); 1151 doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames( 1152 any(IWifiChip.getNanIfaceNamesCallback.class)); 1153 GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this); 1154 doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(), 1155 any(IWifiChip.getStaIfaceCallback.class)); 1156 doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(), 1157 any(IWifiChip.getApIfaceCallback.class)); 1158 doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(), 1159 any(IWifiChip.getP2pIfaceCallback.class)); 1160 doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(), 1161 any(IWifiChip.getNanIfaceCallback.class)); 1162 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface( 1163 anyString()); 1164 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface( 1165 anyString()); 1166 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface( 1167 anyString()); 1168 doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface( 1169 anyString()); 1170 } 1171 } 1172 1173 // emulate baseline/legacy config: 1174 // mode: STA + NAN || P2P 1175 // mode: NAN 1176 private class BaselineChip extends ChipMockBase { 1177 static final int STA_CHIP_MODE_ID = 0; 1178 static final int AP_CHIP_MODE_ID = 1; 1179 1180 void initialize() throws Exception { 1181 super.initialize(); 1182 1183 // chip Id configuration 1184 ArrayList<Integer> chipIds; 1185 chipId = 10; 1186 chipIds = new ArrayList<>(); 1187 chipIds.add(chipId); 1188 doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds( 1189 any(IWifi.getChipIdsCallback.class)); 1190 1191 doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10), 1192 any(IWifi.getChipCallback.class)); 1193 1194 // initialize dummy chip modes 1195 IWifiChip.ChipMode cm; 1196 IWifiChip.ChipIfaceCombination cic; 1197 IWifiChip.ChipIfaceCombinationLimit cicl; 1198 1199 // Mode 0: 1xSTA + 1x{P2P,NAN} 1200 // Mode 1: 1xAP 1201 availableModes = new ArrayList<>(); 1202 cm = new IWifiChip.ChipMode(); 1203 cm.id = STA_CHIP_MODE_ID; 1204 1205 cic = new IWifiChip.ChipIfaceCombination(); 1206 1207 cicl = new IWifiChip.ChipIfaceCombinationLimit(); 1208 cicl.maxIfaces = 1; 1209 cicl.types.add(IfaceType.STA); 1210 cic.limits.add(cicl); 1211 1212 cicl = new IWifiChip.ChipIfaceCombinationLimit(); 1213 cicl.maxIfaces = 1; 1214 cicl.types.add(IfaceType.P2P); 1215 cicl.types.add(IfaceType.NAN); 1216 cic.limits.add(cicl); 1217 cm.availableCombinations.add(cic); 1218 availableModes.add(cm); 1219 1220 cm = new IWifiChip.ChipMode(); 1221 cm.id = AP_CHIP_MODE_ID; 1222 cic = new IWifiChip.ChipIfaceCombination(); 1223 cicl = new IWifiChip.ChipIfaceCombinationLimit(); 1224 cicl.maxIfaces = 1; 1225 cicl.types.add(IfaceType.AP); 1226 cic.limits.add(cicl); 1227 cm.availableCombinations.add(cic); 1228 availableModes.add(cm); 1229 1230 doAnswer(new GetAvailableModesAnswer(this)).when(chip) 1231 .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class)); 1232 } 1233 } 1234} 1235