1 /*
2  * Copyright (C) 2015 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.compatibility.common.util;
18 
19 import android.content.Context;
20 import android.net.wifi.WifiConfiguration;
21 import android.net.wifi.WifiManager;
22 import android.text.TextUtils;
23 import android.util.Log;
24 
25 import java.util.List;
26 
27 /**
28  * A simple activity to create and manage wifi configurations.
29  */
30 public class WifiConfigCreator {
31     public static final String ACTION_CREATE_WIFI_CONFIG =
32             "com.android.compatibility.common.util.CREATE_WIFI_CONFIG";
33     public static final String ACTION_UPDATE_WIFI_CONFIG =
34             "com.android.compatibility.common.util.UPDATE_WIFI_CONFIG";
35     public static final String ACTION_REMOVE_WIFI_CONFIG =
36             "com.android.compatibility.common.util.REMOVE_WIFI_CONFIG";
37     public static final String EXTRA_NETID = "extra-netid";
38     public static final String EXTRA_SSID = "extra-ssid";
39     public static final String EXTRA_SECURITY_TYPE = "extra-security-type";
40     public static final String EXTRA_PASSWORD = "extra-password";
41 
42     public static final int SECURITY_TYPE_NONE = 1;
43     public static final int SECURITY_TYPE_WPA = 2;
44     public static final int SECURITY_TYPE_WEP = 3;
45 
46     private static final String TAG = "WifiConfigCreator";
47 
48     private final WifiManager mWifiManager;
49 
WifiConfigCreator(Context context)50     public WifiConfigCreator(Context context) {
51         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
52     }
53 
54     /**
55      * Adds a new WiFi network.
56      * @return network id or -1 in case of error
57      */
addNetwork(String ssid, boolean hidden, int securityType, String password)58     public int addNetwork(String ssid, boolean hidden, int securityType,
59             String password) throws SecurityException {
60         if (!mWifiManager.isWifiEnabled()) {
61             mWifiManager.setWifiEnabled(true);
62         }
63 
64         WifiConfiguration wifiConf = createConfig(ssid, hidden, securityType, password);
65 
66         int netId = mWifiManager.addNetwork(wifiConf);
67 
68         if (netId != -1) {
69             mWifiManager.enableNetwork(netId, true);
70         } else {
71             Log.w(TAG, "Unable to add SSID '" + ssid + "': netId = " + netId);
72         }
73         return netId;
74     }
75 
76     /**
77      * Updates a new WiFi network.
78      * @return network id (may differ from original) or -1 in case of error
79      */
updateNetwork(WifiConfiguration wifiConf, String ssid, boolean hidden, int securityType, String password)80     public int updateNetwork(WifiConfiguration wifiConf, String ssid, boolean hidden,
81             int securityType, String password) throws SecurityException {
82         if (!mWifiManager.isWifiEnabled()) {
83             mWifiManager.setWifiEnabled(true);
84         }
85         if (wifiConf == null) {
86             return -1;
87         }
88 
89         WifiConfiguration conf = createConfig(ssid, hidden, securityType, password);
90         conf.networkId = wifiConf.networkId;
91 
92         int newNetId = mWifiManager.updateNetwork(conf);
93 
94         if (newNetId != -1) {
95             mWifiManager.saveConfiguration();
96             mWifiManager.enableNetwork(newNetId, true);
97         } else {
98             Log.w(TAG, "Unable to update SSID '" + ssid + "': netId = " + newNetId);
99         }
100         return newNetId;
101     }
102 
103     /**
104      * Updates a new WiFi network.
105      * @return network id (may differ from original) or -1 in case of error
106      */
updateNetwork(int netId, String ssid, boolean hidden, int securityType, String password)107     public int updateNetwork(int netId, String ssid, boolean hidden,
108             int securityType, String password) throws SecurityException {
109         if (!mWifiManager.isWifiEnabled()) {
110             mWifiManager.setWifiEnabled(true);
111         }
112 
113         WifiConfiguration wifiConf = null;
114         List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
115         for (WifiConfiguration config : configs) {
116             if (config.networkId == netId) {
117                 wifiConf = config;
118                 break;
119             }
120         }
121         return updateNetwork(wifiConf, ssid, hidden, securityType, password);
122     }
123 
removeNetwork(int netId)124     public boolean removeNetwork(int netId) {
125         return mWifiManager.removeNetwork(netId);
126     }
127 
128     /**
129      * Creates a WifiConfiguration set up according to given parameters
130      * @param ssid SSID of the network
131      * @param hidden Is SSID not broadcast?
132      * @param securityType One of {@link #SECURITY_TYPE_NONE}, {@link #SECURITY_TYPE_WPA} or
133      *                     {@link #SECURITY_TYPE_WEP}
134      * @param password Password for WPA or WEP
135      * @return Created configuration object
136      */
createConfig(String ssid, boolean hidden, int securityType, String password)137     private WifiConfiguration createConfig(String ssid, boolean hidden, int securityType,
138             String password) {
139         WifiConfiguration wifiConf = new WifiConfiguration();
140         if (!TextUtils.isEmpty(ssid)) {
141             wifiConf.SSID = '"' + ssid + '"';
142         }
143         wifiConf.status = WifiConfiguration.Status.ENABLED;
144         wifiConf.hiddenSSID = hidden;
145         switch (securityType) {
146             case SECURITY_TYPE_NONE:
147                 wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
148                 break;
149             case SECURITY_TYPE_WPA:
150                 updateForWPAConfiguration(wifiConf, password);
151                 break;
152             case SECURITY_TYPE_WEP:
153                 updateForWEPConfiguration(wifiConf, password);
154                 break;
155         }
156         return wifiConf;
157     }
158 
updateForWPAConfiguration(WifiConfiguration wifiConf, String wifiPassword)159     private void updateForWPAConfiguration(WifiConfiguration wifiConf, String wifiPassword) {
160         wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
161         if (!TextUtils.isEmpty(wifiPassword)) {
162             wifiConf.preSharedKey = '"' + wifiPassword + '"';
163         }
164     }
165 
updateForWEPConfiguration(WifiConfiguration wifiConf, String password)166     private void updateForWEPConfiguration(WifiConfiguration wifiConf, String password) {
167         wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
168         wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
169         wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
170         if (!TextUtils.isEmpty(password)) {
171             int length = password.length();
172             if ((length == 10 || length == 26
173                     || length == 58) && password.matches("[0-9A-Fa-f]*")) {
174                 wifiConf.wepKeys[0] = password;
175             } else {
176                 wifiConf.wepKeys[0] = '"' + password + '"';
177             }
178             wifiConf.wepTxKeyIndex = 0;
179         }
180     }
181 }
182 
183