diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2024-02-07 23:20:47 +0100 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2024-02-08 10:50:58 +0100 |
| commit | 6effbc46664b741f702adc0168053f46fa44dd41 (patch) | |
| tree | 218c526e08b9d3143a0757bfdbfc923b26331553 | |
| parent | 1b80203504f58fab47dc6dbe53f223084acecc6a (diff) | |
| download | mullvadvpn-6effbc46664b741f702adc0168053f46fa44dd41.tar.xz mullvadvpn-6effbc46664b741f702adc0168053f46fa44dd41.zip | |
Add support for custom lists in jni
| -rw-r--r-- | mullvad-jni/src/classes.rs | 2 | ||||
| -rw-r--r-- | mullvad-jni/src/daemon_interface.rs | 31 | ||||
| -rw-r--r-- | mullvad-jni/src/lib.rs | 70 | ||||
| -rw-r--r-- | mullvad-types/src/custom_list.rs | 47 | ||||
| -rw-r--r-- | mullvad-types/src/settings/mod.rs | 1 |
5 files changed, 150 insertions, 1 deletions
diff --git a/mullvad-jni/src/classes.rs b/mullvad-jni/src/classes.rs index 454e0e6c62..562fe786f0 100644 --- a/mullvad-jni/src/classes.rs +++ b/mullvad-jni/src/classes.rs @@ -9,6 +9,8 @@ pub const CLASSES: &[&str] = &[ "net/mullvad/mullvadvpn/model/AppVersionInfo", "net/mullvad/mullvadvpn/model/Constraint$Any", "net/mullvad/mullvadvpn/model/Constraint$Only", + "net/mullvad/mullvadvpn/model/CustomList", + "net/mullvad/mullvadvpn/model/CustomListsSettings", "net/mullvad/mullvadvpn/model/DnsState", "net/mullvad/mullvadvpn/model/DnsOptions", "net/mullvad/mullvadvpn/model/CustomDnsOptions", diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs index 7ecc91585a..7abd35cf5b 100644 --- a/mullvad-jni/src/daemon_interface.rs +++ b/mullvad-jni/src/daemon_interface.rs @@ -2,6 +2,7 @@ use futures::{channel::oneshot, executor::block_on}; use mullvad_daemon::{device, DaemonCommand, DaemonCommandSender}; use mullvad_types::{ account::{AccountData, AccountToken, PlayPurchase, VoucherSubmission}, + custom_list::CustomList, device::{Device, DeviceState}, relay_constraints::{ObfuscationSettings, RelaySettings}, relay_list::RelayList, @@ -354,6 +355,36 @@ impl DaemonInterface { .map_err(|_| Error::UpdateSettings) } + pub fn create_custom_list(&self, name: String) -> Result<mullvad_types::custom_list::Id> { + let (tx, rx) = oneshot::channel(); + + self.send_command(DaemonCommand::CreateCustomList(tx, name))?; + + block_on(rx) + .map_err(|_| Error::NoResponse)? + .map_err(Error::from) + } + + pub fn delete_custom_list(&self, id: mullvad_types::custom_list::Id) -> Result<()> { + let (tx, rx) = oneshot::channel(); + + self.send_command(DaemonCommand::DeleteCustomList(tx, id))?; + + block_on(rx) + .map_err(|_| Error::NoResponse)? + .map_err(Error::from) + } + + pub fn update_custom_list(&self, custom_list: CustomList) -> Result<()> { + let (tx, rx) = oneshot::channel(); + + self.send_command(DaemonCommand::UpdateCustomList(tx, custom_list))?; + + block_on(rx) + .map_err(|_| Error::NoResponse)? + .map_err(Error::from) + } + fn send_command(&self, command: DaemonCommand) -> Result<()> { self.command_sender.send(command).map_err(Error::NoDaemon) } diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs index a41b8d6643..1416fd70b5 100644 --- a/mullvad-jni/src/lib.rs +++ b/mullvad-jni/src/lib.rs @@ -24,6 +24,7 @@ use mullvad_daemon::{ }; use mullvad_types::{ account::{AccountData, PlayPurchase, VoucherSubmission}, + custom_list::CustomList, settings::DnsOptions, }; use std::{ @@ -1338,6 +1339,75 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_setQuan } } +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_createCustomList<'env>( + env: JNIEnv<'env>, + _: JObject<'_>, + daemon_interface_address: jlong, + name: JString<'_>, +) -> JObject<'env> { + let env = JnixEnv::from(env); + + // SAFETY: The address points to an instance valid for the duration of this function call + if let Some(daemon_interface) = unsafe { get_daemon_interface(daemon_interface_address) } { + let name = String::from_java(&env, name); + match daemon_interface.create_custom_list(name) { + Ok(id) => id.into_java(&env).forget(), + Err(error) => { + log_request_error("create custom list", &error); + JObject::null() + } + } + } else { + JObject::null() + } +} + +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_deleteCustomList( + env: JNIEnv<'_>, + _: JObject<'_>, + daemon_interface_address: jlong, + id: JString<'_>, +) { + let env = JnixEnv::from(env); + + // SAFETY: The address points to an instance valid for the duration of this function call + if let Some(daemon_interface) = unsafe { get_daemon_interface(daemon_interface_address) } { + let id = mullvad_types::custom_list::Id::from_java(&env, id); + if let Err(error) = daemon_interface.delete_custom_list(id) { + log::error!( + "{}", + error.display_chain_with_msg("Failed to delete custom list") + ); + } + } +} + +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_updateCustomList( + env: JNIEnv<'_>, + _: JObject<'_>, + daemon_interface_address: jlong, + customList: JObject<'_>, +) { + let env = JnixEnv::from(env); + + // SAFETY: The address points to an instance valid for the duration of this function call + if let Some(daemon_interface) = unsafe { get_daemon_interface(daemon_interface_address) } { + let list = CustomList::from_java(&env, customList); + if let Err(error) = daemon_interface.update_custom_list(list) { + log::error!( + "{}", + error.display_chain_with_msg("Failed to update custom list") + ); + } + } +} + fn log_request_error(request: &str, error: &daemon_interface::Error) { match error { daemon_interface::Error::Api(RestError::Aborted) => { diff --git a/mullvad-types/src/custom_list.rs b/mullvad-types/src/custom_list.rs index 58fd046a9e..b92f128a3b 100644 --- a/mullvad-types/src/custom_list.rs +++ b/mullvad-types/src/custom_list.rs @@ -77,6 +77,8 @@ impl<'borrow, 'env: 'borrow> IntoJava<'borrow, 'env> for Id { } } +#[cfg_attr(target_os = "android", derive(IntoJava, FromJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] #[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CustomListsSettings { custom_lists: Vec<CustomList>, @@ -122,9 +124,17 @@ impl DerefMut for CustomListsSettings { } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] pub struct CustomList { pub id: Id, pub name: String, + #[cfg_attr( + target_os = "android", + jnix( + map = "|locations| locations.into_iter().collect::<Vec<GeographicLocationConstraint>>()" + ) + )] pub locations: BTreeSet<GeographicLocationConstraint>, } @@ -137,3 +147,40 @@ impl CustomList { } } } + +#[cfg(target_os = "android")] +impl<'env, 'sub_env> FromJava<'env, JObject<'sub_env>> for CustomList +where + 'env: 'sub_env, +{ + const JNI_SIGNATURE: &'static str = "Lnet/mullvad/mullvadvpn/model/CustomList;"; + + fn from_java(env: &JnixEnv<'env>, source: JObject<'sub_env>) -> Self { + let object_id = env + .call_method(source, "component1", "()Ljava/lang/String;", &[]) + .expect("missing CustomList.id") + .l() + .expect("CustomList.id did not return an object"); + let id = Id::from_str(&String::from_java(env, object_id)).expect("invalid ID"); + + let object_name = env + .call_method(source, "component2", "()Ljava/lang/String;", &[]) + .expect("missing CustomList.name") + .l() + .expect("CustomList.name did not return an object"); + let name = String::from_java(env, object_name); + + let object_locations = env + .call_method(source, "component3", "()Ljava/util/ArrayList;", &[]) + .expect("missing CustomList.locations") + .l() + .expect("CustomList.locations did not return an object"); + let locations = BTreeSet::from_iter(Vec::from_java(env, object_locations)); + + CustomList { + id, + name, + locations, + } + } +} diff --git a/mullvad-types/src/settings/mod.rs b/mullvad-types/src/settings/mod.rs index 3adde14b5d..607e1d9539 100644 --- a/mullvad-types/src/settings/mod.rs +++ b/mullvad-types/src/settings/mod.rs @@ -77,7 +77,6 @@ pub struct Settings { #[cfg_attr(target_os = "android", jnix(skip))] pub bridge_state: BridgeState, /// All of the custom relay lists - #[cfg_attr(target_os = "android", jnix(skip))] pub custom_lists: CustomListsSettings, /// API access methods #[cfg_attr(target_os = "android", jnix(skip))] |
