diff options
| author | Albin <albin@mullvad.net> | 2022-04-27 13:36:37 +0200 |
|---|---|---|
| committer | Albin <albin@mullvad.net> | 2022-05-17 15:06:04 +0200 |
| commit | 35b5edc32e5d8949498d4fbb19c49a550487f5ab (patch) | |
| tree | d4d76b9bc7283c4e5ef72e2dd3141342ef525506 | |
| parent | 26cb06ead245f9bab564be3960973870970f10d7 (diff) | |
| download | mullvadvpn-35b5edc32e5d8949498d4fbb19c49a550487f5ab.tar.xz mullvadvpn-35b5edc32e5d8949498d4fbb19c49a550487f5ab.zip | |
Refactor Android account history
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 { |
