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