OSDN Git Service

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