diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-06-18 07:49:22 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-06-18 07:49:22 -0300 |
| commit | 1f9cac7a2418138d1c1138a5816cffd8df6ebe55 (patch) | |
| tree | 1e5349dde6f991df32b728179efad53185de21b4 /android/src | |
| parent | 76520c1f7335e514eadd204e12c9b91f914a81df (diff) | |
| parent | 1ab36bd1b07f977bfbab43aad64c3a4c1b129f27 (diff) | |
| download | mullvadvpn-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.kt | 15 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/LocationInfo.kt | 68 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt | 5 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/SelectLocationFragment.kt | 2 | ||||
| -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.kt | 72 | ||||
| -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>() |
