• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
20 
21 import android.content.Context;
22 import android.content.res.Resources;
23 import android.net.LinkAddress;
24 import android.net.LinkProperties;
25 import android.net.NetworkInfo.DetailedState;
26 import android.net.NetworkUtils;
27 import android.net.ProxyProperties;
28 import android.net.RouteInfo;
29 import android.net.wifi.WifiConfiguration;
30 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
31 import android.net.wifi.WifiConfiguration.IpAssignment;
32 import android.net.wifi.WifiConfiguration.KeyMgmt;
33 import android.net.wifi.WifiConfiguration.ProxySettings;
34 import android.net.wifi.WifiConfiguration.Status;
35 import android.net.wifi.WifiInfo;
36 import android.os.Handler;
37 import android.security.Credentials;
38 import android.security.KeyStore;
39 import android.text.Editable;
40 import android.text.InputType;
41 import android.text.TextWatcher;
42 import android.text.TextUtils;
43 import android.util.Log;
44 import android.view.View;
45 import android.view.ViewGroup;
46 import android.widget.AdapterView;
47 import android.widget.ArrayAdapter;
48 import android.widget.Button;
49 import android.widget.CheckBox;
50 import android.widget.EditText;
51 import android.widget.Spinner;
52 import android.widget.TextView;
53 
54 import com.android.settings.ProxySelector;
55 import com.android.settings.R;
56 
57 import java.net.InetAddress;
58 import java.util.Iterator;
59 
60 /**
61  * The class for allowing UIs like {@link WifiDialog} and {@link WifiConfigUiBase} to
62  * share the logic for controlling buttons, text fields, etc.
63  */
64 public class WifiConfigController implements TextWatcher,
65         View.OnClickListener, AdapterView.OnItemSelectedListener {
66     private static final String KEYSTORE_SPACE = WifiConfiguration.KEYSTORE_URI;
67 
68     private static final String PHASE2_PREFIX = "auth=";
69 
70     private final WifiConfigUiBase mConfigUi;
71     private final View mView;
72     private final AccessPoint mAccessPoint;
73 
74     private boolean mEdit;
75 
76     private TextView mSsidView;
77 
78     // e.g. AccessPoint.SECURITY_NONE
79     private int mAccessPointSecurity;
80     private TextView mPasswordView;
81 
82     private Spinner mSecuritySpinner;
83     private Spinner mEapMethodSpinner;
84     private Spinner mEapCaCertSpinner;
85     private Spinner mPhase2Spinner;
86     private Spinner mEapUserCertSpinner;
87     private TextView mEapIdentityView;
88     private TextView mEapAnonymousView;
89 
90     /* This value comes from "wifi_ip_settings" resource array */
91     private static final int DHCP = 0;
92     private static final int STATIC_IP = 1;
93 
94     /* These values come from "wifi_proxy_settings" resource array */
95     public static final int PROXY_NONE = 0;
96     public static final int PROXY_STATIC = 1;
97 
98     /* These values from from "wifi_eap_method" resource array */
99     public static final int WIFI_EAP_METHOD_PEAP = 0;
100     public static final int WIFI_EAP_METHOD_TLS  = 1;
101     public static final int WIFI_EAP_METHOD_TTLS = 2;
102     public static final int WIFI_EAP_METHOD_PWD  = 3;
103 
104     private static final String TAG = "WifiConfigController";
105 
106     private Spinner mIpSettingsSpinner;
107     private TextView mIpAddressView;
108     private TextView mGatewayView;
109     private TextView mNetworkPrefixLengthView;
110     private TextView mDns1View;
111     private TextView mDns2View;
112 
113     private Spinner mProxySettingsSpinner;
114     private TextView mProxyHostView;
115     private TextView mProxyPortView;
116     private TextView mProxyExclusionListView;
117 
118     private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED;
119     private ProxySettings mProxySettings = ProxySettings.UNASSIGNED;
120     private LinkProperties mLinkProperties = new LinkProperties();
121 
122     // True when this instance is used in SetupWizard XL context.
123     private final boolean mInXlSetupWizard;
124 
125     private final Handler mTextViewChangedHandler;
126 
requireKeyStore(WifiConfiguration config)127     static boolean requireKeyStore(WifiConfiguration config) {
128         if (config == null) {
129             return false;
130         }
131         if (!TextUtils.isEmpty(config.key_id.value())) {
132             return true;
133         }
134         String values[] = { config.ca_cert.value(), config.client_cert.value() };
135         for (String value : values) {
136             if (value != null && value.startsWith(KEYSTORE_SPACE)) {
137                 return true;
138             }
139         }
140         return false;
141     }
142 
WifiConfigController( WifiConfigUiBase parent, View view, AccessPoint accessPoint, boolean edit)143     public WifiConfigController(
144             WifiConfigUiBase parent, View view, AccessPoint accessPoint, boolean edit) {
145         mConfigUi = parent;
146         mInXlSetupWizard = (parent instanceof WifiConfigUiForSetupWizardXL);
147 
148         mView = view;
149         mAccessPoint = accessPoint;
150         mAccessPointSecurity = (accessPoint == null) ? AccessPoint.SECURITY_NONE :
151                 accessPoint.security;
152         mEdit = edit;
153 
154         mTextViewChangedHandler = new Handler();
155         final Context context = mConfigUi.getContext();
156         final Resources resources = context.getResources();
157 
158         mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ip_settings);
159         mIpSettingsSpinner.setOnItemSelectedListener(this);
160         mProxySettingsSpinner = (Spinner) mView.findViewById(R.id.proxy_settings);
161         mProxySettingsSpinner.setOnItemSelectedListener(this);
162 
163         if (mAccessPoint == null) { // new network
164             mConfigUi.setTitle(R.string.wifi_add_network);
165 
166             mSsidView = (TextView) mView.findViewById(R.id.ssid);
167             mSsidView.addTextChangedListener(this);
168             mSecuritySpinner = ((Spinner) mView.findViewById(R.id.security));
169             mSecuritySpinner.setOnItemSelectedListener(this);
170             if (mInXlSetupWizard) {
171                 mView.findViewById(R.id.type_ssid).setVisibility(View.VISIBLE);
172                 mView.findViewById(R.id.type_security).setVisibility(View.VISIBLE);
173                 // We want custom layout. The content must be same as the other cases.
174 
175                 ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,
176                         R.layout.wifi_setup_custom_list_item_1, android.R.id.text1,
177                         context.getResources().getStringArray(R.array.wifi_security_no_eap));
178                 mSecuritySpinner.setAdapter(adapter);
179             } else {
180                 mView.findViewById(R.id.type).setVisibility(View.VISIBLE);
181             }
182 
183             showIpConfigFields();
184             showProxyFields();
185             mView.findViewById(R.id.wifi_advanced_toggle).setVisibility(View.VISIBLE);
186             mView.findViewById(R.id.wifi_advanced_togglebox).setOnClickListener(this);
187 
188             mConfigUi.setSubmitButton(context.getString(R.string.wifi_save));
189         } else {
190             mConfigUi.setTitle(mAccessPoint.ssid);
191 
192             ViewGroup group = (ViewGroup) mView.findViewById(R.id.info);
193 
194             DetailedState state = mAccessPoint.getState();
195             if (state != null) {
196                 addRow(group, R.string.wifi_status, Summary.get(mConfigUi.getContext(), state));
197             }
198 
199             int level = mAccessPoint.getLevel();
200             if (level != -1) {
201                 String[] signal = resources.getStringArray(R.array.wifi_signal);
202                 addRow(group, R.string.wifi_signal, signal[level]);
203             }
204 
205             WifiInfo info = mAccessPoint.getInfo();
206             if (info != null && info.getLinkSpeed() != -1) {
207                 addRow(group, R.string.wifi_speed, info.getLinkSpeed() + WifiInfo.LINK_SPEED_UNITS);
208             }
209 
210             addRow(group, R.string.wifi_security, mAccessPoint.getSecurityString(false));
211 
212             boolean showAdvancedFields = false;
213             if (mAccessPoint.networkId != INVALID_NETWORK_ID) {
214                 WifiConfiguration config = mAccessPoint.getConfig();
215                 if (config.ipAssignment == IpAssignment.STATIC) {
216                     mIpSettingsSpinner.setSelection(STATIC_IP);
217                     showAdvancedFields = true;
218                 } else {
219                     mIpSettingsSpinner.setSelection(DHCP);
220                 }
221                 //Display IP addresses
222                 for(InetAddress a : config.linkProperties.getAddresses()) {
223                     addRow(group, R.string.wifi_ip_address, a.getHostAddress());
224                 }
225 
226 
227                 if (config.proxySettings == ProxySettings.STATIC) {
228                     mProxySettingsSpinner.setSelection(PROXY_STATIC);
229                     showAdvancedFields = true;
230                 } else {
231                     mProxySettingsSpinner.setSelection(PROXY_NONE);
232                 }
233             }
234 
235             if (mAccessPoint.networkId == INVALID_NETWORK_ID || mEdit) {
236                 showSecurityFields();
237                 showIpConfigFields();
238                 showProxyFields();
239                 mView.findViewById(R.id.wifi_advanced_toggle).setVisibility(View.VISIBLE);
240                 mView.findViewById(R.id.wifi_advanced_togglebox).setOnClickListener(this);
241                 if (showAdvancedFields) {
242                     ((CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox)).setChecked(true);
243                     mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.VISIBLE);
244                 }
245             }
246 
247             if (mEdit) {
248                 mConfigUi.setSubmitButton(context.getString(R.string.wifi_save));
249             } else {
250                 if (state == null && level != -1) {
251                     mConfigUi.setSubmitButton(context.getString(R.string.wifi_connect));
252                 } else {
253                     mView.findViewById(R.id.ip_fields).setVisibility(View.GONE);
254                 }
255                 if (mAccessPoint.networkId != INVALID_NETWORK_ID) {
256                     mConfigUi.setForgetButton(context.getString(R.string.wifi_forget));
257                 }
258             }
259         }
260 
261 
262         mConfigUi.setCancelButton(context.getString(R.string.wifi_cancel));
263         if (mConfigUi.getSubmitButton() != null) {
264             enableSubmitIfAppropriate();
265         }
266     }
267 
addRow(ViewGroup group, int name, String value)268     private void addRow(ViewGroup group, int name, String value) {
269         View row = mConfigUi.getLayoutInflater().inflate(R.layout.wifi_dialog_row, group, false);
270         ((TextView) row.findViewById(R.id.name)).setText(name);
271         ((TextView) row.findViewById(R.id.value)).setText(value);
272         group.addView(row);
273     }
274 
275     /* show submit button if password, ip and proxy settings are valid */
enableSubmitIfAppropriate()276     void enableSubmitIfAppropriate() {
277         Button submit = mConfigUi.getSubmitButton();
278         if (submit == null) return;
279 
280         boolean enabled = false;
281         boolean passwordInvalid = false;
282 
283         if (mPasswordView != null &&
284             ((mAccessPointSecurity == AccessPoint.SECURITY_WEP && mPasswordView.length() == 0) ||
285             (mAccessPointSecurity == AccessPoint.SECURITY_PSK && mPasswordView.length() < 8))) {
286             passwordInvalid = true;
287         }
288 
289         if ((mSsidView != null && mSsidView.length() == 0) ||
290             ((mAccessPoint == null || mAccessPoint.networkId == INVALID_NETWORK_ID) &&
291             passwordInvalid)) {
292             enabled = false;
293         } else {
294             if (ipAndProxyFieldsAreValid()) {
295                 enabled = true;
296             } else {
297                 enabled = false;
298             }
299         }
300         submit.setEnabled(enabled);
301     }
302 
getConfig()303     /* package */ WifiConfiguration getConfig() {
304         if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID && !mEdit) {
305             return null;
306         }
307 
308         WifiConfiguration config = new WifiConfiguration();
309 
310         if (mAccessPoint == null) {
311             config.SSID = AccessPoint.convertToQuotedString(
312                     mSsidView.getText().toString());
313             // If the user adds a network manually, assume that it is hidden.
314             config.hiddenSSID = true;
315         } else if (mAccessPoint.networkId == INVALID_NETWORK_ID) {
316             config.SSID = AccessPoint.convertToQuotedString(
317                     mAccessPoint.ssid);
318         } else {
319             config.networkId = mAccessPoint.networkId;
320         }
321 
322         switch (mAccessPointSecurity) {
323             case AccessPoint.SECURITY_NONE:
324                 config.allowedKeyManagement.set(KeyMgmt.NONE);
325                 break;
326 
327             case AccessPoint.SECURITY_WEP:
328                 config.allowedKeyManagement.set(KeyMgmt.NONE);
329                 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
330                 config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
331                 if (mPasswordView.length() != 0) {
332                     int length = mPasswordView.length();
333                     String password = mPasswordView.getText().toString();
334                     // WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
335                     if ((length == 10 || length == 26 || length == 58) &&
336                             password.matches("[0-9A-Fa-f]*")) {
337                         config.wepKeys[0] = password;
338                     } else {
339                         config.wepKeys[0] = '"' + password + '"';
340                     }
341                 }
342                 break;
343 
344             case AccessPoint.SECURITY_PSK:
345                 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
346                 if (mPasswordView.length() != 0) {
347                     String password = mPasswordView.getText().toString();
348                     if (password.matches("[0-9A-Fa-f]{64}")) {
349                         config.preSharedKey = password;
350                     } else {
351                         config.preSharedKey = '"' + password + '"';
352                     }
353                 }
354                 break;
355 
356             case AccessPoint.SECURITY_EAP:
357                 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
358                 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
359                 config.eap.setValue((String) mEapMethodSpinner.getSelectedItem());
360 
361                 config.phase2.setValue((mPhase2Spinner.getSelectedItemPosition() == 0) ? "" :
362                         PHASE2_PREFIX + mPhase2Spinner.getSelectedItem());
363                 config.ca_cert.setValue((mEapCaCertSpinner.getSelectedItemPosition() == 0) ? "" :
364                         KEYSTORE_SPACE + Credentials.CA_CERTIFICATE +
365                         (String) mEapCaCertSpinner.getSelectedItem());
366                 config.client_cert.setValue((mEapUserCertSpinner.getSelectedItemPosition() == 0) ?
367                         "" : KEYSTORE_SPACE + Credentials.USER_CERTIFICATE +
368                         (String) mEapUserCertSpinner.getSelectedItem());
369                 final boolean isEmptyKeyId = (mEapUserCertSpinner.getSelectedItemPosition() == 0);
370                 config.key_id.setValue(isEmptyKeyId ? "" : Credentials.USER_PRIVATE_KEY +
371                         (String) mEapUserCertSpinner.getSelectedItem());
372                 config.engine.setValue(isEmptyKeyId ? WifiConfiguration.ENGINE_DISABLE :
373                         WifiConfiguration.ENGINE_ENABLE);
374                 config.engine_id.setValue(isEmptyKeyId ? "" : WifiConfiguration.KEYSTORE_ENGINE_ID);
375                 config.identity.setValue((mEapIdentityView.length() == 0) ? "" :
376                         mEapIdentityView.getText().toString());
377                 config.anonymous_identity.setValue((mEapAnonymousView.length() == 0) ? "" :
378                         mEapAnonymousView.getText().toString());
379                 if (mPasswordView.length() != 0) {
380                     config.password.setValue(mPasswordView.getText().toString());
381                 }
382                 break;
383 
384             default:
385                     return null;
386         }
387 
388         config.proxySettings = mProxySettings;
389         config.ipAssignment = mIpAssignment;
390         config.linkProperties = new LinkProperties(mLinkProperties);
391 
392         return config;
393     }
394 
ipAndProxyFieldsAreValid()395     private boolean ipAndProxyFieldsAreValid() {
396         mLinkProperties.clear();
397         mIpAssignment = (mIpSettingsSpinner != null &&
398                 mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) ?
399                 IpAssignment.STATIC : IpAssignment.DHCP;
400 
401         if (mIpAssignment == IpAssignment.STATIC) {
402             int result = validateIpConfigFields(mLinkProperties);
403             if (result != 0) {
404                 return false;
405             }
406         }
407 
408         mProxySettings = (mProxySettingsSpinner != null &&
409                 mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) ?
410                 ProxySettings.STATIC : ProxySettings.NONE;
411 
412         if (mProxySettings == ProxySettings.STATIC && mProxyHostView != null) {
413             String host = mProxyHostView.getText().toString();
414             String portStr = mProxyPortView.getText().toString();
415             String exclusionList = mProxyExclusionListView.getText().toString();
416             int port = 0;
417             int result = 0;
418             try {
419                 port = Integer.parseInt(portStr);
420                 result = ProxySelector.validate(host, portStr, exclusionList);
421             } catch (NumberFormatException e) {
422                 result = R.string.proxy_error_invalid_port;
423             }
424             if (result == 0) {
425                 ProxyProperties proxyProperties= new ProxyProperties(host, port, exclusionList);
426                 mLinkProperties.setHttpProxy(proxyProperties);
427             } else {
428                 return false;
429             }
430         }
431         return true;
432     }
433 
validateIpConfigFields(LinkProperties linkProperties)434     private int validateIpConfigFields(LinkProperties linkProperties) {
435         if (mIpAddressView == null) return 0;
436 
437         String ipAddr = mIpAddressView.getText().toString();
438         if (TextUtils.isEmpty(ipAddr)) return R.string.wifi_ip_settings_invalid_ip_address;
439 
440         InetAddress inetAddr = null;
441         try {
442             inetAddr = NetworkUtils.numericToInetAddress(ipAddr);
443         } catch (IllegalArgumentException e) {
444             return R.string.wifi_ip_settings_invalid_ip_address;
445         }
446 
447         int networkPrefixLength = -1;
448         try {
449             networkPrefixLength = Integer.parseInt(mNetworkPrefixLengthView.getText().toString());
450             if (networkPrefixLength < 0 || networkPrefixLength > 32) {
451                 return R.string.wifi_ip_settings_invalid_network_prefix_length;
452             }
453             linkProperties.addLinkAddress(new LinkAddress(inetAddr, networkPrefixLength));
454         } catch (NumberFormatException e) {
455             // Set the hint as default after user types in ip address
456             mNetworkPrefixLengthView.setText(mConfigUi.getContext().getString(
457                     R.string.wifi_network_prefix_length_hint));
458         }
459 
460         String gateway = mGatewayView.getText().toString();
461         if (TextUtils.isEmpty(gateway)) {
462             try {
463                 //Extract a default gateway from IP address
464                 InetAddress netPart = NetworkUtils.getNetworkPart(inetAddr, networkPrefixLength);
465                 byte[] addr = netPart.getAddress();
466                 addr[addr.length-1] = 1;
467                 mGatewayView.setText(InetAddress.getByAddress(addr).getHostAddress());
468             } catch (RuntimeException ee) {
469             } catch (java.net.UnknownHostException u) {
470             }
471         } else {
472             InetAddress gatewayAddr = null;
473             try {
474                 gatewayAddr = NetworkUtils.numericToInetAddress(gateway);
475             } catch (IllegalArgumentException e) {
476                 return R.string.wifi_ip_settings_invalid_gateway;
477             }
478             linkProperties.addRoute(new RouteInfo(gatewayAddr));
479         }
480 
481         String dns = mDns1View.getText().toString();
482         InetAddress dnsAddr = null;
483 
484         if (TextUtils.isEmpty(dns)) {
485             //If everything else is valid, provide hint as a default option
486             mDns1View.setText(mConfigUi.getContext().getString(R.string.wifi_dns1_hint));
487         } else {
488             try {
489                 dnsAddr = NetworkUtils.numericToInetAddress(dns);
490             } catch (IllegalArgumentException e) {
491                 return R.string.wifi_ip_settings_invalid_dns;
492             }
493             linkProperties.addDns(dnsAddr);
494         }
495 
496         if (mDns2View.length() > 0) {
497             dns = mDns2View.getText().toString();
498             try {
499                 dnsAddr = NetworkUtils.numericToInetAddress(dns);
500             } catch (IllegalArgumentException e) {
501                 return R.string.wifi_ip_settings_invalid_dns;
502             }
503             linkProperties.addDns(dnsAddr);
504         }
505         return 0;
506     }
507 
showSecurityFields()508     private void showSecurityFields() {
509         if (mInXlSetupWizard) {
510             // Note: XL SetupWizard won't hide "EAP" settings here.
511             if (!((WifiSettingsForSetupWizardXL)mConfigUi.getContext()).initSecurityFields(mView,
512                         mAccessPointSecurity)) {
513                 return;
514             }
515         }
516         if (mAccessPointSecurity == AccessPoint.SECURITY_NONE) {
517             mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
518             return;
519         }
520         mView.findViewById(R.id.security_fields).setVisibility(View.VISIBLE);
521 
522         if (mPasswordView == null) {
523             mPasswordView = (TextView) mView.findViewById(R.id.password);
524             mPasswordView.addTextChangedListener(this);
525             ((CheckBox) mView.findViewById(R.id.show_password)).setOnClickListener(this);
526 
527             if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
528                 mPasswordView.setHint(R.string.wifi_unchanged);
529             }
530         }
531 
532         if (mAccessPointSecurity != AccessPoint.SECURITY_EAP) {
533             mView.findViewById(R.id.eap).setVisibility(View.GONE);
534             return;
535         }
536         mView.findViewById(R.id.eap).setVisibility(View.VISIBLE);
537 
538         if (mEapMethodSpinner == null) {
539             mEapMethodSpinner = (Spinner) mView.findViewById(R.id.method);
540             mEapMethodSpinner.setOnItemSelectedListener(this);
541             mPhase2Spinner = (Spinner) mView.findViewById(R.id.phase2);
542             mEapCaCertSpinner = (Spinner) mView.findViewById(R.id.ca_cert);
543             mEapUserCertSpinner = (Spinner) mView.findViewById(R.id.user_cert);
544             mEapIdentityView = (TextView) mView.findViewById(R.id.identity);
545             mEapAnonymousView = (TextView) mView.findViewById(R.id.anonymous);
546 
547             loadCertificates(mEapCaCertSpinner, Credentials.CA_CERTIFICATE);
548             loadCertificates(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY);
549 
550             if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
551                 WifiConfiguration config = mAccessPoint.getConfig();
552                 setSelection(mEapMethodSpinner, config.eap.value());
553 
554                 final String phase2Method = config.phase2.value();
555                 if (phase2Method != null && phase2Method.startsWith(PHASE2_PREFIX)) {
556                     setSelection(mPhase2Spinner, phase2Method.substring(PHASE2_PREFIX.length()));
557                 } else {
558                     setSelection(mPhase2Spinner, phase2Method);
559                 }
560 
561                 setCertificate(mEapCaCertSpinner, KEYSTORE_SPACE + Credentials.CA_CERTIFICATE,
562                         config.ca_cert.value());
563                 setCertificate(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY,
564                         config.key_id.value());
565                 mEapIdentityView.setText(config.identity.value());
566                 mEapAnonymousView.setText(config.anonymous_identity.value());
567             }
568         }
569 
570         mView.findViewById(R.id.l_method).setVisibility(View.VISIBLE);
571         mView.findViewById(R.id.l_identity).setVisibility(View.VISIBLE);
572 
573         if (mEapMethodSpinner.getSelectedItemPosition() == WIFI_EAP_METHOD_PWD){
574             mView.findViewById(R.id.l_phase2).setVisibility(View.GONE);
575             mView.findViewById(R.id.l_ca_cert).setVisibility(View.GONE);
576             mView.findViewById(R.id.l_user_cert).setVisibility(View.GONE);
577             mView.findViewById(R.id.l_anonymous).setVisibility(View.GONE);
578         } else {
579             mView.findViewById(R.id.l_phase2).setVisibility(View.VISIBLE);
580             mView.findViewById(R.id.l_ca_cert).setVisibility(View.VISIBLE);
581             mView.findViewById(R.id.l_user_cert).setVisibility(View.VISIBLE);
582             mView.findViewById(R.id.l_anonymous).setVisibility(View.VISIBLE);
583         }
584     }
585 
showIpConfigFields()586     private void showIpConfigFields() {
587         WifiConfiguration config = null;
588 
589         mView.findViewById(R.id.ip_fields).setVisibility(View.VISIBLE);
590 
591         if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
592             config = mAccessPoint.getConfig();
593         }
594 
595         if (mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) {
596             mView.findViewById(R.id.staticip).setVisibility(View.VISIBLE);
597             if (mIpAddressView == null) {
598                 mIpAddressView = (TextView) mView.findViewById(R.id.ipaddress);
599                 mIpAddressView.addTextChangedListener(this);
600                 mGatewayView = (TextView) mView.findViewById(R.id.gateway);
601                 mGatewayView.addTextChangedListener(this);
602                 mNetworkPrefixLengthView = (TextView) mView.findViewById(
603                         R.id.network_prefix_length);
604                 mNetworkPrefixLengthView.addTextChangedListener(this);
605                 mDns1View = (TextView) mView.findViewById(R.id.dns1);
606                 mDns1View.addTextChangedListener(this);
607                 mDns2View = (TextView) mView.findViewById(R.id.dns2);
608                 mDns2View.addTextChangedListener(this);
609             }
610             if (config != null) {
611                 LinkProperties linkProperties = config.linkProperties;
612                 Iterator<LinkAddress> iterator = linkProperties.getLinkAddresses().iterator();
613                 if (iterator.hasNext()) {
614                     LinkAddress linkAddress = iterator.next();
615                     mIpAddressView.setText(linkAddress.getAddress().getHostAddress());
616                     mNetworkPrefixLengthView.setText(Integer.toString(linkAddress
617                             .getNetworkPrefixLength()));
618                 }
619 
620                 for (RouteInfo route : linkProperties.getRoutes()) {
621                     if (route.isDefaultRoute()) {
622                         mGatewayView.setText(route.getGateway().getHostAddress());
623                         break;
624                     }
625                 }
626 
627                 Iterator<InetAddress> dnsIterator = linkProperties.getDnses().iterator();
628                 if (dnsIterator.hasNext()) {
629                     mDns1View.setText(dnsIterator.next().getHostAddress());
630                 }
631                 if (dnsIterator.hasNext()) {
632                     mDns2View.setText(dnsIterator.next().getHostAddress());
633                 }
634             }
635         } else {
636             mView.findViewById(R.id.staticip).setVisibility(View.GONE);
637         }
638     }
639 
showProxyFields()640     private void showProxyFields() {
641         WifiConfiguration config = null;
642 
643         mView.findViewById(R.id.proxy_settings_fields).setVisibility(View.VISIBLE);
644 
645         if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
646             config = mAccessPoint.getConfig();
647         }
648 
649         if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) {
650             mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.VISIBLE);
651             mView.findViewById(R.id.proxy_fields).setVisibility(View.VISIBLE);
652             if (mProxyHostView == null) {
653                 mProxyHostView = (TextView) mView.findViewById(R.id.proxy_hostname);
654                 mProxyHostView.addTextChangedListener(this);
655                 mProxyPortView = (TextView) mView.findViewById(R.id.proxy_port);
656                 mProxyPortView.addTextChangedListener(this);
657                 mProxyExclusionListView = (TextView) mView.findViewById(R.id.proxy_exclusionlist);
658                 mProxyExclusionListView.addTextChangedListener(this);
659             }
660             if (config != null) {
661                 ProxyProperties proxyProperties = config.linkProperties.getHttpProxy();
662                 if (proxyProperties != null) {
663                     mProxyHostView.setText(proxyProperties.getHost());
664                     mProxyPortView.setText(Integer.toString(proxyProperties.getPort()));
665                     mProxyExclusionListView.setText(proxyProperties.getExclusionList());
666                 }
667             }
668         } else {
669             mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.GONE);
670             mView.findViewById(R.id.proxy_fields).setVisibility(View.GONE);
671         }
672     }
673 
674 
675 
loadCertificates(Spinner spinner, String prefix)676     private void loadCertificates(Spinner spinner, String prefix) {
677         final Context context = mConfigUi.getContext();
678         final String unspecified = context.getString(R.string.wifi_unspecified);
679 
680         String[] certs = KeyStore.getInstance().saw(prefix);
681         if (certs == null || certs.length == 0) {
682             certs = new String[] {unspecified};
683         } else {
684             final String[] array = new String[certs.length + 1];
685             array[0] = unspecified;
686             System.arraycopy(certs, 0, array, 1, certs.length);
687             certs = array;
688         }
689 
690         final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
691                 context, android.R.layout.simple_spinner_item, certs);
692         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
693         spinner.setAdapter(adapter);
694     }
695 
setCertificate(Spinner spinner, String prefix, String cert)696     private void setCertificate(Spinner spinner, String prefix, String cert) {
697         if (cert != null && cert.startsWith(prefix)) {
698             setSelection(spinner, cert.substring(prefix.length()));
699         }
700     }
701 
setSelection(Spinner spinner, String value)702     private void setSelection(Spinner spinner, String value) {
703         if (value != null) {
704             @SuppressWarnings("unchecked")
705             ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinner.getAdapter();
706             for (int i = adapter.getCount() - 1; i >= 0; --i) {
707                 if (value.equals(adapter.getItem(i))) {
708                     spinner.setSelection(i);
709                     break;
710                 }
711             }
712         }
713     }
714 
isEdit()715     public boolean isEdit() {
716         return mEdit;
717     }
718 
719     @Override
afterTextChanged(Editable s)720     public void afterTextChanged(Editable s) {
721         mTextViewChangedHandler.post(new Runnable() {
722                 public void run() {
723                     enableSubmitIfAppropriate();
724                 }
725             });
726     }
727 
728     @Override
beforeTextChanged(CharSequence s, int start, int count, int after)729     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
730         // work done in afterTextChanged
731     }
732 
733     @Override
onTextChanged(CharSequence s, int start, int before, int count)734     public void onTextChanged(CharSequence s, int start, int before, int count) {
735         // work done in afterTextChanged
736     }
737 
738     @Override
onClick(View view)739     public void onClick(View view) {
740         if (view.getId() == R.id.show_password) {
741             int pos = mPasswordView.getSelectionEnd();
742             mPasswordView.setInputType(
743                     InputType.TYPE_CLASS_TEXT | (((CheckBox) view).isChecked() ?
744                             InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD :
745                                 InputType.TYPE_TEXT_VARIATION_PASSWORD));
746             if (pos >= 0) {
747                 ((EditText)mPasswordView).setSelection(pos);
748             }
749         } else if (view.getId() == R.id.wifi_advanced_togglebox) {
750             if (((CheckBox) view).isChecked()) {
751                 mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.VISIBLE);
752             } else {
753                 mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.GONE);
754             }
755         }
756     }
757 
758     @Override
onItemSelected(AdapterView<?> parent, View view, int position, long id)759     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
760         if (parent == mSecuritySpinner) {
761             mAccessPointSecurity = position;
762             showSecurityFields();
763         } else if (parent == mEapMethodSpinner) {
764             showSecurityFields();
765         } else if (parent == mProxySettingsSpinner) {
766             showProxyFields();
767         } else {
768             showIpConfigFields();
769         }
770         enableSubmitIfAppropriate();
771     }
772 
773     @Override
onNothingSelected(AdapterView<?> parent)774     public void onNothingSelected(AdapterView<?> parent) {
775         //
776     }
777 }
778