diff options
| author | Albin <albin@mullvad.net> | 2022-03-15 13:56:35 +0100 |
|---|---|---|
| committer | Albin <albin@mullvad.net> | 2022-03-23 12:48:53 +0100 |
| commit | c9cdb3a6d813d113ef0fe144ee9830660f59b73f (patch) | |
| tree | 5b966c827874b8b10a18c3280349b3ef90a12351 | |
| parent | 928d05a421b000b070543f78ad0b9a647df22bf8 (diff) | |
| download | mullvadvpn-c9cdb3a6d813d113ef0fe144ee9830660f59b73f.tar.xz mullvadvpn-c9cdb3a6d813d113ef0fe144ee9830660f59b73f.zip | |
Initial Android adaption of daemon device API
Initial limited adaption of the daemon device changes. Makes it possible
to launch, login and connect. However, there are some limitiations:
* State is not properly handled thoughout the app.
* The app itself doesn't expose any device functionality to the user.
* The wireguard key actions are disabled (regenerate and verify).
* Accounts are not remembered across app restart.
14 files changed, 157 insertions, 22 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt new file mode 100644 index 0000000000..01a8e6ee37 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt @@ -0,0 +1,12 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class Device( + val id: String, + val name: String, + val pubkey: ByteArray, + val ports: ArrayList<String> +) : Parcelable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceConfig.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceConfig.kt new file mode 100644 index 0000000000..b8f5664e30 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceConfig.kt @@ -0,0 +1,10 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class DeviceConfig( + val token: String, + val device: Device +) : Parcelable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt new file mode 100644 index 0000000000..24703e7066 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt @@ -0,0 +1,10 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class DeviceEvent( + val device: DeviceConfig?, + val remote: Boolean +) : Parcelable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LoginResult.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LoginResult.kt new file mode 100644 index 0000000000..29fb68203d --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LoginResult.kt @@ -0,0 +1,13 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +enum class LoginResult : Parcelable { + Ok, + InvalidAccount, + MaxDevicesReached, + RpcError, + OtherError +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt new file mode 100644 index 0000000000..3080d7f10a --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt @@ -0,0 +1,11 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class RemoveDeviceEvent( + val accountToken: String, + val removedDevice: Device, + val newDevices: ArrayList<Device> +) : Parcelable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceResult.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceResult.kt new file mode 100644 index 0000000000..67bf165a37 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceResult.kt @@ -0,0 +1,12 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +enum class RemoveDeviceResult : Parcelable { + Ok, + NotFound, + RpcError, + OtherError +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt index 03ef69c638..2fcae9f4ea 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt @@ -5,7 +5,6 @@ import kotlinx.parcelize.Parcelize @Parcelize data class Settings( - val accountToken: String?, val relaySettings: RelaySettings, val allowLan: Boolean, val autoConnect: Boolean, 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 8470f314d7..f4b7993e38 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 @@ -1,21 +1,29 @@ package net.mullvad.mullvadvpn.service import net.mullvad.mullvadvpn.model.AppVersionInfo +import net.mullvad.mullvadvpn.model.Device +import net.mullvad.mullvadvpn.model.DeviceConfig +import net.mullvad.mullvadvpn.model.DeviceEvent import net.mullvad.mullvadvpn.model.DnsOptions import net.mullvad.mullvadvpn.model.GeoIpLocation import net.mullvad.mullvadvpn.model.GetAccountDataResult import net.mullvad.mullvadvpn.model.KeygenEvent +import net.mullvad.mullvadvpn.model.LoginResult import net.mullvad.mullvadvpn.model.PublicKey import net.mullvad.mullvadvpn.model.RelayList import net.mullvad.mullvadvpn.model.RelaySettingsUpdate +import net.mullvad.mullvadvpn.model.RemoveDeviceEvent +import net.mullvad.mullvadvpn.model.RemoveDeviceResult import net.mullvad.mullvadvpn.model.Settings import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.model.VoucherSubmissionResult import net.mullvad.talpid.util.EventNotifier -class MullvadDaemon(val vpnService: MullvadVpnService) { +class MullvadDaemon(vpnService: MullvadVpnService) { protected var daemonInterfaceAddress = 0L + var onDeviceChange = EventNotifier<DeviceConfig?>(null) + var onDeviceRemoved = EventNotifier<RemoveDeviceEvent?>(null) val onSettingsChange = EventNotifier<Settings?>(null) var onTunnelStateChange = EventNotifier<TunnelState>(TunnelState.Disconnected) @@ -29,6 +37,8 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { initialize(vpnService, vpnService.cacheDir.absolutePath, vpnService.filesDir.absolutePath) onSettingsChange.notify(getSettings()) + onDeviceChange.notify(getDevice()) + onTunnelStateChange.notify(getState() ?: TunnelState.Disconnected) } @@ -98,8 +108,20 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { clearAccountHistory(daemonInterfaceAddress) } - fun setAccount(accountToken: String?) { - // TODO: replace with login+logout + fun loginAccount(accountToken: String): LoginResult { + return loginAccount(daemonInterfaceAddress, accountToken) + } + + fun logoutAccount() = logoutAccount(daemonInterfaceAddress) + + fun listDevices(accountToken: String?): List<Device>? { + return listDevices(daemonInterfaceAddress, accountToken) + } + + fun getDevice(): DeviceConfig? = getDevice(daemonInterfaceAddress) + + fun removeDevice(accountToken: String?, device: Device) { + removeDevice(daemonInterfaceAddress, accountToken, device.id) } fun setAllowLan(allowLan: Boolean) { @@ -151,6 +173,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { cacheDirectory: String, resourceDirectory: String ) + private external fun deinitialize() private external fun connect(daemonInterfaceAddress: Long) @@ -160,6 +183,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { daemonInterfaceAddress: Long, accountToken: String ): GetAccountDataResult + private external fun getAccountHistory(daemonInterfaceAddress: Long): String? private external fun getWwwAuthToken(daemonInterfaceAddress: Long): String? private external fun getCurrentLocation(daemonInterfaceAddress: Long): GeoIpLocation? @@ -171,8 +195,24 @@ 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 loginAccount(daemonInterfaceAddress: Long, accountToken: String?) + private external fun loginAccount( + daemonInterfaceAddress: Long, + accountToken: String? + ): LoginResult + private external fun logoutAccount(daemonInterfaceAddress: Long) + private external fun listDevices( + daemonInterfaceAddress: Long, + accountToken: String? + ): List<Device>? + + private external fun getDevice(daemonInterfaceAddress: Long): DeviceConfig? + private external fun removeDevice( + daemonInterfaceAddress: Long, + accountToken: String?, + deviceId: String + ): RemoveDeviceResult + private external fun setAllowLan(daemonInterfaceAddress: Long, allowLan: Boolean) private external fun setAutoConnect(daemonInterfaceAddress: Long, alwaysOn: Boolean) private external fun setDnsOptions(daemonInterfaceAddress: Long, dnsOptions: DnsOptions) @@ -182,10 +222,12 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { daemonInterfaceAddress: Long, voucher: String ): VoucherSubmissionResult + private external fun updateRelaySettings( daemonInterfaceAddress: Long, update: RelaySettingsUpdate ) + private external fun verifyWireguardKey(daemonInterfaceAddress: Long): Boolean? private fun notifyAppVersionInfoEvent(appVersionInfo: AppVersionInfo) { @@ -207,4 +249,12 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { private fun notifyDaemonStopped() { onDaemonStopped?.invoke() } + + private fun notifyDeviceEvent(event: DeviceEvent) { + onDeviceChange.notify(event.device) + } + + private fun notifyRemoveDeviceEvent(event: RemoveDeviceEvent) { + onDeviceRemoved.notify(event) + } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt index 6875655e46..e057ed9154 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt @@ -201,7 +201,8 @@ class MullvadVpnService : TalpidVpnService() { if (settings != null) { handlePendingAction(settings) } else { - restart() + // TODO: Skip until device integration is ready. + // restart() } } } @@ -231,11 +232,12 @@ class MullvadVpnService : TalpidVpnService() { private fun handlePendingAction(settings: Settings) { when (pendingAction) { PendingAction.Connect -> { - if (settings.accountToken != null) { - connectionProxy.connect() - } else { - openUi() - } + // TODO: Skip until device integration is ready. + // if (settings.accountToken != null) { + // connectionProxy.connect() + // } else { + // openUi() + // } } PendingAction.Disconnect -> connectionProxy.disconnect() null -> return diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt index 768b00e1b5..830860a45d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt @@ -61,7 +61,8 @@ class AccountCache(private val endpoint: ServiceEndpoint) { get() = endpoint.settingsListener.accountNumberNotifier.latestEvent set(value) { jobTracker.newBackgroundJob("setAccount") { - daemon.await().setAccount(value) + // TODO: Skip until device integration is ready. + // daemon.await().setAccount(value) } } @@ -214,12 +215,14 @@ class AccountCache(private val endpoint: ServiceEndpoint) { } } - daemon.await().setAccount(maybeAccount) + // TODO: Skip until device integration is ready. + // daemon.await().setAccount(maybeAccount) } private suspend fun doLogout() { if (accountNumber != null) { - daemon.await().setAccount(null) + // TODO: Skip until device integration is ready. + // daemon.await().setAccount(null) } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/KeyStatusListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/KeyStatusListener.kt index 70ac7ef827..679f74e9af 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/KeyStatusListener.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/KeyStatusListener.kt @@ -59,8 +59,14 @@ class KeyStatusListener(endpoint: ServiceEndpoint) { try { for (command in channel) { when (command) { - Command.GenerateKey -> generateKey() - Command.VerifyKey -> verifyKey() + Command.GenerateKey -> { + // TODO: Skip until device integration is ready. + // generateKey() + } + Command.VerifyKey -> { + // TODO: Skip until device integration is ready. + // verifyKey() + } } } } catch (exception: ClosedReceiveChannelException) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt index c903fc9e37..cabf03ee5c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt @@ -94,9 +94,10 @@ class SettingsListener(endpoint: ServiceEndpoint) { private fun handleNewSettings(newSettings: Settings?) { if (newSettings != null) { synchronized(this) { - if (settings?.accountToken != newSettings.accountToken) { - accountNumberNotifier.notify(newSettings.accountToken) - } + // TODO: Skip until device integration is ready. + // if (settings?.accountToken != newSettings.accountToken) { + // accountNumberNotifier.notify(newSettings.accountToken) + // } if (settings?.tunnelOptions?.dnsOptions != newSettings.tunnelOptions.dnsOptions) { dnsOptionsNotifier.notify(newSettings.tunnelOptions.dnsOptions) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt index cb8fac65c4..7d956d2bd8 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt @@ -49,9 +49,10 @@ class SettingsListener(private val connection: Messenger, eventDispatcher: Event } private fun handleNewSettings(newSettings: Settings) { - if (settings?.accountToken != newSettings.accountToken) { - accountNumberNotifier.notify(newSettings.accountToken) - } + // TODO: Skip until device integration is ready. + // if (settings?.accountToken != newSettings.accountToken) { + // accountNumberNotifier.notify(newSettings.accountToken) + // } if (settings?.tunnelOptions?.dnsOptions != newSettings.tunnelOptions.dnsOptions) { dnsOptionsNotifier.notify(newSettings.tunnelOptions.dnsOptions) diff --git a/mullvad-jni/src/classes.rs b/mullvad-jni/src/classes.rs index eaa5d215ae..3aceb3a820 100644 --- a/mullvad-jni/src/classes.rs +++ b/mullvad-jni/src/classes.rs @@ -8,6 +8,10 @@ pub const CLASSES: &[&str] = &[ "net/mullvad/mullvadvpn/model/Constraint$Any", "net/mullvad/mullvadvpn/model/Constraint$Only", "net/mullvad/mullvadvpn/model/DnsOptions", + "net/mullvad/mullvadvpn/model/Device", + "net/mullvad/mullvadvpn/model/DeviceConfig", + "net/mullvad/mullvadvpn/model/DeviceEvent", + "net/mullvad/mullvadvpn/model/RemoveDeviceEvent", "net/mullvad/mullvadvpn/model/GeoIpLocation", "net/mullvad/mullvadvpn/model/GetAccountDataResult$Ok", "net/mullvad/mullvadvpn/model/GetAccountDataResult$InvalidAccount", @@ -39,6 +43,7 @@ pub const CLASSES: &[&str] = &[ "net/mullvad/mullvadvpn/model/TunnelState$Disconnecting", "net/mullvad/mullvadvpn/model/VoucherSubmission", "net/mullvad/mullvadvpn/model/VoucherSubmissionResult", + "net/mullvad/mullvadvpn/model/LoginResult", "net/mullvad/mullvadvpn/model/WireguardEndpointData", "net/mullvad/mullvadvpn/service/MullvadDaemon", "net/mullvad/mullvadvpn/service/MullvadVpnService", |
