Add EAP/802.1X configuration for WiFi Setting.

1. Remove the isEnterprise() filter in Scanresult.
2. This requires the new fields such as identity, eap, certificate/key
to support EAP authentication in Wifi Settings.
3. Add simple file-based keystore to select the cert/key from UI.

-- Updated from the comments.
-- Fix the bug for passing null pointer for adding spinner items.
diff --git a/res/layout/wifi_ap_configure.xml b/res/layout/wifi_ap_configure.xml
index d786cff..ecd6337 100644
--- a/res/layout/wifi_ap_configure.xml
+++ b/res/layout/wifi_ap_configure.xml
@@ -24,11 +24,17 @@
             android:padding="8dip"
             android:orientation="vertical"> 
     
-    
+            <LinearLayout
+                android:id="@+id/table"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:orientation="vertical">
+            </LinearLayout>
+
     
         <!-- SSID -->
     
-        <TextView
+        <TextView android:id="@+id/ssid_text"
                 style="?android:attr/textAppearanceSmallInverse"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
@@ -44,7 +50,7 @@
     
         <!-- Security -->
         
-        <TextView
+        <TextView android:id="@+id/security_text"
                 style="?android:attr/textAppearanceSmallInverse"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
@@ -55,9 +61,94 @@
         <Spinner android:id="@+id/security_spinner"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content" />
-                
-                
-        
+
+        <!-- Enterprise Fields -->
+        <LinearLayout android:id="@+id/enterprise_wrapper"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:padding="8dip"
+            android:orientation="vertical">
+                <TextView android:id="@+id/eap_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_select_eap" />
+                <Spinner android:id="@+id/eap_spinner"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content" />
+                <TextView android:id="@+id/phase2_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_select_phase2" />
+                <Spinner android:id="@+id/phase2_spinner"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content" />
+
+                <TextView android:id="@+id/identity_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_type_identity" />
+                <EditText android:id="@+id/identity_edit"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="2dip"
+                        android:singleLine="true" />
+                <TextView android:id="@+id/anonymous_identity_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_type_anonymous_identity" />
+                <EditText android:id="@+id/anonymous_identity_edit"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="2dip"
+                        android:singleLine="true" />
+                <TextView android:id="@+id/client_certificate_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_select_client_certificate" />
+                <Spinner android:id="@+id/client_certificate_spinner"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content" />
+                <TextView android:id="@+id/ca_certificate_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_select_ca_certificate" />
+                <Spinner android:id="@+id/ca_certificate_spinner"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content" />
+                <TextView android:id="@+id/private_key_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_select_private_key" />
+                <Spinner android:id="@+id/private_key_spinner"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content" />
+                <TextView android:id="@+id/private_key_passwd_text"
+                        style="?android:attr/textAppearanceSmallInverse"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="8dip"
+                        android:text="@string/please_type_private_key_passwd" />
+                <EditText android:id="@+id/private_key_passwd_edit"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="2dip"
+                        android:singleLine="true" />
+        </LinearLayout>
+
         <!-- Password -->
         
         <TextView android:id="@+id/password_text"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 6cfa7f0..72f56e7 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -93,9 +93,13 @@
         <!-- Do not translate. The Wi-Fi network has WEP security. -->
         <item>WEP</item>
         <!-- The Wi-Fi network has WPA personal security. WPA Personal is a tech term, and might be better left untranslated? -->
-        <item>WPA Personal</item>
+        <item>WPA personal</item>
         <!-- The Wi-Fi network has WPA2 personal security. WPA Personal is a tech term, and might be better left untranslated? -->
-        <item>WPA2 Personal</item>
+        <item>WPA2 personal</item>
+        <!-- The Wi-Fi network has WPA EAP extensible authentication protocol. -->
+        <item>WPA-EAP</item>
+        <!-- IEEE 802.1X key management -->
+        <item>IEEE 802.1x</item>
     </string-array>
 
     <!-- Match this with code. --> <skip />
@@ -106,9 +110,14 @@
         <!-- Do not translate. The Wi-Fi network has WEP security. -->
         <item>WEP</item>
         <!-- The Wi-Fi network has WPA personal security. WPA Personal is a tech term, and might be better left untranslated? -->
-        <item>WPA Personal</item>
+        <item>WPA personal</item>
         <!-- The Wi-Fi network has WPA2 personal security. WPA Personal is a tech term, and might be better left untranslated? -->
-        <item>WPA2 Personal</item>
+        <item>WPA2 personal</item>
+        <!-- The Wi-Fi network has WPA enterprise security. WPA Enterprise is a tech term, and might be better left untranslated? -->
+        <!-- The Wi-Fi network has WPA EAP extensible authentication protocol. -->
+        <item>WPA-EAP</item>
+        <!-- IEEE 802.1X key management -->
+        <item>IEEE 802.1x</item>
     </string-array>
 
     <!-- Match this with code. --> <skip />
@@ -167,4 +176,20 @@
         <item>Application Name</item>
     </string-array>
 
+    <!-- EAP method -->
+    <string-array name="wifi_eap_entries">
+        <item>PEAP</item>
+        <item>TLS</item>
+        <item>TTLS</item>
+    </string-array>
+
+    <!-- Phase 2 options -->
+    <string-array name="wifi_phase2_entries">
+        <item>None</item>
+        <item>PAP</item>
+        <item>MSCHAP</item>
+        <item>MSCHAP2</item>
+        <item>GTC</item>
+    </string-array>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 62120fc..07bfe2f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -614,6 +614,11 @@
     <string name="wifi_security_wpa">WPA</string>
     <!-- Value for the wifi security -->
     <string name="wifi_security_wpa2">WPA2</string>
+    <!-- Value for the wifi security -->
+    <string name="wifi_security_wpa_eap">WPA-EAP</string>
+    <!-- Value for the wifi security -->
+    <string name="wifi_security_ieee8021x">IEEE8021X</string>
+
     <!-- Value for the wifi security when it is unknown -->
     <string name="wifi_security_unknown">Unknown</string>
     <!-- Verbose security type of a wifi network.  Open means no security. -->
@@ -624,6 +629,10 @@
     <string name="wifi_security_verbose_wpa">Secured with WPA</string>
     <!-- Verbose security type of a wifi network.  -->
     <string name="wifi_security_verbose_wpa2">Secured with WPA2</string>
+    <!-- Verbose security type of a wifi network.  -->
+    <string name="wifi_security_verbose_wpa_eap">Secured with WPA-EAP</string>
+    <!-- Verbose security type of a wifi network.  -->
+    <string name="wifi_security_verbose_ieee8021x">Secured with IEEE 802.1x</string>
     <!-- Wi-Fi IP addrress label -->    
     <string name="ip_address">IP address</string>
     <!-- Label for the signal strength -->
@@ -648,6 +657,22 @@
     <string name="connect">Connect</string>
     <!-- Dialog title for when the user is trying to connect to a particular network-->
     <string name="connect_to_blank">Connect to <xliff:g id="network_name">%1$s</xliff:g></string>
+    <!-- Caption for the eap method -->
+    <string name="please_select_eap">EAP method</string>
+    <!-- Caption for the phase2 -->
+    <string name="please_select_phase2">Phase 2 authentication</string>
+    <!-- Caption for the identity -->
+    <string name="please_type_identity">Identity</string>
+    <!-- Caption for the anonymous_identity -->
+    <string name="please_type_anonymous_identity">Anonymous identity</string>
+    <!-- Caption for the client_certificate -->
+    <string name="please_select_client_certificate">Client certificate</string>
+    <!-- Caption for the ca certificate -->
+    <string name="please_select_ca_certificate">CA certificate</string>
+    <!-- Caption for the Private Key -->
+    <string name="please_select_private_key">Private key</string>
+    <!-- Caption for the private key passwd -->
+    <string name="please_type_private_key_passwd">Private key password</string>
     <!-- Caption for the wireless password -->
     <string name="please_type_passphrase">Wireless password</string>
     <!--Wi-Fi settings screen, connect to network dialog box, field label and hint text -->
diff --git a/src/com/android/settings/wifi/AccessPointDialog.java b/src/com/android/settings/wifi/AccessPointDialog.java
index 919f7fc..dc2b389 100644
--- a/src/com/android/settings/wifi/AccessPointDialog.java
+++ b/src/com/android/settings/wifi/AccessPointDialog.java
@@ -21,6 +21,7 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.res.Resources;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
@@ -71,6 +72,8 @@
     private static final int SECURITY_WEP = 2;
     private static final int SECURITY_WPA_PERSONAL = 3;
     private static final int SECURITY_WPA2_PERSONAL = 4;
+    private static final int SECURITY_WPA_EAP = 5;
+    private static final int SECURITY_IEEE8021X = 6;
 
     private static final int[] WEP_TYPE_VALUES = {
             AccessPointState.WEP_PASSWORD_AUTO, AccessPointState.WEP_PASSWORD_ASCII,
@@ -92,15 +95,39 @@
     
     // General views
     private View mView;
+    private View mEnterpriseView;
     private TextView mPasswordText;
     private EditText mPasswordEdit;
     private CheckBox mShowPasswordCheckBox;
+
+    // Enterprise fields
+    private TextView mEapText;
+    private Spinner mEapSpinner;
+    private TextView mPhase2Text;
+    private Spinner mPhase2Spinner;
+    private TextView mIdentityText;
+    private EditText mIdentityEdit;
+    private TextView mAnonymousIdentityText;
+    private EditText mAnonymousIdentityEdit;
+    private TextView mClientCertText;
+    private Spinner mClientCertSpinner;
+    private TextView mCaCertText;
+    private Spinner mCaCertSpinner;
+    private TextView mPrivateKeyText;
+    private Spinner mPrivateKeySpinner;
+    private TextView mPrivateKeyPasswdText;
+    private EditText mPrivateKeyPasswdEdit;
+    private EditText[] mEnterpriseTextFields;
+    private Spinner[] mEnterpriseSpinnerFields;
+
     
     // Info-specific views
     private ViewGroup mTable;
     
     // Configure-specific views
     private EditText mSsidEdit;
+    private TextView mSsidText;
+    private TextView mSecurityText;
     private Spinner mSecuritySpinner;
     private Spinner mWepTypeSpinner;
     
@@ -208,9 +235,17 @@
 
             positiveButtonResId = R.string.wifi_save_config;
             mSaveButtonPos = POSITIVE_BUTTON;
-            
+
+            setEnterpriseFieldsVisible(false);
+
         } else if (mMode == MODE_INFO) {
-            setLayout(R.layout.wifi_ap_info);
+            if (isEnterprise() && !mState.configured) {
+                setLayout(R.layout.wifi_ap_configure);
+                defaultPasswordVisibility = false;
+                setEnterpriseFieldsVisible(true);
+            } else {
+                setLayout(R.layout.wifi_ap_info);
+            }
 
             if (mState.isConnectable()) {
                 if (mCustomTitle == null) {
@@ -251,41 +286,131 @@
         setButtons(positiveButtonResId, negativeButtonResId, neutralButtonResId);
     }
 
+    private boolean isEnterprise() {
+
+        if(AccessPointState.WPA_EAP.equals(mState.security) ||
+            AccessPointState.IEEE8021X.equals(mState.security)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     /** Called when we need to set our member variables to point to the views. */
     private void onReferenceViews(View view) {
         mPasswordText = (TextView) view.findViewById(R.id.password_text);
         mPasswordEdit = (EditText) view.findViewById(R.id.password_edit);
-        
+        mSsidText = (TextView) view.findViewById(R.id.ssid_text);
+        mSsidEdit = (EditText) view.findViewById(R.id.ssid_edit);
+        mSecurityText = (TextView) view.findViewById(R.id.security_text);
+        mSecuritySpinner = (Spinner) view.findViewById(R.id.security_spinner);
+        mWepTypeSpinner = (Spinner) view.findViewById(R.id.wep_type_spinner);
+        mEnterpriseView = mView.findViewById(R.id.enterprise_wrapper);
+
         mShowPasswordCheckBox = (CheckBox) view.findViewById(R.id.show_password_checkbox);
         if (mShowPasswordCheckBox != null) {
             mShowPasswordCheckBox.setOnClickListener(this);
         }
-        
         if (mMode == MODE_CONFIGURE) {
-            mSsidEdit = (EditText) view.findViewById(R.id.ssid_edit);
-            mSecuritySpinner = (Spinner) view.findViewById(R.id.security_spinner);
             mSecuritySpinner.setOnItemSelectedListener(this);
-            setSecuritySpinnerAdapter();
-            mWepTypeSpinner = (Spinner) view.findViewById(R.id.wep_type_spinner);
-            
+            mSecuritySpinner.setPromptId(R.string.security);
+            setSpinnerAdapter(mSecuritySpinner, mAutoSecurityAllowed ?
+                R.array.wifi_security_entries
+                : R.array.wifi_security_without_auto_entries);
         } else if (mMode == MODE_INFO) {
             mTable = (ViewGroup) view.findViewById(R.id.table);
         }
-        
+        /* for enterprise one */
+        if (mMode == MODE_CONFIGURE || (isEnterprise() && !mState.configured)) {
+            setEnterpriseFields(view);
+            mEapSpinner.setSelection(getSelectionIndex(
+                    R.array.wifi_eap_entries, mState.getEap()));
+            Keystore ks = Keystore.getInstance();
+            mClientCertSpinner.setSelection(getSelectionIndex(
+                    ks.getAllCertificateKeys(), mState.getEnterpriseField(
+                    AccessPointState.CLIENT_CERT)));
+            mCaCertSpinner.setSelection(getSelectionIndex(
+                    ks.getAllCertificateKeys(), mState.getEnterpriseField(
+                    AccessPointState.CA_CERT)));
+            mPrivateKeySpinner.setSelection(getSelectionIndex(
+                    ks.getAllUserkeyKeys(), mState.getEnterpriseField(
+                    AccessPointState.PRIVATE_KEY)));
+        }
     }
-    
-    private void setSecuritySpinnerAdapter() {
-        Context context = getContext();
-        int arrayResId = mAutoSecurityAllowed ? R.array.wifi_security_entries
-                : R.array.wifi_security_without_auto_entries;         
 
-        ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context,
-                android.R.layout.simple_spinner_item,
-                context.getResources().getStringArray(arrayResId));
-        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        mSecuritySpinner.setAdapter(adapter);
+    private void setEnterpriseFields(View view) {
+        mIdentityText = (TextView) view.findViewById(R.id.identity_text);
+        mIdentityEdit = (EditText) view.findViewById(R.id.identity_edit);
+        mAnonymousIdentityText =
+                (TextView) view.findViewById(R.id.anonymous_identity_text);
+        mAnonymousIdentityEdit =
+                (EditText) view.findViewById(R.id.anonymous_identity_edit);
+        mClientCertText =
+                (TextView) view.findViewById(R.id.client_certificate_text);
+        mCaCertText = (TextView) view.findViewById(R.id.ca_certificate_text);
+        mPrivateKeyText = (TextView) view.findViewById(R.id.private_key_text);
+        mPrivateKeyPasswdText =
+                (TextView) view.findViewById(R.id.private_key_passwd_text);
+        mPrivateKeyPasswdEdit =
+                (EditText) view.findViewById(R.id.private_key_passwd_edit);
+        mEapText = (TextView) view.findViewById(R.id.eap_text);
+        mEapSpinner = (Spinner) view.findViewById(R.id.eap_spinner);
+        mEapSpinner.setOnItemSelectedListener(this);
+        mEapSpinner.setPromptId(R.string.please_select_eap);
+        setSpinnerAdapter(mEapSpinner, R.array.wifi_eap_entries);
+
+        mPhase2Text = (TextView) view.findViewById(R.id.phase2_text);
+        mPhase2Spinner = (Spinner) view.findViewById(R.id.phase2_spinner);
+        mPhase2Spinner.setOnItemSelectedListener(this);
+        mPhase2Spinner.setPromptId(R.string.please_select_phase2);
+        setSpinnerAdapter(mPhase2Spinner, R.array.wifi_phase2_entries);
+
+        Keystore ks = Keystore.getInstance();
+
+        mClientCertSpinner =
+                (Spinner) view.findViewById(R.id.client_certificate_spinner);
+        mClientCertSpinner.setOnItemSelectedListener(this);
+        mClientCertSpinner.setPromptId(
+                R.string.please_select_client_certificate);
+        setSpinnerAdapter(mClientCertSpinner, ks.getAllCertificateKeys());
+
+        mCaCertSpinner =
+                (Spinner) view.findViewById(R.id.ca_certificate_spinner);
+        mCaCertSpinner.setOnItemSelectedListener(this);
+        mCaCertSpinner.setPromptId(R.string.please_select_ca_certificate);
+        setSpinnerAdapter(mCaCertSpinner, ks.getAllCertificateKeys());
+
+        mPrivateKeySpinner =
+                (Spinner) view.findViewById(R.id.private_key_spinner);
+        mPrivateKeySpinner.setOnItemSelectedListener(this);
+        mPrivateKeySpinner.setPromptId(R.string.please_select_private_key);
+        setSpinnerAdapter(mPrivateKeySpinner, ks.getAllUserkeyKeys());
+
+        mEnterpriseTextFields = new EditText[] {
+            mIdentityEdit, mAnonymousIdentityEdit, mPrivateKeyPasswdEdit
+        };
+
+        mEnterpriseSpinnerFields = new Spinner[] {
+            mClientCertSpinner, mCaCertSpinner, mPrivateKeySpinner
+        };
+
     }
-    
+
+    private void setSpinnerAdapter(Spinner spinner, String[] items) {
+        if (items != null) {
+            ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
+                    getContext(), android.R.layout.simple_spinner_item, items);
+            adapter.setDropDownViewResource(
+                    android.R.layout.simple_spinner_dropdown_item);
+            spinner.setAdapter(adapter);
+        }
+    }
+
+    private void setSpinnerAdapter(Spinner spinner, int arrayResId) {
+        setSpinnerAdapter(spinner,
+            getContext().getResources().getStringArray(arrayResId));
+    }
+
     /** Called when the widgets are in-place waiting to be filled with data */
     private void onFill() {
 
@@ -381,39 +506,51 @@
         if (!replaceStateWithWifiLayerInstance()) {
             Log.w(TAG, "Assuming connecting to a new network.");
         }
-        
-        /*
-         * If the network is secured and they haven't entered a password, popup
-         * an error. Allow empty passwords if the state already has a password
-         * set (since in that scenario, an empty password means keep the old
-         * password).
-         */
-        String password = getEnteredPassword();
-        boolean passwordIsEmpty = TextUtils.isEmpty(password);
-        
-        /*
-         * When 'retry password', they can not enter a blank password. In any
-         * other mode, we let them enter a blank password if the state already
-         * has a password.
-         */
-        if (passwordIsEmpty && (!mState.hasPassword() || mMode == MODE_RETRY_PASSWORD)
-                && (mState.security != null) && !mState.security.equals(AccessPointState.OPEN)) {
-            new AlertDialog.Builder(getContext())
-                    .setTitle(R.string.error_title)
-                    .setIcon(android.R.drawable.ic_dialog_alert)
-                    .setMessage(R.string.wifi_password_incorrect_error)
-                    .setPositiveButton(android.R.string.ok, null)
-                    .show();
-            return;
+
+        if (isEnterprise()) {
+            if(!mState.configured) {
+                updateEnterpriseFields(
+                        AccessPointState.WPA_EAP.equals(mState.security) ?
+                        SECURITY_WPA_EAP : SECURITY_IEEE8021X);
+            }
+        } else {
+            updatePasswordField();
         }
-        
-        if (!passwordIsEmpty) { 
-            mState.setPassword(password);
-        }
-        
-        mWifiLayer.connectToNetwork(mState);            
+        mWifiLayer.connectToNetwork(mState);
     }
-    
+
+    /*
+     * If the network is secured and they haven't entered a password, popup an
+     * error. Allow empty passwords if the state already has a password set
+     * (since in that scenario, an empty password means keep the old password).
+     */
+    private void updatePasswordField() {
+
+      String password = getEnteredPassword();
+      boolean passwordIsEmpty = TextUtils.isEmpty(password);
+      /*
+       * When 'retry password', they can not enter a blank password. In any
+       * other mode, we let them enter a blank password if the state already
+       * has a password.
+       */
+      if (passwordIsEmpty && (!mState.hasPassword() ||
+              mMode == MODE_RETRY_PASSWORD) &&
+              (mState.security != null) &&
+              !mState.security.equals(AccessPointState.OPEN)) {
+          new AlertDialog.Builder(getContext())
+                  .setTitle(R.string.error_title)
+                  .setIcon(android.R.drawable.ic_dialog_alert)
+                  .setMessage(R.string.wifi_password_incorrect_error)
+                  .setPositiveButton(android.R.string.ok, null)
+                  .show();
+          return;
+      }
+
+      if (!passwordIsEmpty) {
+          mState.setPassword(password);
+      }
+    }
+
     private void handleSave() {
         replaceStateWithWifiLayerInstance();
 
@@ -471,6 +608,61 @@
         
     }
     
+    private int getSelectionIndex(String[] array, String selection) {
+        if(selection != null) {
+            for (int i = 0 ; i < array.length ; i++) {
+                if (selection.contains(array[i])) return i;
+            }
+        }
+        return 0;
+    }
+
+    private int getSelectionIndex(int arrayResId, String selection) {
+        return getSelectionIndex(
+            getContext().getResources().getStringArray(arrayResId), selection);
+    }
+
+    private void updateEnterpriseFields(int securityType) {
+            int i;
+            Keystore ks = Keystore.getInstance();
+            for (i = AccessPointState.IDENTITY ;
+                i < AccessPointState.MAX_ENTRPRISE_FIELD ; i++) {
+                String value;
+                if (i <= AccessPointState.PRIVATE_KEY_PASSWD) {
+                    value = mEnterpriseTextFields[i].getText().toString();
+                } else {
+                    Spinner spinner =  mEnterpriseSpinnerFields[i -
+                        AccessPointState.CLIENT_CERT];
+
+                    if (i != AccessPointState.PRIVATE_KEY) {
+                        value = ks.getCertificate(ks.getAllCertificateKeys()
+                            [spinner.getSelectedItemPosition()]);
+                    } else {
+                        value = ks.getUserkey(ks.getAllUserkeyKeys()
+                            [spinner.getSelectedItemPosition()]);
+                    }
+                }
+                if (!TextUtils.isEmpty(value)) {
+                    mState.setEnterpriseField(i, value);
+                }
+            }
+
+            switch (securityType) {
+                case SECURITY_WPA_EAP: {
+                    mState.setSecurity(AccessPointState.WPA_EAP);
+                    mState.setEap(mEapSpinner.getSelectedItemPosition());
+                    break;
+                }
+                case SECURITY_IEEE8021X: {
+                    mState.setSecurity(AccessPointState.IEEE8021X);
+                    mState.setEap(mEapSpinner.getSelectedItemPosition());
+                  break;
+                }
+                default:
+                    mState.setSecurity(AccessPointState.OPEN);
+            }
+    }
+
     /**
      * Replaces our {@link #mState} with the equal WifiLayer instance.  This is useful after
      * we unparceled the state previously and before we are calling methods on {@link #mWifiLayer}.
@@ -516,7 +708,22 @@
         mPasswordEdit.setVisibility(visibility);
         mShowPasswordCheckBox.setVisibility(visibility);
     }
-    
+
+    private void setEnterpriseFieldsVisible(boolean visible) {
+        int visibility = visible ? View.VISIBLE : View.GONE;
+        mEnterpriseView.setVisibility(visibility);
+        if (visible) {
+            setWepVisible(false);
+            setGenericPasswordVisible(false);
+        }
+        if (mMode != MODE_CONFIGURE) {
+            mSsidText.setVisibility(View.GONE);
+            mSsidEdit.setVisibility(View.GONE);
+            mSecurityText.setVisibility(View.GONE);
+            mSecuritySpinner.setVisibility(View.GONE);
+        }
+    }
+
     public void onItemSelected(AdapterView parent, View view, int position, long id) {
         if (parent == mSecuritySpinner) {
             handleSecurityChange(getSecurityTypeFromSpinner());
@@ -527,7 +734,7 @@
     }
 
     private void handleSecurityChange(int security) {
-        
+        setEnterpriseFieldsVisible(false);
         switch (security) {
             
             case SECURITY_NONE: {
@@ -559,6 +766,11 @@
                 updatePasswordCaption(AccessPointState.WPA);
                 break;
             }
+            case SECURITY_WPA_EAP:
+            case SECURITY_IEEE8021X: {
+                setEnterpriseFieldsVisible(true);
+                break;
+            }
         }
     }
 
diff --git a/src/com/android/settings/wifi/AccessPointState.java b/src/com/android/settings/wifi/AccessPointState.java
index 2569802..d050767 100644
--- a/src/com/android/settings/wifi/AccessPointState.java
+++ b/src/com/android/settings/wifi/AccessPointState.java
@@ -43,6 +43,12 @@
     public static final String WEP = "WEP";
     public static final String OPEN = "Open";
 
+    /* For EAP Enterprise fields */
+    public static final String WPA_EAP = "WPA-EAP";
+    public static final String IEEE8021X = "IEEE8021X";
+
+    public static final String[] EAP_METHOD = { "PEAP", "TLS", "TTLS" };
+
     /** String present in capabilities if the scan result is ad-hoc */
     private static final String ADHOC_CAPABILITY = "[IBSS]";
     /** String present in capabilities if the scan result is enterprise secured */
@@ -93,7 +99,19 @@
     public static final int WEP_PASSWORD_ASCII = 1;
     public static final int WEP_PASSWORD_HEX = 2;
     private int mWepPasswordType;
-    
+
+    /* Enterprise Fields */
+    public static final int IDENTITY = 0;
+    public static final int ANONYMOUS_IDENTITY = 1;
+    public static final int PRIVATE_KEY_PASSWD = 2;
+    public static final int CLIENT_CERT = 3;
+    public static final int CA_CERT = 4;
+    public static final int PRIVATE_KEY = 5;
+    public static final int MAX_ENTRPRISE_FIELD = 6;
+    private String mEnterpriseFields[] = new String[MAX_ENTRPRISE_FIELD];
+    private String mEap;
+    private String mPhase2;
+
     private Context mContext;
 
     /**
@@ -275,7 +293,9 @@
         else if (security.equals(WEP)) return mContext.getString(R.string.wifi_security_wep);
         else if (security.equals(WPA)) return mContext.getString(R.string.wifi_security_wpa);
         else if (security.equals(WPA2)) return mContext.getString(R.string.wifi_security_wpa2);
-        
+        else if (security.equals(WPA_EAP)) return mContext.getString(R.string.wifi_security_wpa_eap);
+        else if (security.equals(IEEE8021X)) return mContext.getString(R.string.wifi_security_ieee8021x);
+
         return mContext.getString(R.string.wifi_security_unknown);
     }
     
@@ -300,7 +320,7 @@
      */
     public static String getScanResultSecurity(ScanResult scanResult) {
         final String cap = scanResult.capabilities;
-        final String[] securityModes = { WEP, WPA, WPA2 }; 
+        final String[] securityModes = { WEP, WPA, WPA2, WPA_EAP, IEEE8021X };
         for (int i = securityModes.length - 1; i >= 0; i--) {
             if (cap.contains(securityModes[i])) {
                 return securityModes[i];
@@ -347,7 +367,30 @@
         mPassword = password;
         mWepPasswordType = wepPasswordType;
     }
-    
+
+    /* For Enterprise Fields */
+    public void setEnterpriseField(int field, String value) {
+        if (value != null && field >= 0 && field < MAX_ENTRPRISE_FIELD) {
+            this.mEnterpriseFields[field] = value;
+            requestRefresh();
+        }
+    }
+
+    public void setEap(int method) {
+        mEap =  EAP_METHOD[method];
+        requestRefresh();
+    }
+
+    public String getEap() {
+        return mEap;
+    }
+    public String getEnterpriseField(int field) {
+        if(field >=0 && field < MAX_ENTRPRISE_FIELD) {
+            return mEnterpriseFields[field];
+        }
+        return null;
+    }
+
     public boolean hasPassword() {
         return !TextUtils.isEmpty(mPassword) || mConfigHadPassword; 
     }
@@ -382,6 +425,10 @@
             } else {
                 return OPEN;
             }
+        } else if (wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
+            return WPA_EAP;
+        } else if (wifiConfig.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+            return IEEE8021X;
         } else if (wifiConfig.allowedProtocols.get(Protocol.RSN)) {
             return WPA2;
         } else if (wifiConfig.allowedProtocols.get(Protocol.WPA)) {
@@ -442,7 +489,43 @@
         config.priority = priority;
         config.hiddenSSID = hiddenSsid;
         config.SSID = convertToQuotedString(ssid);
-        
+        config.eap = mEap;
+        if (!TextUtils.isEmpty(mEnterpriseFields[IDENTITY])) {
+            config.identity =
+                    convertToQuotedString(mEnterpriseFields[IDENTITY]);
+        } else {
+            config.identity = null;
+        }
+        if (!TextUtils.isEmpty(mEnterpriseFields[ANONYMOUS_IDENTITY])) {
+            config.anonymousIdentity = convertToQuotedString(
+                    mEnterpriseFields[ANONYMOUS_IDENTITY]);
+        } else {
+            config.anonymousIdentity = null;
+        }
+        if (!TextUtils.isEmpty(mEnterpriseFields[CLIENT_CERT])) {
+            config.clientCert = convertToQuotedString(
+                    mEnterpriseFields[CLIENT_CERT]);
+        } else {
+            config.clientCert = null;
+        }
+        if (!TextUtils.isEmpty(mEnterpriseFields[CA_CERT])) {
+            config.caCert = convertToQuotedString(
+                    mEnterpriseFields[CA_CERT]);
+        } else {
+            config.caCert = null;
+        }
+        if (!TextUtils.isEmpty(mEnterpriseFields[PRIVATE_KEY])) {
+            config.privateKey = convertToQuotedString(
+                    mEnterpriseFields[PRIVATE_KEY]);
+        } else {
+            config.privateKey = null;
+        }
+        if (!TextUtils.isEmpty(mEnterpriseFields[PRIVATE_KEY_PASSWD])) {
+            config.privateKeyPasswd = convertToQuotedString(
+                    mEnterpriseFields[PRIVATE_KEY_PASSWD]);
+        } else {
+            config.privateKeyPasswd = null;
+        }
         setupSecurity(config);
     }
     
@@ -509,6 +592,14 @@
             
         } else if (security.equals(OPEN)) {
             config.allowedKeyManagement.set(KeyMgmt.NONE);
+        } else if (security.equals(WPA_EAP)) {
+            config.allowedGroupCiphers.set(GroupCipher.TKIP);
+            config.allowedGroupCiphers.set(GroupCipher.CCMP);
+            config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
+        } else if (security.equals(IEEE8021X)) {
+            config.allowedGroupCiphers.set(GroupCipher.TKIP);
+            config.allowedGroupCiphers.set(GroupCipher.CCMP);
+            config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
         }
     }
     
@@ -716,6 +807,10 @@
             return mContext.getString(R.string.wifi_security_verbose_wpa2);
         } else if (OPEN.equals(security)) {
             return mContext.getString(R.string.wifi_security_verbose_open);
+        } else if (WPA_EAP.equals(security)) {
+            return mContext.getString(R.string.wifi_security_verbose_wpa_eap);
+        } else if (IEEE8021X.equals(security)) {
+            return mContext.getString(R.string.wifi_security_verbose_ieee8021x);
         } else {
             return null;
         }
diff --git a/src/com/android/settings/wifi/Keystore.java b/src/com/android/settings/wifi/Keystore.java
new file mode 100644
index 0000000..68af868
--- /dev/null
+++ b/src/com/android/settings/wifi/Keystore.java
@@ -0,0 +1,81 @@
+package com.android.settings.wifi;
+
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ */
+public abstract class Keystore {
+    public static final String TAG = "Keystore";
+
+    private static final String PACKAGE_PREFIX =
+        Keystore.class.getPackage().getName() + ".";
+
+    public static final String ACTION_KEYSTORE_CERTIFICATES =
+        PACKAGE_PREFIX + "CERTIFICATES";
+    public static final String ACTION_KEYSTORE_USERKEYS =
+        PACKAGE_PREFIX + "USERKEYS";
+
+    /**
+     */
+    public static Keystore getInstance() {
+        return new FileKeystore();
+    }
+
+    /**
+     */
+    public abstract String getUserkey(String key);
+
+    /**
+     */
+    public abstract String getCertificate(String key);
+
+    /**
+     */
+    public abstract String[] getAllCertificateKeys();
+
+    /**
+     */
+    public abstract String[] getAllUserkeyKeys();
+
+    private static class FileKeystore extends Keystore {
+        private static final String PATH = "/data/misc/keystore/";
+        private static final String USERKEY_PATH = PATH + "userkeys/";
+        private static final String CERT_PATH = PATH + "certs/";
+
+        @Override
+        public String getUserkey(String key) {
+            String path = USERKEY_PATH + key;
+            return (new File(path).exists() ? path : null);
+        }
+
+        @Override
+        public String getCertificate(String key) {
+            String path = CERT_PATH + key;
+            return (new File(path).exists() ? path : null);
+        }
+
+        @Override
+        public String[] getAllCertificateKeys() {
+            File dir = new File(CERT_PATH);
+            if (dir.exists()) {
+                return dir.list();
+            } else {
+                Log.v(TAG, "-------- cert directory does not exist!");
+                return null;
+            }
+        }
+
+        @Override
+        public String[] getAllUserkeyKeys() {
+            File dir = new File(USERKEY_PATH);
+            if (dir.exists()) {
+                return dir.list();
+            } else {
+                Log.v(TAG, "-------- userkey directory does not exist!");
+                return null;
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/wifi/WifiLayer.java b/src/com/android/settings/wifi/WifiLayer.java
index b0857d2..751a5a3 100644
--- a/src/com/android/settings/wifi/WifiLayer.java
+++ b/src/com/android/settings/wifi/WifiLayer.java
@@ -1133,7 +1133,6 @@
                      * Hidden networks show up with empty SSID.
                      */
                     if (AccessPointState.isAdhoc(scanResult)
-                            || AccessPointState.isEnterprise(scanResult)
                             || TextUtils.isEmpty(scanResult.SSID)) {
                         continue;
                     }