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