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