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.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;
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;
56 import com.android.settings.ProxySelector;
57 import com.android.settings.R;
59 import java.net.InetAddress;
60 import java.net.InetSocketAddress;
61 import java.net.UnknownHostException;
62 import java.util.Iterator;
65 * The class for allowing UIs like {@link WifiDialog} and {@link WifiConfigPreference} to
66 * share the logic for controlling buttons, text fields, etc.
68 public class WifiConfigController implements TextWatcher,
69 View.OnClickListener, AdapterView.OnItemSelectedListener {
70 private static final String KEYSTORE_SPACE = "keystore://";
72 private final WifiConfigUiBase mConfigUi;
73 private final View mView;
74 private final AccessPoint mAccessPoint;
76 private boolean mEdit;
78 private TextView mSsidView;
80 // e.g. AccessPoint.SECURITY_NONE
81 private int mAccessPointSecurity;
82 private TextView mPasswordView;
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;
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;
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;
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;
106 private static final String TAG = "WifiConfigController";
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;
116 private Spinner mProxySettingsSpinner;
117 private TextView mProxyHostView;
118 private TextView mProxyPortView;
119 private TextView mProxyExclusionListView;
121 private IpAssignment mIpAssignment;
122 private ProxySettings mProxySettings;
123 private LinkProperties mLinkProperties = new LinkProperties();
125 // True when this instance is used in SetupWizard XL context.
126 private final boolean mInXlSetupWizard;
128 static boolean requireKeyStore(WifiConfiguration config) {
129 if (config == null) {
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)) {
142 public WifiConfigController(
143 WifiConfigUiBase parent, View view, AccessPoint accessPoint, boolean edit) {
145 mInXlSetupWizard = (parent instanceof WifiConfigUiForSetupWizardXL);
148 mAccessPoint = accessPoint;
149 mAccessPointSecurity = (accessPoint == null) ? AccessPoint.SECURITY_NONE :
150 accessPoint.security;
153 final Context context = mConfigUi.getContext();
154 final Resources resources = context.getResources();
156 if (mAccessPoint == null) { // new network
157 mConfigUi.setTitle(R.string.wifi_add_network);
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,
170 context.getResources().getStringArray(R.array.wifi_security)));
172 mView.findViewById(R.id.type).setVisibility(View.VISIBLE);
174 mConfigUi.setSubmitButton(context.getString(R.string.wifi_save));
176 mConfigUi.setTitle(mAccessPoint.ssid);
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);
183 ViewGroup group = (ViewGroup) mView.findViewById(R.id.info);
185 DetailedState state = mAccessPoint.getState();
187 addRow(group, R.string.wifi_status, Summary.get(mConfigUi.getContext(), state));
190 String[] type = resources.getStringArray(R.array.wifi_security);
191 addRow(group, R.string.wifi_security, type[mAccessPoint.security]);
193 int level = mAccessPoint.getLevel();
195 String[] signal = resources.getStringArray(R.array.wifi_signal);
196 addRow(group, R.string.wifi_signal, signal[level]);
199 WifiInfo info = mAccessPoint.getInfo();
201 addRow(group, R.string.wifi_speed, info.getLinkSpeed() + WifiInfo.LINK_SPEED_UNITS);
204 if (mAccessPoint.networkId != INVALID_NETWORK_ID) {
205 WifiConfiguration config = mAccessPoint.getConfig();
206 if (config.ipAssignment == IpAssignment.STATIC) {
207 mIpSettingsSpinner.setSelection(STATIC_IP);
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());
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 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;
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)))) {
277 if (ipAndProxyFieldsAreValid()) {
282 submit.setEnabled(enabled);
285 /* package */ WifiConfiguration getConfig() {
286 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID && !mEdit) {
290 WifiConfiguration config = new WifiConfiguration();
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(
301 config.networkId = mAccessPoint.networkId;
304 switch (mAccessPointSecurity) {
305 case AccessPoint.SECURITY_NONE:
306 config.allowedKeyManagement.set(KeyMgmt.NONE);
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;
321 config.wepKeys[0] = '"' + password + '"';
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;
333 config.preSharedKey = '"' + password + '"';
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());
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());
367 config.proxySettings = mProxySettings;
368 config.ipAssignment = mIpAssignment;
369 config.linkProperties = new LinkProperties(mLinkProperties);
374 private boolean ipAndProxyFieldsAreValid() {
375 mLinkProperties.clear();
376 mIpAssignment = (mIpSettingsSpinner != null &&
377 mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) ?
378 IpAssignment.STATIC : IpAssignment.DHCP;
380 if (mIpAssignment == IpAssignment.STATIC) {
381 int result = validateIpConfigFields(mLinkProperties);
387 mProxySettings = (mProxySettingsSpinner != null &&
388 mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) ?
389 ProxySettings.STATIC : ProxySettings.NONE;
391 if (mProxySettings == ProxySettings.STATIC) {
392 String host = mProxyHostView.getText().toString();
393 String portStr = mProxyPortView.getText().toString();
394 String exclusionList = mProxyExclusionListView.getText().toString();
398 port = Integer.parseInt(portStr);
399 result = ProxySelector.validate(host, portStr, exclusionList);
400 } catch (NumberFormatException e) {
401 result = R.string.proxy_error_invalid_port;
404 ProxyProperties proxyProperties= new ProxyProperties(host, port, exclusionList);
405 mLinkProperties.setHttpProxy(proxyProperties);
413 private int validateIpConfigFields(LinkProperties linkProperties) {
414 String ipAddr = mIpAddressView.getText().toString();
415 InetAddress inetAddr = null;
417 inetAddr = NetworkUtils.numericToInetAddress(ipAddr);
418 } catch (IllegalArgumentException e) {
419 return R.string.wifi_ip_settings_invalid_ip_address;
422 int networkPrefixLength = -1;
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;
429 linkProperties.addLinkAddress(new LinkAddress(inetAddr, networkPrefixLength));
431 String gateway = mGatewayView.getText().toString();
432 InetAddress gatewayAddr = null;
434 gatewayAddr = NetworkUtils.numericToInetAddress(gateway);
435 } catch (IllegalArgumentException e) {
436 return R.string.wifi_ip_settings_invalid_gateway;
438 linkProperties.addRoute(new RouteInfo(gatewayAddr));
440 String dns = mDns1View.getText().toString();
441 InetAddress dnsAddr = null;
443 dnsAddr = NetworkUtils.numericToInetAddress(dns);
444 } catch (IllegalArgumentException e) {
445 return R.string.wifi_ip_settings_invalid_dns;
447 linkProperties.addDns(dnsAddr);
448 if (mDns2View.length() > 0) {
449 dns = mDns2View.getText().toString();
451 dnsAddr = NetworkUtils.numericToInetAddress(dns);
452 } catch (IllegalArgumentException e) {
453 return R.string.wifi_ip_settings_invalid_dns;
455 linkProperties.addDns(dnsAddr);
460 int chosenNetworkSetupMethod() {
461 if (mNetworkSetupSpinner != null) {
462 return mNetworkSetupSpinner.getSelectedItemPosition();
467 WpsConfiguration getWpsConfig() {
468 WpsConfiguration config = new WpsConfiguration();
469 switch (mNetworkSetupSpinner.getSelectedItemPosition()) {
471 config.setup = Setup.PBC;
473 case WPS_PIN_FROM_ACCESS_POINT:
474 config.setup = Setup.PIN_FROM_ACCESS_POINT;
476 case WPS_PIN_FROM_DEVICE:
477 config.setup = Setup.PIN_FROM_DEVICE;
480 config.setup = Setup.INVALID;
481 Log.e(TAG, "WPS not selected type");
484 config.pin = ((TextView) mView.findViewById(R.id.wps_pin)).getText().toString();
485 config.BSSID = (mAccessPoint != null) ? mAccessPoint.bssid : null;
487 config.proxySettings = mProxySettings;
488 config.ipAssignment = mIpAssignment;
489 config.linkProperties = new LinkProperties(mLinkProperties);
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)) {
501 if (mAccessPointSecurity == AccessPoint.SECURITY_NONE) {
502 mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
505 mView.findViewById(R.id.security_fields).setVisibility(View.VISIBLE);
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);
512 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
513 mPasswordView.setHint(R.string.wifi_unchanged);
517 if (mAccessPointSecurity != AccessPoint.SECURITY_EAP) {
518 mView.findViewById(R.id.eap).setVisibility(View.GONE);
521 mView.findViewById(R.id.eap).setVisibility(View.VISIBLE);
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);
531 loadCertificates(mEapCaCertSpinner, Credentials.CA_CERTIFICATE);
532 loadCertificates(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY);
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());
548 private void showNetworkSetupFields() {
549 mView.findViewById(R.id.setup_fields).setVisibility(View.VISIBLE);
551 if (mNetworkSetupSpinner == null) {
552 mNetworkSetupSpinner = (Spinner) mView.findViewById(R.id.network_setup);
553 mNetworkSetupSpinner.setOnItemSelectedListener(this);
556 int pos = mNetworkSetupSpinner.getSelectedItemPosition();
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);
562 mView.findViewById(R.id.wps_fields).setVisibility(View.GONE);
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);
570 mView.findViewById(R.id.security_fields).setVisibility(View.VISIBLE);
575 private void showIpConfigFields() {
576 WifiConfiguration config = null;
578 mView.findViewById(R.id.ip_fields).setVisibility(View.VISIBLE);
580 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
581 config = mAccessPoint.getConfig();
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);
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()));
609 for (RouteInfo route : linkProperties.getRoutes()) {
610 if (route.isDefaultRoute()) {
611 mGatewayView.setText(route.getGateway().getHostAddress());
616 Iterator<InetAddress> dnsIterator = linkProperties.getDnses().iterator();
617 if (dnsIterator.hasNext()) {
618 mDns1View.setText(dnsIterator.next().getHostAddress());
620 if (dnsIterator.hasNext()) {
621 mDns2View.setText(dnsIterator.next().getHostAddress());
625 mView.findViewById(R.id.staticip).setVisibility(View.GONE);
629 private void showProxyFields() {
630 WifiConfiguration config = null;
632 mView.findViewById(R.id.proxy_settings_fields).setVisibility(View.VISIBLE);
634 if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
635 config = mAccessPoint.getConfig();
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);
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());
658 mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.GONE);
659 mView.findViewById(R.id.proxy_fields).setVisibility(View.GONE);
665 private void loadCertificates(Spinner spinner, String prefix) {
666 final Context context = mConfigUi.getContext();
667 final String unspecified = context.getString(R.string.wifi_unspecified);
669 String[] certs = KeyStore.getInstance().saw(prefix);
670 if (certs == null || certs.length == 0) {
671 certs = new String[] {unspecified};
673 final String[] array = new String[certs.length + 1];
674 array[0] = unspecified;
675 System.arraycopy(certs, 0, array, 1, certs.length);
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);
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()));
692 private void setSelection(Spinner spinner, String value) {
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);
704 public boolean isEdit() {
709 public void afterTextChanged(Editable s) {
710 enableSubmitIfAppropriate();
714 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
718 public void onTextChanged(CharSequence s, int start, int before, int count) {
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));
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) {
739 enableSubmitIfAppropriate();
741 showIpConfigFields();
742 enableSubmitIfAppropriate();
747 public void onNothingSelected(AdapterView<?> parent) {