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