diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-21 09:55:34 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-21 09:55:34 -0300 |
| commit | 25c74e4c247314a6955f1fc08d49a4ceb46f4b49 (patch) | |
| tree | 352413fd309d819bc9fcbbb36d980b454edeadc7 /android/src | |
| parent | 46b0bed2154daa43d6e79413f4f54d0737ff8756 (diff) | |
| parent | 63d88fba3ae8207fc06730658d53dde87c0bac98 (diff) | |
| download | mullvadvpn-25c74e4c247314a6955f1fc08d49a4ceb46f4b49.tar.xz mullvadvpn-25c74e4c247314a6955f1fc08d49a4ceb46f4b49.zip | |
Merge branch 'set-settings-through-ipc'
Diffstat (limited to 'android/src')
10 files changed, 159 insertions, 25 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt index db72cb08c5..67ae40f187 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt @@ -4,6 +4,7 @@ import android.os.Message as RawMessage import android.os.Messenger import java.net.InetAddress import kotlinx.parcelize.Parcelize +import net.mullvad.mullvadvpn.model.LocationConstraint import org.joda.time.DateTime // Requests that the service can handle @@ -65,12 +66,27 @@ sealed class Request : Message.RequestMessage() { ) : Request() @Parcelize + data class SetAccount(val account: String?) : Request() + + @Parcelize + data class SetAllowLan(val allow: Boolean) : Request() + + @Parcelize + data class SetAutoConnect(val autoConnect: Boolean) : Request() + + @Parcelize data class SetEnableCustomDns(val enable: Boolean) : Request() @Parcelize data class SetEnableSplitTunneling(val enable: Boolean) : Request() @Parcelize + data class SetRelayLocation(val relayLocation: LocationConstraint?) : Request() + + @Parcelize + data class SetWireGuardMtu(val mtu: Int?) : Request() + + @Parcelize data class VpnPermissionResponse(val isGranted: Boolean) : Request() @Parcelize diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt index 6f978cd46f..5e6524e3a0 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt @@ -57,6 +57,14 @@ class AccountCache(private val endpoint: ServiceEndpoint) { private var createdAccountExpiry: DateTime? = null private var oldAccountExpiry: DateTime? = null + var account: String? + get() = endpoint.settingsListener.accountNumberNotifier.latestEvent + set(value) { + jobTracker.newBackgroundJob("setAccount") { + daemon.await().setAccount(value) + } + } + var loginStatus by onLoginStatusChange.notifiable() private set diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt index bb5434e3e7..a65c313f54 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt @@ -1,12 +1,34 @@ package net.mullvad.mullvadvpn.service.endpoint import kotlin.properties.Delegates.observable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.ClosedReceiveChannelException +import kotlinx.coroutines.channels.actor +import kotlinx.coroutines.channels.sendBlocking import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.ipc.Request +import net.mullvad.mullvadvpn.model.Constraint +import net.mullvad.mullvadvpn.model.LocationConstraint +import net.mullvad.mullvadvpn.model.RelayConstraintsUpdate import net.mullvad.mullvadvpn.model.RelayList +import net.mullvad.mullvadvpn.model.RelaySettingsUpdate import net.mullvad.mullvadvpn.service.MullvadDaemon class RelayListListener(endpoint: ServiceEndpoint) { - val daemon = endpoint.intermittentDaemon + companion object { + private enum class Command { + SetRelayLocation, + } + } + + private val commandChannel = spawnActor() + private val daemon = endpoint.intermittentDaemon + + private var selectedRelayLocation by observable<LocationConstraint?>(null) { _, _, _ -> + commandChannel.sendBlocking(Command.SetRelayLocation) + } var relayList by observable<RelayList?>(null) { _, _, relays -> endpoint.sendEvent(Event.NewRelayList(relays)) @@ -20,9 +42,14 @@ class RelayListListener(endpoint: ServiceEndpoint) { fetchInitialRelayList(daemon) } } + + endpoint.dispatcher.registerHandler(Request.SetRelayLocation::class) { request -> + selectedRelayLocation = request.relayLocation + } } fun onDestroy() { + commandChannel.close() daemon.unregisterListener(this) } @@ -39,4 +66,26 @@ class RelayListListener(endpoint: ServiceEndpoint) { } } } + + private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.CONFLATED) { + try { + for (command in channel) { + when (command) { + Command.SetRelayLocation -> updateRelayConstraints() + } + } + } catch (exception: ClosedReceiveChannelException) { + // Closed sender, so stop the actor + } + } + + private suspend fun updateRelayConstraints() { + val constraint: Constraint<LocationConstraint> = selectedRelayLocation?.let { location -> + Constraint.Only(location) + } ?: Constraint.Any() + + val update = RelaySettingsUpdate.Normal(RelayConstraintsUpdate(constraint)) + + daemon.await().updateRelaySettings(update) + } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt index e1efe2f8c7..c903fc9e37 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt @@ -1,6 +1,13 @@ package net.mullvad.mullvadvpn.service.endpoint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.ClosedReceiveChannelException +import kotlinx.coroutines.channels.actor +import kotlinx.coroutines.channels.sendBlocking import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.ipc.Request import net.mullvad.mullvadvpn.model.DnsOptions import net.mullvad.mullvadvpn.model.RelaySettings import net.mullvad.mullvadvpn.model.Settings @@ -8,6 +15,13 @@ import net.mullvad.mullvadvpn.service.MullvadDaemon import net.mullvad.talpid.util.EventNotifier class SettingsListener(endpoint: ServiceEndpoint) { + private sealed class Command { + class SetAllowLan(val allow: Boolean) : Command() + class SetAutoConnect(val autoConnect: Boolean) : Command() + class SetWireGuardMtu(val mtu: Int?) : Command() + } + + private val commandChannel = spawnActor() private val daemon = endpoint.intermittentDaemon val accountNumberNotifier = EventNotifier<String?>(null) @@ -29,9 +43,24 @@ class SettingsListener(endpoint: ServiceEndpoint) { settingsNotifier.subscribe(this) { settings -> endpoint.sendEvent(Event.SettingsUpdate(settings)) } + + endpoint.dispatcher.apply { + registerHandler(Request.SetAllowLan::class) { request -> + commandChannel.sendBlocking(Command.SetAllowLan(request.allow)) + } + + registerHandler(Request.SetAutoConnect::class) { request -> + commandChannel.sendBlocking(Command.SetAutoConnect(request.autoConnect)) + } + + registerHandler(Request.SetWireGuardMtu::class) { request -> + commandChannel.sendBlocking(Command.SetWireGuardMtu(request.mtu)) + } + } } fun onDestroy() { + commandChannel.close() daemon.unregisterListener(this) accountNumberNotifier.unsubscribeAll() @@ -81,4 +110,18 @@ class SettingsListener(endpoint: ServiceEndpoint) { } } } + + private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) { + try { + for (command in channel) { + when (command) { + is Command.SetAllowLan -> daemon.await().setAllowLan(command.allow) + is Command.SetAutoConnect -> daemon.await().setAutoConnect(command.autoConnect) + is Command.SetWireGuardMtu -> daemon.await().setWireguardMtu(command.mtu) + } + } + } catch (exception: ClosedReceiveChannelException) { + // Closed sender, so stop the actor + } + } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt index 2b26b5b4d4..f9d0a76a32 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt @@ -75,11 +75,7 @@ class AdvancedFragment : ServiceDependentFragment(OnNoService.GoBack) { private fun configureHeader(view: View) { wireguardMtuInput = view.findViewById<MtuCell>(R.id.wireguard_mtu).apply { - onSubmit = { mtu -> - jobTracker.newBackgroundJob("updateMtu") { - daemon.setWireguardMtu(mtu) - } - } + onSubmit = { mtu -> settingsListener.wireguardMtu = mtu } } view.findViewById<NavigateCell>(R.id.wireguard_keys).apply { 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 5452bf49c3..b3e85a94cc 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt @@ -28,8 +28,8 @@ class PreferencesFragment : ServiceDependentFragment(OnNoService.GoBack) { allowLanToggle = view.findViewById<ToggleCell>(R.id.allow_lan).apply { listener = { state -> when (state) { - CellSwitch.State.ON -> daemon.setAllowLan(true) - CellSwitch.State.OFF -> daemon.setAllowLan(false) + CellSwitch.State.ON -> settingsListener.allowLan = true + CellSwitch.State.OFF -> settingsListener.allowLan = false } } } @@ -37,8 +37,8 @@ class PreferencesFragment : ServiceDependentFragment(OnNoService.GoBack) { autoConnectToggle = view.findViewById<ToggleCell>(R.id.auto_connect).apply { listener = { state -> when (state) { - CellSwitch.State.ON -> daemon.setAutoConnect(true) - CellSwitch.State.OFF -> daemon.setAutoConnect(false) + CellSwitch.State.ON -> settingsListener.autoConnect = true + CellSwitch.State.OFF -> settingsListener.autoConnect = false } } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt index 8d30001f2c..73d5e9d3f5 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt @@ -15,11 +15,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.flow.collect import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.model.Constraint import net.mullvad.mullvadvpn.model.KeygenEvent -import net.mullvad.mullvadvpn.model.LocationConstraint -import net.mullvad.mullvadvpn.model.RelayConstraintsUpdate -import net.mullvad.mullvadvpn.model.RelaySettingsUpdate import net.mullvad.mullvadvpn.relaylist.RelayItem import net.mullvad.mullvadvpn.relaylist.RelayList import net.mullvad.mullvadvpn.relaylist.RelayListAdapter @@ -46,7 +42,7 @@ class SelectLocationFragment : relayListAdapter = RelayListAdapter(context.resources).apply { onSelect = { relayItem -> jobTracker.newBackgroundJob("selectRelay") { - updateLocationConstraint(relayItem) + relayListListener.selectedRelayLocation = relayItem?.location maybeConnect() jobTracker.newUiJob("close") { @@ -152,13 +148,6 @@ class SelectLocationFragment : activity?.onBackPressed() } - private fun updateLocationConstraint(relayItem: RelayItem?) { - val constraint: Constraint<LocationConstraint> = - relayItem?.run { Constraint.Only(location) } ?: Constraint.Any() - - daemon.updateRelaySettings(RelaySettingsUpdate.Normal(RelayConstraintsUpdate(constraint))) - } - private fun updateRelayList(relayList: RelayList, selectedItem: RelayItem?) { relayListAdapter.onRelayListChange(relayList, selectedItem) } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt index a37b595404..b8070843e4 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt @@ -1,14 +1,18 @@ package net.mullvad.mullvadvpn.ui.serviceconnection +import android.os.Messenger import net.mullvad.mullvadvpn.ipc.DispatchingHandler import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.ipc.Request import net.mullvad.mullvadvpn.model.Constraint +import net.mullvad.mullvadvpn.model.LocationConstraint import net.mullvad.mullvadvpn.model.RelayConstraints import net.mullvad.mullvadvpn.model.RelaySettings import net.mullvad.mullvadvpn.relaylist.RelayItem import net.mullvad.mullvadvpn.relaylist.RelayList class RelayListListener( + val connection: Messenger, eventDispatcher: DispatchingHandler<Event>, val settingsListener: SettingsListener ) { @@ -18,6 +22,17 @@ class RelayListListener( var selectedRelayItem: RelayItem? = null private set + var selectedRelayLocation: LocationConstraint? + get() { + val settings = relaySettings as? RelaySettings.Normal + val location = settings?.relayConstraints?.location as? Constraint.Only + + return location?.value + } + set(value) { + connection.send(Request.SetRelayLocation(value).message) + } + var onRelayListChange: ((RelayList, RelayItem?) -> Unit)? = null set(value) { field = value diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt index 95c28b810e..f24ca088f4 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt @@ -36,7 +36,7 @@ class ServiceConnection(private val service: ServiceInstance) : KoinScopeCompone val connectionProxy = ConnectionProxy(service.messenger, dispatcher) val keyStatusListener = KeyStatusListener(service.messenger, dispatcher) val locationInfoCache = LocationInfoCache(dispatcher) - val settingsListener = SettingsListener(dispatcher) + val settingsListener = SettingsListener(service.messenger, dispatcher) val splitTunneling = get<SplitTunneling>( parameters = { parametersOf(service.messenger, dispatcher) } ) @@ -44,7 +44,7 @@ class ServiceConnection(private val service: ServiceInstance) : KoinScopeCompone val appVersionInfoCache = AppVersionInfoCache(dispatcher, settingsListener) val customDns = CustomDns(service.messenger, settingsListener) - var relayListListener = RelayListListener(dispatcher, settingsListener) + var relayListListener = RelayListListener(service.messenger, dispatcher, settingsListener) init { registerListener() diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt index f98b8a27ae..d7382ab240 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt @@ -1,13 +1,15 @@ package net.mullvad.mullvadvpn.ui.serviceconnection +import android.os.Messenger import net.mullvad.mullvadvpn.ipc.DispatchingHandler import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.ipc.Request import net.mullvad.mullvadvpn.model.DnsOptions import net.mullvad.mullvadvpn.model.RelaySettings import net.mullvad.mullvadvpn.model.Settings import net.mullvad.talpid.util.EventNotifier -class SettingsListener(eventDispatcher: DispatchingHandler<Event>) { +class SettingsListener(val connection: Messenger, eventDispatcher: DispatchingHandler<Event>) { val accountNumberNotifier = EventNotifier<String?>(null) val dnsOptionsNotifier = EventNotifier<DnsOptions?>(null) val relaySettingsNotifier = EventNotifier<RelaySettings?>(null) @@ -15,6 +17,22 @@ class SettingsListener(eventDispatcher: DispatchingHandler<Event>) { private var settings by settingsNotifier.notifiable() + var account: String? + get() = accountNumberNotifier.latestEvent + set(value) { connection.send(Request.SetAccount(value).message) } + + var allowLan: Boolean + get() = settingsNotifier.latestEvent?.allowLan ?: false + set(value) { connection.send(Request.SetAllowLan(value).message) } + + var autoConnect: Boolean + get() = settingsNotifier.latestEvent?.autoConnect ?: false + set(value) { connection.send(Request.SetAutoConnect(value).message) } + + var wireguardMtu: Int? + get() = settingsNotifier.latestEvent?.tunnelOptions?.wireguard?.options?.mtu + set(value) { connection.send(Request.SetWireGuardMtu(value).message) } + init { eventDispatcher.registerHandler(Event.SettingsUpdate::class, ::handleNewEvent) } |
