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 17 package com.android.server.wifi.scanner; 18 19 import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder; 20 import static com.android.server.wifi.ScanTestUtil.assertScanDatasEquals; 21 import static com.android.server.wifi.ScanTestUtil.createFreqSet; 22 23 import static org.junit.Assert.*; 24 import static org.mockito.Mockito.*; 25 26 import android.net.wifi.ScanResult; 27 import android.net.wifi.WifiScanner; 28 import android.net.wifi.WifiSsid; 29 import android.test.suitebuilder.annotation.SmallTest; 30 31 import com.android.server.wifi.ScanDetail; 32 import com.android.server.wifi.ScanResults; 33 import com.android.server.wifi.WifiMonitor; 34 import com.android.server.wifi.WifiNative; 35 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.mockito.InOrder; 39 40 import java.util.ArrayList; 41 import java.util.Set; 42 43 /** 44 * Unit tests for {@link com.android.server.wifi.scanner.WificondScannerImpl}. 45 */ 46 @SmallTest 47 public class WificondScannerTest extends BaseWifiScannerImplTest { 48 49 @Before 50 public void setup() throws Exception { 51 mScanner = new WificondScannerImpl(mContext, mWifiNative, mWifiMonitor, 52 mLooper.getLooper(), mClock); 53 } 54 55 @Test 56 public void backgroundScanSuccessSingleBucket() { 57 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 58 .withBasePeriod(10000) 59 .withMaxApPerScan(10) 60 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 61 WifiScanner.WIFI_BAND_24_GHZ) 62 .build(); 63 64 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 65 new ScanPeriod(ScanPeriod.ReportType.RESULT, 66 ScanResults.create(0, 2400), 67 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 68 new ScanPeriod(ScanPeriod.ReportType.RESULT, 69 ScanResults.create(1, 2450), 70 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 71 }; 72 73 doSuccessfulTest(settings, expectedPeriods); 74 } 75 76 @Test 77 public void backgroundScanMaxApExceeded() { 78 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 79 .withBasePeriod(10000) 80 .withMaxApPerScan(2) 81 .addBucketWithBand(10000, 82 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 83 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 84 WifiScanner.WIFI_BAND_24_GHZ) 85 .build(); 86 87 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 88 new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT, 89 ScanResults.createOverflowing(0, 2, 90 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 1"), 91 "00:00:00:00:00:00", "", -70, 2450, Long.MAX_VALUE, 0), 92 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 2"), 93 "AA:BB:CC:DD:EE:FF", "", -66, 2400, Long.MAX_VALUE, 0), 94 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 3"), 95 "00:00:00:00:00:00", "", -80, 2450, Long.MAX_VALUE, 0), 96 new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 4"), 97 "AA:BB:CC:11:22:33", "", -65, 2450, Long.MAX_VALUE, 0)), 98 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 99 }; 100 101 doSuccessfulTest(settings, expectedPeriods); 102 } 103 104 @Test 105 public void backgroundScanSuccessWithFullScanResults() { 106 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 107 .withBasePeriod(10000) 108 .withMaxApPerScan(10) 109 .addBucketWithBand(10000, 110 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 111 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 112 WifiScanner.WIFI_BAND_24_GHZ) 113 .build(); 114 115 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 116 new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT, 117 ScanResults.create(0, 2400, 2450, 2400, 2400), 118 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 119 new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT, 120 ScanResults.create(1, 2450, 2400, 2450, 2400), 121 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 122 }; 123 124 doSuccessfulTest(settings, expectedPeriods); 125 } 126 127 @Test 128 public void backgroundScanSuccessWithMixedFullResultsAndNot() { 129 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 130 .withBasePeriod(10000) 131 .withMaxApPerScan(10) 132 .addBucketWithBand(10000, 133 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 134 WifiScanner.WIFI_BAND_24_GHZ) 135 .addBucketWithBand(20000, 136 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 137 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 138 WifiScanner.WIFI_BAND_5_GHZ) 139 .build(); 140 141 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 142 new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT, 143 ScanResults.create(0, 2400, 2450, 2400, 5175), 144 expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH)), 145 new ScanPeriod(ScanPeriod.ReportType.RESULT, 146 ScanResults.create(1, 2450, 2400, 2450, 2400), 147 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 148 new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT, 149 ScanResults.create(2, 2450, 2400, 2450, 5150), 150 expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH)) 151 }; 152 153 doSuccessfulTest(settings, expectedPeriods); 154 } 155 156 @Test 157 public void backgroundScanNoBatch() { 158 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 159 .withBasePeriod(10000) 160 .withMaxApPerScan(10) 161 .addBucketWithBand(10000, 162 WifiScanner.REPORT_EVENT_NO_BATCH, 163 WifiScanner.WIFI_BAND_24_GHZ) 164 .build(); 165 166 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 167 new ScanPeriod(ScanPeriod.ReportType.NONE, 168 ScanResults.create(0, 2400, 2400, 2400), 169 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 170 new ScanPeriod(ScanPeriod.ReportType.NONE, 171 ScanResults.create(1, 2400, 2400, 2450), 172 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 173 new ScanPeriod(ScanPeriod.ReportType.NONE, 174 ScanResults.create(2, 2400, 2450, 2400), 175 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 176 }; 177 178 doSuccessfulTest(settings, expectedPeriods); 179 } 180 181 @Test 182 public void backgroundScanBatch() { 183 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 184 .withBasePeriod(10000) 185 .withMaxApPerScan(10) 186 .withMaxScansToCache(3) 187 .addBucketWithBand(10000, 188 WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL, 189 WifiScanner.WIFI_BAND_24_GHZ) 190 .build(); 191 192 ScanResults[] periodResults = new ScanResults[] { 193 ScanResults.create(0, 2400, 2400, 2400), 194 ScanResults.create(1, 2400, 2400, 2400, 2400), 195 ScanResults.create(2, 2450), 196 ScanResults.create(3, 2400, 2400), 197 ScanResults.create(4, 2400, 2450), 198 ScanResults.create(5, 2450) 199 }; 200 201 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 202 new ScanPeriod(ScanPeriod.ReportType.NONE, 203 periodResults[0], 204 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 205 new ScanPeriod(ScanPeriod.ReportType.NONE, 206 periodResults[1], 207 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 208 new ScanPeriod(ScanPeriod.ReportType.RESULT, 209 new ScanResults[] { 210 periodResults[0], 211 periodResults[1], 212 periodResults[2] 213 }, 214 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 215 new ScanPeriod(ScanPeriod.ReportType.NONE, 216 periodResults[3], 217 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 218 new ScanPeriod(ScanPeriod.ReportType.NONE, 219 periodResults[4], 220 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 221 new ScanPeriod(ScanPeriod.ReportType.RESULT, 222 new ScanResults[] { 223 periodResults[3], 224 periodResults[4], 225 periodResults[5] 226 }, 227 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 228 }; 229 230 doSuccessfulTest(settings, expectedPeriods); 231 } 232 233 @Test 234 public void backgroundScanSuccessWithMultipleBuckets() { 235 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 236 .withBasePeriod(10000) 237 .withMaxApPerScan(10) 238 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 239 WifiScanner.WIFI_BAND_24_GHZ) 240 .addBucketWithBand(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 241 WifiScanner.WIFI_BAND_BOTH) 242 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 243 5650) 244 .build(); 245 246 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 247 new ScanPeriod(ScanPeriod.ReportType.RESULT, 248 ScanResults.create(0, 2400, 5175), 249 expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650)), 250 new ScanPeriod(ScanPeriod.ReportType.RESULT, 251 ScanResults.create(1, 2400), 252 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 253 new ScanPeriod(ScanPeriod.ReportType.RESULT, 254 ScanResults.create(2, 2450, 5650), 255 expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_24_GHZ, 5650)), 256 new ScanPeriod(ScanPeriod.ReportType.RESULT, 257 ScanResults.create(3, 2450, 5175), 258 expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH)), 259 new ScanPeriod(ScanPeriod.ReportType.RESULT, 260 ScanResults.create(4, new int[0]), 261 expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_24_GHZ, 5650)), 262 new ScanPeriod(ScanPeriod.ReportType.RESULT, 263 ScanResults.create(5, 2400, 2400, 2400, 2450), 264 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 265 new ScanPeriod(ScanPeriod.ReportType.RESULT, 266 ScanResults.create(6, 5150, 5650, 5650), 267 expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650)) 268 }; 269 270 doSuccessfulTest(settings, expectedPeriods); 271 } 272 273 @Test 274 public void backgroundScanSuccessWithMultipleBucketsWhereAPeriodDoesNotRequireAScan() { 275 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 276 .withBasePeriod(10000) 277 .withMaxApPerScan(10) 278 .addBucketWithBand(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 279 WifiScanner.WIFI_BAND_BOTH) 280 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 281 5650) 282 .build(); 283 284 // expected scan frequencies 285 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 286 new ScanPeriod(ScanPeriod.ReportType.RESULT, 287 ScanResults.create(0, 2400, 5175), 288 expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650)), 289 null, 290 new ScanPeriod(ScanPeriod.ReportType.RESULT, 291 ScanResults.create(1, 5650), 292 createFreqSet(5650)), 293 new ScanPeriod(ScanPeriod.ReportType.RESULT, 294 ScanResults.create(2, 2450, 5175), 295 expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH)), 296 new ScanPeriod(ScanPeriod.ReportType.RESULT, 297 ScanResults.create(3, 5650, 5650, 5650), 298 createFreqSet(5650)), 299 null, 300 new ScanPeriod(ScanPeriod.ReportType.RESULT, 301 ScanResults.create(4, 2400, 2400, 2400, 2450), 302 expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650)) 303 }; 304 305 doSuccessfulTest(settings, expectedPeriods); 306 } 307 308 @Test 309 public void backgroundScanStartFailed() { 310 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 311 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 312 .withBasePeriod(10000) 313 .withMaxApPerScan(10) 314 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 315 WifiScanner.WIFI_BAND_24_GHZ) 316 .build(); 317 318 InOrder order = inOrder(eventHandler, mWifiNative); 319 320 // All scans fail 321 when(mWifiNative.scan(any(), any(Set.class))).thenReturn(false); 322 323 // Start scan 324 mScanner.startBatchedScan(settings, eventHandler); 325 326 assertBackgroundPeriodAlarmPending(); 327 328 expectFailedScanStart(order, eventHandler, 329 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)); 330 331 // Fire alarm to start next scan 332 dispatchBackgroundPeriodAlarm(); 333 334 assertBackgroundPeriodAlarmPending(); 335 336 expectFailedScanStart(order, eventHandler, 337 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)); 338 339 verifyNoMoreInteractions(eventHandler); 340 } 341 342 343 @Test 344 public void backgroundScanEventFailed() { 345 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 346 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 347 .withBasePeriod(10000) 348 .withMaxApPerScan(10) 349 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 350 WifiScanner.WIFI_BAND_24_GHZ) 351 .build(); 352 353 InOrder order = inOrder(eventHandler, mWifiNative); 354 355 // All scan starts succeed 356 when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true); 357 358 // Start scan 359 mScanner.startBatchedScan(settings, eventHandler); 360 361 assertBackgroundPeriodAlarmPending(); 362 363 expectFailedEventScan(order, eventHandler, 364 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)); 365 366 // Fire alarm to start next scan 367 dispatchBackgroundPeriodAlarm(); 368 369 assertBackgroundPeriodAlarmPending(); 370 371 expectFailedEventScan(order, eventHandler, 372 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)); 373 374 verifyNoMoreInteractions(eventHandler); 375 } 376 377 /** 378 * Run a scan and then pause after the first scan completes, but before the next one starts 379 * Then resume the scan 380 */ 381 @Test 382 public void pauseWhileWaitingToStartNextScanAndResumeScan() { 383 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 384 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 385 .withBasePeriod(10000) 386 .withMaxApPerScan(10) 387 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 388 WifiScanner.WIFI_BAND_24_GHZ) 389 .build(); 390 391 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 392 new ScanPeriod(ScanPeriod.ReportType.RESULT, 393 ScanResults.create(0, 2400, 2450, 2450), 394 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 395 new ScanPeriod(ScanPeriod.ReportType.RESULT, 396 ScanResults.create(1, 2400), 397 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 398 }; 399 400 InOrder order = inOrder(eventHandler, mWifiNative); 401 402 // All scan starts succeed 403 when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true); 404 405 // Start scan 406 mScanner.startBatchedScan(settings, eventHandler); 407 408 assertBackgroundPeriodAlarmPending(); 409 410 expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[0], 0); 411 412 assertBackgroundPeriodAlarmPending(); 413 414 mScanner.pauseBatchedScan(); 415 416 // onPause callback (previous results were flushed) 417 order.verify(eventHandler).onScanPaused(new WifiScanner.ScanData[0]); 418 419 assertBackgroundPeriodAlarmNotPending(); 420 421 mScanner.restartBatchedScan(); 422 423 // onRestarted callback 424 order.verify(eventHandler).onScanRestarted(); 425 426 expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[1], 1); 427 428 verifyNoMoreInteractions(eventHandler); 429 } 430 431 /** 432 * Run a scan and then pause while the first scan is running 433 * Then resume the scan 434 */ 435 @Test 436 public void pauseWhileScanningAndResumeScan() { 437 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 438 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 439 .withBasePeriod(10000) 440 .withMaxApPerScan(10) 441 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 442 WifiScanner.WIFI_BAND_24_GHZ) 443 .build(); 444 445 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 446 new ScanPeriod(ScanPeriod.ReportType.RESULT, 447 ScanResults.create(0, 2400, 2450, 2450), 448 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)), 449 new ScanPeriod(ScanPeriod.ReportType.RESULT, 450 ScanResults.create(1, 2400), 451 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 452 }; 453 454 InOrder order = inOrder(eventHandler, mWifiNative); 455 456 // All scan starts succeed 457 when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true); 458 459 // Start scan 460 mScanner.startBatchedScan(settings, eventHandler); 461 462 assertBackgroundPeriodAlarmPending(); 463 464 order.verify(mWifiNative).scan(eq(expectedPeriods[0].getScanFreqs()), any(Set.class)); 465 466 mScanner.pauseBatchedScan(); 467 468 // onPause callback (no pending results) 469 order.verify(eventHandler).onScanPaused(new WifiScanner.ScanData[0]); 470 471 assertBackgroundPeriodAlarmNotPending(); 472 473 // Setup scan results 474 when(mWifiNative.getScanResults()).thenReturn(expectedPeriods[0] 475 .getResultsToBeDelivered()[0].getScanDetailArrayList()); 476 477 // Notify scan has finished 478 mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT); 479 assertEquals("dispatch message after results event", 1, mLooper.dispatchAll()); 480 481 // listener should not be notified 482 483 mScanner.restartBatchedScan(); 484 485 // onRestarted callback 486 order.verify(eventHandler).onScanRestarted(); 487 488 expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[1], 1); 489 490 verifyNoMoreInteractions(eventHandler); 491 } 492 493 494 /** 495 * Run a scan and then pause after the first scan completes, but before the next one starts 496 * Then schedule a new scan while still paused 497 */ 498 @Test 499 public void pauseWhileWaitingToStartNextScanAndStartNewScan() { 500 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 501 WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() 502 .withBasePeriod(10000) 503 .withMaxApPerScan(10) 504 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 505 WifiScanner.WIFI_BAND_24_GHZ) 506 .build(); 507 508 WifiNative.ScanSettings settings2 = new NativeScanSettingsBuilder() 509 .withBasePeriod(10000) 510 .withMaxApPerScan(10) 511 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 512 WifiScanner.WIFI_BAND_5_GHZ) 513 .build(); 514 515 ScanPeriod[] expectedPeriods = new ScanPeriod[] { 516 new ScanPeriod(ScanPeriod.ReportType.RESULT, 517 ScanResults.create(0, 2400, 2450, 2450), 518 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)) 519 }; 520 521 ScanPeriod[] expectedPeriods2 = new ScanPeriod[] { 522 new ScanPeriod(ScanPeriod.ReportType.RESULT, 523 ScanResults.create(1, 5150, 5175, 5175), 524 expectedBandScanFreqs(WifiScanner.WIFI_BAND_5_GHZ)), 525 }; 526 527 InOrder order = inOrder(eventHandler, mWifiNative); 528 529 // All scan starts succeed 530 when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true); 531 532 // Start scan 533 mScanner.startBatchedScan(settings, eventHandler); 534 535 assertBackgroundPeriodAlarmPending(); 536 537 expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[0], 0); 538 539 assertBackgroundPeriodAlarmPending(); 540 541 mScanner.pauseBatchedScan(); 542 543 // onPause callback (previous results were flushed) 544 order.verify(eventHandler).onScanPaused(new WifiScanner.ScanData[0]); 545 546 assertBackgroundPeriodAlarmNotPending(); 547 548 // Start new scan 549 mScanner.startBatchedScan(settings2, eventHandler); 550 551 expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods2[0], 0); 552 553 verifyNoMoreInteractions(eventHandler); 554 } 555 556 /** 557 * Run a test with the given settings where all native scans succeed 558 * This will execute expectedPeriods.length scan periods by first 559 * starting the scan settings and then dispatching the scan period alarm to start the 560 * next scan. 561 */ 562 private void doSuccessfulTest(WifiNative.ScanSettings settings, ScanPeriod[] expectedPeriods) { 563 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 564 565 InOrder order = inOrder(eventHandler, mWifiNative); 566 567 // All scans succeed 568 when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true); 569 570 // Start scan 571 mScanner.startBatchedScan(settings, eventHandler); 572 573 for (int i = 0; i < expectedPeriods.length; ++i) { 574 ScanPeriod period = expectedPeriods[i]; 575 assertBackgroundPeriodAlarmPending(); 576 if (period != null) { // scan should be scheduled 577 expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[i], i); 578 } 579 if (i < expectedPeriods.length - 1) { 580 dispatchBackgroundPeriodAlarm(); 581 } 582 } 583 584 verifyNoMoreInteractions(eventHandler); 585 } 586 587 /** 588 * Verify the state after a scan was started either through startBatchedScan or 589 * dispatching the period alarm. 590 */ 591 private void expectSuccessfulBackgroundScan(InOrder order, 592 WifiNative.ScanEventHandler eventHandler, ScanPeriod period, int periodId) { 593 WifiScanner.ScanData[] scanDatas = null; 594 ArrayList<ScanDetail> nativeResults = null; 595 ScanResult[] fullResults = null; 596 if (period.getResultsToBeDelivered() != null) { 597 ScanResults lastPeriodResults = period.getResultsToBeDelivered() 598 [period.getResultsToBeDelivered().length - 1]; 599 nativeResults = lastPeriodResults.getScanDetailArrayList(); 600 if (period.expectResults()) { 601 scanDatas = 602 new WifiScanner.ScanData[period.getResultsToBeDelivered().length]; 603 for (int j = 0; j < scanDatas.length; ++j) { 604 scanDatas[j] = period.getResultsToBeDelivered()[j].getScanData(); 605 } 606 } 607 if (period.expectFullResults()) { 608 fullResults = lastPeriodResults.getRawScanResults(); 609 } 610 } 611 expectSuccessfulBackgroundScan(order, eventHandler, period.getScanFreqs(), 612 nativeResults, scanDatas, fullResults, periodId); 613 } 614 615 /** 616 * Verify the state after a scan was started either through startBatchedScan or 617 * dispatching the period alarm. 618 */ 619 private void expectSuccessfulBackgroundScan(InOrder order, 620 WifiNative.ScanEventHandler eventHandler, Set<Integer> scanFreqs, 621 ArrayList<ScanDetail> nativeResults, 622 WifiScanner.ScanData[] expectedScanResults, 623 ScanResult[] fullResults, int periodId) { 624 // Verify scan started 625 order.verify(mWifiNative).scan(eq(scanFreqs), any(Set.class)); 626 627 // Setup scan results 628 when(mWifiNative.getScanResults()).thenReturn(nativeResults); 629 630 // Notify scan has finished 631 mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT); 632 assertEquals("dispatch message after results event", 1, mLooper.dispatchAll()); 633 634 if (fullResults != null) { 635 for (ScanResult result : fullResults) { 636 order.verify(eventHandler).onFullScanResult(eq(result), eq(0)); 637 } 638 } 639 640 if (expectedScanResults != null) { 641 // Verify scan results delivered 642 order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 643 assertScanDatasEquals("period[" + periodId + "].", expectedScanResults, 644 mScanner.getLatestBatchedScanResults(true)); 645 } 646 } 647 648 private void expectFailedScanStart(InOrder order, WifiNative.ScanEventHandler eventHandler, 649 Set<Integer> scanFreqs) { 650 // Verify scan started 651 order.verify(mWifiNative).scan(eq(scanFreqs), any(Set.class)); 652 } 653 654 private void expectFailedEventScan(InOrder order, WifiNative.ScanEventHandler eventHandler, 655 Set<Integer> scanFreqs) { 656 // Verify scan started 657 order.verify(mWifiNative).scan(eq(scanFreqs), any(Set.class)); 658 659 // Notify scan has failed 660 mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_FAILED_EVENT); 661 assertEquals("dispatch message after results event", 1, mLooper.dispatchAll()); 662 663 // TODO: verify failure event 664 } 665 666 private void assertBackgroundPeriodAlarmPending() { 667 assertTrue("background period alarm not pending", 668 mAlarmManager.isPending(WificondScannerImpl.BACKGROUND_PERIOD_ALARM_TAG)); 669 } 670 671 private void assertBackgroundPeriodAlarmNotPending() { 672 assertFalse("background period alarm is pending", 673 mAlarmManager.isPending(WificondScannerImpl.BACKGROUND_PERIOD_ALARM_TAG)); 674 } 675 676 private void dispatchBackgroundPeriodAlarm() { 677 assertTrue("dispatch background period alarm", 678 mAlarmManager.dispatch(WificondScannerImpl.BACKGROUND_PERIOD_ALARM_TAG)); 679 mLooper.dispatchAll(); 680 } 681 682 private static class ScanPeriod { 683 enum ReportType { 684 NONE(false, false), 685 RESULT(true, false), 686 FULL_AND_RESULT(true, true), 687 FULL(false, true); 688 689 public final boolean result; 690 public final boolean full; 691 ReportType(boolean result, boolean full) { 692 this.result = result; 693 this.full = full; 694 } 695 }; 696 private final ReportType mReportType; 697 private final ScanResults[] mDeliveredResults; 698 private final Set<Integer> mRequestedFreqs; 699 700 ScanPeriod(ReportType reportType, ScanResults deliveredResult, 701 Set<Integer> requestedFreqs) { 702 this(reportType, new ScanResults[] {deliveredResult}, requestedFreqs); 703 } 704 705 ScanPeriod(ReportType reportType, ScanResults[] deliveredResults, 706 Set<Integer> requestedFreqs) { 707 mReportType = reportType; 708 mDeliveredResults = deliveredResults; 709 mRequestedFreqs = requestedFreqs; 710 } 711 712 public boolean expectResults() { 713 return mReportType.result; 714 } 715 public boolean expectFullResults() { 716 return mReportType.full; 717 } 718 public final ScanResults[] getResultsToBeDelivered() { 719 return mDeliveredResults; 720 } 721 public Set<Integer> getScanFreqs() { 722 return mRequestedFreqs; 723 } 724 } 725 } 726