Home | History | Annotate | Download | only in connectivity
      1 /*
      2  * Copyright (C) 2014 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.tv.settings.connectivity;
     18 
     19 import android.content.Context;
     20 import android.net.wifi.WifiConfiguration;
     21 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
     22 import android.net.wifi.WifiConfiguration.KeyMgmt;
     23 import android.net.wifi.WifiInfo;
     24 import android.net.wifi.WifiManager;
     25 import android.text.TextUtils;
     26 import android.util.Log;
     27 
     28 import com.android.settingslib.wifi.AccessPoint;
     29 import com.android.tv.settings.R;
     30 
     31 import java.util.List;
     32 import java.util.regex.Matcher;
     33 import java.util.regex.Pattern;
     34 
     35 /**
     36  * Helper class that deals with Wi-fi configuration
     37  */
     38 public final class WifiConfigHelper {
     39 
     40     private static final String TAG = "WifiConfigHelper";
     41     private static final boolean DEBUG = false;
     42 
     43     /**
     44      * If there are exactly 12 hex digits, this looks like a BSSID
     45      */
     46     private static final String REGEX_HEX_BSSID = "[a-fA-F0-9]{12}";
     47 
     48     // Allows underscore char to supports proxies that do not
     49     // follow the spec
     50     private static final String HC = "a-zA-Z0-9\\_";
     51 
     52     // Matches blank input, ips, and domain names
     53     private static final String HOSTNAME_REGEXP =
     54             "^$|^[" + HC + "]+(\\-[" + HC + "]+)*(\\.[" + HC + "]+(\\-[" + HC + "]+)*)*$";
     55     private static final Pattern HOSTNAME_PATTERN;
     56     private static final String EXCLUSION_REGEXP =
     57             "$|^(\\*)?\\.?[" + HC + "]+(\\-[" + HC + "]+)*(\\.[" + HC + "]+(\\-[" + HC + "]+)*)*$";
     58     private static final Pattern EXCLUSION_PATTERN;
     59     static {
     60         HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
     61         EXCLUSION_PATTERN = Pattern.compile(EXCLUSION_REGEXP);
     62     }
     63 
     64     public static void setConfigSsid(WifiConfiguration config, String ssid) {
     65         // if this looks like a BSSID, don't quote it
     66         if (!Pattern.matches(REGEX_HEX_BSSID, ssid)) {
     67             config.SSID = AccessPoint.convertToQuotedString(ssid);
     68         } else {
     69             config.SSID = ssid;
     70         }
     71     }
     72 
     73     public static void setConfigKeyManagementBySecurity(
     74             WifiConfiguration config, WifiSecurity security) {
     75         config.allowedKeyManagement.clear();
     76         config.allowedAuthAlgorithms.clear();
     77         switch (security) {
     78             case NONE:
     79                 config.allowedKeyManagement.set(KeyMgmt.NONE);
     80                 break;
     81             case WEP:
     82                 config.allowedKeyManagement.set(KeyMgmt.NONE);
     83                 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
     84                 config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
     85                 break;
     86             case PSK:
     87                 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
     88                 break;
     89             case EAP:
     90                 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
     91                 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
     92                 break;
     93         }
     94     }
     95 
     96     /**
     97      * validate syntax of hostname and port entries
     98      * @return 0 on success, string resource ID on failure
     99      */
    100     public static int validate(String hostname, String port, String exclList) {
    101         Matcher match = HOSTNAME_PATTERN.matcher(hostname);
    102         String exclListArray[] = exclList.split(",");
    103 
    104         if (!match.matches()) return R.string.proxy_error_invalid_host;
    105 
    106         for (String excl : exclListArray) {
    107             Matcher m = EXCLUSION_PATTERN.matcher(excl);
    108             if (!m.matches()) return R.string.proxy_error_invalid_exclusion_list;
    109         }
    110 
    111         if (hostname.length() > 0 && port.length() == 0) {
    112             return R.string.proxy_error_empty_port;
    113         }
    114 
    115         if (port.length() > 0) {
    116             if (hostname.length() == 0) {
    117                 return R.string.proxy_error_empty_host_set_port;
    118             }
    119             int portVal = -1;
    120             try {
    121                 portVal = Integer.parseInt(port);
    122             } catch (NumberFormatException ex) {
    123                 return R.string.proxy_error_invalid_port;
    124             }
    125             if (portVal <= 0 || portVal > 0xFFFF) {
    126                 return R.string.proxy_error_invalid_port;
    127             }
    128         }
    129         return 0;
    130     }
    131 
    132     public static WifiConfiguration getWifiConfiguration(WifiManager wifiManager, int networkId) {
    133         List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
    134         if (configuredNetworks != null) {
    135             for (WifiConfiguration configuredNetwork : configuredNetworks) {
    136                 if (configuredNetwork.networkId == networkId) {
    137                     return configuredNetwork;
    138                 }
    139             }
    140         }
    141         return null;
    142     }
    143 
    144     /**
    145      * Did this config come out of the supplicant?  NOT "Is the config currently in the supplicant?"
    146      */
    147     public static boolean isNetworkSaved(WifiConfiguration config) {
    148         return config != null && config.networkId > -1;
    149     }
    150 
    151     /**
    152      * Return the configured network that matches the ssid/security pair, or create one.
    153      */
    154     public static WifiConfiguration getConfiguration(Context context, String ssid,
    155             WifiSecurity security) {
    156         WifiConfiguration config = getFromConfiguredNetworks(context, ssid, security);
    157 
    158         if (config == null) {
    159             // No configured network found; populate a new one with the provided ssid / security.
    160             config = new WifiConfiguration();
    161             setConfigSsid(config, ssid);
    162             setConfigKeyManagementBySecurity(config, security);
    163         }
    164         return config;
    165     }
    166 
    167     /**
    168      * Save a wifi configuration.
    169      */
    170     public static boolean saveConfiguration(Context context, WifiConfiguration config) {
    171         if (config == null) {
    172             return false;
    173         }
    174 
    175         WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    176         int networkId = wifiMan.addNetwork(config);
    177         if (networkId == -1) {
    178           if (DEBUG) Log.e(TAG, "failed to add network: " + config.toString());
    179           return false;
    180         }
    181 
    182         if (!wifiMan.enableNetwork(networkId, false)) {
    183           if (DEBUG) Log.e(TAG, "enable network failed: " + networkId + "; " + config.toString());
    184           return false;
    185         }
    186 
    187         if (!wifiMan.saveConfiguration()) {
    188           if (DEBUG) Log.e(TAG, "failed to save: " + config.toString());
    189           return false;
    190         }
    191 
    192         if (DEBUG) Log.d(TAG, "saved network: " + config.toString());
    193         return true;
    194     }
    195 
    196     /**
    197      * Forget a wifi configuration.
    198      */
    199     public static void forgetConfiguration(Context context, WifiConfiguration config) {
    200         if (config == null) {
    201             return;
    202         }
    203 
    204         WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    205         List<WifiConfiguration> configuredNetworks = wifiMan.getConfiguredNetworks();
    206         if (configuredNetworks == null) {
    207             if (DEBUG) Log.e(TAG, "failed to get configured networks");
    208             return;
    209         }
    210 
    211         for (WifiConfiguration wc : configuredNetworks) {
    212             if (wc != null && wc.SSID != null && TextUtils.equals(wc.SSID, config.SSID)) {
    213                 wifiMan.forget(wc.networkId, null);
    214                 if (DEBUG) Log.d(TAG, "forgot network config: " + wc.toString());
    215                 break;
    216             }
    217         }
    218     }
    219 
    220     /**
    221      * Forget the current wifi connection.
    222      */
    223     public static void forgetWifiNetwork(Context context) {
    224         WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    225         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    226         if (wifiInfo != null) {
    227             int networkId = wifiInfo.getNetworkId();
    228             if (networkId != -1) {
    229                 mWifiManager.forget(networkId, null);
    230             }
    231         }
    232     }
    233 
    234     /**
    235      * @return A matching WifiConfiguration from the list of configured
    236      * networks, or null if no matching network is found.
    237      */
    238     private static WifiConfiguration getFromConfiguredNetworks(Context context, String ssid,
    239             WifiSecurity security) {
    240         WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    241         List<WifiConfiguration> configuredNetworks = wifiMan.getConfiguredNetworks();
    242         if (configuredNetworks != null) {
    243             for (WifiConfiguration configuredNetwork : configuredNetworks) {
    244                 if (configuredNetwork == null || configuredNetwork.SSID == null) {
    245                     continue;  // Does this ever really happen?
    246                 }
    247 
    248                 // If the SSID and the security match, that's our network.
    249                 String configuredSsid = WifiInfo.removeDoubleQuotes(configuredNetwork.SSID);
    250                 if (TextUtils.equals(configuredSsid, ssid)) {
    251                     WifiSecurity configuredSecurity = WifiSecurity.getSecurity(configuredNetwork);
    252                     if (configuredSecurity.equals(security)) {
    253                         return configuredNetwork;
    254                     }
    255                 }
    256             }
    257         }
    258 
    259         return null;
    260     }
    261 
    262     private WifiConfigHelper() {
    263     }
    264 }
    265