summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-11-22 12:18:30 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-11-22 12:18:30 -0300
commitef3f533878771a470e5600e8dde13011365bb5d3 (patch)
treee5665e1dc2e337f9dedc857eb084db159f1e5a31
parent37261f0d5c214b926053329bf24d8e7bd1efbfcb (diff)
parent6677eede732ab9ba6687229caf498d0df8874f11 (diff)
downloadmullvadvpn-ef3f533878771a470e5600e8dde13011365bb5d3.tar.xz
mullvadvpn-ef3f533878771a470e5600e8dde13011365bb5d3.zip
Merge branch 'use-jnix'
-rw-r--r--Cargo.lock32
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectActionButton.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectionStatus.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt8
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt4
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt14
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/SwitchLocationButton.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt9
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/ConnectionProxy.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt8
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomTunnelEndpoint.kt3
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt20
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt3
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt4
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt4
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCountry.kt8
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayTunnels.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardEndpointData.kt3
-rw-r--r--android/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/talpid/tun_provider/TunConfig.kt7
-rw-r--r--android/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt7
-rw-r--r--mullvad-jni/Cargo.toml2
-rw-r--r--mullvad-jni/src/classes.rs58
-rw-r--r--mullvad-jni/src/from_java.rs30
-rw-r--r--mullvad-jni/src/into_java.rs811
-rw-r--r--mullvad-jni/src/is_null.rs2
-rw-r--r--mullvad-jni/src/jni_event_listener.rs51
-rw-r--r--mullvad-jni/src/lib.rs200
-rw-r--r--mullvad-jni/src/vpn_service_tun_provider.rs48
-rw-r--r--mullvad-types/Cargo.toml3
-rw-r--r--mullvad-types/src/account.rs5
-rw-r--r--mullvad-types/src/custom_tunnel.rs6
-rw-r--r--mullvad-types/src/location.rs8
-rw-r--r--mullvad-types/src/relay_constraints.rs13
-rw-r--r--mullvad-types/src/relay_list.rs24
-rw-r--r--mullvad-types/src/settings/mod.rs11
-rw-r--r--mullvad-types/src/states.rs4
-rw-r--r--mullvad-types/src/version.rs4
-rw-r--r--mullvad-types/src/wireguard.rs10
-rw-r--r--talpid-core/Cargo.toml4
-rw-r--r--talpid-core/src/tunnel/tun_provider/mod.rs30
-rw-r--r--talpid-types/Cargo.toml3
-rw-r--r--talpid-types/src/net/mod.rs10
-rw-r--r--talpid-types/src/tunnel.rs8
48 files changed, 475 insertions, 1053 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5e57baa371..5c6db6f0b8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -820,7 +820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "jni"
-version = "0.13.1"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -837,6 +837,27 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "jnix"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "jni 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jnix-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "jnix-macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "jsonrpc-client-core"
version = "0.5.0"
source = "git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b#68aac55b6ddff5e1242594b54f7f9149fe215ff7"
@@ -1294,7 +1315,7 @@ dependencies = [
"err-derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "jni 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jnix 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1390,6 +1411,7 @@ dependencies = [
"chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"err-derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jnix 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mullvad-paths 0.1.0",
@@ -2408,6 +2430,7 @@ dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jnix 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.2 (git+https://github.com/mullvad/jsonrpc?branch=mullvad-fork)",
"jsonrpc-macros 8.0.1 (git+https://github.com/mullvad/jsonrpc?branch=mullvad-fork)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2494,6 +2517,7 @@ dependencies = [
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"err-derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jnix 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3211,8 +3235,10 @@ dependencies = [
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum ipnetwork 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf7762e2b430ad80cbef992a1d4f15a15d9d4068bdd8e57acb0a3d21d0cf7f40"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
-"checksum jni 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e00f1fd30a82a801f8bf38bcb0895088a0013cde111acb713c0824edc372aa4"
+"checksum jni 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1981310da491a4f0f815238097d0d43d8072732b5ae5f8bd0d8eadf5bf245402"
"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
+"checksum jnix 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "14b5a1a12dc744e2a28311fec971a88ed9ff44cc882fe8ed0824609e32b0d36a"
+"checksum jnix-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6381b00e7628f4d3971b9851ffff686dffdde91d15c5ab16621fcee7a52a946"
"checksum jsonrpc-client-core 0.5.0 (git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b)" = "<none>"
"checksum jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f29cb249837420fb0cee7fb0fbf1d22679e121b160e71bb5e0d90b9df241c23e"
"checksum jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e642eb74423b9dfcb4512fda167148746b76f788a823cd712fadf409f31d302"
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectActionButton.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectActionButton.kt
index ae731b4161..4789d27a2c 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectActionButton.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectActionButton.kt
@@ -19,9 +19,9 @@ class ConnectActionButton(val parentView: View) {
is TunnelState.Disconnected -> disconnected()
is TunnelState.Disconnecting -> {
when (value.actionAfterDisconnect) {
- is ActionAfterDisconnect.Nothing -> disconnected()
- is ActionAfterDisconnect.Block -> connected()
- is ActionAfterDisconnect.Reconnect -> connecting()
+ ActionAfterDisconnect.Nothing -> disconnected()
+ ActionAfterDisconnect.Block -> connected()
+ ActionAfterDisconnect.Reconnect -> connecting()
}
}
is TunnelState.Connecting -> connecting()
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectionStatus.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectionStatus.kt
index 17f44a64da..664156dd04 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectionStatus.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectionStatus.kt
@@ -18,9 +18,9 @@ class ConnectionStatus(val parentView: View, val resources: Resources) {
when (state) {
is TunnelState.Disconnecting -> {
when (state.actionAfterDisconnect) {
- is ActionAfterDisconnect.Nothing -> disconnected()
- is ActionAfterDisconnect.Block -> connected()
- is ActionAfterDisconnect.Reconnect -> connecting()
+ ActionAfterDisconnect.Nothing -> disconnected()
+ ActionAfterDisconnect.Block -> connected()
+ ActionAfterDisconnect.Reconnect -> connecting()
}
}
is TunnelState.Disconnected -> disconnected()
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt
index c99d8d7a0d..80890e56ca 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt
@@ -40,7 +40,7 @@ class ForegroundNotificationManager(val service: Service, val connectionProxy: C
reconnecting =
(value is TunnelState.Disconnecting &&
- value.actionAfterDisconnect is ActionAfterDisconnect.Reconnect) ||
+ value.actionAfterDisconnect == ActionAfterDisconnect.Reconnect) ||
(value is TunnelState.Connecting && reconnecting)
updateNotification()
@@ -62,7 +62,7 @@ class ForegroundNotificationManager(val service: Service, val connectionProxy: C
is TunnelState.Connected -> R.string.secured
is TunnelState.Disconnecting -> {
when (state.actionAfterDisconnect) {
- is ActionAfterDisconnect.Reconnect -> R.string.reconnecting
+ ActionAfterDisconnect.Reconnect -> R.string.reconnecting
else -> R.string.disconnecting
}
}
@@ -80,7 +80,7 @@ class ForegroundNotificationManager(val service: Service, val connectionProxy: C
is TunnelState.Connected -> R.string.disconnect
is TunnelState.Disconnecting -> {
when (state.actionAfterDisconnect) {
- is ActionAfterDisconnect.Reconnect -> R.string.cancel
+ ActionAfterDisconnect.Reconnect -> R.string.cancel
else -> R.string.connect
}
}
@@ -98,7 +98,7 @@ class ForegroundNotificationManager(val service: Service, val connectionProxy: C
is TunnelState.Connected -> KEY_DISCONNECT_ACTION
is TunnelState.Disconnecting -> {
when (state.actionAfterDisconnect) {
- is ActionAfterDisconnect.Reconnect -> KEY_DISCONNECT_ACTION
+ ActionAfterDisconnect.Reconnect -> KEY_DISCONNECT_ACTION
else -> KEY_CONNECT_ACTION
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt
index 9278bb315f..9210712365 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt
@@ -99,8 +99,8 @@ class LocationInfo(val parentView: View, val context: Context) {
private fun showInAddress(endpoint: Endpoint?) {
if (endpoint != null) {
val transportProtocol = when (endpoint.protocol) {
- is TransportProtocol.Tcp -> context.getString(R.string.tcp)
- is TransportProtocol.Udp -> context.getString(R.string.udp)
+ TransportProtocol.Tcp -> context.getString(R.string.tcp)
+ TransportProtocol.Udp -> context.getString(R.string.udp)
}
inAddress.text = context.getString(
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt
index 352fe4dd71..f6fd4c9e1e 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt
@@ -124,9 +124,9 @@ class NotificationBanner(
when (state) {
is TunnelState.Disconnecting -> {
when (state.actionAfterDisconnect) {
- is ActionAfterDisconnect.Nothing -> return false
- is ActionAfterDisconnect.Block -> showBlocking(null)
- is ActionAfterDisconnect.Reconnect -> showBlocking(null)
+ ActionAfterDisconnect.Nothing -> return false
+ ActionAfterDisconnect.Block -> showBlocking(null)
+ ActionAfterDisconnect.Reconnect -> showBlocking(null)
}
}
is TunnelState.Disconnected -> return false
@@ -179,12 +179,12 @@ class NotificationBanner(
is BlockReason.TapAdapterProblem -> R.string.tap_adapter_problem
is BlockReason.ParameterGeneration -> {
when (reason.error) {
- is ParameterGenerationError.NoMatchingRelay -> R.string.no_matching_relay
- is ParameterGenerationError.NoMatchingBridgeRelay -> {
+ ParameterGenerationError.NoMatchingRelay -> R.string.no_matching_relay
+ ParameterGenerationError.NoMatchingBridgeRelay -> {
R.string.no_matching_bridge_relay
}
- is ParameterGenerationError.NoWireguardKey -> R.string.no_wireguard_key
- is ParameterGenerationError.CustomTunnelHostResultionError -> {
+ ParameterGenerationError.NoWireguardKey -> R.string.no_wireguard_key
+ ParameterGenerationError.CustomTunnelHostResultionError -> {
R.string.custom_tunnel_host_resolution_error
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/SwitchLocationButton.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/SwitchLocationButton.kt
index f6561e4da1..930c1ff626 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/SwitchLocationButton.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/SwitchLocationButton.kt
@@ -57,9 +57,9 @@ class SwitchLocationButton(val parentView: View, val resources: Resources) {
is TunnelState.Disconnected -> showLocation()
is TunnelState.Disconnecting -> {
when (state.actionAfterDisconnect) {
- is ActionAfterDisconnect.Nothing -> showLocation()
- is ActionAfterDisconnect.Block -> showLocation()
- is ActionAfterDisconnect.Reconnect -> showLabel()
+ ActionAfterDisconnect.Nothing -> showLocation()
+ ActionAfterDisconnect.Block -> showLocation()
+ ActionAfterDisconnect.Reconnect -> showLabel()
}
}
is TunnelState.Connecting -> showLabel()
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt
index e51e43630f..141e373ccf 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt
@@ -152,16 +152,15 @@ class WireguardKeyFragment : Fragment() {
publicKeyAge.setText(formatKeyDateCreated(key.dateCreated))
- if (keyState.verified != null) {
- if (keyState.verified) {
+ keyState.verified?.let { verified ->
+ if (verified) {
setStatusMessage(R.string.wireguard_key_valid, R.color.green)
} else {
setStatusMessage(R.string.wireguard_key_invalid, R.color.red)
}
}
- if (keyState.replacementFailure != null) {
- showKeygenFailure(keyState.replacementFailure)
- }
+
+ keyState.replacementFailure?.let { error -> showKeygenFailure(error) }
}
is KeygenEvent.Failure -> {
showKeygenFailure(keyState.failure)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/ConnectionProxy.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/ConnectionProxy.kt
index 06c594ed1c..ee429ca18d 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/ConnectionProxy.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/ConnectionProxy.kt
@@ -105,7 +105,7 @@ class ConnectionProxy(val context: Context, val daemon: Deferred<MullvadDaemon>)
return false
} else {
scheduleToResetAnticipatedState()
- uiState = TunnelState.Disconnecting(ActionAfterDisconnect.Nothing())
+ uiState = TunnelState.Disconnecting(ActionAfterDisconnect.Nothing)
return true
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
index 94444c5d46..0057f034d8 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
@@ -49,9 +49,9 @@ class LocationInfoCache(
}
is TunnelState.Disconnecting -> {
when (value.actionAfterDisconnect) {
- is ActionAfterDisconnect.Nothing -> location = lastKnownRealLocation
- is ActionAfterDisconnect.Block -> location = null
- is ActionAfterDisconnect.Reconnect -> location = locationFromSelectedRelay()
+ ActionAfterDisconnect.Nothing -> location = lastKnownRealLocation
+ ActionAfterDisconnect.Block -> location = null
+ ActionAfterDisconnect.Reconnect -> location = locationFromSelectedRelay()
}
}
is TunnelState.Blocked -> location = null
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt
index 32b3c10ba7..7d016821a4 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt
@@ -7,6 +7,7 @@ import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.MainActivity
import net.mullvad.mullvadvpn.MullvadDaemon
import net.mullvad.mullvadvpn.model.Constraint
+import net.mullvad.mullvadvpn.model.RelayConstraints
import net.mullvad.mullvadvpn.model.RelaySettings
import net.mullvad.mullvadvpn.relaylist.RelayItem
import net.mullvad.mullvadvpn.relaylist.RelayList
@@ -78,7 +79,8 @@ class RelayListListener(val parentActivity: MainActivity) {
synchronized(this) {
val relayList = this.relayList
- relaySettings = newRelaySettings ?: RelaySettings.RelayConstraints(Constraint.Any())
+ relaySettings = newRelaySettings
+ ?: RelaySettings.Normal(RelayConstraints(Constraint.Any()))
if (relayList != null) {
relayListChanged(relayList)
@@ -100,8 +102,8 @@ class RelayListListener(val parentActivity: MainActivity) {
when (relaySettings) {
is RelaySettings.CustomTunnelEndpoint -> return null
- is RelaySettings.RelayConstraints -> {
- val location = relaySettings.location
+ is RelaySettings.Normal -> {
+ val location = relaySettings.relayConstraints.location
return relayList?.findItemForLocation(location, true)
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomTunnelEndpoint.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomTunnelEndpoint.kt
new file mode 100644
index 0000000000..05dd38a80b
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomTunnelEndpoint.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.model
+
+class CustomTunnelEndpoint()
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt
index f2f85453f9..0e1e801895 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt
@@ -1,11 +1,21 @@
package net.mullvad.mullvadvpn.model
sealed class KeygenEvent {
- class NewKey(
- val publicKey: PublicKey,
- val verified: Boolean?,
- val replacementFailure: KeygenFailure?
- ) : KeygenEvent()
+ class NewKey(val publicKey: PublicKey) : KeygenEvent() {
+ var verified: Boolean? = false
+ private set
+ var replacementFailure: KeygenFailure? = null
+ private set
+
+ constructor(
+ publicKey: PublicKey,
+ verified: Boolean?,
+ replacementFailure: KeygenFailure?
+ ) : this(publicKey) {
+ this.verified = verified
+ this.replacementFailure = replacementFailure
+ }
+ }
class Failure(val failure: KeygenFailure) : KeygenEvent()
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt
index 01c2eb9481..f260baf6e2 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt
@@ -1,3 +1,6 @@
package net.mullvad.mullvadvpn.model
-data class Relay(val hostname: String, val hasWireguardTunnels: Boolean, val active: Boolean)
+data class Relay(val hostname: String, val active: Boolean, val tunnels: RelayTunnels) {
+ val hasWireguardTunnels
+ get() = tunnels.wireguard.isEmpty()
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt
new file mode 100644
index 0000000000..e4e6d6634e
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.model
+
+data class RelayConstraints(val location: Constraint<LocationConstraint>)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt
index 57a4a0e6c5..bc9ec3327a 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt
@@ -1,3 +1,5 @@
package net.mullvad.mullvadvpn.model
-data class RelayList(val countries: List<RelayListCountry>)
+import java.util.ArrayList
+
+data class RelayList(val countries: ArrayList<RelayListCountry>)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt
index 406d2b5ca5..329120350d 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt
@@ -1,3 +1,5 @@
package net.mullvad.mullvadvpn.model
-data class RelayListCity(val name: String, val code: String, val relays: List<Relay>)
+import java.util.ArrayList
+
+data class RelayListCity(val name: String, val code: String, val relays: ArrayList<Relay>)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCountry.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCountry.kt
index de6817b03c..035cb52d19 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCountry.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCountry.kt
@@ -1,3 +1,9 @@
package net.mullvad.mullvadvpn.model
-data class RelayListCountry(val name: String, val code: String, val cities: List<RelayListCity>)
+import java.util.ArrayList
+
+data class RelayListCountry(
+ val name: String,
+ val code: String,
+ val cities: ArrayList<RelayListCity>
+)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
index 6fded8f9c5..cb53911883 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
@@ -2,5 +2,5 @@ package net.mullvad.mullvadvpn.model
sealed class RelaySettings {
class CustomTunnelEndpoint() : RelaySettings()
- class RelayConstraints(var location: Constraint<LocationConstraint>) : RelaySettings()
+ class Normal(var relayConstraints: RelayConstraints) : RelaySettings()
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayTunnels.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayTunnels.kt
new file mode 100644
index 0000000000..5946620566
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayTunnels.kt
@@ -0,0 +1,5 @@
+package net.mullvad.mullvadvpn.model
+
+import java.util.ArrayList
+
+data class RelayTunnels(val wireguard: ArrayList<WireguardEndpointData>)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardEndpointData.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardEndpointData.kt
new file mode 100644
index 0000000000..1d39f1170d
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardEndpointData.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.model
+
+class WireguardEndpointData()
diff --git a/android/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt b/android/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt
index d4372f54ed..013399dc52 100644
--- a/android/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt
+++ b/android/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt
@@ -1,6 +1,5 @@
package net.mullvad.talpid.net
-sealed class TransportProtocol {
- class Tcp : TransportProtocol()
- class Udp : TransportProtocol()
+enum class TransportProtocol {
+ Tcp, Udp
}
diff --git a/android/src/main/kotlin/net/mullvad/talpid/tun_provider/TunConfig.kt b/android/src/main/kotlin/net/mullvad/talpid/tun_provider/TunConfig.kt
index fe8d0f55c7..761462013e 100644
--- a/android/src/main/kotlin/net/mullvad/talpid/tun_provider/TunConfig.kt
+++ b/android/src/main/kotlin/net/mullvad/talpid/tun_provider/TunConfig.kt
@@ -1,10 +1,11 @@
package net.mullvad.talpid.tun_provider
import java.net.InetAddress
+import java.util.ArrayList
data class TunConfig(
- val addresses: List<InetAddress>,
- val dnsServers: List<InetAddress>,
- val routes: List<InetNetwork>,
+ val addresses: ArrayList<InetAddress>,
+ val dnsServers: ArrayList<InetAddress>,
+ val routes: ArrayList<InetNetwork>,
val mtu: Int
)
diff --git a/android/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt b/android/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt
index c352ab06ad..c20d5b33e4 100644
--- a/android/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt
+++ b/android/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt
@@ -1,7 +1,5 @@
package net.mullvad.talpid.tunnel
-sealed class ActionAfterDisconnect {
- class Nothing : ActionAfterDisconnect()
- class Block : ActionAfterDisconnect()
- class Reconnect : ActionAfterDisconnect()
+enum class ActionAfterDisconnect {
+ Nothing, Block, Reconnect
}
diff --git a/android/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt b/android/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt
index 92547a02b4..51fa8ac461 100644
--- a/android/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt
+++ b/android/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt
@@ -1,8 +1,5 @@
package net.mullvad.talpid.tunnel
-sealed class ParameterGenerationError {
- class NoMatchingRelay : ParameterGenerationError()
- class NoMatchingBridgeRelay : ParameterGenerationError()
- class NoWireguardKey : ParameterGenerationError()
- class CustomTunnelHostResultionError : ParameterGenerationError()
+enum class ParameterGenerationError {
+ NoMatchingRelay, NoMatchingBridgeRelay, NoWireguardKey, CustomTunnelHostResultionError
}
diff --git a/mullvad-jni/Cargo.toml b/mullvad-jni/Cargo.toml
index b8b1711e10..138a1be50e 100644
--- a/mullvad-jni/Cargo.toml
+++ b/mullvad-jni/Cargo.toml
@@ -13,7 +13,7 @@ crate_type = ["cdylib"]
err-derive = "0.2.1"
futures = "0.1"
ipnetwork = "0.15"
-jni = "0.13"
+jnix = { version = "0.1", features = ["derive"] }
jsonrpc-client-core = "0.5"
jsonrpc-core = "8"
lazy_static = "1"
diff --git a/mullvad-jni/src/classes.rs b/mullvad-jni/src/classes.rs
new file mode 100644
index 0000000000..39b7713932
--- /dev/null
+++ b/mullvad-jni/src/classes.rs
@@ -0,0 +1,58 @@
+pub const CLASSES: &[&str] = &[
+ "java/lang/Boolean",
+ "java/net/InetAddress",
+ "java/net/InetSocketAddress",
+ "java/util/ArrayList",
+ "net/mullvad/mullvadvpn/model/AccountData",
+ "net/mullvad/mullvadvpn/model/AppVersionInfo",
+ "net/mullvad/mullvadvpn/model/Constraint$Any",
+ "net/mullvad/mullvadvpn/model/Constraint$Only",
+ "net/mullvad/mullvadvpn/model/GeoIpLocation",
+ "net/mullvad/mullvadvpn/model/GetAccountDataResult$Ok",
+ "net/mullvad/mullvadvpn/model/GetAccountDataResult$InvalidAccount",
+ "net/mullvad/mullvadvpn/model/GetAccountDataResult$RpcError",
+ "net/mullvad/mullvadvpn/model/GetAccountDataResult$OtherError",
+ "net/mullvad/mullvadvpn/model/KeygenEvent$NewKey",
+ "net/mullvad/mullvadvpn/model/KeygenEvent$Failure",
+ "net/mullvad/mullvadvpn/model/KeygenFailure$TooManyKeys",
+ "net/mullvad/mullvadvpn/model/KeygenFailure$GenerationFailure",
+ "net/mullvad/mullvadvpn/model/LocationConstraint$City",
+ "net/mullvad/mullvadvpn/model/LocationConstraint$Country",
+ "net/mullvad/mullvadvpn/model/LocationConstraint$Hostname",
+ "net/mullvad/mullvadvpn/model/PublicKey",
+ "net/mullvad/mullvadvpn/model/Relay",
+ "net/mullvad/mullvadvpn/model/RelayConstraints",
+ "net/mullvad/mullvadvpn/model/RelayList",
+ "net/mullvad/mullvadvpn/model/RelayListCity",
+ "net/mullvad/mullvadvpn/model/RelayListCountry",
+ "net/mullvad/mullvadvpn/model/RelaySettings$CustomTunnelEndpoint",
+ "net/mullvad/mullvadvpn/model/RelaySettings$Normal",
+ "net/mullvad/mullvadvpn/model/RelaySettingsUpdate$CustomTunnelEndpoint",
+ "net/mullvad/mullvadvpn/model/RelaySettingsUpdate$RelayConstraintsUpdate",
+ "net/mullvad/mullvadvpn/model/RelayTunnels",
+ "net/mullvad/mullvadvpn/model/Settings",
+ "net/mullvad/mullvadvpn/model/TunnelState$Blocked",
+ "net/mullvad/mullvadvpn/model/TunnelState$Connected",
+ "net/mullvad/mullvadvpn/model/TunnelState$Connecting",
+ "net/mullvad/mullvadvpn/model/TunnelState$Disconnected",
+ "net/mullvad/mullvadvpn/model/TunnelState$Disconnecting",
+ "net/mullvad/mullvadvpn/model/WireguardEndpointData",
+ "net/mullvad/mullvadvpn/MullvadDaemon",
+ "net/mullvad/mullvadvpn/MullvadVpnService",
+ "net/mullvad/talpid/net/Endpoint",
+ "net/mullvad/talpid/net/TransportProtocol",
+ "net/mullvad/talpid/net/TunnelEndpoint",
+ "net/mullvad/talpid/tun_provider/InetNetwork",
+ "net/mullvad/talpid/tun_provider/TunConfig",
+ "net/mullvad/talpid/tunnel/ActionAfterDisconnect",
+ "net/mullvad/talpid/tunnel/BlockReason$AuthFailed",
+ "net/mullvad/talpid/tunnel/BlockReason$Ipv6Unavailable",
+ "net/mullvad/talpid/tunnel/BlockReason$SetFirewallPolicyError",
+ "net/mullvad/talpid/tunnel/BlockReason$SetDnsError",
+ "net/mullvad/talpid/tunnel/BlockReason$StartTunnelError",
+ "net/mullvad/talpid/tunnel/BlockReason$ParameterGeneration",
+ "net/mullvad/talpid/tunnel/BlockReason$IsOffline",
+ "net/mullvad/talpid/tunnel/BlockReason$TapAdapterProblem",
+ "net/mullvad/talpid/tunnel/ParameterGenerationError",
+ "net/mullvad/talpid/TalpidVpnService",
+];
diff --git a/mullvad-jni/src/from_java.rs b/mullvad-jni/src/from_java.rs
index c016134f23..9cccd738d7 100644
--- a/mullvad-jni/src/from_java.rs
+++ b/mullvad-jni/src/from_java.rs
@@ -1,7 +1,7 @@
-use crate::{get_class, is_null::IsNull};
-use jni::{
- objects::{JObject, JString},
- JNIEnv,
+use crate::is_null::IsNull;
+use jnix::{
+ jni::objects::{JObject, JString},
+ JnixEnv,
};
use mullvad_types::relay_constraints::{
Constraint, LocationConstraint, RelayConstraintsUpdate, RelaySettingsUpdate,
@@ -11,7 +11,7 @@ use std::fmt::Debug;
pub trait FromJava<'env> {
type JavaType: 'env;
- fn from_java(env: &JNIEnv<'env>, source: Self::JavaType) -> Self;
+ fn from_java(env: &JnixEnv<'env>, source: Self::JavaType) -> Self;
}
impl<'env, T> FromJava<'env> for Option<T>
@@ -21,7 +21,7 @@ where
{
type JavaType = T::JavaType;
- fn from_java(env: &JNIEnv<'env>, source: Self::JavaType) -> Self {
+ fn from_java(env: &JnixEnv<'env>, source: Self::JavaType) -> Self {
if source.is_null() {
None
} else {
@@ -33,7 +33,7 @@ where
impl<'env> FromJava<'env> for String {
type JavaType = JString<'env>;
- fn from_java(env: &JNIEnv<'env>, source: Self::JavaType) -> Self {
+ fn from_java(env: &JnixEnv<'env>, source: Self::JavaType) -> Self {
String::from(
env.get_string(source)
.expect("Failed to convert from Java String"),
@@ -48,7 +48,7 @@ where
{
type JavaType = JObject<'env>;
- fn from_java(env: &JNIEnv<'env>, source: Self::JavaType) -> Self {
+ fn from_java(env: &JnixEnv<'env>, source: Self::JavaType) -> Self {
if is_instance_of(env, source, "net/mullvad/mullvadvpn/model/Constraint$Any") {
Constraint::Any
} else if is_instance_of(env, source, "net/mullvad/mullvadvpn/model/Constraint$Only") {
@@ -64,7 +64,7 @@ where
impl<'env> FromJava<'env> for LocationConstraint {
type JavaType = JObject<'env>;
- fn from_java(env: &JNIEnv<'env>, source: Self::JavaType) -> Self {
+ fn from_java(env: &JnixEnv<'env>, source: Self::JavaType) -> Self {
let country_class = "net/mullvad/mullvadvpn/model/LocationConstraint$Country";
let city_class = "net/mullvad/mullvadvpn/model/LocationConstraint$City";
let hostname_class = "net/mullvad/mullvadvpn/model/LocationConstraint$Hostname";
@@ -100,7 +100,7 @@ impl<'env> FromJava<'env> for LocationConstraint {
impl<'env> FromJava<'env> for RelayConstraintsUpdate {
type JavaType = JObject<'env>;
- fn from_java(env: &JNIEnv<'env>, source: Self::JavaType) -> Self {
+ fn from_java(env: &JnixEnv<'env>, source: Self::JavaType) -> Self {
let location = get_object_field(
env,
source,
@@ -120,7 +120,7 @@ impl<'env> FromJava<'env> for RelayConstraintsUpdate {
impl<'env> FromJava<'env> for RelaySettingsUpdate {
type JavaType = JObject<'env>;
- fn from_java(env: &JNIEnv<'env>, source: Self::JavaType) -> Self {
+ fn from_java(env: &JnixEnv<'env>, source: Self::JavaType) -> Self {
let custom_tunnel_endpoint_class =
"net/mullvad/mullvadvpn/model/RelaySettingsUpdate$CustomTunnelEndpoint";
let relay_constraints_update_class =
@@ -137,18 +137,18 @@ impl<'env> FromJava<'env> for RelaySettingsUpdate {
}
fn is_instance_of<'env>(
- env: &JNIEnv<'env>,
+ env: &JnixEnv<'env>,
object: JObject<'env>,
class_name: &'static str,
) -> bool {
- let class = get_class(class_name);
+ let class = env.get_class(class_name);
env.is_instance_of(object, &class)
.expect("Failed to check if an object is an instance of a specified class")
}
fn get_string_field<'env>(
- env: &JNIEnv<'env>,
+ env: &JnixEnv<'env>,
object: JObject<'env>,
field_name: &str,
) -> JString<'env> {
@@ -161,7 +161,7 @@ fn get_string_field<'env>(
}
fn get_object_field<'env>(
- env: &JNIEnv<'env>,
+ env: &JnixEnv<'env>,
object: JObject<'env>,
field_name: &str,
field_type: &str,
diff --git a/mullvad-jni/src/into_java.rs b/mullvad-jni/src/into_java.rs
deleted file mode 100644
index bc97ac4bc0..0000000000
--- a/mullvad-jni/src/into_java.rs
+++ /dev/null
@@ -1,811 +0,0 @@
-use crate::{daemon_interface, get_class};
-use ipnetwork::IpNetwork;
-use jni::{
- objects::{JList, JObject, JString, JValue},
- signature::JavaType,
- sys::{jboolean, jint, jshort, jsize},
- JNIEnv,
-};
-use mullvad_types::{
- account::AccountData,
- location::GeoIpLocation,
- relay_constraints::{Constraint, LocationConstraint, RelayConstraints, RelaySettings},
- relay_list::{Relay, RelayList, RelayListCity, RelayListCountry},
- settings::Settings,
- states::TunnelState,
- version::AppVersionInfo,
- wireguard::{KeygenEvent, PublicKey},
- CustomTunnelEndpoint,
-};
-use std::{
- fmt::Debug,
- net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
-};
-use talpid_core::tunnel::tun_provider::TunConfig;
-use talpid_types::{
- net::{Endpoint, TransportProtocol, TunnelEndpoint},
- tunnel::{ActionAfterDisconnect, BlockReason, ParameterGenerationError},
-};
-
-pub trait IntoJava<'env> {
- type JavaType;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType;
-}
-
-impl<'env, T> IntoJava<'env> for Option<T>
-where
- T: IntoJava<'env>,
- T::JavaType: From<JObject<'env>>,
-{
- type JavaType = T::JavaType;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- Some(data) => data.into_java(env),
- None => T::JavaType::from(JObject::null()),
- }
- }
-}
-
-impl<'env> IntoJava<'env> for String {
- type JavaType = JString<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- env.new_string(&self).expect("Failed to create Java String")
- }
-}
-
-impl<'env, T> IntoJava<'env> for Vec<T>
-where
- T: IntoJava<'env>,
- JObject<'env>: From<T::JavaType>,
-{
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("java/util/ArrayList");
- let initial_capacity = self.len();
- let parameters = [JValue::Int(initial_capacity as jint)];
-
- let list_object = env
- .new_object(&class, "(I)V", &parameters)
- .expect("Failed to create ArrayList object");
-
- let list =
- JList::from_env(env, list_object).expect("Failed to create JList from ArrayList");
-
- for element in self {
- let java_element = env.auto_local(JObject::from(element.into_java(env)));
-
- list.add(java_element.as_obj())
- .expect("Failed to add element to ArrayList");
- }
-
- list_object
- }
-}
-
-impl<'array, 'env> IntoJava<'env> for &'array [u8] {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let size = self.len();
- let array = env
- .new_byte_array(size as jsize)
- .expect("Failed to create a Java array of bytes");
-
- let data = unsafe { std::slice::from_raw_parts(self.as_ptr() as *const i8, size) };
-
- env.set_byte_array_region(array, 0, data)
- .expect("Failed to copy bytes to Java array");
-
- JObject::from(array)
- }
-}
-
-fn ipvx_addr_into_java<'env>(original_octets: &[u8], env: &JNIEnv<'env>) -> JObject<'env> {
- let class = get_class("java/net/InetAddress");
-
- let constructor = env
- .get_static_method_id(&class, "getByAddress", "([B)Ljava/net/InetAddress;")
- .expect("Failed to get InetAddress.getByAddress method ID");
-
- let octets_array = env
- .new_byte_array(original_octets.len() as i32)
- .expect("Failed to create byte array to store IP address");
-
- let octet_data: Vec<i8> = original_octets
- .into_iter()
- .map(|octet| *octet as i8)
- .collect();
-
- env.set_byte_array_region(octets_array, 0, &octet_data)
- .expect("Failed to copy IP address octets to byte array");
-
- let octets = env.auto_local(JObject::from(octets_array));
- let result = env
- .call_static_method_unchecked(
- &class,
- constructor,
- JavaType::Object("java/net/InetAddress".to_owned()),
- &[JValue::Object(octets.as_obj())],
- )
- .expect("Failed to create InetAddress Java object");
-
- match result {
- JValue::Object(object) => JObject::from(object.into_inner()),
- value => {
- panic!(
- "InetAddress.getByAddress returned an invalid value: {:?}",
- value
- );
- }
- }
-}
-
-impl<'env> IntoJava<'env> for Ipv4Addr {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- ipvx_addr_into_java(self.octets().as_ref(), env)
- }
-}
-
-impl<'env> IntoJava<'env> for Ipv6Addr {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- ipvx_addr_into_java(self.octets().as_ref(), env)
- }
-}
-
-impl<'env> IntoJava<'env> for IpAddr {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- IpAddr::V4(address) => address.into_java(env),
- IpAddr::V6(address) => address.into_java(env),
- }
- }
-}
-
-impl<'env> IntoJava<'env> for SocketAddr {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("java/net/InetSocketAddress");
- let ip_address = env.auto_local(self.ip().into_java(env));
- let port = self.port() as jint;
- let parameters = [JValue::Object(ip_address.as_obj()), JValue::Int(port)];
-
- env.new_object(&class, "(Ljava/net/InetAddress;I)V", &parameters)
- .expect("Failed to create InetSocketAddress Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for IpNetwork {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/talpid/tun_provider/InetNetwork");
- let address = env.auto_local(self.ip().into_java(env));
- let prefix_length = self.prefix() as jshort;
- let parameters = [
- JValue::Object(address.as_obj()),
- JValue::Short(prefix_length),
- ];
-
- env.new_object(&class, "(Ljava/net/InetAddress;S)V", &parameters)
- .expect("Failed to create InetNetwork Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for PublicKey {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/PublicKey");
- let key = env.auto_local(self.key.as_bytes().into_java(env));
- let date_created = env.auto_local(*self.created.to_string().into_java(env));
- let parameters = [
- JValue::Object(key.as_obj()),
- JValue::Object(date_created.as_obj()),
- ];
-
- env.new_object(&class, "([BLjava/lang/String;)V", &parameters)
- .expect("Failed to create PublicKey Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for AppVersionInfo {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/AppVersionInfo");
- let current_is_supported = self.current_is_supported as jboolean;
- let current_is_outdated = self.current_is_outdated as jboolean;
- let latest_stable = env.auto_local(*self.latest_stable.into_java(env));
- let latest = env.auto_local(*self.latest.into_java(env));
- let parameters = [
- JValue::Bool(current_is_supported),
- JValue::Bool(current_is_outdated),
- JValue::Object(latest_stable.as_obj()),
- JValue::Object(latest.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(ZZLjava/lang/String;Ljava/lang/String;)V",
- &parameters,
- )
- .expect("Failed to create AppVersionInfo Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for AccountData {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/AccountData");
- let account_expiry = env.auto_local(JObject::from(self.expiry.to_string().into_java(env)));
- let parameters = [JValue::Object(account_expiry.as_obj())];
-
- env.new_object(&class, "(Ljava/lang/String;)V", &parameters)
- .expect("Failed to create AccountData Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for TunConfig {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/talpid/tun_provider/TunConfig");
- let addresses = env.auto_local(self.addresses.into_java(env));
- let dns_servers = env.auto_local(self.dns_servers.into_java(env));
- let routes = env.auto_local(self.routes.into_java(env));
- let mtu = self.mtu as jint;
- let parameters = [
- JValue::Object(addresses.as_obj()),
- JValue::Object(dns_servers.as_obj()),
- JValue::Object(routes.as_obj()),
- JValue::Int(mtu),
- ];
-
- env.new_object(
- &class,
- "(Ljava/util/List;Ljava/util/List;Ljava/util/List;I)V",
- &parameters,
- )
- .expect("Failed to create TunConfig Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for TransportProtocol {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class_name = match self {
- TransportProtocol::Tcp => "net/mullvad/talpid/net/TransportProtocol$Tcp",
- TransportProtocol::Udp => "net/mullvad/talpid/net/TransportProtocol$Udp",
- };
- let class = get_class(class_name);
-
- env.new_object(&class, "()V", &[])
- .expect("Failed to create TransportProtocol sub-class variant Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for Endpoint {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/talpid/net/Endpoint");
- let address = env.auto_local(self.address.into_java(env));
- let protocol = env.auto_local(self.protocol.into_java(env));
- let parameters = [
- JValue::Object(address.as_obj()),
- JValue::Object(protocol.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(Ljava/net/InetSocketAddress;Lnet/mullvad/talpid/net/TransportProtocol;)V",
- &parameters,
- )
- .expect("Failed to create Endpoint sub-class variant Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for TunnelEndpoint {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/talpid/net/TunnelEndpoint");
- let endpoint = env.auto_local(self.endpoint.into_java(env));
- let parameters = [JValue::Object(endpoint.as_obj())];
-
- env.new_object(&class, "(Lnet/mullvad/talpid/net/Endpoint;)V", &parameters)
- .expect("Failed to create TunnelEndpoint sub-class variant Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for GeoIpLocation {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/GeoIpLocation");
- let ipv4 = env.auto_local(self.ipv4.into_java(env));
- let ipv6 = env.auto_local(self.ipv6.into_java(env));
- let country = env.auto_local(JObject::from(self.country.into_java(env)));
- let city = env.auto_local(JObject::from(self.city.into_java(env)));
- let hostname = env.auto_local(JObject::from(self.hostname.into_java(env)));
- let parameters = [
- JValue::Object(ipv4.as_obj()),
- JValue::Object(ipv6.as_obj()),
- JValue::Object(country.as_obj()),
- JValue::Object(city.as_obj()),
- JValue::Object(hostname.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(Ljava/net/InetAddress;Ljava/net/InetAddress;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
- &parameters,
- )
- .expect("Failed to create GeoIpLocation Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for RelayList {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/RelayList");
- let relay_countries = env.auto_local(self.countries.into_java(env));
- let parameters = [JValue::Object(relay_countries.as_obj())];
-
- env.new_object(&class, "(Ljava/util/List;)V", &parameters)
- .expect("Failed to create RelayList Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for RelayListCountry {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/RelayListCountry");
- let name = env.auto_local(JObject::from(self.name.into_java(env)));
- let code = env.auto_local(JObject::from(self.code.into_java(env)));
- let relay_cities = env.auto_local(self.cities.into_java(env));
- let parameters = [
- JValue::Object(name.as_obj()),
- JValue::Object(code.as_obj()),
- JValue::Object(relay_cities.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V",
- &parameters,
- )
- .expect("Failed to create RelayListCountry Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for RelayListCity {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/RelayListCity");
- let name = env.auto_local(JObject::from(self.name.into_java(env)));
- let code = env.auto_local(JObject::from(self.code.into_java(env)));
- let relays = env.auto_local(self.relays.into_java(env));
- let parameters = [
- JValue::Object(name.as_obj()),
- JValue::Object(code.as_obj()),
- JValue::Object(relays.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V",
- &parameters,
- )
- .expect("Failed to create RelayListCity Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for Relay {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/Relay");
- let hostname = env.auto_local(JObject::from(self.hostname.into_java(env)));
- let has_wireguard_tunnels = (!self.tunnels.wireguard.is_empty()) as jboolean;
- let parameters = [
- JValue::Object(hostname.as_obj()),
- JValue::Bool(has_wireguard_tunnels),
- JValue::Bool(self.active as jboolean),
- ];
-
- env.new_object(&class, "(Ljava/lang/String;ZZ)V", &parameters)
- .expect("Failed to create Relay Java object")
- }
-}
-
-impl<'env, T> IntoJava<'env> for Constraint<T>
-where
- T: Clone + Eq + Debug + IntoJava<'env>,
- JObject<'env>: From<T::JavaType>,
-{
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- Constraint::Any => {
- let class = get_class("net/mullvad/mullvadvpn/model/Constraint$Any");
-
- env.new_object(&class, "()V", &[])
- .expect("Failed to create Constraint.Any Java object")
- }
- Constraint::Only(constraint) => {
- let class = get_class("net/mullvad/mullvadvpn/model/Constraint$Only");
- let value = env.auto_local(JObject::from(constraint.into_java(env)));
- let parameters = [JValue::Object(value.as_obj())];
-
- env.new_object(&class, "(Ljava/lang/Object;)V", &parameters)
- .expect("Failed to create Constraint.Only Java object")
- }
- }
- }
-}
-
-impl<'env> IntoJava<'env> for LocationConstraint {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- LocationConstraint::Country(country_code) => {
- let class = get_class("net/mullvad/mullvadvpn/model/LocationConstraint$Country");
- let country = env.auto_local(JObject::from(country_code.into_java(env)));
- let parameters = [JValue::Object(country.as_obj())];
-
- env.new_object(&class, "(Ljava/lang/String;)V", &parameters)
- .expect("Failed to create LocationConstraint.Country Java object")
- }
- LocationConstraint::City(country_code, city_code) => {
- let class = get_class("net/mullvad/mullvadvpn/model/LocationConstraint$City");
- let country = env.auto_local(JObject::from(country_code.into_java(env)));
- let city = env.auto_local(JObject::from(city_code.into_java(env)));
- let parameters = [
- JValue::Object(country.as_obj()),
- JValue::Object(city.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(Ljava/lang/String;Ljava/lang/String;)V",
- &parameters,
- )
- .expect("Failed to create LocationConstraint.City Java object")
- }
- LocationConstraint::Hostname(country_code, city_code, hostname) => {
- let class = get_class("net/mullvad/mullvadvpn/model/LocationConstraint$Hostname");
- let country = env.auto_local(JObject::from(country_code.into_java(env)));
- let city = env.auto_local(JObject::from(city_code.into_java(env)));
- let hostname = env.auto_local(JObject::from(hostname.into_java(env)));
- let parameters = [
- JValue::Object(country.as_obj()),
- JValue::Object(city.as_obj()),
- JValue::Object(hostname.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
- &parameters,
- )
- .expect("Failed to create LocationConstraint.Hostname Java object")
- }
- }
- }
-}
-
-impl<'env> IntoJava<'env> for RelaySettings {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- RelaySettings::CustomTunnelEndpoint(endpoint) => endpoint.into_java(env),
- RelaySettings::Normal(relay_constraints) => relay_constraints.into_java(env),
- }
- }
-}
-
-impl<'env> IntoJava<'env> for CustomTunnelEndpoint {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/RelaySettings$CustomTunnelEndpoint");
-
- env.new_object(&class, "()V", &[])
- .expect("Failed to create CustomTunnelEndpoint Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for KeygenEvent {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- KeygenEvent::NewKey(public_key) => {
- let class = get_class("net/mullvad/mullvadvpn/model/KeygenEvent$NewKey");
- let java_public_key = env.auto_local(public_key.into_java(env));
-
- let parameters = [
- JValue::Object(java_public_key.as_obj()),
- JValue::Object(JObject::null()),
- JValue::Object(JObject::null()),
- ];
-
- env.new_object(
- &class,
- "(Lnet/mullvad/mullvadvpn/model/PublicKey;Ljava/lang/Boolean;Lnet/mullvad/mullvadvpn/model/KeygenFailure;)V",
- &parameters,
- )
- .expect("Failed to create KeygenEvent.NewKey Java object")
- }
- KeygenEvent::TooManyKeys => {
- let failure_class =
- get_class("net/mullvad/mullvadvpn/model/KeygenFailure$TooManyKeys");
-
- let failure = env
- .new_object(&failure_class, "()V", &[])
- .expect("Failed to create KeygenFailure.TooManyKeys Java object");
-
- let class = get_class("net/mullvad/mullvadvpn/model/KeygenEvent$Failure");
- env.new_object(
- &class,
- "(Lnet/mullvad/mullvadvpn/model/KeygenFailure;)V",
- &[JValue::Object(failure)],
- )
- .expect("Failed to create KeygenEvent.Failure Java object")
- }
- KeygenEvent::GenerationFailure => {
- let failure_class =
- get_class("net/mullvad/mullvadvpn/model/KeygenFailure$GenerationFailure");
- let failure = env
- .new_object(&failure_class, "()V", &[])
- .expect("Failed to create KeygenFailure.GenerationFailure Java object");
-
- let class = get_class("net/mullvad/mullvadvpn/model/KeygenEvent$Failure");
- env.new_object(
- &class,
- "(Lnet/mullvad/mullvadvpn/model/KeygenFailure;)V",
- &[JValue::Object(failure)],
- )
- .expect("Failed to create KeygenEvent.GenerationFailure Java object")
- }
- }
- }
-}
-
-impl<'env> IntoJava<'env> for RelayConstraints {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/RelaySettings$RelayConstraints");
- let location = env.auto_local(self.location.into_java(env));
- let parameters = [JValue::Object(location.as_obj())];
-
- env.new_object(
- &class,
- "(Lnet/mullvad/mullvadvpn/model/Constraint;)V",
- &parameters,
- )
- .expect("Failed to create RelaySettings.RelayConstraints Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for Settings {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class = get_class("net/mullvad/mullvadvpn/model/Settings");
- let account_token = env.auto_local(JObject::from(self.get_account_token().into_java(env)));
- let relay_settings = env.auto_local(self.get_relay_settings().into_java(env));
- let parameters = [
- JValue::Object(account_token.as_obj()),
- JValue::Object(relay_settings.as_obj()),
- ];
-
- env.new_object(
- &class,
- "(Ljava/lang/String;Lnet/mullvad/mullvadvpn/model/RelaySettings;)V",
- &parameters,
- )
- .expect("Failed to create Settings Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for ActionAfterDisconnect {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let variant = match self {
- ActionAfterDisconnect::Nothing => "Nothing",
- ActionAfterDisconnect::Block => "Block",
- ActionAfterDisconnect::Reconnect => "Reconnect",
- };
- let class_name = format!(
- "net/mullvad/talpid/tunnel/ActionAfterDisconnect${}",
- variant
- );
- let class = get_class(&class_name);
-
- env.new_object(&class, "()V", &[])
- .expect("Failed to create ActionAfterDisconnect sub-class variant Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for BlockReason {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let variant = match self {
- BlockReason::AuthFailed(reason) => {
- let class = get_class("net/mullvad/talpid/tunnel/BlockReason$AuthFailed");
- let reason = env.auto_local(JObject::from(reason.into_java(env)));
- let parameters = [JValue::Object(reason.as_obj())];
-
- return env
- .new_object(&class, "(Ljava/lang/String;)V", &parameters)
- .expect("Failed to create BlockReason.AuthFailed Java object");
- }
- BlockReason::Ipv6Unavailable => "Ipv6Unavailable",
- BlockReason::SetFirewallPolicyError => "SetFirewallPolicyError",
- BlockReason::SetDnsError => "SetDnsError",
- BlockReason::StartTunnelError => "StartTunnelError",
- BlockReason::TunnelParameterError(reason) => {
- let class = get_class("net/mullvad/talpid/tunnel/BlockReason$ParameterGeneration");
- let reason = env.auto_local(JObject::from(reason.into_java(env)));
- let parameters = [JValue::Object(reason.as_obj())];
- return env
- .new_object(
- &class,
- "(Lnet/mullvad/talpid/tunnel/ParameterGenerationError;)V",
- &parameters,
- )
- .expect("Failed to create BlockReason.ParameterGeneration Java object");
- }
- BlockReason::IsOffline => "IsOffline",
- BlockReason::TapAdapterProblem => "TapAdapterProblem",
- };
- let class_name = format!("net/mullvad/talpid/tunnel/BlockReason${}", variant);
- let class = get_class(&class_name);
-
- env.new_object(&class, "()V", &[])
- .expect("Failed to create BlockReason sub-class variant Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for ParameterGenerationError {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- let class_variant = match self {
- ParameterGenerationError::NoMatchingRelay => "NoMatchingRelay",
- ParameterGenerationError::NoMatchingBridgeRelay => "NoMatchingBridgeRelay ",
- ParameterGenerationError::NoWireguardKey => "NoWireguardKey",
- ParameterGenerationError::CustomTunnelHostResultionError => {
- "CustomTunnelHostResultionError"
- }
- };
- let class_name = format!(
- "net/mullvad/talpid/tunnel/ParameterGenerationError${}",
- class_variant
- );
- let class = get_class(&class_name);
- env.new_object(&class, "()V", &[])
- .expect("Failed to create ParameterGenerationError sub-class variant Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for TunnelState {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- TunnelState::Disconnected => {
- let class = get_class("net/mullvad/mullvadvpn/model/TunnelState$Disconnected");
-
- env.new_object(&class, "()V", &[])
- }
- TunnelState::Connecting { endpoint, location } => {
- let class = get_class("net/mullvad/mullvadvpn/model/TunnelState$Connecting");
- let endpoint = env.auto_local(endpoint.into_java(env));
- let location = env.auto_local(location.into_java(env));
- let parameters = [
- JValue::Object(endpoint.as_obj()),
- JValue::Object(location.as_obj()),
- ];
- let signature =
- "(Lnet/mullvad/talpid/net/TunnelEndpoint;Lnet/mullvad/mullvadvpn/model/GeoIpLocation;)V";
-
- env.new_object(&class, signature, &parameters)
- }
- TunnelState::Connected { endpoint, location } => {
- let class = get_class("net/mullvad/mullvadvpn/model/TunnelState$Connected");
- let endpoint = env.auto_local(endpoint.into_java(env));
- let location = env.auto_local(location.into_java(env));
- let parameters = [
- JValue::Object(endpoint.as_obj()),
- JValue::Object(location.as_obj()),
- ];
- let signature =
- "(Lnet/mullvad/talpid/net/TunnelEndpoint;Lnet/mullvad/mullvadvpn/model/GeoIpLocation;)V";
-
- env.new_object(&class, signature, &parameters)
- }
- TunnelState::Disconnecting(action_after_disconnect) => {
- let class = get_class("net/mullvad/mullvadvpn/model/TunnelState$Disconnecting");
- let after_disconnect = env.auto_local(action_after_disconnect.into_java(env));
- let parameters = [JValue::Object(after_disconnect.as_obj())];
- let signature = "(Lnet/mullvad/talpid/tunnel/ActionAfterDisconnect;)V";
-
- env.new_object(&class, signature, &parameters)
- }
- TunnelState::Blocked(block_reason) => {
- let class = get_class("net/mullvad/mullvadvpn/model/TunnelState$Blocked");
- let reason = env.auto_local(block_reason.into_java(env));
- let parameters = [JValue::Object(reason.as_obj())];
- let signature = "(Lnet/mullvad/talpid/tunnel/BlockReason;)V";
-
- env.new_object(&class, signature, &parameters)
- }
- }
- .expect("Failed to create TunnelState sub-class variant Java object")
- }
-}
-
-impl<'env> IntoJava<'env> for Result<AccountData, daemon_interface::Error> {
- type JavaType = JObject<'env>;
-
- fn into_java(self, env: &JNIEnv<'env>) -> Self::JavaType {
- match self {
- Ok(data) => {
- let class = get_class("net/mullvad/mullvadvpn/model/GetAccountDataResult$Ok");
- let java_account_data = env.auto_local(data.into_java(&env));
- let parameters = [JValue::Object(java_account_data.as_obj())];
-
- env.new_object(
- &class,
- "(Lnet/mullvad/mullvadvpn/model/AccountData;)V",
- &parameters,
- )
- .expect("Failed to create GetAccountDataResult.Ok Java object")
- }
- Err(error) => {
- let class_name = match error {
- daemon_interface::Error::RpcError(jsonrpc_client_core::Error(
- jsonrpc_client_core::ErrorKind::JsonRpcError(jsonrpc_core::Error {
- code: jsonrpc_core::ErrorCode::ServerError(-200),
- ..
- }),
- _,
- )) => "net/mullvad/mullvadvpn/model/GetAccountDataResult$InvalidAccount",
- daemon_interface::Error::RpcError(_) => {
- "net/mullvad/mullvadvpn/model/GetAccountDataResult$RpcError"
- }
- _ => "net/mullvad/mullvadvpn/model/GetAccountDataResult$OtherError",
- };
- let class = get_class(class_name);
-
- env.new_object(&class, "()V", &[])
- .expect("Failed to create a GetAccountDataResult error sub-class Java object")
- }
- }
- }
-}
diff --git a/mullvad-jni/src/is_null.rs b/mullvad-jni/src/is_null.rs
index 628fc4c81a..9353d7211c 100644
--- a/mullvad-jni/src/is_null.rs
+++ b/mullvad-jni/src/is_null.rs
@@ -1,4 +1,4 @@
-use jni::objects::{JObject, JString};
+use jnix::jni::objects::{JObject, JString};
use std::ops::Deref;
pub trait IsNull {
diff --git a/mullvad-jni/src/jni_event_listener.rs b/mullvad-jni/src/jni_event_listener.rs
index 5725171ca1..45020111fa 100644
--- a/mullvad-jni/src/jni_event_listener.rs
+++ b/mullvad-jni/src/jni_event_listener.rs
@@ -1,8 +1,9 @@
-use crate::{get_class, into_java::IntoJava};
-use jni::{
- objects::{GlobalRef, JMethodID, JObject, JValue},
- signature::{JavaType, Primitive},
- AttachGuard, JNIEnv,
+use jnix::{
+ jni::{
+ objects::{GlobalRef, JMethodID, JObject, JValue},
+ signature::{JavaType, Primitive},
+ },
+ IntoJava, JnixEnv,
};
use mullvad_daemon::EventListener;
use mullvad_types::{
@@ -16,13 +17,13 @@ use talpid_types::ErrorExt;
#[error(no_from)]
pub enum Error {
#[error(display = "Failed to create global reference to MullvadDaemon Java object")]
- CreateGlobalReference(#[error(source)] jni::errors::Error),
+ CreateGlobalReference(#[error(source)] jnix::jni::errors::Error),
#[error(display = "Failed to find {} method", _0)]
- FindMethod(&'static str, #[error(source)] jni::errors::Error),
+ FindMethod(&'static str, #[error(source)] jnix::jni::errors::Error),
#[error(display = "Failed to retrieve Java VM instance")]
- GetJvmInstance(#[error(source)] jni::errors::Error),
+ GetJvmInstance(#[error(source)] jnix::jni::errors::Error),
}
enum Event {
@@ -37,7 +38,7 @@ enum Event {
pub struct JniEventListener(mpsc::Sender<Event>);
impl JniEventListener {
- pub fn spawn(env: &JNIEnv, mullvad_daemon: &JObject) -> Result<Self, Error> {
+ pub fn spawn(env: &JnixEnv, mullvad_daemon: &JObject) -> Result<Self, Error> {
JniEventHandler::spawn(env, mullvad_daemon)
}
}
@@ -65,7 +66,7 @@ impl EventListener for JniEventListener {
}
struct JniEventHandler<'env> {
- env: AttachGuard<'env>,
+ env: JnixEnv<'env>,
mullvad_ipc_client: JObject<'env>,
notify_app_version_info_event: JMethodID<'env>,
notify_keygen_event: JMethodID<'env>,
@@ -77,7 +78,7 @@ struct JniEventHandler<'env> {
impl JniEventHandler<'_> {
pub fn spawn(
- old_env: &JNIEnv,
+ old_env: &JnixEnv,
old_mullvad_ipc_client: &JObject,
) -> Result<JniEventListener, Error> {
let (tx, rx) = mpsc::channel();
@@ -87,10 +88,14 @@ impl JniEventHandler<'_> {
.map_err(Error::CreateGlobalReference)?;
thread::spawn(move || match jvm.attach_current_thread() {
- Ok(env) => match JniEventHandler::new(env, mullvad_ipc_client.as_obj(), rx) {
- Ok(mut listener) => listener.run(),
- Err(error) => log::error!("{}", error.display_chain()),
- },
+ Ok(attach_guard) => {
+ let env = JnixEnv::from(attach_guard.clone());
+
+ match JniEventHandler::new(env, mullvad_ipc_client.as_obj(), rx) {
+ Ok(mut listener) => listener.run(),
+ Err(error) => log::error!("{}", error.display_chain()),
+ }
+ }
Err(error) => {
log::error!(
"{}",
@@ -107,11 +112,11 @@ impl JniEventHandler<'_> {
impl<'env> JniEventHandler<'env> {
fn new(
- env: AttachGuard<'env>,
+ env: JnixEnv<'env>,
mullvad_ipc_client: JObject<'env>,
events: mpsc::Receiver<Event>,
) -> Result<Self, Error> {
- let class = get_class("net/mullvad/mullvadvpn/MullvadDaemon");
+ let class = env.get_class("net/mullvad/mullvadvpn/MullvadDaemon");
let notify_app_version_info_event = Self::get_method_id(
&env,
&class,
@@ -156,7 +161,7 @@ impl<'env> JniEventHandler<'env> {
}
fn get_method_id(
- env: &AttachGuard<'env>,
+ env: &JnixEnv<'env>,
class: &GlobalRef,
method: &'static str,
signature: &str,
@@ -180,7 +185,7 @@ impl<'env> JniEventHandler<'env> {
}
fn handle_keygen_event(&self, event: KeygenEvent) {
- let java_keygen_event = self.env.auto_local(event.into_java(&self.env));
+ let java_keygen_event = event.into_java(&self.env);
let result = self.env.call_method_unchecked(
self.mullvad_ipc_client,
@@ -198,7 +203,7 @@ impl<'env> JniEventHandler<'env> {
}
fn handle_relay_list_event(&self, relay_list: RelayList) {
- let java_relay_list = self.env.auto_local(relay_list.into_java(&self.env));
+ let java_relay_list = relay_list.into_java(&self.env);
let result = self.env.call_method_unchecked(
self.mullvad_ipc_client,
@@ -216,7 +221,7 @@ impl<'env> JniEventHandler<'env> {
}
fn handle_settings(&self, settings: Settings) {
- let java_settings = self.env.auto_local(settings.into_java(&self.env));
+ let java_settings = settings.into_java(&self.env);
let result = self.env.call_method_unchecked(
self.mullvad_ipc_client,
@@ -234,7 +239,7 @@ impl<'env> JniEventHandler<'env> {
}
fn handle_tunnel_event(&self, event: TunnelState) {
- let java_tunnel_state = self.env.auto_local(event.into_java(&self.env));
+ let java_tunnel_state = event.into_java(&self.env);
let result = self.env.call_method_unchecked(
self.mullvad_ipc_client,
@@ -252,7 +257,7 @@ impl<'env> JniEventHandler<'env> {
}
fn handle_app_version_info_event(&self, app_version_info: AppVersionInfo) {
- let java_app_version_info = self.env.auto_local(app_version_info.into_java(&self.env));
+ let java_app_version_info = app_version_info.into_java(&self.env);
let result = self.env.call_method_unchecked(
self.mullvad_ipc_client,
diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs
index 11c4d8b7e7..0e00decd04 100644
--- a/mullvad-jni/src/lib.rs
+++ b/mullvad-jni/src/lib.rs
@@ -1,26 +1,28 @@
#![cfg(target_os = "android")]
+mod classes;
mod daemon_interface;
mod from_java;
-mod into_java;
mod is_null;
mod jni_event_listener;
mod vpn_service_tun_provider;
use crate::{
- daemon_interface::DaemonInterface, from_java::FromJava, into_java::IntoJava,
- jni_event_listener::JniEventListener, vpn_service_tun_provider::VpnServiceTunProvider,
+ daemon_interface::DaemonInterface, from_java::FromJava, jni_event_listener::JniEventListener,
+ vpn_service_tun_provider::VpnServiceTunProvider,
};
-use jni::{
- objects::{GlobalRef, JObject, JString, JValue},
- sys::{jboolean, JNI_FALSE, JNI_TRUE},
- JNIEnv,
+use jnix::{
+ jni::{
+ objects::{JObject, JString, JValue},
+ sys::{jboolean, JNI_FALSE, JNI_TRUE},
+ JNIEnv,
+ },
+ IntoJava, JnixEnv,
};
use lazy_static::lazy_static;
use mullvad_daemon::{logging, version, Daemon, DaemonCommandSender};
-use parking_lot::RwLock;
+use mullvad_types::account::AccountData;
use std::{
- collections::HashMap,
path::{Path, PathBuf},
sync::{mpsc, Once},
thread,
@@ -29,74 +31,10 @@ use talpid_types::ErrorExt;
const LOG_FILENAME: &str = "daemon.log";
-const CLASSES_TO_LOAD: &[&str] = &[
- "java/lang/Boolean",
- "java/net/InetAddress",
- "java/net/InetSocketAddress",
- "java/util/ArrayList",
- "net/mullvad/mullvadvpn/model/AccountData",
- "net/mullvad/mullvadvpn/model/AppVersionInfo",
- "net/mullvad/mullvadvpn/model/Constraint$Any",
- "net/mullvad/mullvadvpn/model/Constraint$Only",
- "net/mullvad/mullvadvpn/model/GeoIpLocation",
- "net/mullvad/mullvadvpn/model/GetAccountDataResult$Ok",
- "net/mullvad/mullvadvpn/model/GetAccountDataResult$InvalidAccount",
- "net/mullvad/mullvadvpn/model/GetAccountDataResult$RpcError",
- "net/mullvad/mullvadvpn/model/GetAccountDataResult$OtherError",
- "net/mullvad/mullvadvpn/model/KeygenEvent$NewKey",
- "net/mullvad/mullvadvpn/model/KeygenEvent$Failure",
- "net/mullvad/mullvadvpn/model/KeygenFailure$TooManyKeys",
- "net/mullvad/mullvadvpn/model/KeygenFailure$GenerationFailure",
- "net/mullvad/mullvadvpn/model/LocationConstraint$City",
- "net/mullvad/mullvadvpn/model/LocationConstraint$Country",
- "net/mullvad/mullvadvpn/model/LocationConstraint$Hostname",
- "net/mullvad/mullvadvpn/model/PublicKey",
- "net/mullvad/mullvadvpn/model/Relay",
- "net/mullvad/mullvadvpn/model/RelayList",
- "net/mullvad/mullvadvpn/model/RelayListCity",
- "net/mullvad/mullvadvpn/model/RelayListCountry",
- "net/mullvad/mullvadvpn/model/RelaySettings$CustomTunnelEndpoint",
- "net/mullvad/mullvadvpn/model/RelaySettings$RelayConstraints",
- "net/mullvad/mullvadvpn/model/RelaySettingsUpdate$CustomTunnelEndpoint",
- "net/mullvad/mullvadvpn/model/RelaySettingsUpdate$RelayConstraintsUpdate",
- "net/mullvad/mullvadvpn/model/Settings",
- "net/mullvad/mullvadvpn/model/TunnelState$Blocked",
- "net/mullvad/mullvadvpn/model/TunnelState$Connected",
- "net/mullvad/mullvadvpn/model/TunnelState$Connecting",
- "net/mullvad/mullvadvpn/model/TunnelState$Disconnected",
- "net/mullvad/mullvadvpn/model/TunnelState$Disconnecting",
- "net/mullvad/mullvadvpn/MullvadDaemon",
- "net/mullvad/mullvadvpn/MullvadVpnService",
- "net/mullvad/talpid/net/Endpoint",
- "net/mullvad/talpid/net/TransportProtocol$Tcp",
- "net/mullvad/talpid/net/TransportProtocol$Udp",
- "net/mullvad/talpid/net/TunnelEndpoint",
- "net/mullvad/talpid/tun_provider/InetNetwork",
- "net/mullvad/talpid/tun_provider/TunConfig",
- "net/mullvad/talpid/tunnel/ActionAfterDisconnect$Block",
- "net/mullvad/talpid/tunnel/ActionAfterDisconnect$Nothing",
- "net/mullvad/talpid/tunnel/ActionAfterDisconnect$Reconnect",
- "net/mullvad/talpid/tunnel/BlockReason$AuthFailed",
- "net/mullvad/talpid/tunnel/BlockReason$Ipv6Unavailable",
- "net/mullvad/talpid/tunnel/BlockReason$SetFirewallPolicyError",
- "net/mullvad/talpid/tunnel/BlockReason$SetDnsError",
- "net/mullvad/talpid/tunnel/BlockReason$StartTunnelError",
- "net/mullvad/talpid/tunnel/BlockReason$ParameterGeneration",
- "net/mullvad/talpid/tunnel/BlockReason$IsOffline",
- "net/mullvad/talpid/tunnel/BlockReason$TapAdapterProblem",
- "net/mullvad/talpid/tunnel/ParameterGenerationError$NoMatchingRelay",
- "net/mullvad/talpid/tunnel/ParameterGenerationError$NoMatchingBridgeRelay",
- "net/mullvad/talpid/tunnel/ParameterGenerationError$NoWireguardKey",
- "net/mullvad/talpid/tunnel/ParameterGenerationError$CustomTunnelHostResultionError",
- "net/mullvad/talpid/TalpidVpnService",
-];
-
lazy_static! {
static ref LOG_INIT_RESULT: Result<PathBuf, String> =
start_logging().map_err(|error| error.display_chain());
static ref DAEMON_INTERFACE: DaemonInterface = DaemonInterface::new();
- static ref CLASSES: RwLock<HashMap<&'static str, GlobalRef>> =
- RwLock::new(HashMap::with_capacity(CLASSES_TO_LOAD.len()));
}
static LOAD_CLASSES: Once = Once::new();
@@ -123,6 +61,34 @@ pub enum Error {
StartLogging(#[error(source)] logging::Error),
}
+#[derive(IntoJava)]
+#[jnix(package = "net.mullvad.mullvadvpn.model")]
+pub enum GetAccountDataResult {
+ Ok(AccountData),
+ InvalidAccount,
+ RpcError,
+ OtherError,
+}
+
+impl From<Result<AccountData, daemon_interface::Error>> for GetAccountDataResult {
+ fn from(result: Result<AccountData, daemon_interface::Error>) -> Self {
+ match result {
+ Ok(account_data) => GetAccountDataResult::Ok(account_data),
+ Err(error) => match error {
+ daemon_interface::Error::RpcError(jsonrpc_client_core::Error(
+ jsonrpc_client_core::ErrorKind::JsonRpcError(jsonrpc_core::Error {
+ code: jsonrpc_core::ErrorCode::ServerError(-200),
+ ..
+ }),
+ _,
+ )) => GetAccountDataResult::InvalidAccount,
+ daemon_interface::Error::RpcError(_) => GetAccountDataResult::RpcError,
+ _ => GetAccountDataResult::OtherError,
+ },
+ }
+ }
+}
+
#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_initialize(
@@ -130,9 +96,11 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_initialize(
this: JObject,
vpnService: JObject,
) {
+ let env = JnixEnv::from(env);
+
match *LOG_INIT_RESULT {
Ok(ref log_dir) => {
- LOAD_CLASSES.call_once(|| load_classes(&env));
+ LOAD_CLASSES.call_once(|| env.preload_classes(classes::CLASSES.iter().cloned()));
if let Err(error) = initialize(&env, &this, &vpnService, log_dir.clone()) {
log::error!("{}", error.display_chain());
@@ -156,26 +124,8 @@ fn start_logging() -> Result<PathBuf, Error> {
Ok(log_dir)
}
-fn load_classes(env: &JNIEnv) {
- let mut classes = CLASSES.write();
-
- for class in CLASSES_TO_LOAD {
- classes.insert(class, load_class_reference(env, class));
- }
-}
-
-fn load_class_reference(env: &JNIEnv, name: &str) -> GlobalRef {
- let class = match env.find_class(name) {
- Ok(class) => class,
- Err(_) => panic!("Failed to find {} Java class", name),
- };
-
- env.new_global_ref(JObject::from(class))
- .expect("Failed to convert local reference to Java class into a global reference")
-}
-
fn initialize(
- env: &JNIEnv,
+ env: &JnixEnv,
this: &JObject,
vpn_service: &JObject,
log_dir: PathBuf,
@@ -190,7 +140,7 @@ fn initialize(
}
fn spawn_daemon(
- env: &JNIEnv,
+ env: &JnixEnv,
this: &JObject,
tun_provider: VpnServiceTunProvider,
log_dir: PathBuf,
@@ -236,13 +186,6 @@ fn create_daemon(
Ok(daemon)
}
-fn get_class(name: &str) -> GlobalRef {
- match CLASSES.read().get(name) {
- Some(class) => class.clone(),
- None => panic!("Class not loaded: {}", name),
- }
-}
-
#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_connect(_: JNIEnv, _: JObject) {
@@ -271,8 +214,10 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_generateWiregua
env: JNIEnv<'env>,
_: JObject,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.generate_wireguard_key() {
- Ok(keygen_event) => keygen_event.into_java(&env),
+ Ok(keygen_event) => keygen_event.into_java(&env).forget(),
Err(error) => {
log::error!(
"{}",
@@ -289,10 +234,12 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_verifyWireguard
env: JNIEnv<'env>,
_: JObject<'this>,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.verify_wireguard_key() {
Ok(key_is_valid) => env
.new_object(
- &get_class("java/lang/Boolean"),
+ &env.get_class("java/lang/Boolean"),
"(Z)V",
&[JValue::Bool(key_is_valid as jboolean)],
)
@@ -314,6 +261,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getAccountData<
_: JObject<'this>,
accountToken: JString,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
let account = String::from_java(&env, accountToken);
let result = DAEMON_INTERFACE.get_account_data(account);
@@ -324,7 +272,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getAccountData<
);
}
- result.into_java(&env)
+ GetAccountDataResult::from(result).into_java(&env).forget()
}
#[no_mangle]
@@ -332,15 +280,17 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getAccountData<
pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getWwwAuthToken<'env, 'this>(
env: JNIEnv<'env>,
_: JObject<'this>,
-) -> JString<'env> {
+) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_www_auth_token() {
- Ok(token) => token.into_java(&env),
+ Ok(token) => token.into_java(&env).forget(),
Err(err) => {
log::error!(
"{}",
err.display_chain_with_msg("Failed to get WWW auth token")
);
- String::new().into_java(&env)
+ String::new().into_java(&env).forget()
}
}
}
@@ -351,8 +301,10 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getCurrentLocat
env: JNIEnv<'env>,
_: JObject<'this>,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_current_location() {
- Ok(location) => location.into_java(&env),
+ Ok(location) => location.into_java(&env).forget(),
Err(error) => {
log::error!(
"{}",
@@ -368,15 +320,17 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getCurrentLocat
pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getCurrentVersion<'env, 'this>(
env: JNIEnv<'env>,
_: JObject<'this>,
-) -> JString<'env> {
+) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_current_version() {
- Ok(location) => location.into_java(&env),
+ Ok(location) => location.into_java(&env).forget(),
Err(error) => {
log::error!(
"{}",
error.display_chain_with_msg("Failed to get current version")
);
- String::new().into_java(&env)
+ String::new().into_java(&env).forget()
}
}
}
@@ -387,8 +341,10 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getRelayLocatio
env: JNIEnv<'env>,
_: JObject<'this>,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_relay_locations() {
- Ok(relay_list) => relay_list.into_java(&env),
+ Ok(relay_list) => relay_list.into_java(&env).forget(),
Err(error) => {
log::error!(
"{}",
@@ -405,8 +361,10 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getSettings<'en
env: JNIEnv<'env>,
_: JObject<'this>,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_settings() {
- Ok(settings) => settings.into_java(&env),
+ Ok(settings) => settings.into_java(&env).forget(),
Err(error) => {
log::error!("{}", error.display_chain_with_msg("Failed to get settings"));
JObject::null()
@@ -420,8 +378,10 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getState<'env,
env: JNIEnv<'env>,
_: JObject<'this>,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_state() {
- Ok(state) => state.into_java(&env),
+ Ok(state) => state.into_java(&env).forget(),
Err(error) => {
log::error!("{}", error.display_chain_with_msg("Failed to get state"));
JObject::null()
@@ -435,8 +395,10 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getVersionInfo<
env: JNIEnv<'env>,
_: JObject<'this>,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_version_info() {
- Ok(version_info) => version_info.into_java(&env),
+ Ok(version_info) => version_info.into_java(&env).forget(),
Err(error) => {
log::error!(
"{}",
@@ -453,8 +415,10 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getWireguardKey
env: JNIEnv<'env>,
_: JObject<'this>,
) -> JObject<'env> {
+ let env = JnixEnv::from(env);
+
match DAEMON_INTERFACE.get_wireguard_key() {
- Ok(key) => key.into_java(&env),
+ Ok(key) => key.into_java(&env).forget(),
Err(error) => {
log::error!(
"{}",
@@ -472,6 +436,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_setAccount(
_: JObject,
accountToken: JString,
) {
+ let env = JnixEnv::from(env);
let account = <Option<String> as FromJava>::from_java(&env, accountToken);
if let Err(error) = DAEMON_INTERFACE.set_account(account) {
@@ -497,6 +462,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_updateRelaySett
_: JObject,
relaySettingsUpdate: JObject,
) {
+ let env = JnixEnv::from(env);
let update = FromJava::from_java(&env, relaySettingsUpdate);
if let Err(error) = DAEMON_INTERFACE.update_relay_settings(update) {
@@ -514,6 +480,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_dataproxy_MullvadProblemRepor
_: JObject,
outputPath: JString,
) -> jboolean {
+ let env = JnixEnv::from(env);
let output_path_string = String::from_java(&env, outputPath);
let output_path = Path::new(&output_path_string);
@@ -538,6 +505,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_dataproxy_MullvadProblemRepor
userMessage: JString,
outputPath: JString,
) -> jboolean {
+ let env = JnixEnv::from(env);
let user_email = String::from_java(&env, userEmail);
let user_message = String::from_java(&env, userMessage);
let output_path_string = String::from_java(&env, outputPath);
diff --git a/mullvad-jni/src/vpn_service_tun_provider.rs b/mullvad-jni/src/vpn_service_tun_provider.rs
index 35ca55c300..01f1905814 100644
--- a/mullvad-jni/src/vpn_service_tun_provider.rs
+++ b/mullvad-jni/src/vpn_service_tun_provider.rs
@@ -1,9 +1,11 @@
-use crate::{get_class, into_java::IntoJava};
use ipnetwork::IpNetwork;
-use jni::{
- objects::{GlobalRef, JObject, JValue},
- signature::{JavaType, Primitive},
- JNIEnv, JavaVM,
+use jnix::{
+ jni::{
+ objects::{GlobalRef, JObject, JValue},
+ signature::{JavaType, Primitive},
+ JavaVM,
+ },
+ IntoJava, JnixEnv,
};
use std::{
fs::File,
@@ -20,25 +22,25 @@ use talpid_types::BoxedError;
#[error(no_from)]
pub enum Error {
#[error(display = "Failed to attach Java VM to tunnel thread")]
- AttachJvmToThread(#[error(source)] jni::errors::Error),
+ AttachJvmToThread(#[error(source)] jnix::jni::errors::Error),
#[error(display = "Failed to allow socket to bypass tunnel")]
Bypass,
#[error(display = "Failed to call Java method TalpidVpnService.{}", _0)]
- CallMethod(&'static str, #[error(source)] jni::errors::Error),
+ CallMethod(&'static str, #[error(source)] jnix::jni::errors::Error),
#[error(display = "Failed to create Java VM handle clone")]
- CloneJavaVm(#[error(source)] jni::errors::Error),
+ CloneJavaVm(#[error(source)] jnix::jni::errors::Error),
#[error(display = "Failed to create global reference to TalpidVpnService instance")]
- CreateGlobalReference(#[error(source)] jni::errors::Error),
+ CreateGlobalReference(#[error(source)] jnix::jni::errors::Error),
#[error(display = "Failed to find TalpidVpnService.{} method", _0)]
- FindMethod(&'static str, #[error(source)] jni::errors::Error),
+ FindMethod(&'static str, #[error(source)] jnix::jni::errors::Error),
#[error(display = "Failed to get Java VM instance")]
- GetJvmInstance(#[error(source)] jni::errors::Error),
+ GetJvmInstance(#[error(source)] jnix::jni::errors::Error),
#[error(
display = "Received an invalid result from TalpidVpnService.{}: {}",
@@ -59,9 +61,9 @@ pub struct VpnServiceTunProvider {
impl VpnServiceTunProvider {
/// Create a new VpnServiceTunProvider interfacing with Android's VpnService.
- pub fn new(env: &JNIEnv, mullvad_vpn_service: &JObject) -> Result<Self, Error> {
+ pub fn new(env: &JnixEnv, mullvad_vpn_service: &JObject) -> Result<Self, Error> {
let jvm = env.get_java_vm().map_err(Error::GetJvmInstance)?;
- let class = get_class("net/mullvad/talpid/TalpidVpnService");
+ let class = env.get_class("net/mullvad/talpid/TalpidVpnService");
let object = env
.new_global_ref(*mullvad_vpn_service)
.map_err(Error::CreateGlobalReference)?;
@@ -103,10 +105,11 @@ impl VpnServiceTunProvider {
}
fn open_tun(&mut self, config: TunConfig) -> Result<(), Error> {
- let env = self
- .jvm
- .attach_current_thread_as_daemon()
- .map_err(Error::AttachJvmToThread)?;
+ let env = JnixEnv::from(
+ self.jvm
+ .attach_current_thread_as_daemon()
+ .map_err(Error::AttachJvmToThread)?,
+ );
let create_tun_method = env
.get_method_id(
&self.class,
@@ -115,7 +118,7 @@ impl VpnServiceTunProvider {
)
.map_err(|cause| Error::FindMethod("createTun", cause))?;
- let java_config = env.auto_local(config.clone().into_java(&env));
+ let java_config = config.clone().into_java(&env);
let result = env
.call_method_unchecked(
self.object.as_obj(),
@@ -194,10 +197,11 @@ impl Tun for VpnServiceTun {
}
fn bypass(&mut self, socket: RawFd) -> Result<(), BoxedError> {
- let env = self
- .jvm
- .attach_current_thread_as_daemon()
- .map_err(|cause| BoxedError::new(Error::AttachJvmToThread(cause)))?;
+ let env = JnixEnv::from(
+ self.jvm
+ .attach_current_thread_as_daemon()
+ .map_err(|cause| BoxedError::new(Error::AttachJvmToThread(cause)))?,
+ );
let create_tun_method = env
.get_method_id(&self.class, "bypass", "(I)Z")
.map_err(|cause| BoxedError::new(Error::FindMethod("bypass", cause)))?;
diff --git a/mullvad-types/Cargo.toml b/mullvad-types/Cargo.toml
index f02cbc0dab..8ec0369d69 100644
--- a/mullvad-types/Cargo.toml
+++ b/mullvad-types/Cargo.toml
@@ -18,3 +18,6 @@ serde_json = "1.0"
talpid-types = { path = "../talpid-types" }
mullvad-paths = { path = "../mullvad-paths" }
+
+[target.'cfg(target_os = "android")'.dependencies]
+jnix = { version = "0.1", features = ["derive"] }
diff --git a/mullvad-types/src/account.rs b/mullvad-types/src/account.rs
index 909b6c0070..a725db13ee 100644
--- a/mullvad-types/src/account.rs
+++ b/mullvad-types/src/account.rs
@@ -1,10 +1,15 @@
use chrono::{offset::Utc, DateTime};
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
pub type AccountToken = String;
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct AccountData {
+ #[cfg_attr(target_os = "android", jnix(map = "|expiry| expiry.to_string()"))]
pub expiry: DateTime<Utc>,
}
diff --git a/mullvad-types/src/custom_tunnel.rs b/mullvad-types/src/custom_tunnel.rs
index ea84e28979..12c293c22d 100644
--- a/mullvad-types/src/custom_tunnel.rs
+++ b/mullvad-types/src/custom_tunnel.rs
@@ -1,4 +1,6 @@
use crate::settings::TunnelOptions;
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::{
fmt, io,
@@ -18,6 +20,10 @@ pub enum Error {
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
+// TODO: Remove this Java conversion once `jnix` supports skipping fields in enum tuple variants.
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
+#[cfg_attr(target_os = "android", jnix(skip_all))]
pub struct CustomTunnelEndpoint {
host: String,
config: ConnectionConfig,
diff --git a/mullvad-types/src/location.rs b/mullvad-types/src/location.rs
index fbb2c1a7ef..07a0c00795 100644
--- a/mullvad-types/src/location.rs
+++ b/mullvad-types/src/location.rs
@@ -1,3 +1,5 @@
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
@@ -64,15 +66,21 @@ pub struct AmIMullvad {
/// GeoIP information exposed from the daemon to frontends.
#[derive(Debug, Clone, Serialize, Deserialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct GeoIpLocation {
pub ipv4: Option<Ipv4Addr>,
pub ipv6: Option<Ipv6Addr>,
pub country: String,
pub city: Option<String>,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub latitude: f64,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub longitude: f64,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub mullvad_exit_ip: bool,
pub hostname: Option<String>,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub bridge_hostname: Option<String>,
}
diff --git a/mullvad-types/src/relay_constraints.rs b/mullvad-types/src/relay_constraints.rs
index 9306b6670b..63d8070a0e 100644
--- a/mullvad-types/src/relay_constraints.rs
+++ b/mullvad-types/src/relay_constraints.rs
@@ -3,6 +3,8 @@ use crate::{
relay_list::{OpenVpnEndpointData, WireguardEndpointData},
CustomTunnelEndpoint,
};
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::fmt;
use talpid_types::net::{openvpn::ProxySettings, TransportProtocol};
@@ -14,6 +16,8 @@ pub trait Match<T> {
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub enum Constraint<T: fmt::Debug + Clone + Eq + PartialEq> {
Any,
Only(T),
@@ -61,6 +65,8 @@ impl<T: fmt::Debug + Clone + Eq + PartialEq> Match<T> for Constraint<T> {
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub enum RelaySettings {
CustomTunnelEndpoint(CustomTunnelEndpoint),
Normal(RelayConstraints),
@@ -120,10 +126,15 @@ impl RelaySettings {
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[cfg_attr(not(target_os = "android"), derive(Default))]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct RelayConstraints {
pub location: Constraint<LocationConstraint>,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub tunnel_protocol: Constraint<TunnelProtocol>,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub wireguard_constraints: WireguardConstraints,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub openvpn_constraints: OpenVpnConstraints,
}
@@ -187,6 +198,8 @@ impl fmt::Display for RelayConstraints {
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub enum LocationConstraint {
/// A country is represented by its two letter country code.
Country(CountryCode),
diff --git a/mullvad-types/src/relay_list.rs b/mullvad-types/src/relay_list.rs
index ee87751c43..a086dd108c 100644
--- a/mullvad-types/src/relay_list.rs
+++ b/mullvad-types/src/relay_list.rs
@@ -2,7 +2,8 @@ use crate::{
endpoint::MullvadEndpoint,
location::{CityCode, CountryCode, Location},
};
-
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::{
fmt,
@@ -15,6 +16,8 @@ use talpid_types::net::{
#[derive(Debug, Clone, Deserialize, Serialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct RelayList {
pub countries: Vec<RelayListCountry>,
}
@@ -28,6 +31,8 @@ impl RelayList {
}
#[derive(Debug, Clone, Deserialize, Serialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct RelayListCountry {
pub name: String,
pub code: CountryCode,
@@ -35,32 +40,46 @@ pub struct RelayListCountry {
}
#[derive(Debug, Clone, Deserialize, Serialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct RelayListCity {
pub name: String,
pub code: CityCode,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub latitude: f64,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub longitude: f64,
pub relays: Vec<Relay>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct Relay {
pub hostname: String,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub ipv4_addr_in: Ipv4Addr,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub include_in_country: bool,
pub active: bool,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub weight: u64,
#[serde(skip_serializing_if = "RelayTunnels::is_empty", default)]
pub tunnels: RelayTunnels,
#[serde(skip_serializing_if = "RelayBridges::is_empty", default)]
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub bridges: RelayBridges,
#[serde(skip)]
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub location: Option<Location>,
}
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
#[serde(default)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct RelayTunnels {
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub openvpn: Vec<OpenVpnEndpointData>,
pub wireguard: Vec<WireguardEndpointData>,
}
@@ -95,6 +114,9 @@ impl fmt::Display for OpenVpnEndpointData {
}
#[derive(Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Debug)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
+#[cfg_attr(target_os = "android", jnix(skip_all))]
pub struct WireguardEndpointData {
/// Port to connect to
pub port_ranges: Vec<(u16, u16)>,
diff --git a/mullvad-types/src/settings/mod.rs b/mullvad-types/src/settings/mod.rs
index 80ea68c6ce..0c3aa2f6fe 100644
--- a/mullvad-types/src/settings/mod.rs
+++ b/mullvad-types/src/settings/mod.rs
@@ -2,6 +2,8 @@ use crate::relay_constraints::{
BridgeConstraints, BridgeSettings, BridgeState, Constraint, LocationConstraint,
RelayConstraints, RelaySettings, RelaySettingsUpdate,
};
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use log::{debug, info};
use serde::{Deserialize, Serialize};
use serde_json;
@@ -53,22 +55,31 @@ static SETTINGS_FILE: &str = "settings.json";
/// Mullvad daemon settings.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(default)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct Settings {
account_token: Option<String>,
relay_settings: RelaySettings,
+ #[cfg_attr(target_os = "android", jnix(skip))]
bridge_settings: BridgeSettings,
+ #[cfg_attr(target_os = "android", jnix(skip))]
bridge_state: BridgeState,
/// If the daemon should allow communication with private (LAN) networks.
+ #[cfg_attr(target_os = "android", jnix(skip))]
allow_lan: bool,
/// Extra level of kill switch. When this setting is on, the disconnected state will block
/// the firewall to not allow any traffic in or out.
+ #[cfg_attr(target_os = "android", jnix(skip))]
block_when_disconnected: bool,
/// If the daemon should connect the VPN tunnel directly on start or not.
+ #[cfg_attr(target_os = "android", jnix(skip))]
auto_connect: bool,
/// Options that should be applied to tunnels of a specific type regardless of where the relays
/// might be located.
+ #[cfg_attr(target_os = "android", jnix(skip))]
tunnel_options: TunnelOptions,
/// Specifies settings schema version
+ #[cfg_attr(target_os = "android", jnix(skip))]
settings_version: migrations::SettingsVersion,
}
diff --git a/mullvad-types/src/states.rs b/mullvad-types/src/states.rs
index 9c3ffa42a9..e905f329c5 100644
--- a/mullvad-types/src/states.rs
+++ b/mullvad-types/src/states.rs
@@ -1,4 +1,6 @@
use crate::location::GeoIpLocation;
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use talpid_types::{
net::TunnelEndpoint,
@@ -19,6 +21,8 @@ pub enum TargetState {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "state", content = "details")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub enum TunnelState {
Disconnected,
Connecting {
diff --git a/mullvad-types/src/version.rs b/mullvad-types/src/version.rs
index 6e626104d7..21fffca04b 100644
--- a/mullvad-types/src/version.rs
+++ b/mullvad-types/src/version.rs
@@ -1,8 +1,12 @@
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
/// AppVersionInfo represents the current stable and the current latest release versions of the
/// Mullvad VPN app.
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct AppVersionInfo {
/// False if Mullvad has stopped supporting the currently running version. This could mean
/// a number of things. For example:
diff --git a/mullvad-types/src/wireguard.rs b/mullvad-types/src/wireguard.rs
index 8675a6e845..dce0fb74de 100644
--- a/mullvad-types/src/wireguard.rs
+++ b/mullvad-types/src/wireguard.rs
@@ -1,4 +1,6 @@
use chrono::{offset::Utc, DateTime};
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::fmt;
use talpid_types::net::wireguard;
@@ -24,8 +26,12 @@ impl WireguardData {
/// Represents a published public key
#[derive(Serialize, Deserialize, Clone, Debug)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub struct PublicKey {
+ #[cfg_attr(target_os = "android", jnix(map = "|key| *key.as_bytes()"))]
pub key: wireguard::PublicKey,
+ #[cfg_attr(target_os = "android", jnix(map = "|date_time| date_time.to_string()"))]
pub created: DateTime<Utc>,
}
@@ -37,9 +43,11 @@ pub struct AssociatedAddresses {
pub ipv6_address: ipnetwork::Ipv6Network,
}
+/// Event that is emitted when the daemon has finished generating a key.
#[serde(rename_all = "snake_case")]
#[derive(Clone, Debug, Deserialize, Serialize)]
-/// Event that is emitted when the daemon has finished generating a key.
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub enum KeygenEvent {
NewKey(PublicKey),
TooManyKeys,
diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml
index 2695ca0f57..a91c71d843 100644
--- a/talpid-core/Cargo.toml
+++ b/talpid-core/Cargo.toml
@@ -37,6 +37,10 @@ tokio-executor = "0.1"
tokio-io = "0.1"
+[target.'cfg(target_os = "android")'.dependencies]
+jnix = { version = "0.1", features = ["derive"] }
+
+
[target.'cfg(target_os = "linux")'.dependencies]
dbus = "0.6"
failure = "0.1"
diff --git a/talpid-core/src/tunnel/tun_provider/mod.rs b/talpid-core/src/tunnel/tun_provider/mod.rs
index 16c9c3f17c..c6701ceac9 100644
--- a/talpid-core/src/tunnel/tun_provider/mod.rs
+++ b/talpid-core/src/tunnel/tun_provider/mod.rs
@@ -1,5 +1,7 @@
use cfg_if::cfg_if;
use ipnetwork::IpNetwork;
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use std::net::IpAddr;
#[cfg(unix)]
use std::os::unix::io::AsRawFd;
@@ -71,6 +73,11 @@ pub trait TunProvider: Send + 'static {
/// Configuration for creating a tunnel device.
#[derive(Clone, Debug, Eq, PartialEq)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(
+ target_os = "android",
+ jnix(package = "net.mullvad.talpid.tun_provider")
+)]
pub struct TunConfig {
/// IP addresses for the tunnel interface.
pub addresses: Vec<IpAddr>,
@@ -79,8 +86,31 @@ pub struct TunConfig {
pub dns_servers: Vec<IpAddr>,
/// Routes to configure for the tunnel.
+ #[cfg_attr(
+ target_os = "android",
+ jnix(map = "|networks| networks.into_iter().map(InetNetwork::from).collect::<Vec<_>>()")
+ )]
pub routes: Vec<IpNetwork>,
/// Maximum Transmission Unit in the tunnel.
+ #[cfg_attr(target_os = "android", jnix(map = "|mtu| mtu as i32"))]
pub mtu: u16,
}
+
+#[cfg(target_os = "android")]
+#[derive(IntoJava)]
+#[jnix(package = "net.mullvad.talpid.tun_provider")]
+struct InetNetwork {
+ address: IpAddr,
+ prefix: i16,
+}
+
+#[cfg(target_os = "android")]
+impl From<IpNetwork> for InetNetwork {
+ fn from(ip_network: IpNetwork) -> Self {
+ InetNetwork {
+ address: ip_network.ip(),
+ prefix: ip_network.prefix() as i16,
+ }
+ }
+}
diff --git a/talpid-types/Cargo.toml b/talpid-types/Cargo.toml
index 0412c8f501..ff675eed0d 100644
--- a/talpid-types/Cargo.toml
+++ b/talpid-types/Cargo.toml
@@ -13,3 +13,6 @@ base64 = "0.10"
x25519-dalek = { version = "0.5", features = [ "std", "u64_backend" ], default-features = false }
rand = "0.7"
err-derive = "0.2.1"
+
+[target.'cfg(target_os = "android")'.dependencies]
+jnix = { version = "0.1", features = ["derive"] }
diff --git a/talpid-types/src/net/mod.rs b/talpid-types/src/net/mod.rs
index 9c57e7b393..b3b38331cb 100644
--- a/talpid-types/src/net/mod.rs
+++ b/talpid-types/src/net/mod.rs
@@ -1,3 +1,5 @@
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::{
error::Error,
@@ -79,11 +81,15 @@ impl fmt::Display for TunnelType {
/// A tunnel endpoint is broadcast during the connecting and connected states of the tunnel state
/// machine.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.net"))]
pub struct TunnelEndpoint {
#[serde(flatten)]
pub endpoint: Endpoint,
/// Type of the tunnel
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub tunnel_type: TunnelType,
+ #[cfg_attr(target_os = "android", jnix(skip))]
pub proxy: Option<proxy::ProxyEndpoint>,
}
@@ -104,6 +110,8 @@ impl fmt::Display for TunnelEndpoint {
/// Represents a network layer IP address together with the transport layer protocol and port.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.net"))]
pub struct Endpoint {
/// The socket address for the endpoint
pub address: SocketAddr,
@@ -130,6 +138,8 @@ impl fmt::Display for Endpoint {
/// Representation of a transport protocol, either UDP or TCP.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.net"))]
pub enum TransportProtocol {
/// Represents the UDP transport protocol.
Udp,
diff --git a/talpid-types/src/tunnel.rs b/talpid-types/src/tunnel.rs
index 24b05ee24b..9ab3ed6d36 100644
--- a/talpid-types/src/tunnel.rs
+++ b/talpid-types/src/tunnel.rs
@@ -1,4 +1,6 @@
use crate::net::TunnelEndpoint;
+#[cfg(target_os = "android")]
+use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::fmt;
@@ -22,6 +24,8 @@ pub enum TunnelStateTransition {
/// Action that will be taken after disconnection is complete.
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.tunnel"))]
pub enum ActionAfterDisconnect {
Nothing,
Block,
@@ -41,6 +45,8 @@ impl TunnelStateTransition {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "reason", content = "details")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.tunnel"))]
pub enum BlockReason {
/// Authentication with remote server failed.
AuthFailed(Option<String>),
@@ -63,6 +69,8 @@ pub enum BlockReason {
/// Errors that can occur when generating tunnel parameters.
#[derive(err_derive::Error, Debug, Serialize, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "snake_case")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.tunnel"))]
pub enum ParameterGenerationError {
/// Failure to select a matching tunnel relay
#[error(display = "Failure to select a matching tunnel relay")]