summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-05-23 10:05:58 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-05-23 10:05:58 -0300
commit30d55fe3e013e2ef4fa01dce787ac0af781f2450 (patch)
treed1697c4f72283c2a0e955f5b2ffe0e0c51dcca06
parent8ab37040fcc2e8ec0e70555608351e9f4aa01e2c (diff)
parent48a7524589ad1f97a13c08a2a9b02541f89dbfe4 (diff)
downloadmullvadvpn-30d55fe3e013e2ef4fa01dce787ac0af781f2450.tar.xz
mullvadvpn-30d55fe3e013e2ef4fa01dce787ac0af781f2450.zip
Merge branch 'fetch-relay-constraint-on-android'
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/LaunchFragment.kt3
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt29
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItemHolder.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt46
-rw-r--r--mullvad-jni/src/into_java.rs134
-rw-r--r--mullvad-jni/src/lib.rs2
8 files changed, 222 insertions, 6 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/LaunchFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/LaunchFragment.kt
index 043c8efe15..f2a5a5a97f 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/LaunchFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/LaunchFragment.kt
@@ -38,8 +38,7 @@ class LaunchFragment : Fragment() {
private fun checkForAccountToken() = GlobalScope.async(Dispatchers.Default) {
val parentActivity = activity as MainActivity
- val daemon = parentActivity.asyncDaemon.await()
- val settings = daemon.getSettings()
+ val settings = parentActivity.asyncSettings.await()
settings.accountToken != null
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
index b68671afbd..6e3d34730b 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
@@ -12,6 +12,8 @@ import kotlinx.coroutines.Job
import android.os.Bundle
import android.support.v4.app.FragmentActivity
+import net.mullvad.mullvadvpn.model.RelaySettings
+import net.mullvad.mullvadvpn.model.Settings
import net.mullvad.mullvadvpn.relaylist.RelayItem
import net.mullvad.mullvadvpn.relaylist.RelayList
@@ -27,8 +29,15 @@ class MainActivity : FragmentActivity() {
val relayList: RelayList
get() = runBlocking { asyncRelayList.await() }
+ var asyncSettings = fetchSettings()
+ private set
+ val settings
+ get() = runBlocking { asyncSettings.await() }
+
var selectedRelayItem: RelayItem? = null
+ private val restoreSelectedRelayListItemJob = restoreSelectedRelayListItem()
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
@@ -41,6 +50,8 @@ class MainActivity : FragmentActivity() {
}
override fun onDestroy() {
+ restoreSelectedRelayListItemJob.cancel()
+ asyncSettings.cancel()
asyncRelayList.cancel()
asyncDaemon.cancel()
@@ -63,4 +74,22 @@ class MainActivity : FragmentActivity() {
private fun fetchRelayList() = GlobalScope.async(Dispatchers.Default) {
RelayList(asyncDaemon.await().getRelayLocations())
}
+
+ private fun fetchSettings() = GlobalScope.async(Dispatchers.Default) {
+ asyncDaemon.await().getSettings()
+ }
+
+ private fun restoreSelectedRelayListItem() = GlobalScope.launch(Dispatchers.Default) {
+ val relaySettings = asyncSettings.await().relaySettings
+
+ when (relaySettings) {
+ is RelaySettings.CustomTunnelEndpoint -> selectedRelayItem = null
+ is RelaySettings.RelayConstraints -> {
+ val location = relaySettings.location
+ val relayList = asyncRelayList.await()
+
+ selectedRelayItem = relayList.findItemForLocation(location, true)
+ }
+ }
+ }
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
new file mode 100644
index 0000000000..6fded8f9c5
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
@@ -0,0 +1,6 @@
+package net.mullvad.mullvadvpn.model
+
+sealed class RelaySettings {
+ class CustomTunnelEndpoint() : RelaySettings()
+ class RelayConstraints(var location: Constraint<LocationConstraint>) : RelaySettings()
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt
index 1254492b57..c0c2abdbe7 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt
@@ -1,4 +1,4 @@
package net.mullvad.mullvadvpn.model
-data class Settings(var accountToken: String?) {
+data class Settings(var accountToken: String?, var relaySettings: RelaySettings) {
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItemHolder.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItemHolder.kt
index b67c31e2a9..e753d3af5a 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItemHolder.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItemHolder.kt
@@ -65,6 +65,12 @@ class RelayItemHolder(
if (item.hasChildren) {
chevron.visibility = View.VISIBLE
+
+ if (item.expanded) {
+ chevron.rotation = 180.0F
+ } else {
+ chevron.rotation = 0.0F
+ }
} else {
chevron.visibility = View.GONE
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt
index 964833f675..809fa1265f 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt
@@ -1,5 +1,8 @@
package net.mullvad.mullvadvpn.relaylist
+import net.mullvad.mullvadvpn.model.Constraint
+import net.mullvad.mullvadvpn.model.LocationConstraint
+
class RelayList {
val countries: List<RelayCountry>
@@ -16,4 +19,47 @@ class RelayList {
RelayCountry(country.name, country.code, false, cities)
}
}
+
+ fun findItemForLocation(
+ constraint: Constraint<LocationConstraint>,
+ expand: Boolean = false
+ ): RelayItem? {
+ when (constraint) {
+ is Constraint.Any -> return null
+ is Constraint.Only -> {
+ val location = constraint.value
+
+ when (location) {
+ is LocationConstraint.Country -> {
+ return countries.find { country -> country.code == location.countryCode }
+ }
+ is LocationConstraint.City -> {
+ val country = countries.find { country ->
+ country.code == location.countryCode
+ }
+
+ if (expand) {
+ country?.expanded = true
+ }
+
+ return country?.cities?.find { city -> city.code == location.cityCode }
+ }
+ is LocationConstraint.Hostname -> {
+ val country = countries.find { country ->
+ country.code == location.countryCode
+ }
+
+ val city = country?.cities?.find { city -> city.code == location.cityCode }
+
+ if (expand) {
+ country?.expanded = true
+ city?.expanded = true
+ }
+
+ return city?.relays?.find { relay -> relay.name == location.hostname }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/mullvad-jni/src/into_java.rs b/mullvad-jni/src/into_java.rs
index 22b582bc1b..1c6733252b 100644
--- a/mullvad-jni/src/into_java.rs
+++ b/mullvad-jni/src/into_java.rs
@@ -6,9 +6,12 @@ use jni::{
};
use mullvad_types::{
account::AccountData,
+ relay_constraints::{Constraint, LocationConstraint, RelayConstraints, RelaySettings},
relay_list::{Relay, RelayList, RelayListCity, RelayListCountry},
settings::Settings,
+ CustomTunnelEndpoint,
};
+use std::fmt::Debug;
pub trait IntoJava<'env> {
type JavaType;
@@ -154,15 +157,140 @@ impl<'env> IntoJava<'env> for Relay {
}
}
+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 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 parameters = [JValue::Object(account_token.as_obj())];
+ 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;)V", &parameters)
- .expect("Failed to create Settings Java object")
+ env.new_object(
+ &class,
+ "(Ljava/lang/String;Lnet/mullvad/mullvadvpn/model/RelaySettings;)V",
+ &parameters,
+ )
+ .expect("Failed to create Settings Java object")
}
}
diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs
index 99a3041d9a..9a7f81a0fc 100644
--- a/mullvad-jni/src/lib.rs
+++ b/mullvad-jni/src/lib.rs
@@ -31,6 +31,8 @@ const CLASSES_TO_LOAD: &[&str] = &[
"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",