diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt index c2f0aef20f2d..f1fe3ca807b4 100644 --- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt +++ b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt @@ -75,15 +75,12 @@ class ConnectivityListener { fun unregister() { connectivityManager.unregisterNetworkCallback(callback) connectivityManager.unregisterNetworkCallback(defaultNetworkCallback) - } - // DROID-1401 - // This function has never been used and should most likely be merged into unregister(), - // along with ensuring that the lifecycle of it is correct. - @Suppress("UnusedPrivateMember") - private fun finalize() { - destroySender(senderAddress) - senderAddress = 0L + if (senderAddress != 0L) { + var oldSender = senderAddress + senderAddress = 0L + destroySender(oldSender) + } } private external fun notifyConnectivityChange(isConnected: Boolean, senderAddress: Long) diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 0f2914fdff8a..0665c2736ebb 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -622,7 +622,6 @@ impl Daemon { mullvad_api::proxy::ApiConnectionMode::try_delete_cache(&cache_dir).await; let api_runtime = mullvad_api::Runtime::with_cache( - // FIXME: clone is bad (single sender) #[cfg(target_os = "android")] android_dns::AndroidDnsResolver::new(connectivity_listener.clone()), #[cfg(not(target_os = "android"))] diff --git a/talpid-core/src/connectivity_listener.rs b/talpid-core/src/connectivity_listener.rs index b28f58cefbec..2d121d264bcf 100644 --- a/talpid-core/src/connectivity_listener.rs +++ b/talpid-core/src/connectivity_listener.rs @@ -9,10 +9,9 @@ use jnix::{ sys::{jboolean, jlong, JNI_TRUE}, JNIEnv, JavaVM, }, - JnixEnv, - FromJava, + FromJava, JnixEnv, }; -use std::{net::IpAddr, sync::{Arc, Weak}}; +use std::{net::IpAddr, sync::Arc}; use talpid_types::{android::AndroidContext, net::Connectivity, ErrorExt}; /// Error related to Android connectivity monitor @@ -45,7 +44,6 @@ pub struct ConnectivityListener { jvm: Arc, class: GlobalRef, object: GlobalRef, - _sender: Option>>, } impl ConnectivityListener { @@ -96,26 +94,24 @@ impl ConnectivityListener { jvm: android_context.jvm, class, object, - _sender: None, }) } /// Register a channel that receives changes about the offline state + /// + /// # Note + /// + /// The listener is shared by all instances of the struct. pub fn set_connectivity_listener( &mut self, sender: UnboundedSender, ) -> Result<(), Error> { - let sender = Arc::new(sender); - - let weak_sender = Arc::downgrade(&sender); - - let weak_sender_ptr = Box::new(weak_sender); - let weak_sender_address = Box::into_raw(weak_sender_ptr) as jlong; + let sender_ptr = Box::into_raw(Box::new(sender)) as jlong; let result = self.call_method( "setSenderAddress", "(J)V", - &[JValue::Long(weak_sender_address)], + &[JValue::Long(sender_ptr)], JavaType::Primitive(Primitive::Void), )?; @@ -128,8 +124,6 @@ impl ConnectivityListener { )), }?; - self._sender = Some(sender); - Ok(()) } @@ -222,15 +216,18 @@ pub extern "system" fn Java_net_mullvad_talpid_ConnectivityListener_notifyConnec sender_address: jlong, ) { let connected = JNI_TRUE == connected; - let sender_ref = Box::leak(unsafe { get_sender_from_address(sender_address) }); - if let Some(sender) = sender_ref.upgrade() { - if sender - .unbounded_send(Connectivity::Status { connected }) - .is_err() - { - log::warn!("Failed to send offline change event"); - } + + let sender = unsafe { Box::from_raw(sender_address as *mut UnboundedSender) }; + + if sender + .unbounded_send(Connectivity::Status { connected }) + .is_err() + { + log::warn!("Failed to send offline change event"); } + + // Do not destroy + std::mem::forget(sender); } /// Entry point for Android Java code to return ownership of the sender reference. @@ -241,9 +238,5 @@ pub extern "system" fn Java_net_mullvad_talpid_ConnectivityListener_destroySende _: JObject<'_>, sender_address: jlong, ) { - let _ = unsafe { get_sender_from_address(sender_address) }; -} - -unsafe fn get_sender_from_address(address: jlong) -> Box>> { - Box::from_raw(address as *mut Weak>) + let _ = unsafe { Box::from_raw(sender_address as *mut UnboundedSender) }; }