2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.wifi;
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.wifi.WifiConfiguration;
30 import android.net.wifi.WifiConfiguration.IpAssignment;
31 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
32 import android.net.wifi.WifiConfiguration.KeyMgmt;
33 import android.net.wifi.WpsConfiguration;
34 import android.net.wifi.WpsConfiguration.Setup;
36 import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
37 import android.net.wifi.WifiConfiguration.ProxySettings;
38 import android.net.wifi.WifiInfo;
39 import android.security.Credentials;
40 import android.security.KeyStore;
41 import android.text.Editable;
42 import android.text.InputType;
43 import android.text.TextWatcher;
44 import android.text.format.Formatter;
45 import android.util.Log;
46 import android.view.View;
47 import android.view.ViewGroup;
48 import android.widget.AdapterView;
49 import android.widget.ArrayAdapter;
50 import android.widget.CheckBox;
51 import android.widget.Spinner;
52 import android.widget.TextView;
53 import android.widget.Toast;
55 import com.android.settings.ProxySelector;
56 import com.android.settings.R;
58 import java.net.InetAddress;
59 import java.net.InetSocketAddress;
60 import java.net.UnknownHostException;
61 import java.util.Iterator;
64 * The class for allowing UIs like {@link WifiDialog} and {@link WifiConfigPreference} to
65 * share the logic for controlling buttons, text fields, etc.
67 public class WifiConfigController implements TextWatcher,
68 View.OnClickListener, AdapterView.OnItemSelectedListener {
69 private static final String KEYSTORE_SPACE = "keystore://";
71 private final WifiConfigUiBase mConfigUi;
72 private final View mView;
73 private final AccessPoint mAccessPoint;
75 private boolean mEdit;
77 private TextView mSsidView;
79 // e.g. AccessPoint.SECURITY_NONE
80 private int mAccessPointSecurity;
81 private TextView mPasswordView;
83 private Spinner mSecuritySpinner;
84 private Spinner mEapMethodSpinner;
85 private Spinner mEapCaCertSpinner;
86 private Spinner mPhase2Spinner;
87 private Spinner mEapUserCertSpinner;
88 private TextView mEapIdentityView;
89 private TextView mEapAnonymousView;
91 /* This value comes from "wifi_ip_settings" resource array */
92 private static final int DHCP = 0;
93 private static final int STATIC_IP = 1;
95 /* These values come from "wifi_network_setup" resource array */
96 public static final int MANUAL = 0;
97 public static final int WPS_PBC = 1;
98 public static final int WPS_PIN_FROM_ACCESS_POINT = 2;
99 public static final int WPS_PIN_FROM_DEVICE = 3;
101 /* These values come from "wifi_proxy_settings" resource array */
102 public static final int PROXY_NONE = 0;
103 public static final int PROXY_STATIC = 1;
105 private static final String TAG = "WifiConfigController";
107 private Spinner mNetworkSetupSpinner;
108 private Spinner mIpSettingsSpinner;
109 private TextView mIpAddressView;
110 private TextView mGatewayView;
111 private TextView mNetworkPrefixLengthView;
112 private TextView mDns1View;
113 private TextView mDns2View;
115 private Spinner mProxySettingsSpinner;
116 private TextView mProxyHostView;
117 private TextView mProxyPortView;
118 private TextView mProxyExclusionListView;
120 private IpAssignment mIpAssignment;
121 private ProxySettings mProxySettings;
122 private LinkProperties mLinkProperties = new LinkProperties();
124 // True when this instance is used in SetupWizard XL context.
125 private final boolean mInXlSetupWizard;
127 static boolean requireKeyStore(WifiConfiguration config) {
128 if (config == null) {
131 String values[] = {config.ca_cert.value(), config.client_cert.value(),
132 config.private_key.value()};
133 for (String value : values) {
134 if (value != null && value.startsWith(KEYSTORE_SPACE)) {
141 public WifiConfigController(
142 WifiConfigUiBase parent, View view, AccessPoint accessPoint, boolean edit) {
144 mInXlSetupWizard = (parent instanceof WifiConfigUiForSetupWizardXL);
147 mAccessPoint = accessPoint;
148 mAccessPointSecurity = (accessPoint == null) ? AccessPoint.SECURITY_NONE :
149 accessPoint.security;
152 final Context context = mConfigUi.getContext();
153 final Resources resources = context.getResources();
155 if (mAccessPoint == null) { // new network
156 mConfigUi.setTitle(R.string.wifi_add_network);
158 mSsidView = (TextView) mView.findViewById(R.id.ssid);
159 mSsidView.addTextChangedListener(this);
160 mSecuritySpinner = ((Spinner) mView.findViewById(R.id.security));
161 mSecuritySpinner.setOnItemSelectedListener(this);
162 if (mInXlSetupWizard) {
163 mView.findViewById(R.id.type_ssid).setVisibility(View.VISIBLE);
164 mView.findViewById(R.id.type_security).setVisibility(View.VISIBLE);
165 // We want custom layout. The content must be same as the other cases.
166 mSecuritySpinner.setAdapter(
167 new ArrayAdapter<String>(context, R.layout.wifi_setup_custom_list_item_1,
169 context.getResources().getStringArray(R.array.wifi_security)));
171 mView.findViewById(R.id.type).setVisibility(View.VISIBLE);
173 mConfigUi.setSubmitButton(context.getString(R.string.wifi_save));
175 mConfigUi.setTitle(mAccessPoint.ssid);
177 mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ip_settings);
178 mIpSettingsSpinner.setOnItemSelectedListener(this);
179 mProxySettingsSpinner = (Spinner) mView.findViewById(R.id.proxy_settings);
180 mProxySettingsSpinner.setOnItemSelectedListener(this);
182 ViewGroup group = (ViewGroup) mView.findViewById(R.id.info);
184 DetailedState state = mAccessPoint.getState();
186 addRow(group, R.string.wifi_status, Summary.get(mConfigUi.getContext(), state));
189 String[] type = resources.getStringArray(R.array.wifi_security);
190 addRow(group, R.string.wifi_security, type[mAccessPoint.security]);
192 int level = mAccessPoint.getLevel();
194 String[] signal = resources.getStringArray(R.array.wifi_signal);
195 addRow(group, R.string.wifi_signal, signal[level]);
198 WifiInfo info = mAccessPoint.getInfo();
200 addRow(group, R.string.wifi_speed, info.getLinkSpeed() + WifiInfo.LINK_SPEED_UNITS);
201 // TODO: fix the ip address for IPv6.
202 int address = info.getIpAddress();
204 addRow(group, R.string.wifi_ip_address, Formatter.formatIpAddress(address));
208 if (mAccessPoint.networkId != INVALID_NETWORK_ID) {
209 WifiConfiguration config = mAccessPoint.getConfig();
210 if (config.ipAssignment == IpAssignment.STATIC) {
211 mIpSettingsSpinner.setSelection(STATIC_IP);
213 mIpSettingsSpinner.setSelection(DHCP);
216 if (config.proxySettings == ProxySettings.STATIC) {
217 mProxySettingsSpinner.setSelection(PROXY_STATIC);
219 mProxySettingsSpinner.setSelection(PROXY_NONE);
223 /* Show network setup options only for a new network */
224 if (mAccessPoint.networkId == INVALID_NETWORK_ID && mAccessPoint.wpsAvailable) {
225 showNetworkSetupFields();
228 if (mAccessPoint.networkId == INVALID_NETWORK_ID || mEdit) {
229 showSecurityFields();
230 showIpConfigFields();
235 mConfigUi.setSubmitButton(context.getString(R.string.wifi_save));
237 if (state == null && level != -1) {
238 mConfigUi.setSubmitButton(context.getString(R.string.wifi_connect));
240 mView.findViewById(R.id.ip_fields).setVisibility(View.GONE);
242 if (mAccessPoint.networkId != INVALID_NETWORK_ID) {
243 mConfigUi.setForgetButton(context.getString(R.string.wifi_forget));
249 mConfigUi.setCancelButton(context.getString(R.string.wifi_cancel));
250 if (mConfigUi.getSubmitButton() != null) {
251 enableSubmitIfAppropriate();
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);
262 /* show submit button if the password is valid */
263 private void enableSubmitIfAppropriate() {
264 if ((mSsidView != null && mSsidView.length() == 0) ||
265 ((mAccessPoint == null || mAccessPoint.networkId == INVALID_NETWORK_ID) &&
266 ((mAccessPointSecurity == AccessPoint.SECURITY_WEP && mPasswordView.length() == 0) ||
267 (mAccessPointSecurity == AccessPoint.SECURITY_PSK && mPasswordView.length() < 8)))) {
268 mConfigUi.getSubmitButton().setEnabled(false);
270 mConfigUi.getSubmitButton().setEnabled(true);
274 /* package */ WifiConfiguration getConfig() {
275 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID && !mEdit) {
279 WifiConfiguration config = new WifiConfiguration();
281 if (mAccessPoint == null) {
282 config.SSID = AccessPoint.convertToQuotedString(
283 mSsidView.getText().toString());
284 // If the user adds a network manually, assume that it is hidden.
285 config.hiddenSSID = true;
286 } else if (mAccessPoint.networkId == INVALID_NETWORK_ID) {
287 config.SSID = AccessPoint.convertToQuotedString(
290 config.networkId = mAccessPoint.networkId;
293 switch (mAccessPointSecurity) {
294 case AccessPoint.SECURITY_NONE:
295 config.allowedKeyManagement.set(KeyMgmt.NONE);
298 case AccessPoint.SECURITY_WEP:
299 config.allowedKeyManagement.set(KeyMgmt.NONE);
300 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
301 config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
302 if (mPasswordView.length() != 0) {
303 int length = mPasswordView.length();
304 String password = mPasswordView.getText().toString();
305 // WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
306 if ((length == 10 || length == 26 || length == 58) &&
307 password.matches("[0-9A-Fa-f]*")) {
308 config.wepKeys[0] = password;
310 config.wepKeys[0] = '"' + password + '"';
315 case AccessPoint.SECURITY_PSK:
316 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
317 if (mPasswordView.length() != 0) {
318 String password = mPasswordView.getText().toString();
319 if (password.matches("[0-9A-Fa-f]{64}")) {
320 config.preSharedKey = password;
322 config.preSharedKey = '"' + password + '"';
327 case AccessPoint.SECURITY_EAP:
328 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
329 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
330 config.eap.setValue((String) mEapMethodSpinner.getSelectedItem());
332 config.phase2.setValue((mPhase2Spinner.getSelectedItemPosition() == 0) ? "" :
333 "auth=" + mPhase2Spinner.getSelectedItem());
334 config.ca_cert.setValue((mEapCaCertSpinner.getSelectedItemPosition() == 0) ? "" :
335 KEYSTORE_SPACE + Credentials.CA_CERTIFICATE +
336 (String) mEapCaCertSpinner.getSelectedItem());
337 config.client_cert.setValue((mEapUserCertSpinner.getSelectedItemPosition() == 0) ?
338 "" : KEYSTORE_SPACE + Credentials.USER_CERTIFICATE +
339 (String) mEapUserCertSpinner.getSelectedItem());
340 config.private_key.setValue((mEapUserCertSpinner.getSelectedItemPosition() == 0) ?
341 "" : KEYSTORE_SPACE + Credentials.USER_PRIVATE_KEY +
342 (String) mEapUserCertSpinner.getSelectedItem());
343 config.identity.setValue((mEapIdentityView.length() == 0) ? "" :
344 mEapIdentityView.getText().toString());
345 config.anonymous_identity.setValue((mEapAnonymousView.length() == 0) ? "" :
346 mEapAnonymousView.getText().toString());
347 if (mPasswordView.length() != 0) {
348 config.password.setValue(mPasswordView.getText().toString());
356 validateAndFetchIpAndProxyFields();
358 config.proxySettings = mProxySettings;
359 config.ipAssignment = mIpAssignment;
360 config.linkProperties = new LinkProperties(mLinkProperties);
365 private void validateAndFetchIpAndProxyFields() {
366 mLinkProperties.clear();
367 mIpAssignment = (mIpSettingsSpinner != null &&
368 mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) ?
369 IpAssignment.STATIC : IpAssignment.DHCP;
371 if (mIpAssignment == IpAssignment.STATIC) {
372 //TODO: A better way to do this is to not dismiss the
373 //dialog as long as one of the fields is invalid
374 int result = validateIpConfigFields(mLinkProperties);
376 mLinkProperties.clear();
377 Toast.makeText(mConfigUi.getContext(), result, Toast.LENGTH_LONG).show();
378 mIpAssignment = IpAssignment.UNASSIGNED;
382 mProxySettings = (mProxySettingsSpinner != null &&
383 mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) ?
384 ProxySettings.STATIC : ProxySettings.NONE;
386 if (mProxySettings == ProxySettings.STATIC) {
387 String host = mProxyHostView.getText().toString();
388 String portStr = mProxyPortView.getText().toString();
389 String exclusionList = mProxyExclusionListView.getText().toString();
393 port = Integer.parseInt(portStr);
394 result = ProxySelector.validate(host, portStr, exclusionList);
395 } catch (NumberFormatException e) {
396 result = R.string.proxy_error_invalid_port;
399 ProxyProperties proxyProperties= new ProxyProperties(host, port, exclusionList);
400 mLinkProperties.setHttpProxy(proxyProperties);
402 Toast.makeText(mConfigUi.getContext(), result, Toast.LENGTH_LONG).show();
403 mProxySettings = ProxySettings.UNASSIGNED;
408 private int validateIpConfigFields(LinkProperties linkProperties) {
409 String ipAddr = mIpAddressView.getText().toString();
410 InetAddress inetAddr = null;
412 inetAddr = NetworkUtils.numericToInetAddress(ipAddr);
413 } catch (IllegalArgumentException e) {
414 return R.string.wifi_ip_settings_invalid_ip_address;
417 int networkPrefixLength = -1;
419 networkPrefixLength = Integer.parseInt(mNetworkPrefixLengthView.getText().toString());
420 } catch (NumberFormatException e) { }
421 if (networkPrefixLength < 0 || networkPrefixLength > 32) {
422 return R.string.wifi_ip_settings_invalid_network_prefix_length;
424 linkProperties.addLinkAddress(new LinkAddress(inetAddr, networkPrefixLength));
426 String gateway = mGatewayView.getText().toString();
427 InetAddress gatewayAddr = null;
429 gatewayAddr = NetworkUtils.numericToInetAddress(gateway);
430 } catch (IllegalArgumentException e) {
431 return R.string.wifi_ip_settings_invalid_gateway;
433 linkProperties.addGateway(gatewayAddr);
435 String dns = mDns1View.getText().toString();
436 InetAddress dnsAddr = null;
438 dnsAddr = NetworkUtils.numericToInetAddress(dns);
439 } catch (IllegalArgumentException e) {
440 return R.string.wifi_ip_settings_invalid_dns;
442 linkProperties.addDns(dnsAddr);
443 if (mDns2View.length() > 0) {
444 dns = mDns2View.getText().toString();
446 dnsAddr = NetworkUtils.numericToInetAddress(dns);
447 } catch (IllegalArgumentException e) {
448 return R.string.wifi_ip_settings_invalid_dns;
450 linkProperties.addDns(dnsAddr);
455 int chosenNetworkSetupMethod() {
456 if (mNetworkSetupSpinner != null) {
457 return mNetworkSetupSpinner.getSelectedItemPosition();
462 WpsConfiguration getWpsConfig() {
463 WpsConfiguration config = new WpsConfiguration();
464 switch (mNetworkSetupSpinner.getSelectedItemPosition()) {
466 config.setup = Setup.PBC;
468 case WPS_PIN_FROM_ACCESS_POINT:
469 config.setup = Setup.PIN_FROM_ACCESS_POINT;
471 case WPS_PIN_FROM_DEVICE:
472 config.setup = Setup.PIN_FROM_DEVICE;
475 config.setup = Setup.INVALID;
476 Log.e(TAG, "WPS not selected type");
479 config.pin = ((TextView) mView.findViewById(R.id.wps_pin)).getText().toString();
480 config.BSSID = (mAccessPoint != null) ? mAccessPoint.bssid : null;
482 validateAndFetchIpAndProxyFields();
484 config.proxySettings = mProxySettings;
485 config.ipAssignment = mIpAssignment;
486 config.linkProperties = new LinkProperties(mLinkProperties);
490 private void showSecurityFields() {
491 if (mInXlSetupWizard) {
492 // Note: XL SetupWizard won't hide "EAP" settings here.
493 if (!((WifiSettingsForSetupWizardXL)mConfigUi.getContext()).initSecurityFields(mView,
494 mAccessPointSecurity)) {
498 if (mAccessPointSecurity == AccessPoint.SECURITY_NONE) {
499 mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
502 mView.findViewById(R.id.security_fields).setVisibility(View.VISIBLE);
504 if (mPasswordView == null) {
505 mPasswordView = (TextView) mView.findViewById(R.id.password);
506 mPasswordView.addTextChangedListener(this);
507 ((CheckBox) mView.findViewById(R.id.show_password)).setOnClickListener(this);
509 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
510 mPasswordView.setHint(R.string.wifi_unchanged);
514 if (mAccessPointSecurity != AccessPoint.SECURITY_EAP) {
515 mView.findViewById(R.id.eap).setVisibility(View.GONE);
518 mView.findViewById(R.id.eap).setVisibility(View.VISIBLE);
520 if (mEapMethodSpinner == null) {
521 mEapMethodSpinner = (Spinner) mView.findViewById(R.id.method);
522 mPhase2Spinner = (Spinner) mView.findViewById(R.id.phase2);
523 mEapCaCertSpinner = (Spinner) mView.findViewById(R.id.ca_cert);
524 mEapUserCertSpinner = (Spinner) mView.findViewById(R.id.user_cert);
525 mEapIdentityView = (TextView) mView.findViewById(R.id.identity);
526 mEapAnonymousView = (TextView) mView.findViewById(R.id.anonymous);
528 loadCertificates(mEapCaCertSpinner, Credentials.CA_CERTIFICATE);
529 loadCertificates(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY);
531 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
532 WifiConfiguration config = mAccessPoint.getConfig();
533 setSelection(mEapMethodSpinner, config.eap.value());
534 setSelection(mPhase2Spinner, config.phase2.value());
535 setCertificate(mEapCaCertSpinner, Credentials.CA_CERTIFICATE,
536 config.ca_cert.value());
537 setCertificate(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY,
538 config.private_key.value());
539 mEapIdentityView.setText(config.identity.value());
540 mEapAnonymousView.setText(config.anonymous_identity.value());
545 private void showNetworkSetupFields() {
546 mView.findViewById(R.id.setup_fields).setVisibility(View.VISIBLE);
548 if (mNetworkSetupSpinner == null) {
549 mNetworkSetupSpinner = (Spinner) mView.findViewById(R.id.network_setup);
550 mNetworkSetupSpinner.setOnItemSelectedListener(this);
553 int pos = mNetworkSetupSpinner.getSelectedItemPosition();
555 /* Show pin text input if needed */
556 if (pos == WPS_PIN_FROM_ACCESS_POINT) {
557 mView.findViewById(R.id.wps_fields).setVisibility(View.VISIBLE);
559 mView.findViewById(R.id.wps_fields).setVisibility(View.GONE);
562 /* show/hide manual security fields appropriately */
563 if ((pos == WPS_PIN_FROM_ACCESS_POINT) || (pos == WPS_PIN_FROM_DEVICE)
564 || (pos == WPS_PBC)) {
565 mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
567 mView.findViewById(R.id.security_fields).setVisibility(View.VISIBLE);
572 private void showIpConfigFields() {
573 WifiConfiguration config = null;
575 mView.findViewById(R.id.ip_fields).setVisibility(View.VISIBLE);
577 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
578 config = mAccessPoint.getConfig();
581 if (mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) {
582 mView.findViewById(R.id.staticip).setVisibility(View.VISIBLE);
583 if (mIpAddressView == null) {
584 mIpAddressView = (TextView) mView.findViewById(R.id.ipaddress);
585 mGatewayView = (TextView) mView.findViewById(R.id.gateway);
586 mNetworkPrefixLengthView = (TextView) mView.findViewById(
587 R.id.network_prefix_length);
588 mDns1View = (TextView) mView.findViewById(R.id.dns1);
589 mDns2View = (TextView) mView.findViewById(R.id.dns2);
591 if (config != null) {
592 LinkProperties linkProperties = config.linkProperties;
593 Iterator<LinkAddress> iterator = linkProperties.getLinkAddresses().iterator();
594 if (iterator.hasNext()) {
595 LinkAddress linkAddress = iterator.next();
596 mIpAddressView.setText(linkAddress.getAddress().getHostAddress());
597 mNetworkPrefixLengthView.setText(Integer.toString(linkAddress
598 .getNetworkPrefixLength()));
601 Iterator<InetAddress>gateways = linkProperties.getGateways().iterator();
602 if (gateways.hasNext()) {
603 mGatewayView.setText(gateways.next().getHostAddress());
605 Iterator<InetAddress> dnsIterator = linkProperties.getDnses().iterator();
606 if (dnsIterator.hasNext()) {
607 mDns1View.setText(dnsIterator.next().getHostAddress());
609 if (dnsIterator.hasNext()) {
610 mDns2View.setText(dnsIterator.next().getHostAddress());
614 mView.findViewById(R.id.staticip).setVisibility(View.GONE);
618 private void showProxyFields() {
619 WifiConfiguration config = null;
621 mView.findViewById(R.id.proxy_settings_fields).setVisibility(View.VISIBLE);
623 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
624 config = mAccessPoint.getConfig();
627 if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) {
628 mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.VISIBLE);
629 mView.findViewById(R.id.proxy_fields).setVisibility(View.VISIBLE);
630 if (mProxyHostView == null) {
631 mProxyHostView = (TextView) mView.findViewById(R.id.proxy_hostname);
632 mProxyPortView = (TextView) mView.findViewById(R.id.proxy_port);
633 mProxyExclusionListView = (TextView) mView.findViewById(R.id.proxy_exclusionlist);
635 if (config != null) {
636 ProxyProperties proxyProperties = config.linkProperties.getHttpProxy();
637 if (proxyProperties != null) {
638 mProxyHostView.setText(proxyProperties.getHost());
639 mProxyPortView.setText(Integer.toString(proxyProperties.getPort()));
640 mProxyExclusionListView.setText(proxyProperties.getExclusionList());
644 mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.GONE);
645 mView.findViewById(R.id.proxy_fields).setVisibility(View.GONE);
651 private void loadCertificates(Spinner spinner, String prefix) {
652 final Context context = mConfigUi.getContext();
653 final String unspecified = context.getString(R.string.wifi_unspecified);
655 String[] certs = KeyStore.getInstance().saw(prefix);
656 if (certs == null || certs.length == 0) {
657 certs = new String[] {unspecified};
659 final String[] array = new String[certs.length + 1];
660 array[0] = unspecified;
661 System.arraycopy(certs, 0, array, 1, certs.length);
665 final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
666 context, android.R.layout.simple_spinner_item, certs);
667 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
668 spinner.setAdapter(adapter);
671 private void setCertificate(Spinner spinner, String prefix, String cert) {
672 prefix = KEYSTORE_SPACE + prefix;
673 if (cert != null && cert.startsWith(prefix)) {
674 setSelection(spinner, cert.substring(prefix.length()));
678 private void setSelection(Spinner spinner, String value) {
680 ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinner.getAdapter();
681 for (int i = adapter.getCount() - 1; i >= 0; --i) {
682 if (value.equals(adapter.getItem(i))) {
683 spinner.setSelection(i);
690 public boolean isEdit() {
695 public void afterTextChanged(Editable s) {
696 enableSubmitIfAppropriate();
700 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
704 public void onTextChanged(CharSequence s, int start, int before, int count) {
708 public void onClick(View view) {
709 mPasswordView.setInputType(
710 InputType.TYPE_CLASS_TEXT | (((CheckBox) view).isChecked() ?
711 InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD :
712 InputType.TYPE_TEXT_VARIATION_PASSWORD));
716 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
717 if (parent == mSecuritySpinner) {
718 mAccessPointSecurity = position;
719 showSecurityFields();
720 enableSubmitIfAppropriate();
721 } else if (parent == mNetworkSetupSpinner) {
722 showNetworkSetupFields();
723 } else if (parent == mProxySettingsSpinner) {
726 showIpConfigFields();
731 public void onNothingSelected(AdapterView<?> parent) {