From 86ea918f785f665e0fa41ddd5d6803d73ad72650 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 16 Apr 2018 11:06:27 -0700 Subject: WifiConnectivityManager: Add config flag for filtering DBS scans OEM's may want to disable this filtering logic for their devices. Bug: 78112990 Test: Unit tests Test: Ensured DBS scans are still filtered when enabled. Change-Id: Id3bf5b0f0be49c89341f87bac97f4e339d1eb27a --- .../server/wifi/WifiConnectivityManager.java | 9 +- .../server/wifi/WifiConnectivityManagerTest.java | 108 +++++++++++++++++---- 2 files changed, 95 insertions(+), 22 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 3b9d0ff21..aa4fd80df 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -164,6 +164,7 @@ public class WifiConnectivityManager { // Device configs private boolean mEnableAutoJoinWhenAssociated; private boolean mWaitForFullBandScanResults = false; + private boolean mUseSingleRadioChainScanResults = false; private int mFullScanMaxTxRate; private int mFullScanMaxRxRate; @@ -370,8 +371,10 @@ public class WifiConnectivityManager { } // When the scan result has radio chain info, ensure we throw away scan results - // not received with both radio chains. - if (ArrayUtils.size(fullScanResult.radioChainInfos) == 1) { + // not received with both radio chains (if |mUseSingleRadioChainScanResults| is false). + if (!mUseSingleRadioChainScanResults + && fullScanResult.radioChainInfos != null + && fullScanResult.radioChainInfos.length == 1) { // Keep track of the number of dropped scan results for logging. mNumScanResultsIgnoredDueToSingleRadioChain++; return; @@ -605,6 +608,8 @@ public class WifiConnectivityManager { R.integer.config_wifi_framework_SECURITY_AWARD); mEnableAutoJoinWhenAssociated = context.getResources().getBoolean( R.bool.config_wifi_framework_enable_associated_network_selection); + mUseSingleRadioChainScanResults = context.getResources().getBoolean( + R.bool.config_wifi_framework_use_single_radio_chain_scan_results_network_selection); mInitialScoreMax = (Math.max(mScoringParams.getGoodRssi(ScoringParams.BAND2), mScoringParams.getGoodRssi(ScoringParams.BAND5)) + context.getResources().getInteger( diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java index 6eaf767d1..36530edb8 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java @@ -1908,8 +1908,33 @@ public class WifiConnectivityManagerTest { } /** - * WifiConnectivityManager should filter scan results which contain scans from a single radio - * chain (i.e DBS scan). + * Create scan data with different radio chain infos: + * First scan result has null radio chain info (No DBS support). + * Second scan result has empty radio chain info (No DBS support). + * Third scan result has 1 radio chain info (DBS scan). + * Fourth scan result has 2 radio chain info (non-DBS scan). + */ + private ScanData createScanDataWithDifferentRadioChainInfos() { + // Create 4 scan results. + ScanData[] scanDatas = + ScanTestUtil.createScanDatas(new int[][]{{5150, 5175, 2412, 2400}}, new int[]{0}); + // WCM barfs if the scan result does not have an IE. + scanDatas[0].getResults()[0].informationElements = new InformationElement[0]; + scanDatas[0].getResults()[1].informationElements = new InformationElement[0]; + scanDatas[0].getResults()[2].informationElements = new InformationElement[0]; + scanDatas[0].getResults()[3].informationElements = new InformationElement[0]; + scanDatas[0].getResults()[0].radioChainInfos = null; + scanDatas[0].getResults()[1].radioChainInfos = new ScanResult.RadioChainInfo[0]; + scanDatas[0].getResults()[2].radioChainInfos = new ScanResult.RadioChainInfo[1]; + scanDatas[0].getResults()[3].radioChainInfos = new ScanResult.RadioChainInfo[2]; + + return scanDatas[0]; + } + + /** + * If |config_wifi_framework_use_single_radio_chain_scan_results_network_selection| flag is + * false, WifiConnectivityManager should filter scan results which contain scans from a single + * radio chain (i.e DBS scan). * Note: * a) ScanResult with no radio chain indicates a lack of DBS support on the device. * b) ScanResult with 2 radio chain info indicates a scan done using both the radio chains @@ -1920,27 +1945,15 @@ public class WifiConnectivityManagerTest { * after filtering out the scan results obtained via DBS scan. */ @Test - public void filterScanResultsWithOneRadioChainInfoForNetworkSelection() { + public void filterScanResultsWithOneRadioChainInfoForNetworkSelectionIfConfigDisabled() { + when(mResource.getBoolean( + R.bool.config_wifi_framework_use_single_radio_chain_scan_results_network_selection)) + .thenReturn(false); when(mWifiNS.selectNetwork(any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean())) .thenReturn(null); + mWifiConnectivityManager = createConnectivityManager(); - // Create 4 scan results. - ScanData[] scanDatas = - ScanTestUtil.createScanDatas(new int[][]{{5150, 5175, 2412, 2400}}, new int[]{0}); - mScanData = scanDatas[0]; - // WCM barfs if the scan result does not have an IE. - mScanData.getResults()[0].informationElements = new InformationElement[0]; - mScanData.getResults()[1].informationElements = new InformationElement[0]; - mScanData.getResults()[2].informationElements = new InformationElement[0]; - mScanData.getResults()[3].informationElements = new InformationElement[0]; - // First scan result has null radio chain info (No DBS support). - mScanData.getResults()[0].radioChainInfos = null; - // Second scan result has empty radio chain info (No DBS support). - mScanData.getResults()[1].radioChainInfos = new ScanResult.RadioChainInfo[0]; - // Third scan result has 1 radio chain info (DBS scan). - mScanData.getResults()[2].radioChainInfos = new ScanResult.RadioChainInfo[1]; - // Fourth scan result has 2 radio chain info (non-DBS scan). - mScanData.getResults()[3].radioChainInfos = new ScanResult.RadioChainInfo[2]; + mScanData = createScanDataWithDifferentRadioChainInfos(); // Capture scan details which were sent to network selector. final List capturedScanDetails = new ArrayList<>(); @@ -1955,6 +1968,7 @@ public class WifiConnectivityManagerTest { any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean()); // Set WiFi to disconnected state with screen on which triggers a scan immediately. + mWifiConnectivityManager.setWifiEnabled(true); mWifiConnectivityManager.handleScreenStateChanged(true); mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); @@ -1972,4 +1986,58 @@ public class WifiConnectivityManagerTest { assertTrue(capturedScanResults.contains(mScanData.getResults()[3])); } + /** + * If |config_wifi_framework_use_single_radio_chain_scan_results_network_selection| flag is + * true, WifiConnectivityManager should not filter scan results which contain scans from a + * single radio chain (i.e DBS scan). + * Note: + * a) ScanResult with no radio chain indicates a lack of DBS support on the device. + * b) ScanResult with 2 radio chain info indicates a scan done using both the radio chains + * on a DBS supported device. + * + * Expected behavior: WifiConnectivityManager invokes + * {@link WifiNetworkSelector#selectNetwork(List, HashSet, WifiInfo, boolean, boolean, boolean)} + * after filtering out the scan results obtained via DBS scan. + */ + @Test + public void dontFilterScanResultsWithOneRadioChainInfoForNetworkSelectionIfConfigEnabled() { + when(mResource.getBoolean( + R.bool.config_wifi_framework_use_single_radio_chain_scan_results_network_selection)) + .thenReturn(true); + when(mWifiNS.selectNetwork(any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean())) + .thenReturn(null); + mWifiConnectivityManager = createConnectivityManager(); + + mScanData = createScanDataWithDifferentRadioChainInfos(); + + // Capture scan details which were sent to network selector. + final List capturedScanDetails = new ArrayList<>(); + doAnswer(new AnswerWithArguments() { + public WifiConfiguration answer( + List scanDetails, HashSet bssidBlacklist, WifiInfo wifiInfo, + boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) + throws Exception { + capturedScanDetails.addAll(scanDetails); + return null; + }}).when(mWifiNS).selectNetwork( + any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean()); + + // Set WiFi to disconnected state with screen on which triggers a scan immediately. + mWifiConnectivityManager.setWifiEnabled(true); + mWifiConnectivityManager.handleScreenStateChanged(true); + mWifiConnectivityManager.handleConnectionStateChanged( + WifiConnectivityManager.WIFI_STATE_DISCONNECTED); + + // We should not filter any of the scan results. + assertEquals(4, capturedScanDetails.size()); + List capturedScanResults = + capturedScanDetails.stream().map(ScanDetail::getScanResult) + .collect(Collectors.toList()); + + assertEquals(4, capturedScanResults.size()); + assertTrue(capturedScanResults.contains(mScanData.getResults()[0])); + assertTrue(capturedScanResults.contains(mScanData.getResults()[1])); + assertTrue(capturedScanResults.contains(mScanData.getResults()[2])); + assertTrue(capturedScanResults.contains(mScanData.getResults()[3])); + } } -- cgit v1.2.3