diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-11-12 14:12:23 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2022-03-14 12:08:48 +0100 |
| commit | 094ff854c0591ef176b7420e325e4b557963c6d2 (patch) | |
| tree | b9394048cb3e92efcebe1c28187899e015c1475c | |
| parent | 02774dc79db69e8cca343ff659688368198857e5 (diff) | |
| download | mullvadvpn-094ff854c0591ef176b7420e325e4b557963c6d2.tar.xz mullvadvpn-094ff854c0591ef176b7420e325e4b557963c6d2.zip | |
Update Rust-end JNI and Android IPC
| -rw-r--r-- | android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt | 14 | ||||
| -rw-r--r-- | mullvad-jni/src/daemon_interface.rs | 62 | ||||
| -rw-r--r-- | mullvad-jni/src/jni_event_listener.rs | 80 | ||||
| -rw-r--r-- | mullvad-jni/src/lib.rs | 225 | ||||
| -rw-r--r-- | mullvad-management-interface/src/types.rs | 6 | ||||
| -rw-r--r-- | mullvad-types/src/device.rs | 20 |
6 files changed, 289 insertions, 118 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt index 4565844daa..8470f314d7 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt @@ -45,7 +45,8 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { } fun generateWireguardKey(): KeygenEvent? { - return generateWireguardKey(daemonInterfaceAddress) + // TODO: remove + return null } fun getAccountData(accountToken: String): GetAccountDataResult { @@ -85,6 +86,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { } fun getWireguardKey(): PublicKey? { + // TODO: no longer needed return getWireguardKey(daemonInterfaceAddress) } @@ -97,7 +99,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { } fun setAccount(accountToken: String?) { - setAccount(daemonInterfaceAddress, accountToken) + // TODO: replace with login+logout } fun setAllowLan(allowLan: Boolean) { @@ -154,7 +156,6 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { private external fun connect(daemonInterfaceAddress: Long) private external fun createNewAccount(daemonInterfaceAddress: Long): String? private external fun disconnect(daemonInterfaceAddress: Long) - private external fun generateWireguardKey(daemonInterfaceAddress: Long): KeygenEvent? private external fun getAccountData( daemonInterfaceAddress: Long, accountToken: String @@ -170,7 +171,8 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { private external fun getWireguardKey(daemonInterfaceAddress: Long): PublicKey? private external fun reconnect(daemonInterfaceAddress: Long) private external fun clearAccountHistory(daemonInterfaceAddress: Long) - private external fun setAccount(daemonInterfaceAddress: Long, accountToken: String?) + private external fun loginAccount(daemonInterfaceAddress: Long, accountToken: String?) + private external fun logoutAccount(daemonInterfaceAddress: Long) private external fun setAllowLan(daemonInterfaceAddress: Long, allowLan: Boolean) private external fun setAutoConnect(daemonInterfaceAddress: Long, alwaysOn: Boolean) private external fun setDnsOptions(daemonInterfaceAddress: Long, dnsOptions: DnsOptions) @@ -190,10 +192,6 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { onAppVersionInfoChange?.invoke(appVersionInfo) } - private fun notifyKeygenEvent(event: KeygenEvent) { - onKeygenEvent?.invoke(event) - } - private fun notifyRelayListEvent(relayList: RelayList) { onRelayListChange?.invoke(relayList) } diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs index 6f47fe21e8..3550b20d32 100644 --- a/mullvad-jni/src/daemon_interface.rs +++ b/mullvad-jni/src/daemon_interface.rs @@ -1,14 +1,15 @@ use futures::{channel::oneshot, executor::block_on}; -use mullvad_daemon::{DaemonCommand, DaemonCommandSender}; +use mullvad_daemon::{device, DaemonCommand, DaemonCommandSender}; use mullvad_types::{ account::{AccountData, AccountToken, VoucherSubmission}, + device::{Device, DeviceConfig}, location::GeoIpLocation, relay_constraints::RelaySettingsUpdate, relay_list::RelayList, settings::{DnsOptions, Settings}, states::{TargetState, TunnelState}, version::AppVersionInfo, - wireguard::{self, KeygenEvent}, + wireguard, }; #[derive(Debug, err_derive::Error)] @@ -37,6 +38,12 @@ impl From<mullvad_daemon::Error> for Error { fn from(error: mullvad_daemon::Error) -> Error { match error { mullvad_daemon::Error::RestError(error) => Error::RpcError(error), + mullvad_daemon::Error::LoginError(device::Error::OtherRestError(error)) => { + Error::RpcError(error) + } + mullvad_daemon::Error::ListDevicesError(device::Error::OtherRestError(error)) => { + Error::RpcError(error) + } error => Error::OtherError(error), } } @@ -79,16 +86,6 @@ impl DaemonInterface { block_on(rx).map(|_| ()).map_err(|_| Error::NoResponse) } - pub fn generate_wireguard_key(&self) -> Result<KeygenEvent> { - let (tx, rx) = oneshot::channel(); - - self.send_command(DaemonCommand::GenerateWireguardKey(tx))?; - - block_on(rx) - .map_err(|_| Error::NoResponse)? - .map_err(Error::from) - } - pub fn get_account_data(&self, account_token: String) -> Result<AccountData> { let (tx, rx) = oneshot::channel(); @@ -195,23 +192,54 @@ impl DaemonInterface { .map_err(Error::from) } - pub fn verify_wireguard_key(&self) -> Result<bool> { + pub fn login_account(&self, account_token: String) -> Result<()> { + let (tx, rx) = oneshot::channel(); + + self.send_command(DaemonCommand::LoginAccount(tx, account_token))?; + + block_on(rx) + .map_err(|_| Error::NoResponse)? + .map_err(Error::from) + } + + pub fn logout_account(&self) -> Result<()> { let (tx, rx) = oneshot::channel(); - self.send_command(DaemonCommand::VerifyWireguardKey(tx))?; + self.send_command(DaemonCommand::LogoutAccount(tx))?; + block_on(rx) .map_err(|_| Error::NoResponse)? .map_err(Error::from) } - pub fn set_account(&self, account_token: Option<String>) -> Result<()> { + pub fn get_device(&self) -> Result<Option<DeviceConfig>> { let (tx, rx) = oneshot::channel(); - self.send_command(DaemonCommand::SetAccount(tx, account_token))?; + self.send_command(DaemonCommand::GetDevice(tx))?; block_on(rx) .map_err(|_| Error::NoResponse)? - .map_err(|_| Error::SettingsError) + .map_err(Error::from) + } + + pub fn list_devices(&self, account_token: String) -> Result<Vec<Device>> { + let (tx, rx) = oneshot::channel(); + + self.send_command(DaemonCommand::ListDevices(tx, account_token))?; + + block_on(rx) + .map_err(|_| Error::NoResponse)? + .map_err(Error::from) + } + + pub fn remove_device(&self, account_token: String, device_id: String) -> Result<()> { + let (tx, rx) = oneshot::channel(); + + self.send_command(DaemonCommand::RemoveDevice(tx, account_token, device_id))?; + + block_on(rx) + .map_err(|_| Error::NoResponse)? + .map_err(Error::from) } pub fn set_allow_lan(&self, allow_lan: bool) -> Result<()> { diff --git a/mullvad-jni/src/jni_event_listener.rs b/mullvad-jni/src/jni_event_listener.rs index 9fd5c3d2ea..553f3f48f3 100644 --- a/mullvad-jni/src/jni_event_listener.rs +++ b/mullvad-jni/src/jni_event_listener.rs @@ -7,8 +7,11 @@ use jnix::{ }; use mullvad_daemon::EventListener; use mullvad_types::{ - relay_list::RelayList, settings::Settings, states::TunnelState, version::AppVersionInfo, - wireguard::KeygenEvent, + device::{DeviceEvent, RemoveDeviceEvent}, + relay_list::RelayList, + settings::Settings, + states::TunnelState, + version::AppVersionInfo, }; use std::{sync::mpsc, thread}; use talpid_types::ErrorExt; @@ -27,11 +30,12 @@ pub enum Error { } enum Event { - KeygenEvent(KeygenEvent), RelayList(RelayList), Settings(Settings), Tunnel(TunnelState), AppVersionInfo(AppVersionInfo), + DeviceEvent(DeviceEvent), + RemoveDeviceEvent(RemoveDeviceEvent), } #[derive(Clone, Debug)] @@ -44,10 +48,6 @@ impl JniEventListener { } impl EventListener for JniEventListener { - fn notify_key_event(&self, key_event: KeygenEvent) { - let _ = self.0.send(Event::KeygenEvent(key_event)); - } - fn notify_new_state(&self, state: TunnelState) { let _ = self.0.send(Event::Tunnel(state)); } @@ -63,16 +63,25 @@ impl EventListener for JniEventListener { fn notify_app_version(&self, app_version_info: AppVersionInfo) { let _ = self.0.send(Event::AppVersionInfo(app_version_info)); } + + fn notify_device_event(&self, event: DeviceEvent) { + let _ = self.0.send(Event::DeviceEvent(event)); + } + + fn notify_remove_device_event(&self, event: RemoveDeviceEvent) { + let _ = self.0.send(Event::RemoveDeviceEvent(event)); + } } struct JniEventHandler<'env> { env: JnixEnv<'env>, mullvad_ipc_client: JObject<'env>, notify_app_version_info_event: JMethodID<'env>, - notify_keygen_event: JMethodID<'env>, notify_relay_list_event: JMethodID<'env>, notify_settings_event: JMethodID<'env>, notify_tunnel_event: JMethodID<'env>, + notify_device_event: JMethodID<'env>, + notify_remove_device_event: JMethodID<'env>, events: mpsc::Receiver<Event>, } @@ -123,12 +132,6 @@ impl<'env> JniEventHandler<'env> { "notifyAppVersionInfoEvent", "(Lnet/mullvad/mullvadvpn/model/AppVersionInfo;)V", )?; - let notify_keygen_event = Self::get_method_id( - &env, - &class, - "notifyKeygenEvent", - "(Lnet/mullvad/mullvadvpn/model/KeygenEvent;)V", - )?; let notify_relay_list_event = Self::get_method_id( &env, &class, @@ -147,15 +150,28 @@ impl<'env> JniEventHandler<'env> { "notifyTunnelStateEvent", "(Lnet/mullvad/mullvadvpn/model/TunnelState;)V", )?; + let notify_device_event = Self::get_method_id( + &env, + &class, + "notifyDeviceEvent", + "(Lnet/mullvad/mullvadvpn/model/DeviceEvent;)V", + )?; + let notify_remove_device_event = Self::get_method_id( + &env, + &class, + "notifyRemoveDeviceEvent", + "(Lnet/mullvad/mullvadvpn/model/RemoveDeviceEvent;)V", + )?; Ok(JniEventHandler { env, mullvad_ipc_client, notify_app_version_info_event, - notify_keygen_event, notify_relay_list_event, notify_settings_event, notify_tunnel_event, + notify_device_event, + notify_remove_device_event, events, }) } @@ -173,31 +189,53 @@ impl<'env> JniEventHandler<'env> { fn run(&mut self) { while let Ok(event) = self.events.recv() { match event { - Event::KeygenEvent(keygen_event) => self.handle_keygen_event(keygen_event), Event::RelayList(relay_list) => self.handle_relay_list_event(relay_list), Event::Settings(settings) => self.handle_settings(settings), Event::Tunnel(tunnel_event) => self.handle_tunnel_event(tunnel_event), Event::AppVersionInfo(app_version_info) => { self.handle_app_version_info_event(app_version_info) } + Event::DeviceEvent(device_event) => self.handle_device_event(device_event), + Event::RemoveDeviceEvent(device_event) => { + self.handle_remove_device_event(device_event) + } } } } - fn handle_keygen_event(&self, event: KeygenEvent) { - let java_keygen_event = event.into_java(&self.env); + fn handle_device_event(&self, device_event: DeviceEvent) { + let java_event = device_event.into_java(&self.env); + + let result = self.env.call_method_unchecked( + self.mullvad_ipc_client, + self.notify_device_event, + JavaType::Primitive(Primitive::Void), + &[JValue::Object(java_event.as_obj())], + ); + + if let Err(error) = result { + log::error!( + "{}", + error.display_chain_with_msg("Failed to call MullvadDaemon.notifyDeviceEvent") + ); + } + } + + fn handle_remove_device_event(&self, remove_event: RemoveDeviceEvent) { + let java_event = remove_event.into_java(&self.env); let result = self.env.call_method_unchecked( self.mullvad_ipc_client, - self.notify_keygen_event, + self.notify_remove_device_event, JavaType::Primitive(Primitive::Void), - &[JValue::Object(java_keygen_event.as_obj())], + &[JValue::Object(java_event.as_obj())], ); if let Err(error) = result { log::error!( "{}", - error.display_chain_with_msg("Failed to call MullvadDaemon.notifyKeygenEvent") + error + .display_chain_with_msg("Failed to call MullvadDaemon.notifyRemoveDeviceEvent") ); } } diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs index 646988e11b..c98c132e60 100644 --- a/mullvad-jni/src/lib.rs +++ b/mullvad-jni/src/lib.rs @@ -19,7 +19,8 @@ use jnix::{ FromJava, IntoJava, JnixEnv, }; use mullvad_daemon::{ - exception_logging, logging, runtime::new_runtime_builder, version, Daemon, DaemonCommandChannel, + device, exception_logging, logging, runtime::new_runtime_builder, version, Daemon, + DaemonCommandChannel, }; use mullvad_rpc::{rest::Error as RestError, StatusCode}; use mullvad_types::{ @@ -92,6 +93,65 @@ impl From<Result<AccountData, daemon_interface::Error>> for GetAccountDataResult #[derive(IntoJava)] #[jnix(package = "net.mullvad.mullvadvpn.model")] +pub enum LoginResult { + Ok, + InvalidAccount, + MaxDevicesReached, + RpcError, + OtherError, +} + +impl From<Result<(), daemon_interface::Error>> for LoginResult { + fn from(result: Result<(), daemon_interface::Error>) -> Self { + match result { + Ok(()) => LoginResult::Ok, + Err(error) => match error { + daemon_interface::Error::OtherError(mullvad_daemon::Error::LoginError(error)) => { + match error { + device::Error::InvalidAccount => LoginResult::InvalidAccount, + device::Error::MaxDevicesReached => LoginResult::MaxDevicesReached, + device::Error::OtherRestError(_) => LoginResult::RpcError, + _ => LoginResult::OtherError, + } + } + daemon_interface::Error::RpcError(_) => LoginResult::RpcError, + _ => LoginResult::OtherError, + }, + } + } +} + +#[derive(IntoJava)] +#[jnix(package = "net.mullvad.mullvadvpn.model")] +pub enum RemoveDeviceResult { + Ok, + NotFound, + RpcError, + OtherError, +} + +impl From<Result<(), daemon_interface::Error>> for RemoveDeviceResult { + fn from(result: Result<(), daemon_interface::Error>) -> Self { + match result { + Ok(()) => RemoveDeviceResult::Ok, + Err(error) => match error { + daemon_interface::Error::OtherError(mullvad_daemon::Error::LoginError(error)) => { + match error { + device::Error::InvalidAccount => RemoveDeviceResult::RpcError, + device::Error::InvalidDevice => RemoveDeviceResult::NotFound, + device::Error::OtherRestError(_) => RemoveDeviceResult::RpcError, + _ => RemoveDeviceResult::OtherError, + } + } + daemon_interface::Error::RpcError(_) => RemoveDeviceResult::RpcError, + _ => RemoveDeviceResult::OtherError, + }, + } + } +} + +#[derive(IntoJava)] +#[jnix(package = "net.mullvad.mullvadvpn.model")] pub enum VoucherSubmissionResult { Ok(VoucherSubmission), Error(VoucherSubmissionError), @@ -439,66 +499,6 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_disconn #[no_mangle] #[allow(non_snake_case)] -pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_generateWireguardKey< - 'env, ->( - env: JNIEnv<'env>, - _: JObject<'_>, - daemon_interface_address: jlong, -) -> JObject<'env> { - let env = JnixEnv::from(env); - - if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { - match daemon_interface.generate_wireguard_key() { - Ok(keygen_event) => keygen_event.into_java(&env).forget(), - Err(error) => { - log::error!( - "{}", - error.display_chain_with_msg("Failed to request to generate wireguard key") - ); - JObject::null() - } - } - } else { - JObject::null() - } -} - -#[no_mangle] -#[allow(non_snake_case)] -pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_verifyWireguardKey< - 'env, ->( - env: JNIEnv<'env>, - _: JObject<'_>, - daemon_interface_address: jlong, -) -> JObject<'env> { - let env = JnixEnv::from(env); - - if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { - match daemon_interface.verify_wireguard_key() { - Ok(key_is_valid) => env - .new_object( - &env.get_class("java/lang/Boolean"), - "(Z)V", - &[JValue::Bool(key_is_valid as jboolean)], - ) - .expect("Failed to create Boolean Java object"), - Err(error) => { - log::error!( - "{}", - error.display_chain_with_msg("Failed to verify wireguard key") - ); - JObject::null() - } - } - } else { - JObject::null() - } -} - -#[no_mangle] -#[allow(non_snake_case)] pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_getAccountHistory<'env>( env: JNIEnv<'env>, _: JObject<'_>, @@ -768,25 +768,118 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_clearAc #[no_mangle] #[allow(non_snake_case)] -pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_setAccount( - env: JNIEnv<'_>, +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_loginAccount<'env>( + env: JNIEnv<'env>, _: JObject<'_>, daemon_interface_address: jlong, accountToken: JString<'_>, +) -> JObject<'env> { + let env = JnixEnv::from(env); + + if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { + let account = String::from_java(&env, accountToken); + let result = daemon_interface.login_account(account); + + if let Err(ref error) = &result { + log_request_error("login account", error); + } + + LoginResult::from(result).into_java(&env).forget() + } else { + LoginResult::OtherError.into_java(&env).forget() + } +} + +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_logoutAccount( + _: JNIEnv<'_>, + _: JObject<'_>, + daemon_interface_address: jlong, ) { + if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { + if let Err(error) = daemon_interface.logout_account() { + log::error!("{}", error.display_chain_with_msg("Failed to log out")); + } + } +} + +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_getDevice<'env>( + env: JNIEnv<'env>, + _: JObject<'_>, + daemon_interface_address: jlong, +) -> JObject<'env> { let env = JnixEnv::from(env); if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { - let account = Option::from_java(&env, accountToken); + match daemon_interface.get_device() { + Ok(key) => key.into_java(&env).forget(), + Err(error) => { + log::error!("{}", error.display_chain_with_msg("Failed to get device")); + JObject::null() + } + } + } else { + JObject::null() + } +} - if let Err(error) = daemon_interface.set_account(account) { - log::error!("{}", error.display_chain_with_msg("Failed to set account")); +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_listDevices<'env>( + env: JNIEnv<'env>, + _: JObject<'_>, + daemon_interface_address: jlong, + account_token: JString<'_>, +) -> JObject<'env> { + let env = JnixEnv::from(env); + + if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { + let token = String::from_java(&env, account_token); + match daemon_interface.list_devices(token) { + Ok(key) => key.into_java(&env).forget(), + Err(error) => { + log::error!("{}", error.display_chain_with_msg("Failed to list devices")); + JObject::null() + } } + } else { + JObject::null() } } #[no_mangle] #[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_removeDevice<'env>( + env: JNIEnv<'env>, + _: JObject<'_>, + daemon_interface_address: jlong, + account_token: JString<'_>, + device_id: JString<'_>, +) -> JObject<'env> { + let env = JnixEnv::from(env); + + let result = if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { + let token = String::from_java(&env, account_token); + let device_id = String::from_java(&env, device_id); + let raw_result = daemon_interface.remove_device(token, device_id); + + if let Err(ref error) = &raw_result { + log_request_error("remove device", error); + } + + RemoveDeviceResult::from(raw_result) + } else { + RemoveDeviceResult::OtherError + }; + + result.into_java(&env).forget() +} + +#[no_mangle] +#[allow(non_snake_case)] pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_setAllowLan( env: JNIEnv<'_>, _: JObject<'_>, diff --git a/mullvad-management-interface/src/types.rs b/mullvad-management-interface/src/types.rs index b9cbef3ed5..45e0c1c37c 100644 --- a/mullvad-management-interface/src/types.rs +++ b/mullvad-management-interface/src/types.rs @@ -210,9 +210,9 @@ impl From<mullvad_types::device::Device> for Device { impl From<mullvad_types::device::DeviceEvent> for DeviceEvent { fn from(event: mullvad_types::device::DeviceEvent) -> Self { DeviceEvent { - device: event.device.map(|(account_token, device)| DeviceConfig { - account_token, - device: Some(Device::from(device)), + device: event.device.map(|config| DeviceConfig { + account_token: config.token, + device: Some(Device::from(config.device)), }), remote: event.remote, } diff --git a/mullvad-types/src/device.rs b/mullvad-types/src/device.rs index 0ef6a4d753..294529592f 100644 --- a/mullvad-types/src/device.rs +++ b/mullvad-types/src/device.rs @@ -1,4 +1,6 @@ use crate::{account::AccountToken, wireguard}; +#[cfg(target_os = "android")] +use jnix::IntoJava; use serde::{Deserialize, Serialize}; use talpid_types::net::wireguard::PublicKey; @@ -10,9 +12,12 @@ pub type DeviceName = String; /// Contains data for a device returned by the API. #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] pub struct Device { pub id: DeviceId, pub name: DeviceName, + #[cfg_attr(target_os = "android", jnix(map = "|key| *key.as_bytes()"))] pub pubkey: PublicKey, } @@ -51,6 +56,8 @@ impl From<DeviceData> for Device { /// [`DeviceData`] excluding the private key. #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] pub struct DeviceConfig { pub token: AccountToken, pub device: Device, @@ -67,9 +74,11 @@ impl From<DeviceData> for DeviceConfig { /// Emitted when logging in or out of an account, or when the device changes. #[derive(Clone, Debug)] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] pub struct DeviceEvent { /// Device that was affected. - pub device: Option<(AccountToken, Device)>, + pub device: Option<DeviceConfig>, /// Indicates whether the change was initiated remotely or by the daemon. pub remote: bool, } @@ -77,14 +86,17 @@ pub struct DeviceEvent { impl DeviceEvent { pub fn new(data: Option<DeviceData>, remote: bool) -> DeviceEvent { DeviceEvent { - device: data.map(|data| (data.token, data.device)), + device: data.map(DeviceConfig::from), remote, } } pub fn from_device(data: DeviceData, remote: bool) -> DeviceEvent { DeviceEvent { - device: Some((data.token, data.device)), + device: Some(DeviceConfig { + token: data.token, + device: data.device, + }), remote, } } @@ -100,6 +112,8 @@ impl DeviceEvent { /// Emitted when a device is removed using the `RemoveDevice` RPC. /// This is not sent by a normal logout or when it is revoked remotely. #[derive(Clone, Debug)] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] pub struct RemoveDeviceEvent { pub account_token: AccountToken, pub removed_device: Device, |
