OSDN Git Service

am eb7836f1: Apply the new keystore and certtool library in Wifi setting.
[android-x86/packages-apps-Settings.git] / src / com / android / settings / wifi / AccessPointDialog.java
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.settings.wifi;
18
19 import com.android.settings.R;
20 import com.android.settings.SecuritySettings;
21
22 import android.app.AlertDialog;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.Intent;
26 import android.content.res.Resources;
27 import android.security.CertTool;
28 import android.security.Keystore;
29 import android.net.wifi.WifiInfo;
30 import android.net.wifi.WifiManager;
31 import android.os.Bundle;
32 import android.text.InputType;
33 import android.text.TextUtils;
34 import android.text.format.Formatter;
35 import android.text.method.PasswordTransformationMethod;
36 import android.text.method.TransformationMethod;
37 import android.util.Log;
38 import android.view.View;
39 import android.view.ViewGroup;
40 import android.widget.AdapterView;
41 import android.widget.ArrayAdapter;
42 import android.widget.CheckBox;
43 import android.widget.EditText;
44 import android.widget.Spinner;
45 import android.widget.TableLayout;
46 import android.widget.TextView;
47
48 public class AccessPointDialog extends AlertDialog implements DialogInterface.OnClickListener,
49         AdapterView.OnItemSelectedListener, View.OnClickListener {
50
51     private static final String TAG = "AccessPointDialog";
52     private static final String INSTANCE_KEY_ACCESS_POINT_STATE =
53             "com.android.settings.wifi.AccessPointDialog:accessPointState";
54     private static final String INSTANCE_KEY_MODE =
55             "com.android.settings.wifi.AccessPointDialog:mode";
56     private static final String INSTANCE_KEY_CUSTOM_TITLE =
57             "com.android.settings.wifi.AccessPointDialog:customTitle";
58     private static final String INSTANCE_KEY_AUTO_SECURITY_ALLOWED =
59             "com.android.settings.wifi.AccessPointDialog:autoSecurityAllowed";
60     
61     private static final int POSITIVE_BUTTON = BUTTON1;
62     private static final int NEGATIVE_BUTTON = BUTTON2;
63     private static final int NEUTRAL_BUTTON = BUTTON3;
64     
65     /** The dialog should show info connectivity functionality */
66     public static final int MODE_INFO = 0;
67     /** The dialog should configure the detailed AP properties */
68     public static final int MODE_CONFIGURE = 1;
69     /** The dialog should have the password field and connect/cancel */
70     public static final int MODE_RETRY_PASSWORD = 2;
71     
72     // These should be matched with the XML. Both arrays in XML depend on this
73     // ordering!
74     private static final int SECURITY_AUTO = 0;
75     private static final int SECURITY_NONE = 1;
76     private static final int SECURITY_WEP = 2;
77     private static final int SECURITY_WPA_PERSONAL = 3;
78     private static final int SECURITY_WPA2_PERSONAL = 4;
79     private static final int SECURITY_WPA_EAP = 5;
80     private static final int SECURITY_IEEE8021X = 6;
81
82     private static final int[] WEP_TYPE_VALUES = {
83             AccessPointState.WEP_PASSWORD_AUTO, AccessPointState.WEP_PASSWORD_ASCII,
84             AccessPointState.WEP_PASSWORD_HEX
85     };
86     private static final String NOT_APPLICABLE = "N/A";
87
88     // Button positions, default to impossible values
89     private int mConnectButtonPos = Integer.MAX_VALUE; 
90     private int mForgetButtonPos = Integer.MAX_VALUE;
91     private int mSaveButtonPos = Integer.MAX_VALUE;
92
93     // Client configurable items. Generally, these should be saved in instance state
94     private int mMode = MODE_INFO;
95     private boolean mAutoSecurityAllowed = true;
96     private CharSequence mCustomTitle;
97     // This does not need to be saved in instance state.
98     private WifiLayer mWifiLayer;
99     private AccessPointState mState;
100     
101     // General views
102     private View mView;
103     private View mEnterpriseView;
104     private TextView mPasswordText;
105     private EditText mPasswordEdit;
106     private CheckBox mShowPasswordCheckBox;
107
108     // Enterprise fields
109     private TextView mEapText;
110     private Spinner mEapSpinner;
111     private TextView mPhase2Text;
112     private Spinner mPhase2Spinner;
113     private TextView mIdentityText;
114     private EditText mIdentityEdit;
115     private TextView mAnonymousIdentityText;
116     private EditText mAnonymousIdentityEdit;
117     private TextView mCaCertText;
118     private Spinner mCaCertSpinner;
119     private TextView mClientCertText;
120     private Spinner mClientCertSpinner;
121     private TextView mPrivateKeyPasswdText;
122     private EditText mPrivateKeyPasswdEdit;
123     private EditText[] mEnterpriseTextFields;
124
125     
126     // Info-specific views
127     private ViewGroup mTable;
128     
129     // Configure-specific views
130     private EditText mSsidEdit;
131     private TextView mSsidText;
132     private TextView mSecurityText;
133     private Spinner mSecuritySpinner;
134     private Spinner mWepTypeSpinner;
135     private CertTool mCertTool;
136     
137     public AccessPointDialog(Context context, WifiLayer wifiLayer) {
138         super(context);
139
140         mWifiLayer = wifiLayer;
141         mCertTool = CertTool.getInstance();
142     }
143
144     @Override
145     protected void onCreate(Bundle savedInstanceState) {
146         onLayout();
147         onFill();
148
149         super.onCreate(savedInstanceState);
150     }
151     
152     @Override
153     public void onRestoreInstanceState(Bundle savedInstanceState) {
154         // Set to a class loader that can find AccessPointState
155         savedInstanceState.setClassLoader(getClass().getClassLoader());
156         
157         mState = savedInstanceState.getParcelable(INSTANCE_KEY_ACCESS_POINT_STATE);
158         mState.setContext(getContext());
159         
160         mMode = savedInstanceState.getInt(INSTANCE_KEY_MODE, mMode);
161         mAutoSecurityAllowed = savedInstanceState.getBoolean(INSTANCE_KEY_AUTO_SECURITY_ALLOWED,
162                 mAutoSecurityAllowed);
163         mCustomTitle = savedInstanceState.getCharSequence(INSTANCE_KEY_CUSTOM_TITLE);
164         if (mCustomTitle != null) {
165             setTitle(mCustomTitle);
166         }
167
168         // This is called last since it depends on the above values 
169         super.onRestoreInstanceState(savedInstanceState);
170         
171         if (mShowPasswordCheckBox != null) {
172             // Restore the show-password-state on the edit text
173             setShowPassword(mShowPasswordCheckBox.isChecked());
174         }
175     }
176
177     @Override
178     public Bundle onSaveInstanceState() {
179         Bundle bundle = super.onSaveInstanceState();
180         bundle.putParcelable(INSTANCE_KEY_ACCESS_POINT_STATE, mState);
181         bundle.putInt(INSTANCE_KEY_MODE, mMode);
182         bundle.putBoolean(INSTANCE_KEY_AUTO_SECURITY_ALLOWED, mAutoSecurityAllowed);
183         bundle.putCharSequence(INSTANCE_KEY_CUSTOM_TITLE, mCustomTitle);
184         return bundle;
185     }
186
187     /**
188      * Sets state to show in this dialog.
189      * 
190      * @param state The state.
191      */
192     public void setState(AccessPointState state) {
193         mState = state;
194     }
195
196     /**
197      * Sets the dialog mode.
198      * @param mode One of {@link #MODE_CONFIGURE} or {@link #MODE_INFO}
199      */
200     public void setMode(int mode) {
201         mMode = mode;
202     }
203
204     public void setAutoSecurityAllowed(boolean autoSecurityAllowed) {
205         mAutoSecurityAllowed = autoSecurityAllowed;
206     }
207
208     @Override
209     public void setTitle(CharSequence title) {
210         super.setTitle(title);
211         mCustomTitle = title;
212     }
213
214     @Override
215     public void setTitle(int titleId) {
216         setTitle(getContext().getString(titleId));
217     }
218
219     /** Called after flags are set, the dialog's layout/etc should be set up here */
220     private void onLayout() {
221         final Context context = getContext();
222         final String ssid = mState.getHumanReadableSsid();
223         
224         int positiveButtonResId = 0;
225         int negativeButtonResId = R.string.cancel;
226         int neutralButtonResId = 0;
227
228         if (mCustomTitle == null) {
229             // Generic title is the SSID
230             // We don't want to trigger this as a custom title, so call super's
231             super.setTitle(ssid);
232         }
233         setInverseBackgroundForced(true);
234
235         boolean defaultPasswordVisibility = true;
236         
237         if (mMode == MODE_CONFIGURE) {
238             setLayout(R.layout.wifi_ap_configure);
239
240             positiveButtonResId = R.string.wifi_save_config;
241             mSaveButtonPos = POSITIVE_BUTTON;
242
243             setEnterpriseFieldsVisible(false);
244
245         } else if (mMode == MODE_INFO) {
246             if (mState.isEnterprise() && !mState.configured) {
247                 setLayout(R.layout.wifi_ap_configure);
248                 defaultPasswordVisibility = false;
249                 setEnterpriseFieldsVisible(true);
250             } else {
251                 setLayout(R.layout.wifi_ap_info);
252             }
253
254             if (mState.isConnectable()) {
255                 if (mCustomTitle == null) {
256                     // We don't want to trigger this as a custom title, so call super's
257                     super.setTitle(context.getString(R.string.connect_to_blank, ssid));
258                 }
259                 positiveButtonResId = R.string.connect;
260                 mConnectButtonPos = POSITIVE_BUTTON;
261             }
262
263             if (mState.isForgetable()) {
264                 if (positiveButtonResId == 0) {
265                     positiveButtonResId = R.string.forget_network;
266                     mForgetButtonPos = POSITIVE_BUTTON;
267                 } else {
268                     neutralButtonResId = R.string.forget_network;
269                     mForgetButtonPos = NEUTRAL_BUTTON;
270                 }
271             }
272         } else if (mMode == MODE_RETRY_PASSWORD) {
273             setLayout(R.layout.wifi_ap_retry_password);
274             
275             positiveButtonResId = R.string.connect;
276             mConnectButtonPos = POSITIVE_BUTTON;
277             
278             setGenericPasswordVisible(true);
279             defaultPasswordVisibility = false;
280         }
281
282         if (defaultPasswordVisibility) {
283             if (!mState.configured && mState.seen && mState.hasSecurity()) {
284                 setGenericPasswordVisible(true);
285             } else {
286                 setGenericPasswordVisible(false);
287             }
288         }
289         
290         setButtons(positiveButtonResId, negativeButtonResId, neutralButtonResId);
291     }
292
293     /** Called when we need to set our member variables to point to the views. */
294     private void onReferenceViews(View view) {
295         mPasswordText = (TextView) view.findViewById(R.id.password_text);
296         mPasswordEdit = (EditText) view.findViewById(R.id.password_edit);
297         mSsidText = (TextView) view.findViewById(R.id.ssid_text);
298         mSsidEdit = (EditText) view.findViewById(R.id.ssid_edit);
299         mSecurityText = (TextView) view.findViewById(R.id.security_text);
300         mSecuritySpinner = (Spinner) view.findViewById(R.id.security_spinner);
301         mWepTypeSpinner = (Spinner) view.findViewById(R.id.wep_type_spinner);
302         mEnterpriseView = mView.findViewById(R.id.enterprise_wrapper);
303
304         mShowPasswordCheckBox = (CheckBox) view.findViewById(R.id.show_password_checkbox);
305         if (mShowPasswordCheckBox != null) {
306             mShowPasswordCheckBox.setOnClickListener(this);
307         }
308         if (mMode == MODE_CONFIGURE) {
309             mSecuritySpinner.setOnItemSelectedListener(this);
310             mSecuritySpinner.setPromptId(R.string.security);
311             setSpinnerAdapter(mSecuritySpinner, mAutoSecurityAllowed ?
312                 R.array.wifi_security_entries
313                 : R.array.wifi_security_without_auto_entries);
314         } else if (mMode == MODE_INFO) {
315             mTable = (ViewGroup) view.findViewById(R.id.table);
316         }
317         /* for enterprise one */
318         if (mMode == MODE_CONFIGURE ||
319                 (mState.isEnterprise() && !mState.configured)) {
320             setEnterpriseFields(view);
321             mEapSpinner.setSelection(getSelectionIndex(
322                     R.array.wifi_eap_entries, mState.getEap()));
323             mClientCertSpinner.setSelection(getSelectionIndex(
324                     getAllUserCertificateKeys(), mState.getEnterpriseField(
325                     AccessPointState.CLIENT_CERT)));
326             mCaCertSpinner.setSelection(getSelectionIndex(
327                     getAllCaCertificateKeys(), mState.getEnterpriseField(
328                     AccessPointState.CA_CERT)));
329         }
330     }
331
332     private String[] getAllCaCertificateKeys() {
333         return appendEmptyInSelection(mCertTool.getAllCaCertificateKeys());
334     }
335
336     private String[] getAllUserCertificateKeys() {
337         return appendEmptyInSelection(mCertTool.getAllUserCertificateKeys());
338     }
339
340     private String[] appendEmptyInSelection(String[] keys) {
341       String[] selections = new String[keys.length + 1];
342       System.arraycopy(keys, 0, selections, 0, keys.length);
343       selections[keys.length] = NOT_APPLICABLE;
344       return selections;
345     }
346
347     private void setEnterpriseFields(View view) {
348         mIdentityText = (TextView) view.findViewById(R.id.identity_text);
349         mIdentityEdit = (EditText) view.findViewById(R.id.identity_edit);
350         mAnonymousIdentityText =
351                 (TextView) view.findViewById(R.id.anonymous_identity_text);
352         mAnonymousIdentityEdit =
353                 (EditText) view.findViewById(R.id.anonymous_identity_edit);
354         mClientCertText =
355                 (TextView) view.findViewById(R.id.client_certificate_text);
356         mCaCertText = (TextView) view.findViewById(R.id.ca_certificate_text);
357         mPrivateKeyPasswdEdit =
358                 (EditText) view.findViewById(R.id.private_key_passwd_edit);
359         mEapText = (TextView) view.findViewById(R.id.eap_text);
360         mEapSpinner = (Spinner) view.findViewById(R.id.eap_spinner);
361         mEapSpinner.setOnItemSelectedListener(this);
362         mEapSpinner.setPromptId(R.string.please_select_eap);
363         setSpinnerAdapter(mEapSpinner, R.array.wifi_eap_entries);
364
365         mPhase2Text = (TextView) view.findViewById(R.id.phase2_text);
366         mPhase2Spinner = (Spinner) view.findViewById(R.id.phase2_spinner);
367         mPhase2Spinner.setOnItemSelectedListener(this);
368         mPhase2Spinner.setPromptId(R.string.please_select_phase2);
369         setSpinnerAdapter(mPhase2Spinner, R.array.wifi_phase2_entries);
370
371         mClientCertSpinner =
372                 (Spinner) view.findViewById(R.id.client_certificate_spinner);
373         mClientCertSpinner.setOnItemSelectedListener(this);
374         mClientCertSpinner.setPromptId(
375                 R.string.please_select_client_certificate);
376         setSpinnerAdapter(mClientCertSpinner, getAllUserCertificateKeys());
377
378         mCaCertSpinner =
379                 (Spinner) view.findViewById(R.id.ca_certificate_spinner);
380         mCaCertSpinner.setOnItemSelectedListener(this);
381         mCaCertSpinner.setPromptId(R.string.please_select_ca_certificate);
382         setSpinnerAdapter(mCaCertSpinner, getAllCaCertificateKeys());
383
384         mEnterpriseTextFields = new EditText[] {
385             mIdentityEdit, mAnonymousIdentityEdit, mPrivateKeyPasswdEdit
386         };
387
388     }
389
390     private void setSpinnerAdapter(Spinner spinner, String[] items) {
391         if (items != null) {
392             ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
393                     getContext(), android.R.layout.simple_spinner_item, items);
394             adapter.setDropDownViewResource(
395                     android.R.layout.simple_spinner_dropdown_item);
396             spinner.setAdapter(adapter);
397         }
398     }
399
400     private void setSpinnerAdapter(Spinner spinner, int arrayResId) {
401         setSpinnerAdapter(spinner,
402             getContext().getResources().getStringArray(arrayResId));
403     }
404
405     /** Called when the widgets are in-place waiting to be filled with data */
406     private void onFill() {
407
408         // Appears in the order added
409         if (mMode == MODE_INFO) {
410             if (mState.primary) {
411                 addInfoRow(R.string.wifi_status, mState.getSummarizedStatus());
412                 addInfoRow(R.string.wifi_link_speed, mState.linkSpeed + WifiInfo.LINK_SPEED_UNITS);
413             }
414     
415             if (mState.seen) {
416                 addInfoRow(R.string.signal, getSignalResId(mState.signal));
417             }
418             
419             if (mState.security != null) {
420                 addInfoRow(R.string.security, mState.getHumanReadableSecurity());
421             }
422     
423             if (mState.primary && mState.ipAddress != 0) {
424                 addInfoRow(R.string.ip_address, Formatter.formatIpAddress(mState.ipAddress));
425             }
426             
427         } else if (mMode == MODE_CONFIGURE) {
428             String ssid = mState.getHumanReadableSsid();
429             if (!TextUtils.isEmpty(ssid)) {
430                 mSsidEdit.setText(ssid);
431             }
432             if (mState.configured) {
433                 mPasswordEdit.setHint(R.string.wifi_password_unchanged);
434             }
435         }
436
437         updatePasswordCaption(mState.security);
438     }
439
440     private void updatePasswordCaption(String security) {
441         if (mPasswordText != null) {
442             if (security != null && security.equals(AccessPointState.WEP)) {
443                 mPasswordText.setText(R.string.please_type_hex_key);
444             } else {
445                 mPasswordText.setText(R.string.please_type_passphrase);
446             }
447         }
448     }
449     
450     private void addInfoRow(int nameResId, String value) {
451         View rowView = getLayoutInflater().inflate(R.layout.wifi_ap_info_row, mTable, false);
452         ((TextView) rowView.findViewById(R.id.name)).setText(nameResId);
453         ((TextView) rowView.findViewById(R.id.value)).setText(value);
454         mTable.addView(rowView);
455     }
456         
457     private void addInfoRow(int nameResId, int valueResId) {
458         addInfoRow(nameResId, getContext().getString(valueResId));
459     }
460     
461     private void setButtons(int positiveResId, int negativeResId, int neutralResId) {
462         final Context context = getContext();
463         
464         if (positiveResId > 0) {
465             setButton(context.getString(positiveResId), this);
466         }
467         
468         if (negativeResId > 0) {
469             setButton2(context.getString(negativeResId), this);
470         }
471
472         if (neutralResId > 0) {
473             setButton3(context.getString(neutralResId), this);
474         }
475     }
476     
477     private void setLayout(int layoutResId) {
478         setView(mView = getLayoutInflater().inflate(layoutResId, null));
479         onReferenceViews(mView);
480     }
481     
482     public void onClick(DialogInterface dialog, int which) {
483         if (which == mForgetButtonPos) {
484             handleForget();
485         } else if (which == mConnectButtonPos) {
486             handleConnect();
487         } else if (which == mSaveButtonPos) {
488             handleSave();
489         }
490     }
491     
492     private void handleForget() {
493         if (!replaceStateWithWifiLayerInstance()) return;
494         mWifiLayer.forgetNetwork(mState);
495     }
496     
497     private void handleConnect() {
498         if (!replaceStateWithWifiLayerInstance()) {
499             Log.w(TAG, "Assuming connecting to a new network.");
500         }
501
502         if (mState.isEnterprise()) {
503             if(!mState.configured) {
504                 updateEnterpriseFields(
505                         AccessPointState.WPA_EAP.equals(mState.security) ?
506                         SECURITY_WPA_EAP : SECURITY_IEEE8021X);
507             }
508         }
509         updatePasswordField();
510
511         mWifiLayer.connectToNetwork(mState);
512     }
513
514     /*
515      * If the network is secured and they haven't entered a password, popup an
516      * error. Allow empty passwords if the state already has a password set
517      * (since in that scenario, an empty password means keep the old password).
518      */
519     private void updatePasswordField() {
520
521       String password = getEnteredPassword();
522       boolean passwordIsEmpty = TextUtils.isEmpty(password);
523       /*
524        * When 'retry password', they can not enter a blank password. In any
525        * other mode, we let them enter a blank password if the state already
526        * has a password.
527        */
528       if (passwordIsEmpty && (!mState.hasPassword() ||
529               mMode == MODE_RETRY_PASSWORD) &&
530               (mState.security != null) &&
531               !mState.security.equals(AccessPointState.OPEN)) {
532           new AlertDialog.Builder(getContext())
533                   .setTitle(R.string.error_title)
534                   .setIcon(android.R.drawable.ic_dialog_alert)
535                   .setMessage(R.string.wifi_password_incorrect_error)
536                   .setPositiveButton(android.R.string.ok, null)
537                   .show();
538           return;
539       }
540
541       if (!passwordIsEmpty) {
542           mState.setPassword(password);
543       }
544     }
545
546     private void handleSave() {
547         replaceStateWithWifiLayerInstance();
548
549         String ssid = mSsidEdit.getText().toString();
550         String password = mPasswordEdit.getText().toString();
551         
552         mState.setSsid(ssid);
553         
554         int securityType = getSecurityTypeFromSpinner();
555
556         if (!TextUtils.isEmpty(password) && (securityType != SECURITY_WEP)) {
557             mState.setPassword(password);
558         }
559
560         switch (securityType) {
561             case SECURITY_WPA_PERSONAL: {
562                 mState.setSecurity(AccessPointState.WPA);
563                 break;
564             }
565
566             case SECURITY_WPA2_PERSONAL: {
567                 mState.setSecurity(AccessPointState.WPA2);
568                 break;
569             }
570
571             case SECURITY_AUTO: {
572                 break;
573             }
574
575             case SECURITY_WEP: {
576                 mState.setSecurity(AccessPointState.WEP);
577                 mState.setPassword(password, WEP_TYPE_VALUES[
578                         mWepTypeSpinner.getSelectedItemPosition()]);
579                     break;
580             }
581
582             case SECURITY_WPA_EAP:
583                 mState.setSecurity(AccessPointState.WPA_EAP);
584                 break;
585
586             case SECURITY_IEEE8021X:
587                 mState.setSecurity(AccessPointState.IEEE8021X);
588                 break;
589
590             case SECURITY_NONE:
591             default:
592                 mState.setSecurity(AccessPointState.OPEN);
593                 break;
594         }
595
596         if (mState.isEnterprise() && !mState.configured) {
597             updateEnterpriseFields(
598                     AccessPointState.WPA_EAP.equals(mState.security) ?
599                     SECURITY_WPA_EAP : SECURITY_IEEE8021X);
600         }
601
602         if (!mWifiLayer.saveNetwork(mState)) {
603             return;
604         }
605         
606         // Connect right away if they've touched it
607         if (!mWifiLayer.connectToNetwork(mState)) {
608             return;
609         }
610         
611     }
612     
613     private int getSelectionIndex(String[] array, String selection) {
614         if(selection != null) {
615             for (int i = 0 ; i < array.length ; i++) {
616                 if (selection.contains(array[i])) return i;
617             }
618         }
619         return 0;
620     }
621
622     private int getSelectionIndex(int arrayResId, String selection) {
623         return getSelectionIndex(
624             getContext().getResources().getStringArray(arrayResId), selection);
625     }
626
627     private void updateEnterpriseFields(int securityType) {
628         int i;
629         String value;
630         for (i = AccessPointState.IDENTITY ;
631                 i <= AccessPointState.PRIVATE_KEY_PASSWD ; i++) {
632             value = mEnterpriseTextFields[i].getText().toString();
633             if (!TextUtils.isEmpty(value) ||
634                     (i == AccessPointState.PRIVATE_KEY_PASSWD)) {
635                 mState.setEnterpriseField(i, value);
636             }
637         }
638         Spinner spinner = mClientCertSpinner;
639         int index = spinner.getSelectedItemPosition();
640         if (index != (spinner.getCount() - 1)) {
641             String key = (String)spinner.getSelectedItem();
642             value = mCertTool.getUserCertificate(key);
643             if (!TextUtils.isEmpty(value)) {
644                 mState.setEnterpriseField(AccessPointState.CLIENT_CERT,
645                         value);
646             }
647             value = mCertTool.getUserPrivateKey(key);
648             if (!TextUtils.isEmpty(value)) {
649                 mState.setEnterpriseField(AccessPointState.PRIVATE_KEY,
650                         value);
651             }
652         }
653         spinner = mCaCertSpinner;
654         index = spinner.getSelectedItemPosition();
655         if (index != (spinner.getCount() - 1)) {
656             String key = (String)spinner.getSelectedItem();
657             value = mCertTool.getCaCertificate(key);
658             if (!TextUtils.isEmpty(value)) {
659                 mState.setEnterpriseField(AccessPointState.CA_CERT,
660                         value);
661             }
662         }
663         switch (securityType) {
664             case SECURITY_WPA_EAP: {
665                 mState.setSecurity(AccessPointState.WPA_EAP);
666                 mState.setEap(mEapSpinner.getSelectedItemPosition());
667                 break;
668             }
669             case SECURITY_IEEE8021X: {
670                 mState.setSecurity(AccessPointState.IEEE8021X);
671                 mState.setEap(mEapSpinner.getSelectedItemPosition());
672                 break;
673             }
674             default:
675                 mState.setSecurity(AccessPointState.OPEN);
676         }
677     }
678
679     /**
680      * Replaces our {@link #mState} with the equal WifiLayer instance.  This is useful after
681      * we unparceled the state previously and before we are calling methods on {@link #mWifiLayer}.
682      * 
683      * @return Whether WifiLayer was able to find an equal state in its set.
684      */
685     private boolean replaceStateWithWifiLayerInstance() {
686         AccessPointState state = mWifiLayer.getWifiLayerApInstance(mState);
687         if (state == null) {
688             return false;
689         }
690         
691         mState = state;
692         return true;
693     }
694     
695     private int getSecurityTypeFromSpinner() {
696         int position = mSecuritySpinner.getSelectedItemPosition();
697         // If there is no AUTO choice, the position needs 1 added to get
698         // to the proper spinner position -> security constants mapping
699         return mAutoSecurityAllowed ? position : position + 1;
700     }
701     
702     private String getEnteredPassword() {
703         return mPasswordEdit != null ? mPasswordEdit.getText().toString() : null;
704     }
705     
706     /**
707      * Call the one you want to hide first.
708      */
709     private void setWepVisible(boolean visible) {
710         setGenericPasswordVisible(visible);
711         int visibility = visible ? View.VISIBLE : View.GONE;
712         mWepTypeSpinner.setVisibility(visibility);
713     }
714     
715     /**
716      * @see #setWepVisible(boolean)
717      */
718     private void setGenericPasswordVisible(boolean visible) {
719         int visibility = visible ? View.VISIBLE : View.GONE;
720         mPasswordText.setVisibility(visibility);
721         mPasswordEdit.setVisibility(visibility);
722         mShowPasswordCheckBox.setVisibility(visibility);
723     }
724
725     private void setEnterpriseFieldsVisible(boolean visible) {
726         int visibility = visible ? View.VISIBLE : View.GONE;
727         mEnterpriseView.setVisibility(visibility);
728         if (visible) {
729             setWepVisible(false);
730         }
731         if (mMode != MODE_CONFIGURE) {
732             mSsidText.setVisibility(View.GONE);
733             mSsidEdit.setVisibility(View.GONE);
734             mSecurityText.setVisibility(View.GONE);
735             mSecuritySpinner.setVisibility(View.GONE);
736         }
737     }
738
739     public void onItemSelected(AdapterView parent, View view, int position, long id) {
740         if (parent == mSecuritySpinner) {
741             handleSecurityChange(getSecurityTypeFromSpinner());
742         }
743     }
744
745     public void onNothingSelected(AdapterView parent) {
746     }
747
748     private void handleSecurityChange(int security) {
749         setEnterpriseFieldsVisible(false);
750         switch (security) {
751             
752             case SECURITY_NONE: {
753                 setWepVisible(false);
754                 setGenericPasswordVisible(false);
755                 break;
756             }
757             
758             case SECURITY_WEP: {
759                 setGenericPasswordVisible(false);
760                 setWepVisible(true);
761                 updatePasswordCaption(AccessPointState.WEP);
762                 break;
763             }
764             
765             case SECURITY_AUTO: {
766                 setWepVisible(false);
767                 setGenericPasswordVisible(mState.hasSecurity());
768                 // Shows the generic 'wireless password'
769                 updatePasswordCaption(AccessPointState.WPA);
770                 break;
771             }
772             
773             case SECURITY_WPA_PERSONAL:
774             case SECURITY_WPA2_PERSONAL: {
775                 setWepVisible(false);
776                 setGenericPasswordVisible(true);
777                 // Both WPA and WPA2 show the same caption, so either is ok
778                 updatePasswordCaption(AccessPointState.WPA);
779                 break;
780             }
781             case SECURITY_WPA_EAP:
782             case SECURITY_IEEE8021X: {
783                 // Unlock the keystore if it is not unlocked yet.
784                 if (Keystore.getInstance().getState() != Keystore.UNLOCKED) {
785                     getContext().startActivity(new Intent(
786                             SecuritySettings.ACTION_UNLOCK_CREDENTIAL_STORAGE));
787                     mSecuritySpinner.setSelection(0);
788                     return;
789                 }
790                 setEnterpriseFieldsVisible(true);
791                 setGenericPasswordVisible(true);
792                 // Both WPA and WPA2 show the same caption, so either is ok
793                 updatePasswordCaption(AccessPointState.WPA);
794                 break;
795             }
796         }
797     }
798
799     private static int getSignalResId(int signal) {
800         switch (WifiManager.calculateSignalLevel(signal, 4)) {
801             case 0: {
802                 return R.string.wifi_signal_0;
803             }
804             case 1: {
805                 return R.string.wifi_signal_1;
806             }
807             case 2: {
808                 return R.string.wifi_signal_2;
809             }
810             case 3: {
811                 return R.string.wifi_signal_3;
812             }
813         }
814         
815         return 0;
816     }
817     
818
819     public void onClick(View v) {
820         if (v == mShowPasswordCheckBox) {
821             setShowPassword(mShowPasswordCheckBox.isChecked());
822         }
823     }
824     
825     private void setShowPassword(boolean showPassword) {
826         if (mPasswordEdit != null) {
827             mPasswordEdit.setInputType(InputType.TYPE_CLASS_TEXT |
828                     (showPassword ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
829                             : InputType.TYPE_TEXT_VARIATION_PASSWORD));
830         }
831     }
832     
833 }