OSDN Git Service

am 150d5d84: Use the keystore service instead of the direct file access.
[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
21 import android.app.AlertDialog;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.res.Resources;
25 import android.security.Keystore;
26 import android.net.wifi.WifiInfo;
27 import android.net.wifi.WifiManager;
28 import android.os.Bundle;
29 import android.text.InputType;
30 import android.text.TextUtils;
31 import android.text.format.Formatter;
32 import android.text.method.PasswordTransformationMethod;
33 import android.text.method.TransformationMethod;
34 import android.util.Log;
35 import android.view.View;
36 import android.view.ViewGroup;
37 import android.widget.AdapterView;
38 import android.widget.ArrayAdapter;
39 import android.widget.CheckBox;
40 import android.widget.EditText;
41 import android.widget.Spinner;
42 import android.widget.TableLayout;
43 import android.widget.TextView;
44
45 public class AccessPointDialog extends AlertDialog implements DialogInterface.OnClickListener,
46         AdapterView.OnItemSelectedListener, View.OnClickListener {
47
48     private static final String TAG = "AccessPointDialog";
49     private static final String INSTANCE_KEY_ACCESS_POINT_STATE =
50             "com.android.settings.wifi.AccessPointDialog:accessPointState";
51     private static final String INSTANCE_KEY_MODE =
52             "com.android.settings.wifi.AccessPointDialog:mode";
53     private static final String INSTANCE_KEY_CUSTOM_TITLE =
54             "com.android.settings.wifi.AccessPointDialog:customTitle";
55     private static final String INSTANCE_KEY_AUTO_SECURITY_ALLOWED =
56             "com.android.settings.wifi.AccessPointDialog:autoSecurityAllowed";
57     
58     private static final int POSITIVE_BUTTON = BUTTON1;
59     private static final int NEGATIVE_BUTTON = BUTTON2;
60     private static final int NEUTRAL_BUTTON = BUTTON3;
61     
62     /** The dialog should show info connectivity functionality */
63     public static final int MODE_INFO = 0;
64     /** The dialog should configure the detailed AP properties */
65     public static final int MODE_CONFIGURE = 1;
66     /** The dialog should have the password field and connect/cancel */
67     public static final int MODE_RETRY_PASSWORD = 2;
68     
69     // These should be matched with the XML. Both arrays in XML depend on this
70     // ordering!
71     private static final int SECURITY_AUTO = 0;
72     private static final int SECURITY_NONE = 1;
73     private static final int SECURITY_WEP = 2;
74     private static final int SECURITY_WPA_PERSONAL = 3;
75     private static final int SECURITY_WPA2_PERSONAL = 4;
76     private static final int SECURITY_WPA_EAP = 5;
77     private static final int SECURITY_IEEE8021X = 6;
78
79     private static final int[] WEP_TYPE_VALUES = {
80             AccessPointState.WEP_PASSWORD_AUTO, AccessPointState.WEP_PASSWORD_ASCII,
81             AccessPointState.WEP_PASSWORD_HEX
82     };
83     private static final String NOT_APPLICABLE = "N/A";
84
85     // Button positions, default to impossible values
86     private int mConnectButtonPos = Integer.MAX_VALUE; 
87     private int mForgetButtonPos = Integer.MAX_VALUE;
88     private int mSaveButtonPos = Integer.MAX_VALUE;
89
90     // Client configurable items. Generally, these should be saved in instance state
91     private int mMode = MODE_INFO;
92     private boolean mAutoSecurityAllowed = true;
93     private CharSequence mCustomTitle;
94     // This does not need to be saved in instance state.
95     private WifiLayer mWifiLayer;
96     private AccessPointState mState;
97     
98     // General views
99     private View mView;
100     private View mEnterpriseView;
101     private TextView mPasswordText;
102     private EditText mPasswordEdit;
103     private CheckBox mShowPasswordCheckBox;
104
105     // Enterprise fields
106     private TextView mEapText;
107     private Spinner mEapSpinner;
108     private TextView mPhase2Text;
109     private Spinner mPhase2Spinner;
110     private TextView mIdentityText;
111     private EditText mIdentityEdit;
112     private TextView mAnonymousIdentityText;
113     private EditText mAnonymousIdentityEdit;
114     private TextView mClientCertText;
115     private Spinner mClientCertSpinner;
116     private TextView mCaCertText;
117     private Spinner mCaCertSpinner;
118     private TextView mPrivateKeyText;
119     private Spinner mPrivateKeySpinner;
120     private TextView mPrivateKeyPasswdText;
121     private EditText mPrivateKeyPasswdEdit;
122     private EditText[] mEnterpriseTextFields;
123     private Spinner[] mEnterpriseSpinnerFields;
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 Keystore mKeystore;
136     
137     public AccessPointDialog(Context context, WifiLayer wifiLayer) {
138         super(context);
139
140         mWifiLayer = wifiLayer;
141         mKeystore = Keystore.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 (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     private boolean isEnterprise() {
294
295         if(AccessPointState.WPA_EAP.equals(mState.security) ||
296             AccessPointState.IEEE8021X.equals(mState.security)) {
297             return true;
298         } else {
299             return false;
300         }
301     }
302
303     /** Called when we need to set our member variables to point to the views. */
304     private void onReferenceViews(View view) {
305         mPasswordText = (TextView) view.findViewById(R.id.password_text);
306         mPasswordEdit = (EditText) view.findViewById(R.id.password_edit);
307         mSsidText = (TextView) view.findViewById(R.id.ssid_text);
308         mSsidEdit = (EditText) view.findViewById(R.id.ssid_edit);
309         mSecurityText = (TextView) view.findViewById(R.id.security_text);
310         mSecuritySpinner = (Spinner) view.findViewById(R.id.security_spinner);
311         mWepTypeSpinner = (Spinner) view.findViewById(R.id.wep_type_spinner);
312         mEnterpriseView = mView.findViewById(R.id.enterprise_wrapper);
313
314         mShowPasswordCheckBox = (CheckBox) view.findViewById(R.id.show_password_checkbox);
315         if (mShowPasswordCheckBox != null) {
316             mShowPasswordCheckBox.setOnClickListener(this);
317         }
318         if (mMode == MODE_CONFIGURE) {
319             mSecuritySpinner.setOnItemSelectedListener(this);
320             mSecuritySpinner.setPromptId(R.string.security);
321             setSpinnerAdapter(mSecuritySpinner, mAutoSecurityAllowed ?
322                 R.array.wifi_security_entries
323                 : R.array.wifi_security_without_auto_entries);
324         } else if (mMode == MODE_INFO) {
325             mTable = (ViewGroup) view.findViewById(R.id.table);
326         }
327         /* for enterprise one */
328         if (mMode == MODE_CONFIGURE || (isEnterprise() && !mState.configured)) {
329             setEnterpriseFields(view);
330             mEapSpinner.setSelection(getSelectionIndex(
331                     R.array.wifi_eap_entries, mState.getEap()));
332             mClientCertSpinner.setSelection(getSelectionIndex(
333                     getAllCertificateKeys(), mState.getEnterpriseField(
334                     AccessPointState.CLIENT_CERT)));
335             mCaCertSpinner.setSelection(getSelectionIndex(
336                     getAllCertificateKeys(), mState.getEnterpriseField(
337                     AccessPointState.CA_CERT)));
338             mPrivateKeySpinner.setSelection(getSelectionIndex(
339                     getAllUserkeyKeys(), mState.getEnterpriseField(
340                     AccessPointState.PRIVATE_KEY)));
341         }
342     }
343
344     private String[] getAllCertificateKeys() {
345         return appendEmptyInSelection(mKeystore.getAllCertificateKeys());
346     }
347
348     private String[] getAllUserkeyKeys() {
349         return appendEmptyInSelection(mKeystore.getAllUserkeyKeys());
350     }
351
352     private String[] appendEmptyInSelection(String[] keys) {
353       if (keys.length == 0) return keys;
354       String[] selections = new String[keys.length + 1];
355       System.arraycopy(keys, 0, selections, 0, keys.length);
356       selections[keys.length] = NOT_APPLICABLE;
357       return selections;
358     }
359
360     private void setEnterpriseFields(View view) {
361         mIdentityText = (TextView) view.findViewById(R.id.identity_text);
362         mIdentityEdit = (EditText) view.findViewById(R.id.identity_edit);
363         mAnonymousIdentityText =
364                 (TextView) view.findViewById(R.id.anonymous_identity_text);
365         mAnonymousIdentityEdit =
366                 (EditText) view.findViewById(R.id.anonymous_identity_edit);
367         mClientCertText =
368                 (TextView) view.findViewById(R.id.client_certificate_text);
369         mCaCertText = (TextView) view.findViewById(R.id.ca_certificate_text);
370         mPrivateKeyText = (TextView) view.findViewById(R.id.private_key_text);
371         mPrivateKeyPasswdText =
372                 (TextView) view.findViewById(R.id.private_key_passwd_text);
373         mPrivateKeyPasswdEdit =
374                 (EditText) view.findViewById(R.id.private_key_passwd_edit);
375         mEapText = (TextView) view.findViewById(R.id.eap_text);
376         mEapSpinner = (Spinner) view.findViewById(R.id.eap_spinner);
377         mEapSpinner.setOnItemSelectedListener(this);
378         mEapSpinner.setPromptId(R.string.please_select_eap);
379         setSpinnerAdapter(mEapSpinner, R.array.wifi_eap_entries);
380
381         mPhase2Text = (TextView) view.findViewById(R.id.phase2_text);
382         mPhase2Spinner = (Spinner) view.findViewById(R.id.phase2_spinner);
383         mPhase2Spinner.setOnItemSelectedListener(this);
384         mPhase2Spinner.setPromptId(R.string.please_select_phase2);
385         setSpinnerAdapter(mPhase2Spinner, R.array.wifi_phase2_entries);
386
387         mClientCertSpinner =
388                 (Spinner) view.findViewById(R.id.client_certificate_spinner);
389         mClientCertSpinner.setOnItemSelectedListener(this);
390         mClientCertSpinner.setPromptId(
391                 R.string.please_select_client_certificate);
392         setSpinnerAdapter(mClientCertSpinner, getAllCertificateKeys());
393
394         mCaCertSpinner =
395                 (Spinner) view.findViewById(R.id.ca_certificate_spinner);
396         mCaCertSpinner.setOnItemSelectedListener(this);
397         mCaCertSpinner.setPromptId(R.string.please_select_ca_certificate);
398         setSpinnerAdapter(mCaCertSpinner, getAllCertificateKeys());
399
400         mPrivateKeySpinner =
401                 (Spinner) view.findViewById(R.id.private_key_spinner);
402         mPrivateKeySpinner.setOnItemSelectedListener(this);
403         mPrivateKeySpinner.setPromptId(R.string.please_select_private_key);
404         setSpinnerAdapter(mPrivateKeySpinner, getAllUserkeyKeys());
405
406         mEnterpriseTextFields = new EditText[] {
407             mIdentityEdit, mAnonymousIdentityEdit, mPrivateKeyPasswdEdit
408         };
409
410         mEnterpriseSpinnerFields = new Spinner[] {
411             mClientCertSpinner, mCaCertSpinner, mPrivateKeySpinner
412         };
413
414     }
415
416     private void setSpinnerAdapter(Spinner spinner, String[] items) {
417         if (items != null) {
418             ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
419                     getContext(), android.R.layout.simple_spinner_item, items);
420             adapter.setDropDownViewResource(
421                     android.R.layout.simple_spinner_dropdown_item);
422             spinner.setAdapter(adapter);
423         }
424     }
425
426     private void setSpinnerAdapter(Spinner spinner, int arrayResId) {
427         setSpinnerAdapter(spinner,
428             getContext().getResources().getStringArray(arrayResId));
429     }
430
431     /** Called when the widgets are in-place waiting to be filled with data */
432     private void onFill() {
433
434         // Appears in the order added
435         if (mMode == MODE_INFO) {
436             if (mState.primary) {
437                 addInfoRow(R.string.wifi_status, mState.getSummarizedStatus());
438                 addInfoRow(R.string.wifi_link_speed, mState.linkSpeed + WifiInfo.LINK_SPEED_UNITS);
439             }
440     
441             if (mState.seen) {
442                 addInfoRow(R.string.signal, getSignalResId(mState.signal));
443             }
444             
445             if (mState.security != null) {
446                 addInfoRow(R.string.security, mState.getHumanReadableSecurity());
447             }
448     
449             if (mState.primary && mState.ipAddress != 0) {
450                 addInfoRow(R.string.ip_address, Formatter.formatIpAddress(mState.ipAddress));
451             }
452             
453         } else if (mMode == MODE_CONFIGURE) {
454             String ssid = mState.getHumanReadableSsid();
455             if (!TextUtils.isEmpty(ssid)) {
456                 mSsidEdit.setText(ssid);
457             }
458             
459             mPasswordEdit.setHint(R.string.wifi_password_unchanged);
460         }
461
462         updatePasswordCaption(mState.security);
463     }
464
465     private void updatePasswordCaption(String security) {
466         if (mPasswordText != null) {
467             if (security != null && security.equals(AccessPointState.WEP)) {
468                 mPasswordText.setText(R.string.please_type_hex_key);
469             } else {
470                 mPasswordText.setText(R.string.please_type_passphrase);
471             }
472         }
473     }
474     
475     private void addInfoRow(int nameResId, String value) {
476         View rowView = getLayoutInflater().inflate(R.layout.wifi_ap_info_row, mTable, false);
477         ((TextView) rowView.findViewById(R.id.name)).setText(nameResId);
478         ((TextView) rowView.findViewById(R.id.value)).setText(value);
479         mTable.addView(rowView);
480     }
481         
482     private void addInfoRow(int nameResId, int valueResId) {
483         addInfoRow(nameResId, getContext().getString(valueResId));
484     }
485     
486     private void setButtons(int positiveResId, int negativeResId, int neutralResId) {
487         final Context context = getContext();
488         
489         if (positiveResId > 0) {
490             setButton(context.getString(positiveResId), this);
491         }
492         
493         if (negativeResId > 0) {
494             setButton2(context.getString(negativeResId), this);
495         }
496
497         if (neutralResId > 0) {
498             setButton3(context.getString(neutralResId), this);
499         }
500     }
501     
502     private void setLayout(int layoutResId) {
503         setView(mView = getLayoutInflater().inflate(layoutResId, null));
504         onReferenceViews(mView);
505     }
506     
507     public void onClick(DialogInterface dialog, int which) {
508         if (which == mForgetButtonPos) {
509             handleForget();
510         } else if (which == mConnectButtonPos) {
511             handleConnect();
512         } else if (which == mSaveButtonPos) {
513             handleSave();
514         }
515     }
516     
517     private void handleForget() {
518         if (!replaceStateWithWifiLayerInstance()) return;
519         mWifiLayer.forgetNetwork(mState);
520     }
521     
522     private void handleConnect() {
523         if (!replaceStateWithWifiLayerInstance()) {
524             Log.w(TAG, "Assuming connecting to a new network.");
525         }
526
527         if (isEnterprise()) {
528             if(!mState.configured) {
529                 updateEnterpriseFields(
530                         AccessPointState.WPA_EAP.equals(mState.security) ?
531                         SECURITY_WPA_EAP : SECURITY_IEEE8021X);
532             }
533         } else {
534             updatePasswordField();
535         }
536         mWifiLayer.connectToNetwork(mState);
537     }
538
539     /*
540      * If the network is secured and they haven't entered a password, popup an
541      * error. Allow empty passwords if the state already has a password set
542      * (since in that scenario, an empty password means keep the old password).
543      */
544     private void updatePasswordField() {
545
546       String password = getEnteredPassword();
547       boolean passwordIsEmpty = TextUtils.isEmpty(password);
548       /*
549        * When 'retry password', they can not enter a blank password. In any
550        * other mode, we let them enter a blank password if the state already
551        * has a password.
552        */
553       if (passwordIsEmpty && (!mState.hasPassword() ||
554               mMode == MODE_RETRY_PASSWORD) &&
555               (mState.security != null) &&
556               !mState.security.equals(AccessPointState.OPEN)) {
557           new AlertDialog.Builder(getContext())
558                   .setTitle(R.string.error_title)
559                   .setIcon(android.R.drawable.ic_dialog_alert)
560                   .setMessage(R.string.wifi_password_incorrect_error)
561                   .setPositiveButton(android.R.string.ok, null)
562                   .show();
563           return;
564       }
565
566       if (!passwordIsEmpty) {
567           mState.setPassword(password);
568       }
569     }
570
571     private void handleSave() {
572         replaceStateWithWifiLayerInstance();
573
574         String ssid = mSsidEdit.getText().toString();
575         String password = mPasswordEdit.getText().toString();
576         
577         mState.setSsid(ssid);
578         
579         int securityType = getSecurityTypeFromSpinner();
580         
581         if (!TextUtils.isEmpty(password)) {
582             switch (securityType) {
583              
584                 case SECURITY_WPA_PERSONAL: {
585                     mState.setSecurity(AccessPointState.WPA);
586                     mState.setPassword(password);
587                     break;
588                 }
589                     
590                 case SECURITY_WPA2_PERSONAL: {
591                     mState.setSecurity(AccessPointState.WPA2);
592                     mState.setPassword(password);
593                     break;
594                 }
595                 
596                 case SECURITY_AUTO: {
597                     mState.setPassword(password);
598                     break;
599                 }
600                     
601                 case SECURITY_WEP: {
602                     mState.setSecurity(AccessPointState.WEP);
603                     mState.setPassword(password,
604                             WEP_TYPE_VALUES[mWepTypeSpinner.getSelectedItemPosition()]);
605                     break;
606                 }
607                 
608             }
609         } else {
610             switch (securityType) {
611                 case SECURITY_WPA_EAP:
612                     mState.setSecurity(AccessPointState.WPA_EAP);
613                     break;
614                 case SECURITY_IEEE8021X:
615                     mState.setSecurity(AccessPointState.IEEE8021X);
616                     break;
617                 default:
618                     mState.setSecurity(AccessPointState.OPEN);
619                     break;
620             }
621             if (isEnterprise() && !mState.configured) {
622                 updateEnterpriseFields(
623                         AccessPointState.WPA_EAP.equals(mState.security) ?
624                         SECURITY_WPA_EAP : SECURITY_IEEE8021X);
625             }
626         }
627         
628         if (securityType == SECURITY_NONE) {
629             mState.setSecurity(AccessPointState.OPEN);
630         }
631             
632         if (!mWifiLayer.saveNetwork(mState)) {
633             return;
634         }
635         
636         // Connect right away if they've touched it
637         if (!mWifiLayer.connectToNetwork(mState)) {
638             return;
639         }
640         
641     }
642     
643     private int getSelectionIndex(String[] array, String selection) {
644         if(selection != null) {
645             for (int i = 0 ; i < array.length ; i++) {
646                 if (selection.contains(array[i])) return i;
647             }
648         }
649         return 0;
650     }
651
652     private int getSelectionIndex(int arrayResId, String selection) {
653         return getSelectionIndex(
654             getContext().getResources().getStringArray(arrayResId), selection);
655     }
656
657     private void updateEnterpriseFields(int securityType) {
658             int i;
659             for (i = AccessPointState.IDENTITY ;
660                 i < AccessPointState.MAX_ENTRPRISE_FIELD ; i++) {
661                 String value;
662                 if (i <= AccessPointState.PRIVATE_KEY_PASSWD) {
663                     value = mEnterpriseTextFields[i].getText().toString();
664                 } else {
665                     Spinner spinner =  mEnterpriseSpinnerFields[i -
666                         AccessPointState.CLIENT_CERT];
667                     int index = spinner.getSelectedItemPosition();
668                     if (index == (spinner.getCount() - 1)) {
669                         value = "";
670                     } else {
671                         if (i != AccessPointState.PRIVATE_KEY) {
672                             value = mKeystore.getCertificate(
673                                     getAllCertificateKeys()[index]);
674                         } else {
675                             value = mKeystore.getUserkey(
676                                     getAllUserkeyKeys()[index]);
677                         }
678                     }
679                 }
680                 if (!TextUtils.isEmpty(value) ||
681                         (i == AccessPointState.PRIVATE_KEY_PASSWD)) {
682                     mState.setEnterpriseField(i, value);
683                 }
684             }
685
686             switch (securityType) {
687                 case SECURITY_WPA_EAP: {
688                     mState.setSecurity(AccessPointState.WPA_EAP);
689                     mState.setEap(mEapSpinner.getSelectedItemPosition());
690                     break;
691                 }
692                 case SECURITY_IEEE8021X: {
693                     mState.setSecurity(AccessPointState.IEEE8021X);
694                     mState.setEap(mEapSpinner.getSelectedItemPosition());
695                   break;
696                 }
697                 default:
698                     mState.setSecurity(AccessPointState.OPEN);
699             }
700     }
701
702     /**
703      * Replaces our {@link #mState} with the equal WifiLayer instance.  This is useful after
704      * we unparceled the state previously and before we are calling methods on {@link #mWifiLayer}.
705      * 
706      * @return Whether WifiLayer was able to find an equal state in its set.
707      */
708     private boolean replaceStateWithWifiLayerInstance() {
709         AccessPointState state = mWifiLayer.getWifiLayerApInstance(mState);
710         if (state == null) {
711             return false;
712         }
713         
714         mState = state;
715         return true;
716     }
717     
718     private int getSecurityTypeFromSpinner() {
719         int position = mSecuritySpinner.getSelectedItemPosition();
720         // If there is no AUTO choice, the position needs 1 added to get
721         // to the proper spinner position -> security constants mapping
722         return mAutoSecurityAllowed ? position : position + 1;
723     }
724     
725     private String getEnteredPassword() {
726         return mPasswordEdit != null ? mPasswordEdit.getText().toString() : null;
727     }
728     
729     /**
730      * Call the one you want to hide first.
731      */
732     private void setWepVisible(boolean visible) {
733         setGenericPasswordVisible(visible);
734         int visibility = visible ? View.VISIBLE : View.GONE;
735         mWepTypeSpinner.setVisibility(visibility);
736     }
737     
738     /**
739      * @see #setWepVisible(boolean)
740      */
741     private void setGenericPasswordVisible(boolean visible) {
742         int visibility = visible ? View.VISIBLE : View.GONE;
743         mPasswordText.setVisibility(visibility);
744         mPasswordEdit.setVisibility(visibility);
745         mShowPasswordCheckBox.setVisibility(visibility);
746     }
747
748     private void setEnterpriseFieldsVisible(boolean visible) {
749         int visibility = visible ? View.VISIBLE : View.GONE;
750         mEnterpriseView.setVisibility(visibility);
751         if (visible) {
752             setWepVisible(false);
753             setGenericPasswordVisible(false);
754         }
755         if (mMode != MODE_CONFIGURE) {
756             mSsidText.setVisibility(View.GONE);
757             mSsidEdit.setVisibility(View.GONE);
758             mSecurityText.setVisibility(View.GONE);
759             mSecuritySpinner.setVisibility(View.GONE);
760         }
761     }
762
763     public void onItemSelected(AdapterView parent, View view, int position, long id) {
764         if (parent == mSecuritySpinner) {
765             handleSecurityChange(getSecurityTypeFromSpinner());
766         }
767     }
768
769     public void onNothingSelected(AdapterView parent) {
770     }
771
772     private void handleSecurityChange(int security) {
773         setEnterpriseFieldsVisible(false);
774         switch (security) {
775             
776             case SECURITY_NONE: {
777                 setWepVisible(false);
778                 setGenericPasswordVisible(false);
779                 break;
780             }
781             
782             case SECURITY_WEP: {
783                 setGenericPasswordVisible(false);
784                 setWepVisible(true);
785                 updatePasswordCaption(AccessPointState.WEP);
786                 break;
787             }
788             
789             case SECURITY_AUTO: {
790                 setWepVisible(false);
791                 setGenericPasswordVisible(mState.hasSecurity());
792                 // Shows the generic 'wireless password'
793                 updatePasswordCaption(AccessPointState.WPA);
794                 break;
795             }
796             
797             case SECURITY_WPA_PERSONAL:
798             case SECURITY_WPA2_PERSONAL: {
799                 setWepVisible(false);
800                 setGenericPasswordVisible(true);
801                 // Both WPA and WPA2 show the same caption, so either is ok
802                 updatePasswordCaption(AccessPointState.WPA);
803                 break;
804             }
805             case SECURITY_WPA_EAP:
806             case SECURITY_IEEE8021X: {
807                 setEnterpriseFieldsVisible(true);
808                 break;
809             }
810         }
811     }
812
813     private static int getSignalResId(int signal) {
814         switch (WifiManager.calculateSignalLevel(signal, 4)) {
815             case 0: {
816                 return R.string.wifi_signal_0;
817             }
818             case 1: {
819                 return R.string.wifi_signal_1;
820             }
821             case 2: {
822                 return R.string.wifi_signal_2;
823             }
824             case 3: {
825                 return R.string.wifi_signal_3;
826             }
827         }
828         
829         return 0;
830     }
831     
832
833     public void onClick(View v) {
834         if (v == mShowPasswordCheckBox) {
835             setShowPassword(mShowPasswordCheckBox.isChecked());
836         }
837     }
838     
839     private void setShowPassword(boolean showPassword) {
840         if (mPasswordEdit != null) {
841             mPasswordEdit.setInputType(InputType.TYPE_CLASS_TEXT |
842                     (showPassword ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
843                             : InputType.TYPE_TEXT_VARIATION_PASSWORD));
844         }
845     }
846     
847 }