Get rid of NetworkMonitorBase helper class.

All it provides is a method to call a signal on the network thread,
so it's not worth the added complexity. Implementations of
NetworkMonitorInterface must hop to the network thread anyway to
guard their members.

Also added some thread annotations to AndroidNetworkMonitor.

Bug: webrtc:9883
Change-Id: I64bb82ea593433f3a52871dbb75eb2ac4f47d69c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/181420
Commit-Queue: Taylor <deadbeef@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32087}
This commit is contained in:
Taylor Brandstetter 2020-09-11 17:15:30 +00:00 committed by Commit Bot
parent ef8507d106
commit 32eb03a1fb
7 changed files with 116 additions and 123 deletions

View File

@ -10,40 +10,18 @@
#include "rtc_base/network_monitor.h"
#include <stdint.h>
#include "rtc_base/checks.h"
#include "rtc_base/location.h"
#include "rtc_base/logging.h"
namespace {
const uint32_t UPDATE_NETWORKS_MESSAGE = 1;
} // namespace
namespace rtc {
NetworkMonitorInterface::NetworkMonitorInterface() {}
const char* NetworkPreferenceToString(NetworkPreference preference) {
switch (preference) {
case NetworkPreference::NEUTRAL:
return "NEUTRAL";
case NetworkPreference::NOT_PREFERRED:
return "NOT_PREFERRED";
}
}
NetworkMonitorInterface::NetworkMonitorInterface() {}
NetworkMonitorInterface::~NetworkMonitorInterface() {}
NetworkMonitorBase::NetworkMonitorBase()
: MessageHandler(false), worker_thread_(Thread::Current()) {}
NetworkMonitorBase::~NetworkMonitorBase() {
worker_thread_->Clear(this);
}
void NetworkMonitorBase::OnNetworksChanged() {
RTC_LOG(LS_VERBOSE) << "Network change is received at the network monitor";
worker_thread_->Post(RTC_FROM_HERE, this, UPDATE_NETWORKS_MESSAGE);
}
void NetworkMonitorBase::OnMessage(Message* msg) {
RTC_DCHECK(msg->message_id == UPDATE_NETWORKS_MESSAGE);
SignalNetworksChanged();
}
AdapterType NetworkMonitorBase::GetVpnUnderlyingAdapterType(
const std::string& interface_name) {
return ADAPTER_TYPE_UNKNOWN;
}
} // namespace rtc

View File

@ -13,7 +13,6 @@
#include "rtc_base/network_constants.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
namespace rtc {
@ -35,6 +34,8 @@ enum class NetworkPreference {
NOT_PREFERRED = -1,
};
const char* NetworkPreferenceToString(NetworkPreference preference);
class NetworkBinderInterface {
public:
// Binds a socket to the network that is attached to |address| so that all
@ -75,12 +76,6 @@ class NetworkMonitorInterface {
virtual void Start() = 0;
virtual void Stop() = 0;
// Implementations should call this method on the base when networks change,
// and the base will fire SignalNetworksChanged on the right thread.
// TODO(deadbeef): This is an implementation detail of NetworkMonitorBase,
// it doesn't belong here.
virtual void OnNetworksChanged() = 0;
virtual AdapterType GetAdapterType(const std::string& interface_name) = 0;
virtual AdapterType GetVpnUnderlyingAdapterType(
const std::string& interface_name) = 0;
@ -102,30 +97,6 @@ class NetworkMonitorInterface {
}
};
// TODO(deadbeef): This class has marginal value, all it does is post a task
// to call SignalNetworksChanged on the worker thread. Should fold it into
// AndroidNetworkMonitor.
class NetworkMonitorBase : public NetworkMonitorInterface,
public MessageHandler,
public sigslot::has_slots<> {
public:
NetworkMonitorBase();
~NetworkMonitorBase() override;
void OnNetworksChanged() override;
void OnMessage(Message* msg) override;
AdapterType GetVpnUnderlyingAdapterType(
const std::string& interface_name) override;
protected:
Thread* worker_thread() { return worker_thread_; }
private:
Thread* worker_thread_;
};
} // namespace rtc
#endif // RTC_BASE_NETWORK_MONITOR_H_

View File

@ -43,7 +43,7 @@ namespace rtc {
namespace {
class FakeNetworkMonitor : public NetworkMonitorBase {
class FakeNetworkMonitor : public NetworkMonitorInterface {
public:
void Start() override { started_ = true; }
void Stop() override { started_ = false; }
@ -59,6 +59,9 @@ class FakeNetworkMonitor : public NetworkMonitorBase {
}
return ADAPTER_TYPE_UNKNOWN;
}
AdapterType GetVpnUnderlyingAdapterType(const std::string& if_name) override {
return ADAPTER_TYPE_UNKNOWN;
}
NetworkPreference GetNetworkPreference(const std::string& if_name) override {
return NetworkPreference::NEUTRAL;
}
@ -1098,7 +1101,7 @@ TEST_F(NetworkTest, TestNetworkMonitoring) {
ClearNetworks(manager);
// Network manager is started, so the callback is called when the network
// monitor fires the network-change event.
network_monitor->OnNetworksChanged();
network_monitor->SignalNetworksChanged();
EXPECT_TRUE_WAIT(callback_called_, 1000);
// Network manager is stopped.

View File

@ -559,6 +559,7 @@ if (current_os == "linux" || is_android) {
"../../rtc_base",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base/synchronization:sequence_checker",
"../../system_wrappers:field_trial",
"../../system_wrappers:metrics",
]

View File

@ -21,6 +21,7 @@
#include "rtc_base/ip_address.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/sequence_checker.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"
@ -30,6 +31,37 @@
namespace webrtc {
namespace jni {
namespace {
const char* NetworkTypeToString(NetworkType type) {
switch (type) {
case NETWORK_UNKNOWN:
return "UNKNOWN";
case NETWORK_ETHERNET:
return "ETHERNET";
case NETWORK_WIFI:
return "WIFI";
case NETWORK_5G:
return "5G";
case NETWORK_4G:
return "4G";
case NETWORK_3G:
return "3G";
case NETWORK_2G:
return "2G";
case NETWORK_UNKNOWN_CELLULAR:
return "UNKNOWN_CELLULAR";
case NETWORK_BLUETOOTH:
return "BLUETOOTH";
case NETWORK_VPN:
return "VPN";
case NETWORK_NONE:
return "NONE";
}
}
} // namespace
enum AndroidSdkVersion {
SDK_VERSION_LOLLIPOP = 21,
SDK_VERSION_MARSHMALLOW = 23
@ -196,12 +228,13 @@ AndroidNetworkMonitor::AndroidNetworkMonitor(
const JavaRef<jobject>& j_application_context)
: android_sdk_int_(Java_NetworkMonitor_androidSdkInt(env)),
j_application_context_(env, j_application_context),
j_network_monitor_(env, Java_NetworkMonitor_getInstance(env)) {}
j_network_monitor_(env, Java_NetworkMonitor_getInstance(env)),
network_thread_(rtc::Thread::Current()) {}
AndroidNetworkMonitor::~AndroidNetworkMonitor() = default;
void AndroidNetworkMonitor::Start() {
RTC_CHECK(thread_checker_.IsCurrent());
RTC_DCHECK_RUN_ON(network_thread_);
if (started_) {
return;
}
@ -215,7 +248,7 @@ void AndroidNetworkMonitor::Start() {
// This is kind of magic behavior, but doing this allows the SocketServer to
// use this as a NetworkBinder to bind sockets on a particular network when
// it creates sockets.
worker_thread()->socketserver()->set_network_binder(this);
network_thread_->socketserver()->set_network_binder(this);
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_NetworkMonitor_startMonitoring(
@ -223,7 +256,7 @@ void AndroidNetworkMonitor::Start() {
}
void AndroidNetworkMonitor::Stop() {
RTC_CHECK(thread_checker_.IsCurrent());
RTC_DCHECK_RUN_ON(network_thread_);
if (!started_) {
return;
}
@ -232,8 +265,8 @@ void AndroidNetworkMonitor::Stop() {
// Once the network monitor stops, it will clear all network information and
// it won't find the network handle to bind anyway.
if (worker_thread()->socketserver()->network_binder() == this) {
worker_thread()->socketserver()->set_network_binder(nullptr);
if (network_thread_->socketserver()->network_binder() == this) {
network_thread_->socketserver()->set_network_binder(nullptr);
}
JNIEnv* env = AttachCurrentThreadIfNeeded();
@ -249,7 +282,7 @@ void AndroidNetworkMonitor::Stop() {
rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork(
int socket_fd,
const rtc::IPAddress& address) {
RTC_CHECK(thread_checker_.IsCurrent());
RTC_DCHECK_RUN_ON(network_thread_);
// Android prior to Lollipop didn't have support for binding sockets to
// networks. This may also occur if there is no connectivity manager
@ -346,17 +379,9 @@ rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork(
return rtc::NetworkBindingResult::FAILURE;
}
void AndroidNetworkMonitor::OnNetworkConnected(
const NetworkInformation& network_info) {
worker_thread()->Invoke<void>(
RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkConnected_w,
this, network_info));
// Fire SignalNetworksChanged to update the list of networks.
OnNetworksChanged();
}
void AndroidNetworkMonitor::OnNetworkConnected_w(
void AndroidNetworkMonitor::OnNetworkConnected_n(
const NetworkInformation& network_info) {
RTC_DCHECK_RUN_ON(network_thread_);
RTC_LOG(LS_INFO) << "Network connected: " << network_info.ToString();
adapter_type_by_name_[network_info.interface_name] =
AdapterTypeFromNetworkType(network_info.type, surface_cellular_types_);
@ -369,11 +394,13 @@ void AndroidNetworkMonitor::OnNetworkConnected_w(
for (const rtc::IPAddress& address : network_info.ip_addresses) {
network_handle_by_address_[address] = network_info.handle;
}
SignalNetworksChanged();
}
absl::optional<NetworkHandle>
AndroidNetworkMonitor::FindNetworkHandleFromAddress(
const rtc::IPAddress& ip_address) const {
RTC_DCHECK_RUN_ON(network_thread_);
RTC_LOG(LS_INFO) << "Find network handle.";
if (find_network_handle_without_ipv6_temporary_part_) {
for (auto const& iter : network_info_by_handle_) {
@ -396,14 +423,9 @@ AndroidNetworkMonitor::FindNetworkHandleFromAddress(
}
}
void AndroidNetworkMonitor::OnNetworkDisconnected(NetworkHandle handle) {
void AndroidNetworkMonitor::OnNetworkDisconnected_n(NetworkHandle handle) {
RTC_DCHECK_RUN_ON(network_thread_);
RTC_LOG(LS_INFO) << "Network disconnected for handle " << handle;
worker_thread()->Invoke<void>(
RTC_FROM_HERE,
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) {
@ -413,31 +435,33 @@ void AndroidNetworkMonitor::OnNetworkDisconnected_w(NetworkHandle handle) {
}
}
void AndroidNetworkMonitor::OnNetworkPreference(
void AndroidNetworkMonitor::OnNetworkPreference_n(
NetworkType type,
rtc::NetworkPreference preference) {
worker_thread()->Invoke<void>(RTC_FROM_HERE, [&] {
auto adapter_type =
AdapterTypeFromNetworkType(type, surface_cellular_types_);
RTC_DCHECK_RUN_ON(network_thread_);
RTC_LOG(LS_INFO) << "Android network monitor preference for "
<< NetworkTypeToString(type) << " changed to "
<< rtc::NetworkPreferenceToString(preference);
auto adapter_type = AdapterTypeFromNetworkType(type, surface_cellular_types_);
network_preference_by_adapter_type_[adapter_type] = preference;
});
OnNetworksChanged();
SignalNetworksChanged();
}
void AndroidNetworkMonitor::SetNetworkInfos(
const std::vector<NetworkInformation>& network_infos) {
RTC_CHECK(thread_checker_.IsCurrent());
RTC_DCHECK_RUN_ON(network_thread_);
network_handle_by_address_.clear();
network_info_by_handle_.clear();
RTC_LOG(LS_INFO) << "Android network monitor found " << network_infos.size()
<< " networks";
for (const NetworkInformation& network : network_infos) {
OnNetworkConnected_w(network);
OnNetworkConnected_n(network);
}
}
rtc::AdapterType AndroidNetworkMonitor::GetAdapterType(
const std::string& if_name) {
RTC_DCHECK_RUN_ON(network_thread_);
auto iter = adapter_type_by_name_.find(if_name);
rtc::AdapterType type = (iter == adapter_type_by_name_.end())
? rtc::ADAPTER_TYPE_UNKNOWN
@ -450,6 +474,7 @@ rtc::AdapterType AndroidNetworkMonitor::GetAdapterType(
rtc::AdapterType AndroidNetworkMonitor::GetVpnUnderlyingAdapterType(
const std::string& if_name) {
RTC_DCHECK_RUN_ON(network_thread_);
auto iter = vpn_underlying_adapter_type_by_name_.find(if_name);
rtc::AdapterType type = (iter == vpn_underlying_adapter_type_by_name_.end())
? rtc::ADAPTER_TYPE_UNKNOWN
@ -459,6 +484,7 @@ rtc::AdapterType AndroidNetworkMonitor::GetVpnUnderlyingAdapterType(
rtc::NetworkPreference AndroidNetworkMonitor::GetNetworkPreference(
const std::string& if_name) {
RTC_DCHECK_RUN_ON(network_thread_);
auto iter = adapter_type_by_name_.find(if_name);
if (iter == adapter_type_by_name_.end()) {
return rtc::NetworkPreference::NEUTRAL;
@ -499,7 +525,11 @@ AndroidNetworkMonitorFactory::CreateNetworkMonitor() {
void AndroidNetworkMonitor::NotifyConnectionTypeChanged(
JNIEnv* env,
const JavaRef<jobject>& j_caller) {
OnNetworksChanged();
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, network_thread_, [this] {
RTC_LOG(LS_INFO)
<< "Android network monitor detected connection type change.";
SignalNetworksChanged();
});
}
void AndroidNetworkMonitor::NotifyOfActiveNetworkList(
@ -518,14 +548,19 @@ void AndroidNetworkMonitor::NotifyOfNetworkConnect(
const JavaRef<jobject>& j_network_info) {
NetworkInformation network_info =
GetNetworkInformationFromJava(env, j_network_info);
OnNetworkConnected(network_info);
network_thread_->Invoke<void>(
RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkConnected_n,
this, network_info));
}
void AndroidNetworkMonitor::NotifyOfNetworkDisconnect(
JNIEnv* env,
const JavaRef<jobject>& j_caller,
jlong network_handle) {
OnNetworkDisconnected(static_cast<NetworkHandle>(network_handle));
network_thread_->Invoke<void>(
RTC_FROM_HERE,
rtc::Bind(&AndroidNetworkMonitor::OnNetworkDisconnected_n, this,
static_cast<NetworkHandle>(network_handle)));
}
void AndroidNetworkMonitor::NotifyOfNetworkPreference(
@ -536,7 +571,10 @@ void AndroidNetworkMonitor::NotifyOfNetworkPreference(
NetworkType type = GetNetworkTypeFromJava(env, j_connection_type);
rtc::NetworkPreference preference =
static_cast<rtc::NetworkPreference>(jpreference);
OnNetworkPreference(type, preference);
network_thread_->Invoke<void>(
RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkPreference_n,
this, type, preference));
}
} // namespace jni

View File

@ -17,9 +17,11 @@
#include <vector>
#include "absl/types/optional.h"
#include "rtc_base/async_invoker.h"
#include "rtc_base/network_monitor.h"
#include "rtc_base/network_monitor_factory.h"
#include "rtc_base/thread_checker.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc {
@ -61,7 +63,7 @@ struct NetworkInformation {
std::string ToString() const;
};
class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
class AndroidNetworkMonitor : public rtc::NetworkMonitorInterface,
public rtc::NetworkBinderInterface {
public:
AndroidNetworkMonitor(JNIEnv* env,
@ -83,10 +85,6 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
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);
@ -111,22 +109,30 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
const rtc::IPAddress& address) const;
private:
void OnNetworkConnected_w(const NetworkInformation& network_info);
void OnNetworkDisconnected_w(NetworkHandle network_handle);
void OnNetworkConnected_n(const NetworkInformation& network_info);
void OnNetworkDisconnected_n(NetworkHandle network_handle);
void OnNetworkPreference_n(NetworkType type,
rtc::NetworkPreference preference);
const int android_sdk_int_;
ScopedJavaGlobalRef<jobject> j_application_context_;
ScopedJavaGlobalRef<jobject> j_network_monitor_;
rtc::ThreadChecker thread_checker_;
bool started_ = false;
std::map<std::string, rtc::AdapterType> adapter_type_by_name_;
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_;
rtc::Thread* network_thread_;
bool started_ RTC_GUARDED_BY(network_thread_) = false;
std::map<std::string, rtc::AdapterType> adapter_type_by_name_
RTC_GUARDED_BY(network_thread_);
std::map<std::string, rtc::AdapterType> vpn_underlying_adapter_type_by_name_
RTC_GUARDED_BY(network_thread_);
std::map<rtc::IPAddress, NetworkHandle> network_handle_by_address_
RTC_GUARDED_BY(network_thread_);
std::map<NetworkHandle, NetworkInformation> network_info_by_handle_
RTC_GUARDED_BY(network_thread_);
std::map<rtc::AdapterType, rtc::NetworkPreference>
network_preference_by_adapter_type_;
bool find_network_handle_without_ipv6_temporary_part_;
bool surface_cellular_types_;
network_preference_by_adapter_type_ RTC_GUARDED_BY(network_thread_);
bool find_network_handle_without_ipv6_temporary_part_
RTC_GUARDED_BY(network_thread_) = false;
bool surface_cellular_types_ RTC_GUARDED_BY(network_thread_) = false;
rtc::AsyncInvoker invoker_;
};
class AndroidNetworkMonitorFactory : public rtc::NetworkMonitorFactory {

View File

@ -42,10 +42,6 @@ class ObjCNetworkMonitor : public rtc::NetworkMonitorInterface,
void Start() override;
void Stop() override;
// TODO(deadbeef): Remove this once it's been removed from
// NetworkMonitorInterface.
void OnNetworksChanged() override {}
rtc::AdapterType GetAdapterType(const std::string& interface_name) override;
rtc::AdapterType GetVpnUnderlyingAdapterType(
const std::string& interface_name) override;