Home | History | Annotate | Download | only in wifi
      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_KEYPAD) {
    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