blob: 871e2485a742ad9130f0161923382ce01bc3356c [file] [log] [blame]
Jason Monk4cf95ae2015-11-16 15:59:53 -05001/*
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
11package com.android.settingslib.wifi;
12
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050013import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
14import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
15
16import android.content.Context;
Jason Monk4cf95ae2015-11-16 15:59:53 -050017import android.content.Intent;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050018import android.net.ConnectivityManager;
19import android.net.Network;
20import android.net.NetworkCapabilities;
Jason Monk4cf95ae2015-11-16 15:59:53 -050021import android.net.NetworkInfo;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050022import android.net.NetworkKey;
23import android.net.NetworkRequest;
24import android.net.NetworkScoreManager;
25import android.net.ScoredNetwork;
Jason Monk4cf95ae2015-11-16 15:59:53 -050026import android.net.wifi.WifiConfiguration;
27import android.net.wifi.WifiInfo;
28import android.net.wifi.WifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050029import android.net.wifi.WifiNetworkScoreCache;
Amin Shaikhc7593b12018-03-09 16:07:09 -050030import android.net.wifi.WifiSsid;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050031import android.os.Handler;
32import android.os.Looper;
33
34import com.android.settingslib.R;
Jason Monk4cf95ae2015-11-16 15:59:53 -050035
36import java.util.List;
37
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050038public class WifiStatusTracker extends ConnectivityManager.NetworkCallback {
39 private final Context mContext;
40 private final WifiNetworkScoreCache mWifiNetworkScoreCache;
Jason Monk4cf95ae2015-11-16 15:59:53 -050041 private final WifiManager mWifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050042 private final NetworkScoreManager mNetworkScoreManager;
43 private final ConnectivityManager mConnectivityManager;
Erik Kline04ed4302018-04-05 23:28:00 -070044 private final Handler mHandler = new Handler(Looper.getMainLooper());
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050045 private final WifiNetworkScoreCache.CacheListener mCacheListener =
Erik Kline04ed4302018-04-05 23:28:00 -070046 new WifiNetworkScoreCache.CacheListener(mHandler) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050047 @Override
48 public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) {
49 updateStatusLabel();
50 mCallback.run();
51 }
52 };
53 private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
Jeff Sharkeyc159d522018-03-28 10:54:07 -060054 .clearCapabilities()
55 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
56 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050057 private final ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager
58 .NetworkCallback() {
59 @Override
60 public void onCapabilitiesChanged(
61 Network network, NetworkCapabilities networkCapabilities) {
62 updateStatusLabel();
63 mCallback.run();
64 }
65 };
66 private final Runnable mCallback;
67
68 private WifiInfo mWifiInfo;
Jason Monk4cf95ae2015-11-16 15:59:53 -050069 public boolean enabled;
Jason Monk110e5f62017-03-31 13:45:12 -040070 public int state;
Jason Monk4cf95ae2015-11-16 15:59:53 -050071 public boolean connected;
72 public String ssid;
73 public int rssi;
74 public int level;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050075 public String statusLabel;
Jason Monk4cf95ae2015-11-16 15:59:53 -050076
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050077 public WifiStatusTracker(Context context, WifiManager wifiManager,
78 NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager,
79 Runnable callback) {
80 mContext = context;
Jason Monk4cf95ae2015-11-16 15:59:53 -050081 mWifiManager = wifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050082 mWifiNetworkScoreCache = new WifiNetworkScoreCache(context);
83 mNetworkScoreManager = networkScoreManager;
84 mConnectivityManager = connectivityManager;
85 mCallback = callback;
86 }
87
88 public void setListening(boolean listening) {
89 if (listening) {
90 mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
91 mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK);
92 mWifiNetworkScoreCache.registerListener(mCacheListener);
Erik Kline04ed4302018-04-05 23:28:00 -070093 mConnectivityManager.registerNetworkCallback(
94 mNetworkRequest, mNetworkCallback, mHandler);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050095 } else {
96 mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI,
97 mWifiNetworkScoreCache);
98 mWifiNetworkScoreCache.unregisterListener();
99 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
100 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500101 }
102
103 public void handleBroadcast(Intent intent) {
Amin Shaikhbc38add2018-12-26 15:31:45 -0500104 if (mWifiManager == null) {
105 return;
106 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500107 String action = intent.getAction();
108 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400109 updateWifiState();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500110 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400111 updateWifiState();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500112 final NetworkInfo networkInfo =
Jason Monk4cf95ae2015-11-16 15:59:53 -0500113 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
114 connected = networkInfo != null && networkInfo.isConnected();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500115 mWifiInfo = null;
116 ssid = null;
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +0000117 if (connected) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500118 mWifiInfo = mWifiManager.getConnectionInfo();
119 if (mWifiInfo != null) {
120 ssid = getValidSsid(mWifiInfo);
121 updateRssi(mWifiInfo.getRssi());
122 maybeRequestNetworkScore();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500123 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500124 }
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500125 updateStatusLabel();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500126 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
127 // Default to -200 as its below WifiManager.MIN_RSSI.
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500128 updateRssi(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200));
129 updateStatusLabel();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500130 }
131 }
132
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400133 private void updateWifiState() {
134 state = mWifiManager.getWifiState();
135 enabled = state == WifiManager.WIFI_STATE_ENABLED;
136 }
137
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500138 private void updateRssi(int newRssi) {
139 rssi = newRssi;
140 level = WifiManager.calculateSignalLevel(rssi, WifiManager.RSSI_LEVELS);
141 }
142
143 private void maybeRequestNetworkScore() {
144 NetworkKey networkKey = NetworkKey.createFromWifiInfo(mWifiInfo);
145 if (mWifiNetworkScoreCache.getScoredNetwork(networkKey) == null) {
146 mNetworkScoreManager.requestScores(new NetworkKey[]{ networkKey });
147 }
148 }
149
150 private void updateStatusLabel() {
151 final NetworkCapabilities networkCapabilities
152 = mConnectivityManager.getNetworkCapabilities(mWifiManager.getCurrentNetwork());
153 if (networkCapabilities != null) {
154 if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
155 statusLabel = mContext.getString(R.string.wifi_status_sign_in_required);
156 return;
157 } else if (!networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
158 statusLabel = mContext.getString(R.string.wifi_status_no_internet);
159 return;
160 }
161 }
162
163 ScoredNetwork scoredNetwork =
164 mWifiNetworkScoreCache.getScoredNetwork(NetworkKey.createFromWifiInfo(mWifiInfo));
165 statusLabel = scoredNetwork == null
166 ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi);
167 }
168
Fabian Kozynskid9cb3842018-09-28 13:34:14 -0400169 /** Refresh the status label on Locale changed. */
170 public void refreshLocale() {
171 updateStatusLabel();
172 mCallback.run();
173 }
174
Amin Shaikhc7593b12018-03-09 16:07:09 -0500175 private String getValidSsid(WifiInfo info) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500176 String ssid = info.getSSID();
Amin Shaikhc7593b12018-03-09 16:07:09 -0500177 if (ssid != null && !WifiSsid.NONE.equals(ssid)) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500178 return ssid;
179 }
180 // OK, it's not in the connectionInfo; we have to go hunting for it
181 List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
182 int length = networks.size();
183 for (int i = 0; i < length; i++) {
184 if (networks.get(i).networkId == info.getNetworkId()) {
185 return networks.get(i).SSID;
186 }
187 }
188 return null;
189 }
190}