summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-06-18 07:49:22 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-06-18 07:49:22 -0300
commit1f9cac7a2418138d1c1138a5816cffd8df6ebe55 (patch)
tree1e5349dde6f991df32b728179efad53185de21b4 /android/src
parent76520c1f7335e514eadd204e12c9b91f914a81df (diff)
parent1ab36bd1b07f977bfbab43aad64c3a4c1b129f27 (diff)
downloadmullvadvpn-1f9cac7a2418138d1c1138a5816cffd8df6ebe55.tar.xz
mullvadvpn-1f9cac7a2418138d1c1138a5816cffd8df6ebe55.zip
Merge branch 'cache-location-info'
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt15
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt68
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/SelectLocationFragment.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt (renamed from android/src/main/kotlin/net/mullvad/mullvadvpn/AccountCache.kt)5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt72
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt (renamed from android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListListener.kt)4
7 files changed, 110 insertions, 61 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt
index 9c1804ce68..dac1426b2a 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt
@@ -1,6 +1,5 @@
package net.mullvad.mullvadvpn
-import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
@@ -21,6 +20,7 @@ import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageButton
+import net.mullvad.mullvadvpn.dataproxy.LocationInfoCache
import net.mullvad.mullvadvpn.model.GeoIpLocation
import net.mullvad.mullvadvpn.model.TunnelStateTransition
@@ -32,6 +32,7 @@ class ConnectFragment : Fragment() {
private lateinit var locationInfo: LocationInfo
private lateinit var parentActivity: MainActivity
+ private lateinit var locationInfoCache: LocationInfoCache
private var daemon = CompletableDeferred<MullvadDaemon>()
private var vpnPermission = CompletableDeferred<Unit>()
@@ -39,8 +40,6 @@ class ConnectFragment : Fragment() {
private var fetchInitialStateJob = fetchInitialState()
private var generateWireguardKeyJob = generateWireguardKey()
- private var lastKnownRealLocation: GeoIpLocation? = null
-
private var activeAction: Job? = null
private var attachListenerJob: Job? = null
private var updateViewJob: Job? = null
@@ -50,6 +49,7 @@ class ConnectFragment : Fragment() {
super.onAttach(context)
parentActivity = context as MainActivity
+ locationInfoCache = parentActivity.locationInfoCache
waitForDaemonJob = waitForDaemon(parentActivity.asyncDaemon)
}
@@ -71,7 +71,7 @@ class ConnectFragment : Fragment() {
headerBar = HeaderBar(view, context!!)
notificationBanner = NotificationBanner(view)
status = ConnectionStatus(view, context!!)
- locationInfo = LocationInfo(view, daemon)
+ locationInfo = LocationInfo(view, locationInfoCache)
actionButton = ConnectActionButton(view)
actionButton.apply {
@@ -86,11 +86,16 @@ class ConnectFragment : Fragment() {
}
override fun onDestroyView() {
+ locationInfo.onDestroy()
+
waitForDaemonJob?.cancel()
attachListenerJob?.cancel()
+
detachListener()
+
generateWireguardKeyJob.cancel()
updateViewJob?.cancel()
+
super.onDestroyView()
}
@@ -184,7 +189,7 @@ class ConnectFragment : Fragment() {
headerBar.setState(state)
notificationBanner.setState(state)
status.setState(state)
- locationInfo.setState(state)
+ locationInfoCache.setState(state)
}
private fun openSwitchLocationScreen() {
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt
index b25406c90e..4670cd5e12 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt
@@ -1,8 +1,6 @@
package net.mullvad.mullvadvpn
-import kotlinx.coroutines.async
import kotlinx.coroutines.launch
-import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
@@ -10,61 +8,31 @@ import kotlinx.coroutines.Job
import android.view.View
import android.widget.TextView
-import net.mullvad.mullvadvpn.model.GeoIpLocation
-import net.mullvad.mullvadvpn.model.TunnelStateTransition
+import net.mullvad.mullvadvpn.dataproxy.LocationInfoCache
-class LocationInfo(val parentView: View, val daemon: Deferred<MullvadDaemon>) {
- private val country: TextView = parentView.findViewById(R.id.country)
- private val city: TextView = parentView.findViewById(R.id.city)
- private val hostname: TextView = parentView.findViewById(R.id.hostname)
+class LocationInfo(val parentView: View, val locationInfoCache: LocationInfoCache) {
+ private val countryLabel: TextView = parentView.findViewById(R.id.country)
+ private val cityLabel: TextView = parentView.findViewById(R.id.city)
+ private val hostnameLabel: TextView = parentView.findViewById(R.id.hostname)
- private var lastKnownRealLocation: GeoIpLocation? = null
+ private var updateJob: Job? = null
- private var activeFetch: Job? = null
-
- var location: GeoIpLocation? = null
- set(value) {
- field = value
- updateViews(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
+ init {
+ locationInfoCache.onNewLocation = { country, city, hostname ->
+ updateJob?.cancel()
+ updateJob = updateViews(country, city, hostname)
}
}
- fun updateViews(location: GeoIpLocation?) {
- country.text = location?.country ?: ""
- city.text = location?.city ?: ""
- hostname.text = location?.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()
+ fun onDestroy() {
+ updateJob?.cancel()
+ locationInfoCache.onNewLocation = null
}
- private fun fetchLocation() = GlobalScope.async(Dispatchers.Default) {
- daemon.await().getCurrentLocation()
+ fun updateViews(country: String, city: String, hostname: String) =
+ GlobalScope.launch(Dispatchers.Main) {
+ countryLabel.text = country
+ cityLabel.text = city
+ hostnameLabel.text = hostname
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
index e21c7b6682..4b5414da71 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
@@ -16,11 +16,13 @@ import android.os.Bundle
import android.os.IBinder
import android.support.v4.app.FragmentActivity
+import net.mullvad.mullvadvpn.dataproxy.AccountCache
+import net.mullvad.mullvadvpn.dataproxy.LocationInfoCache
+import net.mullvad.mullvadvpn.dataproxy.RelayListListener
import net.mullvad.mullvadvpn.model.RelaySettings
import net.mullvad.mullvadvpn.model.Settings
import net.mullvad.mullvadvpn.relaylist.RelayItem
import net.mullvad.mullvadvpn.relaylist.RelayList
-import net.mullvad.mullvadvpn.relaylist.RelayListListener
class MainActivity : FragmentActivity() {
var asyncDaemon = CompletableDeferred<MullvadDaemon>()
@@ -33,6 +35,7 @@ class MainActivity : FragmentActivity() {
get() = runBlocking { asyncSettings.await() }
val accountCache = AccountCache(this)
+ val locationInfoCache = LocationInfoCache(asyncDaemon)
var relayListListener = RelayListListener(this)
private var waitForDaemonJob: Job? = null
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/SelectLocationFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/SelectLocationFragment.kt
index 4255dc3060..62a9440f64 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/SelectLocationFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/SelectLocationFragment.kt
@@ -16,6 +16,7 @@ import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ViewSwitcher
+import net.mullvad.mullvadvpn.dataproxy.RelayListListener
import net.mullvad.mullvadvpn.model.Constraint
import net.mullvad.mullvadvpn.model.LocationConstraint
import net.mullvad.mullvadvpn.model.RelaySettingsUpdate
@@ -23,7 +24,6 @@ import net.mullvad.mullvadvpn.relaylist.RelayItem
import net.mullvad.mullvadvpn.relaylist.RelayItemDividerDecoration
import net.mullvad.mullvadvpn.relaylist.RelayList
import net.mullvad.mullvadvpn.relaylist.RelayListAdapter
-import net.mullvad.mullvadvpn.relaylist.RelayListListener
class SelectLocationFragment : Fragment() {
private lateinit var parentActivity: MainActivity
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/AccountCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt
index af0e02da7a..41d23b4a26 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/AccountCache.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AccountCache.kt
@@ -1,14 +1,13 @@
-package net.mullvad.mullvadvpn
+package net.mullvad.mullvadvpn.dataproxy
import kotlinx.coroutines.async
-import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import org.joda.time.format.DateTimeFormat
import org.joda.time.DateTime
-import net.mullvad.mullvadvpn.model.Settings
+import net.mullvad.mullvadvpn.MainActivity
val EXPIRY_FORMAT = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss z")
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..98e529fbb8
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
@@ -0,0 +1,72 @@
+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
+ set(value) {
+ field = value
+ notifyNewLocation()
+ }
+
+ var location: GeoIpLocation? = null
+ set(value) {
+ field = value
+ notifyNewLocation()
+ }
+
+ 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() {
+ val location = this.location
+ 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()
+ }
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt
index 87624b116c..64121aac96 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListListener.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/RelayListListener.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.relaylist
+package net.mullvad.mullvadvpn.dataproxy
import kotlinx.coroutines.launch
import kotlinx.coroutines.CompletableDeferred
@@ -10,6 +10,8 @@ import net.mullvad.mullvadvpn.model.Constraint
import net.mullvad.mullvadvpn.model.LocationConstraint
import net.mullvad.mullvadvpn.model.RelaySettings
import net.mullvad.mullvadvpn.MullvadDaemon
+import net.mullvad.mullvadvpn.relaylist.RelayList
+import net.mullvad.mullvadvpn.relaylist.RelayItem
class RelayListListener(val parentActivity: MainActivity) {
private val daemon = CompletableDeferred<MullvadDaemon>()