mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00
Add interface for os/firmware to affect ICE selection.
This patch adds an interface for os/firmware to set a network preference NOT_PREFERRED / NEUTRAL that can be picked up by an IceController and used when selection ice candidate pair. The patch exposes this using an Android Intent based interface. BUG: webrtc:11825 Change-Id: Ic12b6bf704fde7f9c912020dd7bc79ccae4613ab Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180883 Commit-Queue: Jonas Oreland <jonaso@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31877}
This commit is contained in:
parent
c55e24acc7
commit
f7721fb246
13 changed files with 406 additions and 187 deletions
|
@ -1428,4 +1428,7 @@ if (is_android) {
|
|||
"//third_party/android_deps:com_android_support_support_annotations_java",
|
||||
]
|
||||
}
|
||||
java_cpp_enum("network_monitor_enums") {
|
||||
sources = [ "network_monitor.h" ]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,7 +265,9 @@ webrtc::MdnsResponderInterface* NetworkManager::GetMdnsResponder() const {
|
|||
}
|
||||
|
||||
NetworkManagerBase::NetworkManagerBase()
|
||||
: enumeration_permission_(NetworkManager::ENUMERATION_ALLOWED) {}
|
||||
: enumeration_permission_(NetworkManager::ENUMERATION_ALLOWED),
|
||||
signal_network_preference_change_(webrtc::field_trial::IsEnabled(
|
||||
"WebRTC-SignalNetworkPreferenceChange")) {}
|
||||
|
||||
NetworkManagerBase::~NetworkManagerBase() {
|
||||
for (const auto& kv : networks_map_) {
|
||||
|
@ -382,6 +384,12 @@ void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
|
|||
if (!existing_net->active()) {
|
||||
*changed = true;
|
||||
}
|
||||
if (net->network_preference() != existing_net->network_preference()) {
|
||||
existing_net->set_network_preference(net->network_preference());
|
||||
if (signal_network_preference_change_) {
|
||||
*changed = true;
|
||||
}
|
||||
}
|
||||
RTC_DCHECK(net->active());
|
||||
if (existing_net != net) {
|
||||
delete net;
|
||||
|
@ -536,6 +544,7 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
|||
|
||||
AdapterType adapter_type = ADAPTER_TYPE_UNKNOWN;
|
||||
AdapterType vpn_underlying_adapter_type = ADAPTER_TYPE_UNKNOWN;
|
||||
NetworkPreference network_preference = NetworkPreference::NEUTRAL;
|
||||
if (cursor->ifa_flags & IFF_LOOPBACK) {
|
||||
adapter_type = ADAPTER_TYPE_LOOPBACK;
|
||||
} else {
|
||||
|
@ -543,6 +552,8 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
|||
// Otherwise, get the adapter type based on a few name matching rules.
|
||||
if (network_monitor_) {
|
||||
adapter_type = network_monitor_->GetAdapterType(cursor->ifa_name);
|
||||
network_preference =
|
||||
network_monitor_->GetNetworkPreference(cursor->ifa_name);
|
||||
}
|
||||
if (adapter_type == ADAPTER_TYPE_UNKNOWN) {
|
||||
adapter_type = GetAdapterTypeFromName(cursor->ifa_name);
|
||||
|
@ -568,6 +579,7 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
|||
network->AddIP(ip);
|
||||
network->set_ignored(IsIgnoredNetwork(*network));
|
||||
network->set_underlying_type_for_vpn(vpn_underlying_adapter_type);
|
||||
network->set_network_preference(network_preference);
|
||||
if (include_ignored || !network->ignored()) {
|
||||
current_networks[key] = network.get();
|
||||
networks->push_back(network.release());
|
||||
|
@ -580,6 +592,7 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
|||
existing_network->set_underlying_type_for_vpn(
|
||||
vpn_underlying_adapter_type);
|
||||
}
|
||||
existing_network->set_network_preference(network_preference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,6 +215,10 @@ class RTC_EXPORT NetworkManagerBase : public NetworkManager {
|
|||
// network id 0 because we only compare the network ids in the old and the new
|
||||
// best connections in the transport channel.
|
||||
uint16_t next_available_network_id_ = 1;
|
||||
|
||||
// True if calling network_preference() with a changed value
|
||||
// should result in firing the SignalNetworkChanged signal.
|
||||
bool signal_network_preference_change_ = false;
|
||||
};
|
||||
|
||||
// Basic implementation of the NetworkManager interface that gets list
|
||||
|
@ -306,9 +310,13 @@ class RTC_EXPORT Network {
|
|||
AdapterType type);
|
||||
Network(const Network&);
|
||||
~Network();
|
||||
|
||||
// This signal is fired whenever type() or underlying_type_for_vpn() changes.
|
||||
sigslot::signal1<const Network*> SignalTypeChanged;
|
||||
|
||||
// This signal is fired whenever network preference changes.
|
||||
sigslot::signal1<const Network*> SignalNetworkPreferenceChanged;
|
||||
|
||||
const DefaultLocalAddressProvider* default_local_address_provider() {
|
||||
return default_local_address_provider_;
|
||||
}
|
||||
|
@ -453,6 +461,17 @@ class RTC_EXPORT Network {
|
|||
}
|
||||
}
|
||||
|
||||
// Property set by operating system/firmware that has information
|
||||
// about connection strength to e.g WIFI router or CELL base towers.
|
||||
NetworkPreference network_preference() const { return network_preference_; }
|
||||
void set_network_preference(NetworkPreference val) {
|
||||
if (network_preference_ == val) {
|
||||
return;
|
||||
}
|
||||
network_preference_ = val;
|
||||
SignalNetworkPreferenceChanged(this);
|
||||
}
|
||||
|
||||
// Debugging description of this network
|
||||
std::string ToString() const;
|
||||
|
||||
|
@ -473,6 +492,7 @@ class RTC_EXPORT Network {
|
|||
bool active_ = true;
|
||||
uint16_t id_ = 0;
|
||||
bool use_differentiated_cellular_costs_ = false;
|
||||
NetworkPreference network_preference_ = NetworkPreference::NEUTRAL;
|
||||
|
||||
friend class NetworkManager;
|
||||
};
|
||||
|
|
|
@ -30,6 +30,14 @@ enum class NetworkBindingResult {
|
|||
NETWORK_CHANGED = -4
|
||||
};
|
||||
|
||||
// NetworkPreference property set by operating system/firmware that has
|
||||
// information about connection strength to e.g WIFI router or CELL base towers.
|
||||
// GENERATED_JAVA_ENUM_PACKAGE: org.webrtc
|
||||
enum class NetworkPreference {
|
||||
NEUTRAL = 0,
|
||||
NOT_PREFERRED = -1,
|
||||
};
|
||||
|
||||
class NetworkBinderInterface {
|
||||
public:
|
||||
// Binds a socket to the network that is attached to |address| so that all
|
||||
|
@ -78,6 +86,8 @@ class NetworkMonitorInterface {
|
|||
virtual AdapterType GetAdapterType(const std::string& interface_name) = 0;
|
||||
virtual AdapterType GetVpnUnderlyingAdapterType(
|
||||
const std::string& interface_name) = 0;
|
||||
virtual NetworkPreference GetNetworkPreference(
|
||||
const std::string& interface_name) = 0;
|
||||
};
|
||||
|
||||
class NetworkMonitorBase : public NetworkMonitorInterface,
|
||||
|
|
|
@ -57,6 +57,9 @@ class FakeNetworkMonitor : public NetworkMonitorBase {
|
|||
}
|
||||
return ADAPTER_TYPE_UNKNOWN;
|
||||
}
|
||||
NetworkPreference GetNetworkPreference(const std::string& if_name) override {
|
||||
return NetworkPreference::NEUTRAL;
|
||||
}
|
||||
|
||||
private:
|
||||
bool started_ = false;
|
||||
|
|
|
@ -276,12 +276,13 @@ if (is_android) {
|
|||
"api/org/webrtc/NativeLibraryLoader.java",
|
||||
"api/org/webrtc/NativePeerConnectionFactory.java",
|
||||
"api/org/webrtc/NetEqFactoryFactory.java",
|
||||
"api/org/webrtc/NetworkChangeDetector.java",
|
||||
"api/org/webrtc/NetworkChangeDetectorFactory.java",
|
||||
"api/org/webrtc/NetworkControllerFactoryFactory.java",
|
||||
"api/org/webrtc/NetworkMonitor.java", # TODO(sakal): Break dependencies
|
||||
# and move to base_java.
|
||||
"api/org/webrtc/NetworkMonitorAutoDetect.java", # TODO(sakal): Break
|
||||
# dependencies and move
|
||||
# to base_java.
|
||||
|
||||
# TODO(sakal): Break dependencies and move to base_java.
|
||||
"api/org/webrtc/NetworkMonitor.java",
|
||||
"api/org/webrtc/NetworkMonitorAutoDetect.java",
|
||||
"api/org/webrtc/NetworkStatePredictorFactoryFactory.java",
|
||||
"api/org/webrtc/PeerConnection.java",
|
||||
"api/org/webrtc/PeerConnectionDependencies.java",
|
||||
|
@ -328,6 +329,7 @@ if (is_android) {
|
|||
srcjar_deps = [
|
||||
"//api:priority_enums",
|
||||
"//api/video:video_frame_enums",
|
||||
"//rtc_base:network_monitor_enums",
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -1171,8 +1173,8 @@ if (current_os == "linux" || is_android) {
|
|||
|
||||
generate_jni("generated_base_jni") {
|
||||
sources = [
|
||||
"api/org/webrtc/NetworkChangeDetector.java",
|
||||
"api/org/webrtc/NetworkMonitor.java",
|
||||
"api/org/webrtc/NetworkMonitorAutoDetect.java",
|
||||
"api/org/webrtc/RefCounted.java",
|
||||
"src/java/org/webrtc/Histogram.java",
|
||||
"src/java/org/webrtc/JniCommon.java",
|
||||
|
|
116
sdk/android/api/org/webrtc/NetworkChangeDetector.java
Normal file
116
sdk/android/api/org/webrtc/NetworkChangeDetector.java
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/** Interface for detecting network changes */
|
||||
public interface NetworkChangeDetector {
|
||||
// java equivalent of c++ android_network_monitor.h / NetworkType.
|
||||
public static enum ConnectionType {
|
||||
CONNECTION_UNKNOWN,
|
||||
CONNECTION_ETHERNET,
|
||||
CONNECTION_WIFI,
|
||||
CONNECTION_5G,
|
||||
CONNECTION_4G,
|
||||
CONNECTION_3G,
|
||||
CONNECTION_2G,
|
||||
CONNECTION_UNKNOWN_CELLULAR,
|
||||
CONNECTION_BLUETOOTH,
|
||||
CONNECTION_VPN,
|
||||
CONNECTION_NONE
|
||||
}
|
||||
|
||||
public static class IPAddress {
|
||||
public final byte[] address;
|
||||
|
||||
public IPAddress(byte[] address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@CalledByNative("IPAddress")
|
||||
private byte[] getAddress() {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
/** Java version of NetworkMonitor.NetworkInformation */
|
||||
public static class NetworkInformation {
|
||||
public final String name;
|
||||
public final ConnectionType type;
|
||||
// Used to specify the underlying network type if the type is CONNECTION_VPN.
|
||||
public final ConnectionType underlyingTypeForVpn;
|
||||
public final long handle;
|
||||
public final IPAddress[] ipAddresses;
|
||||
|
||||
public NetworkInformation(String name, ConnectionType type, ConnectionType underlyingTypeForVpn,
|
||||
long handle, IPAddress[] addresses) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.underlyingTypeForVpn = underlyingTypeForVpn;
|
||||
this.handle = handle;
|
||||
this.ipAddresses = addresses;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private IPAddress[] getIpAddresses() {
|
||||
return ipAddresses;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private ConnectionType getConnectionType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private ConnectionType getUnderlyingConnectionTypeForVpn() {
|
||||
return underlyingTypeForVpn;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private long getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private String getName() {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
/** Observer interface by which observer is notified of network changes. */
|
||||
public static interface Observer {
|
||||
/** Called when default network changes. */
|
||||
public void onConnectionTypeChanged(ConnectionType newConnectionType);
|
||||
|
||||
public void onNetworkConnect(NetworkInformation networkInfo);
|
||||
|
||||
public void onNetworkDisconnect(long networkHandle);
|
||||
|
||||
/**
|
||||
* Called when network preference change for a (list of) connection type(s). (e.g WIFI) is
|
||||
* |NOT_PREFERRED| or |NEUTRAL|.
|
||||
*
|
||||
* <p>note: |types| is a list of ConnectionTypes, so that all cellular types can be modified in
|
||||
* one call.
|
||||
*/
|
||||
public void onNetworkPreference(List<ConnectionType> types, @NetworkPreference int preference);
|
||||
}
|
||||
|
||||
public ConnectionType getCurrentConnectionType();
|
||||
|
||||
public boolean supportNetworkCallback();
|
||||
|
||||
@Nullable public List<NetworkInformation> getActiveNetworkList();
|
||||
|
||||
public void destroy();
|
||||
}
|
17
sdk/android/api/org/webrtc/NetworkChangeDetectorFactory.java
Normal file
17
sdk/android/api/org/webrtc/NetworkChangeDetectorFactory.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public interface NetworkChangeDetectorFactory {
|
||||
public NetworkChangeDetector create(NetworkChangeDetector.Observer observer, Context context);
|
||||
}
|
|
@ -10,14 +10,12 @@
|
|||
|
||||
package org.webrtc;
|
||||
|
||||
import static org.webrtc.NetworkMonitorAutoDetect.INVALID_NET_ID;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.webrtc.NetworkMonitorAutoDetect;
|
||||
import org.webrtc.NetworkChangeDetector;
|
||||
|
||||
/**
|
||||
* Borrowed from Chromium's
|
||||
|
@ -32,7 +30,7 @@ public class NetworkMonitor {
|
|||
* Alerted when the connection type of the network changes. The alert is fired on the UI thread.
|
||||
*/
|
||||
public interface NetworkObserver {
|
||||
public void onConnectionTypeChanged(NetworkMonitorAutoDetect.ConnectionType connectionType);
|
||||
public void onConnectionTypeChanged(NetworkChangeDetector.ConnectionType connectionType);
|
||||
}
|
||||
|
||||
private static final String TAG = "NetworkMonitor";
|
||||
|
@ -43,24 +41,43 @@ public class NetworkMonitor {
|
|||
static final NetworkMonitor instance = new NetworkMonitor();
|
||||
}
|
||||
|
||||
// Factory for creating NetworkChangeDetector.
|
||||
private NetworkChangeDetectorFactory networkChangeDetectorFactory =
|
||||
new NetworkChangeDetectorFactory() {
|
||||
@Override
|
||||
public NetworkChangeDetector create(
|
||||
NetworkChangeDetector.Observer observer, Context context) {
|
||||
return new NetworkMonitorAutoDetect(observer, context);
|
||||
}
|
||||
};
|
||||
|
||||
// Native observers of the connection type changes.
|
||||
private final ArrayList<Long> nativeNetworkObservers;
|
||||
// Java observers of the connection type changes.
|
||||
private final ArrayList<NetworkObserver> networkObservers;
|
||||
|
||||
private final Object autoDetectLock = new Object();
|
||||
private final Object networkChangeDetectorLock = new Object();
|
||||
// Object that detects the connection type changes and brings up mobile networks.
|
||||
@Nullable private NetworkMonitorAutoDetect autoDetect;
|
||||
@Nullable private NetworkChangeDetector networkChangeDetector;
|
||||
// Also guarded by autoDetectLock.
|
||||
private int numObservers;
|
||||
|
||||
private volatile NetworkMonitorAutoDetect.ConnectionType currentConnectionType;
|
||||
private volatile NetworkChangeDetector.ConnectionType currentConnectionType;
|
||||
|
||||
private NetworkMonitor() {
|
||||
nativeNetworkObservers = new ArrayList<Long>();
|
||||
networkObservers = new ArrayList<NetworkObserver>();
|
||||
numObservers = 0;
|
||||
currentConnectionType = NetworkMonitorAutoDetect.ConnectionType.CONNECTION_UNKNOWN;
|
||||
currentConnectionType = NetworkChangeDetector.ConnectionType.CONNECTION_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the factory that will be used to create the network change detector.
|
||||
* Needs to be called before the monitoring is starts.
|
||||
*/
|
||||
public void setNetworkChangeDetectorFactory(NetworkChangeDetectorFactory factory) {
|
||||
assertIsTrue(numObservers == 0);
|
||||
this.networkChangeDetectorFactory = factory;
|
||||
}
|
||||
|
||||
// TODO(sakal): Remove once downstream dependencies have been updated.
|
||||
|
@ -85,13 +102,12 @@ public class NetworkMonitor {
|
|||
* CHANGE_NETWORK_STATE permission.
|
||||
*/
|
||||
public void startMonitoring(Context applicationContext) {
|
||||
synchronized (autoDetectLock) {
|
||||
synchronized (networkChangeDetectorLock) {
|
||||
++numObservers;
|
||||
if (autoDetect == null) {
|
||||
autoDetect = createAutoDetect(applicationContext);
|
||||
if (networkChangeDetector == null) {
|
||||
networkChangeDetector = createNetworkChangeDetector(applicationContext);
|
||||
}
|
||||
currentConnectionType =
|
||||
NetworkMonitorAutoDetect.getConnectionType(autoDetect.getCurrentNetworkState());
|
||||
currentConnectionType = networkChangeDetector.getCurrentConnectionType();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,12 +138,15 @@ public class NetworkMonitor {
|
|||
notifyObserversOfConnectionTypeChange(currentConnectionType);
|
||||
}
|
||||
|
||||
/** Stop network monitoring. If no one is monitoring networks, destroy and reset autoDetect. */
|
||||
/**
|
||||
* Stop network monitoring. If no one is monitoring networks, destroy and reset
|
||||
* networkChangeDetector.
|
||||
*/
|
||||
public void stopMonitoring() {
|
||||
synchronized (autoDetectLock) {
|
||||
synchronized (networkChangeDetectorLock) {
|
||||
if (--numObservers == 0) {
|
||||
autoDetect.destroy();
|
||||
autoDetect = null;
|
||||
networkChangeDetector.destroy();
|
||||
networkChangeDetector = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,8 +163,8 @@ public class NetworkMonitor {
|
|||
// Returns true if network binding is supported on this platform.
|
||||
@CalledByNative
|
||||
private boolean networkBindingSupported() {
|
||||
synchronized (autoDetectLock) {
|
||||
return autoDetect != null && autoDetect.supportNetworkCallback();
|
||||
synchronized (networkChangeDetectorLock) {
|
||||
return networkChangeDetector != null && networkChangeDetector.supportNetworkCallback();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,27 +173,19 @@ public class NetworkMonitor {
|
|||
return Build.VERSION.SDK_INT;
|
||||
}
|
||||
|
||||
private NetworkMonitorAutoDetect.ConnectionType getCurrentConnectionType() {
|
||||
private NetworkChangeDetector.ConnectionType getCurrentConnectionType() {
|
||||
return currentConnectionType;
|
||||
}
|
||||
|
||||
private long getCurrentDefaultNetId() {
|
||||
synchronized (autoDetectLock) {
|
||||
return autoDetect == null ? INVALID_NET_ID : autoDetect.getDefaultNetId();
|
||||
}
|
||||
}
|
||||
|
||||
private NetworkMonitorAutoDetect createAutoDetect(Context appContext) {
|
||||
return new NetworkMonitorAutoDetect(new NetworkMonitorAutoDetect.Observer() {
|
||||
|
||||
private NetworkChangeDetector createNetworkChangeDetector(Context appContext) {
|
||||
return networkChangeDetectorFactory.create(new NetworkChangeDetector.Observer() {
|
||||
@Override
|
||||
public void onConnectionTypeChanged(
|
||||
NetworkMonitorAutoDetect.ConnectionType newConnectionType) {
|
||||
public void onConnectionTypeChanged(NetworkChangeDetector.ConnectionType newConnectionType) {
|
||||
updateCurrentConnectionType(newConnectionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkConnect(NetworkMonitorAutoDetect.NetworkInformation networkInfo) {
|
||||
public void onNetworkConnect(NetworkChangeDetector.NetworkInformation networkInfo) {
|
||||
notifyObserversOfNetworkConnect(networkInfo);
|
||||
}
|
||||
|
||||
|
@ -182,18 +193,23 @@ public class NetworkMonitor {
|
|||
public void onNetworkDisconnect(long networkHandle) {
|
||||
notifyObserversOfNetworkDisconnect(networkHandle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkPreference(
|
||||
List<NetworkChangeDetector.ConnectionType> types, int preference) {
|
||||
notifyObserversOfNetworkPreference(types, preference);
|
||||
}
|
||||
}, appContext);
|
||||
}
|
||||
|
||||
private void updateCurrentConnectionType(
|
||||
NetworkMonitorAutoDetect.ConnectionType newConnectionType) {
|
||||
private void updateCurrentConnectionType(NetworkChangeDetector.ConnectionType newConnectionType) {
|
||||
currentConnectionType = newConnectionType;
|
||||
notifyObserversOfConnectionTypeChange(newConnectionType);
|
||||
}
|
||||
|
||||
/** Alerts all observers of a connection change. */
|
||||
private void notifyObserversOfConnectionTypeChange(
|
||||
NetworkMonitorAutoDetect.ConnectionType newConnectionType) {
|
||||
NetworkChangeDetector.ConnectionType newConnectionType) {
|
||||
List<Long> nativeObservers = getNativeNetworkObserversSync();
|
||||
for (Long nativeObserver : nativeObservers) {
|
||||
nativeNotifyConnectionTypeChanged(nativeObserver);
|
||||
|
@ -209,7 +225,7 @@ public class NetworkMonitor {
|
|||
}
|
||||
|
||||
private void notifyObserversOfNetworkConnect(
|
||||
NetworkMonitorAutoDetect.NetworkInformation networkInfo) {
|
||||
NetworkChangeDetector.NetworkInformation networkInfo) {
|
||||
List<Long> nativeObservers = getNativeNetworkObserversSync();
|
||||
for (Long nativeObserver : nativeObservers) {
|
||||
nativeNotifyOfNetworkConnect(nativeObserver, networkInfo);
|
||||
|
@ -223,17 +239,28 @@ public class NetworkMonitor {
|
|||
}
|
||||
}
|
||||
|
||||
private void notifyObserversOfNetworkPreference(
|
||||
List<NetworkChangeDetector.ConnectionType> types, int preference) {
|
||||
List<Long> nativeObservers = getNativeNetworkObserversSync();
|
||||
for (NetworkChangeDetector.ConnectionType type : types) {
|
||||
for (Long nativeObserver : nativeObservers) {
|
||||
nativeNotifyOfNetworkPreference(nativeObserver, type, preference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateObserverActiveNetworkList(long nativeObserver) {
|
||||
List<NetworkMonitorAutoDetect.NetworkInformation> networkInfoList;
|
||||
synchronized (autoDetectLock) {
|
||||
networkInfoList = (autoDetect == null) ? null : autoDetect.getActiveNetworkList();
|
||||
List<NetworkChangeDetector.NetworkInformation> networkInfoList;
|
||||
synchronized (networkChangeDetectorLock) {
|
||||
networkInfoList =
|
||||
(networkChangeDetector == null) ? null : networkChangeDetector.getActiveNetworkList();
|
||||
}
|
||||
if (networkInfoList == null || networkInfoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkMonitorAutoDetect.NetworkInformation[] networkInfos =
|
||||
new NetworkMonitorAutoDetect.NetworkInformation[networkInfoList.size()];
|
||||
NetworkChangeDetector.NetworkInformation[] networkInfos =
|
||||
new NetworkChangeDetector.NetworkInformation[networkInfoList.size()];
|
||||
networkInfos = networkInfoList.toArray(networkInfos);
|
||||
nativeNotifyOfActiveNetworkList(nativeObserver, networkInfos);
|
||||
}
|
||||
|
@ -278,30 +305,35 @@ public class NetworkMonitor {
|
|||
|
||||
/** Checks if there currently is connectivity. */
|
||||
public static boolean isOnline() {
|
||||
NetworkMonitorAutoDetect.ConnectionType connectionType =
|
||||
getInstance().getCurrentConnectionType();
|
||||
return connectionType != NetworkMonitorAutoDetect.ConnectionType.CONNECTION_NONE;
|
||||
NetworkChangeDetector.ConnectionType connectionType = getInstance().getCurrentConnectionType();
|
||||
return connectionType != NetworkChangeDetector.ConnectionType.CONNECTION_NONE;
|
||||
}
|
||||
|
||||
private native void nativeNotifyConnectionTypeChanged(long nativeAndroidNetworkMonitor);
|
||||
|
||||
private native void nativeNotifyOfNetworkConnect(
|
||||
long nativeAndroidNetworkMonitor, NetworkMonitorAutoDetect.NetworkInformation networkInfo);
|
||||
long nativeAndroidNetworkMonitor, NetworkChangeDetector.NetworkInformation networkInfo);
|
||||
|
||||
private native void nativeNotifyOfNetworkDisconnect(
|
||||
long nativeAndroidNetworkMonitor, long networkHandle);
|
||||
|
||||
private native void nativeNotifyOfActiveNetworkList(
|
||||
long nativeAndroidNetworkMonitor, NetworkMonitorAutoDetect.NetworkInformation[] networkInfos);
|
||||
long nativeAndroidNetworkMonitor, NetworkChangeDetector.NetworkInformation[] networkInfos);
|
||||
|
||||
private native void nativeNotifyOfNetworkPreference(
|
||||
long nativeAndroidNetworkMonitor, NetworkChangeDetector.ConnectionType type, int preference);
|
||||
|
||||
// For testing only.
|
||||
@Nullable
|
||||
NetworkMonitorAutoDetect getNetworkMonitorAutoDetect() {
|
||||
synchronized (autoDetectLock) {
|
||||
return autoDetect;
|
||||
NetworkChangeDetector getNetworkChangeDetector() {
|
||||
synchronized (networkChangeDetectorLock) {
|
||||
return networkChangeDetector;
|
||||
}
|
||||
}
|
||||
|
||||
// For testing only.
|
||||
int getNumObservers() {
|
||||
synchronized (autoDetectLock) {
|
||||
synchronized (networkChangeDetectorLock) {
|
||||
return numObservers;
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +341,9 @@ public class NetworkMonitor {
|
|||
// For testing only.
|
||||
static NetworkMonitorAutoDetect createAndSetAutoDetectForTest(Context context) {
|
||||
NetworkMonitor networkMonitor = getInstance();
|
||||
NetworkMonitorAutoDetect autoDetect = networkMonitor.createAutoDetect(context);
|
||||
return networkMonitor.autoDetect = autoDetect;
|
||||
NetworkChangeDetector networkChangeDetector =
|
||||
networkMonitor.createNetworkChangeDetector(context);
|
||||
networkMonitor.networkChangeDetector = networkChangeDetector;
|
||||
return (NetworkMonitorAutoDetect) networkChangeDetector;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,80 +41,10 @@ import java.util.List;
|
|||
* Borrowed from Chromium's
|
||||
* src/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
|
||||
*
|
||||
* Used by the NetworkMonitor to listen to platform changes in connectivity.
|
||||
* Note that use of this class requires that the app have the platform
|
||||
* ACCESS_NETWORK_STATE permission.
|
||||
* <p>Used by the NetworkMonitor to listen to platform changes in connectivity. Note that use of
|
||||
* this class requires that the app have the platform ACCESS_NETWORK_STATE permission.
|
||||
*/
|
||||
public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
||||
public static enum ConnectionType {
|
||||
CONNECTION_UNKNOWN,
|
||||
CONNECTION_ETHERNET,
|
||||
CONNECTION_WIFI,
|
||||
CONNECTION_5G,
|
||||
CONNECTION_4G,
|
||||
CONNECTION_3G,
|
||||
CONNECTION_2G,
|
||||
CONNECTION_UNKNOWN_CELLULAR,
|
||||
CONNECTION_BLUETOOTH,
|
||||
CONNECTION_VPN,
|
||||
CONNECTION_NONE
|
||||
}
|
||||
|
||||
public static class IPAddress {
|
||||
public final byte[] address;
|
||||
public IPAddress(byte[] address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@CalledByNative("IPAddress")
|
||||
private byte[] getAddress() {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
/** Java version of NetworkMonitor.NetworkInformation */
|
||||
public static class NetworkInformation {
|
||||
public final String name;
|
||||
public final ConnectionType type;
|
||||
// Used to specify the underlying network type if the type is CONNECTION_VPN.
|
||||
public final ConnectionType underlyingTypeForVpn;
|
||||
public final long handle;
|
||||
public final IPAddress[] ipAddresses;
|
||||
public NetworkInformation(String name, ConnectionType type, ConnectionType underlyingTypeForVpn,
|
||||
long handle, IPAddress[] addresses) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.underlyingTypeForVpn = underlyingTypeForVpn;
|
||||
this.handle = handle;
|
||||
this.ipAddresses = addresses;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private IPAddress[] getIpAddresses() {
|
||||
return ipAddresses;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private ConnectionType getConnectionType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private ConnectionType getUnderlyingConnectionTypeForVpn() {
|
||||
return underlyingTypeForVpn;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private long getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
@CalledByNative("NetworkInformation")
|
||||
private String getName() {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
public class NetworkMonitorAutoDetect extends BroadcastReceiver implements NetworkChangeDetector {
|
||||
static class NetworkState {
|
||||
private final boolean connected;
|
||||
// Defined from ConnectivityManager.TYPE_XXX for non-mobile; for mobile, it is
|
||||
|
@ -410,8 +340,8 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
}
|
||||
|
||||
NetworkState networkState = getNetworkState(network);
|
||||
ConnectionType connectionType = getConnectionType(networkState);
|
||||
if (connectionType == ConnectionType.CONNECTION_NONE) {
|
||||
NetworkChangeDetector.ConnectionType connectionType = getConnectionType(networkState);
|
||||
if (connectionType == NetworkChangeDetector.ConnectionType.CONNECTION_NONE) {
|
||||
// This may not be an error. The OS may signal a network event with connection type
|
||||
// NONE when the network disconnects.
|
||||
Logging.d(TAG, "Network " + network.toString() + " is disconnected");
|
||||
|
@ -420,13 +350,14 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
|
||||
// Some android device may return a CONNECTION_UNKNOWN_CELLULAR or CONNECTION_UNKNOWN type,
|
||||
// which appears to be usable. Just log them here.
|
||||
if (connectionType == ConnectionType.CONNECTION_UNKNOWN
|
||||
|| connectionType == ConnectionType.CONNECTION_UNKNOWN_CELLULAR) {
|
||||
if (connectionType == NetworkChangeDetector.ConnectionType.CONNECTION_UNKNOWN
|
||||
|| connectionType == NetworkChangeDetector.ConnectionType.CONNECTION_UNKNOWN_CELLULAR) {
|
||||
Logging.d(TAG, "Network " + network.toString() + " connection type is " + connectionType
|
||||
+ " because it has type " + networkState.getNetworkType() + " and subtype "
|
||||
+ networkState.getNetworkSubType());
|
||||
}
|
||||
// ConnectionType.CONNECTION_UNKNOWN if the network is not a VPN or the underlying network is
|
||||
// NetworkChangeDetector.ConnectionType.CONNECTION_UNKNOWN if the network is not a VPN or the
|
||||
// underlying network is
|
||||
// unknown.
|
||||
ConnectionType underlyingConnectionTypeForVpn =
|
||||
getUnderlyingConnectionTypeForVpn(networkState);
|
||||
|
@ -529,12 +460,12 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
// (NETWORK_UNSPECIFIED) for these addresses.
|
||||
private static final int WIFI_P2P_NETWORK_HANDLE = 0;
|
||||
private final Context context;
|
||||
private final Observer observer;
|
||||
private final NetworkChangeDetector.Observer observer;
|
||||
// Network information about a WifiP2p (aka WiFi-Direct) network, or null if no such network is
|
||||
// connected.
|
||||
@Nullable private NetworkInformation wifiP2pNetworkInfo;
|
||||
|
||||
WifiDirectManagerDelegate(Observer observer, Context context) {
|
||||
WifiDirectManagerDelegate(NetworkChangeDetector.Observer observer, Context context) {
|
||||
this.context = context;
|
||||
this.observer = observer;
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
|
@ -599,9 +530,10 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
ipAddresses[i] = new IPAddress(interfaceAddresses.get(i).getAddress());
|
||||
}
|
||||
|
||||
wifiP2pNetworkInfo =
|
||||
new NetworkInformation(wifiP2pGroup.getInterface(), ConnectionType.CONNECTION_WIFI,
|
||||
ConnectionType.CONNECTION_NONE, WIFI_P2P_NETWORK_HANDLE, ipAddresses);
|
||||
wifiP2pNetworkInfo = new NetworkInformation(wifiP2pGroup.getInterface(),
|
||||
NetworkChangeDetector.ConnectionType.CONNECTION_WIFI,
|
||||
NetworkChangeDetector.ConnectionType.CONNECTION_NONE, WIFI_P2P_NETWORK_HANDLE,
|
||||
ipAddresses);
|
||||
observer.onNetworkConnect(wifiP2pNetworkInfo);
|
||||
}
|
||||
|
||||
|
@ -614,11 +546,11 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
static final long INVALID_NET_ID = -1;
|
||||
private static final long INVALID_NET_ID = -1;
|
||||
private static final String TAG = "NetworkMonitorAutoDetect";
|
||||
|
||||
// Observer for the connection type change.
|
||||
private final Observer observer;
|
||||
private final NetworkChangeDetector.Observer observer;
|
||||
private final IntentFilter intentFilter;
|
||||
private final Context context;
|
||||
// Used to request mobile network. It does not do anything except for keeping
|
||||
|
@ -632,26 +564,12 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
private WifiDirectManagerDelegate wifiDirectManagerDelegate;
|
||||
|
||||
private boolean isRegistered;
|
||||
private ConnectionType connectionType;
|
||||
private NetworkChangeDetector.ConnectionType connectionType;
|
||||
private String wifiSSID;
|
||||
|
||||
/**
|
||||
* Observer interface by which observer is notified of network changes.
|
||||
*/
|
||||
public static interface Observer {
|
||||
/**
|
||||
* Called when default network changes.
|
||||
*/
|
||||
public void onConnectionTypeChanged(ConnectionType newConnectionType);
|
||||
public void onNetworkConnect(NetworkInformation networkInfo);
|
||||
public void onNetworkDisconnect(long 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(NetworkChangeDetector.Observer observer, Context context) {
|
||||
this.observer = observer;
|
||||
this.context = context;
|
||||
connectivityManagerDelegate = new ConnectivityManagerDelegate(context);
|
||||
|
@ -686,6 +604,7 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportNetworkCallback() {
|
||||
return connectivityManagerDelegate.supportNetworkCallback();
|
||||
}
|
||||
|
@ -712,8 +631,9 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
return isRegistered;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
List<NetworkInformation> getActiveNetworkList() {
|
||||
public List<NetworkInformation> getActiveNetworkList() {
|
||||
List<NetworkInformation> connectivityManagerList =
|
||||
connectivityManagerDelegate.getActiveNetworkList();
|
||||
if (connectivityManagerList == null) {
|
||||
|
@ -727,6 +647,7 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (allNetworkCallback != null) {
|
||||
connectivityManagerDelegate.releaseCallback(allNetworkCallback);
|
||||
|
@ -776,21 +697,21 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
return connectivityManagerDelegate.getDefaultNetId();
|
||||
}
|
||||
|
||||
private static ConnectionType getConnectionType(
|
||||
private static NetworkChangeDetector.ConnectionType getConnectionType(
|
||||
boolean isConnected, int networkType, int networkSubtype) {
|
||||
if (!isConnected) {
|
||||
return ConnectionType.CONNECTION_NONE;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_NONE;
|
||||
}
|
||||
|
||||
switch (networkType) {
|
||||
case ConnectivityManager.TYPE_ETHERNET:
|
||||
return ConnectionType.CONNECTION_ETHERNET;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_ETHERNET;
|
||||
case ConnectivityManager.TYPE_WIFI:
|
||||
return ConnectionType.CONNECTION_WIFI;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_WIFI;
|
||||
case ConnectivityManager.TYPE_WIMAX:
|
||||
return ConnectionType.CONNECTION_4G;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_4G;
|
||||
case ConnectivityManager.TYPE_BLUETOOTH:
|
||||
return ConnectionType.CONNECTION_BLUETOOTH;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_BLUETOOTH;
|
||||
case ConnectivityManager.TYPE_MOBILE:
|
||||
// Use information from TelephonyManager to classify the connection.
|
||||
switch (networkSubtype) {
|
||||
|
@ -800,7 +721,7 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
case TelephonyManager.NETWORK_TYPE_1xRTT:
|
||||
case TelephonyManager.NETWORK_TYPE_IDEN:
|
||||
case TelephonyManager.NETWORK_TYPE_GSM:
|
||||
return ConnectionType.CONNECTION_2G;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_2G;
|
||||
case TelephonyManager.NETWORK_TYPE_UMTS:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_0:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_A:
|
||||
|
@ -811,30 +732,36 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
case TelephonyManager.NETWORK_TYPE_EHRPD:
|
||||
case TelephonyManager.NETWORK_TYPE_HSPAP:
|
||||
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
|
||||
return ConnectionType.CONNECTION_3G;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_3G;
|
||||
case TelephonyManager.NETWORK_TYPE_LTE:
|
||||
case TelephonyManager.NETWORK_TYPE_IWLAN:
|
||||
return ConnectionType.CONNECTION_4G;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_4G;
|
||||
case TelephonyManager.NETWORK_TYPE_NR:
|
||||
return ConnectionType.CONNECTION_5G;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_5G;
|
||||
default:
|
||||
return ConnectionType.CONNECTION_UNKNOWN_CELLULAR;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_UNKNOWN_CELLULAR;
|
||||
}
|
||||
case ConnectivityManager.TYPE_VPN:
|
||||
return ConnectionType.CONNECTION_VPN;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_VPN;
|
||||
default:
|
||||
return ConnectionType.CONNECTION_UNKNOWN;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static ConnectionType getConnectionType(NetworkState networkState) {
|
||||
public static NetworkChangeDetector.ConnectionType getConnectionType(NetworkState networkState) {
|
||||
return getConnectionType(networkState.isConnected(), networkState.getNetworkType(),
|
||||
networkState.getNetworkSubType());
|
||||
}
|
||||
|
||||
private static ConnectionType getUnderlyingConnectionTypeForVpn(NetworkState networkState) {
|
||||
@Override
|
||||
public NetworkChangeDetector.ConnectionType getCurrentConnectionType() {
|
||||
return getConnectionType(getCurrentNetworkState());
|
||||
}
|
||||
|
||||
private static NetworkChangeDetector.ConnectionType getUnderlyingConnectionTypeForVpn(
|
||||
NetworkState networkState) {
|
||||
if (networkState.getNetworkType() != ConnectivityManager.TYPE_VPN) {
|
||||
return ConnectionType.CONNECTION_NONE;
|
||||
return NetworkChangeDetector.ConnectionType.CONNECTION_NONE;
|
||||
}
|
||||
return getConnectionType(networkState.isConnected(),
|
||||
networkState.getUnderlyingNetworkTypeForVpn(),
|
||||
|
@ -842,7 +769,7 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
}
|
||||
|
||||
private String getWifiSSID(NetworkState networkState) {
|
||||
if (getConnectionType(networkState) != ConnectionType.CONNECTION_WIFI)
|
||||
if (getConnectionType(networkState) != NetworkChangeDetector.ConnectionType.CONNECTION_WIFI)
|
||||
return "";
|
||||
return wifiManagerDelegate.getWifiSSID();
|
||||
}
|
||||
|
@ -857,7 +784,7 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver {
|
|||
}
|
||||
|
||||
private void connectionTypeChanged(NetworkState networkState) {
|
||||
ConnectionType newConnectionType = getConnectionType(networkState);
|
||||
NetworkChangeDetector.ConnectionType newConnectionType = getConnectionType(networkState);
|
||||
String newWifiSSID = getWifiSSID(networkState);
|
||||
if (newConnectionType == connectionType && newWifiSSID.equals(wifiSSID))
|
||||
return;
|
||||
|
|
|
@ -15,7 +15,6 @@ import static org.junit.Assert.assertFalse;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.webrtc.NetworkMonitorAutoDetect.INVALID_NET_ID;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
|
@ -31,14 +30,15 @@ import android.support.test.annotation.UiThreadTest;
|
|||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.rule.UiThreadTestRule;
|
||||
import java.util.List;
|
||||
import org.chromium.base.test.BaseJUnit4ClassRunner;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.webrtc.NetworkMonitorAutoDetect.ConnectionType;
|
||||
import org.webrtc.NetworkChangeDetector.ConnectionType;
|
||||
import org.webrtc.NetworkChangeDetector.NetworkInformation;
|
||||
import org.webrtc.NetworkMonitorAutoDetect.ConnectivityManagerDelegate;
|
||||
import org.webrtc.NetworkMonitorAutoDetect.NetworkInformation;
|
||||
import org.webrtc.NetworkMonitorAutoDetect.NetworkState;
|
||||
|
||||
/**
|
||||
|
@ -53,6 +53,9 @@ import org.webrtc.NetworkMonitorAutoDetect.NetworkState;
|
|||
public class NetworkMonitorTest {
|
||||
@Rule public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();
|
||||
|
||||
private static final long INVALID_NET_ID = -1;
|
||||
private NetworkChangeDetector detector;
|
||||
|
||||
/**
|
||||
* Listens for alerts fired by the NetworkMonitor when network status changes.
|
||||
*/
|
||||
|
@ -155,6 +158,10 @@ public class NetworkMonitorTest {
|
|||
|
||||
@Override
|
||||
public void onNetworkDisconnect(long networkHandle) {}
|
||||
|
||||
@Override
|
||||
public void onNetworkPreference(List<ConnectionType> types, @NetworkPreference int preference) {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Object lock = new Object();
|
||||
|
@ -179,6 +186,17 @@ public class NetworkMonitorTest {
|
|||
*/
|
||||
private void createTestMonitor() {
|
||||
Context context = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
NetworkMonitor.getInstance().setNetworkChangeDetectorFactory(
|
||||
new NetworkChangeDetectorFactory() {
|
||||
@Override
|
||||
public NetworkChangeDetector create(
|
||||
NetworkChangeDetector.Observer observer, Context context) {
|
||||
detector = new NetworkMonitorAutoDetect(observer, context);
|
||||
return detector;
|
||||
}
|
||||
});
|
||||
|
||||
receiver = NetworkMonitor.createAndSetAutoDetectForTest(context);
|
||||
assertNotNull(receiver);
|
||||
|
||||
|
@ -311,9 +329,9 @@ public class NetworkMonitorTest {
|
|||
Context context = ContextUtils.getApplicationContext();
|
||||
networkMonitor.startMonitoring(context);
|
||||
assertEquals(1, networkMonitor.getNumObservers());
|
||||
assertNotNull(networkMonitor.getNetworkMonitorAutoDetect());
|
||||
assertEquals(detector, networkMonitor.getNetworkChangeDetector());
|
||||
networkMonitor.stopMonitoring();
|
||||
assertEquals(0, networkMonitor.getNumObservers());
|
||||
assertNull(networkMonitor.getNetworkMonitorAutoDetect());
|
||||
assertNull(networkMonitor.getNetworkChangeDetector());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "rtc_base/ip_address.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
#include "sdk/android/generated_base_jni/NetworkMonitorAutoDetect_jni.h"
|
||||
#include "sdk/android/generated_base_jni/NetworkChangeDetector_jni.h"
|
||||
#include "sdk/android/generated_base_jni/NetworkMonitor_jni.h"
|
||||
#include "sdk/android/native_api/jni/java_types.h"
|
||||
#include "sdk/android/src/jni/jni_helpers.h"
|
||||
|
@ -413,6 +413,17 @@ void AndroidNetworkMonitor::OnNetworkDisconnected_w(NetworkHandle handle) {
|
|||
}
|
||||
}
|
||||
|
||||
void AndroidNetworkMonitor::OnNetworkPreference(
|
||||
NetworkType type,
|
||||
rtc::NetworkPreference preference) {
|
||||
worker_thread()->Invoke<void>(RTC_FROM_HERE, [&] {
|
||||
auto adapter_type =
|
||||
AdapterTypeFromNetworkType(type, surface_cellular_types_);
|
||||
network_preference_by_adapter_type_[adapter_type] = preference;
|
||||
});
|
||||
OnNetworksChanged();
|
||||
}
|
||||
|
||||
void AndroidNetworkMonitor::SetNetworkInfos(
|
||||
const std::vector<NetworkInformation>& network_infos) {
|
||||
RTC_CHECK(thread_checker_.IsCurrent());
|
||||
|
@ -446,6 +457,29 @@ rtc::AdapterType AndroidNetworkMonitor::GetVpnUnderlyingAdapterType(
|
|||
return type;
|
||||
}
|
||||
|
||||
rtc::NetworkPreference AndroidNetworkMonitor::GetNetworkPreference(
|
||||
const std::string& if_name) {
|
||||
auto iter = adapter_type_by_name_.find(if_name);
|
||||
if (iter == adapter_type_by_name_.end()) {
|
||||
return rtc::NetworkPreference::NEUTRAL;
|
||||
}
|
||||
|
||||
rtc::AdapterType adapter_type = iter->second;
|
||||
if (adapter_type == rtc::ADAPTER_TYPE_VPN) {
|
||||
auto iter2 = vpn_underlying_adapter_type_by_name_.find(if_name);
|
||||
if (iter2 != vpn_underlying_adapter_type_by_name_.end()) {
|
||||
adapter_type = iter2->second;
|
||||
}
|
||||
}
|
||||
|
||||
auto preference_iter = network_preference_by_adapter_type_.find(adapter_type);
|
||||
if (preference_iter == network_preference_by_adapter_type_.end()) {
|
||||
return rtc::NetworkPreference::NEUTRAL;
|
||||
}
|
||||
|
||||
return preference_iter->second;
|
||||
}
|
||||
|
||||
AndroidNetworkMonitorFactory::AndroidNetworkMonitorFactory()
|
||||
: j_application_context_(nullptr) {}
|
||||
|
||||
|
@ -494,5 +528,16 @@ void AndroidNetworkMonitor::NotifyOfNetworkDisconnect(
|
|||
OnNetworkDisconnected(static_cast<NetworkHandle>(network_handle));
|
||||
}
|
||||
|
||||
void AndroidNetworkMonitor::NotifyOfNetworkPreference(
|
||||
JNIEnv* env,
|
||||
const JavaRef<jobject>& j_caller,
|
||||
const JavaRef<jobject>& j_connection_type,
|
||||
jint jpreference) {
|
||||
NetworkType type = GetNetworkTypeFromJava(env, j_connection_type);
|
||||
rtc::NetworkPreference preference =
|
||||
static_cast<rtc::NetworkPreference>(jpreference);
|
||||
OnNetworkPreference(type, preference);
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace jni {
|
|||
|
||||
typedef int64_t NetworkHandle;
|
||||
|
||||
// c++ equivalent of java NetworkMonitorAutoDetect.ConnectionType.
|
||||
// c++ equivalent of java NetworkChangeDetector.ConnectionType.
|
||||
enum NetworkType {
|
||||
NETWORK_UNKNOWN,
|
||||
NETWORK_ETHERNET,
|
||||
|
@ -80,8 +80,13 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
|
|||
rtc::AdapterType GetAdapterType(const std::string& if_name) override;
|
||||
rtc::AdapterType GetVpnUnderlyingAdapterType(
|
||||
const std::string& if_name) override;
|
||||
rtc::NetworkPreference GetNetworkPreference(
|
||||
const std::string& if_name) override;
|
||||
|
||||
void OnNetworkConnected(const NetworkInformation& network_info);
|
||||
void OnNetworkDisconnected(NetworkHandle network_handle);
|
||||
void OnNetworkPreference(NetworkType type, rtc::NetworkPreference preference);
|
||||
|
||||
// Always expected to be called on the network thread.
|
||||
void SetNetworkInfos(const std::vector<NetworkInformation>& network_infos);
|
||||
|
||||
|
@ -96,6 +101,10 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
|
|||
void NotifyOfActiveNetworkList(JNIEnv* env,
|
||||
const JavaRef<jobject>& j_caller,
|
||||
const JavaRef<jobjectArray>& j_network_infos);
|
||||
void NotifyOfNetworkPreference(JNIEnv* env,
|
||||
const JavaRef<jobject>& j_caller,
|
||||
const JavaRef<jobject>& j_connection_type,
|
||||
jint preference);
|
||||
|
||||
// Visible for testing.
|
||||
absl::optional<NetworkHandle> FindNetworkHandleFromAddress(
|
||||
|
@ -114,6 +123,8 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
|
|||
std::map<std::string, rtc::AdapterType> vpn_underlying_adapter_type_by_name_;
|
||||
std::map<rtc::IPAddress, NetworkHandle> network_handle_by_address_;
|
||||
std::map<NetworkHandle, NetworkInformation> network_info_by_handle_;
|
||||
std::map<rtc::AdapterType, rtc::NetworkPreference>
|
||||
network_preference_by_adapter_type_;
|
||||
bool find_network_handle_without_ipv6_temporary_part_;
|
||||
bool surface_cellular_types_;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue