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.*; 20 import static org.mockito.ArgumentMatchers.anyInt; 21 import static org.mockito.ArgumentMatchers.eq; 22 import static org.mockito.Matchers.argThat; 23 import static org.mockito.Mockito.*; 24 25 import android.net.MacAddress; 26 import android.net.wifi.IApInterface; 27 import android.net.wifi.IApInterfaceEventCallback; 28 import android.net.wifi.IClientInterface; 29 import android.net.wifi.IPnoScanEvent; 30 import android.net.wifi.IScanEvent; 31 import android.net.wifi.IWifiScannerImpl; 32 import android.net.wifi.IWificond; 33 import android.net.wifi.ScanResult; 34 import android.net.wifi.WifiConfiguration; 35 import android.net.wifi.WifiEnterpriseConfig; 36 import android.net.wifi.WifiScanner; 37 import android.os.IBinder; 38 import android.os.RemoteException; 39 import android.support.test.filters.SmallTest; 40 41 import com.android.server.wifi.util.NativeUtil; 42 import com.android.server.wifi.wificond.ChannelSettings; 43 import com.android.server.wifi.wificond.HiddenNetwork; 44 import com.android.server.wifi.wificond.NativeScanResult; 45 import com.android.server.wifi.wificond.PnoSettings; 46 import com.android.server.wifi.wificond.RadioChainInfo; 47 import com.android.server.wifi.wificond.SingleScanSettings; 48 49 import org.junit.Before; 50 import org.junit.Test; 51 import org.mockito.ArgumentCaptor; 52 import org.mockito.ArgumentMatcher; 53 import org.mockito.Mock; 54 import org.mockito.MockitoAnnotations; 55 56 import java.io.ByteArrayOutputStream; 57 import java.nio.charset.StandardCharsets; 58 import java.util.ArrayList; 59 import java.util.BitSet; 60 import java.util.HashSet; 61 import java.util.List; 62 import java.util.Set; 63 64 /** 65 * Unit tests for {@link com.android.server.wifi.WificondControl}. 66 */ 67 @SmallTest 68 public class WificondControlTest { 69 @Mock private WifiInjector mWifiInjector; 70 @Mock private WifiMonitor mWifiMonitor; 71 @Mock private WifiMetrics mWifiMetrics; 72 @Mock private IWificond mWificond; 73 @Mock private IBinder mWifiCondBinder; 74 @Mock private IClientInterface mClientInterface; 75 @Mock private IWifiScannerImpl mWifiScannerImpl; 76 @Mock private CarrierNetworkConfig mCarrierNetworkConfig; 77 @Mock private IApInterface mApInterface; 78 @Mock private WifiNative.SoftApListener mSoftApListener; 79 private WificondControl mWificondControl; 80 private static final String TEST_INTERFACE_NAME = "test_wlan_if"; 81 private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; 82 private static final byte[] TEST_SSID = 83 new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; 84 private static final byte[] TEST_PSK = 85 new byte[] {'T', 'e', 's', 't'}; 86 private static final byte[] TEST_BSSID = 87 new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1, 88 (byte) 0x2c, (byte) 0x97, (byte) 0x8b}; 89 // This the IE buffer which is consistent with TEST_SSID. 90 private static final byte[] TEST_INFO_ELEMENT_SSID = 91 new byte[] { 92 // Element ID for SSID. 93 (byte) 0x00, 94 // Length of the SSID: 0x0b or 11. 95 (byte) 0x0b, 96 // This is string "GoogleGuest" 97 'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; 98 // RSN IE data indicating EAP key management. 99 private static final byte[] TEST_INFO_ELEMENT_RSN = 100 new byte[] { 101 // Element ID for RSN. 102 (byte) 0x30, 103 // Length of the element data. 104 (byte) 0x18, 105 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02, 106 (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, 107 (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02, (byte) 0x01, (byte) 0x00, 108 (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x01, (byte) 0x00, (byte) 0x00 }; 109 110 private static final int TEST_FREQUENCY = 2456; 111 private static final int TEST_SIGNAL_MBM = -4500; 112 private static final long TEST_TSF = 34455441; 113 private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }}; 114 private static final boolean TEST_ASSOCIATED = true; 115 private static final NativeScanResult MOCK_NATIVE_SCAN_RESULT = 116 new NativeScanResult() {{ 117 ssid = TEST_SSID; 118 bssid = TEST_BSSID; 119 infoElement = TEST_INFO_ELEMENT_SSID; 120 frequency = TEST_FREQUENCY; 121 signalMbm = TEST_SIGNAL_MBM; 122 capability = TEST_CAPABILITY; 123 associated = TEST_ASSOCIATED; 124 radioChainInfos = new ArrayList<>(); 125 }}; 126 private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_1 = 127 new RadioChainInfo() {{ 128 chainId = 1; 129 level = -89; 130 }}; 131 private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_2 = 132 new RadioChainInfo() {{ 133 chainId = 0; 134 level = -78; 135 }}; 136 private static final Set<Integer> SCAN_FREQ_SET = 137 new HashSet<Integer>() {{ 138 add(2410); 139 add(2450); 140 add(5050); 141 add(5200); 142 }}; 143 private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; 144 private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; 145 146 private static final Set<String> SCAN_HIDDEN_NETWORK_SSID_SET = 147 new HashSet<String>() {{ 148 add(TEST_QUOTED_SSID_1); 149 add(TEST_QUOTED_SSID_2); 150 }}; 151 152 153 private static final WifiNative.PnoSettings TEST_PNO_SETTINGS = 154 new WifiNative.PnoSettings() {{ 155 isConnected = false; 156 periodInMs = 6000; 157 networkList = new WifiNative.PnoNetwork[2]; 158 networkList[0] = new WifiNative.PnoNetwork(); 159 networkList[1] = new WifiNative.PnoNetwork(); 160 networkList[0].ssid = TEST_QUOTED_SSID_1; 161 networkList[0].flags = WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN; 162 networkList[1].ssid = TEST_QUOTED_SSID_2; 163 networkList[1].flags = 0; 164 }}; 165 private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("ee:33:a2:94:10:92"); 166 167 @Before 168 public void setUp() throws Exception { 169 // Setup mocks for successful WificondControl operation. Failure case mocks should be 170 // created in specific tests 171 MockitoAnnotations.initMocks(this); 172 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 173 when(mWificond.asBinder()).thenReturn(mWifiCondBinder); 174 when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); 175 when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); 176 when(mWificond.createApInterface(any())).thenReturn(mApInterface); 177 when(mWificond.tearDownClientInterface(any())).thenReturn(true); 178 when(mWificond.tearDownApInterface(any())).thenReturn(true); 179 when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); 180 when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); 181 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 182 mWificondControl = new WificondControl(mWifiInjector, mWifiMonitor, mCarrierNetworkConfig); 183 assertEquals(mClientInterface, mWificondControl.setupInterfaceForClientMode( 184 TEST_INTERFACE_NAME)); 185 verify(mWifiInjector).makeWificond(); 186 verify(mWifiCondBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); 187 } 188 189 /** 190 * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. 191 */ 192 @Test 193 public void testSetupInterfaceForClientMode() throws Exception { 194 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 195 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 196 verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); 197 } 198 199 /** 200 * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). 201 */ 202 @Test 203 public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { 204 verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); 205 } 206 207 /** 208 * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) returns null when wificond is 209 * not started. 210 */ 211 @Test 212 public void testSetupInterfaceForClientModeErrorWhenWificondIsNotStarted() throws Exception { 213 // Invoke wificond death handler to clear the handle. 214 mWificondControl.binderDied(); 215 when(mWifiInjector.makeWificond()).thenReturn(null); 216 IClientInterface returnedClientInterface = 217 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 218 assertEquals(null, returnedClientInterface); 219 verify(mWifiInjector, times(2)).makeWificond(); 220 } 221 222 /** 223 * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) returns null when wificond 224 * failed to setup client interface. 225 */ 226 @Test 227 public void testSetupInterfaceForClientModeErrorWhenWificondFailedToSetupInterface() 228 throws Exception { 229 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 230 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(null); 231 232 IClientInterface returnedClientInterface = 233 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 234 assertEquals(null, returnedClientInterface); 235 } 236 237 /** 238 * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. 239 */ 240 @Test 241 public void testTeardownClientInterface() throws Exception { 242 when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); 243 244 assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); 245 verify(mWifiScannerImpl).unsubscribeScanEvents(); 246 verify(mWifiScannerImpl).unsubscribePnoScanEvents(); 247 verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); 248 } 249 250 /** 251 * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. 252 */ 253 @Test 254 public void testTeardownClientInterfaceOnInvalidIface() throws Exception { 255 when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); 256 257 assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); 258 verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); 259 verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); 260 verify(mWificond, never()).tearDownClientInterface(any()); 261 } 262 263 /** 264 * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. 265 */ 266 @Test 267 public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { 268 when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); 269 doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); 270 271 assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); 272 verify(mWifiScannerImpl).unsubscribeScanEvents(); 273 verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); 274 verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); 275 } 276 /** 277 * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. 278 */ 279 @Test 280 public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { 281 when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); 282 283 assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); 284 verify(mWifiScannerImpl).unsubscribeScanEvents(); 285 verify(mWifiScannerImpl).unsubscribePnoScanEvents(); 286 verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); 287 } 288 289 /** 290 * Verifies that the client handles are cleared after teardown. 291 */ 292 @Test 293 public void testTeardownClientInterfaceClearsHandles() throws Exception { 294 testTeardownClientInterface(); 295 296 assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); 297 verify(mClientInterface, never()).signalPoll(); 298 299 assertFalse(mWificondControl.scan( 300 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_LOW_LATENCY, 301 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET)); 302 verify(mWifiScannerImpl, never()).scan(any()); 303 } 304 305 /** 306 * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. 307 */ 308 @Test 309 public void testSetupInterfaceForSoftApMode() throws Exception { 310 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 311 when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); 312 313 IApInterface returnedApInterface = 314 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME); 315 assertEquals(mApInterface, returnedApInterface); 316 verify(mWifiInjector).makeWificond(); 317 verify(mWifiCondBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); 318 verify(mWificond).createApInterface(TEST_INTERFACE_NAME); 319 } 320 321 /** 322 * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. 323 */ 324 @Test 325 public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { 326 // Invoke wificond death handler to clear the handle. 327 mWificondControl.binderDied(); 328 when(mWifiInjector.makeWificond()).thenReturn(null); 329 330 IApInterface returnedApInterface = 331 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME); 332 333 assertEquals(null, returnedApInterface); 334 verify(mWifiInjector, times(2)).makeWificond(); 335 } 336 337 /** 338 * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond 339 * failed to setup AP interface. 340 */ 341 @Test 342 public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() 343 throws Exception { 344 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 345 when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); 346 347 IApInterface returnedApInterface = 348 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME); 349 assertEquals(null, returnedApInterface); 350 } 351 352 /** 353 * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. 354 */ 355 @Test 356 public void testTeardownSoftApInterface() throws Exception { 357 testSetupInterfaceForSoftApMode(); 358 when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); 359 360 assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); 361 verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); 362 } 363 364 /** 365 * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. 366 */ 367 @Test 368 public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { 369 testSetupInterfaceForSoftApMode(); 370 when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); 371 372 assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); 373 verify(mWificond, never()).tearDownApInterface(any()); 374 } 375 376 /** 377 * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. 378 */ 379 @Test 380 public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { 381 testSetupInterfaceForSoftApMode(); 382 when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); 383 384 assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); 385 verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); 386 } 387 388 /** 389 * Verifies that the SoftAp handles are cleared after teardown. 390 */ 391 @Test 392 public void testTeardownSoftApInterfaceClearsHandles() throws Exception { 393 testTeardownSoftApInterface(); 394 395 assertFalse(mWificondControl.startHostapd( 396 TEST_INTERFACE_NAME, mSoftApListener)); 397 verify(mApInterface, never()).startHostapd(any()); 398 } 399 400 /** 401 * Verifies that we can setup concurrent interfaces. 402 */ 403 @Test 404 public void testSetupMulitpleInterfaces() throws Exception { 405 when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); 406 407 IApInterface returnedApInterface = 408 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1); 409 assertEquals(mApInterface, returnedApInterface); 410 verify(mWifiInjector).makeWificond(); 411 verify(mWifiCondBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); 412 413 verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); 414 verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); 415 } 416 417 /** 418 * Verifies that we can setup concurrent interfaces. 419 */ 420 @Test 421 public void testTeardownMulitpleInterfaces() throws Exception { 422 testSetupMulitpleInterfaces(); 423 assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); 424 assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); 425 426 verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); 427 verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); 428 } 429 430 /** 431 * Verifies that enableSupplicant() calls wificond. 432 */ 433 @Test 434 public void testEnableSupplicant() throws Exception { 435 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 436 when(mWificond.enableSupplicant()).thenReturn(true); 437 438 assertTrue(mWificondControl.enableSupplicant()); 439 verify(mWifiInjector).makeWificond(); 440 verify(mWificond).enableSupplicant(); 441 } 442 443 /** 444 * Verifies that enableSupplicant() returns false when there is no configured 445 * client interface. 446 */ 447 @Test 448 public void testEnableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception { 449 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 450 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 451 452 // Configure client interface. 453 IClientInterface returnedClientInterface = 454 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 455 assertEquals(mClientInterface, returnedClientInterface); 456 457 // Tear down interfaces. 458 assertTrue(mWificondControl.tearDownInterfaces()); 459 460 // Enabling supplicant should fail. 461 assertFalse(mWificondControl.enableSupplicant()); 462 } 463 464 /** 465 * Verifies that disableSupplicant() calls wificond. 466 */ 467 @Test 468 public void testDisableSupplicant() throws Exception { 469 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 470 when(mWificond.disableSupplicant()).thenReturn(true); 471 472 assertTrue(mWificondControl.disableSupplicant()); 473 verify(mWifiInjector).makeWificond(); 474 verify(mWificond).disableSupplicant(); 475 } 476 477 /** 478 * Verifies that disableSupplicant() returns false when there is no configured 479 * client interface. 480 */ 481 @Test 482 public void testDisableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception { 483 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 484 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 485 486 // Configure client interface. 487 IClientInterface returnedClientInterface = 488 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 489 assertEquals(mClientInterface, returnedClientInterface); 490 491 // Tear down interfaces. 492 assertTrue(mWificondControl.tearDownInterfaces()); 493 494 // Disabling supplicant should fail. 495 assertFalse(mWificondControl.disableSupplicant()); 496 } 497 498 /** 499 * Verifies that tearDownInterfaces() calls wificond. 500 */ 501 @Test 502 public void testTearDownInterfaces() throws Exception { 503 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 504 assertTrue(mWificondControl.tearDownInterfaces()); 505 verify(mWificond).tearDownInterfaces(); 506 } 507 508 /** 509 * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was 510 * a configured client interface. 511 */ 512 @Test 513 public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { 514 assertTrue(mWificondControl.tearDownInterfaces()); 515 verify(mWifiScannerImpl).unsubscribeScanEvents(); 516 } 517 518 519 /** 520 * Verifies that tearDownInterfaces() returns false when wificond is not started. 521 */ 522 @Test 523 public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { 524 // Invoke wificond death handler to clear the handle. 525 mWificondControl.binderDied(); 526 when(mWifiInjector.makeWificond()).thenReturn(null); 527 assertFalse(mWificondControl.tearDownInterfaces()); 528 } 529 530 /** 531 * Verifies that signalPoll() calls wificond. 532 */ 533 @Test 534 public void testSignalPoll() throws Exception { 535 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 536 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 537 538 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 539 mWificondControl.signalPoll(TEST_INTERFACE_NAME); 540 verify(mClientInterface).signalPoll(); 541 } 542 543 /** 544 * Verifies that signalPoll() returns null when there is no configured client interface. 545 */ 546 @Test 547 public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { 548 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 549 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 550 551 // Configure client interface. 552 IClientInterface returnedClientInterface = 553 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 554 assertEquals(mClientInterface, returnedClientInterface); 555 556 // Tear down interfaces. 557 assertTrue(mWificondControl.tearDownInterfaces()); 558 559 // Signal poll should fail. 560 assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); 561 } 562 563 /** 564 * Verifies that getTxPacketCounters() calls wificond. 565 */ 566 @Test 567 public void testGetTxPacketCounters() throws Exception { 568 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 569 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 570 571 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 572 mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); 573 verify(mClientInterface).getPacketCounters(); 574 } 575 576 /** 577 * Verifies that getTxPacketCounters() returns null when there is no configured client 578 * interface. 579 */ 580 @Test 581 public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { 582 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 583 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 584 585 // Configure client interface. 586 IClientInterface returnedClientInterface = 587 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 588 assertEquals(mClientInterface, returnedClientInterface); 589 590 // Tear down interfaces. 591 assertTrue(mWificondControl.tearDownInterfaces()); 592 593 // Signal poll should fail. 594 assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); 595 } 596 597 /** 598 * Verifies that getScanResults() returns null when there is no configured client 599 * interface. 600 */ 601 @Test 602 public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { 603 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 604 when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); 605 606 // Configure client interface. 607 IClientInterface returnedClientInterface = 608 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME); 609 assertEquals(mClientInterface, returnedClientInterface); 610 611 // Tear down interfaces. 612 assertTrue(mWificondControl.tearDownInterfaces()); 613 614 // getScanResults should fail. 615 assertEquals(0, 616 mWificondControl.getScanResults(TEST_INTERFACE_NAME, 617 WificondControl.SCAN_TYPE_SINGLE_SCAN).size()); 618 } 619 620 /** 621 * Verifies that getScanResults() can parse NativeScanResult from wificond correctly, 622 */ 623 @Test 624 public void testGetScanResults() throws Exception { 625 assertNotNull(mWifiScannerImpl); 626 627 // Mock the returned array of NativeScanResult. 628 NativeScanResult[] mockScanResults = {MOCK_NATIVE_SCAN_RESULT}; 629 when(mWifiScannerImpl.getScanResults()).thenReturn(mockScanResults); 630 631 ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults( 632 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN); 633 // The test IEs {@link #TEST_INFO_ELEMENT} doesn't contained RSN IE, which means non-EAP 634 // AP. So verify carrier network is not checked, since EAP is currently required for a 635 // carrier network. 636 verify(mCarrierNetworkConfig, never()).isCarrierNetwork(anyString()); 637 assertEquals(mockScanResults.length, returnedScanResults.size()); 638 // Since NativeScanResult is organized differently from ScanResult, this only checks 639 // a few fields. 640 for (int i = 0; i < mockScanResults.length; i++) { 641 assertArrayEquals(mockScanResults[i].ssid, 642 returnedScanResults.get(i).getScanResult().SSID.getBytes()); 643 assertEquals(mockScanResults[i].frequency, 644 returnedScanResults.get(i).getScanResult().frequency); 645 assertEquals(mockScanResults[i].tsf, 646 returnedScanResults.get(i).getScanResult().timestamp); 647 } 648 } 649 650 /** 651 * Verifies that scan result's carrier network info {@link ScanResult#isCarrierAp} and 652 * {@link ScanResult#getCarrierApEapType} is set appropriated based on the carrier network 653 * config. 654 * 655 * @throws Exception 656 */ 657 @Test 658 public void testGetScanResultsForCarrierAp() throws Exception { 659 assertNotNull(mWifiScannerImpl); 660 661 // Include RSN IE to indicate EAP key management. 662 ByteArrayOutputStream out = new ByteArrayOutputStream(); 663 out.write(TEST_INFO_ELEMENT_SSID); 664 out.write(TEST_INFO_ELEMENT_RSN); 665 NativeScanResult nativeScanResult = new NativeScanResult(MOCK_NATIVE_SCAN_RESULT); 666 nativeScanResult.infoElement = out.toByteArray(); 667 when(mWifiScannerImpl.getScanResults()).thenReturn( 668 new NativeScanResult[] {nativeScanResult}); 669 670 // AP associated with a carrier network. 671 int eapType = WifiEnterpriseConfig.Eap.SIM; 672 String carrierName = "Test Carrier"; 673 when(mCarrierNetworkConfig.isCarrierNetwork(new String(nativeScanResult.ssid))) 674 .thenReturn(true); 675 when(mCarrierNetworkConfig.getNetworkEapType(new String(nativeScanResult.ssid))) 676 .thenReturn(eapType); 677 when(mCarrierNetworkConfig.getCarrierName(new String(nativeScanResult.ssid))) 678 .thenReturn(carrierName); 679 ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults( 680 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN); 681 assertEquals(1, returnedScanResults.size()); 682 // Verify returned scan result. 683 ScanResult scanResult = returnedScanResults.get(0).getScanResult(); 684 assertArrayEquals(nativeScanResult.ssid, scanResult.SSID.getBytes()); 685 assertTrue(scanResult.isCarrierAp); 686 assertEquals(eapType, scanResult.carrierApEapType); 687 assertEquals(carrierName, scanResult.carrierName); 688 reset(mCarrierNetworkConfig); 689 690 // AP not associated with a carrier network. 691 when(mCarrierNetworkConfig.isCarrierNetwork(new String(nativeScanResult.ssid))) 692 .thenReturn(false); 693 returnedScanResults = mWificondControl.getScanResults( 694 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN); 695 assertEquals(1, returnedScanResults.size()); 696 // Verify returned scan result. 697 scanResult = returnedScanResults.get(0).getScanResult(); 698 assertArrayEquals(nativeScanResult.ssid, scanResult.SSID.getBytes()); 699 assertFalse(scanResult.isCarrierAp); 700 assertEquals(ScanResult.UNSPECIFIED, scanResult.carrierApEapType); 701 assertEquals(null, scanResult.carrierName); 702 } 703 704 /** 705 * Verifies that getScanResults() can parse NativeScanResult from wificond correctly, 706 * when there is radio chain info. 707 */ 708 @Test 709 public void testGetScanResultsWithRadioChainInfo() throws Exception { 710 assertNotNull(mWifiScannerImpl); 711 712 // Mock the returned array of NativeScanResult. 713 NativeScanResult nativeScanResult = new NativeScanResult(MOCK_NATIVE_SCAN_RESULT); 714 // Add radio chain info 715 ArrayList<RadioChainInfo> nativeRadioChainInfos = new ArrayList<RadioChainInfo>() {{ 716 add(MOCK_NATIVE_RADIO_CHAIN_INFO_1); 717 add(MOCK_NATIVE_RADIO_CHAIN_INFO_2); 718 }}; 719 nativeScanResult.radioChainInfos = nativeRadioChainInfos; 720 NativeScanResult[] mockScanResults = { nativeScanResult }; 721 722 when(mWifiScannerImpl.getScanResults()).thenReturn(mockScanResults); 723 724 ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults( 725 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN); 726 // The test IEs {@link #TEST_INFO_ELEMENT} doesn't contained RSN IE, which means non-EAP 727 // AP. So verify carrier network is not checked, since EAP is currently required for a 728 // carrier network. 729 verify(mCarrierNetworkConfig, never()).isCarrierNetwork(anyString()); 730 assertEquals(mockScanResults.length, returnedScanResults.size()); 731 // Since NativeScanResult is organized differently from ScanResult, this only checks 732 // a few fields. 733 for (int i = 0; i < mockScanResults.length; i++) { 734 assertArrayEquals(mockScanResults[i].ssid, 735 returnedScanResults.get(i).getScanResult().SSID.getBytes()); 736 assertEquals(mockScanResults[i].frequency, 737 returnedScanResults.get(i).getScanResult().frequency); 738 assertEquals(mockScanResults[i].tsf, 739 returnedScanResults.get(i).getScanResult().timestamp); 740 assertRadioChainInfosEqual(nativeRadioChainInfos, 741 returnedScanResults.get(i).getScanResult().radioChainInfos); 742 } 743 } 744 745 /** 746 * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. 747 */ 748 @Test 749 public void testScan() throws Exception { 750 when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); 751 assertTrue(mWificondControl.scan( 752 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_LOW_POWER, 753 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET)); 754 verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( 755 IWifiScannerImpl.SCAN_TYPE_LOW_POWER, 756 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET))); 757 } 758 759 /** 760 * Verifies that Scan() can handle null input parameters correctly. 761 */ 762 @Test 763 public void testScanNullParameters() throws Exception { 764 when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); 765 assertTrue(mWificondControl.scan( 766 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_HIGH_ACCURACY, null, null)); 767 verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( 768 IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); 769 } 770 771 /** 772 * Verifies that Scan() can handle wificond scan failure. 773 */ 774 @Test 775 public void testScanFailure() throws Exception { 776 when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); 777 assertFalse(mWificondControl.scan( 778 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_LOW_LATENCY, 779 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET)); 780 verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); 781 } 782 783 /** 784 * Verifies that Scan() can handle invalid type. 785 */ 786 @Test 787 public void testScanFailureDueToInvalidType() throws Exception { 788 assertFalse(mWificondControl.scan( 789 TEST_INTERFACE_NAME, 100, 790 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET)); 791 verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); 792 } 793 794 /** 795 * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. 796 */ 797 @Test 798 public void testStartPnoScan() throws Exception { 799 when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); 800 assertTrue(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS)); 801 verify(mWifiScannerImpl).startPnoScan(argThat(new PnoScanMatcher(TEST_PNO_SETTINGS))); 802 } 803 804 /** 805 * Verifies that stopPnoScan() calls underlying wificond. 806 */ 807 @Test 808 public void testStopPnoScan() throws Exception { 809 when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); 810 assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); 811 verify(mWifiScannerImpl).stopPnoScan(); 812 } 813 814 /** 815 * Verifies that stopPnoScan() can handle wificond failure. 816 */ 817 @Test 818 public void testStopPnoScanFailure() throws Exception { 819 820 when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); 821 assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); 822 verify(mWifiScannerImpl).stopPnoScan(); 823 } 824 825 /** 826 * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan 827 * reuslt event. 828 */ 829 @Test 830 public void testScanResultEvent() throws Exception { 831 ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); 832 verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); 833 IScanEvent scanEvent = messageCaptor.getValue(); 834 assertNotNull(scanEvent); 835 scanEvent.OnScanResultReady(); 836 837 verify(mWifiMonitor).broadcastScanResultEvent(any(String.class)); 838 } 839 840 /** 841 * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan 842 * failed event. 843 */ 844 @Test 845 public void testScanFailedEvent() throws Exception { 846 847 ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); 848 verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); 849 IScanEvent scanEvent = messageCaptor.getValue(); 850 assertNotNull(scanEvent); 851 scanEvent.OnScanFailed(); 852 853 verify(mWifiMonitor).broadcastScanFailedEvent(any(String.class)); 854 } 855 856 /** 857 * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan 858 * result event. 859 */ 860 @Test 861 public void testPnoScanResultEvent() throws Exception { 862 ArgumentCaptor<IPnoScanEvent> messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); 863 verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); 864 IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); 865 assertNotNull(pnoScanEvent); 866 pnoScanEvent.OnPnoNetworkFound(); 867 verify(mWifiMonitor).broadcastPnoScanResultEvent(any(String.class)); 868 } 869 870 /** 871 * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. 872 */ 873 @Test 874 public void testPnoScanEventsForMetrics() throws Exception { 875 ArgumentCaptor<IPnoScanEvent> messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); 876 verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); 877 IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); 878 assertNotNull(pnoScanEvent); 879 880 pnoScanEvent.OnPnoNetworkFound(); 881 verify(mWifiMetrics).incrementPnoFoundNetworkEventCount(); 882 883 pnoScanEvent.OnPnoScanFailed(); 884 verify(mWifiMetrics).incrementPnoScanFailedCount(); 885 886 pnoScanEvent.OnPnoScanOverOffloadStarted(); 887 verify(mWifiMetrics).incrementPnoScanStartedOverOffloadCount(); 888 889 pnoScanEvent.OnPnoScanOverOffloadFailed(0); 890 verify(mWifiMetrics).incrementPnoScanFailedOverOffloadCount(); 891 } 892 893 /** 894 * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. 895 */ 896 @Test 897 public void testStartPnoScanForMetrics() throws Exception { 898 when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); 899 assertFalse(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS)); 900 verify(mWifiMetrics).incrementPnoScanStartAttempCount(); 901 verify(mWifiMetrics).incrementPnoScanFailedCount(); 902 } 903 904 /** 905 * Verifies that abortScan() calls underlying wificond. 906 */ 907 @Test 908 public void testAbortScan() throws Exception { 909 mWificondControl.abortScan(TEST_INTERFACE_NAME); 910 verify(mWifiScannerImpl).abortScan(); 911 } 912 913 /** 914 * Verifies successful soft ap start. 915 */ 916 @Test 917 public void testStartHostapdWithPskConfig() throws Exception { 918 testSetupInterfaceForSoftApMode(); 919 when(mApInterface.startHostapd(any())).thenReturn(true); 920 921 assertTrue(mWificondControl.startHostapd( 922 TEST_INTERFACE_NAME, mSoftApListener)); 923 verify(mApInterface).startHostapd(any()); 924 } 925 926 /** 927 * Ensures that the Ap interface callbacks are forwarded to the 928 * SoftApListener used for starting soft AP. 929 */ 930 @Test 931 public void testSoftApListenerInvocation() throws Exception { 932 testSetupInterfaceForSoftApMode(); 933 934 WifiConfiguration config = new WifiConfiguration(); 935 config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); 936 937 when(mApInterface.startHostapd(any())).thenReturn(true); 938 939 final ArgumentCaptor<IApInterfaceEventCallback> apInterfaceCallbackCaptor = 940 ArgumentCaptor.forClass(IApInterfaceEventCallback.class); 941 942 assertTrue(mWificondControl.startHostapd( 943 TEST_INTERFACE_NAME, mSoftApListener)); 944 verify(mApInterface).startHostapd(apInterfaceCallbackCaptor.capture()); 945 946 int numStations = 5; 947 apInterfaceCallbackCaptor.getValue().onNumAssociatedStationsChanged(numStations); 948 verify(mSoftApListener).onNumAssociatedStationsChanged(eq(numStations)); 949 950 int channelFrequency = 2437; 951 int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; 952 apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, 953 channelBandwidth); 954 verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), eq(channelBandwidth)); 955 } 956 957 /** 958 * Ensure that soft ap start fails when the interface is not setup. 959 */ 960 @Test 961 public void testStartHostapdWithoutSetupInterface() throws Exception { 962 assertFalse(mWificondControl.startHostapd( 963 TEST_INTERFACE_NAME, mSoftApListener)); 964 verify(mApInterface, never()).startHostapd(any()); 965 } 966 967 /** 968 * Verifies soft ap start failure. 969 */ 970 @Test 971 public void testStartHostapdFailDueToStartError() throws Exception { 972 testSetupInterfaceForSoftApMode(); 973 WifiConfiguration config = new WifiConfiguration(); 974 config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); 975 976 when(mApInterface.startHostapd(any())).thenReturn(false); 977 978 assertFalse(mWificondControl.startHostapd( 979 TEST_INTERFACE_NAME, mSoftApListener)); 980 verify(mApInterface).startHostapd(any()); 981 } 982 983 /** 984 * Verifies soft ap start failure. 985 */ 986 @Test 987 public void testStartHostapdFailDueToExceptionInStart() throws Exception { 988 testSetupInterfaceForSoftApMode(); 989 WifiConfiguration config = new WifiConfiguration(); 990 config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); 991 992 doThrow(new RemoteException()).when(mApInterface).startHostapd(any()); 993 994 assertFalse(mWificondControl.startHostapd( 995 TEST_INTERFACE_NAME, mSoftApListener)); 996 verify(mApInterface).startHostapd(any()); 997 } 998 999 /** 1000 * Verifies soft ap stop success. 1001 */ 1002 @Test 1003 public void testStopSoftAp() throws Exception { 1004 testSetupInterfaceForSoftApMode(); 1005 1006 when(mApInterface.stopHostapd()).thenReturn(true); 1007 1008 assertTrue(mWificondControl.stopHostapd(TEST_INTERFACE_NAME)); 1009 verify(mApInterface).stopHostapd(); 1010 } 1011 1012 /** 1013 * Ensure that soft ap stop fails when the interface is not setup. 1014 */ 1015 @Test 1016 public void testStopSoftApWithOutSetupInterface() throws Exception { 1017 when(mApInterface.stopHostapd()).thenReturn(true); 1018 assertFalse(mWificondControl.stopHostapd(TEST_INTERFACE_NAME)); 1019 verify(mApInterface, never()).stopHostapd(); 1020 } 1021 1022 /** 1023 * Verifies soft ap stop failure. 1024 */ 1025 @Test 1026 public void testStopSoftApFailDueToStopError() throws Exception { 1027 testSetupInterfaceForSoftApMode(); 1028 1029 when(mApInterface.stopHostapd()).thenReturn(false); 1030 1031 assertFalse(mWificondControl.stopHostapd(TEST_INTERFACE_NAME)); 1032 verify(mApInterface).stopHostapd(); 1033 } 1034 1035 /** 1036 * Verifies soft ap stop failure. 1037 */ 1038 @Test 1039 public void testStopSoftApFailDueToExceptionInStop() throws Exception { 1040 testSetupInterfaceForSoftApMode(); 1041 1042 doThrow(new RemoteException()).when(mApInterface).stopHostapd(); 1043 1044 assertFalse(mWificondControl.stopHostapd(TEST_INTERFACE_NAME)); 1045 verify(mApInterface).stopHostapd(); 1046 } 1047 1048 /** 1049 * Verifies registration and invocation of wificond death handler. 1050 */ 1051 @Test 1052 public void testRegisterDeathHandler() throws Exception { 1053 WifiNative.WificondDeathEventHandler handler = 1054 mock(WifiNative.WificondDeathEventHandler.class); 1055 assertTrue(mWificondControl.initialize(handler)); 1056 verify(mWificond).tearDownInterfaces(); 1057 mWificondControl.binderDied(); 1058 verify(handler).onDeath(); 1059 } 1060 1061 /** 1062 * Verifies handling of wificond death and ensures that all internal state is cleared and 1063 * handlers are invoked. 1064 */ 1065 @Test 1066 public void testDeathHandling() throws Exception { 1067 WifiNative.WificondDeathEventHandler handler = 1068 mock(WifiNative.WificondDeathEventHandler.class); 1069 assertTrue(mWificondControl.initialize(handler)); 1070 1071 testSetupInterfaceForClientMode(); 1072 1073 mWificondControl.binderDied(); 1074 verify(handler).onDeath(); 1075 1076 // The handles should be cleared after death, so these should retrieve new handles. 1077 when(mWificond.enableSupplicant()).thenReturn(true); 1078 assertTrue(mWificondControl.enableSupplicant()); 1079 verify(mWifiInjector, times(2)).makeWificond(); 1080 verify(mWificond).enableSupplicant(); 1081 } 1082 1083 /** 1084 * Verifies setMacAddress() success. 1085 */ 1086 @Test 1087 public void testSetMacAddressSuccess() throws Exception { 1088 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 1089 assertTrue(mWificondControl.setMacAddress(TEST_INTERFACE_NAME, TEST_MAC_ADDRESS)); 1090 verify(mClientInterface).setMacAddress(macByteArray); 1091 } 1092 1093 /** 1094 * Verifies setMacAddress() can handle failure. 1095 */ 1096 @Test 1097 public void testSetMacAddressFailDueToExceptionInInterface() throws Exception { 1098 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 1099 doThrow(new RemoteException()).when(mClientInterface).setMacAddress(macByteArray); 1100 assertFalse(mWificondControl.setMacAddress(TEST_INTERFACE_NAME, TEST_MAC_ADDRESS)); 1101 verify(mClientInterface).setMacAddress(macByteArray); 1102 } 1103 1104 private void assertRadioChainInfosEqual( 1105 List<RadioChainInfo> expected, android.net.wifi.ScanResult.RadioChainInfo[] actual) { 1106 assertEquals(expected.size(), actual.length); 1107 for (int i = 0; i < actual.length; i++) { 1108 RadioChainInfo nativeRadioChainInfo = 1109 new RadioChainInfo(actual[i].id, actual[i].level); 1110 assertTrue(expected.contains(nativeRadioChainInfo)); 1111 } 1112 } 1113 1114 // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it 1115 // matches the provided frequency set and ssid set. 1116 private class ScanMatcher implements ArgumentMatcher<SingleScanSettings> { 1117 int mExpectedScanType; 1118 private final Set<Integer> mExpectedFreqs; 1119 private final Set<String> mExpectedSsids; 1120 ScanMatcher(int expectedScanType, Set<Integer> expectedFreqs, Set<String> expectedSsids) { 1121 this.mExpectedScanType = expectedScanType; 1122 this.mExpectedFreqs = expectedFreqs; 1123 this.mExpectedSsids = expectedSsids; 1124 } 1125 1126 @Override 1127 public boolean matches(SingleScanSettings settings) { 1128 if (settings.scanType != mExpectedScanType) { 1129 return false; 1130 } 1131 ArrayList<ChannelSettings> channelSettings = settings.channelSettings; 1132 ArrayList<HiddenNetwork> hiddenNetworks = settings.hiddenNetworks; 1133 if (mExpectedFreqs != null) { 1134 Set<Integer> freqSet = new HashSet<Integer>(); 1135 for (ChannelSettings channel : channelSettings) { 1136 freqSet.add(channel.frequency); 1137 } 1138 if (!mExpectedFreqs.equals(freqSet)) { 1139 return false; 1140 } 1141 } else { 1142 if (channelSettings != null && channelSettings.size() > 0) { 1143 return false; 1144 } 1145 } 1146 1147 if (mExpectedSsids != null) { 1148 Set<String> ssidSet = new HashSet<String>(); 1149 for (HiddenNetwork network : hiddenNetworks) { 1150 ssidSet.add(NativeUtil.encodeSsid( 1151 NativeUtil.byteArrayToArrayList(network.ssid))); 1152 } 1153 if (!mExpectedSsids.equals(ssidSet)) { 1154 return false; 1155 } 1156 1157 } else { 1158 if (hiddenNetworks != null && hiddenNetworks.size() > 0) { 1159 return false; 1160 } 1161 } 1162 return true; 1163 } 1164 1165 @Override 1166 public String toString() { 1167 return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs 1168 + ", mExpectedSsids=" + mExpectedSsids + '}'; 1169 } 1170 } 1171 1172 // Create a ArgumentMatcher which captures a PnoSettings parameter and checks if it 1173 // matches the WifiNative.PnoSettings; 1174 private class PnoScanMatcher implements ArgumentMatcher<PnoSettings> { 1175 private final WifiNative.PnoSettings mExpectedPnoSettings; 1176 PnoScanMatcher(WifiNative.PnoSettings expectedPnoSettings) { 1177 this.mExpectedPnoSettings = expectedPnoSettings; 1178 } 1179 @Override 1180 public boolean matches(PnoSettings settings) { 1181 if (mExpectedPnoSettings == null) { 1182 return false; 1183 } 1184 if (settings.intervalMs != mExpectedPnoSettings.periodInMs 1185 || settings.min2gRssi != mExpectedPnoSettings.min24GHzRssi 1186 || settings.min5gRssi != mExpectedPnoSettings.min5GHzRssi) { 1187 return false; 1188 } 1189 if (settings.pnoNetworks == null || mExpectedPnoSettings.networkList == null) { 1190 return false; 1191 } 1192 if (settings.pnoNetworks.size() != mExpectedPnoSettings.networkList.length) { 1193 return false; 1194 } 1195 1196 for (int i = 0; i < settings.pnoNetworks.size(); i++) { 1197 if (!mExpectedPnoSettings.networkList[i].ssid.equals(NativeUtil.encodeSsid( 1198 NativeUtil.byteArrayToArrayList(settings.pnoNetworks.get(i).ssid)))) { 1199 return false; 1200 } 1201 boolean isNetworkHidden = (mExpectedPnoSettings.networkList[i].flags 1202 & WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0; 1203 if (isNetworkHidden != settings.pnoNetworks.get(i).isHidden) { 1204 return false; 1205 } 1206 1207 } 1208 return true; 1209 } 1210 1211 @Override 1212 public String toString() { 1213 return "PnoScanMatcher{" + "mExpectedPnoSettings=" + mExpectedPnoSettings + '}'; 1214 } 1215 } 1216 } 1217