From 58a91c15aa8cb00d7b5feee084c6610d25f706aa Mon Sep 17 00:00:00 2001 From: David Perez Date: Mon, 29 Jul 2024 15:10:38 -0500 Subject: [PATCH] PM-10140: Update the VaultSdkSource and VaultDiskSource to use parallelization when processing heavier loads (#3649) --- .../datasource/disk/VaultDiskSourceImpl.kt | 26 +++++++++++++------ .../datasource/sdk/VaultSdkSourceImpl.kt | 13 ++++++++-- .../vault/datasource/sdk/di/VaultSdkModule.kt | 3 +++ .../datasource/sdk/VaultSdkSourceTest.kt | 3 +++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceImpl.kt index 40af90b01b..60c42afbd4 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceImpl.kt @@ -66,10 +66,16 @@ class VaultDiskSourceImpl( ciphersDao .getAllCiphers(userId = userId) .map { entities -> - entities.map { entity -> - withContext(dispatcherManager.default) { - json.decodeFromString(entity.cipherJson) - } + withContext(context = dispatcherManager.default) { + entities + .map { entity -> + async { + json.decodeFromString( + string = entity.cipherJson, + ) + } + } + .awaitAll() } }, ) @@ -180,10 +186,14 @@ class VaultDiskSourceImpl( sendsDao .getAllSends(userId = userId) .map { entities -> - entities.map { entity -> - withContext(dispatcherManager.default) { - json.decodeFromString(entity.sendJson) - } + withContext(context = dispatcherManager.default) { + entities + .map { entity -> + async { + json.decodeFromString(entity.sendJson) + } + } + .awaitAll() } }, ) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt index cc228938ce..d7a856768b 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt @@ -29,15 +29,19 @@ import com.bitwarden.vault.PasswordHistory import com.bitwarden.vault.PasswordHistoryView import com.bitwarden.vault.TotpResponse import com.x8bit.bitwarden.data.platform.manager.SdkClientManager +import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager import com.x8bit.bitwarden.data.vault.datasource.sdk.model.AuthenticateFido2CredentialRequest import com.x8bit.bitwarden.data.vault.datasource.sdk.model.Fido2CredentialAuthenticationUserInterfaceImpl import com.x8bit.bitwarden.data.vault.datasource.sdk.model.Fido2CredentialRegistrationUserInterfaceImpl import com.x8bit.bitwarden.data.vault.datasource.sdk.model.Fido2CredentialSearchUserInterfaceImpl import com.x8bit.bitwarden.data.vault.datasource.sdk.model.InitializeCryptoResult import com.x8bit.bitwarden.data.vault.datasource.sdk.model.RegisterFido2CredentialRequest +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.first +import kotlinx.coroutines.withContext import java.io.File /** @@ -47,6 +51,7 @@ import java.io.File @Suppress("TooManyFunctions") class VaultSdkSourceImpl( private val sdkClientManager: SdkClientManager, + private val dispatcherManager: DispatcherManager, ) : VaultSdkSource { override fun clearCrypto(userId: String) { sdkClientManager.destroyClient(userId = userId) @@ -247,7 +252,9 @@ class VaultSdkSourceImpl( ): Result> = runCatching { val ciphers = getClient(userId = userId).vault().ciphers() - cipherList.map { ciphers.decrypt(cipher = it) } + withContext(context = dispatcherManager.default) { + cipherList.map { async { ciphers.decrypt(cipher = it) } }.awaitAll() + } } override suspend fun decryptCollection( @@ -288,7 +295,9 @@ class VaultSdkSourceImpl( ): Result> = runCatching { val sends = getClient(userId = userId).sends() - sendList.map { sends.decrypt(send = it) } + withContext(dispatcherManager.default) { + sendList.map { async { sends.decrypt(send = it) } }.awaitAll() + } } override suspend fun encryptFolder( diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/di/VaultSdkModule.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/di/VaultSdkModule.kt index 28b9e50657..7e9bcfee6e 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/di/VaultSdkModule.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/di/VaultSdkModule.kt @@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.vault.datasource.sdk.di import com.bitwarden.sdk.Fido2CredentialStore import com.x8bit.bitwarden.data.auth.repository.AuthRepository import com.x8bit.bitwarden.data.platform.manager.SdkClientManager +import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager import com.x8bit.bitwarden.data.vault.datasource.sdk.BitwardenFeatureFlagManager import com.x8bit.bitwarden.data.vault.datasource.sdk.BitwardenFeatureFlagManagerImpl import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource @@ -26,9 +27,11 @@ object VaultSdkModule { @Singleton fun providesVaultSdkSource( sdkClientManager: SdkClientManager, + dispatcherManager: DispatcherManager, ): VaultSdkSource = VaultSdkSourceImpl( sdkClientManager = sdkClientManager, + dispatcherManager = dispatcherManager, ) @Provides diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt index 70ff269dbc..27ab5bce01 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt @@ -39,6 +39,7 @@ import com.bitwarden.vault.FolderView import com.bitwarden.vault.PasswordHistory import com.bitwarden.vault.PasswordHistoryView import com.bitwarden.vault.TotpResponse +import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager import com.x8bit.bitwarden.data.platform.manager.SdkClientManager import com.x8bit.bitwarden.data.platform.util.asFailure import com.x8bit.bitwarden.data.platform.util.asSuccess @@ -100,8 +101,10 @@ class VaultSdkSourceTest { every { destroyClient(any()) } just runs } private val mockFido2CredentialStore: Fido2CredentialStore = mockk() + private val fakeDispatcherManager = FakeDispatcherManager() private val vaultSdkSource: VaultSdkSource = VaultSdkSourceImpl( sdkClientManager = sdkClientManager, + dispatcherManager = fakeDispatcherManager, ) @Test