blob: c6fc3ca813ba9d04b580a60ac7d29f7d7f2d3eb1 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tv.settings.connectivity;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.settingslib.wifi.AccessPoint;
import com.android.tv.settings.R;
import com.android.tv.settings.connectivity.util.WifiSecurityUtil;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Helper class that deals with Wi-fi configuration.
*/
public final class WifiConfigHelper {
private static final String TAG = "WifiConfigHelper";
private static final boolean DEBUG = false;
// Allows underscore char to supports proxies that do not
// follow the spec
private static final String HC = "a-zA-Z0-9\\_";
// Matches blank input, ips, and domain names
private static final String HOSTNAME_REGEXP =
"^$|^[" + HC + "]+(\\-[" + HC + "]+)*(\\.[" + HC + "]+(\\-[" + HC + "]+)*)*$";
private static final Pattern HOSTNAME_PATTERN;
private static final String EXCLUSION_REGEXP =
"$|^(\\*)?\\.?[" + HC + "]+(\\-[" + HC + "]+)*(\\.[" + HC + "]+(\\-[" + HC + "]+)*)*$";
private static final Pattern EXCLUSION_PATTERN;
static {
HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
EXCLUSION_PATTERN = Pattern.compile(EXCLUSION_REGEXP);
}
private WifiConfigHelper() {
}
/**
* Set configuration ssid.
*
* @param config configuration
* @param ssid network ssid
*/
public static void setConfigSsid(WifiConfiguration config, String ssid) {
config.SSID = AccessPoint.convertToQuotedString(ssid);
}
/**
* Set configuration key managment by security.
*/
public static void setConfigKeyManagementBySecurity(
WifiConfiguration config, int security) {
config.allowedKeyManagement.clear();
config.allowedAuthAlgorithms.clear();
switch (security) {
case AccessPoint.SECURITY_NONE:
config.allowedKeyManagement.set(KeyMgmt.NONE);
break;
case AccessPoint.SECURITY_WEP:
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
break;
case AccessPoint.SECURITY_PSK:
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
break;
case AccessPoint.SECURITY_EAP:
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
break;
}
}
/**
* validate syntax of hostname and port entries
*
* @return 0 on success, string resource ID on failure
*/
public static int validate(String hostname, String port, String exclList) {
Matcher match = HOSTNAME_PATTERN.matcher(hostname);
String[] exclListArray = exclList.split(",");
if (!match.matches()) return R.string.proxy_error_invalid_host;
for (String excl : exclListArray) {
Matcher m = EXCLUSION_PATTERN.matcher(excl);
if (!m.matches()) return R.string.proxy_error_invalid_exclusion_list;
}
if (hostname.length() > 0 && port.length() == 0) {
return R.string.proxy_error_empty_port;
}
if (port.length() > 0) {
if (hostname.length() == 0) {
return R.string.proxy_error_empty_host_set_port;
}
int portVal = -1;
try {
portVal = Integer.parseInt(port);
} catch (NumberFormatException ex) {
return R.string.proxy_error_invalid_port;
}
if (portVal <= 0 || portVal > 0xFFFF) {
return R.string.proxy_error_invalid_port;
}
}
return 0;
}
/**
* Get {@link WifiConfiguration} based upon the {@link WifiManager} and networkId.
* @param wifiManager
* @param networkId the id of the network.
* @return the {@link WifiConfiguration} of the specified network.
*/
public static WifiConfiguration getWifiConfiguration(WifiManager wifiManager, int networkId) {
List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
if (configuredNetworks != null) {
for (WifiConfiguration configuredNetwork : configuredNetworks) {
if (configuredNetwork.networkId == networkId) {
return configuredNetwork;
}
}
}
return null;
}
/**
* Did this config come out of the supplicant? NOT "Is the config currently in the supplicant?"
*/
public static boolean isNetworkSaved(WifiConfiguration config) {
return config != null && config.networkId > -1;
}
/**
* Return the configured network that matches the ssid/security pair, or create one.
*/
public static WifiConfiguration getConfiguration(Context context, String ssid, int security) {
WifiConfiguration config = getFromConfiguredNetworks(context, ssid, security);
if (config == null) {
// No configured network found; populate a new one with the provided ssid / security.
config = new WifiConfiguration();
setConfigSsid(config, ssid);
setConfigKeyManagementBySecurity(config, security);
}
return config;
}
/**
* Save a wifi configuration.
*/
public static boolean saveConfiguration(Context context, WifiConfiguration config) {
if (config == null) {
return false;
}
WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
int networkId = wifiMan.addNetwork(config);
if (networkId == -1) {
if (DEBUG) Log.e(TAG, "failed to add network: " + config.toString());
return false;
}
if (!wifiMan.enableNetwork(networkId, false)) {
if (DEBUG) Log.e(TAG, "enable network failed: " + networkId + "; " + config.toString());
return false;
}
if (!wifiMan.saveConfiguration()) {
if (DEBUG) Log.e(TAG, "failed to save: " + config.toString());
return false;
}
if (DEBUG) Log.d(TAG, "saved network: " + config.toString());
return true;
}
/**
* @return A matching WifiConfiguration from the list of configured
* networks, or null if no matching network is found.
*/
private static WifiConfiguration getFromConfiguredNetworks(Context context,
String ssid,
int security) {
WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configuredNetworks = wifiMan.getConfiguredNetworks();
if (configuredNetworks != null) {
for (WifiConfiguration configuredNetwork : configuredNetworks) {
if (configuredNetwork == null || configuredNetwork.SSID == null) {
continue; // Does this ever really happen?
}
// If the SSID and the security match, that's our network.
String configuredSsid = WifiInfo.removeDoubleQuotes(configuredNetwork.SSID);
if (TextUtils.equals(configuredSsid, ssid)) {
int configuredSecurity = WifiSecurityUtil.getSecurity(configuredNetwork);
if (configuredSecurity == security) {
return configuredNetwork;
}
}
}
}
return null;
}
}