diff options
author | Roshan Pius <rpius@google.com> | 2018-04-26 13:33:00 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2018-04-26 16:57:13 -0700 |
commit | 72024817b555c872ef21cfbcca3b33851a406d29 (patch) | |
tree | 274d4b29040b790ecb48a4e43de4de9bec9f6f29 /tests | |
parent | a0daf40587b185e4f65549964c465ba7489ad753 (diff) |
WifiScanningServiceImpl: Ignore duplicate scan available
Receiving duplicate SCAN_AVAILABLE broadcast currently puts WifiScanner
in a weird state. This is what happens:
a) WifiBackgroundScanStateMachine is already in StartedState.
b) WifiBackgroundScanStateMachine receives another CMD_DRIVER_LOADED
message.
c) CMD_DRIVER_LOADED is handled in the DefaultState which creates a new
mScannerImpl instance.
d) Handling of CMD_DRIVER_LOADED also asks the
WifiBackgroundScanStateMachine to transition to StartedState.
e) This causes WifiBackgroundScanStateMachine to transition out of
StartedState and back into StartedState.
(This transition to the same state should probably have been ignored
by the base StateMachine class)
f) In the above transition, exit() of StartedState invokes
mScannerImpl.cleanup().
So, we end up with a new mScannerImpl instance on which we invoked
mScannerImpl.cleanup() and hence no more scans work.
Note: We may still need to debug why WSM is sending out back to back
scan available notification. But, we should fix the handling in
WifiScanner regardless.
Bug: 78549365
Test: Unit tests
Test: Ran WifiManager ACTS tests locally
Test: Toggled wifi a bunch of times and ensured scanning still works.
Change-Id: I2cf606ecf2d2d261d3354be30135c4ec93f278ff
Diffstat (limited to 'tests')
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java index 08eca85f7..85f1bede0 100644 --- a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java +++ b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java @@ -497,6 +497,23 @@ public class WifiScanningServiceTest { assertDumpContainsRequestLog("addBackgroundScanRequest", 192); } + /** + * Verifies that duplicate SCAN_AVAILABLE broadcast with |WIFI_STATE_ENABLED| is ignored. + */ + @Test + public void duplicateScanAvailableBroadcastIsIgnored() throws RemoteException { + startServiceAndLoadDriver(); + + // Send scan available again. + TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext, + WifiManager.WIFI_STATE_ENABLED); + mLooper.dispatchAll(); + + // Ensure we didn't create scanner instance twice. + verify(mWifiScannerImplFactory, times(1)) + .create(any(), any(), any()); + } + @Test public void disconnectClientAfterStartingWifi() throws Exception { mWifiScanningServiceImpl.startService(); @@ -2293,4 +2310,117 @@ public class WifiScanningServiceTest { messenger.send(message); verify(mFrameworkFacade, never()).makeWifiAsyncChannel(anyString()); } + + /** + * Verifies that background scan works after duplicate SCAN_AVAILABLE broadcast with + * |WIFI_STATE_ENABLED|. + */ + @Test + public void backgroundScanAfterDuplicateScanAvailableBroadcast() throws RemoteException { + startServiceAndLoadDriver(); + + // Send scan available again. + TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext, + WifiManager.WIFI_STATE_ENABLED); + mLooper.dispatchAll(); + + // Ensure we didn't create scanner instance twice. + verify(mWifiScannerImplFactory, times(1)) + .create(any(), any(), any()); + + Handler handler = mock(Handler.class); + BidirectionalAsyncChannel controlChannel = connectChannel(handler); + InOrder order = inOrder(handler); + when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), + any(WifiNative.ScanEventHandler.class))).thenReturn(true); + sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings(), null); + mLooper.dispatchAll(); + verifySuccessfulResponse(order, handler, 192); + assertDumpContainsRequestLog("addBackgroundScanRequest", 192); + } + + /** + * Verifies that single scan works after duplicate SCAN_AVAILABLE broadcast with + * |WIFI_STATE_ENABLED|. + */ + @Test + public void singleScanScanAfterDuplicateScanAvailableBroadcast() throws RemoteException { + startServiceAndLoadDriver(); + + // Send scan available again. + TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext, + WifiManager.WIFI_STATE_ENABLED); + mLooper.dispatchAll(); + + // Ensure we didn't create scanner instance twice. + verify(mWifiScannerImplFactory, times(1)) + .create(any(), any(), any()); + + Handler handler = mock(Handler.class); + BidirectionalAsyncChannel controlChannel = connectChannel(handler); + InOrder order = inOrder(handler, mWifiScannerImpl); + + int requestId = 12; + WorkSource workSource = new WorkSource(2292); + WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400, 5150, 5175), + 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); + ScanResults results = ScanResults.create(0, true, 2400, 5150, 5175); + + when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), + any(WifiNative.ScanEventHandler.class))).thenReturn(true); + + sendSingleScanRequest(controlChannel, requestId, requestSettings, workSource); + + mLooper.dispatchAll(); + WifiNative.ScanEventHandler eventHandler = + verifyStartSingleScan(order, computeSingleScanNativeSettings(requestSettings)); + verifySuccessfulResponse(order, handler, requestId); + verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource)); + + when(mWifiScannerImpl.getLatestSingleScanResults()) + .thenReturn(results.getRawScanData()); + eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); + + mLooper.dispatchAll(); + verifyScanResultsReceived(order, handler, requestId, results.getScanData()); + verifySingleScanCompletedReceived(order, handler, requestId); + verifyNoMoreInteractions(handler); + verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource)); + assertDumpContainsRequestLog("addSingleScanRequest", requestId); + assertDumpContainsCallbackLog("singleScanResults", requestId, + "results=" + results.getScanData().getResults().length); + } + + /** + * Verifies that pno scan works after duplicate SCAN_AVAILABLE broadcast with + * |WIFI_STATE_ENABLED|. + */ + @Test + public void hwPnoScanScanAfterDuplicateScanAvailableBroadcast() throws Exception { + startServiceAndLoadDriver(); + + // Send scan available again. + TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext, + WifiManager.WIFI_STATE_ENABLED); + mLooper.dispatchAll(); + + // Ensure we didn't create scanner instance twice. + verify(mWifiScannerImplFactory, times(1)) + .create(any(), any(), any()); + + Handler handler = mock(Handler.class); + BidirectionalAsyncChannel controlChannel = connectChannel(handler); + InOrder order = inOrder(handler, mWifiScannerImpl); + int requestId = 12; + + ScanResults scanResults = createScanResultsForPno(); + Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings = + createScanSettingsForHwPno(); + Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings = + createPnoSettings(scanResults); + + sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first); + expectHwPnoScan(order, handler, requestId, pnoSettings.second, scanResults); + verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults()); + } } |