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