summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <pinkisemils@mullvad.net>2020-02-14 13:54:40 +0000
committerEmīls <pinkisemils@mullvad.net>2020-02-14 13:54:40 +0000
commit56d75e848dc8dbec4be193f65bc5827e9156dc4a (patch)
treeb63cebd9707b181a6c0f5a15736da25c2edc43c6
parent7a75ce2d4c31db33a4419fcc45102d6e357f1a73 (diff)
parent4caa932497c71795005ae72a88ead9d32eff61e5 (diff)
downloadmullvadvpn-56d75e848dc8dbec4be193f65bc5827e9156dc4a.tar.xz
mullvadvpn-56d75e848dc8dbec4be193f65bc5827e9156dc4a.zip
Merge branch 'android-add-auto-connect'
-rw-r--r--CHANGELOG.md1
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/SettingsListener.kt26
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt3
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt43
-rw-r--r--android/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt2
-rw-r--r--android/src/main/res/layout/preferences.xml34
-rw-r--r--android/src/main/res/values/strings.xml4
-rw-r--r--mullvad-jni/src/daemon_interface.rs8
-rw-r--r--mullvad-jni/src/lib.rs22
-rw-r--r--mullvad-types/src/settings/mod.rs1
-rw-r--r--talpid-core/src/tunnel/tun_provider/android/mod.rs4
12 files changed, 130 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 527360851a..ae3e998ca6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -32,6 +32,7 @@ Line wrap the file at 100 chars. Th
#### Android
- Add option to enable or disable local network sharing.
- Show account history in login fragment
+- Add option to enable auto-connecting behavior
### Changed
- Change project copyright and company name from Amagicom AB to Mullvad VPN AB
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/SettingsListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/SettingsListener.kt
index be27eb7b89..a79307811d 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/SettingsListener.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/SettingsListener.kt
@@ -3,15 +3,21 @@ package net.mullvad.mullvadvpn.dataproxy
import net.mullvad.mullvadvpn.model.RelaySettings
import net.mullvad.mullvadvpn.model.Settings
import net.mullvad.mullvadvpn.service.MullvadDaemon
+import net.mullvad.talpid.util.EventNotifier
class SettingsListener(val daemon: MullvadDaemon) {
+ var settings: Settings = daemon.getSettings()
+ private set(value) {
+ settingsNotifier.notify(value)
+ field = value
+ }
+
+ private val settingsNotifier: EventNotifier<Settings> = EventNotifier(settings)
+
private val listenerId = daemon.onSettingsChange.subscribe { maybeSettings ->
maybeSettings?.let { settings -> handleNewSettings(settings) }
}
- var settings: Settings? = null
- private set
-
var onAccountNumberChange: ((String?) -> Unit)? = null
set(value) {
synchronized(this) {
@@ -43,6 +49,16 @@ class SettingsListener(val daemon: MullvadDaemon) {
if (listenerId != -1) {
daemon.onSettingsChange.unsubscribe(listenerId)
}
+
+ settingsNotifier.unsubscribeAll()
+ }
+
+ fun subscribe(listener: (Settings) -> Unit): Int {
+ return settingsNotifier.subscribe(listener)
+ }
+
+ fun unsubscribe(id: Int) {
+ settingsNotifier.unsubscribe(id)
}
private fun handleNewSettings(newSettings: Settings) {
@@ -55,10 +71,6 @@ class SettingsListener(val daemon: MullvadDaemon) {
onRelaySettingsChange?.invoke(newSettings.relaySettings)
}
- if (settings?.allowLan != newSettings.allowLan) {
- onAllowLanChange?.invoke(newSettings.allowLan)
- }
-
settings = newSettings
}
}
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 6cc83b157f..77a45e03a8 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt
@@ -3,5 +3,6 @@ package net.mullvad.mullvadvpn.model
data class Settings(
var accountToken: String?,
var relaySettings: RelaySettings,
- var allowLan: Boolean
+ var allowLan: Boolean,
+ var autoConnect: Boolean
)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
index a0dabf1a53..df608dab69 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
@@ -89,6 +89,10 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
setAllowLan(daemonInterfaceAddress, allowLan)
}
+ fun setAutoConnect(autoConnect: Boolean) {
+ setAutoConnect(daemonInterfaceAddress, autoConnect)
+ }
+
fun shutdown() {
shutdown(daemonInterfaceAddress)
}
@@ -122,6 +126,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
private external fun getWireguardKey(daemonInterfaceAddress: Long): PublicKey?
private external fun setAccount(daemonInterfaceAddress: Long, accountToken: String?)
private external fun setAllowLan(daemonInterfaceAddress: Long, allowLan: Boolean)
+ private external fun setAutoConnect(daemonInterfaceAddress: Long, alwaysOn: Boolean)
private external fun shutdown(daemonInterfaceAddress: Long)
private external fun updateRelaySettings(
daemonInterfaceAddress: Long,
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt
index 160caafd22..387864f26c 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt
@@ -9,10 +9,13 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.R
+import net.mullvad.mullvadvpn.model.Settings
class PreferencesFragment : ServiceDependentFragment(OnNoService.GoBack) {
private lateinit var allowLanToggle: CellSwitch
+ private lateinit var autoConnectToggle: CellSwitch
+ private var subscriptionId: Int? = null
private var updateUiJob: Job? = null
override fun onSafelyCreateView(
@@ -28,11 +31,7 @@ class PreferencesFragment : ServiceDependentFragment(OnNoService.GoBack) {
allowLanToggle = view.findViewById<CellSwitch>(R.id.allow_lan_toggle).apply {
settingsListener.settings?.let { settings ->
- if (settings.allowLan) {
- forcefullySetState(CellSwitch.State.ON)
- } else {
- forcefullySetState(CellSwitch.State.OFF)
- }
+ forcefullySetState(boolToSwitchState(settings.allowLan))
}
listener = { state ->
@@ -43,23 +42,41 @@ class PreferencesFragment : ServiceDependentFragment(OnNoService.GoBack) {
}
}
- settingsListener.onAllowLanChange = { allowLan ->
- updateUiJob?.cancel()
- updateUiJob = updateUi(allowLan)
+ autoConnectToggle = view.findViewById<CellSwitch>(R.id.auto_connect_toggle).apply {
+ settingsListener.settings?.let { settings ->
+ forcefullySetState(boolToSwitchState(settings.autoConnect))
+ }
+
+ listener = { state ->
+ when (state) {
+ CellSwitch.State.ON -> daemon.setAutoConnect(true)
+ CellSwitch.State.OFF -> daemon.setAutoConnect(false)
+ }
+ }
}
+ settingsListener.subscribe({ settings -> updateUi(settings) })
+
return view
}
+ private fun updateUi(settings: Settings) {
+ updateUiJob?.cancel()
+ updateUiJob = GlobalScope.launch(Dispatchers.Main) {
+ allowLanToggle.state = boolToSwitchState(settings.allowLan)
+ autoConnectToggle.state = boolToSwitchState(settings.autoConnect)
+ }
+ }
+
override fun onSafelyDestroyView() {
- settingsListener.onAllowLanChange = null
+ subscriptionId?.let { id -> settingsListener.unsubscribe(id) }
}
- private fun updateUi(allowLan: Boolean) = GlobalScope.launch(Dispatchers.Main) {
- if (allowLan) {
- allowLanToggle.state = CellSwitch.State.ON
+ private fun boolToSwitchState(pref: Boolean): CellSwitch.State {
+ if (pref) {
+ return CellSwitch.State.ON
} else {
- allowLanToggle.state = CellSwitch.State.OFF
+ return CellSwitch.State.OFF
}
}
}
diff --git a/android/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt b/android/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
index 3d9200f345..e2ea8c5818 100644
--- a/android/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
+++ b/android/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
@@ -34,7 +34,7 @@ open class TalpidVpnService : VpnService() {
val vpnInterface = builder.establish()
- return vpnInterface.detachFd()
+ return vpnInterface?.detachFd() ?: 0
}
fun bypass(socket: Int): Boolean {
diff --git a/android/src/main/res/layout/preferences.xml b/android/src/main/res/layout/preferences.xml
index 59d42635fe..a03726482d 100644
--- a/android/src/main/res/layout/preferences.xml
+++ b/android/src/main/res/layout/preferences.xml
@@ -41,6 +41,40 @@
android:textStyle="bold"
android:text="@string/settings_preferences"
/>
+ <LinearLayout android:id="@+id/auto_connect"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="24dp"
+ android:paddingHorizontal="16dp"
+ android:background="@drawable/cell_button_background"
+ android:gravity="center"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingHorizontal="8dp"
+ android:paddingVertical="17dp"
+ android:textColor="@color/white"
+ android:textSize="20sp"
+ android:textStyle="bold"
+ android:text="@string/auto_connect"
+ />
+ <net.mullvad.mullvadvpn.ui.CellSwitch android:id="@+id/auto_connect_toggle"
+ android:layout_width="52dp"
+ android:layout_height="32dp"
+ android:layout_weight="0"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/auto_connect_footer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingHorizontal="24dp"
+ android:textColor="@color/white60"
+ android:textSize="13sp"
+ android:text="@string/auto_connect_footer"
+ />
<LinearLayout android:id="@+id/allow_lan"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml
index 0a87ff3736..f722cb845c 100644
--- a/android/src/main/res/values/strings.xml
+++ b/android/src/main/res/values/strings.xml
@@ -45,6 +45,10 @@
<string name="allow_lan_footer">
Allows access to other devices on the same network for sharing, printing etc.
</string>
+ <string name="auto_connect">Auto-connect</string>
+ <string name="auto_connect_footer">
+ Automatically connect to a server when the app launches.
+ </string>
<string name="problem_report_description">
To help you more effectively, your app\'s log file will be attached to this message. Your
diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs
index 5515668e08..a376fa6aa8 100644
--- a/mullvad-jni/src/daemon_interface.rs
+++ b/mullvad-jni/src/daemon_interface.rs
@@ -184,6 +184,14 @@ impl DaemonInterface {
rx.wait().map_err(|_| Error::NoResponse)
}
+ pub fn set_auto_connect(&self, auto_connect: bool) -> Result<()> {
+ let (tx, rx) = oneshot::channel();
+
+ self.send_command(ManagementCommand::SetAutoConnect(tx, auto_connect))?;
+
+ rx.wait().map_err(|_| Error::NoResponse)
+ }
+
pub fn shutdown(&self) -> Result<()> {
self.send_command(ManagementCommand::Shutdown)
}
diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs
index 5f4cae6e1c..dd1fd939b8 100644
--- a/mullvad-jni/src/lib.rs
+++ b/mullvad-jni/src/lib.rs
@@ -694,6 +694,28 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_setAllo
#[no_mangle]
#[allow(non_snake_case)]
+pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_setAutoConnect(
+ env: JNIEnv<'_>,
+ _: JObject<'_>,
+ daemon_interface_address: jlong,
+ auto_connect: jboolean,
+) {
+ let env = JnixEnv::from(env);
+
+ if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) {
+ let auto_connect = bool::from_java(&env, auto_connect);
+
+ if let Err(error) = daemon_interface.set_auto_connect(auto_connect) {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg("Failed to set auto-connect")
+ );
+ }
+ }
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_shutdown(
_: JNIEnv<'_>,
_: JObject<'_>,
diff --git a/mullvad-types/src/settings/mod.rs b/mullvad-types/src/settings/mod.rs
index 19f350b7f7..ed7080f67d 100644
--- a/mullvad-types/src/settings/mod.rs
+++ b/mullvad-types/src/settings/mod.rs
@@ -71,7 +71,6 @@ pub struct Settings {
#[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.
diff --git a/talpid-core/src/tunnel/tun_provider/android/mod.rs b/talpid-core/src/tunnel/tun_provider/android/mod.rs
index 6de6217a31..3b5b9c45dd 100644
--- a/talpid-core/src/tunnel/tun_provider/android/mod.rs
+++ b/talpid-core/src/tunnel/tun_provider/android/mod.rs
@@ -60,6 +60,9 @@ pub enum Error {
#[error(display = "Timed out while waiting for tunnel device to receive data")]
TunnelDeviceTimeout,
+
+ #[error(display = "Failed to create tunnel device")]
+ TunnelDeviceError,
}
/// Factory of tunnel devices on Android.
@@ -334,6 +337,7 @@ impl AndroidTunProvider {
.map_err(|cause| Error::CallMethod("createTun", cause))?;
match result {
+ JValue::Int(0) => Err(Error::TunnelDeviceError),
JValue::Int(fd) => {
Self::wait_for_tunnel_up(fd, &config)?;
let tun = unsafe { File::from_raw_fd(fd) };