diff --git a/rtc_base/network_monitor.cc b/rtc_base/network_monitor.cc index 36eadf7c70..b22618a46e 100644 --- a/rtc_base/network_monitor.cc +++ b/rtc_base/network_monitor.cc @@ -10,40 +10,18 @@ #include "rtc_base/network_monitor.h" -#include - -#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 diff --git a/rtc_base/network_monitor.h b/rtc_base/network_monitor.h index 1098219ee0..4a3002f427 100644 --- a/rtc_base/network_monitor.h +++ b/rtc_base/network_monitor.h @@ -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_ diff --git a/rtc_base/network_unittest.cc b/rtc_base/network_unittest.cc index fac8c254b5..13f888e04e 100644 --- a/rtc_base/network_unittest.cc +++ b/rtc_base/network_unittest.cc @@ -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. diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 9663547093..cf53e7aa74 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -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", ] diff --git a/sdk/android/src/jni/android_network_monitor.cc b/sdk/android/src/jni/android_network_monitor.cc index e41fd035d7..434e6d3af9 100644 --- a/sdk/android/src/jni/android_network_monitor.cc +++ b/sdk/android/src/jni/android_network_monitor.cc @@ -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& 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( - 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 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( - 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(RTC_FROM_HERE, [&] { - auto adapter_type = - AdapterTypeFromNetworkType(type, surface_cellular_types_); - network_preference_by_adapter_type_[adapter_type] = preference; - }); - OnNetworksChanged(); + 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; + SignalNetworksChanged(); } void AndroidNetworkMonitor::SetNetworkInfos( const std::vector& 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& j_caller) { - OnNetworksChanged(); + invoker_.AsyncInvoke(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& j_network_info) { NetworkInformation network_info = GetNetworkInformationFromJava(env, j_network_info); - OnNetworkConnected(network_info); + network_thread_->Invoke( + RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkConnected_n, + this, network_info)); } void AndroidNetworkMonitor::NotifyOfNetworkDisconnect( JNIEnv* env, const JavaRef& j_caller, jlong network_handle) { - OnNetworkDisconnected(static_cast(network_handle)); + network_thread_->Invoke( + RTC_FROM_HERE, + rtc::Bind(&AndroidNetworkMonitor::OnNetworkDisconnected_n, this, + static_cast(network_handle))); } void AndroidNetworkMonitor::NotifyOfNetworkPreference( @@ -536,7 +571,10 @@ void AndroidNetworkMonitor::NotifyOfNetworkPreference( NetworkType type = GetNetworkTypeFromJava(env, j_connection_type); rtc::NetworkPreference preference = static_cast(jpreference); - OnNetworkPreference(type, preference); + + network_thread_->Invoke( + RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkPreference_n, + this, type, preference)); } } // namespace jni diff --git a/sdk/android/src/jni/android_network_monitor.h b/sdk/android/src/jni/android_network_monitor.h index d1008f2665..eff2122549 100644 --- a/sdk/android/src/jni/android_network_monitor.h +++ b/sdk/android/src/jni/android_network_monitor.h @@ -17,9 +17,11 @@ #include #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& 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 j_application_context_; ScopedJavaGlobalRef j_network_monitor_; - rtc::ThreadChecker thread_checker_; - bool started_ = false; - std::map adapter_type_by_name_; - std::map vpn_underlying_adapter_type_by_name_; - std::map network_handle_by_address_; - std::map network_info_by_handle_; + rtc::Thread* network_thread_; + bool started_ RTC_GUARDED_BY(network_thread_) = false; + std::map adapter_type_by_name_ + RTC_GUARDED_BY(network_thread_); + std::map vpn_underlying_adapter_type_by_name_ + RTC_GUARDED_BY(network_thread_); + std::map network_handle_by_address_ + RTC_GUARDED_BY(network_thread_); + std::map network_info_by_handle_ + RTC_GUARDED_BY(network_thread_); std::map - 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 { diff --git a/sdk/objc/native/src/objc_network_monitor.h b/sdk/objc/native/src/objc_network_monitor.h index cffe3a2f8f..7fcb1c7fd0 100644 --- a/sdk/objc/native/src/objc_network_monitor.h +++ b/sdk/objc/native/src/objc_network_monitor.h @@ -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;