diff --git a/api/scoped_refptr.h b/api/scoped_refptr.h index fa4e83dbaf..4e3f0ebfc8 100644 --- a/api/scoped_refptr.h +++ b/api/scoped_refptr.h @@ -104,6 +104,7 @@ class scoped_refptr { T* get() const { return ptr_; } operator T*() const { return ptr_; } + T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } // Returns the (possibly null) raw pointer, and makes the scoped_refptr hold a diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 141763de3c..0d2ede0022 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -141,7 +141,10 @@ if (is_android) { suppressed_configs += [ "//build/config/android:hide_all_but_jni_onload" ] configs += [ "//build/config/android:hide_all_but_jni" ] - ldflags = [ "-lEGL", "-Wl,--build-id" ] + ldflags = [ + "-lEGL", + "-Wl,--build-id", + ] deps = [ ":libjingle_peerconnection_jni", @@ -565,6 +568,8 @@ if (current_os == "linux" || is_android) { "../../rtc_base:ip_address", "../../rtc_base:rtc_base_approved", "../../rtc_base:threading", + "../../rtc_base/task_utils:pending_task_safety_flag", + "../../rtc_base/task_utils:to_queued_task", "../../system_wrappers:field_trial", "../../system_wrappers:metrics", ] diff --git a/sdk/android/native_unittests/android_network_monitor_unittest.cc b/sdk/android/native_unittests/android_network_monitor_unittest.cc index de54d24a4d..20e756ae7b 100644 --- a/sdk/android/native_unittests/android_network_monitor_unittest.cc +++ b/sdk/android/native_unittests/android_network_monitor_unittest.cc @@ -51,11 +51,16 @@ class AndroidNetworkMonitorTest : public ::testing::Test { std::make_unique(env, context); } - void SetUp() { + void SetUp() override { // Reset network monitor states. network_monitor_->Stop(); } + void TearDown() override { + // The network monitor must be stopped, before it is destructed. + network_monitor_->Stop(); + } + protected: std::unique_ptr network_monitor_; }; diff --git a/sdk/android/src/jni/android_network_monitor.cc b/sdk/android/src/jni/android_network_monitor.cc index 0780a442c7..03675132d7 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/task_utils/to_queued_task.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" @@ -228,9 +229,12 @@ AndroidNetworkMonitor::AndroidNetworkMonitor( : android_sdk_int_(Java_NetworkMonitor_androidSdkInt(env)), j_application_context_(env, j_application_context), j_network_monitor_(env, Java_NetworkMonitor_getInstance(env)), - network_thread_(rtc::Thread::Current()) {} + network_thread_(rtc::Thread::Current()), + safety_flag_(PendingTaskSafetyFlag::Create()) {} -AndroidNetworkMonitor::~AndroidNetworkMonitor() = default; +AndroidNetworkMonitor::~AndroidNetworkMonitor() { + RTC_DCHECK(!started_); +} void AndroidNetworkMonitor::Start() { RTC_DCHECK_RUN_ON(network_thread_); @@ -246,6 +250,9 @@ void AndroidNetworkMonitor::Start() { bind_using_ifname_ = webrtc::field_trial::IsEnabled("WebRTC-BindUsingInterfaceName"); + // Needed for restart after Stop(). + safety_flag_->SetAlive(); + JNIEnv* env = AttachCurrentThreadIfNeeded(); Java_NetworkMonitor_startMonitoring( env, j_network_monitor_, j_application_context_, jlongFromPointer(this)); @@ -259,6 +266,10 @@ void AndroidNetworkMonitor::Stop() { started_ = false; find_network_handle_without_ipv6_temporary_part_ = false; + // Cancel any pending tasks. We should not call SignalNetworksChanged when the + // monitor is stopped. + safety_flag_->SetNotAlive(); + JNIEnv* env = AttachCurrentThreadIfNeeded(); Java_NetworkMonitor_stopMonitoring(env, j_network_monitor_, jlongFromPointer(this)); @@ -571,11 +582,11 @@ AndroidNetworkMonitorFactory::CreateNetworkMonitor() { void AndroidNetworkMonitor::NotifyConnectionTypeChanged( JNIEnv* env, const JavaRef& j_caller) { - network_thread_->Invoke(RTC_FROM_HERE, [this] { + network_thread_->PostTask(ToQueuedTask(safety_flag_, [this] { RTC_LOG(LS_INFO) << "Android network monitor detected connection type change."; SignalNetworksChanged(); - }); + })); } void AndroidNetworkMonitor::NotifyOfActiveNetworkList( @@ -594,18 +605,19 @@ void AndroidNetworkMonitor::NotifyOfNetworkConnect( const JavaRef& j_network_info) { NetworkInformation network_info = GetNetworkInformationFromJava(env, j_network_info); - network_thread_->Invoke(RTC_FROM_HERE, [this, &network_info] { - OnNetworkConnected_n(network_info); - }); + network_thread_->PostTask(ToQueuedTask( + safety_flag_, [this, network_info = std::move(network_info)] { + OnNetworkConnected_n(network_info); + })); } void AndroidNetworkMonitor::NotifyOfNetworkDisconnect( JNIEnv* env, const JavaRef& j_caller, jlong network_handle) { - network_thread_->Invoke(RTC_FROM_HERE, [this, network_handle] { + network_thread_->PostTask(ToQueuedTask(safety_flag_, [this, network_handle] { OnNetworkDisconnected_n(static_cast(network_handle)); - }); + })); } void AndroidNetworkMonitor::NotifyOfNetworkPreference( @@ -617,9 +629,9 @@ void AndroidNetworkMonitor::NotifyOfNetworkPreference( rtc::NetworkPreference preference = static_cast(jpreference); - network_thread_->Invoke(RTC_FROM_HERE, [this, type, preference] { - OnNetworkPreference_n(type, preference); - }); + network_thread_->PostTask(ToQueuedTask( + safety_flag_, + [this, type, preference] { OnNetworkPreference_n(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 70e8e2e4a7..6349a11cf6 100644 --- a/sdk/android/src/jni/android_network_monitor.h +++ b/sdk/android/src/jni/android_network_monitor.h @@ -12,6 +12,7 @@ #define SDK_ANDROID_SRC_JNI_ANDROID_NETWORK_MONITOR_H_ #include + #include #include #include @@ -19,6 +20,7 @@ #include "absl/types/optional.h" #include "rtc_base/network_monitor.h" #include "rtc_base/network_monitor_factory.h" +#include "rtc_base/task_utils/pending_task_safety_flag.h" #include "rtc_base/thread.h" #include "rtc_base/thread_annotations.h" #include "sdk/android/src/jni/jni_helpers.h" @@ -147,6 +149,8 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorInterface { // This applies to adapter_type_by_name_, vpn_underlying_adapter_type_by_name_ // and FindNetworkHandleFromIfname. bool bind_using_ifname_ RTC_GUARDED_BY(network_thread_) = true; + const rtc::scoped_refptr safety_flag_ + RTC_PT_GUARDED_BY(network_thread_); }; class AndroidNetworkMonitorFactory : public rtc::NetworkMonitorFactory {