diff options
Diffstat (limited to 'android')
11 files changed, 139 insertions, 105 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AppVersionInfoCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AppVersionInfoCache.kt deleted file mode 100644 index eafe9f1493..0000000000 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/AppVersionInfoCache.kt +++ /dev/null @@ -1,94 +0,0 @@ -package net.mullvad.mullvadvpn.dataproxy - -import android.content.Context -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.model.AppVersionInfo -import net.mullvad.mullvadvpn.service.MullvadDaemon -import net.mullvad.mullvadvpn.ui.serviceconnection.SettingsListener - -class AppVersionInfoCache( - val context: Context, - val daemon: MullvadDaemon, - val settingsListener: SettingsListener -) { - companion object { - val LEGACY_SHARED_PREFERENCES = "app_version_info_cache" - } - - private val setUpJob = setUp() - - private var appVersionInfo: AppVersionInfo? = null - set(value) { - synchronized(this) { - field = value - onUpdate?.invoke() - } - } - - val isSupported - get() = appVersionInfo?.supported ?: true - - val isOutdated - get() = appVersionInfo?.suggestedUpgrade != null - - val upgradeVersion - get() = appVersionInfo?.suggestedUpgrade - - var onUpdate: (() -> Unit)? = null - set(value) { - field = value - value?.invoke() - } - - var showBetaReleases = false - private set(value) { - if (field != value) { - field = value - onUpdate?.invoke() - } - } - - var version: String? = null - private set - - init { - settingsListener.settingsNotifier.subscribe(this) { maybeSettings -> - maybeSettings?.let { settings -> - showBetaReleases = settings.showBetaReleases - } - } - } - - fun onCreate() { - context.getSharedPreferences(LEGACY_SHARED_PREFERENCES, Context.MODE_PRIVATE) - .edit() - .clear() - .commit() - } - - fun onDestroy() { - setUpJob.cancel() - settingsListener.settingsNotifier.unsubscribe(this) - daemon.onAppVersionInfoChange = null - } - - private fun setUp() = GlobalScope.launch(Dispatchers.Default) { - val currentVersion = daemon.getCurrentVersion() - - version = currentVersion - - daemon.onAppVersionInfoChange = { newAppVersionInfo -> - appVersionInfo = newAppVersionInfo - } - - synchronized(this@AppVersionInfoCache) { - val initialVersionInfo = daemon.getVersionInfo() - - if (appVersionInfo == null) { - appVersionInfo = initialVersionInfo - } - } - } -} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt index 1211e88d04..c9a039be70 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt @@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.ipc import android.os.Message as RawMessage import kotlinx.parcelize.Parcelize +import net.mullvad.mullvadvpn.model.AppVersionInfo as AppVersionInfoData import net.mullvad.mullvadvpn.model.GeoIpLocation import net.mullvad.mullvadvpn.model.KeygenEvent import net.mullvad.mullvadvpn.model.LoginStatus as LoginStatusData @@ -16,6 +17,12 @@ sealed class Event : Message.EventMessage() { data class AccountHistory(val history: List<String>?) : Event() @Parcelize + data class AppVersionInfo(val versionInfo: AppVersionInfoData?) : Event() + + @Parcelize + data class CurrentVersion(val version: String?) : Event() + + @Parcelize object ListenerReady : Event() @Parcelize diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt index 5f985189d5..cc1127d026 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt @@ -1,6 +1,10 @@ package net.mullvad.mullvadvpn.model +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize data class AppVersionInfo( val supported: Boolean, val suggestedUpgrade: String? -) +) : Parcelable diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt new file mode 100644 index 0000000000..0c95293ae7 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt @@ -0,0 +1,56 @@ +package net.mullvad.mullvadvpn.service.endpoint + +import kotlin.properties.Delegates.observable +import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.model.AppVersionInfo +import net.mullvad.mullvadvpn.service.MullvadDaemon + +class AppVersionInfoCache(endpoint: ServiceEndpoint) { + private val daemon = endpoint.intermittentDaemon + + var appVersionInfo by observable<AppVersionInfo?>(null) { _, _, info -> + endpoint.sendEvent(Event.AppVersionInfo(info)) + } + private set + + var currentVersion by observable<String?>(null) { _, _, version -> + endpoint.sendEvent(Event.CurrentVersion(version)) + } + private set + + init { + daemon.registerListener(this) { newDaemon -> + newDaemon?.let { daemon -> + initializeCurrentVersion(daemon) + registerVersionInfoListener(daemon) + fetchInitialVersionInfo(daemon) + } + } + } + + fun onDestroy() { + daemon.unregisterListener(this) + } + + private fun initializeCurrentVersion(daemon: MullvadDaemon) { + if (currentVersion == null) { + currentVersion = daemon.getCurrentVersion() + } + } + + private fun registerVersionInfoListener(daemon: MullvadDaemon) { + daemon.onAppVersionInfoChange = { newAppVersionInfo -> + synchronized(this@AppVersionInfoCache) { + appVersionInfo = newAppVersionInfo + } + } + } + + private fun fetchInitialVersionInfo(daemon: MullvadDaemon) { + synchronized(this@AppVersionInfoCache) { + if (appVersionInfo == null) { + appVersionInfo = daemon.getVersionInfo() + } + } + } +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt index 0f583d1fc9..4a753bc01d 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt @@ -40,6 +40,7 @@ class ServiceEndpoint( val settingsListener = SettingsListener(this) val accountCache = AccountCache(this) + val appVersionInfoCache = AppVersionInfoCache(this) val customDns = CustomDns(this) val keyStatusListener = KeyStatusListener(this) val locationInfoCache = LocationInfoCache(this) @@ -56,6 +57,7 @@ class ServiceEndpoint( registrationQueue.close() accountCache.onDestroy() + appVersionInfoCache.onDestroy() connectionProxy.onDestroy() customDns.onDestroy() keyStatusListener.onDestroy() @@ -109,6 +111,8 @@ class ServiceEndpoint( Event.NewLocation(locationInfoCache.location), Event.WireGuardKeyStatus(keyStatusListener.keyStatus), Event.SplitTunnelingUpdate(splitTunneling.onChange.latestEvent), + Event.CurrentVersion(appVersionInfoCache.currentVersion), + Event.AppVersionInfo(appVersionInfoCache.appVersionInfo), Event.ListenerReady ) diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt index 43f46a7101..6569c155d2 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt @@ -55,7 +55,7 @@ open class MainActivity : FragmentActivity() { serviceConnection?.onDestroy() val newConnection = service?.let { safeService -> - ServiceConnection(safeService, this@MainActivity) + ServiceConnection(safeService) } serviceConnection = newConnection diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt index 946e876615..b1a9493e28 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt @@ -5,10 +5,10 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache import net.mullvad.mullvadvpn.dataproxy.RelayListListener import net.mullvad.mullvadvpn.service.MullvadDaemon import net.mullvad.mullvadvpn.ui.serviceconnection.AccountCache +import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoCache import net.mullvad.mullvadvpn.ui.serviceconnection.ConnectionProxy import net.mullvad.mullvadvpn.ui.serviceconnection.CustomDns import net.mullvad.mullvadvpn.ui.serviceconnection.KeyStatusListener diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt index 585ff11c2d..7204c1084c 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt @@ -9,8 +9,8 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.flow.collect import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache import net.mullvad.mullvadvpn.ui.serviceconnection.AccountCache +import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoCache import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnection import net.mullvad.mullvadvpn.ui.widget.AccountCell import net.mullvad.mullvadvpn.ui.widget.AppVersionCell diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt index 942a48d792..8a8104290f 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt @@ -2,7 +2,7 @@ package net.mullvad.mullvadvpn.ui.notification import android.content.Context import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache +import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoCache class VersionInfoNotification( context: Context, diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt new file mode 100644 index 0000000000..c02ae54836 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt @@ -0,0 +1,61 @@ +package net.mullvad.mullvadvpn.ui.serviceconnection + +import kotlin.properties.Delegates.observable +import net.mullvad.mullvadvpn.ipc.DispatchingHandler +import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.model.AppVersionInfo + +class AppVersionInfoCache( + eventDispatcher: DispatchingHandler<Event>, + val settingsListener: SettingsListener +) { + private var appVersionInfo by observable<AppVersionInfo?>(null) { _, _, _ -> + onUpdate?.invoke() + } + + val isSupported + get() = appVersionInfo?.supported ?: true + + val isOutdated + get() = appVersionInfo?.suggestedUpgrade != null + + val upgradeVersion + get() = appVersionInfo?.suggestedUpgrade + + var onUpdate by observable<(() -> Unit)?>(null) { _, _, callback -> + callback?.invoke() + } + + var showBetaReleases by observable(false) { _, wasShowing, shouldShow -> + if (shouldShow != wasShowing) { + onUpdate?.invoke() + } + } + private set + + var version: String? = null + private set + + init { + eventDispatcher.apply { + registerHandler(Event.CurrentVersion::class) { event -> + version = event.version + } + + registerHandler(Event.AppVersionInfo::class) { event -> + appVersionInfo = event.versionInfo + } + } + + settingsListener.settingsNotifier.subscribe(this) { maybeSettings -> + maybeSettings?.let { settings -> + showBetaReleases = settings.showBetaReleases + } + } + } + + fun onDestroy() { + settingsListener.settingsNotifier.unsubscribe(this) + onUpdate = null + } +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt index 200853cd38..8cd894d335 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt @@ -4,14 +4,12 @@ import android.os.Looper import android.os.Messenger import android.os.RemoteException import android.util.Log -import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache import net.mullvad.mullvadvpn.dataproxy.RelayListListener import net.mullvad.mullvadvpn.di.SERVICE_CONNECTION_SCOPE import net.mullvad.mullvadvpn.ipc.DispatchingHandler import net.mullvad.mullvadvpn.ipc.Event import net.mullvad.mullvadvpn.ipc.Request import net.mullvad.mullvadvpn.service.ServiceInstance -import net.mullvad.mullvadvpn.ui.MainActivity import org.koin.core.component.KoinApiExtension import org.koin.core.parameter.parametersOf import org.koin.core.qualifier.named @@ -23,8 +21,7 @@ import org.koin.core.scope.get // The properties of this class can be used to send events to the service, to listen for events from // the service and to get values received from events. @OptIn(KoinApiExtension::class) -class ServiceConnection(private val service: ServiceInstance, mainActivity: MainActivity) : - KoinScopeComponent { +class ServiceConnection(private val service: ServiceInstance) : KoinScopeComponent { override val scope = getKoin().createScope( SERVICE_CONNECTION_SCOPE, named(SERVICE_CONNECTION_SCOPE), this @@ -45,12 +42,11 @@ class ServiceConnection(private val service: ServiceInstance, mainActivity: Main ) val vpnPermission = VpnPermission(service.messenger) - val appVersionInfoCache = AppVersionInfoCache(mainActivity, daemon, settingsListener) + val appVersionInfoCache = AppVersionInfoCache(dispatcher, settingsListener) val customDns = CustomDns(service.messenger, settingsListener) var relayListListener = RelayListListener(daemon, settingsListener) init { - appVersionInfoCache.onCreate() registerListener() } |
