From e6b6ab66c49702d3358b4894d28e322ea9534a84 Mon Sep 17 00:00:00 2001 From: Ningyuan Wang Date: Wed, 27 Sep 2017 16:19:39 -0700 Subject: Fail scan request if no channels are available This fails scan request if no available channels could be scanned for this request. With this fix we can avoid the freezing of WifiScanner in aformentioned case. Bug: 67015387 Test: compile, unit test, integration test Change-Id: I68654ce8d53104484c1559d8b0525585ab50b9e5 --- .../server/wifi/scanner/WificondScannerImpl.java | 22 ++++++++++---- .../server/wifi/scanner/WificondScannerTest.java | 34 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java index 12a0bdee0..ed25e0f67 100644 --- a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java +++ b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java @@ -422,11 +422,22 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call mPendingSingleScanEventHandler = null; } - if ((newScanSettings.backgroundScanActive || newScanSettings.singleScanActive) - && !allFreqs.isEmpty()) { - pauseHwPnoScan(); - Set freqs = allFreqs.getScanFreqs(); - boolean success = mWifiNative.scan(freqs, hiddenNetworkSSIDSet); + if (newScanSettings.backgroundScanActive || newScanSettings.singleScanActive) { + boolean success = false; + Set freqs; + if (!allFreqs.isEmpty()) { + pauseHwPnoScan(); + freqs = allFreqs.getScanFreqs(); + success = mWifiNative.scan(freqs, hiddenNetworkSSIDSet); + if (!success) { + Log.e(TAG, "Failed to start scan, freqs=" + freqs); + } + } else { + // There is a scan request but no available channels could be scanned for. + // We regard it as a scan failure in this case. + Log.e(TAG, "Failed to start scan because there is " + + "no available channel to scan for"); + } if (success) { // TODO handle scan timeout if (DBG) { @@ -439,7 +450,6 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call mClock.getElapsedSinceBootMillis() + SCAN_TIMEOUT_MS, TIMEOUT_ALARM_TAG, mScanTimeoutListener, mEventHandler); } else { - Log.e(TAG, "Failed to start scan, freqs=" + freqs); // indicate scan failure async mEventHandler.post(new Runnable() { public void run() { diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java index ed7c58298..d337cf1cf 100644 --- a/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java @@ -32,6 +32,7 @@ import com.android.server.wifi.ScanDetail; import com.android.server.wifi.ScanResults; import com.android.server.wifi.WifiMonitor; import com.android.server.wifi.WifiNative; +import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection; import org.junit.Before; import org.junit.Test; @@ -56,6 +57,39 @@ public class WificondScannerTest extends BaseWifiScannerImplTest { mLooper.getLooper(), mClock); } + /** + * Test that WificondScannerImpl will not issue a scan and report scan failure + * when there is no channel to scan for. + */ + @Test + public void singleScanNotIssuedIfNoAvailableChannels() { + // Use mocked ChannelHelper and ChannelCollection to simulate the scenario + // that no channel is available for this request. + ChannelHelper channelHelper = mock(ChannelHelper.class); + ChannelCollection channelCollection = mock(ChannelCollection.class); + when(channelHelper.createChannelCollection()).thenReturn(channelCollection); + when(channelCollection.isEmpty()).thenReturn(true); + + mScanner = new WificondScannerImpl(mContext, mWifiNative, mWifiMonitor, + channelHelper, mLooper.getLooper(), mClock); + + WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() + .withBasePeriod(10000) // ms + .withMaxApPerScan(10) + .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, + WifiScanner.WIFI_BAND_5_GHZ) + .build(); + WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); + mScanner.startSingleScan(settings, eventHandler); + + mLooper.dispatchAll(); + + // No scan is issued to WifiNative. + verify(mWifiNative, never()).scan(any(), any(Set.class)); + // A scan failed event must be reported. + verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED); + } + @Test public void backgroundScanSuccessSingleBucket() { WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() -- cgit v1.2.3