WifiScanningServiceTest.java revision c9c91fd93350151a33d87fca768921520c256256
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.app.test.MockAnswerUtil.AnswerWithArguments; 26import android.app.test.TestAlarmManager; 27import android.content.BroadcastReceiver; 28import android.content.Context; 29import android.content.Intent; 30import android.content.IntentFilter; 31import android.net.wifi.ScanResult; 32import android.net.wifi.WifiManager; 33import android.net.wifi.WifiScanner; 34import android.os.Binder; 35import android.os.Bundle; 36import android.os.Handler; 37import android.os.Looper; 38import android.os.Message; 39import android.os.RemoteException; 40import android.os.UserHandle; 41import android.os.WorkSource; 42import android.os.test.TestLooper; 43import android.test.suitebuilder.annotation.SmallTest; 44import android.util.Pair; 45 46import com.android.internal.app.IBatteryStats; 47import com.android.internal.util.AsyncChannel; 48import com.android.internal.util.Protocol; 49import com.android.internal.util.test.BidirectionalAsyncChannel; 50import com.android.server.wifi.Clock; 51import com.android.server.wifi.ScanResults; 52import com.android.server.wifi.TestUtil; 53import com.android.server.wifi.WifiInjector; 54import com.android.server.wifi.WifiMetrics; 55import com.android.server.wifi.WifiMetricsProto; 56import com.android.server.wifi.WifiNative; 57 58import org.junit.After; 59import org.junit.Before; 60import org.junit.Test; 61import org.mockito.ArgumentCaptor; 62import org.mockito.InOrder; 63import org.mockito.Mock; 64import org.mockito.MockitoAnnotations; 65import org.mockito.internal.matchers.CapturingMatcher; 66 67import java.io.FileDescriptor; 68import java.io.PrintWriter; 69import java.io.StringWriter; 70import java.util.ArrayList; 71import java.util.Arrays; 72import java.util.Collections; 73import java.util.List; 74import java.util.regex.Pattern; 75 76/** 77 * Unit tests for {@link com.android.server.wifi.scanner.WifiScanningServiceImpl}. 78 */ 79@SmallTest 80public class WifiScanningServiceTest { 81 public static final String TAG = "WifiScanningServiceTest"; 82 83 @Mock Context mContext; 84 TestAlarmManager mAlarmManager; 85 @Mock WifiScannerImpl mWifiScannerImpl; 86 @Mock WifiScannerImpl.WifiScannerImplFactory mWifiScannerImplFactory; 87 @Mock IBatteryStats mBatteryStats; 88 @Mock WifiInjector mWifiInjector; 89 @Mock Clock mClock; 90 WifiMetrics mWifiMetrics; 91 TestLooper mLooper; 92 WifiScanningServiceImpl mWifiScanningServiceImpl; 93 94 95 @Before 96 public void setUp() throws Exception { 97 MockitoAnnotations.initMocks(this); 98 99 mAlarmManager = new TestAlarmManager(); 100 when(mContext.getSystemService(Context.ALARM_SERVICE)) 101 .thenReturn(mAlarmManager.getAlarmManager()); 102 mWifiMetrics = new WifiMetrics(mClock); 103 104 ChannelHelper channelHelper = new PresetKnownBandsChannelHelper( 105 new int[]{2400, 2450}, 106 new int[]{5150, 5175}, 107 new int[]{5600, 5650, 5660}); 108 109 mLooper = new TestLooper(); 110 when(mWifiScannerImplFactory 111 .create(any(Context.class), any(Looper.class), any(Clock.class))) 112 .thenReturn(mWifiScannerImpl); 113 when(mWifiScannerImpl.getChannelHelper()).thenReturn(channelHelper); 114 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 115 mWifiScanningServiceImpl = new WifiScanningServiceImpl(mContext, mLooper.getLooper(), 116 mWifiScannerImplFactory, mBatteryStats, mWifiInjector); 117 } 118 119 @After 120 public void cleanup() { 121 validateMockitoUsage(); 122 } 123 124 /** 125 * Internal BroadcastReceiver that WifiScanningServiceImpl uses to listen for broadcasts 126 * this is initialized by calling startServiceAndLoadDriver 127 */ 128 BroadcastReceiver mBroadcastReceiver; 129 130 private WifiScanner.ScanSettings generateValidScanSettings() { 131 return createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20, 132 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 133 } 134 135 private BidirectionalAsyncChannel connectChannel(Handler handler) { 136 BidirectionalAsyncChannel controlChannel = new BidirectionalAsyncChannel(); 137 controlChannel.connect(mLooper.getLooper(), mWifiScanningServiceImpl.getMessenger(), 138 handler); 139 mLooper.dispatchAll(); 140 controlChannel.assertConnected(); 141 return controlChannel; 142 } 143 144 private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler) { 145 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 146 order.verify(handler).handleMessage(messageCaptor.capture()); 147 return messageCaptor.getValue(); 148 } 149 150 private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler, 151 final int what) { 152 CapturingMatcher<Message> messageMatcher = new CapturingMatcher<Message>() { 153 public boolean matches(Object argument) { 154 Message message = (Message) argument; 155 return message.what == what; 156 } 157 }; 158 order.verify(handler).handleMessage(argThat(messageMatcher)); 159 return messageMatcher.getLastValue(); 160 } 161 162 private static void verifyScanResultsReceived(InOrder order, Handler handler, int listenerId, 163 WifiScanner.ScanData... expected) { 164 Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler, 165 WifiScanner.CMD_SCAN_RESULT); 166 assertScanResultsMessage(listenerId, expected, scanResultMessage); 167 } 168 169 private static void assertScanResultsMessage(int listenerId, WifiScanner.ScanData[] expected, 170 Message scanResultMessage) { 171 assertEquals("what", WifiScanner.CMD_SCAN_RESULT, scanResultMessage.what); 172 assertEquals("listenerId", listenerId, scanResultMessage.arg2); 173 assertScanDatasEquals(expected, 174 ((WifiScanner.ParcelableScanData) scanResultMessage.obj).getResults()); 175 } 176 177 private static void verifySingleScanCompletedReceived(InOrder order, Handler handler, 178 int listenerId) { 179 Message completedMessage = verifyHandleMessageAndGetMessage(order, handler, 180 WifiScanner.CMD_SINGLE_SCAN_COMPLETED); 181 assertSingleScanCompletedMessage(listenerId, completedMessage); 182 } 183 184 private static void assertSingleScanCompletedMessage(int listenerId, Message completedMessage) { 185 assertEquals("what", WifiScanner.CMD_SINGLE_SCAN_COMPLETED, completedMessage.what); 186 assertEquals("listenerId", listenerId, completedMessage.arg2); 187 } 188 189 private static void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel, 190 int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) { 191 Bundle scanParams = new Bundle(); 192 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings); 193 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource); 194 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0, 195 scanRequestId, scanParams)); 196 } 197 198 private static void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel, 199 int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) { 200 Bundle scanParams = new Bundle(); 201 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings); 202 scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource); 203 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_SINGLE_SCAN, 0, 204 scanRequestId, scanParams)); 205 } 206 207 private static void registerScanListener(BidirectionalAsyncChannel controlChannel, 208 int listenerRequestId) { 209 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_REGISTER_SCAN_LISTENER, 0, 210 listenerRequestId, null)); 211 } 212 213 private static void deregisterScanListener(BidirectionalAsyncChannel controlChannel, 214 int listenerRequestId) { 215 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_DEREGISTER_SCAN_LISTENER, 0, 216 listenerRequestId, null)); 217 } 218 219 private static void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) { 220 Message response = verifyHandleMessageAndGetMessage(order, handler); 221 assertSuccessfulResponse(arg2, response); 222 } 223 224 private static void assertSuccessfulResponse(int arg2, Message response) { 225 if (response.what == WifiScanner.CMD_OP_FAILED) { 226 WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj; 227 fail("response indicates failure, reason=" + result.reason 228 + ", description=" + result.description); 229 } else { 230 assertEquals("response.what", WifiScanner.CMD_OP_SUCCEEDED, response.what); 231 assertEquals("response.arg2", arg2, response.arg2); 232 } 233 } 234 235 /** 236 * If multiple results are expected for a single hardware scan then the order that they are 237 * dispatched is dependant on the order which they are iterated through internally. This 238 * function validates that the order is either one way or the other. A scan listener can 239 * optionally be provided as well and will be checked after the after the single scan requests. 240 */ 241 private static void verifyMultipleSingleScanResults(InOrder handlerOrder, Handler handler, 242 int requestId1, ScanResults results1, int requestId2, ScanResults results2, 243 int listenerRequestId, ScanResults listenerResults) { 244 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 245 handlerOrder.verify(handler, times(listenerResults == null ? 4 : 5)) 246 .handleMessage(messageCaptor.capture()); 247 int firstListenerId = messageCaptor.getAllValues().get(0).arg2; 248 assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId1, 249 firstListenerId == requestId2 || firstListenerId == requestId1); 250 if (firstListenerId == requestId2) { 251 assertScanResultsMessage(requestId2, 252 new WifiScanner.ScanData[] {results2.getScanData()}, 253 messageCaptor.getAllValues().get(0)); 254 assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(1)); 255 assertScanResultsMessage(requestId1, 256 new WifiScanner.ScanData[] {results1.getScanData()}, 257 messageCaptor.getAllValues().get(2)); 258 assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(3)); 259 if (listenerResults != null) { 260 assertScanResultsMessage(listenerRequestId, 261 new WifiScanner.ScanData[] {listenerResults.getScanData()}, 262 messageCaptor.getAllValues().get(4)); 263 } 264 } else { 265 assertScanResultsMessage(requestId1, 266 new WifiScanner.ScanData[] {results1.getScanData()}, 267 messageCaptor.getAllValues().get(0)); 268 assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(1)); 269 assertScanResultsMessage(requestId2, 270 new WifiScanner.ScanData[] {results2.getScanData()}, 271 messageCaptor.getAllValues().get(2)); 272 assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(3)); 273 if (listenerResults != null) { 274 assertScanResultsMessage(listenerRequestId, 275 new WifiScanner.ScanData[] {listenerResults.getScanData()}, 276 messageCaptor.getAllValues().get(4)); 277 } 278 } 279 } 280 281 private static void verifyMultipleSingleScanResults(InOrder handlerOrder, Handler handler, 282 int requestId1, ScanResults results1, int requestId2, ScanResults results2) { 283 verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId2, 284 results2, -1, null); 285 } 286 287 private static void verifyFailedResponse(InOrder order, Handler handler, int arg2, 288 int expectedErrorReason, String expectedErrorDescription) { 289 Message response = verifyHandleMessageAndGetMessage(order, handler); 290 assertFailedResponse(arg2, expectedErrorReason, expectedErrorDescription, response); 291 } 292 293 private static void assertFailedResponse(int arg2, int expectedErrorReason, 294 String expectedErrorDescription, Message response) { 295 if (response.what == WifiScanner.CMD_OP_SUCCEEDED) { 296 fail("response indicates success"); 297 } else { 298 assertEquals("response.what", WifiScanner.CMD_OP_FAILED, response.what); 299 assertEquals("response.arg2", arg2, response.arg2); 300 WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj; 301 assertEquals("response.obj.reason", 302 expectedErrorReason, result.reason); 303 assertEquals("response.obj.description", 304 expectedErrorDescription, result.description); 305 } 306 } 307 308 private WifiNative.ScanEventHandler verifyStartSingleScan(InOrder order, 309 WifiNative.ScanSettings expected) { 310 ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor = 311 ArgumentCaptor.forClass(WifiNative.ScanSettings.class); 312 ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor = 313 ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class); 314 order.verify(mWifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(), 315 scanEventHandlerCaptor.capture()); 316 assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue()); 317 return scanEventHandlerCaptor.getValue(); 318 } 319 320 private WifiNative.ScanEventHandler verifyStartBackgroundScan(InOrder order, 321 WifiNative.ScanSettings expected) { 322 ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor = 323 ArgumentCaptor.forClass(WifiNative.ScanSettings.class); 324 ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor = 325 ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class); 326 order.verify(mWifiScannerImpl).startBatchedScan(scanSettingsCaptor.capture(), 327 scanEventHandlerCaptor.capture()); 328 assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue()); 329 return scanEventHandlerCaptor.getValue(); 330 } 331 332 private static final int MAX_AP_PER_SCAN = 16; 333 private void startServiceAndLoadDriver() { 334 mWifiScanningServiceImpl.startService(); 335 setupAndLoadDriver(); 336 } 337 338 private void setupAndLoadDriver() { 339 when(mWifiScannerImpl.getScanCapabilities(any(WifiNative.ScanCapabilities.class))) 340 .thenAnswer(new AnswerWithArguments() { 341 public boolean answer(WifiNative.ScanCapabilities capabilities) { 342 capabilities.max_scan_cache_size = Integer.MAX_VALUE; 343 capabilities.max_scan_buckets = 8; 344 capabilities.max_ap_cache_per_scan = MAX_AP_PER_SCAN; 345 capabilities.max_rssi_sample_size = 8; 346 capabilities.max_scan_reporting_threshold = 10; 347 capabilities.max_hotlist_bssids = 0; 348 capabilities.max_significant_wifi_change_aps = 0; 349 return true; 350 } 351 }); 352 ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = 353 ArgumentCaptor.forClass(BroadcastReceiver.class); 354 verify(mContext) 355 .registerReceiver(broadcastReceiverCaptor.capture(), any(IntentFilter.class)); 356 mBroadcastReceiver = broadcastReceiverCaptor.getValue(); 357 TestUtil.sendWifiScanAvailable(broadcastReceiverCaptor.getValue(), mContext, 358 WifiManager.WIFI_STATE_ENABLED); 359 mLooper.dispatchAll(); 360 } 361 362 private String dumpService() { 363 StringWriter stringWriter = new StringWriter(); 364 mWifiScanningServiceImpl.dump(new FileDescriptor(), new PrintWriter(stringWriter), 365 new String[0]); 366 return stringWriter.toString(); 367 } 368 369 private void assertDumpContainsRequestLog(String type, int id) { 370 String serviceDump = dumpService(); 371 Pattern logLineRegex = Pattern.compile("^.+" + type 372 + ": ClientInfo\\[uid=\\d+,android\\.os\\.Messenger@[a-f0-9]+\\],Id=" + id 373 + ".*$", Pattern.MULTILINE); 374 assertTrue("dump did not contain log with type=" + type + ", id=" + id + 375 ": " + serviceDump + "\n", 376 logLineRegex.matcher(serviceDump).find()); 377 } 378 379 private void assertDumpContainsCallbackLog(String callback, int id, String extra) { 380 String serviceDump = dumpService(); 381 String extraPattern = extra == null ? "" : "," + extra; 382 Pattern logLineRegex = Pattern.compile("^.+" + callback 383 + ": ClientInfo\\[uid=\\d+,android\\.os\\.Messenger@[a-f0-9]+\\],Id=" + id 384 + extraPattern + "$", Pattern.MULTILINE); 385 assertTrue("dump did not contain callback log with callback=" + callback + ", id=" + id + 386 ", extra=" + extra + ": " + serviceDump + "\n", 387 logLineRegex.matcher(serviceDump).find()); 388 } 389 390 @Test 391 public void construct() throws Exception { 392 verifyNoMoreInteractions(mWifiScannerImpl, mWifiScannerImpl, 393 mWifiScannerImplFactory, mBatteryStats); 394 dumpService(); // make sure this succeeds 395 } 396 397 @Test 398 public void startService() throws Exception { 399 mWifiScanningServiceImpl.startService(); 400 verifyNoMoreInteractions(mWifiScannerImplFactory); 401 402 Handler handler = mock(Handler.class); 403 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 404 InOrder order = inOrder(handler); 405 sendBackgroundScanRequest(controlChannel, 122, generateValidScanSettings(), null); 406 mLooper.dispatchAll(); 407 verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available"); 408 } 409 410 @Test 411 public void disconnectClientBeforeWifiEnabled() throws Exception { 412 mWifiScanningServiceImpl.startService(); 413 414 BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class)); 415 mLooper.dispatchAll(); 416 417 controlChannel.disconnect(); 418 mLooper.dispatchAll(); 419 } 420 421 @Test 422 public void loadDriver() throws Exception { 423 startServiceAndLoadDriver(); 424 verify(mWifiScannerImplFactory, times(1)) 425 .create(any(Context.class), any(Looper.class), any(Clock.class)); 426 427 Handler handler = mock(Handler.class); 428 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 429 InOrder order = inOrder(handler); 430 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 431 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 432 sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings(), null); 433 mLooper.dispatchAll(); 434 verifySuccessfulResponse(order, handler, 192); 435 assertDumpContainsRequestLog("addBackgroundScanRequest", 192); 436 } 437 438 @Test 439 public void disconnectClientAfterStartingWifi() throws Exception { 440 mWifiScanningServiceImpl.startService(); 441 442 BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class)); 443 mLooper.dispatchAll(); 444 445 setupAndLoadDriver(); 446 447 controlChannel.disconnect(); 448 mLooper.dispatchAll(); 449 } 450 451 @Test 452 public void connectAndDisconnectClientAfterStartingWifi() throws Exception { 453 startServiceAndLoadDriver(); 454 455 BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class)); 456 mLooper.dispatchAll(); 457 controlChannel.disconnect(); 458 mLooper.dispatchAll(); 459 } 460 461 @Test 462 public void sendInvalidCommand() throws Exception { 463 startServiceAndLoadDriver(); 464 465 Handler handler = mock(Handler.class); 466 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 467 InOrder order = inOrder(handler, mWifiScannerImpl); 468 controlChannel.sendMessage(Message.obtain(null, Protocol.BASE_WIFI_MANAGER)); 469 mLooper.dispatchAll(); 470 verifyFailedResponse(order, handler, 0, WifiScanner.REASON_INVALID_REQUEST, 471 "Invalid request"); 472 } 473 474 private void doSuccessfulSingleScan(WifiScanner.ScanSettings requestSettings, 475 WifiNative.ScanSettings nativeSettings, ScanResults results) throws RemoteException { 476 int requestId = 12; 477 WorkSource workSource = new WorkSource(2292); 478 startServiceAndLoadDriver(); 479 480 Handler handler = mock(Handler.class); 481 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 482 InOrder order = inOrder(handler, mWifiScannerImpl); 483 484 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 485 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 486 487 sendSingleScanRequest(controlChannel, requestId, requestSettings, workSource); 488 489 mLooper.dispatchAll(); 490 WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings); 491 verifySuccessfulResponse(order, handler, requestId); 492 verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource)); 493 494 when(mWifiScannerImpl.getLatestSingleScanResults()) 495 .thenReturn(results.getRawScanData()); 496 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 497 498 mLooper.dispatchAll(); 499 verifyScanResultsReceived(order, handler, requestId, results.getScanData()); 500 verifySingleScanCompletedReceived(order, handler, requestId); 501 verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 502 verifyNoMoreInteractions(handler); 503 verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource)); 504 assertDumpContainsRequestLog("addSingleScanRequest", requestId); 505 assertDumpContainsCallbackLog("singleScanResults", requestId, 506 "results=" + results.getScanData().getResults().length); 507 } 508 509 /** 510 * Do a single scan for a band and verify that it is successful. 511 */ 512 @Test 513 public void sendSingleScanBandRequest() throws Exception { 514 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 515 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 516 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 517 ScanResults.create(0, true, 2400, 5150, 5175)); 518 } 519 520 /** 521 * Do a single scan for a list of channels and verify that it is successful. 522 */ 523 @Test 524 public void sendSingleScanChannelsRequest() throws Exception { 525 WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400, 5150, 5175), 526 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 527 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 528 ScanResults.create(0, 2400, 5150, 5175)); 529 } 530 531 /** 532 * Do a single scan for a list of all channels and verify that it is successful. 533 */ 534 @Test 535 public void sendSingleScanAllChannelsRequest() throws Exception { 536 WifiScanner.ScanSettings requestSettings = createRequest( 537 channelsToSpec(2400, 2450, 5150, 5175, 5600, 5650, 5660), 538 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 539 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 540 ScanResults.create(0, true, 2400, 5150, 5175)); 541 } 542 543 /** 544 * Do a single scan with no results and verify that it is successful. 545 */ 546 @Test 547 public void sendSingleScanRequestWithNoResults() throws Exception { 548 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 549 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 550 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 551 ScanResults.create(0, new int[0])); 552 } 553 554 /** 555 * Do a single scan with results that do not match the requested scan and verify that it is 556 * still successful (and returns no results). 557 */ 558 @Test 559 public void sendSingleScanRequestWithBadRawResults() throws Exception { 560 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0, 561 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 562 // Create a set of scan results that has results not matching the request settings, but is 563 // limited to zero results for the expected results. 564 ScanResults results = ScanResults.createOverflowing(0, 0, 565 ScanResults.generateNativeResults(0, 5150, 5171)); 566 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 567 results); 568 } 569 570 /** 571 * Do a single scan, which the hardware fails to start, and verify that a failure response is 572 * delivered. 573 */ 574 @Test 575 public void sendSingleScanRequestWhichFailsToStart() throws Exception { 576 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 577 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 578 int requestId = 33; 579 580 startServiceAndLoadDriver(); 581 582 Handler handler = mock(Handler.class); 583 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 584 InOrder order = inOrder(handler, mWifiScannerImpl); 585 586 // scan fails 587 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 588 any(WifiNative.ScanEventHandler.class))).thenReturn(false); 589 590 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 591 592 mLooper.dispatchAll(); 593 // Scan is successfully queue, but then fails to execute 594 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 595 order.verify(handler, times(2)).handleMessage(messageCaptor.capture()); 596 assertSuccessfulResponse(requestId, messageCaptor.getAllValues().get(0)); 597 assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED, 598 "Failed to start single scan", messageCaptor.getAllValues().get(1)); 599 verifyNoMoreInteractions(mBatteryStats); 600 601 assertEquals(mWifiMetrics.getOneshotScanCount(), 1); 602 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1); 603 assertDumpContainsRequestLog("addSingleScanRequest", requestId); 604 } 605 606 /** 607 * Do a single scan, which successfully starts, but fails partway through and verify that a 608 * failure response is delivered. 609 */ 610 @Test 611 public void sendSingleScanRequestWhichFailsAfterStart() throws Exception { 612 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 613 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 614 int requestId = 33; 615 WorkSource workSource = new WorkSource(Binder.getCallingUid()); // don't explicitly set 616 617 startServiceAndLoadDriver(); 618 619 Handler handler = mock(Handler.class); 620 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 621 InOrder order = inOrder(handler, mWifiScannerImpl); 622 623 // successful start 624 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 625 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 626 627 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 628 629 // Scan is successfully queue 630 mLooper.dispatchAll(); 631 WifiNative.ScanEventHandler eventHandler = 632 verifyStartSingleScan(order, computeSingleScanNativeSettings(requestSettings)); 633 verifySuccessfulResponse(order, handler, requestId); 634 verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource)); 635 636 // but then fails to execute 637 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_FAILED); 638 mLooper.dispatchAll(); 639 verifyFailedResponse(order, handler, requestId, 640 WifiScanner.REASON_UNSPECIFIED, "Scan failed"); 641 assertDumpContainsCallbackLog("singleScanFailed", requestId, 642 "reason=" + WifiScanner.REASON_UNSPECIFIED + ", Scan failed"); 643 assertEquals(mWifiMetrics.getOneshotScanCount(), 1); 644 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1); 645 verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource)); 646 verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 647 } 648 649 /** 650 * Send a single scan request and then disable Wi-Fi before it completes 651 */ 652 @Test 653 public void sendSingleScanRequestThenDisableWifi() { 654 WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400), 0, 655 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 656 int requestId = 2293; 657 658 startServiceAndLoadDriver(); 659 660 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 661 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 662 663 Handler handler = mock(Handler.class); 664 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 665 InOrder order = inOrder(handler, mWifiScannerImpl); 666 667 // Run scan 1 668 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 669 mLooper.dispatchAll(); 670 verifySuccessfulResponse(order, handler, requestId); 671 672 // disable wifi 673 TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext, 674 WifiManager.WIFI_STATE_DISABLED); 675 676 // validate failed response 677 mLooper.dispatchAll(); 678 verifyFailedResponse(order, handler, requestId, WifiScanner.REASON_UNSPECIFIED, 679 "Scan was interrupted"); 680 verifyNoMoreInteractions(handler); 681 } 682 683 /** 684 * Send a single scan request, schedule a second pending scan and disable Wi-Fi before the first 685 * scan completes. 686 */ 687 @Test 688 public void sendSingleScanAndPendingScanAndListenerThenDisableWifi() { 689 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 690 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 691 int requestId1 = 2293; 692 693 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450), 0, 694 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 695 int requestId2 = 2294; 696 697 int listenerRequestId = 2295; 698 699 startServiceAndLoadDriver(); 700 701 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 702 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 703 704 Handler handler = mock(Handler.class); 705 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 706 InOrder order = inOrder(handler, mWifiScannerImpl); 707 708 // Request scan 1 709 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 710 mLooper.dispatchAll(); 711 verifySuccessfulResponse(order, handler, requestId1); 712 713 // Request scan 2 714 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 715 mLooper.dispatchAll(); 716 verifySuccessfulResponse(order, handler, requestId2); 717 718 // Setup scan listener 719 registerScanListener(controlChannel, listenerRequestId); 720 mLooper.dispatchAll(); 721 verifySuccessfulResponse(order, handler, listenerRequestId); 722 723 // disable wifi 724 TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext, 725 WifiManager.WIFI_STATE_DISABLED); 726 727 // validate failed response 728 mLooper.dispatchAll(); 729 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 730 order.verify(handler, times(2)).handleMessage(messageCaptor.capture()); 731 assertFailedResponse(requestId1, WifiScanner.REASON_UNSPECIFIED, 732 "Scan was interrupted", messageCaptor.getAllValues().get(0)); 733 assertFailedResponse(requestId2, WifiScanner.REASON_UNSPECIFIED, 734 "Scan was interrupted", messageCaptor.getAllValues().get(1)); 735 // No additional callbacks for scan listener 736 verifyNoMoreInteractions(handler); 737 } 738 739 /** 740 * Send a single scan request and then a second one after the first completes. 741 */ 742 @Test 743 public void sendSingleScanRequestAfterPreviousCompletes() { 744 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 745 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 746 int requestId1 = 12; 747 ScanResults results1 = ScanResults.create(0, 2400); 748 749 750 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 751 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 752 int requestId2 = 13; 753 ScanResults results2 = ScanResults.create(0, 2450); 754 755 756 startServiceAndLoadDriver(); 757 758 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 759 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 760 761 Handler handler = mock(Handler.class); 762 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 763 InOrder order = inOrder(handler, mWifiScannerImpl, mContext); 764 765 // Run scan 1 766 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 767 768 mLooper.dispatchAll(); 769 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order, 770 computeSingleScanNativeSettings(requestSettings1)); 771 verifySuccessfulResponse(order, handler, requestId1); 772 773 // dispatch scan 1 results 774 when(mWifiScannerImpl.getLatestSingleScanResults()) 775 .thenReturn(results1.getScanData()); 776 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 777 778 mLooper.dispatchAll(); 779 // Note: The order of the following verification calls looks out of order if you compare to 780 // the source code of WifiScanningServiceImpl WifiSingleScanStateMachine.reportScanResults. 781 // This is due to the fact that verifyScanResultsReceived and 782 // verifySingleScanCompletedReceived require an additional call to handle the message that 783 // is created in reportScanResults. This handling is done in the two verify*Received calls 784 // that is run AFTER the reportScanResults method in WifiScanningServiceImpl completes. 785 order.verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 786 verifyScanResultsReceived(order, handler, requestId1, results1.getScanData()); 787 verifySingleScanCompletedReceived(order, handler, requestId1); 788 789 // Run scan 2 790 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 791 792 mLooper.dispatchAll(); 793 WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order, 794 computeSingleScanNativeSettings(requestSettings2)); 795 verifySuccessfulResponse(order, handler, requestId2); 796 797 // dispatch scan 2 results 798 when(mWifiScannerImpl.getLatestSingleScanResults()) 799 .thenReturn(results2.getScanData()); 800 eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 801 802 mLooper.dispatchAll(); 803 order.verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 804 verifyScanResultsReceived(order, handler, requestId2, results2.getScanData()); 805 verifySingleScanCompletedReceived(order, handler, requestId2); 806 } 807 808 /** 809 * Send a single scan request and then a second one not satisfied by the first before the first 810 * completes. Verify that both are scheduled and succeed. 811 */ 812 @Test 813 public void sendSingleScanRequestWhilePreviousScanRunning() { 814 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 815 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 816 int requestId1 = 12; 817 ScanResults results1 = ScanResults.create(0, 2400); 818 819 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 820 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 821 int requestId2 = 13; 822 ScanResults results2 = ScanResults.create(0, 2450); 823 824 825 startServiceAndLoadDriver(); 826 827 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 828 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 829 830 Handler handler = mock(Handler.class); 831 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 832 InOrder handlerOrder = inOrder(handler); 833 InOrder nativeOrder = inOrder(mWifiScannerImpl); 834 835 // Run scan 1 836 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 837 838 mLooper.dispatchAll(); 839 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, 840 computeSingleScanNativeSettings(requestSettings1)); 841 verifySuccessfulResponse(handlerOrder, handler, requestId1); 842 843 // Queue scan 2 (will not run because previous is in progress) 844 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 845 mLooper.dispatchAll(); 846 verifySuccessfulResponse(handlerOrder, handler, requestId2); 847 848 // dispatch scan 1 results 849 when(mWifiScannerImpl.getLatestSingleScanResults()) 850 .thenReturn(results1.getScanData()); 851 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 852 853 mLooper.dispatchAll(); 854 verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData()); 855 verifySingleScanCompletedReceived(handlerOrder, handler, requestId1); 856 verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 857 858 // now that the first scan completed we expect the second one to start 859 WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder, 860 computeSingleScanNativeSettings(requestSettings2)); 861 862 // dispatch scan 2 results 863 when(mWifiScannerImpl.getLatestSingleScanResults()) 864 .thenReturn(results2.getScanData()); 865 eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 866 867 mLooper.dispatchAll(); 868 verifyScanResultsReceived(handlerOrder, handler, requestId2, results2.getScanData()); 869 verifySingleScanCompletedReceived(handlerOrder, handler, requestId2); 870 verify(mContext, times(2)).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 871 assertEquals(mWifiMetrics.getOneshotScanCount(), 2); 872 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2); 873 } 874 875 876 /** 877 * Send a single scan request and then two more before the first completes. Neither are 878 * satisfied by the first scan. Verify that the first completes and the second two are merged. 879 */ 880 @Test 881 public void sendMultipleSingleScanRequestWhilePreviousScanRunning() throws RemoteException { 882 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 883 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 884 int requestId1 = 12; 885 WorkSource workSource1 = new WorkSource(1121); 886 ScanResults results1 = ScanResults.create(0, 2400); 887 888 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 889 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 890 int requestId2 = 13; 891 WorkSource workSource2 = new WorkSource(Binder.getCallingUid()); // don't explicitly set 892 ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450); 893 894 WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0, 895 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 896 int requestId3 = 15; 897 WorkSource workSource3 = new WorkSource(2292); 898 ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150); 899 900 WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels( 901 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150)); 902 ScanResults results2and3 = ScanResults.merge(results2, results3); 903 WorkSource workSource2and3 = new WorkSource(); 904 workSource2and3.add(workSource2); 905 workSource2and3.add(workSource3); 906 907 908 startServiceAndLoadDriver(); 909 910 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 911 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 912 913 Handler handler = mock(Handler.class); 914 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 915 InOrder handlerOrder = inOrder(handler); 916 InOrder nativeOrder = inOrder(mWifiScannerImpl); 917 918 // Run scan 1 919 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1); 920 921 mLooper.dispatchAll(); 922 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, 923 computeSingleScanNativeSettings(requestSettings1)); 924 verifySuccessfulResponse(handlerOrder, handler, requestId1); 925 verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource1)); 926 927 928 // Queue scan 2 (will not run because previous is in progress) 929 // uses uid of calling process 930 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 931 mLooper.dispatchAll(); 932 verifySuccessfulResponse(handlerOrder, handler, requestId2); 933 934 // Queue scan 3 (will not run because previous is in progress) 935 sendSingleScanRequest(controlChannel, requestId3, requestSettings3, workSource3); 936 mLooper.dispatchAll(); 937 verifySuccessfulResponse(handlerOrder, handler, requestId3); 938 939 // dispatch scan 1 results 940 when(mWifiScannerImpl.getLatestSingleScanResults()) 941 .thenReturn(results1.getScanData()); 942 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 943 944 mLooper.dispatchAll(); 945 verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData()); 946 verifySingleScanCompletedReceived(handlerOrder, handler, requestId1); 947 verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 948 verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource1)); 949 verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource2and3)); 950 951 // now that the first scan completed we expect the second and third ones to start 952 WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder, 953 nativeSettings2and3); 954 955 // dispatch scan 2 and 3 results 956 when(mWifiScannerImpl.getLatestSingleScanResults()) 957 .thenReturn(results2and3.getScanData()); 958 eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 959 960 mLooper.dispatchAll(); 961 962 verifyMultipleSingleScanResults(handlerOrder, handler, requestId2, results2, requestId3, 963 results3); 964 assertEquals(mWifiMetrics.getOneshotScanCount(), 3); 965 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3); 966 967 verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource2and3)); 968 969 assertDumpContainsRequestLog("addSingleScanRequest", requestId1); 970 assertDumpContainsRequestLog("addSingleScanRequest", requestId2); 971 assertDumpContainsRequestLog("addSingleScanRequest", requestId3); 972 assertDumpContainsCallbackLog("singleScanResults", requestId1, 973 "results=" + results1.getRawScanResults().length); 974 assertDumpContainsCallbackLog("singleScanResults", requestId2, 975 "results=" + results2.getRawScanResults().length); 976 assertDumpContainsCallbackLog("singleScanResults", requestId3, 977 "results=" + results3.getRawScanResults().length); 978 } 979 980 981 /** 982 * Send a single scan request and then a second one satisfied by the first before the first 983 * completes. Verify that only one scan is scheduled. 984 */ 985 @Test 986 public void sendSingleScanRequestWhilePreviousScanRunningAndMergeIntoFirstScan() { 987 // Split by frequency to make it easier to determine which results each request is expecting 988 ScanResults results24GHz = ScanResults.create(0, 2400, 2400, 2400, 2450); 989 ScanResults results5GHz = ScanResults.create(0, 5150, 5150, 5175); 990 ScanResults resultsBoth = ScanResults.merge(results24GHz, results5GHz); 991 992 WifiScanner.ScanSettings requestSettings1 = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 993 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 994 int requestId1 = 12; 995 ScanResults results1 = resultsBoth; 996 997 WifiScanner.ScanSettings requestSettings2 = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0, 998 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 999 int requestId2 = 13; 1000 ScanResults results2 = results24GHz; 1001 1002 1003 startServiceAndLoadDriver(); 1004 1005 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 1006 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1007 1008 Handler handler = mock(Handler.class); 1009 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1010 InOrder handlerOrder = inOrder(handler); 1011 InOrder nativeOrder = inOrder(mWifiScannerImpl); 1012 1013 // Run scan 1 1014 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 1015 1016 mLooper.dispatchAll(); 1017 WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(nativeOrder, 1018 computeSingleScanNativeSettings(requestSettings1)); 1019 verifySuccessfulResponse(handlerOrder, handler, requestId1); 1020 1021 // Queue scan 2 (will be folded into ongoing scan) 1022 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 1023 mLooper.dispatchAll(); 1024 verifySuccessfulResponse(handlerOrder, handler, requestId2); 1025 1026 // dispatch scan 1 results 1027 when(mWifiScannerImpl.getLatestSingleScanResults()) 1028 .thenReturn(resultsBoth.getScanData()); 1029 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1030 1031 mLooper.dispatchAll(); 1032 verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId2, 1033 results2); 1034 1035 assertEquals(mWifiMetrics.getOneshotScanCount(), 2); 1036 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2); 1037 } 1038 1039 /** 1040 * Send a single scan request and then two more before the first completes, one of which is 1041 * satisfied by the first scan. Verify that the first two complete together the second scan is 1042 * just for the other scan. 1043 */ 1044 @Test 1045 public void sendMultipleSingleScanRequestWhilePreviousScanRunningAndMergeOneIntoFirstScan() 1046 throws RemoteException { 1047 // Split by frequency to make it easier to determine which results each request is expecting 1048 ScanResults results2400 = ScanResults.create(0, 2400, 2400, 2400); 1049 ScanResults results2450 = ScanResults.create(0, 2450); 1050 ScanResults results1and3 = ScanResults.merge(results2400, results2450); 1051 1052 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400, 2450), 0, 1053 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1054 int requestId1 = 12; 1055 WorkSource workSource1 = new WorkSource(1121); 1056 ScanResults results1 = results1and3; 1057 1058 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 1059 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1060 int requestId2 = 13; 1061 WorkSource workSource2 = new WorkSource(Binder.getCallingUid()); // don't explicitly set 1062 ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450); 1063 1064 WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(2400), 0, 1065 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1066 int requestId3 = 15; 1067 WorkSource workSource3 = new WorkSource(2292); 1068 ScanResults results3 = results2400; 1069 1070 startServiceAndLoadDriver(); 1071 1072 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 1073 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1074 1075 Handler handler = mock(Handler.class); 1076 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1077 InOrder handlerOrder = inOrder(handler); 1078 InOrder nativeOrder = inOrder(mWifiScannerImpl); 1079 1080 // Run scan 1 1081 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1); 1082 1083 mLooper.dispatchAll(); 1084 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, 1085 computeSingleScanNativeSettings(requestSettings1)); 1086 verifySuccessfulResponse(handlerOrder, handler, requestId1); 1087 verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource1)); 1088 1089 1090 // Queue scan 2 (will not run because previous is in progress) 1091 // uses uid of calling process 1092 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 1093 mLooper.dispatchAll(); 1094 verifySuccessfulResponse(handlerOrder, handler, requestId2); 1095 1096 // Queue scan 3 (will be merged into the active scan) 1097 sendSingleScanRequest(controlChannel, requestId3, requestSettings3, workSource3); 1098 mLooper.dispatchAll(); 1099 verifySuccessfulResponse(handlerOrder, handler, requestId3); 1100 1101 // dispatch scan 1 results 1102 when(mWifiScannerImpl.getLatestSingleScanResults()) 1103 .thenReturn(results1and3.getScanData()); 1104 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1105 1106 mLooper.dispatchAll(); 1107 verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId3, 1108 results3); 1109 // only the requests know at the beginning of the scan get blamed 1110 verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource1)); 1111 verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource2)); 1112 1113 // now that the first scan completed we expect the second and third ones to start 1114 WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder, 1115 computeSingleScanNativeSettings(requestSettings2)); 1116 1117 // dispatch scan 2 and 3 results 1118 when(mWifiScannerImpl.getLatestSingleScanResults()) 1119 .thenReturn(results2.getScanData()); 1120 eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1121 1122 mLooper.dispatchAll(); 1123 1124 verifyScanResultsReceived(handlerOrder, handler, requestId2, results2.getScanData()); 1125 verifySingleScanCompletedReceived(handlerOrder, handler, requestId2); 1126 verify(mContext, times(2)).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 1127 assertEquals(mWifiMetrics.getOneshotScanCount(), 3); 1128 assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3); 1129 1130 verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource2)); 1131 1132 assertDumpContainsRequestLog("addSingleScanRequest", requestId1); 1133 assertDumpContainsRequestLog("addSingleScanRequest", requestId2); 1134 assertDumpContainsRequestLog("addSingleScanRequest", requestId3); 1135 assertDumpContainsCallbackLog("singleScanResults", requestId1, 1136 "results=" + results1.getRawScanResults().length); 1137 assertDumpContainsCallbackLog("singleScanResults", requestId2, 1138 "results=" + results2.getRawScanResults().length); 1139 assertDumpContainsCallbackLog("singleScanResults", requestId3, 1140 "results=" + results3.getRawScanResults().length); 1141 } 1142 1143 /** 1144 * Verify that WifiService provides a way to get the most recent SingleScan results. 1145 */ 1146 @Test 1147 public void retrieveSingleScanResults() throws Exception { 1148 WifiScanner.ScanSettings requestSettings = 1149 createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 1150 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1151 ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175); 1152 doSuccessfulSingleScan(requestSettings, 1153 computeSingleScanNativeSettings(requestSettings), 1154 expectedResults); 1155 Handler handler = mock(Handler.class); 1156 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1157 InOrder order = inOrder(handler, mWifiScannerImpl); 1158 1159 controlChannel.sendMessage( 1160 Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0)); 1161 mLooper.dispatchAll(); 1162 Message response = verifyHandleMessageAndGetMessage(order, handler); 1163 List<ScanResult> results = Arrays.asList( 1164 ((WifiScanner.ParcelableScanResults) response.obj).getResults()); 1165 assertEquals(results.size(), expectedResults.getRawScanResults().length); 1166 } 1167 1168 /** 1169 * Verify that WifiService provides a way to get the most recent SingleScan results even when 1170 * they are empty. 1171 */ 1172 @Test 1173 public void retrieveSingleScanResultsEmpty() throws Exception { 1174 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 1175 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1176 doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), 1177 ScanResults.create(0, new int[0])); 1178 1179 Handler handler = mock(Handler.class); 1180 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1181 InOrder order = inOrder(handler, mWifiScannerImpl); 1182 1183 controlChannel.sendMessage( 1184 Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0)); 1185 mLooper.dispatchAll(); 1186 Message response = verifyHandleMessageAndGetMessage(order, handler); 1187 1188 List<ScanResult> results = Arrays.asList( 1189 ((WifiScanner.ParcelableScanResults) response.obj).getResults()); 1190 assertEquals(results.size(), 0); 1191 } 1192 1193 /** 1194 * Verify that WifiService will return empty SingleScan results if a scan has not been 1195 * performed. 1196 */ 1197 @Test 1198 public void retrieveSingleScanResultsBeforeAnySingleScans() throws Exception { 1199 startServiceAndLoadDriver(); 1200 Handler handler = mock(Handler.class); 1201 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1202 InOrder order = inOrder(handler, mWifiScannerImpl); 1203 1204 controlChannel.sendMessage( 1205 Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0)); 1206 mLooper.dispatchAll(); 1207 Message response = verifyHandleMessageAndGetMessage(order, handler); 1208 1209 List<ScanResult> results = Arrays.asList( 1210 ((WifiScanner.ParcelableScanResults) response.obj).getResults()); 1211 assertEquals(results.size(), 0); 1212 } 1213 1214 /** 1215 * Verify that the newest scan results are returned by WifiService.getSingleScanResults. 1216 */ 1217 @Test 1218 public void retrieveMostRecentSingleScanResults() throws Exception { 1219 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 1220 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1221 ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175); 1222 doSuccessfulSingleScan(requestSettings, 1223 computeSingleScanNativeSettings(requestSettings), 1224 expectedResults); 1225 1226 Handler handler = mock(Handler.class); 1227 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1228 InOrder order = inOrder(handler, mWifiScannerImpl); 1229 1230 controlChannel.sendMessage( 1231 Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0)); 1232 mLooper.dispatchAll(); 1233 Message response = verifyHandleMessageAndGetMessage(order, handler); 1234 1235 List<ScanResult> results = Arrays.asList( 1236 ((WifiScanner.ParcelableScanResults) response.obj).getResults()); 1237 assertEquals(results.size(), expectedResults.getRawScanResults().length); 1238 1239 // now update with a new scan that only has one result 1240 int secondScanRequestId = 35; 1241 ScanResults expectedSingleResult = ScanResults.create(0, true, 5150); 1242 sendSingleScanRequest(controlChannel, secondScanRequestId, requestSettings, null); 1243 1244 mLooper.dispatchAll(); 1245 WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, 1246 computeSingleScanNativeSettings(requestSettings)); 1247 verifySuccessfulResponse(order, handler, secondScanRequestId); 1248 1249 // dispatch scan 2 results 1250 when(mWifiScannerImpl.getLatestSingleScanResults()) 1251 .thenReturn(expectedSingleResult.getScanData()); 1252 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1253 1254 mLooper.dispatchAll(); 1255 verifyScanResultsReceived(order, handler, secondScanRequestId, 1256 expectedSingleResult.getScanData()); 1257 verifySingleScanCompletedReceived(order, handler, secondScanRequestId); 1258 1259 controlChannel.sendMessage( 1260 Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0)); 1261 mLooper.dispatchAll(); 1262 Message response2 = verifyHandleMessageAndGetMessage(order, handler); 1263 1264 List<ScanResult> results2 = Arrays.asList( 1265 ((WifiScanner.ParcelableScanResults) response2.obj).getResults()); 1266 assertEquals(results2.size(), expectedSingleResult.getRawScanResults().length); 1267 } 1268 1269 /** 1270 * Cached scan results should be cleared after the driver is unloaded. 1271 */ 1272 @Test 1273 public void validateScanResultsClearedAfterDriverUnloaded() throws Exception { 1274 WifiScanner.ScanSettings requestSettings = 1275 createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 1276 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1277 ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175); 1278 doSuccessfulSingleScan(requestSettings, 1279 computeSingleScanNativeSettings(requestSettings), 1280 expectedResults); 1281 Handler handler = mock(Handler.class); 1282 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1283 InOrder order = inOrder(handler, mWifiScannerImpl); 1284 1285 controlChannel.sendMessage( 1286 Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0)); 1287 mLooper.dispatchAll(); 1288 Message response = verifyHandleMessageAndGetMessage(order, handler); 1289 List<ScanResult> results = Arrays.asList( 1290 ((WifiScanner.ParcelableScanResults) response.obj).getResults()); 1291 assertEquals(results.size(), expectedResults.getRawScanResults().length); 1292 1293 // disable wifi 1294 TestUtil.sendWifiScanAvailable(mBroadcastReceiver, 1295 mContext, 1296 WifiManager.WIFI_STATE_DISABLED); 1297 // Now get scan results again. The returned list should be empty since we 1298 // clear the cache when exiting the DriverLoaded state. 1299 controlChannel.sendMessage( 1300 Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0)); 1301 mLooper.dispatchAll(); 1302 Message response2 = verifyHandleMessageAndGetMessage(order, handler); 1303 List<ScanResult> results2 = Arrays.asList( 1304 ((WifiScanner.ParcelableScanResults) response2.obj).getResults()); 1305 assertEquals(results2.size(), 0); 1306 } 1307 1308 /** 1309 * Register a single scan listener and do a single scan 1310 */ 1311 @Test 1312 public void registerScanListener() throws Exception { 1313 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 1314 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1315 WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings); 1316 ScanResults results = ScanResults.create(0, 2400, 5150, 5175); 1317 1318 int requestId = 12; 1319 int listenerRequestId = 13; 1320 1321 startServiceAndLoadDriver(); 1322 1323 Handler handler = mock(Handler.class); 1324 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1325 InOrder order = inOrder(handler, mWifiScannerImpl); 1326 1327 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 1328 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1329 1330 registerScanListener(controlChannel, listenerRequestId); 1331 mLooper.dispatchAll(); 1332 verifySuccessfulResponse(order, handler, listenerRequestId); 1333 1334 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 1335 1336 mLooper.dispatchAll(); 1337 WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings); 1338 verifySuccessfulResponse(order, handler, requestId); 1339 1340 when(mWifiScannerImpl.getLatestSingleScanResults()) 1341 .thenReturn(results.getRawScanData()); 1342 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1343 1344 mLooper.dispatchAll(); 1345 verifyScanResultsReceived(order, handler, requestId, results.getScanData()); 1346 verifySingleScanCompletedReceived(order, handler, requestId); 1347 verifyScanResultsReceived(order, handler, listenerRequestId, results.getScanData()); 1348 verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 1349 verifyNoMoreInteractions(handler); 1350 1351 assertDumpContainsRequestLog("registerScanListener", listenerRequestId); 1352 assertDumpContainsCallbackLog("singleScanResults", listenerRequestId, 1353 "results=" + results.getScanData().getResults().length); 1354 } 1355 1356 /** 1357 * Register a single scan listener and do a single scan 1358 */ 1359 @Test 1360 public void deregisterScanListener() throws Exception { 1361 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 1362 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1363 WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings); 1364 ScanResults results = ScanResults.create(0, 2400, 5150, 5175); 1365 1366 int requestId = 12; 1367 int listenerRequestId = 13; 1368 1369 startServiceAndLoadDriver(); 1370 1371 Handler handler = mock(Handler.class); 1372 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1373 InOrder order = inOrder(handler, mWifiScannerImpl); 1374 1375 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 1376 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1377 1378 registerScanListener(controlChannel, listenerRequestId); 1379 mLooper.dispatchAll(); 1380 verifySuccessfulResponse(order, handler, listenerRequestId); 1381 1382 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 1383 1384 mLooper.dispatchAll(); 1385 WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings); 1386 verifySuccessfulResponse(order, handler, requestId); 1387 1388 deregisterScanListener(controlChannel, listenerRequestId); 1389 mLooper.dispatchAll(); 1390 1391 when(mWifiScannerImpl.getLatestSingleScanResults()) 1392 .thenReturn(results.getRawScanData()); 1393 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1394 1395 mLooper.dispatchAll(); 1396 verifyScanResultsReceived(order, handler, requestId, results.getScanData()); 1397 verifySingleScanCompletedReceived(order, handler, requestId); 1398 verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 1399 verifyNoMoreInteractions(handler); 1400 1401 assertDumpContainsRequestLog("registerScanListener", listenerRequestId); 1402 assertDumpContainsRequestLog("deregisterScanListener", listenerRequestId); 1403 } 1404 1405 /** 1406 * Send a single scan request and then two more before the first completes. Neither are 1407 * satisfied by the first scan. Verify that the first completes and the second two are merged. 1408 */ 1409 @Test 1410 public void scanListenerReceivesAllResults() throws RemoteException { 1411 WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, 1412 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1413 int requestId1 = 12; 1414 ScanResults results1 = ScanResults.create(0, 2400); 1415 1416 WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, 1417 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1418 int requestId2 = 13; 1419 ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450); 1420 1421 WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0, 1422 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1423 int requestId3 = 15; 1424 ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150); 1425 1426 WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels( 1427 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150)); 1428 ScanResults results2and3 = ScanResults.merge(results2, results3); 1429 1430 int listenerRequestId = 13; 1431 1432 1433 startServiceAndLoadDriver(); 1434 1435 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 1436 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1437 1438 Handler handler = mock(Handler.class); 1439 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1440 InOrder handlerOrder = inOrder(handler); 1441 InOrder nativeOrder = inOrder(mWifiScannerImpl); 1442 1443 // Run scan 1 1444 sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null); 1445 1446 mLooper.dispatchAll(); 1447 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, 1448 computeSingleScanNativeSettings(requestSettings1)); 1449 verifySuccessfulResponse(handlerOrder, handler, requestId1); 1450 1451 1452 // Queue scan 2 (will not run because previous is in progress) 1453 sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null); 1454 mLooper.dispatchAll(); 1455 verifySuccessfulResponse(handlerOrder, handler, requestId2); 1456 1457 // Queue scan 3 (will not run because previous is in progress) 1458 sendSingleScanRequest(controlChannel, requestId3, requestSettings3, null); 1459 mLooper.dispatchAll(); 1460 verifySuccessfulResponse(handlerOrder, handler, requestId3); 1461 1462 // Register scan listener 1463 registerScanListener(controlChannel, listenerRequestId); 1464 mLooper.dispatchAll(); 1465 verifySuccessfulResponse(handlerOrder, handler, listenerRequestId); 1466 1467 // dispatch scan 1 results 1468 when(mWifiScannerImpl.getLatestSingleScanResults()) 1469 .thenReturn(results1.getScanData()); 1470 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1471 1472 mLooper.dispatchAll(); 1473 verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData()); 1474 verifySingleScanCompletedReceived(handlerOrder, handler, requestId1); 1475 verifyScanResultsReceived(handlerOrder, handler, listenerRequestId, results1.getScanData()); 1476 verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL)); 1477 1478 // now that the first scan completed we expect the second and third ones to start 1479 WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder, 1480 nativeSettings2and3); 1481 1482 // dispatch scan 2 and 3 results 1483 when(mWifiScannerImpl.getLatestSingleScanResults()) 1484 .thenReturn(results2and3.getScanData()); 1485 eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1486 1487 mLooper.dispatchAll(); 1488 1489 verifyMultipleSingleScanResults(handlerOrder, handler, requestId2, results2, requestId3, 1490 results3, listenerRequestId, results2and3); 1491 1492 assertDumpContainsRequestLog("registerScanListener", listenerRequestId); 1493 assertDumpContainsCallbackLog("singleScanResults", listenerRequestId, 1494 "results=" + results1.getRawScanResults().length); 1495 assertDumpContainsCallbackLog("singleScanResults", listenerRequestId, 1496 "results=" + results2and3.getRawScanResults().length); 1497 } 1498 1499 1500 private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings, 1501 WifiNative.ScanSettings nativeSettings) { 1502 startServiceAndLoadDriver(); 1503 1504 Handler handler = mock(Handler.class); 1505 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1506 InOrder order = inOrder(handler, mWifiScannerImpl); 1507 1508 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 1509 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1510 1511 sendBackgroundScanRequest(controlChannel, 12, requestSettings, null); 1512 mLooper.dispatchAll(); 1513 verifyStartBackgroundScan(order, nativeSettings); 1514 verifySuccessfulResponse(order, handler, 12); 1515 verifyNoMoreInteractions(handler); 1516 assertDumpContainsRequestLog("addBackgroundScanRequest", 12); 1517 } 1518 1519 /** 1520 * Do a background scan for a band and verify that it is successful. 1521 */ 1522 @Test 1523 public void sendBackgroundScanBandRequest() throws Exception { 1524 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 1525 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1526 WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() 1527 .withBasePeriod(30000) 1528 .withMaxApPerScan(MAX_AP_PER_SCAN) 1529 .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH) 1530 .addBucketWithBand(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 1531 WifiScanner.WIFI_BAND_BOTH) 1532 .build(); 1533 doSuccessfulBackgroundScan(requestSettings, nativeSettings); 1534 assertEquals(mWifiMetrics.getBackgroundScanCount(), 1); 1535 } 1536 1537 /** 1538 * Do a background scan for a list of channels and verify that it is successful. 1539 */ 1540 @Test 1541 public void sendBackgroundScanChannelsRequest() throws Exception { 1542 WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(5150), 30000, 1543 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1544 WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() 1545 .withBasePeriod(30000) 1546 .withMaxApPerScan(MAX_AP_PER_SCAN) 1547 .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH) 1548 .addBucketWithChannels(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5150) 1549 .build(); 1550 doSuccessfulBackgroundScan(requestSettings, nativeSettings); 1551 } 1552 1553 private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForHwPno() 1554 throws Exception { 1555 WifiScanner.ScanSettings requestSettings = createRequest( 1556 channelsToSpec(0, 2400, 5150, 5175), 30000, 0, 20, 1557 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1558 WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() 1559 .withBasePeriod(30000) 1560 .withMaxApPerScan(MAX_AP_PER_SCAN) 1561 .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH) 1562 .addBucketWithChannels(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 1563 0, 2400, 5150, 5175) 1564 .build(); 1565 return Pair.create(requestSettings, nativeSettings); 1566 } 1567 1568 private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForSwPno() 1569 throws Exception { 1570 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> settingsPair = 1571 createScanSettingsForHwPno(); 1572 1573 WifiScanner.ScanSettings requestSettings = settingsPair.first; 1574 WifiNative.ScanSettings nativeSettings = settingsPair.second; 1575 // reportEvents field is overridden for SW PNO 1576 for (int i = 0; i < nativeSettings.buckets.length; i++) { 1577 nativeSettings.buckets[i].report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 1578 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; 1579 } 1580 return Pair.create(requestSettings, nativeSettings); 1581 } 1582 1583 private Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> createPnoSettings( 1584 ScanResults results) 1585 throws Exception { 1586 WifiScanner.PnoSettings requestPnoSettings = new WifiScanner.PnoSettings(); 1587 requestPnoSettings.networkList = 1588 new WifiScanner.PnoSettings.PnoNetwork[results.getRawScanResults().length]; 1589 int i = 0; 1590 for (ScanResult scanResult : results.getRawScanResults()) { 1591 requestPnoSettings.networkList[i++] = 1592 new WifiScanner.PnoSettings.PnoNetwork(scanResult.SSID); 1593 } 1594 1595 WifiNative.PnoSettings nativePnoSettings = new WifiNative.PnoSettings(); 1596 nativePnoSettings.min5GHzRssi = requestPnoSettings.min5GHzRssi; 1597 nativePnoSettings.min24GHzRssi = requestPnoSettings.min24GHzRssi; 1598 nativePnoSettings.initialScoreMax = requestPnoSettings.initialScoreMax; 1599 nativePnoSettings.currentConnectionBonus = requestPnoSettings.currentConnectionBonus; 1600 nativePnoSettings.sameNetworkBonus = requestPnoSettings.sameNetworkBonus; 1601 nativePnoSettings.secureBonus = requestPnoSettings.secureBonus; 1602 nativePnoSettings.band5GHzBonus = requestPnoSettings.band5GHzBonus; 1603 nativePnoSettings.isConnected = requestPnoSettings.isConnected; 1604 nativePnoSettings.networkList = 1605 new WifiNative.PnoNetwork[requestPnoSettings.networkList.length]; 1606 for (i = 0; i < requestPnoSettings.networkList.length; i++) { 1607 nativePnoSettings.networkList[i] = new WifiNative.PnoNetwork(); 1608 nativePnoSettings.networkList[i].ssid = requestPnoSettings.networkList[i].ssid; 1609 nativePnoSettings.networkList[i].flags = requestPnoSettings.networkList[i].flags; 1610 nativePnoSettings.networkList[i].auth_bit_field = 1611 requestPnoSettings.networkList[i].authBitField; 1612 } 1613 return Pair.create(requestPnoSettings, nativePnoSettings); 1614 } 1615 1616 private ScanResults createScanResultsForPno() { 1617 return ScanResults.create(0, 2400, 5150, 5175); 1618 } 1619 1620 private ScanResults createScanResultsForPnoWithNoIE() { 1621 return ScanResults.createWithNoIE(0, 2400, 5150, 5175); 1622 } 1623 1624 private WifiNative.PnoEventHandler verifyHwPno(InOrder order, 1625 WifiNative.PnoSettings expected) { 1626 ArgumentCaptor<WifiNative.PnoSettings> pnoSettingsCaptor = 1627 ArgumentCaptor.forClass(WifiNative.PnoSettings.class); 1628 ArgumentCaptor<WifiNative.PnoEventHandler> pnoEventHandlerCaptor = 1629 ArgumentCaptor.forClass(WifiNative.PnoEventHandler.class); 1630 order.verify(mWifiScannerImpl).setHwPnoList(pnoSettingsCaptor.capture(), 1631 pnoEventHandlerCaptor.capture()); 1632 assertNativePnoSettingsEquals(expected, pnoSettingsCaptor.getValue()); 1633 return pnoEventHandlerCaptor.getValue(); 1634 } 1635 1636 private void sendPnoScanRequest(BidirectionalAsyncChannel controlChannel, 1637 int scanRequestId, WifiScanner.ScanSettings scanSettings, 1638 WifiScanner.PnoSettings pnoSettings) { 1639 Bundle pnoParams = new Bundle(); 1640 scanSettings.isPnoScan = true; 1641 pnoParams.putParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings); 1642 pnoParams.putParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings); 1643 controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_PNO_SCAN, 0, 1644 scanRequestId, pnoParams)); 1645 } 1646 1647 private void assertPnoNetworkFoundMessage(int listenerId, ScanResult[] expected, 1648 Message networkFoundMessage) { 1649 assertEquals("what", WifiScanner.CMD_PNO_NETWORK_FOUND, networkFoundMessage.what); 1650 assertEquals("listenerId", listenerId, networkFoundMessage.arg2); 1651 assertScanResultsEquals(expected, 1652 ((WifiScanner.ParcelableScanResults) networkFoundMessage.obj).getResults()); 1653 } 1654 1655 private void verifyPnoNetworkFoundReceived(InOrder order, Handler handler, int listenerId, 1656 ScanResult[] expected) { 1657 Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler, 1658 WifiScanner.CMD_PNO_NETWORK_FOUND); 1659 assertPnoNetworkFoundMessage(listenerId, expected, scanResultMessage); 1660 } 1661 1662 private void expectSuccessfulBackgroundScan(InOrder order, 1663 WifiNative.ScanSettings nativeSettings, ScanResults results) { 1664 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 1665 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1666 mLooper.dispatchAll(); 1667 WifiNative.ScanEventHandler eventHandler = verifyStartBackgroundScan(order, nativeSettings); 1668 WifiScanner.ScanData[] scanDatas = new WifiScanner.ScanData[1]; 1669 scanDatas[0] = results.getScanData(); 1670 for (ScanResult fullScanResult : results.getRawScanResults()) { 1671 eventHandler.onFullScanResult(fullScanResult, 0); 1672 } 1673 when(mWifiScannerImpl.getLatestBatchedScanResults(anyBoolean())).thenReturn(scanDatas); 1674 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1675 mLooper.dispatchAll(); 1676 } 1677 1678 private void expectHwPnoScanWithNoBackgroundScan(InOrder order, Handler handler, int requestId, 1679 WifiNative.PnoSettings nativeSettings, ScanResults results) { 1680 when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true); 1681 when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(false); 1682 1683 when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class), 1684 any(WifiNative.PnoEventHandler.class))).thenReturn(true); 1685 mLooper.dispatchAll(); 1686 WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativeSettings); 1687 verifySuccessfulResponse(order, handler, requestId); 1688 eventHandler.onPnoNetworkFound(results.getRawScanResults()); 1689 mLooper.dispatchAll(); 1690 } 1691 1692 private void expectHwPnoScanWithBackgroundScan(InOrder order, Handler handler, int requestId, 1693 WifiNative.ScanSettings nativeScanSettings, 1694 WifiNative.PnoSettings nativePnoSettings, ScanResults results) { 1695 when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true); 1696 when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true); 1697 1698 when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class), 1699 any(WifiNative.PnoEventHandler.class))).thenReturn(true); 1700 when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), 1701 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1702 mLooper.dispatchAll(); 1703 WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativePnoSettings); 1704 verifySuccessfulResponse(order, handler, requestId); 1705 verifyStartBackgroundScan(order, nativeScanSettings); 1706 eventHandler.onPnoNetworkFound(results.getRawScanResults()); 1707 mLooper.dispatchAll(); 1708 } 1709 1710 private void expectHwPnoScanWithBackgroundScanWithNoIE(InOrder order, Handler handler, 1711 int requestId, WifiNative.ScanSettings nativeBackgroundScanSettings, 1712 WifiNative.ScanSettings nativeSingleScanSettings, 1713 WifiNative.PnoSettings nativePnoSettings, ScanResults results) { 1714 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 1715 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1716 1717 expectHwPnoScanWithBackgroundScan(order, handler, requestId, nativeBackgroundScanSettings, 1718 nativePnoSettings, results); 1719 WifiNative.ScanEventHandler eventHandler = 1720 verifyStartSingleScan(order, nativeSingleScanSettings); 1721 when(mWifiScannerImpl.getLatestSingleScanResults()).thenReturn(results.getScanData()); 1722 eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1723 mLooper.dispatchAll(); 1724 } 1725 private void expectSwPnoScan(InOrder order, WifiNative.ScanSettings nativeScanSettings, 1726 ScanResults results) { 1727 when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(false); 1728 when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true); 1729 1730 expectSuccessfulBackgroundScan(order, nativeScanSettings, results); 1731 } 1732 1733 /** 1734 * Tests Supplicant PNO scan when the PNO scan results contain IE info. This ensures that the 1735 * PNO scan results are plumbed back to the client as a PNO network found event. 1736 */ 1737 @Test 1738 public void testSuccessfulHwPnoScanWithNoBackgroundScan() throws Exception { 1739 startServiceAndLoadDriver(); 1740 Handler handler = mock(Handler.class); 1741 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1742 InOrder order = inOrder(handler, mWifiScannerImpl); 1743 int requestId = 12; 1744 1745 ScanResults scanResults = createScanResultsForPno(); 1746 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 1747 createScanSettingsForHwPno(); 1748 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 1749 createPnoSettings(scanResults); 1750 1751 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 1752 expectHwPnoScanWithNoBackgroundScan(order, handler, requestId, pnoSettings.second, 1753 scanResults); 1754 verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults()); 1755 } 1756 1757 /** 1758 * Tests Hal ePNO scan when the PNO scan results contain IE info. This ensures that the 1759 * PNO scan results are plumbed back to the client as a PNO network found event. 1760 */ 1761 @Test 1762 public void testSuccessfulHwPnoScanWithBackgroundScan() throws Exception { 1763 startServiceAndLoadDriver(); 1764 Handler handler = mock(Handler.class); 1765 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1766 InOrder order = inOrder(handler, mWifiScannerImpl); 1767 int requestId = 12; 1768 1769 ScanResults scanResults = createScanResultsForPno(); 1770 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 1771 createScanSettingsForHwPno(); 1772 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 1773 createPnoSettings(scanResults); 1774 1775 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 1776 expectHwPnoScanWithBackgroundScan(order, handler, requestId, scanSettings.second, 1777 pnoSettings.second, scanResults); 1778 verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults()); 1779 } 1780 1781 /** 1782 * Tests Hal ePNO scan when the PNO scan results don't contain IE info. This ensures that the 1783 * single scan results are plumbed back to the client as a PNO network found event. 1784 */ 1785 @Test 1786 public void testSuccessfulHwPnoScanWithBackgroundScanWithNoIE() throws Exception { 1787 startServiceAndLoadDriver(); 1788 Handler handler = mock(Handler.class); 1789 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1790 InOrder order = inOrder(handler, mWifiScannerImpl); 1791 int requestId = 12; 1792 1793 ScanResults scanResults = createScanResultsForPnoWithNoIE(); 1794 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 1795 createScanSettingsForHwPno(); 1796 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 1797 createPnoSettings(scanResults); 1798 1799 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 1800 expectHwPnoScanWithBackgroundScanWithNoIE(order, handler, requestId, scanSettings.second, 1801 computeSingleScanNativeSettings(scanSettings.first), pnoSettings.second, 1802 scanResults); 1803 1804 ArrayList<ScanResult> sortScanList = 1805 new ArrayList<ScanResult>(Arrays.asList(scanResults.getRawScanResults())); 1806 Collections.sort(sortScanList, WifiScannerImpl.SCAN_RESULT_SORT_COMPARATOR); 1807 verifyPnoNetworkFoundReceived(order, handler, requestId, 1808 sortScanList.toArray(new ScanResult[sortScanList.size()])); 1809 } 1810 1811 /** 1812 * Tests SW PNO scan. This ensures that the background scan results are plumbed back to the 1813 * client as a PNO network found event. 1814 */ 1815 @Test 1816 public void testSuccessfulSwPnoScan() throws Exception { 1817 startServiceAndLoadDriver(); 1818 Handler handler = mock(Handler.class); 1819 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1820 InOrder order = inOrder(handler, mWifiScannerImpl); 1821 int requestId = 12; 1822 1823 ScanResults scanResults = createScanResultsForPno(); 1824 Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = 1825 createScanSettingsForSwPno(); 1826 Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = 1827 createPnoSettings(scanResults); 1828 1829 sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); 1830 expectSwPnoScan(order, scanSettings.second, scanResults); 1831 verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults()); 1832 } 1833 1834 /** 1835 * Tries to simulate the race scenario where a client is disconnected immediately after single 1836 * scan request is sent to |SingleScanStateMachine|. 1837 */ 1838 @Test 1839 public void processSingleScanRequestAfterDisconnect() throws Exception { 1840 startServiceAndLoadDriver(); 1841 BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class)); 1842 mLooper.dispatchAll(); 1843 1844 // Send the single scan request and then send the disconnect immediately after. 1845 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 1846 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1847 int requestId = 10; 1848 1849 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 1850 // Can't call |disconnect| here because that sends |CMD_CHANNEL_DISCONNECT| followed by 1851 // |CMD_CHANNEL_DISCONNECTED|. 1852 controlChannel.sendMessage(Message.obtain(null, AsyncChannel.CMD_CHANNEL_DISCONNECTED, 1853 AsyncChannel.STATUS_REMOTE_DISCONNECTION, 0, null)); 1854 1855 // Now process the above 2 actions. This should result in first processing the single scan 1856 // request (which forwards the request to SingleScanStateMachine) and then processing the 1857 // disconnect after. 1858 mLooper.dispatchAll(); 1859 1860 // Now check that we logged the invalid request. 1861 String serviceDump = dumpService(); 1862 Pattern logLineRegex = Pattern.compile("^.+" + "singleScanInvalidRequest: " 1863 + "ClientInfo\\[unknown\\],Id=" + requestId + ",bad request$", Pattern.MULTILINE); 1864 assertTrue("dump did not contain log with ClientInfo[unknown]: " + serviceDump + "\n", 1865 logLineRegex.matcher(serviceDump).find()); 1866 } 1867 1868 /** 1869 * Tries to simulate the race scenario where a client is disconnected immediately after single 1870 * scan request is sent to |SingleScanStateMachine|. 1871 */ 1872 @Test 1873 public void sendScanRequestAfterUnsuccessfulSend() throws Exception { 1874 WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, 1875 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); 1876 int requestId = 9; 1877 1878 startServiceAndLoadDriver(); 1879 Handler handler = mock(Handler.class); 1880 BidirectionalAsyncChannel controlChannel = connectChannel(handler); 1881 mLooper.dispatchAll(); 1882 1883 when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), 1884 any(WifiNative.ScanEventHandler.class))).thenReturn(true); 1885 ScanResults results = ScanResults.create(0, 2400); 1886 when(mWifiScannerImpl.getLatestSingleScanResults()) 1887 .thenReturn(results.getRawScanData()); 1888 1889 InOrder order = inOrder(mWifiScannerImpl, handler); 1890 1891 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 1892 mLooper.dispatchAll(); 1893 WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order, 1894 computeSingleScanNativeSettings(requestSettings)); 1895 verifySuccessfulResponse(order, handler, requestId); 1896 1897 eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1898 mLooper.dispatchAll(); 1899 verifyScanResultsReceived(order, handler, requestId, results.getScanData()); 1900 verifySingleScanCompletedReceived(order, handler, requestId); 1901 verifyNoMoreInteractions(handler); 1902 1903 controlChannel.sendMessage(Message.obtain(null, AsyncChannel.CMD_CHANNEL_DISCONNECTED, 1904 AsyncChannel.STATUS_SEND_UNSUCCESSFUL, 0, null)); 1905 mLooper.dispatchAll(); 1906 1907 sendSingleScanRequest(controlChannel, requestId, requestSettings, null); 1908 mLooper.dispatchAll(); 1909 WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order, 1910 computeSingleScanNativeSettings(requestSettings)); 1911 verifySuccessfulResponse(order, handler, requestId); 1912 1913 eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1914 mLooper.dispatchAll(); 1915 verifyScanResultsReceived(order, handler, requestId, results.getScanData()); 1916 verifySingleScanCompletedReceived(order, handler, requestId); 1917 verifyNoMoreInteractions(handler); 1918 } 1919} 1920