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