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