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