diff options
4 files changed, 135 insertions, 20 deletions
diff --git a/service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java b/service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java index 95f17b364..2d481ec45 100644 --- a/service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java +++ b/service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java @@ -23,9 +23,12 @@ import android.net.RecommendationResult; import android.net.WifiKey; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; import android.net.wifi.WifiNetworkScoreCache; +import android.os.Process; import android.util.LocalLog; import android.util.Pair; +import android.util.Slog; import com.android.server.wifi.util.ScanResultUtil; @@ -37,6 +40,7 @@ import java.util.List; * {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}. */ public class RecommendedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluator { + private static final String TAG = "RecNetEvaluator"; private final NetworkScoreManager mNetworkScoreManager; private final WifiNetworkScoreCache mNetworkScoreCache; private final WifiConfigManager mWifiConfigManager; @@ -107,22 +111,64 @@ public class RecommendedNetworkEvaluator implements WifiNetworkSelector.NetworkE return null; } + ScanResult[] scanResultArray = scanResults.toArray(new ScanResult[scanResults.size()]); RecommendationRequest request = new RecommendationRequest.Builder() - .setScanResults(scanResults.toArray(new ScanResult[scanResults.size()])) + .setScanResults(scanResultArray) // TODO: pass in currently recommended network .build(); RecommendationResult result = mNetworkScoreManager.requestRecommendation(request); - if (result != null && result.getWifiConfiguration() != null) { - WifiConfiguration wifiConfiguration = result.getWifiConfiguration(); - // TODO(b/33490132): Get recommended ScanResult and optionally create a - // WifiConfiguration for untrusted networks. Also call setNetworkCandidateScanResult. - return wifiConfiguration; + if (result == null || result.getWifiConfiguration() == null) { + return null; + } + + WifiConfiguration wifiConfiguration = result.getWifiConfiguration(); + ScanResult scanResult = findMatchingScanResult(scanResultArray, wifiConfiguration); + if (scanResult == null) { + Slog.e(TAG, "Could not match WifiConfiguration to a ScanResult."); + return null; + } + + int networkId = wifiConfiguration.networkId; + if (networkId == WifiConfiguration.INVALID_NETWORK_ID) { + networkId = addEphemeralNetwork(wifiConfiguration, scanResult); + if (networkId == WifiConfiguration.INVALID_NETWORK_ID) { + return null; + } + } + mWifiConfigManager.setNetworkCandidateScanResult(networkId, scanResult, 0 /* score */); + return mWifiConfigManager.getConfiguredNetwork(networkId); + } + + private ScanResult findMatchingScanResult(ScanResult[] scanResults, + WifiConfiguration wifiConfiguration) { + String ssid = WifiInfo.removeDoubleQuotes(wifiConfiguration.SSID); + String bssid = wifiConfiguration.BSSID; + for (int i = 0; i < scanResults.length; i++) { + if (ssid.equals(scanResults[i].SSID) && bssid.equals(scanResults[i].BSSID)) { + return scanResults[i]; + } } return null; } + private int addEphemeralNetwork(WifiConfiguration wifiConfiguration, ScanResult scanResult) { + if (wifiConfiguration.allowedKeyManagement.isEmpty()) { + ScanResultUtil.setAllowedKeyManagementFromScanResult(scanResult, + wifiConfiguration); + } + wifiConfiguration.ephemeral = true; + NetworkUpdateResult networkUpdateResult = mWifiConfigManager + .addOrUpdateNetwork(wifiConfiguration, Process.WIFI_UID); + if (networkUpdateResult.isSuccess()) { + return networkUpdateResult.getNetworkId(); + } + mLocalLog.log("Failed to add ephemeral network for networkId: " + + WifiNetworkSelector.toScanId(scanResult)); + return WifiConfiguration.INVALID_NETWORK_ID; + } + @Override public String getName() { - return "RecommendedNetworkEvaluator"; + return TAG; } } diff --git a/service/java/com/android/server/wifi/WifiSupplicantControl.java b/service/java/com/android/server/wifi/WifiSupplicantControl.java index 138126999..1acc4ae5e 100644 --- a/service/java/com/android/server/wifi/WifiSupplicantControl.java +++ b/service/java/com/android/server/wifi/WifiSupplicantControl.java @@ -20,6 +20,7 @@ import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; +import android.net.wifi.WifiInfo; import android.net.wifi.WifiSsid; import android.net.wifi.WpsInfo; import android.net.wifi.WpsResult; @@ -91,15 +92,6 @@ public class WifiSupplicantControl { mFileObserver.startWatching(); } - private static String removeDoubleQuotes(String string) { - int length = string.length(); - if ((length > 1) && (string.charAt(0) == '"') - && (string.charAt(length - 1) == '"')) { - return string.substring(1, length - 1); - } - return string; - } - /** * Generate a string to be used as a key value by wpa_supplicant from * 'set', within the set of strings from 'strings' for the variable concatenated. @@ -963,7 +955,7 @@ public class WifiSupplicantControl { String value = mWifiNative.getNetworkVariable(mNetId, key); if (!TextUtils.isEmpty(value)) { if (!enterpriseConfigKeyShouldBeQuoted(key)) { - value = removeDoubleQuotes(value); + value = WifiInfo.removeDoubleQuotes(value); } return value; } else { diff --git a/service/java/com/android/server/wifi/util/ScanResultUtil.java b/service/java/com/android/server/wifi/util/ScanResultUtil.java index 9ba54bb32..0e08701a7 100644 --- a/service/java/com/android/server/wifi/util/ScanResultUtil.java +++ b/service/java/com/android/server/wifi/util/ScanResultUtil.java @@ -124,6 +124,16 @@ public class ScanResultUtil { public static WifiConfiguration createNetworkFromScanResult(ScanResult scanResult) { WifiConfiguration config = new WifiConfiguration(); config.SSID = createQuotedSSID(scanResult.SSID); + setAllowedKeyManagementFromScanResult(scanResult, config); + return config; + } + + /** + * Sets the {@link WifiConfiguration#allowedKeyManagement} field on the given + * {@link WifiConfiguration} based on its corresponding {@link ScanResult}. + */ + public static void setAllowedKeyManagementFromScanResult(ScanResult scanResult, + WifiConfiguration config) { if (isScanResultForPskNetwork(scanResult)) { config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); } else if (isScanResultForEapNetwork(scanResult)) { @@ -136,7 +146,5 @@ public class ScanResultUtil { } else { config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); } - return config; } - } diff --git a/tests/wifitests/src/com/android/server/wifi/RecommendedNetworkEvaluatorTest.java b/tests/wifitests/src/com/android/server/wifi/RecommendedNetworkEvaluatorTest.java index 824c7feb3..b97447077 100644 --- a/tests/wifitests/src/com/android/server/wifi/RecommendedNetworkEvaluatorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/RecommendedNetworkEvaluatorTest.java @@ -19,8 +19,10 @@ package com.android.server.wifi; import static junit.framework.Assert.assertNull; import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @@ -30,9 +32,11 @@ import android.net.NetworkScoreManager; import android.net.RecommendationRequest; import android.net.RecommendationResult; import android.net.WifiKey; +import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.WifiSsid; +import android.os.Process; import android.test.suitebuilder.annotation.SmallTest; import android.util.LocalLog; @@ -57,12 +61,16 @@ public class RecommendedNetworkEvaluatorTest { private static final ScanDetail TRUSTED_SCAN_DETAIL = buildScanDetail("ssid"); private static final ScanDetail UNTRUSTED_SCAN_DETAIL = buildScanDetail("ssid1"); private static final WifiConfiguration TRUSTED_WIFI_CONFIGURATION = new WifiConfiguration(); + private static final WifiConfiguration UNTRUSTED_WIFI_CONFIGURATION = new WifiConfiguration(); static { TRUSTED_WIFI_CONFIGURATION.networkId = 5; TRUSTED_WIFI_CONFIGURATION.SSID = TRUSTED_SCAN_DETAIL.getSSID(); TRUSTED_WIFI_CONFIGURATION.BSSID = TRUSTED_SCAN_DETAIL.getBSSIDString(); TRUSTED_WIFI_CONFIGURATION.getNetworkSelectionStatus().setCandidate( TRUSTED_SCAN_DETAIL.getScanResult()); + + UNTRUSTED_WIFI_CONFIGURATION.SSID = UNTRUSTED_SCAN_DETAIL.getSSID(); + UNTRUSTED_WIFI_CONFIGURATION.BSSID = UNTRUSTED_SCAN_DETAIL.getBSSIDString(); } @Mock private NetworkScoreManager mNetworkScoreManager; @@ -85,6 +93,8 @@ public class RecommendedNetworkEvaluatorTest { .thenReturn(TRUSTED_WIFI_CONFIGURATION); when(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(UNTRUSTED_SCAN_DETAIL)) .thenReturn(null); + when(mWifiConfigManager.getConfiguredNetwork(TRUSTED_WIFI_CONFIGURATION.networkId)) + .thenReturn(TRUSTED_WIFI_CONFIGURATION); } @Test @@ -165,6 +175,8 @@ public class RecommendedNetworkEvaluatorTest { when(mNetworkScoreManager.requestRecommendation(any(RecommendationRequest.class))) .thenReturn(RecommendationResult .createConnectRecommendation(TRUSTED_WIFI_CONFIGURATION)); + when(mWifiConfigManager.addOrUpdateNetwork(TRUSTED_WIFI_CONFIGURATION, Process.WIFI_UID)) + .thenReturn(new NetworkUpdateResult(TRUSTED_WIFI_CONFIGURATION.networkId)); WifiConfiguration result = mRecommendedNetworkEvaluator.evaluateNetworks( Lists.newArrayList(TRUSTED_SCAN_DETAIL, UNTRUSTED_SCAN_DETAIL), @@ -175,10 +187,12 @@ public class RecommendedNetworkEvaluatorTest { assertEquals(1, mRecommendationRequestCaptor.getValue().getScanResults().length); assertEquals(TRUSTED_SCAN_DETAIL.getScanResult(), mRecommendationRequestCaptor.getValue().getScanResults()[0]); + verify(mWifiConfigManager).setNetworkCandidateScanResult( + TRUSTED_WIFI_CONFIGURATION.networkId, TRUSTED_SCAN_DETAIL.getScanResult(), 0); } @Test - public void testEvaluateNetworks_recommendation_untrustedNetworksAllowed() { + public void testEvaluateNetworks_trustedRecommendation_untrustedNetworksAllowed() { when(mWifiConfigManager.wasEphemeralNetworkDeleted(anyString())).thenReturn(false); when(mNetworkScoreManager.requestRecommendation(any(RecommendationRequest.class))) .thenReturn(RecommendationResult @@ -195,6 +209,61 @@ public class RecommendedNetworkEvaluatorTest { mRecommendationRequestCaptor.getValue().getScanResults()[0]); assertEquals(UNTRUSTED_SCAN_DETAIL.getScanResult(), mRecommendationRequestCaptor.getValue().getScanResults()[1]); + verify(mWifiConfigManager).setNetworkCandidateScanResult( + TRUSTED_WIFI_CONFIGURATION.networkId, TRUSTED_SCAN_DETAIL.getScanResult(), 0); + } + + @Test + public void testEvaluateNetworks_untrustedRecommendation_untrustedNetworksAllowed() { + NetworkUpdateResult networkUpdateResult = new NetworkUpdateResult(10); + when(mWifiConfigManager.addOrUpdateNetwork(UNTRUSTED_WIFI_CONFIGURATION, Process.WIFI_UID)) + .thenReturn(networkUpdateResult); + when(mWifiConfigManager.getConfiguredNetwork(networkUpdateResult.getNetworkId())) + .thenReturn(UNTRUSTED_WIFI_CONFIGURATION); + when(mWifiConfigManager.wasEphemeralNetworkDeleted(anyString())).thenReturn(false); + when(mNetworkScoreManager.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn(RecommendationResult + .createConnectRecommendation(UNTRUSTED_WIFI_CONFIGURATION)); + + WifiConfiguration result = mRecommendedNetworkEvaluator.evaluateNetworks( + Lists.newArrayList(TRUSTED_SCAN_DETAIL, UNTRUSTED_SCAN_DETAIL), + null, null, false, true /* untrustedNetworkAllowed */, null); + + assertEquals(UNTRUSTED_WIFI_CONFIGURATION, result); + verify(mNetworkScoreManager).requestRecommendation(mRecommendationRequestCaptor.capture()); + assertEquals(2, mRecommendationRequestCaptor.getValue().getScanResults().length); + assertEquals(TRUSTED_SCAN_DETAIL.getScanResult(), + mRecommendationRequestCaptor.getValue().getScanResults()[0]); + assertEquals(UNTRUSTED_SCAN_DETAIL.getScanResult(), + mRecommendationRequestCaptor.getValue().getScanResults()[1]); + verify(mWifiConfigManager).setNetworkCandidateScanResult( + networkUpdateResult.getNetworkId(), UNTRUSTED_SCAN_DETAIL.getScanResult(), 0); + } + + @Test + public void testEvaluateNetworks_untrustedRecommendation_updateFailed() { + NetworkUpdateResult networkUpdateResult = new NetworkUpdateResult( + WifiConfiguration.INVALID_NETWORK_ID); + when(mWifiConfigManager.addOrUpdateNetwork(UNTRUSTED_WIFI_CONFIGURATION, Process.WIFI_UID)) + .thenReturn(networkUpdateResult); + when(mWifiConfigManager.wasEphemeralNetworkDeleted(anyString())).thenReturn(false); + when(mNetworkScoreManager.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn(RecommendationResult + .createConnectRecommendation(UNTRUSTED_WIFI_CONFIGURATION)); + + WifiConfiguration result = mRecommendedNetworkEvaluator.evaluateNetworks( + Lists.newArrayList(TRUSTED_SCAN_DETAIL, UNTRUSTED_SCAN_DETAIL), + null, null, false, true /* untrustedNetworkAllowed */, null); + + assertNull(result); + verify(mNetworkScoreManager).requestRecommendation(mRecommendationRequestCaptor.capture()); + assertEquals(2, mRecommendationRequestCaptor.getValue().getScanResults().length); + assertEquals(TRUSTED_SCAN_DETAIL.getScanResult(), + mRecommendationRequestCaptor.getValue().getScanResults()[0]); + assertEquals(UNTRUSTED_SCAN_DETAIL.getScanResult(), + mRecommendationRequestCaptor.getValue().getScanResults()[1]); + verify(mWifiConfigManager, never()) + .setNetworkCandidateScanResult(anyInt(), any(ScanResult.class), anyInt()); } @Test |