summaryrefslogtreecommitdiffhomepage
path: root/android/app/src
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2022-04-27 13:36:37 +0200
committerAlbin <albin@mullvad.net>2022-05-17 15:06:04 +0200
commit35b5edc32e5d8949498d4fbb19c49a550487f5ab (patch)
treed4d76b9bc7283c4e5ef72e2dd3141342ef525506 /android/app/src
parent26cb06ead245f9bab564be3960973870970f10d7 (diff)
downloadmullvadvpn-35b5edc32e5d8949498d4fbb19c49a550487f5ab.tar.xz
mullvadvpn-35b5edc32e5d8949498d4fbb19c49a550487f5ab.zip
Refactor Android account history
Diffstat (limited to 'android/app/src')
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt14
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt31
7 files changed, 49 insertions, 26 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
index c09ea43164..7338c6bd3a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
@@ -4,6 +4,7 @@ import android.os.Message as RawMessage
import android.os.Messenger
import kotlinx.parcelize.Parcelize
import net.mullvad.mullvadvpn.model.AccountCreationResult
+import net.mullvad.mullvadvpn.model.AccountHistory
import net.mullvad.mullvadvpn.model.AppVersionInfo as AppVersionInfoData
import net.mullvad.mullvadvpn.model.DeviceState
import net.mullvad.mullvadvpn.model.GeoIpLocation
@@ -23,7 +24,7 @@ sealed class Event : Message.EventMessage() {
data class AccountCreationEvent(val result: AccountCreationResult) : Event()
@Parcelize
- data class AccountHistory(val history: String?) : Event()
+ data class AccountHistoryEvent(val history: AccountHistory) : Event()
@Parcelize
data class AppVersionInfo(val versionInfo: AppVersionInfoData?) : Event()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt
new file mode 100644
index 0000000000..114463aaaa
--- /dev/null
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt
@@ -0,0 +1,12 @@
+package net.mullvad.mullvadvpn.model
+
+import android.os.Parcelable
+import kotlinx.android.parcel.Parcelize
+
+sealed class AccountHistory : Parcelable {
+ @Parcelize
+ data class Available(val accountToken: String) : AccountHistory()
+
+ @Parcelize
+ object Missing : AccountHistory()
+}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
index 8ce533ca3c..018ded6fe6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
@@ -10,6 +10,7 @@ import kotlinx.coroutines.delay
import net.mullvad.mullvadvpn.ipc.Event
import net.mullvad.mullvadvpn.ipc.Request
import net.mullvad.mullvadvpn.model.AccountCreationResult
+import net.mullvad.mullvadvpn.model.AccountHistory
import net.mullvad.mullvadvpn.model.GetAccountDataResult
import net.mullvad.mullvadvpn.model.LoginResult
import net.mullvad.mullvadvpn.model.LoginStatus
@@ -44,7 +45,7 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
val onAccountNumberChange = EventNotifier<String?>(null)
val onAccountExpiryChange = EventNotifier<DateTime?>(null)
- val onAccountHistoryChange = EventNotifier<String?>(null)
+ val onAccountHistoryChange = EventNotifier<AccountHistory>(AccountHistory.Missing)
val onLoginStatusChange = EventNotifier<LoginStatus?>(null)
var newlyCreatedAccount = false
@@ -68,7 +69,7 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
}
onAccountHistoryChange.subscribe(this) { history ->
- endpoint.sendEvent(Event.AccountHistory(history))
+ endpoint.sendEvent(Event.AccountHistoryEvent(history))
}
onLoginStatusChange.subscribe(this) { status ->
@@ -224,7 +225,11 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
private fun fetchAccountHistory() {
jobTracker.newBackgroundJob("fetchHistory") {
daemon.await().getAccountHistory().let { history ->
- accountHistory = history
+ accountHistory = if (history != null) {
+ AccountHistory.Available(history)
+ } else {
+ AccountHistory.Missing
+ }
}
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
index f53454b401..7aed21ba3a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
@@ -135,7 +135,7 @@ class ServiceEndpoint(
val initialEvents = mutableListOf(
Event.TunnelStateChange(connectionProxy.state),
Event.LoginStatus(accountCache.onLoginStatusChange.latestEvent),
- Event.AccountHistory(accountCache.onAccountHistoryChange.latestEvent),
+ Event.AccountHistoryEvent(accountCache.onAccountHistoryChange.latestEvent),
Event.SettingsUpdate(settingsListener.settings),
Event.NewLocation(locationInfoCache.location),
Event.WireGuardKeyStatus(keyStatusListener.keyStatus),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
index 91fec93d87..056bff9227 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
@@ -16,6 +16,7 @@ import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.R
+import net.mullvad.mullvadvpn.model.AccountHistory
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnection
import net.mullvad.mullvadvpn.ui.widget.AccountLogin
import net.mullvad.mullvadvpn.ui.widget.HeaderBar
@@ -120,6 +121,7 @@ class LoginFragment :
launch {
loginViewModel.accountHistory.collect { history ->
accountLogin.accountHistory = history
+ .let { it as? AccountHistory.Available }?.accountToken
}
}
launch {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt
index 829c8ffeb9..6dec53cb57 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt
@@ -8,16 +8,15 @@ import net.mullvad.mullvadvpn.ipc.Event
import net.mullvad.mullvadvpn.ipc.EventDispatcher
import net.mullvad.mullvadvpn.ipc.Request
import net.mullvad.mullvadvpn.model.AccountCreationResult
+import net.mullvad.mullvadvpn.model.AccountHistory
import net.mullvad.mullvadvpn.model.LoginStatus
import net.mullvad.talpid.util.EventNotifier
import org.joda.time.DateTime
class AccountCache(private val connection: Messenger, eventDispatcher: EventDispatcher) {
val onAccountExpiryChange = EventNotifier<DateTime?>(null)
- val onAccountHistoryChange = EventNotifier<String?>(null)
val onLoginStatusChange = EventNotifier<LoginStatus?>(null)
- private var accountHistory by onAccountHistoryChange.notifiable()
private var loginStatus by onLoginStatusChange.notifiable()
private val _accountCreationEvents = MutableSharedFlow<AccountCreationResult>(
@@ -26,6 +25,12 @@ class AccountCache(private val connection: Messenger, eventDispatcher: EventDisp
)
val accountCreationEvents = _accountCreationEvents.asSharedFlow()
+ private val _accountHistoryEvents = MutableSharedFlow<AccountHistory>(
+ extraBufferCapacity = 1,
+ onBufferOverflow = BufferOverflow.DROP_OLDEST
+ )
+ val accountHistoryEvents = _accountHistoryEvents.asSharedFlow()
+
private val _loginEvents = MutableSharedFlow<Event.LoginEvent>(
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
@@ -34,8 +39,8 @@ class AccountCache(private val connection: Messenger, eventDispatcher: EventDisp
init {
eventDispatcher.apply {
- registerHandler(Event.AccountHistory::class) { event ->
- accountHistory = event.history
+ registerHandler(Event.AccountHistoryEvent::class) { event ->
+ _accountHistoryEvents.tryEmit(event.history)
}
registerHandler(Event.LoginStatus::class) { event ->
@@ -81,7 +86,6 @@ class AccountCache(private val connection: Messenger, eventDispatcher: EventDisp
fun onDestroy() {
onAccountExpiryChange.unsubscribeAll()
- onAccountHistoryChange.unsubscribeAll()
onLoginStatusChange.unsubscribeAll()
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt
index 10305ea9d2..d064b8a91d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt
@@ -8,9 +8,11 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.model.AccountCreationResult
+import net.mullvad.mullvadvpn.model.AccountHistory
import net.mullvad.mullvadvpn.model.LoginResult
import net.mullvad.mullvadvpn.ui.serviceconnection.AccountCache
@@ -18,9 +20,10 @@ class LoginViewModel(
application: Application
) : AndroidViewModel(application) {
private val _uiState = MutableStateFlow<LoginUiState>(LoginUiState.Default)
- private val _accountHistory = MutableStateFlow<String?>(null)
val uiState: StateFlow<LoginUiState> = _uiState
- val accountHistory: StateFlow<String?> = _accountHistory
+
+ private val _accountHistory = MutableStateFlow<AccountHistory>(AccountHistory.Missing)
+ val accountHistory: StateFlow<AccountHistory> = _accountHistory
private var accountCache: AccountCache? = null
@@ -42,8 +45,15 @@ class LoginViewModel(
// Ensures the view model has an up-to-date instance of account cache. This is an intermediate
// solution due to limitations in the current app architecture.
fun updateAccountCacheInstance(newAccountCache: AccountCache?) {
- accountCache?.unsubscribe()
- accountCache = newAccountCache?.apply { subscribe() }
+ accountCache?.onLoginStatusChange?.unsubscribe(this)
+
+ accountCache = newAccountCache?.apply {
+ viewModelScope.launch {
+ accountHistoryEvents.collect {
+ _accountHistory.value = it
+ }
+ }
+ }
}
fun clearAccountHistory() {
@@ -76,13 +86,7 @@ class LoginViewModel(
@RestrictTo(RestrictTo.Scope.TESTS)
public override fun onCleared() {
- accountCache?.unsubscribe()
- }
-
- private fun AccountCache.subscribe() {
- onAccountHistoryChange.subscribe(this) { history ->
- _accountHistory.value = history
- }
+ accountCache?.onLoginStatusChange?.unsubscribe(this)
}
private fun AccountCreationResult.mapToUiState(): LoginUiState {
@@ -101,11 +105,6 @@ class LoginViewModel(
}
}
- private fun AccountCache.unsubscribe() {
- onAccountHistoryChange.unsubscribe(this)
- onLoginStatusChange.unsubscribe(this)
- }
-
class Factory(val application: Application) :
ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {