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