Home | History | Annotate | Download | only in connectivity
      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.content.BroadcastReceiver;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.IntentFilter;
     23 import android.net.ConnectivityManager;
     24 import android.net.EthernetManager;
     25 import android.net.LinkAddress;
     26 import android.net.LinkProperties;
     27 import android.net.Network;
     28 import android.net.NetworkInfo;
     29 import android.net.wifi.WifiInfo;
     30 import android.net.wifi.WifiManager;
     31 import android.os.HandlerThread;
     32 import android.os.Process;
     33 import android.support.annotation.UiThread;
     34 import android.telephony.PhoneStateListener;
     35 import android.telephony.SignalStrength;
     36 import android.telephony.TelephonyManager;
     37 import android.text.TextUtils;
     38 
     39 import com.android.settingslib.wifi.AccessPoint;
     40 import com.android.settingslib.wifi.WifiTracker;
     41 
     42 import java.util.List;
     43 
     44 /**
     45  * Listens for changes to the current connectivity status.
     46  */
     47 public class ConnectivityListener implements WifiTracker.WifiListener {
     48 
     49     private static final String TAG = "ConnectivityListener";
     50 
     51     private final Context mContext;
     52     private final Listener mListener;
     53     private boolean mStarted;
     54 
     55     private WifiTracker mWifiTracker;
     56     private final HandlerThread mBgThread;
     57 
     58     private final ConnectivityManager mConnectivityManager;
     59     private final WifiManager mWifiManager;
     60     private final EthernetManager mEthernetManager;
     61     private WifiNetworkListener mWifiListener;
     62     private final BroadcastReceiver mNetworkReceiver = new BroadcastReceiver() {
     63         @Override
     64         public void onReceive(Context context, Intent intent) {
     65             mListener.onConnectivityChange();
     66         }
     67     };
     68     private final EthernetManager.Listener mEthernetListener = new EthernetManager.Listener() {
     69         @Override
     70         public void onAvailabilityChanged(boolean isAvailable) {
     71             mListener.onConnectivityChange();
     72         }
     73     };
     74     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
     75         @Override
     76         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
     77             mCellSignalStrength = signalStrength;
     78             mListener.onConnectivityChange();
     79         }
     80     };
     81 
     82     private SignalStrength mCellSignalStrength;
     83     private int mNetworkType;
     84     private String mWifiSsid;
     85     private int mWifiSignalStrength;
     86 
     87     public ConnectivityListener(Context context, Listener listener) {
     88         mContext = context;
     89         mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
     90                 Context.CONNECTIVITY_SERVICE);
     91         mWifiManager = mContext.getSystemService(WifiManager.class);
     92         mEthernetManager = mContext.getSystemService(EthernetManager.class);
     93         mListener = listener;
     94         mBgThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
     95         mBgThread.start();
     96         mWifiTracker = new WifiTracker(context, this, mBgThread.getLooper(), true, true);
     97     }
     98 
     99     /**
    100      * Starts {@link ConnectivityListener}.
    101      * This should be called only from main thread.
    102      */
    103     @UiThread
    104     public void start() {
    105         if (!mStarted) {
    106             mStarted = true;
    107             updateConnectivityStatus();
    108             mWifiTracker.startTracking();
    109             IntentFilter networkIntentFilter = new IntentFilter();
    110             networkIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    111             networkIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
    112             networkIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    113 
    114             mContext.registerReceiver(mNetworkReceiver, networkIntentFilter);
    115             mEthernetManager.addListener(mEthernetListener);
    116             final TelephonyManager telephonyManager = mContext
    117                     .getSystemService(TelephonyManager.class);
    118             if (telephonyManager != null) {
    119                 telephonyManager.listen(mPhoneStateListener,
    120                         PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    121             }
    122         }
    123     }
    124 
    125     /**
    126      * Stops {@link ConnectivityListener}.
    127      * This should be called only from main thread.
    128      */
    129     @UiThread
    130     public void stop() {
    131         if (mStarted) {
    132             mStarted = false;
    133             mWifiTracker.stopTracking();
    134             mContext.unregisterReceiver(mNetworkReceiver);
    135             mWifiListener = null;
    136             mEthernetManager.removeListener(mEthernetListener);
    137             final TelephonyManager telephonyManager = mContext
    138                     .getSystemService(TelephonyManager.class);
    139             if (telephonyManager != null) {
    140                 telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
    141             }
    142         }
    143     }
    144 
    145     /**
    146      * Causes the background thread to quit.
    147      */
    148     public void destroy() {
    149         mBgThread.quit();
    150     }
    151 
    152     public void setWifiListener(WifiNetworkListener wifiListener) {
    153         mWifiListener = wifiListener;
    154     }
    155 
    156     public String getWifiIpAddress() {
    157         if (isWifiConnected()) {
    158             WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    159             int ip = wifiInfo.getIpAddress();
    160             return String.format("%d.%d.%d.%d", (ip & 0xff), (ip >> 8 & 0xff),
    161                     (ip >> 16 & 0xff), (ip >> 24 & 0xff));
    162         } else {
    163             return "";
    164         }
    165     }
    166 
    167     /**
    168      * Return the MAC address of the currently connected Wifi AP.
    169      */
    170     public String getWifiMacAddress() {
    171         if (isWifiConnected()) {
    172             WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    173             return wifiInfo.getMacAddress();
    174         } else {
    175             return "";
    176         }
    177     }
    178 
    179     public boolean isEthernetConnected() {
    180         return mNetworkType == ConnectivityManager.TYPE_ETHERNET;
    181     }
    182 
    183     public boolean isWifiConnected() {
    184         return mNetworkType == ConnectivityManager.TYPE_WIFI;
    185     }
    186 
    187     public boolean isCellConnected() {
    188         return mNetworkType == ConnectivityManager.TYPE_MOBILE;
    189     }
    190 
    191     /**
    192      * Return whether Ethernet port is available.
    193      */
    194     public boolean isEthernetAvailable() {
    195         return mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_ETHERNET)
    196                 && mEthernetManager.isAvailable();
    197     }
    198 
    199     private Network getFirstEthernet() {
    200         final Network[] networks = mConnectivityManager.getAllNetworks();
    201         for (final Network network : networks) {
    202             NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(network);
    203             if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
    204                 return network;
    205             }
    206         }
    207         return null;
    208     }
    209 
    210     public String getEthernetIpAddress() {
    211         final Network network = getFirstEthernet();
    212         if (network == null) {
    213             return null;
    214         }
    215         final StringBuilder sb = new StringBuilder();
    216         boolean gotAddress = false;
    217         final LinkProperties linkProperties = mConnectivityManager.getLinkProperties(network);
    218         for (LinkAddress linkAddress : linkProperties.getLinkAddresses()) {
    219             if (gotAddress) {
    220                 sb.append("\n");
    221             }
    222             sb.append(linkAddress.getAddress().getHostAddress());
    223             gotAddress = true;
    224         }
    225         if (gotAddress) {
    226             return sb.toString();
    227         } else {
    228             return null;
    229         }
    230     }
    231 
    232     public int getWifiSignalStrength(int maxLevel) {
    233         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    234         return WifiManager.calculateSignalLevel(wifiInfo.getRssi(), maxLevel);
    235     }
    236 
    237     public int getCellSignalStrength() {
    238         if (isCellConnected() && mCellSignalStrength != null) {
    239             return mCellSignalStrength.getLevel();
    240         } else {
    241             return 0;
    242         }
    243     }
    244 
    245     /**
    246      * Return a list of wifi networks. Ensure that if a wifi network is connected that it appears
    247      * as the first item on the list.
    248      */
    249     public List<AccessPoint> getAvailableNetworks() {
    250         return mWifiTracker.getAccessPoints();
    251     }
    252 
    253     public boolean isWifiEnabledOrEnabling() {
    254         return mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED
    255                 || mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING;
    256     }
    257 
    258     public void setWifiEnabled(boolean enable) {
    259         mWifiManager.setWifiEnabled(enable);
    260     }
    261 
    262     private boolean setNetworkType(int networkType) {
    263         boolean hasChanged = mNetworkType != networkType;
    264         mNetworkType = networkType;
    265         return hasChanged;
    266     }
    267 
    268     private boolean updateConnectivityStatus() {
    269         NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
    270         if (networkInfo == null) {
    271             return setNetworkType(ConnectivityManager.TYPE_NONE);
    272         } else {
    273             switch (networkInfo.getType()) {
    274                 case ConnectivityManager.TYPE_WIFI: {
    275                     boolean hasChanged;
    276 
    277                     // Determine if this is an open or secure wifi connection.
    278                     WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    279                     hasChanged = setNetworkType(ConnectivityManager.TYPE_WIFI);
    280 
    281                     // Find the SSID of network.
    282                     String ssid = null;
    283                     if (wifiInfo != null) {
    284                         ssid = wifiInfo.getSSID();
    285                         if (ssid != null) {
    286                             ssid = WifiInfo.removeDoubleQuotes(ssid);
    287                         }
    288                     }
    289                     if (!TextUtils.equals(mWifiSsid, ssid)) {
    290                         hasChanged = true;
    291                         mWifiSsid = ssid;
    292                     }
    293 
    294                     // Calculate the signal strength.
    295                     int signalStrength;
    296                     if (wifiInfo != null) {
    297                         // Calculate the signal strength between 0 and 3.
    298                         signalStrength = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), 4);
    299                     } else {
    300                         signalStrength = 0;
    301                     }
    302                     if (mWifiSignalStrength != signalStrength) {
    303                         hasChanged = true;
    304                         mWifiSignalStrength = signalStrength;
    305                     }
    306                     return hasChanged;
    307                 }
    308 
    309                 case ConnectivityManager.TYPE_ETHERNET:
    310                     return setNetworkType(ConnectivityManager.TYPE_ETHERNET);
    311 
    312                 case ConnectivityManager.TYPE_MOBILE:
    313                     return setNetworkType(ConnectivityManager.TYPE_MOBILE);
    314 
    315                 default:
    316                     return setNetworkType(ConnectivityManager.TYPE_NONE);
    317             }
    318         }
    319     }
    320 
    321     @Override
    322     public void onWifiStateChanged(int state) {
    323         mListener.onConnectivityChange();
    324     }
    325 
    326     @Override
    327     public void onConnectedChanged() {
    328 
    329     }
    330 
    331     @Override
    332     public void onAccessPointsChanged() {
    333         if (mWifiListener != null) {
    334             mWifiListener.onWifiListChanged();
    335         }
    336     }
    337 
    338     public interface Listener {
    339         void onConnectivityChange();
    340     }
    341 
    342     public interface WifiNetworkListener {
    343         void onWifiListChanged();
    344     }
    345 }
    346