241 lines
8.7 KiB
Java
Executable File
241 lines
8.7 KiB
Java
Executable File
// Copyright 2012 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
package org.chromium.net;
|
|
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.net.ConnectivityManager;
|
|
import android.net.wifi.WifiInfo;
|
|
import android.net.wifi.WifiManager;
|
|
import android.telephony.TelephonyManager;
|
|
import android.util.Log;
|
|
|
|
import org.chromium.base.ActivityStatus;
|
|
|
|
/**
|
|
* Used by the NetworkChangeNotifier to listens to platform changes in connectivity.
|
|
* Note that use of this class requires that the app have the platform
|
|
* ACCESS_NETWORK_STATE permission.
|
|
*/
|
|
public class NetworkChangeNotifierAutoDetect extends BroadcastReceiver
|
|
implements ActivityStatus.StateListener {
|
|
|
|
/** Queries the ConnectivityManager for information about the current connection. */
|
|
static class ConnectivityManagerDelegate {
|
|
private final ConnectivityManager mConnectivityManager;
|
|
|
|
ConnectivityManagerDelegate(Context context) {
|
|
mConnectivityManager =
|
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
}
|
|
|
|
// For testing.
|
|
ConnectivityManagerDelegate() {
|
|
// All the methods below should be overridden.
|
|
mConnectivityManager = null;
|
|
}
|
|
|
|
boolean activeNetworkExists() {
|
|
return mConnectivityManager.getActiveNetworkInfo() != null;
|
|
}
|
|
|
|
boolean isConnected() {
|
|
return mConnectivityManager.getActiveNetworkInfo().isConnected();
|
|
}
|
|
|
|
int getNetworkType() {
|
|
return mConnectivityManager.getActiveNetworkInfo().getType();
|
|
}
|
|
|
|
int getNetworkSubtype() {
|
|
return mConnectivityManager.getActiveNetworkInfo().getSubtype();
|
|
}
|
|
}
|
|
|
|
/** Queries the WifiManager for SSID of the current Wifi connection. */
|
|
static class WifiManagerDelegate {
|
|
private final WifiManager mWifiManager;
|
|
|
|
WifiManagerDelegate(Context context) {
|
|
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
|
}
|
|
|
|
// For testing.
|
|
WifiManagerDelegate() {
|
|
// All the methods below should be overridden.
|
|
mWifiManager = null;
|
|
}
|
|
|
|
String getWifiSSID() {
|
|
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
|
|
if (wifiInfo == null)
|
|
return "";
|
|
String ssid = wifiInfo.getSSID();
|
|
return ssid == null ? "" : ssid;
|
|
}
|
|
}
|
|
|
|
private static final String TAG = "NetworkChangeNotifierAutoDetect";
|
|
|
|
private final NetworkConnectivityIntentFilter mIntentFilter =
|
|
new NetworkConnectivityIntentFilter();
|
|
|
|
private final Observer mObserver;
|
|
|
|
private final Context mContext;
|
|
private ConnectivityManagerDelegate mConnectivityManagerDelegate;
|
|
private WifiManagerDelegate mWifiManagerDelegate;
|
|
private boolean mRegistered;
|
|
private int mConnectionType;
|
|
private String mWifiSSID;
|
|
|
|
/**
|
|
* Observer notified on the UI thread whenever a new connection type was detected.
|
|
*/
|
|
public static interface Observer {
|
|
public void onConnectionTypeChanged(int newConnectionType);
|
|
}
|
|
|
|
public NetworkChangeNotifierAutoDetect(Observer observer, Context context) {
|
|
mObserver = observer;
|
|
mContext = context.getApplicationContext();
|
|
mConnectivityManagerDelegate = new ConnectivityManagerDelegate(context);
|
|
mWifiManagerDelegate = new WifiManagerDelegate(context);
|
|
mConnectionType = getCurrentConnectionType();
|
|
mWifiSSID = getCurrentWifiSSID();
|
|
ActivityStatus.registerStateListener(this);
|
|
}
|
|
|
|
/**
|
|
* Allows overriding the ConnectivityManagerDelegate for tests.
|
|
*/
|
|
void setConnectivityManagerDelegateForTests(ConnectivityManagerDelegate delegate) {
|
|
mConnectivityManagerDelegate = delegate;
|
|
}
|
|
|
|
/**
|
|
* Allows overriding the WifiManagerDelegate for tests.
|
|
*/
|
|
void setWifiManagerDelegateForTests(WifiManagerDelegate delegate) {
|
|
mWifiManagerDelegate = delegate;
|
|
}
|
|
|
|
public void destroy() {
|
|
unregisterReceiver();
|
|
}
|
|
|
|
/**
|
|
* Register a BroadcastReceiver in the given context.
|
|
*/
|
|
private void registerReceiver() {
|
|
if (!mRegistered) {
|
|
mRegistered = true;
|
|
mContext.registerReceiver(this, mIntentFilter);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unregister the BroadcastReceiver in the given context.
|
|
*/
|
|
private void unregisterReceiver() {
|
|
if (mRegistered) {
|
|
mRegistered = false;
|
|
mContext.unregisterReceiver(this);
|
|
}
|
|
}
|
|
|
|
public int getCurrentConnectionType() {
|
|
// Track exactly what type of connection we have.
|
|
if (!mConnectivityManagerDelegate.activeNetworkExists() ||
|
|
!mConnectivityManagerDelegate.isConnected()) {
|
|
return NetworkChangeNotifier.CONNECTION_NONE;
|
|
}
|
|
|
|
switch (mConnectivityManagerDelegate.getNetworkType()) {
|
|
case ConnectivityManager.TYPE_ETHERNET:
|
|
return NetworkChangeNotifier.CONNECTION_ETHERNET;
|
|
case ConnectivityManager.TYPE_WIFI:
|
|
return NetworkChangeNotifier.CONNECTION_WIFI;
|
|
case ConnectivityManager.TYPE_WIMAX:
|
|
return NetworkChangeNotifier.CONNECTION_4G;
|
|
case ConnectivityManager.TYPE_MOBILE:
|
|
// Use information from TelephonyManager to classify the connection.
|
|
switch (mConnectivityManagerDelegate.getNetworkSubtype()) {
|
|
case TelephonyManager.NETWORK_TYPE_GPRS:
|
|
case TelephonyManager.NETWORK_TYPE_EDGE:
|
|
case TelephonyManager.NETWORK_TYPE_CDMA:
|
|
case TelephonyManager.NETWORK_TYPE_1xRTT:
|
|
case TelephonyManager.NETWORK_TYPE_IDEN:
|
|
return NetworkChangeNotifier.CONNECTION_2G;
|
|
case TelephonyManager.NETWORK_TYPE_UMTS:
|
|
case TelephonyManager.NETWORK_TYPE_EVDO_0:
|
|
case TelephonyManager.NETWORK_TYPE_EVDO_A:
|
|
case TelephonyManager.NETWORK_TYPE_HSDPA:
|
|
case TelephonyManager.NETWORK_TYPE_HSUPA:
|
|
case TelephonyManager.NETWORK_TYPE_HSPA:
|
|
case TelephonyManager.NETWORK_TYPE_EVDO_B:
|
|
case TelephonyManager.NETWORK_TYPE_EHRPD:
|
|
case TelephonyManager.NETWORK_TYPE_HSPAP:
|
|
return NetworkChangeNotifier.CONNECTION_3G;
|
|
case TelephonyManager.NETWORK_TYPE_LTE:
|
|
return NetworkChangeNotifier.CONNECTION_4G;
|
|
default:
|
|
return NetworkChangeNotifier.CONNECTION_UNKNOWN;
|
|
}
|
|
default:
|
|
return NetworkChangeNotifier.CONNECTION_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
private String getCurrentWifiSSID() {
|
|
if (getCurrentConnectionType() != NetworkChangeNotifier.CONNECTION_WIFI)
|
|
return "";
|
|
return mWifiManagerDelegate.getWifiSSID();
|
|
}
|
|
|
|
// BroadcastReceiver
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
connectionTypeChanged();
|
|
}
|
|
|
|
// ActivityStatus.StateListener
|
|
@Override
|
|
public void onActivityStateChange(int state) {
|
|
if (state == ActivityStatus.RESUMED) {
|
|
// Note that this also covers the case where the main activity is created. The CREATED
|
|
// event is always followed by the RESUMED event. This is a temporary "hack" until
|
|
// http://crbug.com/176837 is fixed. The CREATED event can't be used reliably for now
|
|
// since its notification is deferred. This means that it can immediately follow a
|
|
// DESTROYED/STOPPED/... event which is problematic.
|
|
// TODO(pliard): fix http://crbug.com/176837.
|
|
connectionTypeChanged();
|
|
registerReceiver();
|
|
} else if (state == ActivityStatus.PAUSED) {
|
|
unregisterReceiver();
|
|
}
|
|
}
|
|
|
|
private void connectionTypeChanged() {
|
|
int newConnectionType = getCurrentConnectionType();
|
|
String newWifiSSID = getCurrentWifiSSID();
|
|
if (newConnectionType == mConnectionType && newWifiSSID.equals(mWifiSSID))
|
|
return;
|
|
|
|
mConnectionType = newConnectionType;
|
|
mWifiSSID = newWifiSSID;
|
|
Log.d(TAG, "Network connectivity changed, type is: " + mConnectionType);
|
|
mObserver.onConnectionTypeChanged(newConnectionType);
|
|
}
|
|
|
|
private static class NetworkConnectivityIntentFilter extends IntentFilter {
|
|
NetworkConnectivityIntentFilter() {
|
|
addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
|
}
|
|
}
|
|
}
|