1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.wifi; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertTrue; 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyBoolean; 26 import static org.mockito.Mockito.atLeastOnce; 27 import static org.mockito.Mockito.doAnswer; 28 import static org.mockito.Mockito.doNothing; 29 import static org.mockito.Mockito.doThrow; 30 import static org.mockito.Mockito.eq; 31 import static org.mockito.Mockito.inOrder; 32 import static org.mockito.Mockito.mock; 33 import static org.mockito.Mockito.times; 34 import static org.mockito.Mockito.verify; 35 import static org.mockito.Mockito.verifyNoMoreInteractions; 36 import static org.mockito.Mockito.when; 37 38 import android.app.test.MockAnswerUtil; 39 import android.net.InterfaceConfiguration; 40 import android.net.wifi.IApInterface; 41 import android.net.wifi.IClientInterface; 42 import android.net.wifi.WifiConfiguration; 43 import android.net.wifi.WifiScanner; 44 import android.os.INetworkManagementService; 45 import android.os.RemoteException; 46 import android.support.test.filters.SmallTest; 47 48 import com.android.server.net.BaseNetworkObserver; 49 import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener; 50 import com.android.server.wifi.WifiNative.SupplicantDeathEventHandler; 51 import com.android.server.wifi.WifiNative.VendorHalDeathEventHandler; 52 import com.android.server.wifi.WifiNative.WificondDeathEventHandler; 53 54 import org.junit.After; 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.mockito.ArgumentCaptor; 58 import org.mockito.InOrder; 59 import org.mockito.Mock; 60 import org.mockito.MockitoAnnotations; 61 62 /** 63 * Unit tests for the interface management operations in 64 * {@link com.android.server.wifi.WifiNative}. 65 */ 66 @SmallTest 67 public class WifiNativeInterfaceManagementTest { 68 private static final String IFACE_NAME_0 = "mockWlan0"; 69 private static final String IFACE_NAME_1 = "mockWlan1"; 70 71 @Mock private WifiVendorHal mWifiVendorHal; 72 @Mock private WificondControl mWificondControl; 73 @Mock private SupplicantStaIfaceHal mSupplicantStaIfaceHal; 74 @Mock private HostapdHal mHostapdHal; 75 @Mock private WifiMonitor mWifiMonitor; 76 @Mock private INetworkManagementService mNwManagementService; 77 @Mock private PropertyService mPropertyService; 78 @Mock private WifiMetrics mWifiMetrics; 79 80 @Mock private WifiNative.StatusListener mStatusListener; 81 @Mock private WifiNative.InterfaceCallback mIfaceCallback0; 82 @Mock private WifiNative.InterfaceCallback mIfaceCallback1; 83 private final InterfaceConfiguration mInterfaceConfiguration = new InterfaceConfiguration(); 84 85 private ArgumentCaptor<VendorHalDeathEventHandler> mWifiVendorHalDeathHandlerCaptor = 86 ArgumentCaptor.forClass(VendorHalDeathEventHandler.class); 87 private ArgumentCaptor<WificondDeathEventHandler> mWificondDeathHandlerCaptor = 88 ArgumentCaptor.forClass(WificondDeathEventHandler.class); 89 private ArgumentCaptor<WifiNative.VendorHalRadioModeChangeEventHandler> 90 mWifiVendorHalRadioModeChangeHandlerCaptor = 91 ArgumentCaptor.forClass(WifiNative.VendorHalRadioModeChangeEventHandler.class); 92 private ArgumentCaptor<SupplicantDeathEventHandler> mSupplicantDeathHandlerCaptor = 93 ArgumentCaptor.forClass(SupplicantDeathEventHandler.class); 94 private ArgumentCaptor<WifiNative.HostapdDeathEventHandler> mHostapdDeathHandlerCaptor = 95 ArgumentCaptor.forClass(WifiNative.HostapdDeathEventHandler.class); 96 private ArgumentCaptor<BaseNetworkObserver> mNetworkObserverCaptor0 = 97 ArgumentCaptor.forClass(BaseNetworkObserver.class); 98 private ArgumentCaptor<BaseNetworkObserver> mNetworkObserverCaptor1 = 99 ArgumentCaptor.forClass(BaseNetworkObserver.class); 100 private ArgumentCaptor<InterfaceDestroyedListener> mIfaceDestroyedListenerCaptor0 = 101 ArgumentCaptor.forClass(InterfaceDestroyedListener.class); 102 private ArgumentCaptor<InterfaceDestroyedListener> mIfaceDestroyedListenerCaptor1 = 103 ArgumentCaptor.forClass(InterfaceDestroyedListener.class); 104 private InOrder mInOrder; 105 106 private WifiNative mWifiNative; 107 108 @Before 109 public void setUp() throws Exception { 110 MockitoAnnotations.initMocks(this); 111 // Setup mocks for the positive single interface cases, individual tests can modify the 112 // mocks for negative or multi-interface tests. 113 when(mWifiVendorHal.initialize(mWifiVendorHalDeathHandlerCaptor.capture())) 114 .thenReturn(true); 115 doNothing().when(mWifiVendorHal).registerRadioModeChangeHandler( 116 mWifiVendorHalRadioModeChangeHandlerCaptor.capture()); 117 when(mWifiVendorHal.isVendorHalSupported()).thenReturn(true); 118 when(mWifiVendorHal.startVendorHal()).thenReturn(true); 119 when(mWifiVendorHal.createStaIface(anyBoolean(), any())).thenReturn(IFACE_NAME_0); 120 when(mWifiVendorHal.createApIface(any())).thenReturn(IFACE_NAME_0); 121 when(mWifiVendorHal.removeStaIface(any())).thenReturn(true); 122 when(mWifiVendorHal.removeApIface(any())).thenReturn(true); 123 124 when(mWificondControl.initialize(mWificondDeathHandlerCaptor.capture())) 125 .thenReturn(true); 126 when(mWificondControl.enableSupplicant()).thenReturn(true); 127 when(mWificondControl.disableSupplicant()).thenReturn(true); 128 when(mWificondControl.startHostapd(any(), any())).thenReturn(true); 129 when(mWificondControl.stopHostapd(any())).thenReturn(true); 130 when(mWificondControl.setupInterfaceForClientMode(any())) 131 .thenReturn(mock(IClientInterface.class)); 132 when(mWificondControl.setupInterfaceForSoftApMode(any())) 133 .thenReturn(mock(IApInterface.class)); 134 when(mWificondControl.tearDownClientInterface(any())).thenReturn(true); 135 when(mWificondControl.tearDownSoftApInterface(any())).thenReturn(true); 136 when(mWificondControl.tearDownInterfaces()).thenReturn(true); 137 138 when(mSupplicantStaIfaceHal.registerDeathHandler(mSupplicantDeathHandlerCaptor.capture())) 139 .thenReturn(true); 140 when(mSupplicantStaIfaceHal.deregisterDeathHandler()).thenReturn(true); 141 when(mSupplicantStaIfaceHal.initialize()).thenReturn(true); 142 when(mSupplicantStaIfaceHal.isInitializationStarted()).thenReturn(false); 143 when(mSupplicantStaIfaceHal.isInitializationComplete()).thenReturn(true); 144 when(mSupplicantStaIfaceHal.setupIface(any())).thenReturn(true); 145 when(mSupplicantStaIfaceHal.teardownIface(any())).thenReturn(true); 146 147 when(mHostapdHal.registerDeathHandler(mHostapdDeathHandlerCaptor.capture())) 148 .thenReturn(true); 149 when(mHostapdHal.deregisterDeathHandler()).thenReturn(true); 150 when(mHostapdHal.initialize()).thenReturn(true); 151 when(mHostapdHal.isInitializationStarted()).thenReturn(false); 152 when(mHostapdHal.isInitializationComplete()).thenReturn(true); 153 when(mHostapdHal.addAccessPoint(any(), any())).thenReturn(true); 154 when(mHostapdHal.removeAccessPoint(any())).thenReturn(true); 155 156 when(mNwManagementService.getInterfaceConfig(IFACE_NAME_0)) 157 .thenReturn(mInterfaceConfiguration); 158 159 mInOrder = inOrder(mWifiVendorHal, mWificondControl, mSupplicantStaIfaceHal, mHostapdHal, 160 mWifiMonitor, mNwManagementService, mIfaceCallback0, mIfaceCallback1, mWifiMetrics); 161 162 mWifiNative = new WifiNative( 163 mWifiVendorHal, mSupplicantStaIfaceHal, mHostapdHal, mWificondControl, 164 mWifiMonitor, mNwManagementService, mPropertyService, mWifiMetrics); 165 mWifiNative.initialize(); 166 mWifiNative.registerStatusListener(mStatusListener); 167 168 mInOrder.verify(mWifiVendorHal).initialize(any()); 169 mInOrder.verify(mWificondControl).initialize(any()); 170 mInOrder.verify(mWifiVendorHal).registerRadioModeChangeHandler(any()); 171 } 172 173 @After 174 public void tearDown() throws Exception { 175 verifyNoMoreInteractions(mWifiVendorHal, mWificondControl, mSupplicantStaIfaceHal, 176 mHostapdHal, mWifiMonitor, mNwManagementService, mIfaceCallback0, mIfaceCallback1, 177 mWifiMetrics); 178 } 179 180 /** 181 * Verifies the setup of a single client interface. 182 */ 183 @Test 184 public void testSetupClientInterface() throws Exception { 185 executeAndValidateSetupClientInterface( 186 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 187 mNetworkObserverCaptor0); 188 assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName()); 189 } 190 191 /** 192 * Verifies the setup of a single softAp interface. 193 */ 194 @Test 195 public void testSetupSoftApInterface() throws Exception { 196 executeAndValidateSetupSoftApInterface( 197 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 198 mNetworkObserverCaptor0); 199 assertNull(mWifiNative.getClientInterfaceName()); 200 } 201 202 /** 203 * Verifies the setup & teardown of a single client interface. 204 */ 205 @Test 206 public void testSetupAndTeardownClientInterface() throws Exception { 207 executeAndValidateSetupClientInterface( 208 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 209 mNetworkObserverCaptor0); 210 assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName()); 211 executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 212 mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue()); 213 } 214 215 /** 216 * Verifies the setup & teardown of a single softAp interface. 217 */ 218 @Test 219 public void testSetupAndTeardownSoftApInterface() throws Exception { 220 executeAndValidateSetupSoftApInterface( 221 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 222 mNetworkObserverCaptor0); 223 assertNull(mWifiNative.getClientInterfaceName()); 224 executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 225 mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue()); 226 } 227 228 /** 229 * Verifies the setup & teardown of a client & softAp interface. 230 * 231 * Sequence tested: 232 * a) Setup client interface. 233 * b) Setup softAp interface. 234 * c) Teardown client interface. 235 * d) Teardown softAp interface. 236 */ 237 @Test 238 public void testSetupAndTeardownClientAndSoftApInterface_Seq1() throws Exception { 239 executeAndValidateSetupClientInterface( 240 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 241 mNetworkObserverCaptor0); 242 executeAndValidateSetupSoftApInterface( 243 true, false, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1, 244 mNetworkObserverCaptor1); 245 assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName()); 246 executeAndValidateTeardownClientInterface(false, true, IFACE_NAME_0, mIfaceCallback0, 247 mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue()); 248 executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_1, mIfaceCallback1, 249 mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue()); 250 } 251 252 /** 253 * Verifies the setup & teardown of a client & softAp interface. 254 * 255 * Sequence tested: 256 * a) Setup client interface. 257 * b) Setup softAp interface. 258 * c) Teardown softAp interface. 259 * d) Teardown client interface. 260 */ 261 @Test 262 public void testSetupAndTeardownClientAndSoftApInterface_Seq2() throws Exception { 263 executeAndValidateSetupClientInterface( 264 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 265 mNetworkObserverCaptor0); 266 executeAndValidateSetupSoftApInterface( 267 true, false, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1, 268 mNetworkObserverCaptor1); 269 assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName()); 270 executeAndValidateTeardownSoftApInterface(true, false, IFACE_NAME_1, mIfaceCallback1, 271 mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue()); 272 executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 273 mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue()); 274 } 275 276 /** 277 * Verifies the setup & teardown of a client & softAp interface. 278 * 279 * Sequence tested: 280 * a) Setup softAp interface. 281 * b) Setup client interface. 282 * c) Teardown softAp interface. 283 * d) Teardown client interface. 284 */ 285 @Test 286 public void testSetupAndTeardownClientAndSoftApInterface_Seq3() throws Exception { 287 executeAndValidateSetupSoftApInterface( 288 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 289 mNetworkObserverCaptor0); 290 executeAndValidateSetupClientInterface( 291 false, true, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1, 292 mNetworkObserverCaptor1); 293 assertEquals(IFACE_NAME_1, mWifiNative.getClientInterfaceName()); 294 executeAndValidateTeardownSoftApInterface(true, false, IFACE_NAME_0, mIfaceCallback0, 295 mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue()); 296 executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_1, mIfaceCallback1, 297 mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue()); 298 } 299 300 /** 301 * Verifies the setup & teardown of a client & softAp interface. 302 * 303 * Sequence tested: 304 * a) Setup softAp interface. 305 * b) Setup client interface. 306 * c) Teardown client interface. 307 * d) Teardown softAp interface. 308 */ 309 @Test 310 public void testSetupAndTeardownClientAndSoftApInterface_Seq4() throws Exception { 311 executeAndValidateSetupSoftApInterface( 312 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 313 mNetworkObserverCaptor0); 314 executeAndValidateSetupClientInterface( 315 false, true, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1, 316 mNetworkObserverCaptor1); 317 assertEquals(IFACE_NAME_1, mWifiNative.getClientInterfaceName()); 318 executeAndValidateTeardownClientInterface(false, true, IFACE_NAME_1, mIfaceCallback1, 319 mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue()); 320 executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 321 mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue()); 322 } 323 324 /** 325 * Verifies the setup of a client & softAp interface & then initiate teardown of all active 326 * interfaces. 327 * 328 * Sequence tested: 329 * a) Setup softAp interface. 330 * b) Setup client interface. 331 * c) Teardown all active interfaces. 332 */ 333 @Test 334 public void testTeardownAllInterfaces() throws Exception { 335 executeAndValidateSetupSoftApInterface( 336 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 337 mNetworkObserverCaptor0); 338 executeAndValidateSetupClientInterface( 339 false, true, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1, 340 mNetworkObserverCaptor1); 341 342 // Assert that a client & softap interface is present. 343 assertNotNull(mWifiNative.getClientInterfaceName()); 344 assertNotNull(mWifiNative.getSoftApInterfaceName()); 345 346 mWifiNative.teardownAllInterfaces(); 347 348 // Note: This is not using InOrder because order of interface deletion cannot be 349 // predetermined. 350 351 // Verify STA removal 352 verify(mWifiMonitor).stopMonitoring(IFACE_NAME_1); 353 verify(mNwManagementService).unregisterObserver(mNetworkObserverCaptor1.getValue()); 354 verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_1); 355 verify(mWificondControl).tearDownClientInterface(IFACE_NAME_1); 356 verify(mSupplicantStaIfaceHal).deregisterDeathHandler(); 357 verify(mWificondControl).disableSupplicant(); 358 verify(mIfaceCallback1).onDestroyed(IFACE_NAME_1); 359 360 // Verify AP removal 361 verify(mNwManagementService).unregisterObserver(mNetworkObserverCaptor0.getValue()); 362 verify(mHostapdHal).removeAccessPoint(IFACE_NAME_0); 363 verify(mHostapdHal).deregisterDeathHandler(); 364 verify(mWificondControl).stopHostapd(IFACE_NAME_0); 365 verify(mWificondControl).tearDownSoftApInterface(IFACE_NAME_0); 366 367 // Verify we stopped HAL & wificond 368 verify(mWificondControl).tearDownInterfaces(); 369 verify(mWifiVendorHal).stopVendorHal(); 370 verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0); 371 372 verify(mWifiVendorHal, atLeastOnce()).isVendorHalSupported(); 373 374 // Assert that the client & softap interface is no more there. 375 assertNull(mWifiNative.getClientInterfaceName()); 376 assertNull(mWifiNative.getSoftApInterfaceName()); 377 } 378 379 /** 380 * Verifies the setup of a client interface and then a SoftAp interface which would 381 * destroy the Client interface. This is what would happen on older devices which do not 382 * support concurrent interfaces. 383 */ 384 @Test 385 public void testSetupClientAndSoftApInterfaceCausesClientInterfaceTeardown() throws Exception { 386 executeAndValidateSetupClientInterface( 387 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 388 mNetworkObserverCaptor0); 389 390 // Trigger the STA interface teardown when AP interface is created. 391 // The iface name will remain the same. 392 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 393 public String answer(InterfaceDestroyedListener destroyedListener) { 394 mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); 395 return IFACE_NAME_0; 396 } 397 }).when(mWifiVendorHal).createApIface(any()); 398 399 assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1)); 400 401 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 402 mInOrder.verify(mWifiVendorHal).createApIface(mIfaceDestroyedListenerCaptor1.capture()); 403 // Creation of AP interface should trigger the STA interface destroy 404 validateOnDestroyedClientInterface( 405 false, true, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue()); 406 // Now continue with rest of AP interface setup. 407 mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0); 408 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture()); 409 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 410 411 // Execute a teardown of the interface to ensure that the new iface removal works. 412 executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback1, 413 mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue()); 414 } 415 416 /** 417 * Verifies the setup of a client interface and then a SoftAp interface which would 418 * destroy the Client interface. This is what would happen on older devices which do not 419 * support concurrent interfaces. 420 */ 421 @Test 422 public void testSetupSoftApAndClientInterfaceCausesSoftApInterfaceTeardown() throws Exception { 423 executeAndValidateSetupSoftApInterface( 424 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 425 mNetworkObserverCaptor0); 426 427 // Trigger the AP interface teardown when STA interface is created. 428 // The iface name will remain the same. 429 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 430 public String answer(boolean lowPrioritySta, 431 InterfaceDestroyedListener destroyedListener) { 432 mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); 433 return IFACE_NAME_0; 434 } 435 }).when(mWifiVendorHal).createStaIface(anyBoolean(), any()); 436 437 assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback1)); 438 439 mInOrder.verify(mWificondControl).enableSupplicant(); 440 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 441 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 442 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 443 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 444 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 445 mInOrder.verify(mWifiVendorHal).createStaIface(eq(false), 446 mIfaceDestroyedListenerCaptor1.capture()); 447 // Creation of STA interface should trigger the AP interface destroy. 448 validateOnDestroyedSoftApInterface( 449 true, false, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue()); 450 // Now continue with rest of STA interface setup. 451 mInOrder.verify(mWificondControl).setupInterfaceForClientMode(IFACE_NAME_0); 452 mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0); 453 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture()); 454 mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0); 455 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 456 mInOrder.verify(mNwManagementService).clearInterfaceAddresses(IFACE_NAME_0); 457 mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true); 458 mInOrder.verify(mNwManagementService).disableIpv6(IFACE_NAME_0); 459 460 // Execute a teardown of the interface to ensure that the new iface removal works. 461 executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_0, mIfaceCallback1, 462 mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue()); 463 } 464 465 /** 466 * Verifies the setup of a client interface and trigger an interface down event. 467 * This should be ignored since interface is considered to be down before setup. 468 */ 469 @Test 470 public void testSetupClientInterfaceAndTriggerInterfaceDown() throws Exception { 471 executeAndValidateSetupSoftApInterface( 472 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 473 mNetworkObserverCaptor0); 474 475 executeAndValidateInterfaceStateChange( 476 IFACE_NAME_0, false, mNetworkObserverCaptor0.getValue()); 477 } 478 479 /** 480 * Verifies the setup of a client interface and trigger an interface up event. 481 */ 482 @Test 483 public void testSetupClientInterfaceAndTriggerInterfaceUp() throws Exception { 484 executeAndValidateSetupSoftApInterface( 485 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 486 mNetworkObserverCaptor0); 487 488 executeAndValidateInterfaceStateChange( 489 IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue()); 490 mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0); 491 } 492 493 /** 494 * Verifies the setup of a client interface and trigger an interface up event, followed by a 495 * down event. 496 */ 497 @Test 498 public void testSetupClientInterfaceAndTriggerInterfaceUpFollowedByDown() throws Exception { 499 executeAndValidateSetupClientInterface( 500 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 501 mNetworkObserverCaptor0); 502 503 executeAndValidateInterfaceStateChange( 504 IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue()); 505 mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0); 506 507 executeAndValidateInterfaceStateChange( 508 IFACE_NAME_0, false, mNetworkObserverCaptor0.getValue()); 509 mInOrder.verify(mIfaceCallback0).onDown(IFACE_NAME_0); 510 mInOrder.verify(mWifiMetrics).incrementNumClientInterfaceDown(); 511 } 512 513 /** 514 * Verifies the setup of a softap interface and trigger an interface up event, followed by a 515 * down event. 516 */ 517 @Test 518 public void testSetupSoftApInterfaceAndTriggerInterfaceUpFollowedByDown() throws Exception { 519 executeAndValidateSetupSoftApInterface( 520 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 521 mNetworkObserverCaptor0); 522 523 executeAndValidateInterfaceStateChange( 524 IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue()); 525 mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0); 526 527 executeAndValidateInterfaceStateChange( 528 IFACE_NAME_0, false, mNetworkObserverCaptor0.getValue()); 529 mInOrder.verify(mIfaceCallback0).onDown(IFACE_NAME_0); 530 mInOrder.verify(mWifiMetrics).incrementNumSoftApInterfaceDown(); 531 } 532 533 /** 534 * Verifies the setup of a client interface and trigger an interface up event, followed by 535 * link down/up events. The link state change events should be ignored since we only care for 536 * interface state changes. 537 */ 538 @Test 539 public void testSetupClientInterfaceAndTriggerInterfaceUpFollowedByLinkDownAndUp() 540 throws Exception { 541 executeAndValidateSetupClientInterface( 542 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 543 mNetworkObserverCaptor0); 544 545 executeAndValidateInterfaceStateChange( 546 IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue()); 547 mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0); 548 549 // Trigger a link down, with the interface still up. 550 // Should not trigger the external iface callback. 551 mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, false); 552 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 553 554 // Now trigger a link up, with the interface still up. 555 // Should not trigger the external iface callback. 556 mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, true); 557 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 558 } 559 560 /** 561 * Verifies the setup of a client interface and trigger an interface up event, followed by 562 * link down/up events. The link state change events should be ignored since we only care for 563 * interface state changes. 564 */ 565 @Test 566 public void testSetupSoftApInterfaceAndTriggerInterfaceUpFollowedByLinkDownAndUp() 567 throws Exception { 568 executeAndValidateSetupSoftApInterface( 569 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 570 mNetworkObserverCaptor0); 571 572 executeAndValidateInterfaceStateChange( 573 IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue()); 574 mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0); 575 576 // Trigger a link down, with the interface still up. 577 // Should not trigger the external iface callback. 578 mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, false); 579 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 580 581 // Now trigger a link up, with the interface still up. 582 // Should not trigger the external iface callback. 583 mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, true); 584 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 585 } 586 587 /** 588 * Verifies the setup of a client interface and trigger an interface up event twice. 589 * The second interface up event should be masked. 590 */ 591 @Test 592 public void testSetupClientInterfaceAndTriggerInterfaceUpTwice() throws Exception { 593 executeAndValidateSetupSoftApInterface( 594 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 595 mNetworkObserverCaptor0); 596 597 executeAndValidateInterfaceStateChange( 598 IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue()); 599 mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0); 600 601 executeAndValidateInterfaceStateChange( 602 IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue()); 603 } 604 605 /** 606 * Verifies the setup of a client interface and trigger an interface up event on a different 607 * interface. 608 */ 609 @Test 610 public void testSetupClientInterfaceAndTriggerInterfaceUpOnAnInvalidIface() throws Exception { 611 executeAndValidateSetupSoftApInterface( 612 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 613 mNetworkObserverCaptor0); 614 615 mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_1, true); 616 } 617 618 /** 619 * Verifies that interface down on a destroyed interface is ignored. 620 * The test triggers 621 * a) Setup of a client interface 622 * b) Setup of a SoftAp interface which would destroy the Client interface. 623 * This is what would happen on older devices which do not support concurrent interfaces. 624 * c) Once the client interface is destroyed, trigger an interface up event on the old 625 * network observer. This should be ignored. 626 * d) Trigger an interface down event on the new network observer. This should trigger an 627 * interface up event to external clients. 628 * e) Remove the new SoftAp interface. 629 */ 630 @Test 631 public void testSetupClientInterfaceAndTriggerInterfaceUpOnDestroyedIface() throws Exception { 632 // Step (a) 633 executeAndValidateSetupClientInterface( 634 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 635 mNetworkObserverCaptor0); 636 637 // Step (b) 638 // Trigger the STA interface teardown when AP interface is created. 639 // The iface name will remain the same. 640 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 641 public String answer(InterfaceDestroyedListener destroyedListener) { 642 mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); 643 return IFACE_NAME_0; 644 } 645 }).when(mWifiVendorHal).createApIface(any()); 646 647 assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1)); 648 649 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 650 mInOrder.verify(mWifiVendorHal).createApIface(mIfaceDestroyedListenerCaptor1.capture()); 651 // Creation of AP interface should trigger the STA interface destroy 652 validateOnDestroyedClientInterface( 653 false, true, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue()); 654 // Now continue with rest of AP interface setup. 655 mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0); 656 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture()); 657 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 658 659 // Step (c) - Iface up on old iface, ignored! 660 mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, true); 661 662 // Step (d) - Iface up on new iface, handled! 663 executeAndValidateInterfaceStateChange( 664 IFACE_NAME_0, true, mNetworkObserverCaptor1.getValue()); 665 mInOrder.verify(mIfaceCallback1).onUp(IFACE_NAME_0); 666 667 // Execute a teardown of the softap interface to ensure that the new iface removal works. 668 executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback1, 669 mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue()); 670 } 671 672 /** 673 * Verifies the setup of a client interface and wificond death handling. 674 */ 675 @Test 676 public void testSetupClientInterfaceAndWicondDied() throws Exception { 677 executeAndValidateSetupClientInterface( 678 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 679 mNetworkObserverCaptor0); 680 // Trigger wificond death 681 mWificondDeathHandlerCaptor.getValue().onDeath(); 682 683 mInOrder.verify(mWifiMetrics).incrementNumWificondCrashes(); 684 685 verify(mStatusListener).onStatusChanged(false); 686 verify(mStatusListener).onStatusChanged(true); 687 } 688 689 /** 690 * Verifies the setup of a soft ap interface and vendor HAL death handling. 691 */ 692 @Test 693 public void testSetupSoftApInterfaceAndVendorHalDied() throws Exception { 694 executeAndValidateSetupSoftApInterface( 695 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 696 mNetworkObserverCaptor0); 697 698 // Trigger vendor HAL death 699 mWifiVendorHalDeathHandlerCaptor.getValue().onDeath(); 700 701 mInOrder.verify(mWifiMetrics).incrementNumHalCrashes(); 702 703 verify(mStatusListener).onStatusChanged(false); 704 verify(mStatusListener).onStatusChanged(true); 705 } 706 707 /** 708 * Verifies the setup of a client interface and supplicant HAL death handling. 709 */ 710 @Test 711 public void testSetupClientInterfaceAndSupplicantDied() throws Exception { 712 executeAndValidateSetupClientInterface( 713 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 714 mNetworkObserverCaptor0); 715 // Trigger wificond death 716 mSupplicantDeathHandlerCaptor.getValue().onDeath(); 717 718 mInOrder.verify(mWifiMetrics).incrementNumSupplicantCrashes(); 719 720 verify(mStatusListener).onStatusChanged(false); 721 verify(mStatusListener).onStatusChanged(true); 722 } 723 724 /** 725 * Verifies the setup of a soft ap interface and hostapd death handling. 726 */ 727 @Test 728 public void testStartSoftApAndHostapdDied() throws Exception { 729 executeAndValidateSetupSoftApInterface( 730 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 731 mNetworkObserverCaptor0); 732 733 // Start softap 734 assertTrue(mWifiNative.startSoftAp(IFACE_NAME_0, new WifiConfiguration(), 735 mock(WifiNative.SoftApListener.class))); 736 737 mInOrder.verify(mWificondControl).startHostapd(eq(IFACE_NAME_0), any()); 738 mInOrder.verify(mHostapdHal).isInitializationStarted(); 739 mInOrder.verify(mHostapdHal).initialize(); 740 mInOrder.verify(mHostapdHal).isInitializationComplete(); 741 mInOrder.verify(mHostapdHal).registerDeathHandler(any()); 742 mInOrder.verify(mHostapdHal).addAccessPoint(any(), any()); 743 744 // Trigger vendor HAL death 745 mHostapdDeathHandlerCaptor.getValue().onDeath(); 746 747 mInOrder.verify(mWifiMetrics).incrementNumHostapdCrashes(); 748 749 verify(mStatusListener).onStatusChanged(false); 750 verify(mStatusListener).onStatusChanged(true); 751 } 752 753 /** 754 * Verifies failure handling in setup of a client interface. 755 */ 756 @Test 757 public void testSetupClientInterfaceFailureInStartHal() throws Exception { 758 when(mWifiVendorHal.startVendorHal()).thenReturn(false); 759 assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0)); 760 761 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 762 mInOrder.verify(mWifiVendorHal).startVendorHal(); 763 mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToHal(); 764 765 // To test if the failure is handled cleanly, invoke teardown and ensure that 766 // none of the mocks are used because the iface does not exist in the internal 767 // database. 768 mWifiNative.teardownInterface(IFACE_NAME_0); 769 } 770 771 /** 772 * Verifies failure handling in setup of a client interface. 773 */ 774 @Test 775 public void testSetupClientInterfaceFailureInStartSupplicant() throws Exception { 776 when(mWificondControl.enableSupplicant()).thenReturn(false); 777 assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0)); 778 779 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 780 mInOrder.verify(mWifiVendorHal).startVendorHal(); 781 mInOrder.verify(mWificondControl).enableSupplicant(); 782 mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant(); 783 784 // To test if the failure is handled cleanly, invoke teardown and ensure that 785 // none of the mocks are used because the iface does not exist in the internal 786 // database. 787 mWifiNative.teardownInterface(IFACE_NAME_0); 788 } 789 790 /** 791 * Verifies failure handling in setup of a client interface. 792 */ 793 @Test 794 public void testSetupClientInterfaceFailureInHalCreateStaIface() throws Exception { 795 when(mWifiVendorHal.createStaIface(anyBoolean(), any())).thenReturn(null); 796 assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0)); 797 798 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 799 mInOrder.verify(mWifiVendorHal).startVendorHal(); 800 mInOrder.verify(mWificondControl).enableSupplicant(); 801 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 802 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 803 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 804 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 805 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 806 mInOrder.verify(mWifiVendorHal).createStaIface(eq(false), any()); 807 mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToHal(); 808 809 // To test if the failure is handled cleanly, invoke teardown and ensure that 810 // none of the mocks are used because the iface does not exist in the internal 811 // database. 812 mWifiNative.teardownInterface(IFACE_NAME_0); 813 } 814 815 /** 816 * Verifies failure handling in setup of a client interface. 817 */ 818 @Test 819 public void testSetupClientInterfaceFailureInWificondSetupInterfaceForClientMode() 820 throws Exception { 821 when(mWificondControl.setupInterfaceForClientMode(any())).thenReturn(null); 822 assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0)); 823 824 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 825 mInOrder.verify(mWifiVendorHal).startVendorHal(); 826 mInOrder.verify(mWificondControl).enableSupplicant(); 827 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 828 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 829 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 830 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 831 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 832 mInOrder.verify(mWifiVendorHal).createStaIface(eq(false), 833 mIfaceDestroyedListenerCaptor0.capture()); 834 mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any()); 835 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 836 mInOrder.verify(mWifiVendorHal).removeStaIface(any()); 837 mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToWificond(); 838 839 // Trigger the HAL interface destroyed callback to verify the whole removal sequence. 840 mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); 841 validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 842 null); 843 844 // To test if the failure is handled cleanly, invoke teardown and ensure that 845 // none of the mocks are used because the iface does not exist in the internal 846 // database. 847 mWifiNative.teardownInterface(IFACE_NAME_0); 848 } 849 850 /** 851 * Verifies failure handling in setup of a client interface. 852 */ 853 @Test 854 public void testSetupClientInterfaceFailureInSupplicantSetupIface() throws Exception { 855 when(mSupplicantStaIfaceHal.setupIface(any())).thenReturn(false); 856 assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0)); 857 858 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 859 mInOrder.verify(mWifiVendorHal).startVendorHal(); 860 mInOrder.verify(mWificondControl).enableSupplicant(); 861 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 862 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 863 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 864 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 865 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 866 mInOrder.verify(mWifiVendorHal).createStaIface(eq(false), 867 mIfaceDestroyedListenerCaptor0.capture()); 868 mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any()); 869 mInOrder.verify(mSupplicantStaIfaceHal).setupIface(any()); 870 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 871 mInOrder.verify(mWifiVendorHal).removeStaIface(any()); 872 mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant(); 873 874 // Trigger the HAL interface destroyed callback to verify the whole removal sequence. 875 mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); 876 validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 877 null); 878 879 // To test if the failure is handled cleanly, invoke teardown and ensure that 880 // none of the mocks are used because the iface does not exist in the internal 881 // database. 882 mWifiNative.teardownInterface(IFACE_NAME_0); 883 } 884 885 /** 886 * Verifies failure handling in setup of a client interface. 887 */ 888 @Test 889 public void testSetupClientInterfaceFailureInNetworkObserverRegister() throws Exception { 890 doThrow(new RemoteException()).when(mNwManagementService).registerObserver(any()); 891 assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0)); 892 893 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 894 mInOrder.verify(mWifiVendorHal).startVendorHal(); 895 mInOrder.verify(mWificondControl).enableSupplicant(); 896 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 897 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 898 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 899 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 900 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 901 mInOrder.verify(mWifiVendorHal).createStaIface(eq(false), 902 mIfaceDestroyedListenerCaptor0.capture()); 903 mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any()); 904 mInOrder.verify(mSupplicantStaIfaceHal).setupIface(any()); 905 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor0.capture()); 906 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 907 mInOrder.verify(mWifiVendorHal).removeStaIface(any()); 908 909 // Trigger the HAL interface destroyed callback to verify the whole removal sequence. 910 mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); 911 validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 912 mNetworkObserverCaptor0.getValue()); 913 914 // To test if the failure is handled cleanly, invoke teardown and ensure that 915 // none of the mocks are used because the iface does not exist in the internal 916 // database. 917 mWifiNative.teardownInterface(IFACE_NAME_0); 918 } 919 920 /** 921 * Verifies failure handling in setup of a softAp interface. 922 */ 923 @Test 924 public void testSetupSoftApInterfaceFailureInStartHal() throws Exception { 925 when(mWifiVendorHal.startVendorHal()).thenReturn(false); 926 assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0)); 927 928 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 929 mInOrder.verify(mWifiVendorHal).startVendorHal(); 930 mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal(); 931 932 // To test if the failure is handled cleanly, invoke teardown and ensure that 933 // none of the mocks are used because the iface does not exist in the internal 934 // database. 935 mWifiNative.teardownInterface(IFACE_NAME_0); 936 } 937 938 /** 939 * Verifies failure handling in setup of a softAp interface. 940 */ 941 @Test 942 public void testSetupSoftApInterfaceFailureInHalCreateApIface() throws Exception { 943 when(mWifiVendorHal.createApIface(any())).thenReturn(null); 944 assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0)); 945 946 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 947 mInOrder.verify(mWifiVendorHal).startVendorHal(); 948 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 949 mInOrder.verify(mWifiVendorHal).createApIface(any()); 950 mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal(); 951 952 // To test if the failure is handled cleanly, invoke teardown and ensure that 953 // none of the mocks are used because the iface does not exist in the internal 954 // database. 955 mWifiNative.teardownInterface(IFACE_NAME_0); 956 } 957 958 /** 959 * Verifies failure handling in setup of a softAp interface. 960 */ 961 @Test 962 public void testSetupSoftApInterfaceFailureInWificondSetupInterfaceForSoftapMode() 963 throws Exception { 964 when(mWificondControl.setupInterfaceForSoftApMode(any())).thenReturn(null); 965 assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0)); 966 967 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 968 mInOrder.verify(mWifiVendorHal).startVendorHal(); 969 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 970 mInOrder.verify(mWifiVendorHal).createApIface(mIfaceDestroyedListenerCaptor0.capture()); 971 mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(any()); 972 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 973 mInOrder.verify(mWifiVendorHal).removeApIface(any()); 974 mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToWificond(); 975 976 // Trigger the HAL interface destroyed callback to verify the whole removal sequence. 977 mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); 978 validateOnDestroyedSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0, 979 null); 980 981 // To test if the failure is handled cleanly, invoke teardown and ensure that 982 // none of the mocks are used because the iface does not exist in the internal 983 // database. 984 mWifiNative.teardownInterface(IFACE_NAME_0); 985 } 986 987 /** 988 * Verifies the interface state query API. 989 */ 990 @Test 991 public void testIsInterfaceUp() throws Exception { 992 executeAndValidateSetupClientInterface( 993 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 994 mNetworkObserverCaptor0); 995 996 mInterfaceConfiguration.setInterfaceUp(); 997 assertTrue(mWifiNative.isInterfaceUp(IFACE_NAME_0)); 998 999 mInterfaceConfiguration.setInterfaceDown(); 1000 assertFalse(mWifiNative.isInterfaceUp(IFACE_NAME_0)); 1001 1002 when(mNwManagementService.getInterfaceConfig(IFACE_NAME_0)).thenReturn(null); 1003 assertFalse(mWifiNative.isInterfaceUp(IFACE_NAME_0)); 1004 1005 verify(mNwManagementService, times(4)).getInterfaceConfig(IFACE_NAME_0); 1006 } 1007 1008 /** 1009 * Verifies that the interface name is null when there are no interfaces setup. 1010 */ 1011 @Test 1012 public void testGetClientInterfaceNameWithNoInterfacesSetup() throws Exception { 1013 assertNull(mWifiNative.getClientInterfaceName()); 1014 } 1015 1016 /** 1017 * Verifies that the interface name is null when there are no client interfaces setup. 1018 */ 1019 @Test 1020 public void testGetClientInterfaceNameWithNoClientInterfaceSetup() throws Exception { 1021 executeAndValidateSetupSoftApInterface( 1022 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 1023 mNetworkObserverCaptor0); 1024 assertNull(mWifiNative.getClientInterfaceName()); 1025 } 1026 1027 /** 1028 * Verifies that the interface name is not null when there is one client interface setup. 1029 */ 1030 @Test 1031 public void testGetClientInterfaceNameWithOneClientInterfaceSetup() throws Exception { 1032 executeAndValidateSetupClientInterface( 1033 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 1034 mNetworkObserverCaptor0); 1035 assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName()); 1036 } 1037 1038 /** 1039 * Verifies that the interface name is not null when there are more than one client interfaces 1040 * setup. 1041 */ 1042 @Test 1043 public void testGetClientInterfaceNameWithMoreThanOneClientInterfaceSetup() throws Exception { 1044 executeAndValidateSetupClientInterface( 1045 false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, 1046 mNetworkObserverCaptor0); 1047 executeAndValidateSetupClientInterface( 1048 true, false, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1, 1049 mNetworkObserverCaptor1); 1050 String interfaceName = mWifiNative.getClientInterfaceName(); 1051 assertNotNull(interfaceName); 1052 assertTrue(interfaceName.equals(IFACE_NAME_0) || interfaceName.equals(IFACE_NAME_1)); 1053 } 1054 1055 /* 1056 * Verifies the setup of a client interface and then a SoftAp interface which would 1057 * destroy the Client interface. This is what would happen on older devices which do not 1058 * support the vendor HAL. 1059 */ 1060 @Test 1061 public void testSetupClientAndSoftApInterfaceCausesClientInterfaceTeardownWithNoVendorHal() 1062 throws Exception { 1063 when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false); 1064 when(mPropertyService.getString(any(), any())).thenReturn(IFACE_NAME_0); 1065 1066 // First setup a STA interface and verify. 1067 assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0)); 1068 1069 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1070 mInOrder.verify(mWificondControl).enableSupplicant(); 1071 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 1072 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 1073 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 1074 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 1075 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1076 mInOrder.verify(mWificondControl).setupInterfaceForClientMode(IFACE_NAME_0); 1077 mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0); 1078 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor0.capture()); 1079 mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0); 1080 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 1081 mInOrder.verify(mNwManagementService).clearInterfaceAddresses(IFACE_NAME_0); 1082 mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true); 1083 mInOrder.verify(mNwManagementService).disableIpv6(IFACE_NAME_0); 1084 1085 // Now setup an AP interface. 1086 assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1)); 1087 1088 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1089 // Creation of AP interface should trigger the STA interface destroy 1090 verify(mWifiMonitor).stopMonitoring(IFACE_NAME_0); 1091 mInOrder.verify(mNwManagementService).unregisterObserver( 1092 mNetworkObserverCaptor0.getValue()); 1093 mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_0); 1094 mInOrder.verify(mWificondControl).tearDownClientInterface(IFACE_NAME_0); 1095 mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler(); 1096 mInOrder.verify(mWificondControl).disableSupplicant(); 1097 mInOrder.verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0); 1098 // Now continue with rest of AP interface setup. 1099 mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0); 1100 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture()); 1101 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 1102 } 1103 1104 /** 1105 * Verifies the setup of a client interface and then a SoftAp interface which would 1106 * destroy the Client interface. This is what would happen on older devices which do not 1107 * support the vendor HAL. 1108 */ 1109 @Test 1110 public void testSetupSoftApAndClientInterfaceCausesSoftApInterfaceTeardownWithNoVendorHal() 1111 throws Exception { 1112 when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false); 1113 when(mPropertyService.getString(any(), any())).thenReturn(IFACE_NAME_0); 1114 1115 // First setup an AP interface and verify. 1116 assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0)); 1117 1118 mInOrder.verify(mWifiVendorHal, times(2)).isVendorHalSupported(); 1119 mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0); 1120 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor0.capture()); 1121 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 1122 1123 // Now setup a STA interface. 1124 assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback1)); 1125 1126 mInOrder.verify(mWificondControl).enableSupplicant(); 1127 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 1128 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 1129 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 1130 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 1131 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1132 // Creation of STA interface should trigger the AP interface destroy. 1133 mInOrder.verify(mNwManagementService).unregisterObserver( 1134 mNetworkObserverCaptor0.getValue()); 1135 mInOrder.verify(mHostapdHal).removeAccessPoint(IFACE_NAME_0); 1136 mInOrder.verify(mHostapdHal).deregisterDeathHandler(); 1137 mInOrder.verify(mWificondControl).stopHostapd(IFACE_NAME_0); 1138 mInOrder.verify(mWificondControl).tearDownSoftApInterface(IFACE_NAME_0); 1139 mInOrder.verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0); 1140 // Now continue with rest of STA interface setup. 1141 mInOrder.verify(mWificondControl).setupInterfaceForClientMode(IFACE_NAME_0); 1142 mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0); 1143 mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture()); 1144 mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0); 1145 mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0); 1146 mInOrder.verify(mNwManagementService).clearInterfaceAddresses(IFACE_NAME_0); 1147 mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true); 1148 mInOrder.verify(mNwManagementService).disableIpv6(IFACE_NAME_0); 1149 } 1150 1151 /** 1152 * Verifies the handling of radio mode change callbacks. 1153 */ 1154 @Test 1155 public void testRadioModeChangeCallback() { 1156 WifiNative.VendorHalRadioModeChangeEventHandler handler = 1157 mWifiVendorHalRadioModeChangeHandlerCaptor.getValue(); 1158 1159 handler.onMcc(WifiScanner.WIFI_BAND_5_GHZ); 1160 mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToMcc(); 1161 1162 handler.onScc(WifiScanner.WIFI_BAND_24_GHZ); 1163 mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToScc(); 1164 1165 handler.onSbs(WifiScanner.WIFI_BAND_24_GHZ); 1166 mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToSbs(); 1167 1168 handler.onDbs(); 1169 mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToDbs(); 1170 } 1171 1172 private void executeAndValidateSetupClientInterface( 1173 boolean existingStaIface, boolean existingApIface, 1174 String ifaceName, @Mock WifiNative.InterfaceCallback callback, 1175 ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, 1176 ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception { 1177 when(mWifiVendorHal.createStaIface(anyBoolean(), any())).thenReturn(ifaceName); 1178 assertEquals(ifaceName, mWifiNative.setupInterfaceForClientMode(false, callback)); 1179 1180 validateSetupClientInterface( 1181 existingStaIface, existingApIface, ifaceName, destroyedListenerCaptor, 1182 networkObserverCaptor); 1183 } 1184 1185 private void validateSetupClientInterface( 1186 boolean existingStaIface, boolean existingApIface, 1187 String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, 1188 ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception { 1189 if (!existingStaIface && !existingApIface) { 1190 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1191 mInOrder.verify(mWifiVendorHal).startVendorHal(); 1192 } 1193 if (!existingStaIface) { 1194 mInOrder.verify(mWificondControl).enableSupplicant(); 1195 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted(); 1196 mInOrder.verify(mSupplicantStaIfaceHal).initialize(); 1197 mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete(); 1198 mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any()); 1199 } 1200 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1201 mInOrder.verify(mWifiVendorHal).createStaIface(eq(false), 1202 destroyedListenerCaptor.capture()); 1203 mInOrder.verify(mWificondControl).setupInterfaceForClientMode(ifaceName); 1204 mInOrder.verify(mSupplicantStaIfaceHal).setupIface(ifaceName); 1205 mInOrder.verify(mNwManagementService).registerObserver(networkObserverCaptor.capture()); 1206 mInOrder.verify(mWifiMonitor).startMonitoring(ifaceName); 1207 mInOrder.verify(mNwManagementService).getInterfaceConfig(ifaceName); 1208 mInOrder.verify(mNwManagementService).clearInterfaceAddresses(ifaceName); 1209 mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(ifaceName, true); 1210 mInOrder.verify(mNwManagementService).disableIpv6(ifaceName); 1211 } 1212 1213 private void executeAndValidateTeardownClientInterface( 1214 boolean anyOtherStaIface, boolean anyOtherApIface, 1215 String ifaceName, @Mock WifiNative.InterfaceCallback callback, 1216 InterfaceDestroyedListener destroyedListener, 1217 BaseNetworkObserver networkObserver) throws Exception { 1218 mWifiNative.teardownInterface(ifaceName); 1219 1220 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1221 mInOrder.verify(mWifiVendorHal).removeStaIface(ifaceName); 1222 1223 // Now trigger the HalDeviceManager destroy callback to initiate the rest of the teardown. 1224 destroyedListener.onDestroyed(ifaceName); 1225 1226 validateOnDestroyedClientInterface( 1227 anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver); 1228 } 1229 1230 private void validateOnDestroyedClientInterface( 1231 boolean anyOtherStaIface, boolean anyOtherApIface, 1232 String ifaceName, @Mock WifiNative.InterfaceCallback callback, 1233 BaseNetworkObserver networkObserver) throws Exception { 1234 mInOrder.verify(mWifiMonitor).stopMonitoring(ifaceName); 1235 if (networkObserver != null) { 1236 mInOrder.verify(mNwManagementService).unregisterObserver(networkObserver); 1237 } 1238 mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(ifaceName); 1239 mInOrder.verify(mWificondControl).tearDownClientInterface(ifaceName); 1240 1241 if (!anyOtherStaIface) { 1242 mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler(); 1243 mInOrder.verify(mWificondControl).disableSupplicant(); 1244 } 1245 if (!anyOtherStaIface && !anyOtherApIface) { 1246 mInOrder.verify(mWificondControl).tearDownInterfaces(); 1247 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1248 mInOrder.verify(mWifiVendorHal).stopVendorHal(); 1249 } 1250 mInOrder.verify(callback).onDestroyed(ifaceName); 1251 } 1252 1253 private void executeAndValidateSetupSoftApInterface( 1254 boolean existingStaIface, boolean existingApIface, 1255 String ifaceName, @Mock WifiNative.InterfaceCallback callback, 1256 ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, 1257 ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception { 1258 when(mWifiVendorHal.createApIface(any())).thenReturn(ifaceName); 1259 assertEquals(ifaceName, mWifiNative.setupInterfaceForSoftApMode(callback)); 1260 1261 validateSetupSoftApInterface( 1262 existingStaIface, existingApIface, ifaceName, destroyedListenerCaptor, 1263 networkObserverCaptor); 1264 } 1265 1266 private void validateSetupSoftApInterface( 1267 boolean existingStaIface, boolean existingApIface, 1268 String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, 1269 ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception { 1270 if (!existingStaIface && !existingApIface) { 1271 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1272 mInOrder.verify(mWifiVendorHal).startVendorHal(); 1273 } 1274 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1275 mInOrder.verify(mWifiVendorHal).createApIface(destroyedListenerCaptor.capture()); 1276 mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(ifaceName); 1277 mInOrder.verify(mNwManagementService).registerObserver(networkObserverCaptor.capture()); 1278 mInOrder.verify(mNwManagementService).getInterfaceConfig(ifaceName); 1279 } 1280 1281 private void executeAndValidateTeardownSoftApInterface( 1282 boolean anyOtherStaIface, boolean anyOtherApIface, 1283 String ifaceName, @Mock WifiNative.InterfaceCallback callback, 1284 InterfaceDestroyedListener destroyedListener, 1285 BaseNetworkObserver networkObserver) throws Exception { 1286 mWifiNative.teardownInterface(ifaceName); 1287 1288 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1289 mInOrder.verify(mWifiVendorHal).removeApIface(ifaceName); 1290 1291 // Now trigger the HalDeviceManager destroy callback to initiate the rest of the teardown. 1292 destroyedListener.onDestroyed(ifaceName); 1293 1294 validateOnDestroyedSoftApInterface( 1295 anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver); 1296 } 1297 1298 private void validateOnDestroyedSoftApInterface( 1299 boolean anyOtherStaIface, boolean anyOtherApIface, 1300 String ifaceName, @Mock WifiNative.InterfaceCallback callback, 1301 BaseNetworkObserver networkObserver) throws Exception { 1302 if (networkObserver != null) { 1303 mInOrder.verify(mNwManagementService).unregisterObserver(networkObserver); 1304 } 1305 mInOrder.verify(mHostapdHal).removeAccessPoint(ifaceName); 1306 mInOrder.verify(mHostapdHal).deregisterDeathHandler(); 1307 mInOrder.verify(mWificondControl).stopHostapd(ifaceName); 1308 mInOrder.verify(mWificondControl).tearDownSoftApInterface(ifaceName); 1309 1310 if (!anyOtherStaIface && !anyOtherApIface) { 1311 mInOrder.verify(mWificondControl).tearDownInterfaces(); 1312 mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); 1313 mInOrder.verify(mWifiVendorHal).stopVendorHal(); 1314 } 1315 mInOrder.verify(callback).onDestroyed(ifaceName); 1316 } 1317 1318 private void executeAndValidateInterfaceStateChange( 1319 String ifaceName, boolean up, BaseNetworkObserver networkObserver) throws Exception { 1320 if (up) { 1321 mInterfaceConfiguration.setInterfaceUp(); 1322 } else { 1323 mInterfaceConfiguration.setInterfaceDown(); 1324 } 1325 networkObserver.interfaceLinkStateChanged(ifaceName, up); 1326 mInOrder.verify(mNwManagementService).getInterfaceConfig(ifaceName); 1327 } 1328 } 1329