BaseWifiScannerImplTest.java revision 00b3049b477728d3fb2424b9ffaac67b19dea348
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi.scanner; 18 19import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder; 20import static com.android.server.wifi.ScanTestUtil.assertScanDataEquals; 21import static com.android.server.wifi.ScanTestUtil.createFreqSet; 22 23import static org.junit.Assert.*; 24import static org.mockito.Mockito.*; 25 26import android.app.test.TestAlarmManager; 27import android.content.Context; 28import android.net.wifi.ScanResult; 29import android.net.wifi.WifiScanner; 30import android.net.wifi.WifiScanner.ScanData; 31import android.net.wifi.WifiSsid; 32import android.os.SystemClock; 33import android.os.test.TestLooper; 34 35import com.android.server.wifi.Clock; 36import com.android.server.wifi.MockResources; 37import com.android.server.wifi.MockWifiMonitor; 38import com.android.server.wifi.ScanDetail; 39import com.android.server.wifi.ScanResults; 40import com.android.server.wifi.WifiMonitor; 41import com.android.server.wifi.WifiNative; 42import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection; 43 44import org.junit.Before; 45import org.junit.Test; 46import org.mockito.InOrder; 47import org.mockito.Mock; 48import org.mockito.MockitoAnnotations; 49 50import java.util.ArrayList; 51import java.util.Arrays; 52import java.util.Collections; 53import java.util.HashSet; 54import java.util.Set; 55 56/** 57 * Base unit tests that should pass for all implementations of 58 * {@link com.android.server.wifi.scanner.WifiScannerImpl}. 59 */ 60public abstract class BaseWifiScannerImplTest { 61 @Mock Context mContext; 62 TestAlarmManager mAlarmManager; 63 MockWifiMonitor mWifiMonitor; 64 TestLooper mLooper; 65 @Mock WifiNative mWifiNative; 66 MockResources mResources; 67 @Mock Clock mClock; 68 69 /** 70 * mScanner implementation should be filled in by derived test class 71 */ 72 WifiScannerImpl mScanner; 73 74 @Before 75 public void setUpBase() throws Exception { 76 MockitoAnnotations.initMocks(this); 77 78 mLooper = new TestLooper(); 79 mAlarmManager = new TestAlarmManager(); 80 mWifiMonitor = new MockWifiMonitor(); 81 mResources = new MockResources(); 82 83 when(mWifiNative.getInterfaceName()).thenReturn("a_test_interface_name"); 84 85 when(mContext.getSystemService(Context.ALARM_SERVICE)) 86 .thenReturn(mAlarmManager.getAlarmManager()); 87 88 when(mContext.getResources()).thenReturn(mResources); 89 when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()); 90 } 91 92 protected boolean isAllChannelsScanned(int band) { 93 ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection(); 94 collection.addBand(band); 95 return collection.isAllChannels(); 96 } 97 98 protected Set<Integer> expectedBandScanFreqs(int band) { 99 ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection(); 100 collection.addBand(band); 101 return collection.getSupplicantScanFreqs(); 102 } 103 104 protected Set<Integer> expectedBandAndChannelScanFreqs(int band, int... channels) { 105 ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection(); 106 collection.addBand(band); 107 for (int channel : channels) { 108 collection.addChannel(channel); 109 } 110 return collection.getSupplicantScanFreqs(); 111 } 112 113 @Test 114 public void singleScanSuccess() { 115 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 116 .withBasePeriod(10000) // ms 117 .withMaxApPerScan(10) 118 .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 119 WifiScanner.WIFI_BAND_24_GHZ) 120 .build(); 121 122 doSuccessfulSingleScanTest(settings, expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ), 123 new HashSet<Integer>(), 124 ScanResults.create(0, isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ), 125 2400, 2450, 2450, 2400, 2450, 2450, 2400, 2450, 2450), false); 126 } 127 128 @Test 129 public void singleScanSuccessWithChannels() { 130 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 131 .withBasePeriod(10000) 132 .withMaxApPerScan(10) 133 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650) 134 .build(); 135 136 doSuccessfulSingleScanTest(settings, createFreqSet(5650), 137 new HashSet<Integer>(), 138 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false); 139 } 140 141 @Test 142 public void singleScanSuccessWithFullResults() { 143 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 144 .withBasePeriod(10000) 145 .withMaxApPerScan(10) 146 .addBucketWithBand(10000, 147 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 148 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 149 WifiScanner.WIFI_BAND_24_GHZ) 150 .build(); 151 152 doSuccessfulSingleScanTest(settings, expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ), 153 new HashSet<Integer>(), 154 ScanResults.create(0, isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ), 155 2400, 2450, 2450, 2400, 2450, 2450, 2400, 2450, 2450), true); 156 } 157 158 /** 159 * Tests whether the provided hidden networkId's in scan settings is correctly passed along 160 * when invoking native scan. 161 */ 162 @Test 163 public void singleScanSuccessWithHiddenNetworkIds() { 164 int[] hiddenNetworkIds = {0, 5}; 165 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 166 .withBasePeriod(10000) 167 .withMaxApPerScan(10) 168 .withHiddenNetworkIds(hiddenNetworkIds) 169 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650) 170 .build(); 171 172 Set<Integer> hiddenNetworkIdSet = new HashSet<Integer>(); 173 for (int i = 0; i < hiddenNetworkIds.length; i++) { 174 hiddenNetworkIdSet.add(hiddenNetworkIds[i]); 175 } 176 doSuccessfulSingleScanTest(settings, createFreqSet(5650), 177 hiddenNetworkIdSet, 178 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false); 179 } 180 181 /** 182 * Tests whether the provided hidden networkId's in scan settings is truncated to max size 183 * supported by wpa_supplicant when invoking native scan. 184 */ 185 @Test 186 public void singleScanSuccessWithTruncatedHiddenNetworkIds() { 187 int[] hiddenNetworkIds = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; 188 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 189 .withBasePeriod(10000) 190 .withMaxApPerScan(10) 191 .withHiddenNetworkIds(hiddenNetworkIds) 192 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650) 193 .build(); 194 195 Set<Integer> hiddenNetworkIdSet = new HashSet<Integer>(); 196 for (int i = 0; i < SupplicantWifiScannerImpl.MAX_HIDDEN_NETWORK_IDS_PER_SCAN; i++) { 197 hiddenNetworkIdSet.add(hiddenNetworkIds[i]); 198 } 199 doSuccessfulSingleScanTest(settings, createFreqSet(5650), 200 hiddenNetworkIdSet, 201 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false); 202 } 203 204 @Test 205 public void overlappingSingleScanFails() { 206 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 207 .withBasePeriod(10000) // ms 208 .withMaxApPerScan(10) 209 .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 210 WifiScanner.WIFI_BAND_24_GHZ) 211 .build(); 212 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 213 214 WifiNative.ScanSettings settings2 = new NativeScanSettingsBuilder() 215 .withBasePeriod(10000) // ms 216 .withMaxApPerScan(10) 217 .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 218 WifiScanner.WIFI_BAND_5_GHZ) 219 .build(); 220 WifiNative.ScanEventHandler eventHandler2 = mock(WifiNative.ScanEventHandler.class); 221 222 // scan start succeeds 223 when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(true); 224 225 assertTrue(mScanner.startSingleScan(settings, eventHandler)); 226 assertFalse("second scan while first scan running should fail immediately", 227 mScanner.startSingleScan(settings2, eventHandler2)); 228 } 229 230 @Test 231 public void singleScanFailOnExecute() { 232 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 233 .withBasePeriod(10000) 234 .withMaxApPerScan(10) 235 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 236 WifiScanner.WIFI_BAND_24_GHZ) 237 .build(); 238 239 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 240 241 ScanResults results = ScanResults.create(0, 2400, 2450, 2450); 242 243 InOrder order = inOrder(eventHandler, mWifiNative); 244 245 // scan fails 246 when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(false); 247 248 // start scan 249 assertTrue(mScanner.startSingleScan(settings, eventHandler)); 250 251 mLooper.dispatchAll(); 252 order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED); 253 254 verifyNoMoreInteractions(eventHandler); 255 } 256 257 /** 258 * Test that a scan failure is reported if a scan times out 259 */ 260 @Test 261 public void singleScanFailOnTimeout() { 262 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 263 .withBasePeriod(10000) 264 .withMaxApPerScan(10) 265 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 266 WifiScanner.WIFI_BAND_24_GHZ) 267 .build(); 268 269 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 270 271 ScanResults results = ScanResults.create(0, 2400, 2450, 2450); 272 273 InOrder order = inOrder(eventHandler, mWifiNative); 274 275 // scan succeeds 276 when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(true); 277 278 // start scan 279 assertTrue(mScanner.startSingleScan(settings, eventHandler)); 280 mLooper.dispatchAll(); 281 282 // Fire timeout 283 mAlarmManager.dispatch(SupplicantWifiScannerImpl.TIMEOUT_ALARM_TAG); 284 mLooper.dispatchAll(); 285 286 order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED); 287 288 verifyNoMoreInteractions(eventHandler); 289 } 290 291 /** 292 * Test that a scan failure is reported if supplicant sends a scan failed event 293 */ 294 @Test 295 public void singleScanFailOnFailedEvent() { 296 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 297 .withBasePeriod(10000) 298 .withMaxApPerScan(10) 299 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 300 WifiScanner.WIFI_BAND_24_GHZ) 301 .build(); 302 303 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 304 305 ScanResults results = ScanResults.create(0, 2400, 2450, 2450); 306 307 InOrder order = inOrder(eventHandler, mWifiNative); 308 309 // scan succeeds 310 when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(true); 311 312 // start scan 313 assertTrue(mScanner.startSingleScan(settings, eventHandler)); 314 mLooper.dispatchAll(); 315 316 // Fire failed event 317 mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_FAILED_EVENT); 318 mLooper.dispatchAll(); 319 320 order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED); 321 322 verifyNoMoreInteractions(eventHandler); 323 } 324 325 @Test 326 public void singleScanNullEventHandler() { 327 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 328 .withBasePeriod(10000) 329 .withMaxApPerScan(10) 330 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 331 WifiScanner.WIFI_BAND_24_GHZ) 332 .build(); 333 assertFalse(mScanner.startSingleScan(settings, null)); 334 } 335 336 @Test 337 public void singleScanNullSettings() { 338 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 339 340 assertFalse(mScanner.startSingleScan(null, eventHandler)); 341 342 verifyNoMoreInteractions(eventHandler); 343 } 344 345 @Test 346 public void multipleSingleScanSuccess() { 347 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 348 .withBasePeriod(10000) 349 .withMaxApPerScan(10) 350 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 351 WifiScanner.WIFI_BAND_24_GHZ) 352 .build(); 353 WifiNative.ScanSettings settings2 = new NativeScanSettingsBuilder() 354 .withBasePeriod(10000) 355 .withMaxApPerScan(10) 356 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 357 WifiScanner.WIFI_BAND_BOTH_WITH_DFS) 358 .build(); 359 360 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 361 InOrder order = inOrder(eventHandler, mWifiNative); 362 363 // scans succeed 364 when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(true); 365 366 // start first scan 367 assertTrue(mScanner.startSingleScan(settings, eventHandler)); 368 369 expectSuccessfulSingleScan(order, eventHandler, 370 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ), 371 new HashSet<Integer>(), 372 ScanResults.create(0, isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ), 373 2400, 2450, 2450), false); 374 375 // start second scan 376 assertTrue(mScanner.startSingleScan(settings2, eventHandler)); 377 378 expectSuccessfulSingleScan(order, eventHandler, 379 expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH_WITH_DFS), 380 new HashSet<Integer>(), 381 ScanResults.create(0, true, 382 5150, 5175), false); 383 384 verifyNoMoreInteractions(eventHandler); 385 } 386 387 /** 388 * Validate that scan results that are returned from supplicant, which are timestamped prior to 389 * the start of the scan, are ignored. 390 */ 391 @Test 392 public void singleScanWhereSupplicantReturnsSomeOldResults() { 393 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 394 .withBasePeriod(10000) 395 .withMaxApPerScan(2) 396 .addBucketWithBand(10000, 397 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 398 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 399 WifiScanner.WIFI_BAND_24_GHZ) 400 .build(); 401 402 long approxScanStartUs = mClock.getElapsedSinceBootMillis() * 1000; 403 ArrayList<ScanDetail> rawResults = new ArrayList<>(Arrays.asList( 404 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 1"), 405 "00:00:00:00:00:00", "", -70, 2450, 406 approxScanStartUs + 2000 * 1000, 0), 407 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 2"), 408 "AA:BB:CC:DD:EE:FF", "", -66, 2400, 409 approxScanStartUs + 2500 * 1000, 0), 410 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 3"), 411 "00:00:00:00:00:00", "", -80, 2450, 412 approxScanStartUs - 2000 * 1000, 0), // old result will be filtered 413 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 4"), 414 "AA:BB:CC:11:22:33", "", -65, 2450, 415 approxScanStartUs + 4000 * 1000, 0))); 416 417 ArrayList<ScanResult> fullResults = new ArrayList<>(); 418 for (ScanDetail detail : rawResults) { 419 if (detail.getScanResult().timestamp > approxScanStartUs) { 420 fullResults.add(detail.getScanResult()); 421 } 422 } 423 ArrayList<ScanResult> scanDataResults = new ArrayList<>(fullResults); 424 Collections.sort(scanDataResults, ScanResults.SCAN_RESULT_RSSI_COMPARATOR); 425 ScanData scanData = new ScanData(0, 0, 0, 426 isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ), 427 scanDataResults.toArray(new ScanResult[scanDataResults.size()])); 428 Set<Integer> expectedScan = expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ); 429 430 // Actual test 431 432 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 433 434 InOrder order = inOrder(eventHandler, mWifiNative); 435 436 // scan succeeds 437 when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(true); 438 439 // start scan 440 assertTrue(mScanner.startSingleScan(settings, eventHandler)); 441 442 order.verify(mWifiNative).scan(eq(expectedScan), any(Set.class)); 443 444 when(mWifiNative.getScanResults()).thenReturn(rawResults); 445 446 // Notify scan has finished 447 mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT); 448 449 mLooper.dispatchAll(); 450 451 for (ScanResult result : fullResults) { 452 order.verify(eventHandler).onFullScanResult(eq(result), eq(0)); 453 } 454 455 order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 456 assertScanDataEquals(scanData, mScanner.getLatestSingleScanResults()); 457 458 verifyNoMoreInteractions(eventHandler); 459 } 460 461 @Test 462 public void backgroundScanNullEventHandler() { 463 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 464 .withBasePeriod(10000) 465 .withMaxApPerScan(10) 466 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 467 WifiScanner.WIFI_BAND_24_GHZ) 468 .build(); 469 assertFalse(mScanner.startBatchedScan(settings, null)); 470 } 471 472 @Test 473 public void backgroundScanNullSettings() { 474 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 475 476 assertFalse(mScanner.startBatchedScan(null, eventHandler)); 477 478 verifyNoMoreInteractions(eventHandler); 479 } 480 481 protected void doSuccessfulSingleScanTest(WifiNative.ScanSettings settings, 482 Set<Integer> expectedScan, Set<Integer> expectedHiddenNetIds, ScanResults results, 483 boolean expectFullResults) { 484 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 485 486 InOrder order = inOrder(eventHandler, mWifiNative); 487 488 // scan succeeds 489 when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(true); 490 491 // start scan 492 assertTrue(mScanner.startSingleScan(settings, eventHandler)); 493 494 expectSuccessfulSingleScan(order, eventHandler, expectedScan, expectedHiddenNetIds, 495 results, expectFullResults); 496 497 verifyNoMoreInteractions(eventHandler); 498 } 499 500 protected void expectSuccessfulSingleScan(InOrder order, 501 WifiNative.ScanEventHandler eventHandler, Set<Integer> expectedScan, 502 Set<Integer> expectedHiddenNetIds, ScanResults results, boolean expectFullResults) { 503 order.verify(mWifiNative).scan(eq(expectedScan), eq(expectedHiddenNetIds)); 504 505 when(mWifiNative.getScanResults()).thenReturn(results.getScanDetailArrayList()); 506 507 // Notify scan has finished 508 mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT); 509 510 mLooper.dispatchAll(); 511 512 if (expectFullResults) { 513 for (ScanResult result : results.getRawScanResults()) { 514 order.verify(eventHandler).onFullScanResult(eq(result), eq(0)); 515 } 516 } 517 518 order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 519 assertScanDataEquals(results.getScanData(), mScanner.getLatestSingleScanResults()); 520 } 521} 522