1 /* 2 * Copyright (C) 2016 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 android.net.wifi; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertThrows; 24 import static org.junit.Assert.assertTrue; 25 import static org.junit.Assert.fail; 26 import static org.junit.Assume.assumeTrue; 27 import static org.mockito.ArgumentMatchers.any; 28 import static org.mockito.ArgumentMatchers.eq; 29 import static org.mockito.Mockito.doAnswer; 30 import static org.mockito.Mockito.mock; 31 import static org.mockito.Mockito.never; 32 import static org.mockito.Mockito.spy; 33 import static org.mockito.Mockito.times; 34 import static org.mockito.Mockito.validateMockitoUsage; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.when; 37 38 import android.app.test.MockAnswerUtil; 39 import android.content.Context; 40 import android.net.wifi.WifiScanner.PnoSettings; 41 import android.net.wifi.WifiScanner.PnoSettings.PnoNetwork; 42 import android.net.wifi.WifiScanner.ScanData; 43 import android.net.wifi.WifiScanner.ScanListener; 44 import android.net.wifi.WifiScanner.ScanSettings; 45 import android.os.Handler; 46 import android.os.Parcel; 47 import android.os.WorkSource; 48 import android.os.test.TestLooper; 49 50 import androidx.test.filters.SmallTest; 51 52 import com.android.modules.utils.build.SdkLevel; 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.Mock; 59 import org.mockito.MockitoAnnotations; 60 import org.mockito.Spy; 61 62 import java.util.ArrayList; 63 import java.util.Arrays; 64 import java.util.List; 65 import java.util.concurrent.Executor; 66 67 /** 68 * Unit tests for {@link android.net.wifi.WifiScanner}. 69 */ 70 @SmallTest 71 public class WifiScannerTest { 72 @Mock 73 private Context mContext; 74 @Mock 75 private IWifiScanner mService; 76 @Spy 77 private Executor mExecutor = new SynchronousExecutor(); 78 @Mock 79 private ScanListener mScanListener; 80 @Mock 81 private WifiScanner.ParcelableScanData mParcelableScanData; 82 private ScanData[] mScanData = {}; 83 84 private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false; 85 private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60; 86 private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70; 87 private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55; 88 private static final String TEST_SSID_1 = "TEST1"; 89 private static final String TEST_SSID_2 = "TEST2"; 90 private static final int[] TEST_FREQUENCIES_1 = {}; 91 private static final int[] TEST_FREQUENCIES_2 = {2500, 5124, 6245}; 92 private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized"; 93 private static final String TEST_PACKAGE_NAME = "com.test.123"; 94 private static final String TEST_FEATURE_ID = "test.feature"; 95 96 private WifiScanner mWifiScanner; 97 private TestLooper mLooper; 98 private Handler mHandler; 99 100 /** 101 * Setup before tests. 102 */ 103 @Before setUp()104 public void setUp() throws Exception { 105 MockitoAnnotations.initMocks(this); 106 mLooper = new TestLooper(); 107 mHandler = spy(new Handler(mLooper.getLooper())); 108 mWifiScanner = new WifiScanner(mContext, mService, mLooper.getLooper()); 109 mLooper.dispatchAll(); 110 when(mParcelableScanData.getResults()).thenReturn(mScanData); 111 when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); 112 when(mContext.getPackageName()).thenReturn(TEST_PACKAGE_NAME); 113 when(mContext.getAttributionTag()).thenReturn(TEST_FEATURE_ID); 114 } 115 116 /** 117 * Clean up after tests. 118 */ 119 @After cleanup()120 public void cleanup() { 121 validateMockitoUsage(); 122 } 123 124 /** 125 * Verify parcel read/write for ScanSettings. 126 */ 127 @Test verifyScanSettingsParcelWithBand()128 public void verifyScanSettingsParcelWithBand() throws Exception { 129 ScanSettings writeSettings = new ScanSettings(); 130 writeSettings.type = WifiScanner.SCAN_TYPE_LOW_POWER; 131 writeSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; 132 133 ScanSettings readSettings = parcelWriteRead(writeSettings); 134 assertEquals(readSettings.type, writeSettings.type); 135 assertEquals(readSettings.band, writeSettings.band); 136 assertEquals(0, readSettings.channels.length); 137 } 138 139 /** 140 * Verify parcel read/write for ScanSettings. 141 */ 142 @Test verifyScanSettingsParcelWithChannels()143 public void verifyScanSettingsParcelWithChannels() throws Exception { 144 ScanSettings writeSettings = new ScanSettings(); 145 writeSettings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY; 146 writeSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 147 writeSettings.channels = new WifiScanner.ChannelSpec[] { 148 new WifiScanner.ChannelSpec(5), 149 new WifiScanner.ChannelSpec(7) 150 }; 151 152 ScanSettings readSettings = parcelWriteRead(writeSettings); 153 assertEquals(writeSettings.type, readSettings.type); 154 assertEquals(writeSettings.band, readSettings.band); 155 assertEquals(2, readSettings.channels.length); 156 assertEquals(5, readSettings.channels[0].frequency); 157 assertEquals(7, readSettings.channels[1].frequency); 158 } 159 160 /** 161 * Write the provided {@link ScanSettings} to a parcel and deserialize it. 162 */ parcelWriteRead(ScanSettings writeSettings)163 private static ScanSettings parcelWriteRead(ScanSettings writeSettings) throws Exception { 164 Parcel parcel = Parcel.obtain(); 165 writeSettings.writeToParcel(parcel, 0); 166 parcel.setDataPosition(0); // Rewind data position back to the beginning for read. 167 return ScanSettings.CREATOR.createFromParcel(parcel); 168 } 169 170 /** 171 * PnoSettings object can be serialized and deserialized, while keeping the 172 * values unchanged. 173 */ 174 @Test canSerializeAndDeserializePnoSettings()175 public void canSerializeAndDeserializePnoSettings() throws Exception { 176 177 PnoSettings pnoSettings = new PnoSettings(); 178 179 PnoNetwork pnoNetwork1 = new PnoNetwork(TEST_SSID_1); 180 PnoNetwork pnoNetwork2 = new PnoNetwork(TEST_SSID_2); 181 pnoNetwork1.frequencies = TEST_FREQUENCIES_1; 182 pnoNetwork2.frequencies = TEST_FREQUENCIES_2; 183 184 pnoSettings.networkList = new PnoNetwork[]{pnoNetwork1, pnoNetwork2}; 185 pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED; 186 pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI; 187 pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI; 188 pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI; 189 190 Parcel parcel = Parcel.obtain(); 191 pnoSettings.writeToParcel(parcel, 0); 192 // Rewind the pointer to the head of the parcel. 193 parcel.setDataPosition(0); 194 PnoSettings pnoSettingsDeserialized = 195 pnoSettings.CREATOR.createFromParcel(parcel); 196 197 assertNotNull(pnoSettingsDeserialized); 198 assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected); 199 assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi); 200 assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi); 201 assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi); 202 203 // Test parsing of PnoNetwork 204 assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length); 205 for (int i = 0; i < pnoSettings.networkList.length; i++) { 206 PnoNetwork expected = pnoSettings.networkList[i]; 207 PnoNetwork actual = pnoSettingsDeserialized.networkList[i]; 208 assertEquals(expected.ssid, actual.ssid); 209 assertEquals(expected.flags, actual.flags); 210 assertEquals(expected.authBitField, actual.authBitField); 211 assertTrue(Arrays.equals(expected.frequencies, actual.frequencies)); 212 } 213 } 214 215 /** 216 * Make sure that frequencies is not null by default. 217 */ 218 @Test pnoNetworkFrequencyIsNotNull()219 public void pnoNetworkFrequencyIsNotNull() throws Exception { 220 PnoNetwork pnoNetwork = new PnoNetwork(TEST_SSID_1); 221 assertNotNull(pnoNetwork.frequencies); 222 } 223 224 /** 225 * Verify parcel read/write for ScanData. 226 */ 227 @Test verifyScanDataParcel()228 public void verifyScanDataParcel() throws Exception { 229 ScanData writeScanData = new ScanData(2, 0, 3, 230 WifiScanner.WIFI_BAND_BOTH_WITH_DFS, new ScanResult[0]); 231 232 ScanData readScanData = parcelWriteRead(writeScanData); 233 assertEquals(writeScanData.getId(), readScanData.getId()); 234 assertEquals(writeScanData.getFlags(), readScanData.getFlags()); 235 assertEquals(writeScanData.getBucketsScanned(), readScanData.getBucketsScanned()); 236 assertEquals(writeScanData.getScannedBandsInternal(), 237 readScanData.getScannedBandsInternal()); 238 assertArrayEquals(writeScanData.getResults(), readScanData.getResults()); 239 } 240 241 /** 242 * Write the provided {@link ScanData} to a parcel and deserialize it. 243 */ parcelWriteRead(ScanData writeScanData)244 private static ScanData parcelWriteRead(ScanData writeScanData) throws Exception { 245 Parcel parcel = Parcel.obtain(); 246 writeScanData.writeToParcel(parcel, 0); 247 parcel.setDataPosition(0); // Rewind data position back to the beginning for read. 248 return ScanData.CREATOR.createFromParcel(parcel); 249 } 250 251 /** 252 * Verify #setRnrSetting with valid and invalid inputs. 253 */ 254 @Test testSetRnrSetting()255 public void testSetRnrSetting() throws Exception { 256 // First verify IllegalArgumentException if an invalid input is passed in. 257 assumeTrue(SdkLevel.isAtLeastS()); 258 try { 259 WifiScanner.ScanSettings scanSettings = new WifiScanner.ScanSettings(); 260 scanSettings.setRnrSetting(-1); 261 fail("Excepted IllegalArgumentException"); 262 } catch (IllegalArgumentException e) { 263 } 264 265 // Then verify calling the API with a valid input. 266 WifiScanner.ScanSettings scanSettings = new WifiScanner.ScanSettings(); 267 scanSettings.setRnrSetting(WifiScanner.WIFI_RNR_NOT_NEEDED); 268 assertEquals(WifiScanner.WIFI_RNR_NOT_NEEDED, scanSettings.getRnrSetting()); 269 } 270 271 @Test testIsScanning()272 public void testIsScanning() throws Exception { 273 mWifiScanner.isScanning(); 274 verify(mService).isScanning(); 275 } 276 277 /** 278 * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} 279 * @throws Exception 280 */ 281 @Test testStartScan()282 public void testStartScan() throws Exception { 283 ScanSettings scanSettings = new ScanSettings(); 284 ScanListener scanListener = mock(ScanListener.class); 285 286 mWifiScanner.startScan(scanSettings, scanListener); 287 mLooper.dispatchAll(); 288 289 verify(mService).startScan(any(), eq(scanSettings), 290 any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 291 } 292 293 /** 294 * Test behavior of {@link WifiScanner#getSingleScanResults()}. 295 */ 296 @Test testGetSingleScanResults()297 public void testGetSingleScanResults() throws Exception { 298 ScanResult scanResult = new ScanResult(); 299 scanResult.SSID = TEST_SSID_1; 300 ScanResult[] scanResults = {scanResult}; 301 302 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 303 public List<ScanResult> answer(String packageName, String featureId) { 304 return new ArrayList<>(Arrays.asList(scanResults)); 305 } 306 }).when(mService).getSingleScanResults(any(), any()); 307 308 List<ScanResult> results = mWifiScanner.getSingleScanResults(); 309 assertEquals(1, results.size()); 310 assertEquals(TEST_SSID_1, results.get(0).SSID); 311 } 312 313 /** 314 * Test behavior of {@link WifiScanner#getSingleScanResults()} with an incorrect response from 315 * the server. 316 */ 317 @Test testGetSingleScanResultsIncorrectResponse()318 public void testGetSingleScanResultsIncorrectResponse() throws Exception { 319 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 320 public List<ScanResult> answer(String packageName, String featureId) { 321 return new ArrayList<>(); 322 } 323 }).when(mService).getSingleScanResults(any(), any()); 324 List<ScanResult> results = mWifiScanner.getSingleScanResults(); 325 verify(mService).getSingleScanResults(eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 326 assertEquals(0, results.size()); 327 } 328 329 /** 330 * Test behavior of {@link WifiScanner#stopScan(ScanListener)} 331 * @throws Exception 332 */ 333 @Test testStopScan()334 public void testStopScan() throws Exception { 335 ScanSettings scanSettings = new ScanSettings(); 336 ScanListener scanListener = mock(ScanListener.class); 337 338 mWifiScanner.startScan(scanSettings, scanListener); 339 mLooper.dispatchAll(); 340 341 mWifiScanner.stopScan(scanListener); 342 mLooper.dispatchAll(); 343 344 verify(mService, times(1)).startScan(any(), 345 eq(scanSettings), any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 346 verify(mService, times(1)).stopScan(any(), 347 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 348 } 349 350 /** 351 * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} 352 * @throws Exception 353 */ 354 @Test testStartScanListenerOnSuccess()355 public void testStartScanListenerOnSuccess() throws Exception { 356 ScanSettings scanSettings = new ScanSettings(); 357 ScanListener scanListener = mock(ScanListener.class); 358 359 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 360 public void answer(IWifiScannerListener listener, WifiScanner.ScanSettings settings, 361 WorkSource workSource, String packageName, String featureId) throws Exception { 362 listener.onSuccess(); 363 } 364 }).when(mService).startScan(any(), any(), any(), any(), any()); 365 mWifiScanner.startScan(scanSettings, scanListener); 366 mLooper.dispatchAll(); 367 368 verify(mService, times(1)).startScan(any(), 369 eq(scanSettings), any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 370 verify(scanListener).onSuccess(); 371 } 372 373 /** 374 * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} 375 * @throws Exception 376 */ 377 @Test testStartScanListenerOnResults()378 public void testStartScanListenerOnResults() throws Exception { 379 ScanSettings scanSettings = new ScanSettings(); 380 ScanListener scanListener = mock(ScanListener.class); 381 ScanResult scanResult = new ScanResult(); 382 ScanData[] scanDatas = new ScanData[]{ 383 new ScanData(0, 0, new ScanResult[]{scanResult})}; 384 385 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 386 public void answer(IWifiScannerListener listener, WifiScanner.ScanSettings settings, 387 WorkSource workSource, String packageName, String featureId) throws Exception { 388 listener.onSuccess(); 389 listener.onResults(scanDatas); 390 } 391 }).when(mService).startScan(any(), any(), any(), any(), any()); 392 mWifiScanner.startScan(scanSettings, scanListener); 393 mLooper.dispatchAll(); 394 verify(mService).startScan(any(), eq(scanSettings), 395 any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 396 mLooper.dispatchAll(); 397 verify(scanListener).onResults(eq(scanDatas)); 398 } 399 400 /** 401 * Test behavior of {@link WifiScanner#startDisconnectedPnoScan(ScanSettings, PnoSettings, 402 * Executor, WifiScanner.PnoScanListener)} 403 * @throws Exception 404 */ 405 @Test testStartDisconnectedPnoScan()406 public void testStartDisconnectedPnoScan() throws Exception { 407 ScanSettings scanSettings = new ScanSettings(); 408 PnoSettings pnoSettings = new PnoSettings(); 409 WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); 410 411 mWifiScanner.startDisconnectedPnoScan( 412 scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); 413 mLooper.dispatchAll(); 414 verify(mService).startPnoScan(any(), 415 eq(scanSettings), eq(pnoSettings), 416 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 417 } 418 419 /** 420 * Test behavior of {@link WifiScanner#startConnectedPnoScan(ScanSettings, PnoSettings, 421 * Executor, WifiScanner.PnoScanListener)} 422 * @throws Exception 423 */ 424 @Test testStartConnectedPnoScan()425 public void testStartConnectedPnoScan() throws Exception { 426 ScanSettings scanSettings = new ScanSettings(); 427 PnoSettings pnoSettings = new PnoSettings(); 428 WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); 429 430 mWifiScanner.startConnectedPnoScan( 431 scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); 432 verify(mService).startPnoScan(any(), eq(scanSettings), eq(pnoSettings), any(), any()); 433 assertTrue(scanSettings.isPnoScan); 434 assertTrue(pnoSettings.isConnected); 435 } 436 437 /** 438 * Test behavior of {@link WifiScanner#stopPnoScan(ScanListener)} 439 * Executor, WifiScanner.PnoScanListener)} 440 * @throws Exception 441 */ 442 @Test testStopPnoScan()443 public void testStopPnoScan() throws Exception { 444 ScanSettings scanSettings = new ScanSettings(); 445 PnoSettings pnoSettings = new PnoSettings(); 446 WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); 447 448 mWifiScanner.startDisconnectedPnoScan( 449 scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); 450 mWifiScanner.stopPnoScan(pnoScanListener); 451 452 verify(mService, times(1)).stopPnoScan(any(), 453 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 454 } 455 456 @Test testScanDataAddResults()457 public void testScanDataAddResults() throws Exception { 458 ScanResult scanResult1 = new ScanResult(); 459 scanResult1.SSID = TEST_SSID_1; 460 ScanData scanData = new ScanData(0, 0, new ScanResult[]{scanResult1}); 461 462 ScanResult scanResult2 = new ScanResult(); 463 scanResult2.SSID = TEST_SSID_2; 464 scanData.addResults(new ScanResult[]{scanResult2}); 465 466 ScanResult[] consolidatedScanResults = scanData.getResults(); 467 assertEquals(2, consolidatedScanResults.length); 468 assertEquals(TEST_SSID_1, consolidatedScanResults[0].SSID); 469 assertEquals(TEST_SSID_2, consolidatedScanResults[1].SSID); 470 } 471 472 @Test testScanDataParcel()473 public void testScanDataParcel() throws Exception { 474 ScanResult scanResult1 = new ScanResult(); 475 scanResult1.SSID = TEST_SSID_1; 476 ScanData scanData = new ScanData(5, 4, new ScanResult[]{scanResult1}); 477 478 Parcel parcel = Parcel.obtain(); 479 scanData.writeToParcel(parcel, 0); 480 parcel.setDataPosition(0); // Rewind data position back to the beginning for read. 481 ScanData readScanData = ScanData.CREATOR.createFromParcel(parcel); 482 483 assertEquals(scanData.getId(), readScanData.getId()); 484 assertEquals(scanData.getFlags(), readScanData.getFlags()); 485 assertEquals(scanData.getResults().length, readScanData.getResults().length); 486 assertEquals(scanData.getResults()[0].SSID, readScanData.getResults()[0].SSID); 487 } 488 489 /** Tests that upon registration success, {@link ScanListener#onSuccess()} is called. */ 490 @Test testRegisterScanListenerSuccess()491 public void testRegisterScanListenerSuccess() throws Exception { 492 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 493 public void answer(IWifiScannerListener listener, String packageName, String featureId) 494 throws Exception { 495 listener.onSuccess(); 496 } 497 }).when(mService).registerScanListener(any(), any(), any()); 498 mWifiScanner.registerScanListener(mExecutor, mScanListener); 499 mLooper.dispatchAll(); 500 verify(mService).registerScanListener(any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 501 verify(mScanListener).onSuccess(); 502 } 503 504 /** 505 * Tests that upon registration failed, {@link ScanListener#onFailure(int, String)} is called. 506 */ 507 @Test testRegisterScanListenerFailed()508 public void testRegisterScanListenerFailed() throws Exception { 509 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 510 public void answer(IWifiScannerListener listener, String packageName, String featureId) 511 throws Exception { 512 listener.onFailure(WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED); 513 } 514 }).when(mService).registerScanListener(any(), any(), any()); 515 mWifiScanner.registerScanListener(mExecutor, mScanListener); 516 mLooper.dispatchAll(); 517 verify(mService).registerScanListener(any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 518 verify(mScanListener).onFailure(WifiScanner.REASON_NOT_AUTHORIZED, 519 DESCRIPTION_NOT_AUTHORIZED); 520 } 521 522 /** 523 * Tests that when the ScanListener is triggered, {@link ScanListener#onResults(ScanData[])} 524 * is called. 525 */ 526 @Test testRegisterScanListenerReceiveScanResults()527 public void testRegisterScanListenerReceiveScanResults() throws Exception { 528 ArgumentCaptor<IWifiScannerListener> listenerArgumentCaptor = ArgumentCaptor.forClass( 529 IWifiScannerListener.class); 530 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 531 public void answer(IWifiScannerListener listener, String packageName, String featureId) 532 throws Exception { 533 listener.onSuccess(); 534 } 535 }).when(mService).registerScanListener(any(), any(), any()); 536 mWifiScanner.registerScanListener(mExecutor, mScanListener); 537 verify(mService).registerScanListener(listenerArgumentCaptor.capture(), 538 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 539 verify(mExecutor, times(1)).execute(any()); 540 verify(mScanListener).onSuccess(); 541 542 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 543 public void answer(IWifiScannerListener listener, WifiScanner.ScanSettings settings, 544 WorkSource workSource, String packageName, String featureId) throws Exception { 545 listener.onResults(mScanData); 546 listenerArgumentCaptor.getValue().onResults(mScanData); 547 } 548 }).when(mService).startScan(any(), any(), any(), any(), any()); 549 ScanSettings scanSettings = new ScanSettings(); 550 mWifiScanner.startScan(scanSettings, mock(ScanListener.class)); 551 verify(mExecutor, times(2)).execute(any()); 552 verify(mScanListener).onResults(mScanData); 553 } 554 555 /** 556 * Tests that after unregistering a scan listener, {@link ScanListener#onResults(ScanData[])} 557 * is not called. 558 */ 559 @Test testUnregisterScanListener()560 public void testUnregisterScanListener() throws Exception { 561 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 562 public void answer(IWifiScannerListener listener, String packageName, String featureId) 563 throws Exception { 564 listener.onSuccess(); 565 } 566 }).when(mService).unregisterScanListener(any(), any(), any()); 567 568 mWifiScanner.registerScanListener(mExecutor, mScanListener); 569 mWifiScanner.unregisterScanListener(mScanListener); 570 verify(mService).registerScanListener(any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 571 verify(mService).unregisterScanListener(any(), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID)); 572 verify(mScanListener).onSuccess(); 573 verify(mScanListener, never()).onResults(mScanData); 574 } 575 576 /** 577 * Tests isFullBandScan() method with and without DFS check 578 */ 579 @Test testIsFullBandScan()580 public void testIsFullBandScan() throws Exception { 581 assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_24_GHZ, true)); 582 assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_5_GHZ, true)); 583 assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_6_GHZ, true)); 584 assertFalse(WifiScanner.isFullBandScan( 585 WifiScanner.WIFI_BAND_6_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true)); 586 assertTrue(WifiScanner.isFullBandScan( 587 WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true)); 588 assertFalse(WifiScanner.isFullBandScan( 589 WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, false)); 590 assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, true)); 591 assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, false)); 592 } 593 594 /** 595 * Tests creating WifiScanner in multi threads, with async channel disconnects. 596 */ 597 @Test testWifiScannerConcurrentServiceStart()598 public void testWifiScannerConcurrentServiceStart() { 599 WifiScanner wifiScanner = new WifiScanner( 600 mContext, mService, WifiFrameworkInitializer.getInstanceLooper()); 601 602 Thread thread1 = new Thread(() -> { 603 try { 604 WifiScanner wifiScanner1 = new WifiScanner( 605 mContext, mService, WifiFrameworkInitializer.getInstanceLooper()); 606 } catch (NullPointerException e) { 607 fail("WifiScanner can't be initialized! " + e); 608 } 609 }); 610 611 thread1.start(); 612 try { 613 thread1.join(); 614 } catch (InterruptedException e) { 615 fail("WifiScanner can't be initialized!" + e); 616 } 617 } 618 619 /** 620 * Verify #setVendorIes with valid and invalid inputs 621 */ 622 @Test testSetVendorIes()623 public void testSetVendorIes() throws Exception { 624 assumeTrue(SdkLevel.isAtLeastU()); 625 WifiScanner.ScanSettings scanSettings = new WifiScanner.ScanSettings(); 626 List<ScanResult.InformationElement> vendorIesList = new ArrayList<>(); 627 ScanResult.InformationElement vendorIe1 = new ScanResult.InformationElement(221, 0, 628 new byte[]{0x00, 0x50, (byte) 0xf2, 0x08, 0x11, 0x22, 0x33}); 629 ScanResult.InformationElement vendorIe2 = new ScanResult.InformationElement(255, 0, 630 new byte[]{0x00, 0x50, (byte) 0xf2, 0x08, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc}); 631 ScanResult.InformationElement vendorIe3 = new ScanResult.InformationElement(221, 0, 632 new byte[0]); 633 vendorIe3.bytes = null; 634 ScanResult.InformationElement vendorIe4 = new ScanResult.InformationElement(221, 0, 635 new byte[256]); 636 ScanResult.InformationElement vendorIe5 = new ScanResult.InformationElement(221, 0, 637 new byte[256]); 638 639 vendorIesList.add(vendorIe2); 640 assertThrows(IllegalArgumentException.class, 641 () -> scanSettings.setVendorIes(vendorIesList)); 642 643 vendorIesList.remove(vendorIe2); 644 vendorIesList.add(vendorIe3); 645 assertThrows(IllegalArgumentException.class, 646 () -> scanSettings.setVendorIes(vendorIesList)); 647 648 vendorIesList.remove(vendorIe3); 649 vendorIesList.add(vendorIe4); 650 assertThrows(IllegalArgumentException.class, 651 () -> scanSettings.setVendorIes(vendorIesList)); 652 653 vendorIesList.add(vendorIe5); 654 assertThrows(IllegalArgumentException.class, 655 () -> scanSettings.setVendorIes(vendorIesList)); 656 657 vendorIesList.remove(vendorIe4); 658 vendorIesList.remove(vendorIe5); 659 vendorIesList.add(vendorIe1); 660 scanSettings.setVendorIes(vendorIesList); 661 assertEquals(vendorIesList, scanSettings.getVendorIes()); 662 } 663 } 664