1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * 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 5 * 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * 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. 9 */ 10 11 package com.android.settingslib.wifi; 12 13 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 14 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; 15 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 16 17 import android.content.Context; 18 import android.content.Intent; 19 import android.net.ConnectivityManager; 20 import android.net.Network; 21 import android.net.NetworkCapabilities; 22 import android.net.NetworkInfo; 23 import android.net.NetworkKey; 24 import android.net.NetworkRequest; 25 import android.net.NetworkScoreManager; 26 import android.net.ScoredNetwork; 27 import android.net.wifi.WifiConfiguration; 28 import android.net.wifi.WifiInfo; 29 import android.net.wifi.WifiManager; 30 import android.net.wifi.WifiNetworkScoreCache; 31 import android.net.wifi.WifiSsid; 32 import android.os.Handler; 33 import android.os.Looper; 34 35 import com.android.settingslib.R; 36 37 import java.util.List; 38 39 public class WifiStatusTracker extends ConnectivityManager.NetworkCallback { 40 private final Context mContext; 41 private final WifiNetworkScoreCache mWifiNetworkScoreCache; 42 private final WifiManager mWifiManager; 43 private final NetworkScoreManager mNetworkScoreManager; 44 private final ConnectivityManager mConnectivityManager; 45 private final Handler mHandler = new Handler(Looper.getMainLooper()); 46 private final WifiNetworkScoreCache.CacheListener mCacheListener = 47 new WifiNetworkScoreCache.CacheListener(mHandler) { 48 @Override 49 public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) { 50 updateStatusLabel(); 51 mCallback.run(); 52 } 53 }; 54 private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder() 55 .clearCapabilities() 56 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) 57 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build(); 58 private final ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager 59 .NetworkCallback() { 60 @Override 61 public void onCapabilitiesChanged( 62 Network network, NetworkCapabilities networkCapabilities) { 63 updateStatusLabel(); 64 mCallback.run(); 65 } 66 }; 67 private final Runnable mCallback; 68 69 private WifiInfo mWifiInfo; 70 public boolean enabled; 71 public int state; 72 public boolean connected; 73 public String ssid; 74 public int rssi; 75 public int level; 76 public String statusLabel; 77 WifiStatusTracker(Context context, WifiManager wifiManager, NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager, Runnable callback)78 public WifiStatusTracker(Context context, WifiManager wifiManager, 79 NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager, 80 Runnable callback) { 81 mContext = context; 82 mWifiManager = wifiManager; 83 mWifiNetworkScoreCache = new WifiNetworkScoreCache(context); 84 mNetworkScoreManager = networkScoreManager; 85 mConnectivityManager = connectivityManager; 86 mCallback = callback; 87 } 88 setListening(boolean listening)89 public void setListening(boolean listening) { 90 if (listening) { 91 mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, 92 mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK); 93 mWifiNetworkScoreCache.registerListener(mCacheListener); 94 mConnectivityManager.registerNetworkCallback( 95 mNetworkRequest, mNetworkCallback, mHandler); 96 } else { 97 mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, 98 mWifiNetworkScoreCache); 99 mWifiNetworkScoreCache.unregisterListener(); 100 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); 101 } 102 } 103 handleBroadcast(Intent intent)104 public void handleBroadcast(Intent intent) { 105 if (mWifiManager == null) { 106 return; 107 } 108 String action = intent.getAction(); 109 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 110 updateWifiState(); 111 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 112 updateWifiState(); 113 final NetworkInfo networkInfo = 114 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 115 connected = networkInfo != null && networkInfo.isConnected(); 116 mWifiInfo = null; 117 ssid = null; 118 if (connected) { 119 mWifiInfo = mWifiManager.getConnectionInfo(); 120 if (mWifiInfo != null) { 121 if (mWifiInfo.isPasspointAp() || mWifiInfo.isOsuAp()) { 122 ssid = mWifiInfo.getPasspointProviderFriendlyName(); 123 } else { 124 ssid = getValidSsid(mWifiInfo); 125 } 126 updateRssi(mWifiInfo.getRssi()); 127 maybeRequestNetworkScore(); 128 } 129 } 130 updateStatusLabel(); 131 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { 132 // Default to -200 as its below WifiManager.MIN_RSSI. 133 updateRssi(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200)); 134 updateStatusLabel(); 135 } 136 } 137 updateWifiState()138 private void updateWifiState() { 139 state = mWifiManager.getWifiState(); 140 enabled = state == WifiManager.WIFI_STATE_ENABLED; 141 } 142 updateRssi(int newRssi)143 private void updateRssi(int newRssi) { 144 rssi = newRssi; 145 level = WifiManager.calculateSignalLevel(rssi, WifiManager.RSSI_LEVELS); 146 } 147 maybeRequestNetworkScore()148 private void maybeRequestNetworkScore() { 149 NetworkKey networkKey = NetworkKey.createFromWifiInfo(mWifiInfo); 150 if (mWifiNetworkScoreCache.getScoredNetwork(networkKey) == null) { 151 mNetworkScoreManager.requestScores(new NetworkKey[]{ networkKey }); 152 } 153 } 154 updateStatusLabel()155 private void updateStatusLabel() { 156 final NetworkCapabilities networkCapabilities 157 = mConnectivityManager.getNetworkCapabilities(mWifiManager.getCurrentNetwork()); 158 if (networkCapabilities != null) { 159 if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) { 160 statusLabel = mContext.getString(R.string.wifi_status_sign_in_required); 161 return; 162 } else if (networkCapabilities.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)) { 163 statusLabel = mContext.getString(R.string.wifi_limited_connection); 164 return; 165 } else if (!networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 166 statusLabel = mContext.getString(R.string.wifi_status_no_internet); 167 return; 168 } 169 } 170 171 ScoredNetwork scoredNetwork = 172 mWifiNetworkScoreCache.getScoredNetwork(NetworkKey.createFromWifiInfo(mWifiInfo)); 173 statusLabel = scoredNetwork == null 174 ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi); 175 } 176 177 /** Refresh the status label on Locale changed. */ refreshLocale()178 public void refreshLocale() { 179 updateStatusLabel(); 180 mCallback.run(); 181 } 182 getValidSsid(WifiInfo info)183 private String getValidSsid(WifiInfo info) { 184 String ssid = info.getSSID(); 185 if (ssid != null && !WifiSsid.NONE.equals(ssid)) { 186 return ssid; 187 } 188 // OK, it's not in the connectionInfo; we have to go hunting for it 189 List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks(); 190 int length = networks.size(); 191 for (int i = 0; i < length; i++) { 192 if (networks.get(i).networkId == info.getNetworkId()) { 193 return networks.get(i).SSID; 194 } 195 } 196 return null; 197 } 198 } 199