[Wi-Fi] Force users to select a phase2 authentication for PEAP & TTLS

To improve security.

Bug: 143601727
Test: make RunSettingsRoboTests ROBOTEST_FILTER=WifiConfigControllerTest
Change-Id: Idb93d5ca1eb81bdcc2bc139679f72053161e3e35
Merged-In: I0cb1ceda6d89a52224f80ea5ffd1af709a6acace
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index 0a25934..50c22a2 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -156,8 +156,7 @@
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
                             style="@style/wifi_item_spinner"
-                            android:prompt="@string/please_select_phase2"
-                            android:entries="@array/wifi_phase2_entries" />
+                            android:prompt="@string/please_select_phase2" />
                 </LinearLayout>
 
                 <LinearLayout android:id="@+id/l_ca_cert"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 194e8fb..09447b9 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -368,14 +368,12 @@
 
     <!-- Phase 2 options for PEAP -->
     <string-array name="wifi_peap_phase2_entries">
-        <item>None</item>
         <item>MSCHAPV2</item>
         <item>GTC</item>
     </string-array>
 
     <!-- Type of EAP method when EAP SIM, AKA, AKA' are supported -->
     <string-array name="wifi_peap_phase2_entries_with_sim_auth">
-        <item>None</item>
         <item translatable="false">MSCHAPV2</item>
         <item translatable="false">GTC</item>
         <item translatable="false">SIM</item>
@@ -383,9 +381,8 @@
         <item translatable="false">AKA\'</item>
     </string-array>
 
-    <!-- Phase 2 options for rest of EAP methods -->
-    <string-array name="wifi_phase2_entries">
-        <item>None</item>
+    <!-- Phase 2 options for TTLS -->
+    <string-array name="wifi_ttls_phase2_entries">
         <item>PAP</item>
         <item>MSCHAP</item>
         <item>MSCHAPV2</item>
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 48c9e54..27ac69d 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -113,18 +113,22 @@
     public static final int WIFI_EAP_METHOD_AKA_PRIME  = 6;
 
     /* These values come from "wifi_peap_phase2_entries" resource array */
-    public static final int WIFI_PEAP_PHASE2_NONE       = 0;
-    public static final int WIFI_PEAP_PHASE2_MSCHAPV2   = 1;
-    public static final int WIFI_PEAP_PHASE2_GTC        = 2;
-    public static final int WIFI_PEAP_PHASE2_SIM        = 3;
-    public static final int WIFI_PEAP_PHASE2_AKA        = 4;
-    public static final int WIFI_PEAP_PHASE2_AKA_PRIME  = 5;
+    public static final int WIFI_PEAP_PHASE2_MSCHAPV2   = 0;
+    public static final int WIFI_PEAP_PHASE2_GTC        = 1;
+    public static final int WIFI_PEAP_PHASE2_SIM        = 2;
+    public static final int WIFI_PEAP_PHASE2_AKA        = 3;
+    public static final int WIFI_PEAP_PHASE2_AKA_PRIME  = 4;
 
+    /* These values come from "wifi_ttls_phase2_entries" resource array */
+    public static final int WIFI_TTLS_PHASE2_PAP       = 0;
+    public static final int WIFI_TTLS_PHASE2_MSCHAP    = 1;
+    public static final int WIFI_TTLS_PHASE2_MSCHAPV2  = 2;
+    public static final int WIFI_TTLS_PHASE2_GTC       = 3;
 
     /* Phase2 methods supported by PEAP are limited */
-    private ArrayAdapter<String> mPhase2PeapAdapter;
-    /* Full list of phase2 methods */
-    private ArrayAdapter<String> mPhase2FullAdapter;
+    private ArrayAdapter<CharSequence> mPhase2PeapAdapter;
+    /* Phase2 methods supported by TTLS are limited */
+    private ArrayAdapter<CharSequence> mPhase2TtlsAdapter;
 
     // e.g. AccessPoint.SECURITY_NONE
     @VisibleForTesting
@@ -145,8 +149,8 @@
     private Spinner mEapCaCertSpinner;
     private TextView mEapDomainView;
     private Spinner mPhase2Spinner;
-    // Associated with mPhase2Spinner, one of mPhase2FullAdapter or mPhase2PeapAdapter
-    private ArrayAdapter<String> mPhase2Adapter;
+    // Associated with mPhase2Spinner, one of mPhase2TtlsAdapter or mPhase2PeapAdapter
+    private ArrayAdapter<CharSequence> mPhase2Adapter;
     private Spinner mEapUserCertSpinner;
     private TextView mEapIdentityView;
     private TextView mEapAnonymousView;
@@ -221,20 +225,20 @@
         mLevels = res.getStringArray(R.array.wifi_signal);
         if (Utils.isWifiOnly(mContext) || !mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_eap_sim_based_auth_supported)) {
-            mPhase2PeapAdapter = new ArrayAdapter<String>(
+            mPhase2PeapAdapter = new ArrayAdapter<CharSequence>(
                     mContext, android.R.layout.simple_spinner_item,
                     res.getStringArray(R.array.wifi_peap_phase2_entries));
         } else {
-            mPhase2PeapAdapter = new ArrayAdapter<String>(
+            mPhase2PeapAdapter = new ArrayAdapter<CharSequence>(
                     mContext, android.R.layout.simple_spinner_item,
                     res.getStringArray(R.array.wifi_peap_phase2_entries_with_sim_auth));
         }
         mPhase2PeapAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 
-        mPhase2FullAdapter = new ArrayAdapter<String>(
+        mPhase2TtlsAdapter = new ArrayAdapter<CharSequence>(
                 mContext, android.R.layout.simple_spinner_item,
-                res.getStringArray(R.array.wifi_phase2_entries));
-        mPhase2FullAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                res.getStringArray(R.array.wifi_ttls_phase2_entries));
+        mPhase2TtlsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 
         mUnspecifiedCertString = mContext.getString(R.string.wifi_unspecified);
         mMultipleCertSetString = mContext.getString(R.string.wifi_multiple_cert_added);
@@ -662,9 +666,6 @@
                         // Map the index from the mPhase2PeapAdapter to the one used
                         // by the API which has the full list of PEAP methods.
                         switch(phase2Method) {
-                            case WIFI_PEAP_PHASE2_NONE:
-                                config.enterpriseConfig.setPhase2Method(Phase2.NONE);
-                                break;
                             case WIFI_PEAP_PHASE2_MSCHAPV2:
                                 config.enterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
                                 break;
@@ -685,9 +686,27 @@
                                 break;
                         }
                         break;
+                    case Eap.TTLS:
+                        // The default index from mPhase2TtlsAdapter maps to the API
+                        switch(phase2Method) {
+                            case WIFI_TTLS_PHASE2_PAP:
+                                config.enterpriseConfig.setPhase2Method(Phase2.PAP);
+                                break;
+                            case WIFI_TTLS_PHASE2_MSCHAP:
+                                config.enterpriseConfig.setPhase2Method(Phase2.MSCHAP);
+                                break;
+                            case WIFI_TTLS_PHASE2_MSCHAPV2:
+                                config.enterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
+                                break;
+                            case WIFI_TTLS_PHASE2_GTC:
+                                config.enterpriseConfig.setPhase2Method(Phase2.GTC);
+                                break;
+                            default:
+                                Log.e(TAG, "Unknown phase2 method" + phase2Method);
+                                break;
+                        }
+                        break;
                     default:
-                        // The default index from mPhase2FullAdapter maps to the API
-                        config.enterpriseConfig.setPhase2Method(phase2Method);
                         break;
                 }
 
@@ -1024,9 +1043,6 @@
             switch (eapMethod) {
                 case Eap.PEAP:
                     switch (phase2Method) {
-                        case Phase2.NONE:
-                            mPhase2Spinner.setSelection(WIFI_PEAP_PHASE2_NONE);
-                            break;
                         case Phase2.MSCHAPV2:
                             mPhase2Spinner.setSelection(WIFI_PEAP_PHASE2_MSCHAPV2);
                             break;
@@ -1047,8 +1063,26 @@
                             break;
                     }
                     break;
+                case Eap.TTLS:
+                    switch (phase2Method) {
+                        case Phase2.PAP:
+                            mPhase2Spinner.setSelection(WIFI_TTLS_PHASE2_PAP);
+                            break;
+                        case Phase2.MSCHAP:
+                            mPhase2Spinner.setSelection(WIFI_TTLS_PHASE2_MSCHAP);
+                            break;
+                        case Phase2.MSCHAPV2:
+                            mPhase2Spinner.setSelection(WIFI_TTLS_PHASE2_MSCHAPV2);
+                            break;
+                        case Phase2.GTC:
+                            mPhase2Spinner.setSelection(WIFI_TTLS_PHASE2_GTC);
+                            break;
+                        default:
+                            Log.e(TAG, "Invalid phase 2 method " + phase2Method);
+                            break;
+                    }
+                    break;
                 default:
-                    mPhase2Spinner.setSelection(phase2Method);
                     break;
             }
             if (!TextUtils.isEmpty(enterpriseConfig.getCaPath())) {
@@ -1146,8 +1180,8 @@
                 break;
             case WIFI_EAP_METHOD_TTLS:
                 // Reset adapter if needed
-                if (mPhase2Adapter != mPhase2FullAdapter) {
-                    mPhase2Adapter = mPhase2FullAdapter;
+                if (mPhase2Adapter != mPhase2TtlsAdapter) {
+                    mPhase2Adapter = mPhase2TtlsAdapter;
                     mPhase2Spinner.setAdapter(mPhase2Adapter);
                 }
                 mView.findViewById(R.id.l_phase2).setVisibility(View.VISIBLE);
@@ -1198,12 +1232,10 @@
 
     private void setIdentityInvisible() {
         mView.findViewById(R.id.l_identity).setVisibility(View.GONE);
-        mPhase2Spinner.setSelection(Phase2.NONE);
     }
 
     private void setPhase2Invisible() {
         mView.findViewById(R.id.l_phase2).setVisibility(View.GONE);
-        mPhase2Spinner.setSelection(Phase2.NONE);
     }
 
     private void setCaCertInvisible() {
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
index 669a2e6..ac5fa08 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
@@ -30,6 +30,7 @@
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiEnterpriseConfig.Eap;
+import android.net.wifi.WifiEnterpriseConfig.Phase2;
 import android.net.wifi.WifiManager;
 import android.os.ServiceSpecificException;
 import android.security.KeyStore;
@@ -484,9 +485,25 @@
         mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint,
                 WifiConfigUiBase.MODE_MODIFY);
         final Spinner eapMethodSpinner = mView.findViewById(R.id.method);
+        final Spinner phase2Spinner = mView.findViewById(R.id.phase2);
+        WifiConfiguration wifiConfiguration;
 
-        eapMethodSpinner.setSelection(Eap.TLS);
+        // Test EAP method PEAP
+        eapMethodSpinner.setSelection(Eap.PEAP);
+        phase2Spinner.setSelection(WifiConfigController.WIFI_PEAP_PHASE2_MSCHAPV2);
+        wifiConfiguration = mController.getConfig();
 
-        assertThat(eapMethodSpinner.getSelectedItemPosition()).isEqualTo(Eap.TLS);
+        assertThat(wifiConfiguration.enterpriseConfig.getEapMethod()).isEqualTo(Eap.PEAP);
+        assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(
+                Phase2.MSCHAPV2);
+
+        // Test EAP method TTLS
+        eapMethodSpinner.setSelection(Eap.TTLS);
+        phase2Spinner.setSelection(WifiConfigController.WIFI_TTLS_PHASE2_MSCHAPV2);
+        wifiConfiguration = mController.getConfig();
+
+        assertThat(wifiConfiguration.enterpriseConfig.getEapMethod()).isEqualTo(Eap.TTLS);
+        assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(
+                Phase2.MSCHAPV2);
     }
 }