Get the adapter type information from Android OS.
BUG= Review URL: https://codereview.webrtc.org/1594673002 Cr-Commit-Position: refs/heads/master@{#11463}
This commit is contained in:
parent
ae695e95a6
commit
a7ad7c3ca0
@ -142,6 +142,9 @@ public class NetworkMonitorTest extends ActivityTestCase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNetworkConnect(NetworkInformation networkInfo) {}
|
public void onNetworkConnect(NetworkInformation networkInfo) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkDisconnect(int networkHandle) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Object lock = new Object();
|
private static final Object lock = new Object();
|
||||||
|
|||||||
@ -154,19 +154,27 @@ public class NetworkMonitor {
|
|||||||
if (autoDetector == null) {
|
if (autoDetector == null) {
|
||||||
autoDetector = new NetworkMonitorAutoDetect(
|
autoDetector = new NetworkMonitorAutoDetect(
|
||||||
new NetworkMonitorAutoDetect.Observer() {
|
new NetworkMonitorAutoDetect.Observer() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionTypeChanged(ConnectionType newConnectionType) {
|
public void onConnectionTypeChanged(ConnectionType newConnectionType) {
|
||||||
updateCurrentConnectionType(newConnectionType);
|
updateCurrentConnectionType(newConnectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNetworkConnect(NetworkInformation networkInfo) {
|
public void onNetworkConnect(NetworkInformation networkInfo) {
|
||||||
updateNetworkInformation(networkInfo);
|
notifyObserversOfNetworkConnect(networkInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkDisconnect(int networkHandle) {
|
||||||
|
notifyObserversOfNetworkDisconnect(networkHandle);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
applicationContext);
|
applicationContext);
|
||||||
final NetworkMonitorAutoDetect.NetworkState networkState =
|
final NetworkMonitorAutoDetect.NetworkState networkState =
|
||||||
autoDetector.getCurrentNetworkState();
|
autoDetector.getCurrentNetworkState();
|
||||||
updateCurrentConnectionType(autoDetector.getConnectionType(networkState));
|
updateCurrentConnectionType(autoDetector.getConnectionType(networkState));
|
||||||
|
updateActiveNetworkList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,12 +195,28 @@ public class NetworkMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNetworkInformation(NetworkInformation networkInfo) {
|
private void notifyObserversOfNetworkConnect(NetworkInformation networkInfo) {
|
||||||
for (long nativeObserver : nativeNetworkObservers) {
|
for (long nativeObserver : nativeNetworkObservers) {
|
||||||
nativeNotifyOfNetworkConnect(nativeObserver, networkInfo);
|
nativeNotifyOfNetworkConnect(nativeObserver, networkInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyObserversOfNetworkDisconnect(int networkHandle) {
|
||||||
|
for (long nativeObserver : nativeNetworkObservers) {
|
||||||
|
nativeNotifyOfNetworkDisconnect(nativeObserver, networkHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateActiveNetworkList() {
|
||||||
|
NetworkInformation[] networkInfos = autoDetector.getActiveNetworkList();
|
||||||
|
if (networkInfos.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (long nativeObserver : nativeNetworkObservers) {
|
||||||
|
nativeNotifyOfActiveNetworkList(nativeObserver, networkInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an observer for any connection type changes.
|
* Adds an observer for any connection type changes.
|
||||||
*/
|
*/
|
||||||
@ -224,11 +248,11 @@ public class NetworkMonitor {
|
|||||||
&& connectionType != ConnectionType.CONNECTION_NONE;
|
&& connectionType != ConnectionType.CONNECTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long nativeCreateNetworkMonitor();
|
|
||||||
|
|
||||||
private native void nativeNotifyConnectionTypeChanged(long nativePtr);
|
private native void nativeNotifyConnectionTypeChanged(long nativePtr);
|
||||||
|
|
||||||
private native void nativeNotifyOfNetworkConnect(long nativePtr, NetworkInformation networkInfo);
|
private native void nativeNotifyOfNetworkConnect(long nativePtr, NetworkInformation networkInfo);
|
||||||
|
private native void nativeNotifyOfNetworkDisconnect(long nativePtr, int networkHandle);
|
||||||
|
private native void nativeNotifyOfActiveNetworkList(long nativePtr,
|
||||||
|
NetworkInformation[] networkInfos);
|
||||||
|
|
||||||
// For testing only.
|
// For testing only.
|
||||||
static void resetInstanceForTests(Context context) {
|
static void resetInstanceForTests(Context context) {
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
package org.webrtc;
|
package org.webrtc;
|
||||||
|
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
|
|
||||||
|
|
||||||
import org.webrtc.Logging;
|
import org.webrtc.Logging;
|
||||||
|
|
||||||
@ -120,6 +122,54 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
return subtype;
|
return subtype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* The methods in this class get called when the network changes if the callback
|
||||||
|
* is registered with a proper network request. It is only available in Android Lollipop
|
||||||
|
* and above.
|
||||||
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
private class SimpleNetworkCallback extends NetworkCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAvailable(Network network) {
|
||||||
|
NetworkInformation networkInformation = connectivityManagerDelegate.networkToInfo(network);
|
||||||
|
Logging.d(TAG, "Network " + networkInformation.name + " with handle " +
|
||||||
|
networkInformation.handle + " is connected ");
|
||||||
|
observer.onNetworkConnect(networkInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCapabilitiesChanged(
|
||||||
|
Network network, NetworkCapabilities networkCapabilities) {
|
||||||
|
// A capabilities change may indicate the ConnectionType has changed,
|
||||||
|
// so forward the new NetworkInformation along to observer.
|
||||||
|
NetworkInformation networkInformation = connectivityManagerDelegate.networkToInfo(network);
|
||||||
|
observer.onNetworkConnect(networkInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
|
||||||
|
// A link property change may indicate the IP address changes.
|
||||||
|
// so forward the new NetworkInformation to the observer.
|
||||||
|
NetworkInformation networkInformation = connectivityManagerDelegate.networkToInfo(network);
|
||||||
|
observer.onNetworkConnect(networkInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLosing(Network network, int maxMsToLive) {
|
||||||
|
// Tell the network is going to lose in MaxMsToLive milliseconds.
|
||||||
|
// We may use this signal later.
|
||||||
|
Logging.d(TAG, "Network with handle " + networkToNetId(network) +
|
||||||
|
" is about to lose in " + maxMsToLive + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLost(Network network) {
|
||||||
|
int handle = networkToNetId(network);
|
||||||
|
Logging.d(TAG, "Network with handle " + handle + " is disconnected");
|
||||||
|
observer.onNetworkDisconnect(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Queries the ConnectivityManager for information about the current connection. */
|
/** Queries the ConnectivityManager for information about the current connection. */
|
||||||
static class ConnectivityManagerDelegate {
|
static class ConnectivityManagerDelegate {
|
||||||
@ -128,7 +178,6 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
* gracefully below.
|
* gracefully below.
|
||||||
*/
|
*/
|
||||||
private final ConnectivityManager connectivityManager;
|
private final ConnectivityManager connectivityManager;
|
||||||
private NetworkCallback networkCallback;
|
|
||||||
|
|
||||||
ConnectivityManagerDelegate(Context context) {
|
ConnectivityManagerDelegate(Context context) {
|
||||||
connectivityManager =
|
connectivityManager =
|
||||||
@ -186,6 +235,18 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
return connectivityManager.getAllNetworks();
|
return connectivityManager.getAllNetworks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkInformation[] getActiveNetworkList() {
|
||||||
|
if (!supportNetworkCallback()) {
|
||||||
|
return new NetworkInformation[0];
|
||||||
|
}
|
||||||
|
Network[] networks = getAllNetworks();
|
||||||
|
NetworkInformation[] netInfos = new NetworkInformation[networks.length];
|
||||||
|
for (int i = 0; i < networks.length; ++i) {
|
||||||
|
netInfos[i] = networkToInfo(networks[i]);
|
||||||
|
}
|
||||||
|
return netInfos;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the NetID of the current default network. Returns
|
* Returns the NetID of the current default network. Returns
|
||||||
* INVALID_NET_ID if no current default network connected.
|
* INVALID_NET_ID if no current default network connected.
|
||||||
@ -193,7 +254,7 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
*/
|
*/
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
int getDefaultNetId() {
|
int getDefaultNetId() {
|
||||||
if (connectivityManager == null) {
|
if (!supportNetworkCallback()) {
|
||||||
return INVALID_NET_ID;
|
return INVALID_NET_ID;
|
||||||
}
|
}
|
||||||
// Android Lollipop had no API to get the default network; only an
|
// Android Lollipop had no API to get the default network; only an
|
||||||
@ -226,6 +287,17 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
return defaultNetId;
|
return defaultNetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
private NetworkInformation networkToInfo(Network network) {
|
||||||
|
LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
|
||||||
|
NetworkInformation networkInformation = new NetworkInformation(
|
||||||
|
linkProperties.getInterfaceName(),
|
||||||
|
getConnectionType(getNetworkState(network)),
|
||||||
|
networkToNetId(network),
|
||||||
|
getIPAddresses(linkProperties));
|
||||||
|
return networkInformation;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if {@code network} can provide Internet access. Can be used to
|
* Returns true if {@code network} can provide Internet access. Can be used to
|
||||||
* ignore specialized networks (e.g. IMS, FOTA).
|
* ignore specialized networks (e.g. IMS, FOTA).
|
||||||
@ -240,30 +312,19 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
return capabilities != null && capabilities.hasCapability(NET_CAPABILITY_INTERNET);
|
return capabilities != null && capabilities.hasCapability(NET_CAPABILITY_INTERNET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Only callable on Lollipop and newer releases. */
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
public void requestMobileNetwork(final Observer observer) {
|
public void registerNetworkCallback(NetworkCallback networkCallback) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ||
|
connectivityManager.registerNetworkCallback(
|
||||||
connectivityManager == null) {
|
new NetworkRequest.Builder().addCapability(NET_CAPABILITY_INTERNET).build(),
|
||||||
return;
|
networkCallback);
|
||||||
}
|
}
|
||||||
networkCallback = new NetworkCallback() {
|
|
||||||
@Override
|
/** Only callable on Lollipop and newer releases. */
|
||||||
public void onAvailable(Network network) {
|
@SuppressLint("NewApi")
|
||||||
super.onAvailable(network);
|
public void requestMobileNetwork(NetworkCallback networkCallback) {
|
||||||
LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
|
|
||||||
NetworkInformation networkInformation = new NetworkInformation(
|
|
||||||
linkProperties.getInterfaceName(),
|
|
||||||
getConnectionType(getNetworkState(network)),
|
|
||||||
networkToNetId(network),
|
|
||||||
getIPAddresses(linkProperties));
|
|
||||||
Logging.d(TAG, "Network " + networkInformation.name + " is connected ");
|
|
||||||
observer.onNetworkConnect(networkInformation);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Logging.d(TAG, "Requesting cellular network");
|
|
||||||
NetworkRequest.Builder builder = new NetworkRequest.Builder();
|
NetworkRequest.Builder builder = new NetworkRequest.Builder();
|
||||||
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
|
builder.addCapability(NET_CAPABILITY_INTERNET).addTransportType(TRANSPORT_CELLULAR);
|
||||||
builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
|
|
||||||
connectivityManager.requestNetwork(builder.build(), networkCallback);
|
connectivityManager.requestNetwork(builder.build(), networkCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,15 +340,16 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
public void releaseCallback() {
|
public void releaseCallback(NetworkCallback networkCallback) {
|
||||||
if (networkCallback != null) {
|
if (supportNetworkCallback()) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
Logging.d(TAG, "Unregister network callback");
|
||||||
connectivityManager.unregisterNetworkCallback(networkCallback);
|
connectivityManager.unregisterNetworkCallback(networkCallback);
|
||||||
}
|
}
|
||||||
networkCallback = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean supportNetworkCallback() {
|
||||||
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && connectivityManager != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -323,15 +385,20 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
|
|
||||||
static final int INVALID_NET_ID = -1;
|
static final int INVALID_NET_ID = -1;
|
||||||
private static final String TAG = "NetworkMonitorAutoDetect";
|
private static final String TAG = "NetworkMonitorAutoDetect";
|
||||||
private final IntentFilter intentFilter;
|
|
||||||
|
|
||||||
// Observer for the connection type change.
|
// Observer for the connection type change.
|
||||||
private final Observer observer;
|
private final Observer observer;
|
||||||
|
private final IntentFilter intentFilter;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
// connectivityManagerDelegates and wifiManagerDelegate are only non-final for testing.
|
// Used to request mobile network. It does not do anything except for keeping
|
||||||
|
// the callback for releasing the request.
|
||||||
|
private final NetworkCallback mobileNetworkCallback;
|
||||||
|
// Used to receive updates on all networks.
|
||||||
|
private final NetworkCallback allNetworkCallback;
|
||||||
|
// connectivityManagerDelegate and wifiManagerDelegate are only non-final for testing.
|
||||||
private ConnectivityManagerDelegate connectivityManagerDelegate;
|
private ConnectivityManagerDelegate connectivityManagerDelegate;
|
||||||
private WifiManagerDelegate wifiManagerDelegate;
|
private WifiManagerDelegate wifiManagerDelegate;
|
||||||
|
|
||||||
private boolean isRegistered;
|
private boolean isRegistered;
|
||||||
private ConnectionType connectionType;
|
private ConnectionType connectionType;
|
||||||
private String wifiSSID;
|
private String wifiSSID;
|
||||||
@ -345,11 +412,13 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
*/
|
*/
|
||||||
public void onConnectionTypeChanged(ConnectionType newConnectionType);
|
public void onConnectionTypeChanged(ConnectionType newConnectionType);
|
||||||
public void onNetworkConnect(NetworkInformation networkInfo);
|
public void onNetworkConnect(NetworkInformation networkInfo);
|
||||||
|
public void onNetworkDisconnect(int networkHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a NetworkMonitorAutoDetect. Should only be called on UI thread.
|
* Constructs a NetworkMonitorAutoDetect. Should only be called on UI thread.
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public NetworkMonitorAutoDetect(Observer observer, Context context) {
|
public NetworkMonitorAutoDetect(Observer observer, Context context) {
|
||||||
this.observer = observer;
|
this.observer = observer;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
@ -360,7 +429,17 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
connectionType = getConnectionType(networkState);
|
connectionType = getConnectionType(networkState);
|
||||||
wifiSSID = getWifiSSID(networkState);
|
wifiSSID = getWifiSSID(networkState);
|
||||||
intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||||
|
|
||||||
registerReceiver();
|
registerReceiver();
|
||||||
|
if (connectivityManagerDelegate.supportNetworkCallback()) {
|
||||||
|
mobileNetworkCallback = new NetworkCallback();
|
||||||
|
connectivityManagerDelegate.requestMobileNetwork(mobileNetworkCallback);
|
||||||
|
allNetworkCallback = new SimpleNetworkCallback();
|
||||||
|
connectivityManagerDelegate.registerNetworkCallback(allNetworkCallback);
|
||||||
|
} else {
|
||||||
|
mobileNetworkCallback = null;
|
||||||
|
allNetworkCallback = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -385,7 +464,17 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
return isRegistered;
|
return isRegistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkInformation[] getActiveNetworkList() {
|
||||||
|
return connectivityManagerDelegate.getActiveNetworkList();
|
||||||
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
if (allNetworkCallback != null) {
|
||||||
|
connectivityManagerDelegate.releaseCallback(allNetworkCallback);
|
||||||
|
}
|
||||||
|
if (mobileNetworkCallback != null) {
|
||||||
|
connectivityManagerDelegate.releaseCallback(mobileNetworkCallback);
|
||||||
|
}
|
||||||
unregisterReceiver();
|
unregisterReceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,22 +482,20 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
* Registers a BroadcastReceiver in the given context.
|
* Registers a BroadcastReceiver in the given context.
|
||||||
*/
|
*/
|
||||||
private void registerReceiver() {
|
private void registerReceiver() {
|
||||||
if (!isRegistered) {
|
if (isRegistered) return;
|
||||||
|
|
||||||
isRegistered = true;
|
isRegistered = true;
|
||||||
context.registerReceiver(this, intentFilter);
|
context.registerReceiver(this, intentFilter);
|
||||||
connectivityManagerDelegate.requestMobileNetwork(observer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters the BroadcastReceiver in the given context.
|
* Unregisters the BroadcastReceiver in the given context.
|
||||||
*/
|
*/
|
||||||
private void unregisterReceiver() {
|
private void unregisterReceiver() {
|
||||||
if (isRegistered) {
|
if (!isRegistered) return;
|
||||||
|
|
||||||
isRegistered = false;
|
isRegistered = false;
|
||||||
context.unregisterReceiver(this);
|
context.unregisterReceiver(this);
|
||||||
connectivityManagerDelegate.releaseCallback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkState getCurrentNetworkState() {
|
public NetworkState getCurrentNetworkState() {
|
||||||
@ -422,9 +509,6 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||||||
* when not implemented.
|
* when not implemented.
|
||||||
*/
|
*/
|
||||||
public int getDefaultNetId() {
|
public int getDefaultNetId() {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
return INVALID_NET_ID;
|
|
||||||
}
|
|
||||||
return connectivityManagerDelegate.getDefaultNetId();
|
return connectivityManagerDelegate.getDefaultNetId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,29 @@ static NetworkType GetNetworkTypeFromJava(JNIEnv* jni, jobject j_network_type) {
|
|||||||
return NetworkType::NETWORK_UNKNOWN;
|
return NetworkType::NETWORK_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) {
|
||||||
|
switch (network_type) {
|
||||||
|
case NETWORK_UNKNOWN:
|
||||||
|
RTC_DCHECK(false) << "Unknown network type ";
|
||||||
|
return rtc::ADAPTER_TYPE_UNKNOWN;
|
||||||
|
case NETWORK_ETHERNET:
|
||||||
|
return rtc::ADAPTER_TYPE_ETHERNET;
|
||||||
|
case NETWORK_WIFI:
|
||||||
|
return rtc::ADAPTER_TYPE_WIFI;
|
||||||
|
case NETWORK_4G:
|
||||||
|
case NETWORK_3G:
|
||||||
|
case NETWORK_2G:
|
||||||
|
return rtc::ADAPTER_TYPE_CELLULAR;
|
||||||
|
case NETWORK_BLUETOOTH:
|
||||||
|
// There is no corresponding mapping for bluetooth networks.
|
||||||
|
// Map it to VPN for now.
|
||||||
|
return rtc::ADAPTER_TYPE_VPN;
|
||||||
|
default:
|
||||||
|
RTC_DCHECK(false) << "Invalid network type " << network_type;
|
||||||
|
return rtc::ADAPTER_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static rtc::IPAddress GetIPAddressFromJava(JNIEnv* jni, jobject j_ip_address) {
|
static rtc::IPAddress GetIPAddressFromJava(JNIEnv* jni, jobject j_ip_address) {
|
||||||
jclass j_ip_address_class = GetObjectClass(jni, j_ip_address);
|
jclass j_ip_address_class = GetObjectClass(jni, j_ip_address);
|
||||||
jfieldID j_address_id = GetFieldID(jni, j_ip_address_class, "address", "[B");
|
jfieldID j_address_id = GetFieldID(jni, j_ip_address_class, "address", "[B");
|
||||||
@ -186,7 +209,7 @@ void AndroidNetworkMonitor::Start() {
|
|||||||
jmethodID m =
|
jmethodID m =
|
||||||
GetMethodID(jni(), *j_network_monitor_class_, "startMonitoring", "(J)V");
|
GetMethodID(jni(), *j_network_monitor_class_, "startMonitoring", "(J)V");
|
||||||
jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
|
jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
|
||||||
CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.startMonitoring";
|
CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidNetworkMonitor::Stop() {
|
void AndroidNetworkMonitor::Stop() {
|
||||||
@ -207,21 +230,24 @@ void AndroidNetworkMonitor::Stop() {
|
|||||||
jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
|
jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
|
||||||
CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring";
|
CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring";
|
||||||
|
|
||||||
network_info_by_address_.clear();
|
network_handle_by_address_.clear();
|
||||||
|
network_info_by_handle_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
|
int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
|
||||||
const rtc::IPAddress& address) {
|
const rtc::IPAddress& address) {
|
||||||
RTC_CHECK(thread_checker_.CalledOnValidThread());
|
RTC_CHECK(thread_checker_.CalledOnValidThread());
|
||||||
auto it = network_info_by_address_.find(address);
|
|
||||||
if (it == network_info_by_address_.end()) {
|
|
||||||
return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// Android prior to Lollipop didn't have support for binding sockets to
|
// Android prior to Lollipop didn't have support for binding sockets to
|
||||||
// networks. However, in that case it should not have reached here because
|
// networks. However, in that case it should not have reached here because
|
||||||
// |network_info_by_address_| should only be populated in Android Lollipop
|
// |network_handle_by_address_| should only be populated in Android Lollipop
|
||||||
// and above.
|
// and above.
|
||||||
NetworkInformation network = it->second;
|
// TODO(honghaiz): Add a check for Android version here so that it won't try
|
||||||
|
// to look for handle if the Android version is before Lollipop.
|
||||||
|
auto iter = network_handle_by_address_.find(address);
|
||||||
|
if (iter == network_handle_by_address_.end()) {
|
||||||
|
return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
NetworkHandle network_handle = iter->second;
|
||||||
|
|
||||||
// NOTE: This does rely on Android implementation details, but
|
// NOTE: This does rely on Android implementation details, but
|
||||||
// these details are unlikely to change.
|
// these details are unlikely to change.
|
||||||
@ -244,7 +270,7 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
|
|||||||
LOG(LS_ERROR) << "Symbol setNetworkForSocket not found ";
|
LOG(LS_ERROR) << "Symbol setNetworkForSocket not found ";
|
||||||
return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
|
return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
int rv = setNetworkForSocket(network.handle, socket_fd);
|
int rv = setNetworkForSocket(network_handle, socket_fd);
|
||||||
// If |network| has since disconnected, |rv| will be ENONET. Surface this as
|
// If |network| has since disconnected, |rv| will be ENONET. Surface this as
|
||||||
// ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
|
// ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
|
||||||
// the less descriptive ERR_FAILED.
|
// the less descriptive ERR_FAILED.
|
||||||
@ -257,20 +283,58 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
|
|||||||
return rtc::NETWORK_BIND_FAILURE;
|
return rtc::NETWORK_BIND_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidNetworkMonitor::OnNetworkAvailable(
|
void AndroidNetworkMonitor::OnNetworkConnected(
|
||||||
const NetworkInformation& network_info) {
|
const NetworkInformation& network_info) {
|
||||||
|
LOG(LS_INFO) << "Network connected: " << network_info.ToString();
|
||||||
worker_thread()->Invoke<void>(rtc::Bind(
|
worker_thread()->Invoke<void>(rtc::Bind(
|
||||||
&AndroidNetworkMonitor::OnNetworkAvailable_w, this, network_info));
|
&AndroidNetworkMonitor::OnNetworkConnected_w, this, network_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidNetworkMonitor::OnNetworkAvailable_w(
|
void AndroidNetworkMonitor::OnNetworkConnected_w(
|
||||||
const NetworkInformation& network_info) {
|
const NetworkInformation& network_info) {
|
||||||
LOG(LS_INFO) << "Network available: " << network_info.ToString();
|
adapter_type_by_name_[network_info.interface_name] =
|
||||||
for (rtc::IPAddress address : network_info.ip_addresses) {
|
AdapterTypeFromNetworkType(network_info.type);
|
||||||
network_info_by_address_[address] = network_info;
|
network_info_by_handle_[network_info.handle] = network_info;
|
||||||
|
for (const rtc::IPAddress& address : network_info.ip_addresses) {
|
||||||
|
network_handle_by_address_[address] = network_info.handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidNetworkMonitor::OnNetworkDisconnected(NetworkHandle handle) {
|
||||||
|
LOG(LS_INFO) << "Network disconnected for handle " << handle;
|
||||||
|
worker_thread()->Invoke<void>(
|
||||||
|
rtc::Bind(&AndroidNetworkMonitor::OnNetworkDisconnected_w, this, handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidNetworkMonitor::OnNetworkDisconnected_w(NetworkHandle handle) {
|
||||||
|
auto iter = network_info_by_handle_.find(handle);
|
||||||
|
if (iter != network_info_by_handle_.end()) {
|
||||||
|
for (const rtc::IPAddress& address : iter->second.ip_addresses) {
|
||||||
|
network_handle_by_address_.erase(address);
|
||||||
|
}
|
||||||
|
network_info_by_handle_.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidNetworkMonitor::SetNetworkInfos(
|
||||||
|
const std::vector<NetworkInformation>& network_infos) {
|
||||||
|
RTC_CHECK(thread_checker_.CalledOnValidThread());
|
||||||
|
network_handle_by_address_.clear();
|
||||||
|
network_info_by_handle_.clear();
|
||||||
|
for (NetworkInformation network : network_infos) {
|
||||||
|
OnNetworkConnected_w(network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::AdapterType AndroidNetworkMonitor::GetAdapterType(
|
||||||
|
const std::string& if_name) {
|
||||||
|
auto iter = adapter_type_by_name_.find(if_name);
|
||||||
|
if (iter == adapter_type_by_name_.end()) {
|
||||||
|
return rtc::ADAPTER_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
rtc::NetworkMonitorInterface*
|
rtc::NetworkMonitorInterface*
|
||||||
AndroidNetworkMonitorFactory::CreateNetworkMonitor() {
|
AndroidNetworkMonitorFactory::CreateNetworkMonitor() {
|
||||||
return new AndroidNetworkMonitor();
|
return new AndroidNetworkMonitor();
|
||||||
@ -283,6 +347,21 @@ JOW(void, NetworkMonitor_nativeNotifyConnectionTypeChanged)(
|
|||||||
network_monitor->OnNetworksChanged();
|
network_monitor->OnNetworksChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JOW(void, NetworkMonitor_nativeNotifyOfActiveNetworkList)(
|
||||||
|
JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
|
||||||
|
jobjectArray j_network_infos) {
|
||||||
|
AndroidNetworkMonitor* network_monitor =
|
||||||
|
reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
|
||||||
|
std::vector<NetworkInformation> network_infos;
|
||||||
|
size_t num_networks = jni->GetArrayLength(j_network_infos);
|
||||||
|
for (size_t i = 0; i < num_networks; ++i) {
|
||||||
|
jobject j_network_info = jni->GetObjectArrayElement(j_network_infos, i);
|
||||||
|
CHECK_EXCEPTION(jni) << "Error during GetObjectArrayElement";
|
||||||
|
network_infos.push_back(GetNetworkInformationFromJava(jni, j_network_info));
|
||||||
|
}
|
||||||
|
network_monitor->SetNetworkInfos(network_infos);
|
||||||
|
}
|
||||||
|
|
||||||
JOW(void, NetworkMonitor_nativeNotifyOfNetworkConnect)(
|
JOW(void, NetworkMonitor_nativeNotifyOfNetworkConnect)(
|
||||||
JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
|
JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
|
||||||
jobject j_network_info) {
|
jobject j_network_info) {
|
||||||
@ -290,7 +369,16 @@ JOW(void, NetworkMonitor_nativeNotifyOfNetworkConnect)(
|
|||||||
reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
|
reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
|
||||||
NetworkInformation network_info =
|
NetworkInformation network_info =
|
||||||
GetNetworkInformationFromJava(jni, j_network_info);
|
GetNetworkInformationFromJava(jni, j_network_info);
|
||||||
network_monitor->OnNetworkAvailable(network_info);
|
network_monitor->OnNetworkConnected(network_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
JOW(void, NetworkMonitor_nativeNotifyOfNetworkDisconnect)(
|
||||||
|
JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
|
||||||
|
jint network_handle) {
|
||||||
|
AndroidNetworkMonitor* network_monitor =
|
||||||
|
reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
|
||||||
|
network_monitor->OnNetworkDisconnected(
|
||||||
|
static_cast<NetworkHandle>(network_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc_jni
|
} // namespace webrtc_jni
|
||||||
|
|||||||
@ -75,19 +75,25 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
|
|||||||
|
|
||||||
int BindSocketToNetwork(int socket_fd,
|
int BindSocketToNetwork(int socket_fd,
|
||||||
const rtc::IPAddress& address) override;
|
const rtc::IPAddress& address) override;
|
||||||
void OnNetworkAvailable(const NetworkInformation& network_info);
|
rtc::AdapterType GetAdapterType(const std::string& if_name) override;
|
||||||
|
void OnNetworkConnected(const NetworkInformation& network_info);
|
||||||
|
void OnNetworkDisconnected(NetworkHandle network_handle);
|
||||||
|
void SetNetworkInfos(const std::vector<NetworkInformation>& network_infos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
|
JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
|
||||||
|
|
||||||
void OnNetworkAvailable_w(const NetworkInformation& network_info);
|
void OnNetworkConnected_w(const NetworkInformation& network_info);
|
||||||
|
void OnNetworkDisconnected_w(NetworkHandle network_handle);
|
||||||
|
|
||||||
ScopedGlobalRef<jclass> j_network_monitor_class_;
|
ScopedGlobalRef<jclass> j_network_monitor_class_;
|
||||||
ScopedGlobalRef<jobject> j_network_monitor_;
|
ScopedGlobalRef<jobject> j_network_monitor_;
|
||||||
rtc::ThreadChecker thread_checker_;
|
rtc::ThreadChecker thread_checker_;
|
||||||
static jobject application_context_;
|
static jobject application_context_;
|
||||||
bool started_ = false;
|
bool started_ = false;
|
||||||
std::map<rtc::IPAddress, NetworkInformation> network_info_by_address_;
|
std::map<std::string, rtc::AdapterType> adapter_type_by_name_;
|
||||||
|
std::map<rtc::IPAddress, NetworkHandle> network_handle_by_address_;
|
||||||
|
std::map<NetworkHandle, NetworkInformation> network_info_by_handle_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AndroidNetworkMonitorFactory : public rtc::NetworkMonitorFactory {
|
class AndroidNetworkMonitorFactory : public rtc::NetworkMonitorFactory {
|
||||||
|
|||||||
@ -441,6 +441,8 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
|||||||
AdapterType adapter_type = ADAPTER_TYPE_UNKNOWN;
|
AdapterType adapter_type = ADAPTER_TYPE_UNKNOWN;
|
||||||
if (cursor->ifa_flags & IFF_LOOPBACK) {
|
if (cursor->ifa_flags & IFF_LOOPBACK) {
|
||||||
adapter_type = ADAPTER_TYPE_LOOPBACK;
|
adapter_type = ADAPTER_TYPE_LOOPBACK;
|
||||||
|
} else if (network_monitor_) {
|
||||||
|
adapter_type = network_monitor_->GetAdapterType(cursor->ifa_name);
|
||||||
}
|
}
|
||||||
#if defined(WEBRTC_IOS)
|
#if defined(WEBRTC_IOS)
|
||||||
// Cell networks are pdp_ipN on iOS.
|
// Cell networks are pdp_ipN on iOS.
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "webrtc/base/basictypes.h"
|
#include "webrtc/base/basictypes.h"
|
||||||
#include "webrtc/base/ipaddress.h"
|
#include "webrtc/base/ipaddress.h"
|
||||||
|
#include "webrtc/base/networkmonitor.h"
|
||||||
#include "webrtc/base/messagehandler.h"
|
#include "webrtc/base/messagehandler.h"
|
||||||
#include "webrtc/base/scoped_ptr.h"
|
#include "webrtc/base/scoped_ptr.h"
|
||||||
#include "webrtc/base/sigslot.h"
|
#include "webrtc/base/sigslot.h"
|
||||||
@ -36,15 +37,6 @@ class Network;
|
|||||||
class NetworkMonitorInterface;
|
class NetworkMonitorInterface;
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
enum AdapterType {
|
|
||||||
// This enum resembles the one in Chromium net::ConnectionType.
|
|
||||||
ADAPTER_TYPE_UNKNOWN = 0,
|
|
||||||
ADAPTER_TYPE_ETHERNET = 1 << 0,
|
|
||||||
ADAPTER_TYPE_WIFI = 1 << 1,
|
|
||||||
ADAPTER_TYPE_CELLULAR = 1 << 2,
|
|
||||||
ADAPTER_TYPE_VPN = 1 << 3,
|
|
||||||
ADAPTER_TYPE_LOOPBACK = 1 << 4
|
|
||||||
};
|
|
||||||
|
|
||||||
// By default, ignore loopback interfaces on the host.
|
// By default, ignore loopback interfaces on the host.
|
||||||
const int kDefaultNetworkIgnoreMask = ADAPTER_TYPE_LOOPBACK;
|
const int kDefaultNetworkIgnoreMask = ADAPTER_TYPE_LOOPBACK;
|
||||||
|
|||||||
@ -32,6 +32,9 @@ class FakeNetworkMonitor : public NetworkMonitorBase {
|
|||||||
void Start() override { started_ = true; }
|
void Start() override { started_ = true; }
|
||||||
void Stop() override { started_ = false; }
|
void Stop() override { started_ = false; }
|
||||||
bool started() { return started_; }
|
bool started() { return started_; }
|
||||||
|
AdapterType GetAdapterType(const std::string& if_name) override {
|
||||||
|
return ADAPTER_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool started_ = false;
|
bool started_ = false;
|
||||||
|
|||||||
@ -29,6 +29,16 @@ enum NetworkBindingResults {
|
|||||||
NETWORK_BIND_NETWORK_CHANGED = -4
|
NETWORK_BIND_NETWORK_CHANGED = -4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AdapterType {
|
||||||
|
// This enum resembles the one in Chromium net::ConnectionType.
|
||||||
|
ADAPTER_TYPE_UNKNOWN = 0,
|
||||||
|
ADAPTER_TYPE_ETHERNET = 1 << 0,
|
||||||
|
ADAPTER_TYPE_WIFI = 1 << 1,
|
||||||
|
ADAPTER_TYPE_CELLULAR = 1 << 2,
|
||||||
|
ADAPTER_TYPE_VPN = 1 << 3,
|
||||||
|
ADAPTER_TYPE_LOOPBACK = 1 << 4
|
||||||
|
};
|
||||||
|
|
||||||
class NetworkBinderInterface {
|
class NetworkBinderInterface {
|
||||||
public:
|
public:
|
||||||
// Binds a socket to the network that is attached to |address| so that all
|
// Binds a socket to the network that is attached to |address| so that all
|
||||||
@ -70,6 +80,8 @@ class NetworkMonitorInterface {
|
|||||||
// Implementations should call this method on the base when networks change,
|
// Implementations should call this method on the base when networks change,
|
||||||
// and the base will fire SignalNetworksChanged on the right thread.
|
// and the base will fire SignalNetworksChanged on the right thread.
|
||||||
virtual void OnNetworksChanged() = 0;
|
virtual void OnNetworksChanged() = 0;
|
||||||
|
|
||||||
|
virtual AdapterType GetAdapterType(const std::string& interface_name) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetworkMonitorBase : public NetworkMonitorInterface,
|
class NetworkMonitorBase : public NetworkMonitorInterface,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user