From 64b894f81d732f4a8712b9b5df6b603397389843 Mon Sep 17 00:00:00 2001 From: cosmohsieh Date: Wed, 12 Dec 2018 10:14:54 +0800 Subject: [PATCH] Implement getConfig() method to get WifiConfiguration Make a duplicated function of WifiConfigController.getConfig(). This function could get a new WifiConfiguration from input AccessPoint or ScanResult. Should be removed if there is standard one in framework. Bug: 120827021 Test: RunSettingsRoboTests Change-Id: Ia5981e8d41f434c097b464a2bfe18e1356f7b087 --- .../wifi/NetworkRequestDialogFragment.java | 12 +- src/com/android/settings/wifi/WifiUtils.java | 143 ++++++++++++++++++ .../NetworkRequestDialogFragmentTest.java | 3 + .../android/settings/wifi/WifiUtilsTest.java | 31 +++- 4 files changed, 186 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java index efb3f8cd3a5..c627a2e6628 100644 --- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java +++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java @@ -129,8 +129,16 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp } if (which < accessPointList.size()) { - WifiConfiguration wifiConfig = accessPointList.get(which).getConfig(); - mUserSelectionCallback.select(wifiConfig); + final AccessPoint selectedAccessPoint = accessPointList.get(which); + WifiConfiguration wifiConfig = selectedAccessPoint.getConfig(); + if (wifiConfig == null) { + wifiConfig = WifiUtils.getWifiConfig(selectedAccessPoint, /* scanResult */ + null, /* password */ null); + } + + if (wifiConfig != null) { + mUserSelectionCallback.select(wifiConfig); + } } } diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java index ff8570e7a59..7970b2a6edd 100644 --- a/src/com/android/settings/wifi/WifiUtils.java +++ b/src/com/android/settings/wifi/WifiUtils.java @@ -22,10 +22,13 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.net.NetworkCapabilities; +import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.provider.Settings; import android.text.TextUtils; +import com.android.settingslib.wifi.AccessPoint; + import java.nio.charset.StandardCharsets; public class WifiUtils { @@ -110,4 +113,144 @@ public class WifiUtils { return (capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)); } + + /** + * Provides a simple way to generate a new {@link WifiConfiguration} obj from + * {@link ScanResult} or {@link AccessPoint}. Either {@code accessPoint} or {@code scanResult + * } input should be not null for retrieving information, otherwise will throw + * IllegalArgumentException. + * This method prefers to take {@link AccessPoint} input in priority. Therefore this method + * will take {@link AccessPoint} input as preferred data extraction source when you input + * both {@link AccessPoint} and {@link ScanResult}, and ignore {@link ScanResult} input. + * + * Duplicated and simplified method from {@link WifiConfigController#getConfig()}. + * TODO(b/120827021): Should be removed if the there is have a common one in shared place (e.g. + * SettingsLib). + * + * @param accessPoint Input data for retrieving WifiConfiguration. + * @param scanResult Input data for retrieving WifiConfiguration. + * @return WifiConfiguration obj based on input. + */ + public static WifiConfiguration getWifiConfig(AccessPoint accessPoint, ScanResult scanResult, + String password) { + if (accessPoint == null && scanResult == null) { + throw new IllegalArgumentException( + "At least one of AccessPoint and ScanResult input is required."); + } + + final WifiConfiguration config = new WifiConfiguration(); + final int security; + + if (accessPoint == null) { + config.SSID = AccessPoint.convertToQuotedString(scanResult.SSID); + security = getAccessPointSecurity(scanResult); + } else { + if (!accessPoint.isSaved()) { + config.SSID = AccessPoint.convertToQuotedString( + accessPoint.getSsidStr()); + } else { + config.networkId = accessPoint.getConfig().networkId; + config.hiddenSSID = accessPoint.getConfig().hiddenSSID; + } + security = accessPoint.getSecurity(); + } + + switch (security) { + case AccessPoint.SECURITY_NONE: + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + break; + + case AccessPoint.SECURITY_WEP: + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); + config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); + if (!TextUtils.isEmpty(password)) { + int length = password.length(); + // WEP-40, WEP-104, and 256-bit WEP (WEP-232?) + if ((length == 10 || length == 26 || length == 58) + && password.matches("[0-9A-Fa-f]*")) { + config.wepKeys[0] = password; + } else { + config.wepKeys[0] = '"' + password + '"'; + } + } + break; + + case AccessPoint.SECURITY_PSK: + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + if (!TextUtils.isEmpty(password)) { + if (password.matches("[0-9A-Fa-f]{64}")) { + config.preSharedKey = password; + } else { + config.preSharedKey = '"' + password + '"'; + } + } + break; + + case AccessPoint.SECURITY_EAP: + case AccessPoint.SECURITY_EAP_SUITE_B: + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); + if (security == AccessPoint.SECURITY_EAP_SUITE_B) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); + config.requirePMF = true; + config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256); + config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); + config.allowedGroupMgmtCiphers.set(WifiConfiguration.GroupMgmtCipher + .BIP_GMAC_256); + config.allowedSuiteBCiphers.set(WifiConfiguration.SuiteBCipher.ECDHE_RSA); + } + + if (!TextUtils.isEmpty(password)) { + config.enterpriseConfig.setPassword(password); + } + break; + case AccessPoint.SECURITY_SAE: + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); + config.requirePMF = true; + if (!TextUtils.isEmpty(password)) { + config.preSharedKey = '"' + password + '"'; + } + break; + + case AccessPoint.SECURITY_OWE: + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); + config.requirePMF = true; + break; + + default: + break; + } + + return config; + } + + + /** + * Gets security value from ScanResult. + * + * Duplicated method from {@link AccessPoint#getSecurity(ScanResult)}. + * TODO(b/120827021): Should be removed if the there is have a common one in shared place (e.g. + * SettingsLib). + * + * @param result ScanResult + * @return Related security value based on {@link AccessPoint}. + */ + public static int getAccessPointSecurity(ScanResult result) { + if (result.capabilities.contains("WEP")) { + return AccessPoint.SECURITY_WEP; + } else if (result.capabilities.contains("SAE")) { + return AccessPoint.SECURITY_SAE; + } else if (result.capabilities.contains("PSK")) { + return AccessPoint.SECURITY_PSK; + } else if (result.capabilities.contains("EAP_SUITE_B_192")) { + return AccessPoint.SECURITY_EAP_SUITE_B; + } else if (result.capabilities.contains("EAP")) { + return AccessPoint.SECURITY_EAP; + } else if (result.capabilities.contains("OWE")) { + return AccessPoint.SECURITY_OWE; + } + + return AccessPoint.SECURITY_NONE; + } } diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java index c9cdc154356..343d170e7ed 100644 --- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java @@ -197,9 +197,12 @@ public class NetworkRequestDialogFragmentTest { accessPointList.add(new AccessPoint(mContext, bundle)); bundle.putString(KEY_SSID, "Test AP 2"); accessPointList.add(new AccessPoint(mContext, bundle)); + bundle.putString(KEY_SSID, "Test AP 3"); AccessPoint clickedAccessPoint = new AccessPoint(mContext, bundle); + clickedAccessPoint.generateOpenNetworkConfig(); accessPointList.add(clickedAccessPoint); + bundle.putString(KEY_SSID, "Test AP 4"); accessPointList.add(new AccessPoint(mContext, bundle)); when(networkRequestDialogFragment.getAccessPointList()).thenReturn(accessPointList); diff --git a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java index a95624b7ecc..9de095d14dd 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java @@ -22,6 +22,16 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.os.Bundle; + +import com.android.settingslib.wifi.AccessPoint; + +import org.robolectric.RuntimeEnvironment; + @RunWith(RobolectricTestRunner.class) public class WifiUtilsTest { @@ -44,4 +54,23 @@ public class WifiUtilsTest { assertThat(WifiUtils.isHotspotPasswordValid(longPassword)).isFalse(); assertThat(WifiUtils.isHotspotPasswordValid("")).isFalse(); } -} + + @Test + public void getWifiConfigByAccessPoint_shouldReturnCorrectConfig() { + String testSSID = "WifiUtilsTest"; + Bundle bundle = new Bundle(); + bundle.putString("key_ssid", testSSID); + Context context = spy(RuntimeEnvironment.application); + AccessPoint accessPoint = new AccessPoint(context, bundle); + + WifiConfiguration config = WifiUtils.getWifiConfig(accessPoint, null, null); + + assertThat(config).isNotNull(); + assertThat(config.SSID).isEqualTo(AccessPoint.convertToQuotedString(testSSID)); + } + + @Test(expected = IllegalArgumentException.class) + public void getWifiConfigWithNullInput_ThrowIllegalArgumentException() { + WifiConfiguration config = WifiUtils.getWifiConfig(null, null, null); + } +} \ No newline at end of file