summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2023-10-04 13:46:23 +0200
committerAlbin <albin@mullvad.net>2023-10-16 17:09:22 +0200
commit989f57e29d1f694d8bfda186d52697aaf85dcae4 (patch)
tree2a33ca74411ee5208619d763dcde2b21b49988c2
parent05a0a17332fe09ccea78eefcb323773732160ae0 (diff)
downloadmullvadvpn-989f57e29d1f694d8bfda186d52697aaf85dcae4.tar.xz
mullvadvpn-989f57e29d1f694d8bfda186d52697aaf85dcae4.zip
Refactor account repo and data source
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt56
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt58
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt1
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt4
7 files changed, 35 insertions, 93 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
index 7134f7b7d2..1d4421b063 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
@@ -15,6 +15,7 @@ import net.mullvad.mullvadvpn.repository.ChangelogRepository
import net.mullvad.mullvadvpn.repository.DeviceRepository
import net.mullvad.mullvadvpn.repository.PrivacyDisclaimerRepository
import net.mullvad.mullvadvpn.repository.SettingsRepository
+import net.mullvad.mullvadvpn.ui.serviceconnection.MessageHandler
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.ui.serviceconnection.SplitTunneling
import net.mullvad.mullvadvpn.util.ChangelogDataProvider
@@ -40,6 +41,7 @@ import org.koin.android.ext.koin.androidApplication
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.qualifier.named
+import org.koin.dsl.bind
import org.koin.dsl.module
import org.koin.dsl.onClose
@@ -59,7 +61,7 @@ val uiModule = module {
SplitTunneling(messenger, dispatcher)
}
- single { ServiceConnectionManager(androidContext()) }
+ single { ServiceConnectionManager(androidContext()) } bind MessageHandler::class
single { InetAddressValidator.getInstance() }
single { androidContext().resources }
single { androidContext().assets }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt
index de72fa8d93..0bf8b1b8ec 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt
@@ -10,43 +10,41 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
import net.mullvad.mullvadvpn.lib.ipc.Event
+import net.mullvad.mullvadvpn.lib.ipc.Request
import net.mullvad.mullvadvpn.model.AccountCreationResult
import net.mullvad.mullvadvpn.model.AccountExpiry
import net.mullvad.mullvadvpn.model.AccountHistory
import net.mullvad.mullvadvpn.model.LoginResult
-import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
-import net.mullvad.mullvadvpn.ui.serviceconnection.accountDataSource
-import net.mullvad.mullvadvpn.util.flatMapReadyConnectionOrDefault
+import net.mullvad.mullvadvpn.ui.serviceconnection.MessageHandler
+import net.mullvad.mullvadvpn.ui.serviceconnection.events
class AccountRepository(
- private val serviceConnectionManager: ServiceConnectionManager,
- val dispatcher: CoroutineDispatcher = Dispatchers.IO
+ private val messageHandler: MessageHandler,
+ private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) {
private val _cachedCreatedAccount = MutableStateFlow<String?>(null)
val cachedCreatedAccount = _cachedCreatedAccount.asStateFlow()
private val accountCreationEvents: SharedFlow<AccountCreationResult> =
- serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- state.container.accountDataSource.accountCreationResult
- }
+ messageHandler
+ .events<Event.AccountCreationEvent>()
+ .map { it.result }
.onEach {
_cachedCreatedAccount.value = (it as? AccountCreationResult.Success)?.accountToken
}
.shareIn(CoroutineScope(dispatcher), SharingStarted.WhileSubscribed())
val accountExpiryState: StateFlow<AccountExpiry> =
- serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- state.container.accountDataSource.accountExpiry
- }
+ messageHandler
+ .events<Event.AccountExpiryEvent>()
+ .map { it.expiry }
.stateIn(
CoroutineScope(dispatcher),
SharingStarted.WhileSubscribed(),
@@ -54,10 +52,9 @@ class AccountRepository(
)
val accountHistory: StateFlow<AccountHistory> =
- serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- state.container.accountDataSource.accountHistory
- }
+ messageHandler
+ .events<Event.AccountHistoryEvent>()
+ .map { it.history }
.onStart { fetchAccountHistory() }
.stateIn(
CoroutineScope(dispatcher),
@@ -65,42 +62,41 @@ class AccountRepository(
AccountHistory.Missing
)
- private val loginEvents: SharedFlow<Event.LoginEvent> =
- serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- state.container.accountDataSource.loginEvents
- }
+ private val loginEvents: SharedFlow<LoginResult> =
+ messageHandler
+ .events<Event.LoginEvent>()
+ .map { it.result }
.shareIn(CoroutineScope(dispatcher), SharingStarted.WhileSubscribed())
suspend fun createAccount(): AccountCreationResult =
withContext(dispatcher) {
val deferred = async { accountCreationEvents.first() }
- serviceConnectionManager.accountDataSource()?.createAccount()
+ messageHandler.trySendRequest(Request.CreateAccount)
deferred.await()
}
suspend fun login(accountToken: String): LoginResult =
withContext(Dispatchers.IO) {
- val deferred = async { loginEvents.first().result }
- serviceConnectionManager.accountDataSource()?.login(accountToken)
+ val deferred = async { loginEvents.first() }
+ messageHandler.trySendRequest(Request.Login(accountToken))
deferred.await()
}
fun logout() {
clearCreatedAccountCache()
- serviceConnectionManager.accountDataSource()?.logout()
+ messageHandler.trySendRequest(Request.Logout)
}
fun fetchAccountExpiry() {
- serviceConnectionManager.accountDataSource()?.fetchAccountExpiry()
+ messageHandler.trySendRequest(Request.FetchAccountExpiry)
}
fun fetchAccountHistory() {
- serviceConnectionManager.accountDataSource()?.fetchAccountHistory()
+ messageHandler.trySendRequest(Request.FetchAccountHistory)
}
fun clearAccountHistory() {
- serviceConnectionManager.accountDataSource()?.clearAccountHistory()
+ messageHandler.trySendRequest(Request.ClearAccountHistory)
}
private fun clearCreatedAccountCache() {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
index 3d30d28845..e8c8cefb81 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
@@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onSubscription
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
import net.mullvad.mullvadvpn.BuildConfig
@@ -312,6 +313,7 @@ open class MainActivity : FragmentActivity() {
private suspend fun isExpired(timeoutMillis: Long): Boolean {
return withTimeoutOrNull(timeoutMillis) {
accountRepository.accountExpiryState
+ .onSubscription { accountRepository.fetchAccountExpiry() }
.filter { it is AccountExpiry.Available }
.map { it.date()?.isBeforeNow }
.first()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt
deleted file mode 100644
index d383035102..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-package net.mullvad.mullvadvpn.ui.serviceconnection
-
-import android.os.Messenger
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.callbackFlow
-import net.mullvad.mullvadvpn.lib.ipc.Event
-import net.mullvad.mullvadvpn.lib.ipc.EventDispatcher
-import net.mullvad.mullvadvpn.lib.ipc.Request
-
-class ServiceConnectionAccountDataSource(
- private val connection: Messenger,
- private val dispatcher: EventDispatcher
-) {
- val accountCreationResult = callbackFlow {
- val handler: (Event.AccountCreationEvent) -> Unit = { event -> trySend(event.result) }
- dispatcher.registerHandler(Event.AccountCreationEvent::class, handler)
- awaitClose {
- // The current dispatcher doesn't support unregistration of handlers.
- }
- }
-
- val accountExpiry = callbackFlow {
- val handler: (Event.AccountExpiryEvent) -> Unit = { event -> trySend(event.expiry) }
- dispatcher.registerHandler(Event.AccountExpiryEvent::class, handler)
- connection.send(Request.FetchAccountExpiry.message)
- awaitClose {
- // The current dispatcher doesn't support unregistration of handlers.
- }
- }
-
- val accountHistory = callbackFlow {
- val handler: (Event.AccountHistoryEvent) -> Unit = { event -> trySend(event.history) }
- dispatcher.registerHandler(Event.AccountHistoryEvent::class, handler)
- awaitClose {
- // The current dispatcher doesn't support unregistration of handlers.
- }
- }
-
- val loginEvents = callbackFlow {
- val handler: (Event.LoginEvent) -> Unit = { event -> trySend(event) }
- dispatcher.registerHandler(Event.LoginEvent::class, handler)
- awaitClose {
- // The current dispatcher doesn't support unregistration of handlers.
- }
- }
-
- fun createAccount() = connection.send(Request.CreateAccount.message)
-
- fun login(accountToken: String) = connection.send(Request.Login(accountToken).message)
-
- fun logout() = connection.send(Request.Logout.message)
-
- fun fetchAccountExpiry() = connection.send(Request.FetchAccountExpiry.message)
-
- fun fetchAccountHistory() = connection.send(Request.FetchAccountHistory.message)
-
- fun clearAccountHistory() = connection.send(Request.ClearAccountHistory.message)
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt
index 93dcd75359..7d34f2a96f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt
@@ -25,7 +25,6 @@ class ServiceConnectionContainer(
val events = dispatcher.parsedMessages.filterIsInstance<Event>()
- val accountDataSource = ServiceConnectionAccountDataSource(connection, dispatcher)
val authTokenCache = AuthTokenCache(connection, dispatcher)
val connectionProxy = ConnectionProxy(connection, dispatcher)
val deviceDataSource = ServiceConnectionDeviceDataSource(connection, dispatcher)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt
index f7be833792..c4b3d100bd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt
@@ -1,8 +1,5 @@
package net.mullvad.mullvadvpn.ui.serviceconnection
-fun ServiceConnectionManager.accountDataSource() =
- this.connectionState.value.readyContainer()?.accountDataSource
-
fun ServiceConnectionManager.appVersionInfoCache() =
this.connectionState.value.readyContainer()?.appVersionInfoCache
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt
index a03de806b4..fb3e3d6393 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt
@@ -41,6 +41,10 @@ class AccountViewModel(
@Suppress("konsist.ensure public properties use permitted names")
val enterTransitionEndAction = _enterTransitionEndAction.asSharedFlow()
+ init {
+ accountRepository.fetchAccountExpiry()
+ }
+
fun onManageAccountClick() {
viewModelScope.launch {
_uiSideEffect.tryEmit(