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