blob: 8591116fce0ffe7b9c89d4fcf50293cc117ec9ec [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;
lucaslinfc731ab2019-03-12 17:52:15 +080014import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050015import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
16
17import android.content.Context;
Jason Monk4cf95ae2015-11-16 15:59:53 -050018import android.content.Intent;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050019import android.net.ConnectivityManager;
20import android.net.Network;
21import android.net.NetworkCapabilities;
Jason Monk4cf95ae2015-11-16 15:59:53 -050022import android.net.NetworkInfo;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050023import android.net.NetworkKey;
24import android.net.NetworkRequest;
25import android.net.NetworkScoreManager;
26import android.net.ScoredNetwork;
Jason Monk4cf95ae2015-11-16 15:59:53 -050027import android.net.wifi.WifiConfiguration;
28import android.net.wifi.WifiInfo;
29import android.net.wifi.WifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050030import android.net.wifi.WifiNetworkScoreCache;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050031import android.os.Handler;
32import android.os.Looper;
lucaslin783f2212019-10-22 18:27:33 +080033import android.provider.Settings;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050034
35import com.android.settingslib.R;
Jason Monk4cf95ae2015-11-16 15:59:53 -050036
37import java.util.List;
38
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050039public class WifiStatusTracker extends ConnectivityManager.NetworkCallback {
40 private final Context mContext;
41 private final WifiNetworkScoreCache mWifiNetworkScoreCache;
Jason Monk4cf95ae2015-11-16 15:59:53 -050042 private final WifiManager mWifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050043 private final NetworkScoreManager mNetworkScoreManager;
44 private final ConnectivityManager mConnectivityManager;
Erik Kline04ed4302018-04-05 23:28:00 -070045 private final Handler mHandler = new Handler(Looper.getMainLooper());
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050046 private final WifiNetworkScoreCache.CacheListener mCacheListener =
Erik Kline04ed4302018-04-05 23:28:00 -070047 new WifiNetworkScoreCache.CacheListener(mHandler) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050048 @Override
49 public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) {
50 updateStatusLabel();
51 mCallback.run();
52 }
53 };
54 private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
Jeff Sharkeyc159d522018-03-28 10:54:07 -060055 .clearCapabilities()
56 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
57 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050058 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;
Jason Monk4cf95ae2015-11-16 15:59:53 -050070 public boolean enabled;
Jason Monk110e5f62017-03-31 13:45:12 -040071 public int state;
Jason Monk4cf95ae2015-11-16 15:59:53 -050072 public boolean connected;
73 public String ssid;
74 public int rssi;
75 public int level;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050076 public String statusLabel;
Jason Monk4cf95ae2015-11-16 15:59:53 -050077
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050078 public WifiStatusTracker(Context context, WifiManager wifiManager,
79 NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager,
80 Runnable callback) {
81 mContext = context;
Jason Monk4cf95ae2015-11-16 15:59:53 -050082 mWifiManager = wifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050083 mWifiNetworkScoreCache = new WifiNetworkScoreCache(context);
84 mNetworkScoreManager = networkScoreManager;
85 mConnectivityManager = connectivityManager;
86 mCallback = callback;
87 }
88
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);
Erik Kline04ed4302018-04-05 23:28:00 -070094 mConnectivityManager.registerNetworkCallback(
95 mNetworkRequest, mNetworkCallback, mHandler);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050096 } else {
97 mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI,
98 mWifiNetworkScoreCache);
99 mWifiNetworkScoreCache.unregisterListener();
100 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
101 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500102 }
103
104 public void handleBroadcast(Intent intent) {
Amin Shaikhbc38add2018-12-26 15:31:45 -0500105 if (mWifiManager == null) {
106 return;
107 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500108 String action = intent.getAction();
109 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400110 updateWifiState();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500111 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400112 updateWifiState();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500113 final NetworkInfo networkInfo =
Jason Monk4cf95ae2015-11-16 15:59:53 -0500114 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
115 connected = networkInfo != null && networkInfo.isConnected();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500116 mWifiInfo = null;
117 ssid = null;
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +0000118 if (connected) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500119 mWifiInfo = mWifiManager.getConnectionInfo();
120 if (mWifiInfo != null) {
Quang Luong72c0ebc2019-03-05 17:06:33 -0800121 if (mWifiInfo.isPasspointAp() || mWifiInfo.isOsuAp()) {
Quang Luong2a6cdc52019-03-05 17:35:45 -0800122 ssid = mWifiInfo.getPasspointProviderFriendlyName();
Quang Luong72c0ebc2019-03-05 17:06:33 -0800123 } else {
124 ssid = getValidSsid(mWifiInfo);
125 }
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500126 updateRssi(mWifiInfo.getRssi());
127 maybeRequestNetworkScore();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500128 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500129 }
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500130 updateStatusLabel();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500131 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
132 // Default to -200 as its below WifiManager.MIN_RSSI.
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500133 updateRssi(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200));
134 updateStatusLabel();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500135 }
136 }
137
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400138 private void updateWifiState() {
139 state = mWifiManager.getWifiState();
140 enabled = state == WifiManager.WIFI_STATE_ENABLED;
141 }
142
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500143 private void updateRssi(int newRssi) {
144 rssi = newRssi;
David Su576bf9b2019-11-18 12:48:02 -0800145 level = mWifiManager.calculateSignalLevel(rssi);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500146 }
147
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
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;
lucaslinfc731ab2019-03-12 17:52:15 +0800162 } else if (networkCapabilities.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)) {
163 statusLabel = mContext.getString(R.string.wifi_limited_connection);
164 return;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500165 } else if (!networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
lucaslin783f2212019-10-22 18:27:33 +0800166 final String mode = Settings.Global.getString(mContext.getContentResolver(),
167 Settings.Global.PRIVATE_DNS_MODE);
168 if (networkCapabilities.isPrivateDnsBroken()) {
169 statusLabel = mContext.getString(R.string.private_dns_broken);
170 } else {
171 statusLabel = mContext.getString(R.string.wifi_status_no_internet);
172 }
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500173 return;
174 }
175 }
176
177 ScoredNetwork scoredNetwork =
178 mWifiNetworkScoreCache.getScoredNetwork(NetworkKey.createFromWifiInfo(mWifiInfo));
179 statusLabel = scoredNetwork == null
180 ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi);
181 }
182
Fabian Kozynskid9cb3842018-09-28 13:34:14 -0400183 /** Refresh the status label on Locale changed. */
184 public void refreshLocale() {
185 updateStatusLabel();
186 mCallback.run();
187 }
188
Amin Shaikhc7593b12018-03-09 16:07:09 -0500189 private String getValidSsid(WifiInfo info) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500190 String ssid = info.getSSID();
David Sud9bb9a82019-11-13 10:49:01 -0800191 if (ssid != null && !WifiManager.UNKNOWN_SSID.equals(ssid)) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500192 return ssid;
193 }
194 // OK, it's not in the connectionInfo; we have to go hunting for it
195 List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
196 int length = networks.size();
197 for (int i = 0; i < length; i++) {
198 if (networks.get(i).networkId == info.getNetworkId()) {
199 return networks.get(i).SSID;
200 }
201 }
202 return null;
203 }
204}