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