summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AppVersionInfoFetcher.kt74
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt7
4 files changed, 88 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
index 9de3dc12d7..751334ea61 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
@@ -1,6 +1,7 @@
package net.mullvad.mullvadvpn
import net.mullvad.mullvadvpn.model.AccountData
+import net.mullvad.mullvadvpn.model.AppVersionInfo
import net.mullvad.mullvadvpn.model.GeoIpLocation
import net.mullvad.mullvadvpn.model.KeygenEvent
import net.mullvad.mullvadvpn.model.PublicKey
@@ -29,6 +30,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
external fun getRelayLocations(): RelayList
external fun getSettings(): Settings
external fun getState(): TunnelState
+ external fun getVersionInfo(): AppVersionInfo?
external fun getWireguardKey(): PublicKey?
external fun setAccount(accountToken: String?)
external fun updateRelaySettings(update: RelaySettingsUpdate)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt
index bc0c317cf2..6cb45329ff 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt
@@ -15,15 +15,19 @@ import android.net.VpnService
import android.os.Binder
import android.os.IBinder
+import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoFetcher
import net.mullvad.mullvadvpn.model.TunConfig
class MullvadVpnService : VpnService() {
private val created = CompletableDeferred<Unit>()
private val binder = LocalBinder()
+ private lateinit var versionInfoFetcher: AppVersionInfoFetcher
+
val daemon = startDaemon()
override fun onCreate() {
+ versionInfoFetcher = AppVersionInfoFetcher(daemon, this)
created.complete(Unit)
}
@@ -32,6 +36,7 @@ class MullvadVpnService : VpnService() {
}
override fun onDestroy() {
+ versionInfoFetcher.stop()
daemon.cancel()
created.cancel()
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AppVersionInfoFetcher.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AppVersionInfoFetcher.kt
new file mode 100644
index 0000000000..2b066c934b
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AppVersionInfoFetcher.kt
@@ -0,0 +1,74 @@
+package net.mullvad.mullvadvpn.dataproxy
+
+import java.util.Calendar
+
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+
+import android.content.Context
+
+import net.mullvad.mullvadvpn.MullvadDaemon
+
+val ONE_DAY_IN_MILLISECONDS = 24L * 60L * 60L * 1000L
+val ONE_MINUTE_IN_MILLISECONDS = 60L * 1000L
+
+val KEY_CURRENT_IS_SUPPORTED = "current_is_supported"
+val KEY_LAST_UPDATED = "last_updated"
+val KEY_LATEST_STABLE = "latest_stable"
+val KEY_LATEST = "latest"
+val SHARED_PREFERENCES = "app_version_info_cache"
+
+class AppVersionInfoFetcher(val daemon: Deferred<MullvadDaemon>, val context: Context) {
+ private val preferences = context.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE)
+
+ private val mainLoop = run()
+
+ fun stop() {
+ mainLoop.cancel()
+ }
+
+ private fun run() = GlobalScope.launch(Dispatchers.Default) {
+ while (true) {
+ delay(calculateDelay())
+ fetch()
+ }
+ }
+
+ private fun calculateDelay(): Long {
+ val now = Calendar.getInstance().timeInMillis
+ val lastUpdated = preferences.getLong(KEY_LAST_UPDATED, 0)
+ val delta = now - lastUpdated
+
+ if (delta < 0 || delta >= ONE_DAY_IN_MILLISECONDS) {
+ return 0
+ } else {
+ return ONE_DAY_IN_MILLISECONDS - delta
+ }
+ }
+
+ private suspend fun fetch() {
+ var now = Calendar.getInstance().timeInMillis
+ var versionInfo = daemon.await().getVersionInfo()
+ var attempt = 0
+
+ while (attempt < 5 && versionInfo == null) {
+ delay(ONE_MINUTE_IN_MILLISECONDS)
+ now = Calendar.getInstance().timeInMillis
+ versionInfo = daemon.await().getVersionInfo()
+ attempt += 1
+ }
+
+ if (versionInfo != null) {
+ preferences.edit().apply {
+ putLong(KEY_LAST_UPDATED, now)
+ putBoolean(KEY_CURRENT_IS_SUPPORTED, versionInfo.currentIsSupported)
+ putString(KEY_LATEST_STABLE, versionInfo.latestStable)
+ putString(KEY_LATEST, versionInfo.latest)
+ commit()
+ }
+ }
+ }
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt
new file mode 100644
index 0000000000..0c41090f3f
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt
@@ -0,0 +1,7 @@
+package net.mullvad.mullvadvpn.model
+
+data class AppVersionInfo(
+ val currentIsSupported: Boolean,
+ val latestStable: String,
+ val latest: String
+)