WifiScanningServiceTest.java revision ee0ab818341d44614ffe56ae73ecc08b974c2cbb
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 17package com.android.server.wifi.scanner; 18 19import static com.android.server.wifi.ScanTestUtil.*; 20 21import static org.junit.Assert.*; 22import static org.mockito.Mockito.*; 23 24import android.content.BroadcastReceiver; 25import android.content.Context; 26import android.content.IntentFilter; 27import android.net.wifi.ScanResult; 28import android.net.wifi.WifiManager; 29import android.net.wifi.WifiScanner; 30import android.os.Bundle; 31import android.os.Handler; 32import android.os.Looper; 33import android.os.Message; 34import android.os.WorkSource; 35import android.test.suitebuilder.annotation.SmallTest; 36import android.util.Pair; 37 38import com.android.internal.app.IBatteryStats; 39import com.android.internal.util.Protocol; 40import com.android.server.wifi.BidirectionalAsyncChannel; 41import com.android.server.wifi.Clock; 42import com.android.server.wifi.MockAlarmManager; 43import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments; 44import com.android.server.wifi.MockLooper; 45import com.android.server.wifi.ScanResults; 46import com.android.server.wifi.TestUtil; 47import com.android.server.wifi.WifiInjector; 48import com.android.server.wifi.WifiMetrics; 49import com.android.server.wifi.WifiMetricsProto; 50import com.android.server.wifi.WifiNative; 51 52import org.junit.After; 53import org.junit.Before; 54import org.junit.Test; 55import org.mockito.ArgumentCaptor; 56import org.mockito.InOrder; 57import org.mockito.Mock; 58import org.mockito.MockitoAnnotations; 59import org.mockito.internal.matchers.CapturingMatcher; 60 61import java.io.FileDescriptor; 62import java.io.PrintWriter; 63import java.io.StringWriter; 64import java.util.ArrayList; 65import java.util.Arrays; 66import java.util.Collections; 67import java.util.regex.Pattern; 68 69/** 70 * Unit tests for {@link com.android.server.wifi.scanner.WifiScanningServiceImpl}. 71 */ 72@SmallTest 73public class WifiScanningServiceTest { 74 public static final String TAG = "WifiScanningServiceTest"; 75 76 @Mock Context mContext; 77 MockAlarmManager mAlarmManager; 78 @Mock WifiScannerImpl mWifiScannerImpl; 79 @Mock WifiScannerImpl.WifiScannerImplFactory mWifiScannerImplFactory; 80 @Mock IBatteryStats mBatteryStats; 81 @Mock WifiInjector mWifiInjector; 82 WifiMetrics mWifiMetrics; 83 MockLooper mLooper; 84 WifiScanningServiceImpl mWifiScanningServiceImpl; 85 86 87 @Before 88 public void setUp() throws Exception { 89 MockitoAnnotations.initMocks(this); 90 91 mAlarmManager = new MockAlarmManager(); 92 when(mContext.getSystemService(Context.ALARM_SERVICE)) 93 .thenReturn(mAlarmManager.getAlarmManager()); 94 mWifiMetrics = new WifiMetrics(); 95 96 ChannelHelper channelHelper = new PresetKnownBandsChannelHelper( 97 new int[]{2400, 2450}, 98 new int[]{5150, 5175}, 99 new int[]{5600, 5650, 5660}); 100 101 mLooper = new MockLooper(); 102 when(mWifiScannerImplFactory 103 .create(any(Context.class), any(Looper.class), any(Clock.class))) 104 .thenReturn(mWifiScannerImpl); 105 when(mWifiScannerImpl.getChannelHelper()).thenReturn(channelHelper); 106 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 107 mWifiScanningServiceImpl = new WifiScanningServiceImpl(mContext, mLooper.getLooper(), 108 mWifiScannerImplFactory, mBatteryStats, mWifiInjector); 109 } 110 111 @After 112 public void cleanup() { 113 validateMockitoUsage(); 114 } 115 116 /** 117 * Internal BroadcastReceiver that WifiScanningServiceImpl uses to listen for broadcasts 118 * this is initialized by calling startServiceAndLoadDriver 119 */ 120 BroadcastReceiver mBroadcastReceiver; 121 122 private WifiScanner.ScanSettings generateValidScanSettings() { 123 return createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20, 124 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 125 } 126 127 private BidirectionalAsyncChannel connectChannel(Handler handler) { 128 BidirectionalAsyncChannel controlChannel = new BidirectionalAsyncChannel(); 129 controlChannel.connect(mLooper.getLooper(), mWifiScanningServiceImpl.getMessenger(), 130 handler); 131 mLooper.dispatchAll(); 132 controlChannel.assertConnected(); 133 return controlChannel; 134 } 135 136 private Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler) { 137 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 138 order.verify(handler).handleMessage(messageCaptor.capture()); 139 return messageCaptor.getValue(); 140 } 141 142 private Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler, 143 final int what) { 144 CapturingMatcher<Message> messageMatcher = new CapturingMatcher<Message>() { 145 public boolean matches(Object argument) { 146 Message message = (Message) argument; 147 return message.what == what; 148 } 149 }; 150 order.verify(handler).handleMessage(argThat(messageMatcher)); 151 return messageMatcher.getLastValue(); 152 } 153 154 private void verifyScanResultsRecieved(InOrder order, Handler handler, int listenerId, 155 WifiScanner.ScanData... expected) { 156 Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler, 157 WifiScanner.CMD_SCAN_RESULT); 158 assertScanResultsMessage(listenerId, expected, scanResultMessage); 159 } 160 161 private void assertScanResultsMessage(int listenerId, WifiScanner.ScanData[] expected, 162 Message scanResultMessage) { 163 assertEquals("what", WifiScanner.CMD_SCAN_RESULT, scanResultMessage.what); 164 assertEquals("listenerId", listenerId, scanResultMessage.arg2); 165 assertScanDatasEquals(expected, 166 ((WifiScanner.ParcelableScanData) scanResultMessage.obj).getResults()); 167 } 168 169 private void verifySingleScanCompletedRecieved(InOrder order, Handler handler, int listenerId) { 170 Message completedMessage = verifyHandleMessageAndGetMessage(order, handler, 171 WifiScanner.CMD_SINGLE_SCAN_COMPLETED); 172 assertSingleScanCompletedMessage(listenerId, completedMessage); 173 } 174 175 private void assertSingleScanCompletedMessage(int listenerId, Message completedMessage) { 176 assertEquals("what", WifiScanner.CMD_SINGLE_SCAN_COMPLETED, completedMessage.what); 177 assertEquals("listenerId", listenerId, completedMessage.arg2); 178 } 179 180 private void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel, 181 int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) { 182 Bundle scanParams = new Bundle(); 183 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings); 184 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource); 185 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0, 186 scanRequestId, scanParams)); 187 } 188 189 private void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel, 190 int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) { 191 Bundle scanParams = new Bundle(); 192 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings); 193 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource); 194 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_SINGLE_SCAN, 0, 195 scanRequestId, scanParams)); 196 } 197 198 private void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) { 199 Message response = verifyHandleMessageAndGetMessage(order, handler); 200 assertSuccessfulResponse(arg2, response); 201 } 202 203 private void assertSuccessfulResponse(int arg2, Message response) { 204 if (response.what == WifiScanner.CMD_OP_FAILED) { 205 WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj; 206 fail("response indicates failure, reason=" + result.reason 207 + ", description=" + result.description); 208 } else { 209 assertEquals("response.what", WifiScanner.CMD_OP_SUCCEEDED, response.what); 210 assertEquals("response.arg2", arg2, response.arg2); 211 } 212 } 213 214 private void verifyFailedResponse(InOrder order, Handler handler, int arg2, 215 int expectedErrorReason, String expectedErrorDescription) { 216 Message response = verifyHandleMessageAndGetMessage(order, handler); 217 assertFailedResponse(arg2, expectedErrorReason, expectedErrorDescription, response); 218 } 219 220 private void assertFailedResponse(int arg2, int expectedErrorReason, 221 String expectedErrorDescription, Message response) { 222 if (response.what == WifiScanner.CMD_OP_SUCCEEDED) { 223 fail("response indicates success"); 224 } else { 225 assertEquals("response.what", WifiScanner.CMD_OP_FAILED, response.what); 226 assertEquals("response.arg2", arg2, response.arg2); 227 WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj; 228 assertEquals("response.obj.reason", 229 expectedErrorReason, result.reason); 230 assertEquals("response.obj.description", 231 expectedErrorDescription, result.description); 232 } 233 } 234 235 private WifiNative.ScanEventHandler verifyStartSingleScan(InOrder order, 236 WifiNative.ScanSettings expected) { 237 ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor = 238 ArgumentCaptor.forClass(WifiNative.ScanSettings.class); 239 ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor = 240 ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class); 241 order.verify(mWifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(), 242 scanEventHandlerCaptor.capture()); 243 assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue()); 244 return scanEventHandlerCaptor.getValue(); 245 } 246 247 private WifiNative.ScanEventHandler verifyStartBackgroundScan(InOrder order, 248 WifiNative.ScanSettings expected) { 249 ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor = 250 ArgumentCaptor.forClass(WifiNative.ScanSettings.class); 251 ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor = 252 ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class); 253 order.verify(mWifiScannerImpl).startBatchedScan(scanSettingsCaptor.capture(), 254 scanEventHandlerCaptor.capture()); 255 assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue()); 256 return scanEventHandlerCaptor.getValue(); 257 } 258 259 private static final int MAX_AP_PER_SCAN = 16; 260 private void startServiceAndLoadDriver() { 261 mWifiScanningServiceImpl.startService(); 262 when(mWifiScannerImpl.getScanCapabilities(any(WifiNative.ScanCapabilities.class))) 263 .thenAnswer(new AnswerWithArguments() { 264 public boolean answer(WifiNative.ScanCapabilities capabilities) { 265 capabilities.max_scan_cache_size = Integer.MAX_VALUE; 266 capabilities.max_scan_buckets = 8; 267 capabilities.max_ap_cache_per_scan = MAX_AP_PER_SCAN; 268 capabilities.max_rssi_sample_size = 8; 269 capabilities.max_scan_reporting_threshold = 10; 270 capabilities.max_hotlist_bssids = 0; 271 capabilities.max_significant_wifi_change_aps = 0; 272 return true; 273 } 274 }); 275 ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = 276 ArgumentCaptor.forClass(BroadcastReceiver.class); 277 verify(mContext) 278 .registerReceiver(broadcastReceiverCaptor.capture(), any(IntentFilter.class)); 279 mBroadcastReceiver = broadcastReceiverCaptor.getValue(); 280 TestUtil.sendWifiScanAvailable(broadcastReceiverCaptor.getValue(), mContext, 281 WifiManager.WIFI_STATE_ENABLED); 282 mLooper.dispatchAll(); 283 } 284 285 private String dumpService() { 286 StringWriter stringWriter = new StringWriter(); 287 mWifiScanningServiceImpl.dump(new FileDescriptor(), new PrintWriter(stringWriter), 288 new String[0]); 289 return stringWriter.toString(); 290 } 291 292 private void assertDumpContainsRequestLog(String type, int id) { 293 String serviceDump = dumpService(); 294 Pattern logLineRegex = Pattern.compile("^.+" + type + ": ClientInfo\\[uid=\\d+\\],Id=" + 295 id + ".*$", Pattern.MULTILINE); 296 assertTrue("dump did not contain log with type=" + type + ", id=" + id + 297 ": " + serviceDump + "\n", 298 logLineRegex.matcher(serviceDump).find()); 299 } 300 301 private void assertDumpContainsCallbackLog(String callback, int id, String extra) { 302 String serviceDump = dumpService(); 303 String extraPattern = extra == null ? "" : "," + extra; 304 Pattern logLineRegex = Pattern.compile("^.+" + callback + ": ClientInfo\\[uid=\\d+\\],Id=" + 305 id + extraPattern + "$", Pattern.MULTILINE); 306 assertTrue("dump did not contain callback log with callback=" + callback + ", id=" + id + 307 ", extra=" + extra + ": " + serviceDump + "\n", 308 logLineRegex.matcher(serviceDump).find()); 309 } 310 311 @Test 312 public void construct() throws Exception { 313 verifyNoMoreInteractions(mWifiScannerImpl, mWifiScannerImpl, 314 mWifiScannerImplFactory, mBatteryStats); 315 dumpService(); // make sure this succeeds 316 } 317 318 @Test 319 public void startService() throws Exception { 320 mWifiScanningServiceImpl.startService(); 321 verifyNoMoreInteractions(mWifiScannerImplFactory); 322 323 Handler handler = mock(Handler.class); 324 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 325 InOrder order = inOrder(handler); 326 sendBackgroundScanRequest(controlChannel, 122, generateValidScanSettings(), null); 327 mLooper.dispatchAll(); 328 verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available"); 329 } 330 331 @Test 332 public void loadDriver() throws Exception { 333 startServiceAndLoadDriver(); 334 verify(mWifiScannerImplFactory, times(1)) 335 .create(any(Context.class), any(Looper.class), any(Clock.class)); 336 337 Handler handler = mock(Handler.class); 338 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 339 InOrder order = inOrder(handler); 340 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 341 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 342 sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings(), null); 343 mLooper.dispatchAll(); 344 verifySuccessfulResponse(order, handler, 192); 345 assertDumpContainsRequestLog("addBackgroundScanRequest", 192); 346 } 347 348 @Test 349 public void sendInvalidCommand() throws Exception { 350 startServiceAndLoadDriver(); 351 352 Handler handler = mock(Handler.class); 353 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 354 InOrder order = inOrder(handler, mWifiScannerImpl); 355 controlChannel.sendMessage(Message.obtain(null, Protocol.BASE_WIFI_MANAGER)); 356 mLooper.dispatchAll(); 357 verifyFailedResponse(order, handler, 0, WifiScanner.REASON_INVALID_REQUEST, 358 "Invalid request"); 359 } 360 361 private void doSuccessfulSingleScan(WifiScanner.ScanSettings requestSettings, 362 WifiNative.ScanSettings nativeSettings, ScanResults results) { 363 int requestId = 12; 364 startServiceAndLoadDriver(); 365 366 Handler handler = mock(Handler.class); 367 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 368 InOrder order = inOrder(handler, mWifiScannerImpl); 369 370 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 371 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 372 373 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 374 375 mLooper.dispatchAll(); 376 WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings); 377 verifySuccessfulResponse(order, handler, requestId); 378 379 when(mWifiScannerImpl.getLatestSingleScanResults()) 380 .thenReturn(results.getScanData()); 381 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 382 383 mLooper.dispatchAll(); 384 verifyScanResultsRecieved(order, handler, requestId, results.getScanData()); 385 verifySingleScanCompletedRecieved(order, handler, requestId); 386 verifyNoMoreInteractions(handler); 387 assertDumpContainsRequestLog("addSingleScanRequest", requestId); 388 assertDumpContainsCallbackLog("singleScanResults", requestId, 389 "results=" + results.getRawScanResults().length); 390 } 391 392 /** 393 * Do a single scan for a band and verify that it is successful. 394 */ 395 @Test 396 public void sendSingleScanBandRequest() throws Exception { 397 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 398 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 399 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 400 ScanResults.create(0, 2400, 5150, 5175)); 401 } 402 403 /** 404 * Do a single scan for a list of channels and verify that it is successful. 405 */ 406 @Test 407 public void sendSingleScanChannelsRequest() throws Exception { 408 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 409 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 410 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 411 ScanResults.create(0, 2400, 5150, 5175)); 412 } 413 414 /** 415 * Do a single scan, which the hardware fails to start, and verify that a failure response is 416 * delivered. 417 */ 418 @Test 419 public void sendSingleScanRequestWhichFailsToStart() throws Exception { 420 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 421 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 422 int requestId = 33; 423 424 startServiceAndLoadDriver(); 425 426 Handler handler = mock(Handler.class); 427 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 428 InOrder order = inOrder(handler, mWifiScannerImpl); 429 430 // scan fails 431 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 432 any(WifiNative.ScanEventHandler.class))).thenReturn(false); 433 434 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 435 436 mLooper.dispatchAll(); 437 // Scan is successfully queue, but then fails to execute 438 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 439 order.verify(handler, times(2)).handleMessage(messageCaptor.capture()); 440 assertSuccessfulResponse(requestId, messageCaptor.getAllValues().get(0)); 441 assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED, 442 "Failed to start single scan", messageCaptor.getAllValues().get(1)); 443 444 assertEquals(mWifiMetrics.getOneshotScanCount(), 1); 445 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1); 446 assertDumpContainsRequestLog("addSingleScanRequest", requestId); 447 } 448 449 /** 450 * Do a single scan, which successfully starts, but fails partway through and verify that a 451 * failure response is delivered. 452 */ 453 @Test 454 public void sendSingleScanRequestWhichFailsAfterStart() throws Exception { 455 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 456 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 457 int requestId = 33; 458 459 startServiceAndLoadDriver(); 460 461 Handler handler = mock(Handler.class); 462 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 463 InOrder order = inOrder(handler, mWifiScannerImpl); 464 465 // successful start 466 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 467 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 468 469 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 470 471 // Scan is successfully queue 472 mLooper.dispatchAll(); 473 WifiNative.ScanEventHandler eventHandler = 474 verifyStartSingleScan(order, computeSingleScanNativeSettings(requestSettings)); 475 verifySuccessfulResponse(order, handler, requestId); 476 477 // but then fails to execute 478 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_FAILED); 479 mLooper.dispatchAll(); 480 verifyFailedResponse(order, handler, requestId, 481 WifiScanner.REASON_UNSPECIFIED, "Scan failed"); 482 assertEquals(mWifiMetrics.getOneshotScanCount(), 1); 483 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1); 484 } 485 486 // TODO Add more single scan tests 487 // * disable wifi while scanning 488 // * disable wifi while scanning with pending scan 489 490 /** 491 * Send a single scan request and then a second one after the first completes. 492 */ 493 @Test 494 public void sendSingleScanRequestAfterPreviousCompletes() { 495 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 496 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 497 int requestId1 = 12; 498 ScanResults results1 = ScanResults.create(0, 2400); 499 500 501 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 502 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 503 int requestId2 = 13; 504 ScanResults results2 = ScanResults.create(0, 2450); 505 506 507 startServiceAndLoadDriver(); 508 509 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 510 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 511 512 Handler handler = mock(Handler.class); 513 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 514 InOrder order = inOrder(handler, mWifiScannerImpl); 515 516 // Run scan 1 517 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 518 519 mLooper.dispatchAll(); 520 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order, 521 computeSingleScanNativeSettings(requestSettings1)); 522 verifySuccessfulResponse(order, handler, requestId1); 523 524 // dispatch scan 1 results 525 when(mWifiScannerImpl.getLatestSingleScanResults()) 526 .thenReturn(results1.getScanData()); 527 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 528 529 mLooper.dispatchAll(); 530 verifyScanResultsRecieved(order, handler, requestId1, results1.getScanData()); 531 verifySingleScanCompletedRecieved(order, handler, requestId1); 532 533 // Run scan 2 534 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 535 536 mLooper.dispatchAll(); 537 WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order, 538 computeSingleScanNativeSettings(requestSettings2)); 539 verifySuccessfulResponse(order, handler, requestId2); 540 541 // dispatch scan 2 results 542 when(mWifiScannerImpl.getLatestSingleScanResults()) 543 .thenReturn(results2.getScanData()); 544 eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 545 546 mLooper.dispatchAll(); 547 verifyScanResultsRecieved(order, handler, requestId2, results2.getScanData()); 548 verifySingleScanCompletedRecieved(order, handler, requestId2); 549 } 550 551 /** 552 * Send a single scan request and then a second one before the first completes. 553 * Verify that both are scheduled and succeed. 554 */ 555 @Test 556 public void sendSingleScanRequestWhilePreviousScanRunning() { 557 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 558 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 559 int requestId1 = 12; 560 ScanResults results1 = ScanResults.create(0, 2400); 561 562 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 563 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 564 int requestId2 = 13; 565 ScanResults results2 = ScanResults.create(0, 2450); 566 567 568 startServiceAndLoadDriver(); 569 570 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 571 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 572 573 Handler handler = mock(Handler.class); 574 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 575 InOrder handlerOrder = inOrder(handler); 576 InOrder nativeOrder = inOrder(mWifiScannerImpl); 577 578 // Run scan 1 579 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 580 581 mLooper.dispatchAll(); 582 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, 583 computeSingleScanNativeSettings(requestSettings1)); 584 verifySuccessfulResponse(handlerOrder, handler, requestId1); 585 586 // Queue scan 2 (will not run because previous is in progress) 587 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 588 mLooper.dispatchAll(); 589 verifySuccessfulResponse(handlerOrder, handler, requestId2); 590 591 // dispatch scan 1 results 592 when(mWifiScannerImpl.getLatestSingleScanResults()) 593 .thenReturn(results1.getScanData()); 594 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 595 596 mLooper.dispatchAll(); 597 verifyScanResultsRecieved(handlerOrder, handler, requestId1, results1.getScanData()); 598 verifySingleScanCompletedRecieved(handlerOrder, handler, requestId1); 599 600 // now that the first scan completed we expect the second one to start 601 WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder, 602 computeSingleScanNativeSettings(requestSettings2)); 603 604 // dispatch scan 2 results 605 when(mWifiScannerImpl.getLatestSingleScanResults()) 606 .thenReturn(results2.getScanData()); 607 eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 608 609 mLooper.dispatchAll(); 610 verifyScanResultsRecieved(handlerOrder, handler, requestId2, results2.getScanData()); 611 verifySingleScanCompletedRecieved(handlerOrder, handler, requestId2); 612 assertEquals(mWifiMetrics.getOneshotScanCount(), 2); 613 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2); 614 } 615 616 617 /** 618 * Send a single scan request and then two more before the first completes. 619 * Verify that the first completes and the second two are merged. 620 */ 621 @Test 622 public void sendMultipleSingleScanRequestWhilePreviousScanRunning() { 623 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 624 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 625 int requestId1 = 12; 626 ScanResults results1 = ScanResults.create(0, 2400); 627 628 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 629 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 630 int requestId2 = 13; 631 ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450); 632 633 WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0, 634 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 635 int requestId3 = 15; 636 ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150); 637 638 WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels( 639 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150)); 640 ScanResults results2and3 = ScanResults.merge(results2, results3); 641 642 643 startServiceAndLoadDriver(); 644 645 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 646 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 647 648 Handler handler = mock(Handler.class); 649 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 650 InOrder handlerOrder = inOrder(handler); 651 InOrder nativeOrder = inOrder(mWifiScannerImpl); 652 653 // Run scan 1 654 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 655 656 mLooper.dispatchAll(); 657 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, 658 computeSingleScanNativeSettings(requestSettings1)); 659 verifySuccessfulResponse(handlerOrder, handler, requestId1); 660 661 // Queue scan 2 (will not run because previous is in progress) 662 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 663 mLooper.dispatchAll(); 664 verifySuccessfulResponse(handlerOrder, handler, requestId2); 665 666 // Queue scan 3 (will not run because previous is in progress) 667 sendSingleScanRequest(controlChannel, requestId3, requestSettings3, null); 668 mLooper.dispatchAll(); 669 verifySuccessfulResponse(handlerOrder, handler, requestId3); 670 671 // dispatch scan 1 results 672 when(mWifiScannerImpl.getLatestSingleScanResults()) 673 .thenReturn(results1.getScanData()); 674 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 675 676 mLooper.dispatchAll(); 677 verifyScanResultsRecieved(handlerOrder, handler, requestId1, results1.getScanData()); 678 verifySingleScanCompletedRecieved(handlerOrder, handler, requestId1); 679 680 // now that the first scan completed we expect the second and third ones to start 681 WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder, 682 nativeSettings2and3); 683 684 // dispatch scan 2 and 3 results 685 when(mWifiScannerImpl.getLatestSingleScanResults()) 686 .thenReturn(results2and3.getScanData()); 687 eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 688 689 mLooper.dispatchAll(); 690 691 // unfortunatally the order that these events are dispatched is dependant on the order which 692 // they are iterated through internally 693 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 694 handlerOrder.verify(handler, times(4)).handleMessage(messageCaptor.capture()); 695 int firstListenerId = messageCaptor.getAllValues().get(0).arg2; 696 assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId3, 697 firstListenerId == requestId2 || firstListenerId == requestId3); 698 if (firstListenerId == requestId2) { 699 assertScanResultsMessage(requestId2, 700 new WifiScanner.ScanData[] {results2.getScanData()}, 701 messageCaptor.getAllValues().get(0)); 702 assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(1)); 703 assertScanResultsMessage(requestId3, 704 new WifiScanner.ScanData[] {results3.getScanData()}, 705 messageCaptor.getAllValues().get(2)); 706 assertSingleScanCompletedMessage(requestId3, messageCaptor.getAllValues().get(3)); 707 } else { 708 assertScanResultsMessage(requestId3, 709 new WifiScanner.ScanData[] {results3.getScanData()}, 710 messageCaptor.getAllValues().get(0)); 711 assertSingleScanCompletedMessage(requestId3, messageCaptor.getAllValues().get(1)); 712 assertScanResultsMessage(requestId2, 713 new WifiScanner.ScanData[] {results2.getScanData()}, 714 messageCaptor.getAllValues().get(2)); 715 assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(3)); 716 } 717 assertEquals(mWifiMetrics.getOneshotScanCount(), 3); 718 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3); 719 720 assertDumpContainsRequestLog("addSingleScanRequest", requestId1); 721 assertDumpContainsRequestLog("addSingleScanRequest", requestId2); 722 assertDumpContainsRequestLog("addSingleScanRequest", requestId3); 723 assertDumpContainsCallbackLog("singleScanResults", requestId1, 724 "results=" + results1.getRawScanResults().length); 725 assertDumpContainsCallbackLog("singleScanResults", requestId2, 726 "results=" + results2.getRawScanResults().length); 727 assertDumpContainsCallbackLog("singleScanResults", requestId3, 728 "results=" + results3.getRawScanResults().length); 729 } 730 731 private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings, 732 WifiNative.ScanSettings nativeSettings) { 733 startServiceAndLoadDriver(); 734 735 Handler handler = mock(Handler.class); 736 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 737 InOrder order = inOrder(handler, mWifiScannerImpl); 738 739 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 740 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 741 742 sendBackgroundScanRequest(controlChannel, 12, requestSettings, null); 743 mLooper.dispatchAll(); 744 verifyStartBackgroundScan(order, nativeSettings); 745 verifySuccessfulResponse(order, handler, 12); 746 verifyNoMoreInteractions(handler); 747 assertDumpContainsRequestLog("addBackgroundScanRequest", 12); 748 } 749 750 /** 751 * Do a background scan for a band and verify that it is successful. 752 */ 753 @Test 754 public void sendBackgroundScanBandRequest() throws Exception { 755 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, 756 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 757 WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() 758 .withBasePeriod(20000) 759 .withMaxApPerScan(MAX_AP_PER_SCAN) 760 .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH) 761 .addBucketWithBand(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 762 WifiScanner.WIFI_BAND_BOTH) 763 .build(); 764 doSuccessfulBackgroundScan(requestSettings, nativeSettings); 765 assertEquals(mWifiMetrics.getBackgroundScanCount(), 1); 766 } 767 768 /** 769 * Do a background scan for a list of channels and verify that it is successful. 770 */ 771 @Test 772 public void sendBackgroundScanChannelsRequest() throws Exception { 773 WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(5150), 20000, 774 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 775 WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() 776 .withBasePeriod(20000) 777 .withMaxApPerScan(MAX_AP_PER_SCAN) 778 .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH) 779 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5150) 780 .build(); 781 doSuccessfulBackgroundScan(requestSettings, nativeSettings); 782 } 783 784 private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForHwPno() 785 throws Exception { 786 WifiScanner.ScanSettings requestSettings = createRequest( 787 channelsToSpec(0, 2400, 5150, 5175), 20000, 0, 20, 788 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 789 WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() 790 .withBasePeriod(20000) 791 .withMaxApPerScan(MAX_AP_PER_SCAN) 792 .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH) 793 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 794 0, 2400, 5150, 5175) 795 .build(); 796 return Pair.create(requestSettings, nativeSettings); 797 } 798 799 private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForSwPno() 800 throws Exception { 801 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> settingsPair = 802 createScanSettingsForHwPno(); 803 804 WifiScanner.ScanSettings requestSettings = settingsPair.first; 805 WifiNative.ScanSettings nativeSettings = settingsPair.second; 806 // reportEvents field is overridden for SW PNO 807 for (int i = 0; i < nativeSettings.buckets.length; i++) { 808 nativeSettings.buckets[i].report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 809 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; 810 } 811 return Pair.create(requestSettings, nativeSettings); 812 } 813 814 private Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> createPnoSettings( 815 ScanResults results) 816 throws Exception { 817 WifiScanner.PnoSettings requestPnoSettings = new WifiScanner.PnoSettings(); 818 requestPnoSettings.networkList = 819 new WifiScanner.PnoSettings.PnoNetwork[results.getRawScanResults().length]; 820 int i = 0; 821 for (ScanResult scanResult : results.getRawScanResults()) { 822 requestPnoSettings.networkList[i++] = 823 new WifiScanner.PnoSettings.PnoNetwork(scanResult.SSID); 824 } 825 826 WifiNative.PnoSettings nativePnoSettings = new WifiNative.PnoSettings(); 827 nativePnoSettings.min5GHzRssi = requestPnoSettings.min5GHzRssi; 828 nativePnoSettings.min24GHzRssi = requestPnoSettings.min24GHzRssi; 829 nativePnoSettings.initialScoreMax = requestPnoSettings.initialScoreMax; 830 nativePnoSettings.currentConnectionBonus = requestPnoSettings.currentConnectionBonus; 831 nativePnoSettings.sameNetworkBonus = requestPnoSettings.sameNetworkBonus; 832 nativePnoSettings.secureBonus = requestPnoSettings.secureBonus; 833 nativePnoSettings.band5GHzBonus = requestPnoSettings.band5GHzBonus; 834 nativePnoSettings.isConnected = requestPnoSettings.isConnected; 835 nativePnoSettings.networkList = 836 new WifiNative.PnoNetwork[requestPnoSettings.networkList.length]; 837 for (i = 0; i < requestPnoSettings.networkList.length; i++) { 838 nativePnoSettings.networkList[i] = new WifiNative.PnoNetwork(); 839 nativePnoSettings.networkList[i].ssid = requestPnoSettings.networkList[i].ssid; 840 nativePnoSettings.networkList[i].networkId = 841 requestPnoSettings.networkList[i].networkId; 842 nativePnoSettings.networkList[i].priority = requestPnoSettings.networkList[i].priority; 843 nativePnoSettings.networkList[i].flags = requestPnoSettings.networkList[i].flags; 844 nativePnoSettings.networkList[i].auth_bit_field = 845 requestPnoSettings.networkList[i].authBitField; 846 } 847 return Pair.create(requestPnoSettings, nativePnoSettings); 848 } 849 850 private ScanResults createScanResultsForPno() { 851 return ScanResults.create(0, 2400, 5150, 5175); 852 } 853 854 private ScanResults createScanResultsForPnoWithNoIE() { 855 return ScanResults.createWithNoIE(0, 2400, 5150, 5175); 856 } 857 858 private WifiNative.PnoEventHandler verifyHwPno(InOrder order, 859 WifiNative.PnoSettings expected) { 860 ArgumentCaptor<WifiNative.PnoSettings> pnoSettingsCaptor = 861 ArgumentCaptor.forClass(WifiNative.PnoSettings.class); 862 ArgumentCaptor<WifiNative.PnoEventHandler> pnoEventHandlerCaptor = 863 ArgumentCaptor.forClass(WifiNative.PnoEventHandler.class); 864 order.verify(mWifiScannerImpl).setHwPnoList(pnoSettingsCaptor.capture(), 865 pnoEventHandlerCaptor.capture()); 866 assertNativePnoSettingsEquals(expected, pnoSettingsCaptor.getValue()); 867 return pnoEventHandlerCaptor.getValue(); 868 } 869 870 private void sendPnoScanRequest(BidirectionalAsyncChannel controlChannel, 871 int scanRequestId, WifiScanner.ScanSettings scanSettings, 872 WifiScanner.PnoSettings pnoSettings) { 873 Bundle pnoParams = new Bundle(); 874 scanSettings.isPnoScan = true; 875 pnoParams.putParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings); 876 pnoParams.putParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings); 877 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_PNO_SCAN, 0, 878 scanRequestId, pnoParams)); 879 } 880 881 private void assertPnoNetworkFoundMessage(int listenerId, ScanResult[] expected, 882 Message networkFoundMessage) { 883 assertEquals("what", WifiScanner.CMD_PNO_NETWORK_FOUND, networkFoundMessage.what); 884 assertEquals("listenerId", listenerId, networkFoundMessage.arg2); 885 assertScanResultsEquals(expected, 886 ((WifiScanner.ParcelableScanResults) networkFoundMessage.obj).getResults()); 887 } 888 889 private void verifyPnoNetworkFoundRecieved(InOrder order, Handler handler, int listenerId, 890 ScanResult[] expected) { 891 Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler, 892 WifiScanner.CMD_PNO_NETWORK_FOUND); 893 assertPnoNetworkFoundMessage(listenerId, expected, scanResultMessage); 894 } 895 896 private void expectSuccessfulBackgroundScan(InOrder order, 897 WifiNative.ScanSettings nativeSettings, ScanResults results) { 898 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 899 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 900 mLooper.dispatchAll(); 901 WifiNative.ScanEventHandler eventHandler = verifyStartBackgroundScan(order, nativeSettings); 902 WifiScanner.ScanData[] scanDatas = new WifiScanner.ScanData[1]; 903 scanDatas[0] = results.getScanData(); 904 for (ScanResult fullScanResult : results.getRawScanResults()) { 905 eventHandler.onFullScanResult(fullScanResult, 0); 906 } 907 when(mWifiScannerImpl.getLatestBatchedScanResults(anyBoolean())).thenReturn(scanDatas); 908 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 909 mLooper.dispatchAll(); 910 } 911 912 private void expectHwPnoScanWithNoBackgroundScan(InOrder order, Handler handler, int requestId, 913 WifiNative.PnoSettings nativeSettings, ScanResults results) { 914 when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true); 915 when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(false); 916 917 when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class), 918 any(WifiNative.PnoEventHandler.class))).thenReturn(true); 919 mLooper.dispatchAll(); 920 WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativeSettings); 921 verifySuccessfulResponse(order, handler, requestId); 922 eventHandler.onPnoNetworkFound(results.getRawScanResults()); 923 mLooper.dispatchAll(); 924 } 925 926 private void expectHwPnoScanWithBackgroundScan(InOrder order, Handler handler, int requestId, 927 WifiNative.ScanSettings nativeScanSettings, 928 WifiNative.PnoSettings nativePnoSettings, ScanResults results) { 929 when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true); 930 when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true); 931 932 when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class), 933 any(WifiNative.PnoEventHandler.class))).thenReturn(true); 934 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 935 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 936 mLooper.dispatchAll(); 937 WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativePnoSettings); 938 verifySuccessfulResponse(order, handler, requestId); 939 verifyStartBackgroundScan(order, nativeScanSettings); 940 eventHandler.onPnoNetworkFound(results.getRawScanResults()); 941 mLooper.dispatchAll(); 942 } 943 944 private void expectHwPnoScanWithBackgroundScanWithNoIE(InOrder order, Handler handler, 945 int requestId, WifiNative.ScanSettings nativeBackgroundScanSettings, 946 WifiNative.ScanSettings nativeSingleScanSettings, 947 WifiNative.PnoSettings nativePnoSettings, ScanResults results) { 948 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 949 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 950 951 expectHwPnoScanWithBackgroundScan(order, handler, requestId, nativeBackgroundScanSettings, 952 nativePnoSettings, results); 953 WifiNative.ScanEventHandler eventHandler = 954 verifyStartSingleScan(order, nativeSingleScanSettings); 955 when(mWifiScannerImpl.getLatestSingleScanResults()).thenReturn(results.getScanData()); 956 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 957 mLooper.dispatchAll(); 958 } 959 private void expectSwPnoScan(InOrder order, WifiNative.ScanSettings nativeScanSettings, 960 ScanResults results) { 961 when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(false); 962 when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true); 963 964 expectSuccessfulBackgroundScan(order, nativeScanSettings, results); 965 } 966 967 /** 968 * Tests Supplicant PNO scan when the PNO scan results contain IE info. This ensures that the 969 * PNO scan results are plumbed back to the client as a PNO network found event. 970 */ 971 @Test 972 public void testSuccessfulHwPnoScanWithNoBackgroundScan() throws Exception { 973 startServiceAndLoadDriver(); 974 Handler handler = mock(Handler.class); 975 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 976 InOrder order = inOrder(handler, mWifiScannerImpl); 977 int requestId = 12; 978 979 ScanResults scanResults = createScanResultsForPno(); 980 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 981 createScanSettingsForHwPno(); 982 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 983 createPnoSettings(scanResults); 984 985 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 986 expectHwPnoScanWithNoBackgroundScan(order, handler, requestId, pnoSettings.second, 987 scanResults); 988 verifyPnoNetworkFoundRecieved(order, handler, requestId, scanResults.getRawScanResults()); 989 } 990 991 /** 992 * Tests Hal ePNO scan when the PNO scan results contain IE info. This ensures that the 993 * PNO scan results are plumbed back to the client as a PNO network found event. 994 */ 995 @Test 996 public void testSuccessfulHwPnoScanWithBackgroundScan() throws Exception { 997 startServiceAndLoadDriver(); 998 Handler handler = mock(Handler.class); 999 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1000 InOrder order = inOrder(handler, mWifiScannerImpl); 1001 int requestId = 12; 1002 1003 ScanResults scanResults = createScanResultsForPno(); 1004 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 1005 createScanSettingsForHwPno(); 1006 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 1007 createPnoSettings(scanResults); 1008 1009 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 1010 expectHwPnoScanWithBackgroundScan(order, handler, requestId, scanSettings.second, 1011 pnoSettings.second, scanResults); 1012 verifyPnoNetworkFoundRecieved(order, handler, requestId, scanResults.getRawScanResults()); 1013 } 1014 1015 /** 1016 * Tests Hal ePNO scan when the PNO scan results don't contain IE info. This ensures that the 1017 * single scan results are plumbed back to the client as a PNO network found event. 1018 */ 1019 @Test 1020 public void testSuccessfulHwPnoScanWithBackgroundScanWithNoIE() throws Exception { 1021 startServiceAndLoadDriver(); 1022 Handler handler = mock(Handler.class); 1023 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1024 InOrder order = inOrder(handler, mWifiScannerImpl); 1025 int requestId = 12; 1026 1027 ScanResults scanResults = createScanResultsForPnoWithNoIE(); 1028 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 1029 createScanSettingsForHwPno(); 1030 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 1031 createPnoSettings(scanResults); 1032 1033 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 1034 expectHwPnoScanWithBackgroundScanWithNoIE(order, handler, requestId, scanSettings.second, 1035 computeSingleScanNativeSettings(scanSettings.first), pnoSettings.second, 1036 scanResults); 1037 1038 ArrayList<ScanResult> sortScanList = 1039 new ArrayList<ScanResult>(Arrays.asList(scanResults.getRawScanResults())); 1040 Collections.sort(sortScanList, WifiScannerImpl.SCAN_RESULT_SORT_COMPARATOR); 1041 verifyPnoNetworkFoundRecieved(order, handler, requestId, 1042 sortScanList.toArray(new ScanResult[sortScanList.size()])); 1043 } 1044 1045 /** 1046 * Tests SW PNO scan. This ensures that the background scan results are plumbed back to the 1047 * client as a PNO network found event. 1048 */ 1049 @Test 1050 public void testSuccessfulSwPnoScan() throws Exception { 1051 startServiceAndLoadDriver(); 1052 Handler handler = mock(Handler.class); 1053 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1054 InOrder order = inOrder(handler, mWifiScannerImpl); 1055 int requestId = 12; 1056 1057 ScanResults scanResults = createScanResultsForPno(); 1058 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 1059 createScanSettingsForSwPno(); 1060 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 1061 createPnoSettings(scanResults); 1062 1063 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 1064 expectSwPnoScan(order, scanSettings.second, scanResults); 1065 verifyPnoNetworkFoundRecieved(order, handler, requestId, scanResults.getRawScanResults()); 1066 } 1067} 1068