summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-06-13 19:25:03 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-06-17 14:42:59 +0000
commit6599e42d93469d5fbe4ac77b0b16721d1acd257c (patch)
treeaa00e9fc004e8bc8ae19a8b34f6f4344f9756f45 /android
parent981b2e2174b41ceabf6464e86e7f9c4fc175bf2f (diff)
downloadmullvadvpn-6599e42d93469d5fbe4ac77b0b16721d1acd257c.tar.xz
mullvadvpn-6599e42d93469d5fbe4ac77b0b16721d1acd257c.zip
Create `RelayListListener` helper type
Diffstat (limited to 'android')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListListener.kt113
1 files changed, 113 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListListener.kt
new file mode 100644
index 0000000000..87624b116c
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListListener.kt
@@ -0,0 +1,113 @@
+package net.mullvad.mullvadvpn.relaylist
+
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+
+import net.mullvad.mullvadvpn.MainActivity
+import net.mullvad.mullvadvpn.model.Constraint
+import net.mullvad.mullvadvpn.model.LocationConstraint
+import net.mullvad.mullvadvpn.model.RelaySettings
+import net.mullvad.mullvadvpn.MullvadDaemon
+
+class RelayListListener(val parentActivity: MainActivity) {
+ private val daemon = CompletableDeferred<MullvadDaemon>()
+ private val setUpJob = setUp()
+
+ private var relayList: RelayList? = null
+ private var relaySettings: RelaySettings? = null
+
+ var selectedRelayItem: RelayItem? = null
+ set(value) {
+ field = value
+ updateRelaySettings()
+ }
+
+ val selectedRelayLocation: Constraint<LocationConstraint>
+ get() {
+ val location = selectedRelayItem?.location
+
+ if (location == null) {
+ return Constraint.Any()
+ } else {
+ return Constraint.Only(location)
+ }
+ }
+
+ var onRelayListChange: ((RelayList, RelayItem?) -> Unit)? = null
+ set(value) {
+ field = value
+
+ synchronized(this) {
+ val relayList = this.relayList
+
+ if (relayList != null) {
+ value?.invoke(relayList, selectedRelayItem)
+ }
+ }
+ }
+
+ fun onDestroy() {
+ setUpJob.cancel()
+
+ if (daemon.isActive) {
+ daemon.cancel()
+ } else {
+ daemon.getCompleted().onRelayListChange = null
+ }
+ }
+
+ private fun setUp() = GlobalScope.launch(Dispatchers.Default) {
+ daemon.complete(parentActivity.asyncDaemon.await())
+
+ setUpListener()
+ fetchInitialRelayList()
+ }
+
+ private suspend fun setUpListener() {
+ daemon.await().onRelayListChange = { relayLocations ->
+ relayListChanged(RelayList(relayLocations))
+ }
+ }
+
+ private suspend fun fetchInitialRelayList() {
+ val relayLocations = daemon.await().getRelayLocations()
+
+ relaySettings = parentActivity.asyncSettings.await().relaySettings
+
+ synchronized(this) {
+ if (relayList == null) {
+ relayListChanged(RelayList(relayLocations))
+ }
+ }
+ }
+
+ private fun relayListChanged(newRelayList: RelayList) {
+ synchronized(this) {
+ relayList = newRelayList
+ selectedRelayItem = findSelectedRelayItem()
+
+ onRelayListChange?.invoke(newRelayList, selectedRelayItem)
+ }
+ }
+
+ private fun findSelectedRelayItem(): RelayItem? {
+ val relaySettings = this.relaySettings
+
+ when (relaySettings) {
+ is RelaySettings.CustomTunnelEndpoint -> return null
+ is RelaySettings.RelayConstraints -> {
+ val location = relaySettings.location
+
+ return relayList?.findItemForLocation(location, true)
+ }
+ }
+
+ return null
+ }
+
+ private fun updateRelaySettings() {
+ relaySettings = RelaySettings.RelayConstraints(selectedRelayLocation)
+ }
+}