summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-10-29 23:42:37 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-11-08 08:55:59 +0100
commitcf98ad2685c579d585ca2d30c4dfcdcde5879d36 (patch)
tree46be4c94d8f681e01dfbb7863024f5d7280b60ef /android
parent5e9ea351730db33da12193d96363a3b79374d361 (diff)
downloadmullvadvpn-cf98ad2685c579d585ca2d30c4dfcdcde5879d36.tar.xz
mullvadvpn-cf98ad2685c579d585ca2d30c4dfcdcde5879d36.zip
Add ownership and provider to relay constraints updates
Diffstat (limited to 'android')
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Provider.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/RelayListFilterUseCase.kt17
-rw-r--r--android/lib/ipc/src/main/kotlin/net/mullvad/mullvadvpn/lib/ipc/Request.kt2
-rw-r--r--android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt123
5 files changed, 75 insertions, 75 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Provider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Provider.kt
new file mode 100644
index 0000000000..c103976700
--- /dev/null
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Provider.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.relaylist
+
+data class Provider(val name: String, val mullvadOwned: Boolean)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt
index 386f7e3bf4..0a1767624c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt
@@ -6,6 +6,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import net.mullvad.mullvadvpn.lib.ipc.Event
import net.mullvad.mullvadvpn.lib.ipc.Request
@@ -25,6 +26,10 @@ class RelayListListener(
messageHandler
.events<Event.NewRelayList>()
.map { it.relayList ?: defaultRelayList() }
+ // This is added so that we always have a relay list. Otherwise sometimes there would
+ // not be a relay list since the fetching of a relay list would be done before the
+ // event stream is available.
+ .onStart { messageHandler.trySendRequest(Request.FetchRelayList) }
.stateIn(CoroutineScope(dispatcher), SharingStarted.Eagerly, defaultRelayList())
fun updateSelectedRelayLocation(value: GeographicLocationConstraint) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/RelayListFilterUseCase.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/RelayListFilterUseCase.kt
index f15b2535cb..a26f302f9c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/RelayListFilterUseCase.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/RelayListFilterUseCase.kt
@@ -7,6 +7,7 @@ import net.mullvad.mullvadvpn.model.Ownership
import net.mullvad.mullvadvpn.model.Providers
import net.mullvad.mullvadvpn.model.RelayListCity
import net.mullvad.mullvadvpn.model.RelayListCountry
+import net.mullvad.mullvadvpn.relaylist.Provider
import net.mullvad.mullvadvpn.repository.SettingsRepository
import net.mullvad.mullvadvpn.ui.serviceconnection.RelayListListener
@@ -32,15 +33,13 @@ class RelayListFilterUseCase(
settings?.relaySettings?.relayConstraints()?.providers ?: Constraint.Any()
}
- fun availableProviders(): Flow<List<Pair<String, Boolean>>> =
+ fun availableProviders(): Flow<List<Provider>> =
relayListListener.relayListEvents.map { relayList ->
- relayList
- ?.countries
- ?.flatMap(RelayListCountry::cities)
- ?.flatMap(RelayListCity::relays)
- ?.filter { relay -> relay.isWireguardRelay }
- ?.map { relay -> relay.provider to relay.owned }
- ?.distinct()
- ?: emptyList()
+ relayList.countries
+ .flatMap(RelayListCountry::cities)
+ .flatMap(RelayListCity::relays)
+ .filter { relay -> relay.isWireguardRelay }
+ .map { relay -> Provider(relay.provider, relay.owned) }
+ .distinct()
}
}
diff --git a/android/lib/ipc/src/main/kotlin/net/mullvad/mullvadvpn/lib/ipc/Request.kt b/android/lib/ipc/src/main/kotlin/net/mullvad/mullvadvpn/lib/ipc/Request.kt
index 704013fb39..38237e84b3 100644
--- a/android/lib/ipc/src/main/kotlin/net/mullvad/mullvadvpn/lib/ipc/Request.kt
+++ b/android/lib/ipc/src/main/kotlin/net/mullvad/mullvadvpn/lib/ipc/Request.kt
@@ -102,6 +102,8 @@ sealed class Request : Message.RequestMessage() {
@Parcelize data class SetProviders(val providers: Constraint<Providers>) : Request()
+ @Parcelize data object FetchRelayList : Request()
+
companion object {
private const val MESSAGE_KEY = "request"
diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt
index 2fc1e4115a..186ac21092 100644
--- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt
+++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt
@@ -1,16 +1,16 @@
package net.mullvad.mullvadvpn.service.endpoint
import kotlin.properties.Delegates.observable
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
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.trySendBlocking
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.filterIsInstance
+import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.lib.ipc.Event
import net.mullvad.mullvadvpn.lib.ipc.Request
import net.mullvad.mullvadvpn.model.Constraint
-import net.mullvad.mullvadvpn.model.GeographicLocationConstraint
import net.mullvad.mullvadvpn.model.LocationConstraint
import net.mullvad.mullvadvpn.model.RelayConstraints
import net.mullvad.mullvadvpn.model.RelayList
@@ -18,20 +18,13 @@ import net.mullvad.mullvadvpn.model.RelaySettings
import net.mullvad.mullvadvpn.model.WireguardConstraints
import net.mullvad.mullvadvpn.service.MullvadDaemon
-class RelayListListener(endpoint: ServiceEndpoint) {
-
- private val commandChannel = spawnActor()
+class RelayListListener(
+ endpoint: ServiceEndpoint,
+ dispatcher: CoroutineDispatcher = Dispatchers.IO
+) {
+ private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + dispatcher)
private val daemon = endpoint.intermittentDaemon
- private var selectedRelayLocation by
- observable<GeographicLocationConstraint?>(null) { _, _, _ ->
- commandChannel.trySendBlocking(Command.SetRelayLocation)
- }
- private var selectedWireguardConstraints by
- observable<WireguardConstraints?>(null) { _, _, _ ->
- commandChannel.trySendBlocking(Command.SetWireguardConstraints)
- }
-
var relayList by
observable<RelayList?>(null) { _, _, relays ->
endpoint.sendEvent(Event.NewRelayList(relays))
@@ -46,18 +39,59 @@ class RelayListListener(endpoint: ServiceEndpoint) {
}
}
- endpoint.dispatcher.registerHandler(Request.SetRelayLocation::class) { request ->
- selectedRelayLocation = request.relayLocation
+ scope.launch {
+ endpoint.dispatcher.parsedMessages
+ .filterIsInstance<Request.SetRelayLocation>()
+ .collect { request ->
+ val update =
+ getCurrentRelayConstraints()
+ .copy(
+ location =
+ Constraint.Only(
+ LocationConstraint.Location(request.relayLocation)
+ )
+ )
+ daemon.await().setRelaySettings(RelaySettings.Normal(update))
+ }
+ }
+
+ scope.launch {
+ endpoint.dispatcher.parsedMessages
+ .filterIsInstance<Request.SetWireguardConstraints>()
+ .collect { request ->
+ val update =
+ getCurrentRelayConstraints()
+ .copy(wireguardConstraints = request.wireguardConstraints)
+ daemon.await().setRelaySettings(RelaySettings.Normal(update))
+ }
}
- endpoint.dispatcher.registerHandler(Request.SetWireguardConstraints::class) { request ->
- selectedWireguardConstraints = request.wireguardConstraints
+ scope.launch {
+ endpoint.dispatcher.parsedMessages.filterIsInstance<Request.SetOwnership>().collect {
+ request ->
+ val update = getCurrentRelayConstraints().copy(ownership = request.ownership)
+ daemon.await().setRelaySettings(RelaySettings.Normal(update))
+ }
+ }
+
+ scope.launch {
+ endpoint.dispatcher.parsedMessages.filterIsInstance<Request.SetProviders>().collect {
+ request ->
+ val update = getCurrentRelayConstraints().copy(providers = request.providers)
+ daemon.await().setRelaySettings(RelaySettings.Normal(update))
+ }
+ }
+
+ scope.launch {
+ endpoint.dispatcher.parsedMessages.filterIsInstance<Request.FetchRelayList>().collect {
+ relayList = daemon.await().getRelayLocations()
+ }
}
}
fun onDestroy() {
- commandChannel.close()
daemon.unregisterListener(this)
+ scope.cancel()
}
private fun setUpListener(daemon: MullvadDaemon) {
@@ -72,42 +106,6 @@ class RelayListListener(endpoint: ServiceEndpoint) {
}
}
- private fun spawnActor() =
- GlobalScope.actor<Command>(Dispatchers.Default, Channel.CONFLATED) {
- try {
- for (command in channel) {
- when (command) {
- Command.SetRelayLocation,
- Command.SetWireguardConstraints -> updateRelayConstraints()
- }
- }
- } catch (exception: ClosedReceiveChannelException) {
- // Closed sender, so stop the actor
- }
- }
-
- private suspend fun updateRelayConstraints() {
- val currentRelayConstraints = getCurrentRelayConstraints()
- val location: Constraint<LocationConstraint> =
- selectedRelayLocation?.let { location ->
- Constraint.Only(LocationConstraint.Location(location))
- } ?: currentRelayConstraints.location
- val wireguardConstraints: WireguardConstraints =
- selectedWireguardConstraints ?: currentRelayConstraints.wireguardConstraints
-
- val update =
- RelaySettings.Normal(
- RelayConstraints(
- location = location,
- wireguardConstraints = wireguardConstraints,
- ownership = Constraint.Any(),
- providers = Constraint.Any()
- )
- )
-
- daemon.await().setRelaySettings(update)
- }
-
private suspend fun getCurrentRelayConstraints(): RelayConstraints =
when (val relaySettings = daemon.await().getSettings()?.relaySettings) {
is RelaySettings.Normal -> relaySettings.relayConstraints
@@ -119,11 +117,4 @@ class RelayListListener(endpoint: ServiceEndpoint) {
wireguardConstraints = WireguardConstraints(Constraint.Any())
)
}
-
- companion object {
- private enum class Command {
- SetRelayLocation,
- SetWireguardConstraints
- }
- }
}