From 0a08889eb6a6dd41bca12dcd6dfc5a6d9c964f27 Mon Sep 17 00:00:00 2001 From: Mitchell Wills Date: Mon, 16 May 2016 14:55:39 -0700 Subject: Fix crash when scanner gets results that don't match the request Before this, when WifiScanningService processed single scan results from supplicant that only contained results that did not match a request the filter code would return null indicating that the results should not be delivered, causing a NPE later. This change updates the meaning of the bucket index that the single scan code provides to the filtering code to instead force it to always include scan results. Change-Id: I65cd57b14abacec3f407991188c570601d05ac77 Fixes: 28794598 --- .../server/wifi/scanner/ScanScheduleUtil.java | 10 +++++-- .../src/com/android/server/wifi/ScanResults.java | 11 +++++-- .../wifi/scanner/ScanScheduleUtilFilterTest.java | 34 +++++++++++++++------- .../wifi/scanner/WifiScanningServiceTest.java | 31 ++++++++++++++++++-- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java b/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java index 01418b91c..9267aa0f5 100644 --- a/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java +++ b/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java @@ -94,7 +94,8 @@ public class ScanScheduleUtil { * Check if the specified bucket was scanned. If not all information is available then this * method will return true. * - * @param scheduledBucket Index of the bucket to check for, zero indexed, or -1 if unavailable + * @param scheduledBucket Index of the bucket to check for, zero indexed, or -1 if any scan + * should be treated as scanning this bucket. * @param bucketsScannedBitSet The bitset of all buckets scanned, 0 if unavailable */ private static boolean isBucketMaybeScanned(int scheduledBucket, int bucketsScannedBitSet) { @@ -109,11 +110,14 @@ public class ScanScheduleUtil { * Check if the specified bucket was scanned. If not all information is available then this * method will return false. * - * @param scheduledBucket Index of the bucket to check for, zero indexed, or -1 if unavailable + * @param scheduledBucket Index of the bucket to check for, zero indexed, or -1 if any scan + * should be treated as scanning this bucket. * @param bucketsScannedBitSet The bitset of all buckets scanned, 0 if unavailable */ private static boolean isBucketDefinitlyScanned(int scheduledBucket, int bucketsScannedBitSet) { - if (bucketsScannedBitSet == 0 || scheduledBucket < 0) { + if (scheduledBucket < 0) { + return true; + } else if (bucketsScannedBitSet == 0) { return false; } else { return (bucketsScannedBitSet & (1 << scheduledBucket)) != 0; diff --git a/tests/wifitests/src/com/android/server/wifi/ScanResults.java b/tests/wifitests/src/com/android/server/wifi/ScanResults.java index bc76d0f90..160902081 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanResults.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanResults.java @@ -37,12 +37,14 @@ import java.util.Random; public class ScanResults { private final ArrayList mScanDetails = new ArrayList<>(); private final ScanData mScanData; + private final ScanData mRawScanData; private final ScanResult[] mScanResults; private ScanResults(ArrayList scanDetails, ScanData scanData, ScanResult[] scanResults) { mScanDetails.addAll(scanDetails); mScanData = scanData; + mRawScanData = scanData; mScanResults = scanResults; } @@ -127,7 +129,7 @@ public class ScanResults { /** * Create scan results with no IE information. */ - private static ScanDetail[] generateNativeResults(int seed, int... freqs) { + public static ScanDetail[] generateNativeResults(int seed, int... freqs) { return generateNativeResults(true, seed, freqs); } @@ -171,8 +173,9 @@ public class ScanResults { } ScanResult[] sortedScanResults = Arrays.copyOf(mScanResults, mScanResults.length); Arrays.sort(sortedScanResults, SCAN_RESULT_RSSI_COMPARATOR); + mRawScanData = new ScanData(id, 0, sortedScanResults); if (maxResults == -1) { - mScanData = new ScanData(id, 0, sortedScanResults); + mScanData = mRawScanData; } else { ScanResult[] reducedScanResults = Arrays.copyOf(sortedScanResults, Math.min(sortedScanResults.length, maxResults)); @@ -191,4 +194,8 @@ public class ScanResults { public ScanResult[] getRawScanResults() { return mScanResults; } + + public ScanData getRawScanData() { + return mRawScanData; + } } diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java index 3117fd96c..b8e20b5f0 100644 --- a/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java +++ b/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java @@ -71,7 +71,7 @@ public class ScanScheduleUtilFilterTest { ); assertFalse(ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper, - createScanResult(5150), 0, settings, -1)); + createScanResult(5150), 0, settings, 0)); } @Test @@ -82,7 +82,7 @@ public class ScanScheduleUtilFilterTest { ); assertTrue(ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper, - createScanResult(2400), 0, settings, -1)); + createScanResult(2400), 0, settings, 0)); } @Test @@ -93,7 +93,7 @@ public class ScanScheduleUtilFilterTest { ); assertFalse(ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper, - createScanResult(5175), 0, settings, -1)); + createScanResult(5175), 0, settings, 0)); } @Test @@ -138,10 +138,22 @@ public class ScanScheduleUtilFilterTest { ); ScanData[] results = ScanScheduleUtil.filterResultsForSettings(mChannelHelper, - createScanDatas(new int[][]{ { 2450 } }), settings, -1); + createScanDatas(new int[][]{ { 2450 } }), settings, 0); assertScanDataFreqsEquals(null, results); } + @Test + public void filterScanDataSingleNotMatchingWithDefinitlyScannedBucketIndex() { + ScanSettings settings = createRequest( + channelsToSpec(2400, 5150), 30000, 0, 20, + WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT + ); + + ScanData[] results = ScanScheduleUtil.filterResultsForSettings(mChannelHelper, + createScanDatas(new int[][]{ { 2450 } }), settings, -1); + assertScanDataFreqsEquals(new int[][]{ { } }, results); + } + @Test public void filterScanDataSingleNotMatchingWithBucketDefinitlyScanned() { ScanSettings settings = createRequest( @@ -162,7 +174,7 @@ public class ScanScheduleUtilFilterTest { ); ScanData[] results = ScanScheduleUtil.filterResultsForSettings(mChannelHelper, - createScanDatas(new int[][]{ { 2400 } }), settings, -1); + createScanDatas(new int[][]{ { 2400 } }), settings, 0); assertScanDataFreqsEquals(new int[][]{ { 2400 } }, results); } @@ -188,7 +200,7 @@ public class ScanScheduleUtilFilterTest { ); ScanData[] results = ScanScheduleUtil.filterResultsForSettings(mChannelHelper, - createScanDatas(new int[][]{ { 2400, 2450, 5150, 5175 } }), settings, -1); + createScanDatas(new int[][]{ { 2400, 2450, 5150, 5175 } }), settings, 0); assertScanDataFreqsEquals(new int[][]{ { 2400, 5150 } }, results); } @@ -201,7 +213,7 @@ public class ScanScheduleUtilFilterTest { ); ScanData[] results = ScanScheduleUtil.filterResultsForSettings(mChannelHelper, - createScanDatas(new int[][]{ { 2450 }, { 2450, 5175 } }), settings, -1); + createScanDatas(new int[][]{ { 2450 }, { 2450, 5175 } }), settings, 0); assertScanDataFreqsEquals(null, results); } @@ -226,7 +238,7 @@ public class ScanScheduleUtilFilterTest { ); ScanData[] results = ScanScheduleUtil.filterResultsForSettings(mChannelHelper, - createScanDatas(new int[][]{ { 2400 }, {2400, 5150} }), settings, -1); + createScanDatas(new int[][]{ { 2400 }, {2400, 5150} }), settings, 0); assertScanDataFreqsEquals(new int[][]{ { 2400 }, {2400, 5150} }, results); } @@ -256,7 +268,7 @@ public class ScanScheduleUtilFilterTest { createScanDatas(new int[][]{ { 2400, 2450, 5150, 5175, 2400 }, { 2400, 2450, 5175 }, - { 5175, 5175, 5150 } }), settings, -1); + { 5175, 5175, 5150 } }), settings, 0); assertScanDataFreqsEquals(new int[][]{ { 2400, 5150, 2400 }, { 2400 }, { 5150 } }, results); } @@ -272,7 +284,7 @@ public class ScanScheduleUtilFilterTest { createScanDatas(new int[][]{ { 2400, 2450, 5150, 5175, 2400 }, { 5175 }, - { 5175, 5175, 5150 } }), settings, -1); + { 5175, 5175, 5150 } }), settings, 0); assertScanDataFreqsEquals(new int[][]{ { 2400, 5150, 2400 }, { 5150 } }, results); } @@ -288,7 +300,7 @@ public class ScanScheduleUtilFilterTest { createScanDatas(new int[][]{ { 2400, 2450, 5150, 5175, 2400, 2400}, { 5175 }, - { 5175, 5175, 5150, 2400, 2400, 5150 } }), settings, -1); + { 5175, 5175, 5150, 2400, 2400, 5150 } }), settings, 0); assertScanDataFreqsEquals(new int[][]{ { 2400, 5150, 2400 }, { 5150, 2400, 2400 } }, results); 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 1fb0f951a..c0e0a102e 100644 --- a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java +++ b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java @@ -374,7 +374,7 @@ public class WifiScanningServiceTest { verifySuccessfulResponse(order, handler, requestId); when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results.getScanData()); + .thenReturn(results.getRawScanData()); eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); mLooper.dispatchAll(); @@ -383,7 +383,7 @@ public class WifiScanningServiceTest { verifyNoMoreInteractions(handler); assertDumpContainsRequestLog("addSingleScanRequest", requestId); assertDumpContainsCallbackLog("singleScanResults", requestId, - "results=" + results.getRawScanResults().length); + "results=" + results.getScanData().getResults().length); } /** @@ -408,6 +408,33 @@ public class WifiScanningServiceTest { ScanResults.create(0, 2400, 5150, 5175)); } + /** + * Do a single scan with no results and verify that it is successful. + */ + @Test + public void sendSingleScanRequestWithNoResults() throws Exception { + WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, + 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); + doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), + ScanResults.create(0, new int[0])); + } + + /** + * Do a single scan with results that do not match the requested scan and verify that it is + * still successful (and returns no results). + */ + @Test + public void sendSingleScanRequestWithBadRawResults() throws Exception { + WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0, + 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); + // Create a set of scan results that has results not matching the request settings, but is + // limited to zero results for the expected results. + ScanResults results = ScanResults.createOverflowing(0, 0, + ScanResults.generateNativeResults(0, 5150, 5171)); + doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), + results); + } + /** * Do a single scan, which the hardware fails to start, and verify that a failure response is * delivered. -- cgit v1.2.3 From 3d2be9af50d6df4c2e7ce1a0b630cdfe736be019 Mon Sep 17 00:00:00 2001 From: Randy Pan Date: Wed, 18 May 2016 11:19:51 -0700 Subject: WifiConnectivityManager: partial scan only when connected Starts partial scan only when Wifi is connected and traffic is heavy. This is to work around an issue that WifiInfo tx/rx rate is not updated to reflect the Wifi state. Ideally the tx/rx rate should have been reset to 0 when Wifi is disconnected. Bug: 28831562 Change-Id: Ifa415b14e2b216654ddd8a2a0c885754da489bef Test: Wifi Framework Unit Tests, manual tests --- .../java/com/android/server/wifi/WifiConnectivityManager.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 8200ef633..dd182dd16 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -663,10 +663,11 @@ public class WifiConnectivityManager { boolean isFullBandScan = true; // If the WiFi traffic is heavy, only partial scan is initiated. - if (mWifiInfo.txSuccessRate - > mConfigManager.MAX_TX_PACKET_FOR_FULL_SCANS - || mWifiInfo.rxSuccessRate - > mConfigManager.MAX_RX_PACKET_FOR_FULL_SCANS) { + if (mWifiState == WIFI_STATE_CONNECTED + && (mWifiInfo.txSuccessRate + > mConfigManager.MAX_TX_PACKET_FOR_FULL_SCANS + || mWifiInfo.rxSuccessRate + > mConfigManager.MAX_RX_PACKET_FOR_FULL_SCANS)) { localLog("No full band scan due to heavy traffic, txSuccessRate=" + mWifiInfo.txSuccessRate + " rxSuccessRate=" + mWifiInfo.rxSuccessRate); -- cgit v1.2.3 From 9bcdc174e4d0ec2b2a99a0933d619902e9d4a611 Mon Sep 17 00:00:00 2001 From: Mitchell Wills Date: Thu, 9 Jun 2016 09:39:25 -0700 Subject: Fix crashes in significant change when wifi hasn't started The SignificantChange state machine doesn't actually have a concept of if Wifi is on or not. This will simply ensure that it is not possible to cause a crash. Change-Id: I8ff87364bf7d5c87f0519b6cdc32d164facf30eb Fixes: 29237535 --- .../android/server/wifi/scanner/WifiScanningServiceImpl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java index a82ce1f25..5c085432a 100644 --- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java +++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java @@ -2373,12 +2373,16 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } private void trackSignificantWifiChange(WifiScanner.WifiChangeSettings settings) { - mScannerImpl.untrackSignificantWifiChange(); - mScannerImpl.trackSignificantWifiChange(settings, this); + if (mScannerImpl != null) { + mScannerImpl.untrackSignificantWifiChange(); + mScannerImpl.trackSignificantWifiChange(settings, this); + } } private void untrackSignificantWifiChange() { - mScannerImpl.untrackSignificantWifiChange(); + if (mScannerImpl != null) { + mScannerImpl.untrackSignificantWifiChange(); + } } private void addWifiChangeHandler(ClientInfo ci, int handler) { -- cgit v1.2.3