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