• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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