blob: 8bd5f57f9b719518b038b282353b54a4e413ecf4 [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 Shaikhc7593b12018-03-09 16:07:09 -050031import android.net.wifi.WifiSsid;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050032import android.os.Handler;
33import android.os.Looper;
lucaslin783f2212019-10-22 18:27:33 +080034import android.provider.Settings;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050035
36import com.android.settingslib.R;
Jason Monk4cf95ae2015-11-16 15:59:53 -050037
38import java.util.List;
39
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050040public class WifiStatusTracker extends ConnectivityManager.NetworkCallback {
41 private final Context mContext;
42 private final WifiNetworkScoreCache mWifiNetworkScoreCache;
Jason Monk4cf95ae2015-11-16 15:59:53 -050043 private final WifiManager mWifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050044 private final NetworkScoreManager mNetworkScoreManager;
45 private final ConnectivityManager mConnectivityManager;
Erik Kline04ed4302018-04-05 23:28:00 -070046 private final Handler mHandler = new Handler(Looper.getMainLooper());
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050047 private final WifiNetworkScoreCache.CacheListener mCacheListener =
Erik Kline04ed4302018-04-05 23:28:00 -070048 new WifiNetworkScoreCache.CacheListener(mHandler) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050049 @Override
50 public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) {
51 updateStatusLabel();
52 mCallback.run();
53 }
54 };
55 private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
Jeff Sharkeyc159d522018-03-28 10:54:07 -060056 .clearCapabilities()
57 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
58 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050059 private final ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager
60 .NetworkCallback() {
61 @Override
62 public void onCapabilitiesChanged(
63 Network network, NetworkCapabilities networkCapabilities) {
64 updateStatusLabel();
65 mCallback.run();
66 }
67 };
68 private final Runnable mCallback;
69
70 private WifiInfo mWifiInfo;
Jason Monk4cf95ae2015-11-16 15:59:53 -050071 public boolean enabled;
Jason Monk110e5f62017-03-31 13:45:12 -040072 public int state;
Jason Monk4cf95ae2015-11-16 15:59:53 -050073 public boolean connected;
74 public String ssid;
75 public int rssi;
76 public int level;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050077 public String statusLabel;
Jason Monk4cf95ae2015-11-16 15:59:53 -050078
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050079 public WifiStatusTracker(Context context, WifiManager wifiManager,
80 NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager,
81 Runnable callback) {
82 mContext = context;
Jason Monk4cf95ae2015-11-16 15:59:53 -050083 mWifiManager = wifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050084 mWifiNetworkScoreCache = new WifiNetworkScoreCache(context);
85 mNetworkScoreManager = networkScoreManager;
86 mConnectivityManager = connectivityManager;
87 mCallback = callback;
88 }
89
90 public void setListening(boolean listening) {
91 if (listening) {
92 mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
David Sueea09212020-01-13 17:12:27 -080093 mWifiNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_CURRENT_NETWORK);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050094 mWifiNetworkScoreCache.registerListener(mCacheListener);
Erik Kline04ed4302018-04-05 23:28:00 -070095 mConnectivityManager.registerNetworkCallback(
96 mNetworkRequest, mNetworkCallback, mHandler);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050097 } else {
98 mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI,
99 mWifiNetworkScoreCache);
100 mWifiNetworkScoreCache.unregisterListener();
101 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
102 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500103 }
104
105 public void handleBroadcast(Intent intent) {
Amin Shaikhbc38add2018-12-26 15:31:45 -0500106 if (mWifiManager == null) {
107 return;
108 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500109 String action = intent.getAction();
110 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400111 updateWifiState();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500112 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400113 updateWifiState();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500114 final NetworkInfo networkInfo =
Jason Monk4cf95ae2015-11-16 15:59:53 -0500115 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
116 connected = networkInfo != null && networkInfo.isConnected();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500117 mWifiInfo = null;
118 ssid = null;
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +0000119 if (connected) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500120 mWifiInfo = mWifiManager.getConnectionInfo();
121 if (mWifiInfo != null) {
Quang Luong72c0ebc2019-03-05 17:06:33 -0800122 if (mWifiInfo.isPasspointAp() || mWifiInfo.isOsuAp()) {
Quang Luong2a6cdc52019-03-05 17:35:45 -0800123 ssid = mWifiInfo.getPasspointProviderFriendlyName();
Quang Luong72c0ebc2019-03-05 17:06:33 -0800124 } else {
125 ssid = getValidSsid(mWifiInfo);
126 }
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500127 updateRssi(mWifiInfo.getRssi());
128 maybeRequestNetworkScore();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500129 }
Jason Monk4cf95ae2015-11-16 15:59:53 -0500130 }
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500131 updateStatusLabel();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500132 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
133 // Default to -200 as its below WifiManager.MIN_RSSI.
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500134 updateRssi(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200));
135 updateStatusLabel();
Jason Monk4cf95ae2015-11-16 15:59:53 -0500136 }
137 }
138
Amin Shaikheddaf3f2018-04-18 17:43:53 -0400139 private void updateWifiState() {
140 state = mWifiManager.getWifiState();
141 enabled = state == WifiManager.WIFI_STATE_ENABLED;
142 }
143
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500144 private void updateRssi(int newRssi) {
145 rssi = newRssi;
146 level = WifiManager.calculateSignalLevel(rssi, WifiManager.RSSI_LEVELS);
147 }
148
149 private void maybeRequestNetworkScore() {
150 NetworkKey networkKey = NetworkKey.createFromWifiInfo(mWifiInfo);
151 if (mWifiNetworkScoreCache.getScoredNetwork(networkKey) == null) {
152 mNetworkScoreManager.requestScores(new NetworkKey[]{ networkKey });
153 }
154 }
155
156 private void updateStatusLabel() {
157 final NetworkCapabilities networkCapabilities
158 = mConnectivityManager.getNetworkCapabilities(mWifiManager.getCurrentNetwork());
159 if (networkCapabilities != null) {
160 if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
161 statusLabel = mContext.getString(R.string.wifi_status_sign_in_required);
162 return;
lucaslinfc731ab2019-03-12 17:52:15 +0800163 } else if (networkCapabilities.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)) {
164 statusLabel = mContext.getString(R.string.wifi_limited_connection);
165 return;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500166 } else if (!networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
lucaslin783f2212019-10-22 18:27:33 +0800167 final String mode = Settings.Global.getString(mContext.getContentResolver(),
168 Settings.Global.PRIVATE_DNS_MODE);
169 if (networkCapabilities.isPrivateDnsBroken()) {
170 statusLabel = mContext.getString(R.string.private_dns_broken);
171 } else {
172 statusLabel = mContext.getString(R.string.wifi_status_no_internet);
173 }
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500174 return;
175 }
176 }
177
178 ScoredNetwork scoredNetwork =
179 mWifiNetworkScoreCache.getScoredNetwork(NetworkKey.createFromWifiInfo(mWifiInfo));
180 statusLabel = scoredNetwork == null
181 ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi);
182 }
183
Fabian Kozynskid9cb3842018-09-28 13:34:14 -0400184 /** Refresh the status label on Locale changed. */
185 public void refreshLocale() {
186 updateStatusLabel();
187 mCallback.run();
188 }
189
Amin Shaikhc7593b12018-03-09 16:07:09 -0500190 private String getValidSsid(WifiInfo info) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500191 String ssid = info.getSSID();
Amin Shaikhc7593b12018-03-09 16:07:09 -0500192 if (ssid != null && !WifiSsid.NONE.equals(ssid)) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500193 return ssid;
194 }
195 // OK, it's not in the connectionInfo; we have to go hunting for it
196 List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
197 int length = networks.size();
198 for (int i = 0; i < length; i++) {
199 if (networks.get(i).networkId == info.getNetworkId()) {
200 return networks.get(i).SSID;
201 }
202 }
203 return null;
204 }
205}