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.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.net.ConnectivityManager; 24 import android.net.EthernetManager; 25 import android.net.IpConfiguration; 26 import android.net.LinkAddress; 27 import android.net.LinkProperties; 28 import android.net.Network; 29 import android.net.NetworkInfo; 30 import android.net.wifi.WifiConfiguration; 31 import android.net.wifi.WifiConfiguration.KeyMgmt; 32 import android.net.wifi.WifiInfo; 33 import android.net.wifi.WifiManager; 34 import android.text.TextUtils; 35 36 import com.android.settingslib.wifi.AccessPoint; 37 import com.android.settingslib.wifi.WifiTracker; 38 39 import java.util.List; 40 41 /** 42 * Listens for changes to the current connectivity status. 43 */ 44 public class ConnectivityListener implements WifiTracker.WifiListener { 45 46 public interface Listener { onConnectivityChange()47 void onConnectivityChange(); 48 } 49 50 public interface WifiNetworkListener { onWifiListChanged()51 void onWifiListChanged(); 52 } 53 54 private static final String TAG = "ConnectivityListener"; 55 private static final boolean DEBUG = false; 56 57 private final Context mContext; 58 private final Listener mListener; 59 private boolean mStarted; 60 61 private WifiTracker mWifiTracker; 62 63 private final ConnectivityManager mConnectivityManager; 64 private final WifiManager mWifiManager; 65 private final EthernetManager mEthernetManager; 66 private WifiNetworkListener mWifiListener; 67 private final BroadcastReceiver mWifiEnabledReceiver = new BroadcastReceiver() { 68 @Override 69 public void onReceive(Context context, Intent intent) { 70 mListener.onConnectivityChange(); 71 } 72 }; 73 private final EthernetManager.Listener mEthernetListener = new EthernetManager.Listener() { 74 @Override 75 public void onAvailabilityChanged(boolean isAvailable) { 76 mListener.onConnectivityChange(); 77 } 78 }; 79 80 public static class ConnectivityStatus { 81 public static final int NETWORK_NONE = 1; 82 public static final int NETWORK_WIFI_OPEN = 3; 83 public static final int NETWORK_WIFI_SECURE = 5; 84 public static final int NETWORK_ETHERNET = 7; 85 86 public int mNetworkType; 87 public String mWifiSsid; 88 public int mWifiSignalStrength; 89 isEthernetConnected()90 boolean isEthernetConnected() { return mNetworkType == NETWORK_ETHERNET; } isWifiConnected()91 boolean isWifiConnected() { 92 return mNetworkType == NETWORK_WIFI_OPEN || mNetworkType == NETWORK_WIFI_SECURE; 93 } 94 95 @Override toString()96 public String toString() { 97 return 98 "mNetworkType " + mNetworkType + 99 " miWifiSsid " + mWifiSsid + 100 " mWifiSignalStrength " + mWifiSignalStrength; 101 } 102 } 103 104 private final ConnectivityStatus mConnectivityStatus = new ConnectivityStatus(); 105 ConnectivityListener(Context context, Listener listener)106 public ConnectivityListener(Context context, Listener listener) { 107 mContext = context; 108 mConnectivityManager = (ConnectivityManager) mContext.getSystemService( 109 Context.CONNECTIVITY_SERVICE); 110 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 111 mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE); 112 mListener = listener; 113 mWifiTracker = new WifiTracker(context, this, true, true); 114 } 115 116 /** 117 * Starts {@link ConnectivityListener}. 118 * This should be called only from main thread. 119 */ start()120 public void start() { 121 if (!mStarted) { 122 mStarted = true; 123 updateConnectivityStatus(); 124 mWifiTracker.startTracking(); 125 mContext.registerReceiver(mWifiEnabledReceiver, new IntentFilter( 126 WifiManager.WIFI_STATE_CHANGED_ACTION)); 127 mEthernetManager.addListener(mEthernetListener); 128 } 129 } 130 131 /** 132 * Stops {@link ConnectivityListener}. 133 * This should be called only from main thread. 134 */ stop()135 public void stop() { 136 if (mStarted) { 137 mStarted = false; 138 mWifiTracker.stopTracking(); 139 mContext.unregisterReceiver(mWifiEnabledReceiver); 140 mWifiListener = null; 141 mEthernetManager.removeListener(mEthernetListener); 142 } 143 } 144 setWifiListener(WifiNetworkListener wifiListener)145 public void setWifiListener(WifiNetworkListener wifiListener) { 146 mWifiListener = wifiListener; 147 } 148 getConnectivityStatus()149 public ConnectivityStatus getConnectivityStatus() { 150 return mConnectivityStatus; 151 } 152 getWifiIpAddress()153 public String getWifiIpAddress() { 154 if (mConnectivityStatus.isWifiConnected()) { 155 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 156 int ip = wifiInfo.getIpAddress(); 157 return String.format("%d.%d.%d.%d", (ip & 0xff), (ip >> 8 & 0xff), 158 (ip >> 16 & 0xff), (ip >> 24 & 0xff)); 159 } else { 160 return ""; 161 } 162 } 163 164 /** 165 * Return the MAC address of the currently connected Wifi AP. 166 */ getWifiMacAddress()167 public String getWifiMacAddress() { 168 if (mConnectivityStatus.isWifiConnected()) { 169 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 170 return wifiInfo.getMacAddress(); 171 } else { 172 return ""; 173 } 174 } 175 176 /** 177 * Return whether Ethernet port is available. 178 */ isEthernetAvailable()179 public boolean isEthernetAvailable() { 180 return mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_ETHERNET) 181 && mEthernetManager.isAvailable(); 182 } 183 getFirstEthernet()184 private Network getFirstEthernet() { 185 final Network[] networks = mConnectivityManager.getAllNetworks(); 186 for (final Network network : networks) { 187 NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(network); 188 if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) { 189 return network; 190 } 191 } 192 return null; 193 } 194 getEthernetMacAddress()195 public String getEthernetMacAddress() { 196 final Network network = getFirstEthernet(); 197 return network != null ? mConnectivityManager.getNetworkInfo(network).getExtraInfo() : null; 198 } 199 getEthernetIpAddress()200 public String getEthernetIpAddress() { 201 final Network network = getFirstEthernet(); 202 if (network == null) { 203 return null; 204 } 205 final StringBuilder sb = new StringBuilder(); 206 boolean gotAddress = false; 207 final LinkProperties linkProperties = mConnectivityManager.getLinkProperties(network); 208 for (LinkAddress linkAddress : linkProperties.getLinkAddresses()) { 209 if (gotAddress) { 210 sb.append("\n"); 211 } 212 sb.append(linkAddress.getAddress().getHostAddress()); 213 gotAddress = true; 214 } 215 if (gotAddress) { 216 return sb.toString(); 217 } else { 218 return null; 219 } 220 } 221 getWifiSignalStrength(int maxLevel)222 public int getWifiSignalStrength(int maxLevel) { 223 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 224 return WifiManager.calculateSignalLevel(wifiInfo.getRssi(), maxLevel); 225 } 226 forgetWifiNetwork()227 public void forgetWifiNetwork() { 228 int networkId = getWifiNetworkId(); 229 if (networkId != -1) { 230 mWifiManager.forget(networkId, null); 231 } 232 } 233 getWifiNetworkId()234 public int getWifiNetworkId() { 235 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 236 if (wifiInfo != null) { 237 return wifiInfo.getNetworkId(); 238 } else { 239 return -1; 240 } 241 } 242 getWifiConfiguration()243 public WifiConfiguration getWifiConfiguration() { 244 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 245 if (wifiInfo != null) { 246 int networkId = wifiInfo.getNetworkId(); 247 List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks(); 248 if (configuredNetworks != null) { 249 for (WifiConfiguration configuredNetwork : configuredNetworks) { 250 if (configuredNetwork.networkId == networkId) { 251 return configuredNetwork; 252 } 253 } 254 } 255 } 256 return null; 257 } 258 259 /** 260 * Return a list of wifi networks. Ensure that if a wifi network is connected that it appears 261 * as the first item on the list. 262 */ getAvailableNetworks()263 public List<AccessPoint> getAvailableNetworks() { 264 return mWifiTracker.getAccessPoints(); 265 } 266 getIpConfiguration()267 public IpConfiguration getIpConfiguration() { 268 return mEthernetManager.getConfiguration(); 269 } 270 isSecureWifi(WifiInfo wifiInfo)271 private boolean isSecureWifi(WifiInfo wifiInfo) { 272 if (wifiInfo == null) 273 return false; 274 int networkId = wifiInfo.getNetworkId(); 275 List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks(); 276 if (configuredNetworks != null) { 277 for (WifiConfiguration configuredNetwork : configuredNetworks) { 278 if (configuredNetwork.networkId == networkId) { 279 return configuredNetwork.allowedKeyManagement.get(KeyMgmt.WPA_PSK) || 280 configuredNetwork.allowedKeyManagement.get(KeyMgmt.WPA_EAP) || 281 configuredNetwork.allowedKeyManagement.get(KeyMgmt.IEEE8021X); 282 } 283 } 284 } 285 return false; 286 } 287 isWifiEnabled()288 public boolean isWifiEnabled() { 289 return mWifiManager.isWifiEnabled(); 290 } 291 setWifiEnabled(boolean enable)292 public void setWifiEnabled(boolean enable) { 293 mWifiManager.setWifiEnabled(enable); 294 } 295 setNetworkType(int networkType)296 private boolean setNetworkType(int networkType) { 297 boolean hasChanged = mConnectivityStatus.mNetworkType != networkType; 298 mConnectivityStatus.mNetworkType = networkType; 299 return hasChanged; 300 } 301 updateConnectivityStatus()302 private boolean updateConnectivityStatus() { 303 NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo(); 304 if (networkInfo == null) { 305 return setNetworkType(ConnectivityStatus.NETWORK_NONE); 306 } else { 307 switch (networkInfo.getType()) { 308 case ConnectivityManager.TYPE_WIFI: { 309 boolean hasChanged; 310 311 // Determine if this is an open or secure wifi connection. 312 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 313 if (isSecureWifi(wifiInfo)) { 314 hasChanged = setNetworkType(ConnectivityStatus.NETWORK_WIFI_SECURE); 315 } else { 316 hasChanged = setNetworkType(ConnectivityStatus.NETWORK_WIFI_OPEN); 317 } 318 319 // Find the SSID of network. 320 String ssid = null; 321 if (wifiInfo != null) { 322 ssid = wifiInfo.getSSID(); 323 if (ssid != null) { 324 ssid = WifiInfo.removeDoubleQuotes(ssid); 325 } 326 } 327 if (!TextUtils.equals(mConnectivityStatus.mWifiSsid, ssid)) { 328 hasChanged = true; 329 mConnectivityStatus.mWifiSsid = ssid; 330 } 331 332 // Calculate the signal strength. 333 int signalStrength; 334 if (wifiInfo != null) { 335 // Calculate the signal strength between 0 and 3. 336 signalStrength = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), 4); 337 } else { 338 signalStrength = 0; 339 } 340 if (mConnectivityStatus.mWifiSignalStrength != signalStrength) { 341 hasChanged = true; 342 mConnectivityStatus.mWifiSignalStrength = signalStrength; 343 } 344 return hasChanged; 345 } 346 347 case ConnectivityManager.TYPE_ETHERNET: 348 return setNetworkType(ConnectivityStatus.NETWORK_ETHERNET); 349 350 default: 351 return setNetworkType(ConnectivityStatus.NETWORK_NONE); 352 } 353 } 354 } 355 356 @Override onWifiStateChanged(int state)357 public void onWifiStateChanged(int state) { 358 mListener.onConnectivityChange(); 359 } 360 361 @Override onConnectedChanged()362 public void onConnectedChanged() { 363 364 } 365 366 @Override onAccessPointsChanged()367 public void onAccessPointsChanged() { 368 if (mWifiListener != null) { 369 mWifiListener.onWifiListChanged(); 370 } 371 } 372 } 373