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