• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.settings.connectivity;
18 
19 import android.annotation.SuppressLint;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.net.ConnectivityManager;
25 import android.net.EthernetManager;
26 import android.net.LinkAddress;
27 import android.net.LinkProperties;
28 import android.net.Network;
29 import android.net.NetworkInfo;
30 import android.net.wifi.WifiInfo;
31 import android.net.wifi.WifiManager;
32 import android.telephony.PhoneStateListener;
33 import android.telephony.SignalStrength;
34 import android.telephony.TelephonyManager;
35 import android.text.TextUtils;
36 
37 import androidx.annotation.UiThread;
38 
39 import com.android.settingslib.core.lifecycle.Lifecycle;
40 import com.android.settingslib.core.lifecycle.LifecycleObserver;
41 import com.android.settingslib.core.lifecycle.events.OnStart;
42 import com.android.settingslib.core.lifecycle.events.OnStop;
43 import com.android.settingslib.wifi.AccessPoint;
44 import com.android.settingslib.wifi.WifiTracker;
45 
46 import java.util.List;
47 import java.util.Locale;
48 
49 /**
50  * Listens for changes to the current connectivity status.
51  */
52 public class ConnectivityListener implements WifiTracker.WifiListener, LifecycleObserver, OnStart,
53         OnStop {
54 
55     private static final String TAG = "ConnectivityListener";
56 
57     private final Context mContext;
58     private final Listener mListener;
59     private boolean mStarted;
60 
61     private WifiTracker mWifiTracker;
62 
63     private final ConnectivityManager mConnectivityManager;
64     private final WifiManager mWifiManager;
65     private final EthernetManager mEthernetManager;
66     private WifiNetworkListener mWifiListener;
67     private final BroadcastReceiver mNetworkReceiver = new BroadcastReceiver() {
68         @Override
69         public void onReceive(Context context, Intent intent) {
70             if (mListener != null) {
71                 mListener.onConnectivityChange();
72             }
73         }
74     };
75     private final EthernetManager.Listener mEthernetListener = new EthernetManager.Listener() {
76         @Override
77         public void onAvailabilityChanged(String iface, boolean isAvailable) {
78             mListener.onConnectivityChange();
79         }
80     };
81     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
82         @Override
83         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
84             mCellSignalStrength = signalStrength;
85             mListener.onConnectivityChange();
86         }
87     };
88 
89     private SignalStrength mCellSignalStrength;
90     private int mNetworkType;
91     private String mWifiSsid;
92     private int mWifiSignalStrength;
93 
94     /**
95      * @deprecated use the constructor that provides a {@link Lifecycle} instead
96      */
97     @Deprecated
ConnectivityListener(Context context, Listener listener)98     public ConnectivityListener(Context context, Listener listener) {
99         this(context, listener, null);
100     }
101 
ConnectivityListener(Context context, Listener listener, Lifecycle lifecycle)102     public ConnectivityListener(Context context, Listener listener, Lifecycle lifecycle) {
103         mContext = context;
104         mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
105                 Context.CONNECTIVITY_SERVICE);
106         mWifiManager = mContext.getSystemService(WifiManager.class);
107         mEthernetManager = mContext.getSystemService(EthernetManager.class);
108         mListener = listener;
109         if (lifecycle != null) {
110             mWifiTracker = new WifiTracker(context, this, lifecycle, true, true);
111         } else {
112             mWifiTracker = new WifiTracker(context, this, true, true);
113         }
114     }
115 
116     /**
117      * Starts {@link ConnectivityListener}.
118      * This should be called only from main thread.
119      * @deprecated not needed when a {@link Lifecycle} is provided
120      */
121     @UiThread
122     @Deprecated
start()123     public void start() {
124         if (!mStarted) {
125             mWifiTracker.onStart();
126         }
127         onStart();
128     }
129 
130     @Override
onStart()131     public void onStart() {
132         if (!mStarted) {
133             mStarted = true;
134             updateConnectivityStatus();
135             IntentFilter networkIntentFilter = new IntentFilter();
136             networkIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
137             networkIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
138             networkIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
139 
140             mContext.registerReceiver(mNetworkReceiver, networkIntentFilter);
141             mEthernetManager.addListener(mEthernetListener);
142             final TelephonyManager telephonyManager = mContext
143                     .getSystemService(TelephonyManager.class);
144             if (telephonyManager != null) {
145                 telephonyManager.listen(mPhoneStateListener,
146                         PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
147             }
148         }
149     }
150 
151     /**
152      * Stops {@link ConnectivityListener}.
153      * This should be called only from main thread.
154      * @deprecated not needed when a {@link Lifecycle} is provided
155      */
156     @UiThread
157     @Deprecated
stop()158     public void stop() {
159         if (mStarted) {
160             mWifiTracker.onStop();
161         }
162         onStop();
163     }
164 
165     @Override
onStop()166     public void onStop() {
167         if (mStarted) {
168             mStarted = false;
169             mContext.unregisterReceiver(mNetworkReceiver);
170             mWifiListener = null;
171             mEthernetManager.removeListener(mEthernetListener);
172             final TelephonyManager telephonyManager = mContext
173                     .getSystemService(TelephonyManager.class);
174             if (telephonyManager != null) {
175                 telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
176             }
177         }
178     }
179 
180     /**
181      * Causes the background thread to quit.
182      * @deprecated not needed when a {@link Lifecycle} is provided
183      */
184     @Deprecated
destroy()185     public void destroy() {
186         mWifiTracker.onDestroy();
187     }
188 
setWifiListener(WifiNetworkListener wifiListener)189     public void setWifiListener(WifiNetworkListener wifiListener) {
190         mWifiListener = wifiListener;
191     }
192 
getWifiIpAddress()193     public String getWifiIpAddress() {
194         if (isWifiConnected()) {
195             WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
196             int ip = wifiInfo.getIpAddress();
197             return String.format(Locale.US, "%d.%d.%d.%d", (ip & 0xff), (ip >> 8 & 0xff),
198                     (ip >> 16 & 0xff), (ip >> 24 & 0xff));
199         } else {
200             return "";
201         }
202     }
203 
204     /**
205      * Return the MAC address of the currently connected Wifi AP.
206      */
207     @SuppressLint("HardwareIds")
getWifiMacAddress()208     public String getWifiMacAddress() {
209         if (isWifiConnected()) {
210             WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
211             return wifiInfo.getMacAddress();
212         } else {
213             return "";
214         }
215     }
216 
isEthernetConnected()217     public boolean isEthernetConnected() {
218         return mNetworkType == ConnectivityManager.TYPE_ETHERNET;
219     }
220 
isWifiConnected()221     public boolean isWifiConnected() {
222         return mNetworkType == ConnectivityManager.TYPE_WIFI;
223     }
224 
isCellConnected()225     public boolean isCellConnected() {
226         return mNetworkType == ConnectivityManager.TYPE_MOBILE;
227     }
228 
229     /**
230      * Return whether Ethernet port is available.
231      */
isEthernetAvailable()232     public boolean isEthernetAvailable() {
233         return mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_ETHERNET)
234                 && mEthernetManager.getAvailableInterfaces().length > 0;
235     }
236 
getFirstEthernet()237     private Network getFirstEthernet() {
238         final Network[] networks = mConnectivityManager.getAllNetworks();
239         for (final Network network : networks) {
240             NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(network);
241             if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
242                 return network;
243             }
244         }
245         return null;
246     }
247 
getEthernetIpAddress()248     public String getEthernetIpAddress() {
249         final Network network = getFirstEthernet();
250         if (network == null) {
251             return null;
252         }
253         final StringBuilder sb = new StringBuilder();
254         boolean gotAddress = false;
255         final LinkProperties linkProperties = mConnectivityManager.getLinkProperties(network);
256         for (LinkAddress linkAddress : linkProperties.getLinkAddresses()) {
257             if (gotAddress) {
258                 sb.append("\n");
259             }
260             sb.append(linkAddress.getAddress().getHostAddress());
261             gotAddress = true;
262         }
263         if (gotAddress) {
264             return sb.toString();
265         } else {
266             return null;
267         }
268     }
269 
getWifiSignalStrength(int maxLevel)270     public int getWifiSignalStrength(int maxLevel) {
271         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
272         return WifiManager.calculateSignalLevel(wifiInfo.getRssi(), maxLevel);
273     }
274 
getCellSignalStrength()275     public int getCellSignalStrength() {
276         if (isCellConnected() && mCellSignalStrength != null) {
277             return mCellSignalStrength.getLevel();
278         } else {
279             return 0;
280         }
281     }
282 
283     /**
284      * Return a list of wifi networks. Ensure that if a wifi network is connected that it appears
285      * as the first item on the list.
286      */
getAvailableNetworks()287     public List<AccessPoint> getAvailableNetworks() {
288         return mWifiTracker.getAccessPoints();
289     }
290 
isWifiEnabledOrEnabling()291     public boolean isWifiEnabledOrEnabling() {
292         return mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED
293                 || mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING;
294     }
295 
setWifiEnabled(boolean enable)296     public void setWifiEnabled(boolean enable) {
297         mWifiManager.setWifiEnabled(enable);
298     }
299 
updateConnectivityStatus()300     private void updateConnectivityStatus() {
301         NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
302         if (networkInfo == null) {
303             mNetworkType = ConnectivityManager.TYPE_NONE;
304         } else {
305             switch (networkInfo.getType()) {
306                 case ConnectivityManager.TYPE_WIFI: {
307 
308                     // Determine if this is
309                     // an open or secure wifi connection.
310                     mNetworkType = ConnectivityManager.TYPE_WIFI;
311 
312                     String ssid = getSsid();
313                     if (!TextUtils.equals(mWifiSsid, ssid)) {
314                         mWifiSsid = ssid;
315                     }
316 
317                     WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
318                     // Calculate the signal strength.
319                     int signalStrength;
320                     if (wifiInfo != null) {
321                         // Calculate the signal strength between 0 and 3.
322                         signalStrength = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), 4);
323                     } else {
324                         signalStrength = 0;
325                     }
326                     if (mWifiSignalStrength != signalStrength) {
327                         mWifiSignalStrength = signalStrength;
328                     }
329                     break;
330                 }
331 
332                 case ConnectivityManager.TYPE_ETHERNET:
333                     mNetworkType = ConnectivityManager.TYPE_ETHERNET;
334                     break;
335 
336                 case ConnectivityManager.TYPE_MOBILE:
337                     mNetworkType = ConnectivityManager.TYPE_MOBILE;
338                     break;
339 
340                 default:
341                     mNetworkType = ConnectivityManager.TYPE_NONE;
342                     break;
343             }
344         }
345     }
346 
347     @Override
onWifiStateChanged(int state)348     public void onWifiStateChanged(int state) {
349         updateConnectivityStatus();
350         if (mListener != null) {
351             mListener.onConnectivityChange();
352         }
353     }
354 
355     @Override
onConnectedChanged()356     public void onConnectedChanged() {
357         updateConnectivityStatus();
358         if (mListener != null) {
359             mListener.onConnectivityChange();
360         }
361     }
362 
363     @Override
onAccessPointsChanged()364     public void onAccessPointsChanged() {
365         if (mWifiListener != null) {
366             mWifiListener.onWifiListChanged();
367         }
368     }
369 
370     public interface Listener {
onConnectivityChange()371         void onConnectivityChange();
372     }
373 
374     public interface WifiNetworkListener {
onWifiListChanged()375         void onWifiListChanged();
376     }
377 
378     /**
379      * Get the SSID of current connected network.
380      * @return SSID
381      */
getSsid()382     public String getSsid() {
383         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
384         // Find the SSID of network.
385         String ssid = null;
386         if (wifiInfo != null) {
387             ssid = wifiInfo.getSSID();
388             if (ssid != null) {
389                 ssid = WifiInfo.removeDoubleQuotes(ssid);
390             }
391         }
392         return ssid;
393     }
394 }
395