summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-06-14 13:48:25 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-06-18 10:40:26 +0000
commit2dc2f762228ed61cd27971fefe74c3540778f1a1 (patch)
tree38eb2dbb36c32c6e72526116c3e45c41d9009c26 /android/src
parenta60873ee8564157fc0e0a1c40df205c6c4104436 (diff)
downloadmullvadvpn-2dc2f762228ed61cd27971fefe74c3540778f1a1.tar.xz
mullvadvpn-2dc2f762228ed61cd27971fefe74c3540778f1a1.zip
Create `LocationInfoCache` helper class
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt67
1 files changed, 67 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
new file mode 100644
index 0000000000..ba3f9cefd4
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
@@ -0,0 +1,67 @@
+package net.mullvad.mullvadvpn.dataproxy
+
+import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+
+import net.mullvad.mullvadvpn.model.GeoIpLocation
+import net.mullvad.mullvadvpn.model.TunnelStateTransition
+import net.mullvad.mullvadvpn.MullvadDaemon
+
+class LocationInfoCache(val daemon: Deferred<MullvadDaemon>) {
+ private var lastKnownRealLocation: GeoIpLocation? = null
+ private var activeFetch: Job? = null
+
+ var onNewLocation: ((String, String, String) -> Unit)? = null
+
+ var location: GeoIpLocation? = null
+ set(value) {
+ field = value
+ notifyNewLocation(value)
+ }
+
+ fun setState(state: TunnelStateTransition) {
+ activeFetch?.cancel()
+ activeFetch = null
+
+ when (state) {
+ is TunnelStateTransition.Disconnected -> activeFetch = fetchRealLocation()
+ is TunnelStateTransition.Connecting -> activeFetch = fetchRelayLocation()
+ is TunnelStateTransition.Connected -> activeFetch = fetchRelayLocation()
+ is TunnelStateTransition.Disconnecting -> location = lastKnownRealLocation
+ is TunnelStateTransition.Blocked -> location = null
+ }
+ }
+
+ fun notifyNewLocation(location: GeoIpLocation?) {
+ val country = location?.country ?: ""
+ val city = location?.city ?: ""
+ val hostname = location?.hostname ?: ""
+
+ onNewLocation?.invoke(country, city, hostname)
+ }
+
+ private fun fetchRealLocation() = GlobalScope.launch(Dispatchers.Main) {
+ var realLocation: GeoIpLocation? = null
+ var remainingAttempts = 10
+
+ while (realLocation == null && remainingAttempts > 0) {
+ realLocation = fetchLocation().await()
+ remainingAttempts -= 1
+ }
+
+ lastKnownRealLocation = realLocation
+ location = realLocation
+ }
+
+ private fun fetchRelayLocation() = GlobalScope.launch(Dispatchers.Main) {
+ location = fetchLocation().await()
+ }
+
+ private fun fetchLocation() = GlobalScope.async(Dispatchers.Default) {
+ daemon.await().getCurrentLocation()
+ }
+}