Merge "Implement getConfig() method to get WifiConfiguration"
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index efb3f8c..c627a2e 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -129,8 +129,16 @@
         }
 
         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 ff8570e..7970b2a 100644
--- a/src/com/android/settings/wifi/WifiUtils.java
+++ b/src/com/android/settings/wifi/WifiUtils.java
@@ -22,10 +22,13 @@
 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 @@
         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 c9cdc15..343d170 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 @@
         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 a95624b..9de095d 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.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 @@
         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