PM-27755: Create a common LocalQrCodeAnalyzer for both apps (#6115)

This commit is contained in:
David Perez 2025-11-03 14:13:39 -06:00 committed by GitHub
parent dc79176274
commit 1f24ca7de1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 34 additions and 8 deletions

View File

@ -23,6 +23,9 @@ import com.bitwarden.cxf.ui.composition.LocalCredentialExchangeRequestValidator
import com.bitwarden.cxf.validator.CredentialExchangeRequestValidator import com.bitwarden.cxf.validator.CredentialExchangeRequestValidator
import com.bitwarden.cxf.validator.dsl.credentialExchangeRequestValidator import com.bitwarden.cxf.validator.dsl.credentialExchangeRequestValidator
import com.bitwarden.ui.platform.composition.LocalIntentManager import com.bitwarden.ui.platform.composition.LocalIntentManager
import com.bitwarden.ui.platform.composition.LocalQrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzerImpl
import com.bitwarden.ui.platform.manager.IntentManager import com.bitwarden.ui.platform.manager.IntentManager
import com.x8bit.bitwarden.R import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.platform.manager.util.AppResumeStateManager import com.x8bit.bitwarden.data.platform.manager.util.AppResumeStateManager
@ -80,6 +83,7 @@ fun LocalManagerProvider(
credentialExchangeRequestValidator: CredentialExchangeRequestValidator = credentialExchangeRequestValidator: CredentialExchangeRequestValidator =
credentialExchangeRequestValidator(activity = activity), credentialExchangeRequestValidator(activity = activity),
authTabLaunchers: AuthTabLaunchers, authTabLaunchers: AuthTabLaunchers,
qrCodeAnalyzer: QrCodeAnalyzer = QrCodeAnalyzerImpl(),
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
CompositionLocalProvider( CompositionLocalProvider(
@ -98,6 +102,7 @@ fun LocalManagerProvider(
LocalCredentialExchangeCompletionManager provides credentialExchangeCompletionManager, LocalCredentialExchangeCompletionManager provides credentialExchangeCompletionManager,
LocalCredentialExchangeRequestValidator provides credentialExchangeRequestValidator, LocalCredentialExchangeRequestValidator provides credentialExchangeRequestValidator,
LocalAuthTabLaunchers provides authTabLaunchers, LocalAuthTabLaunchers provides authTabLaunchers,
LocalQrCodeAnalyzer provides qrCodeAnalyzer,
content = content, content = content,
) )
} }

View File

@ -35,8 +35,8 @@ import com.bitwarden.ui.platform.components.camera.CameraPreview
import com.bitwarden.ui.platform.components.camera.QrCodeSquare import com.bitwarden.ui.platform.components.camera.QrCodeSquare
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.bitwarden.ui.platform.components.util.rememberVectorPainter import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.composition.LocalQrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzerImpl
import com.bitwarden.ui.platform.model.WindowSize import com.bitwarden.ui.platform.model.WindowSize
import com.bitwarden.ui.platform.resource.BitwardenDrawable import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.platform.resource.BitwardenString
@ -55,7 +55,7 @@ fun QrCodeScanScreen(
onNavigateBack: () -> Unit, onNavigateBack: () -> Unit,
onNavigateToManualCodeEntryScreen: () -> Unit, onNavigateToManualCodeEntryScreen: () -> Unit,
viewModel: QrCodeScanViewModel = hiltViewModel(), viewModel: QrCodeScanViewModel = hiltViewModel(),
qrCodeAnalyzer: QrCodeAnalyzer = QrCodeAnalyzerImpl(), qrCodeAnalyzer: QrCodeAnalyzer = LocalQrCodeAnalyzer.current,
) { ) {
qrCodeAnalyzer.onQrCodeScanned = remember(viewModel) { qrCodeAnalyzer.onQrCodeScanned = remember(viewModel) {
{ viewModel.trySendAction(QrCodeScanAction.QrCodeScanReceive(it)) } { viewModel.trySendAction(QrCodeScanAction.QrCodeScanReceive(it)) }

View File

@ -5,6 +5,7 @@ import com.bitwarden.cxf.importer.CredentialExchangeImporter
import com.bitwarden.cxf.manager.CredentialExchangeCompletionManager import com.bitwarden.cxf.manager.CredentialExchangeCompletionManager
import com.bitwarden.cxf.validator.CredentialExchangeRequestValidator import com.bitwarden.cxf.validator.CredentialExchangeRequestValidator
import com.bitwarden.ui.platform.base.BaseComposeTest import com.bitwarden.ui.platform.base.BaseComposeTest
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer
import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.bitwarden.ui.platform.manager.IntentManager import com.bitwarden.ui.platform.manager.IntentManager
import com.bitwarden.ui.platform.theme.BitwardenTheme import com.bitwarden.ui.platform.theme.BitwardenTheme
@ -48,6 +49,7 @@ abstract class BitwardenComposeTest : BaseComposeTest() {
credentialExchangeImporter: CredentialExchangeImporter = mockk(), credentialExchangeImporter: CredentialExchangeImporter = mockk(),
credentialExchangeCompletionManager: CredentialExchangeCompletionManager = mockk(), credentialExchangeCompletionManager: CredentialExchangeCompletionManager = mockk(),
credentialExchangeRequestValidator: CredentialExchangeRequestValidator = mockk(), credentialExchangeRequestValidator: CredentialExchangeRequestValidator = mockk(),
qrCodeAnalyzer: QrCodeAnalyzer = mockk(),
test: @Composable () -> Unit, test: @Composable () -> Unit,
) { ) {
setTestContent { setTestContent {
@ -67,6 +69,7 @@ abstract class BitwardenComposeTest : BaseComposeTest() {
credentialExchangeImporter = credentialExchangeImporter, credentialExchangeImporter = credentialExchangeImporter,
credentialExchangeCompletionManager = credentialExchangeCompletionManager, credentialExchangeCompletionManager = credentialExchangeCompletionManager,
credentialExchangeRequestValidator = credentialExchangeRequestValidator, credentialExchangeRequestValidator = credentialExchangeRequestValidator,
qrCodeAnalyzer = qrCodeAnalyzer,
) { ) {
BitwardenTheme( BitwardenTheme(
theme = theme, theme = theme,

View File

@ -31,11 +31,12 @@ class QrCodeScanScreenTest : BitwardenComposeTest() {
@Before @Before
fun setup() { fun setup() {
setContent { setContent(
qrCodeAnalyzer = qrCodeAnalyzer,
) {
QrCodeScanScreen( QrCodeScanScreen(
onNavigateBack = { onNavigateBackCalled = true }, onNavigateBack = { onNavigateBackCalled = true },
viewModel = viewModel, viewModel = viewModel,
qrCodeAnalyzer = qrCodeAnalyzer,
onNavigateToManualCodeEntryScreen = { onNavigateToManualCodeEntryScreen = {
onNavigateToManualCodeEntryScreenCalled = true onNavigateToManualCodeEntryScreenCalled = true
}, },

View File

@ -40,8 +40,8 @@ import com.bitwarden.ui.platform.components.camera.CameraPreview
import com.bitwarden.ui.platform.components.camera.QrCodeSquare import com.bitwarden.ui.platform.components.camera.QrCodeSquare
import com.bitwarden.ui.platform.components.dialog.BitwardenBasicDialog import com.bitwarden.ui.platform.components.dialog.BitwardenBasicDialog
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.bitwarden.ui.platform.composition.LocalQrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzerImpl
import com.bitwarden.ui.platform.resource.BitwardenDrawable import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.platform.theme.BitwardenTheme import com.bitwarden.ui.platform.theme.BitwardenTheme
@ -57,7 +57,7 @@ import com.bitwarden.ui.platform.theme.color.darkBitwardenColorScheme
fun QrCodeScanScreen( fun QrCodeScanScreen(
onNavigateBack: () -> Unit, onNavigateBack: () -> Unit,
viewModel: QrCodeScanViewModel = hiltViewModel(), viewModel: QrCodeScanViewModel = hiltViewModel(),
qrCodeAnalyzer: QrCodeAnalyzer = QrCodeAnalyzerImpl(), qrCodeAnalyzer: QrCodeAnalyzer = LocalQrCodeAnalyzer.current,
onNavigateToManualCodeEntryScreen: () -> Unit, onNavigateToManualCodeEntryScreen: () -> Unit,
) { ) {
qrCodeAnalyzer.onQrCodeScanned = remember(viewModel) { qrCodeAnalyzer.onQrCodeScanned = remember(viewModel) {

View File

@ -19,6 +19,9 @@ import com.bitwarden.authenticator.ui.platform.manager.permissions.PermissionsMa
import com.bitwarden.authenticator.ui.platform.manager.permissions.PermissionsManagerImpl import com.bitwarden.authenticator.ui.platform.manager.permissions.PermissionsManagerImpl
import com.bitwarden.core.data.manager.BuildInfoManager import com.bitwarden.core.data.manager.BuildInfoManager
import com.bitwarden.ui.platform.composition.LocalIntentManager import com.bitwarden.ui.platform.composition.LocalIntentManager
import com.bitwarden.ui.platform.composition.LocalQrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzerImpl
import com.bitwarden.ui.platform.manager.IntentManager import com.bitwarden.ui.platform.manager.IntentManager
import java.time.Clock import java.time.Clock
@ -34,6 +37,7 @@ fun LocalManagerProvider(
intentManager: IntentManager = IntentManager.create(activity, clock, buildInfoManager), intentManager: IntentManager = IntentManager.create(activity, clock, buildInfoManager),
exitManager: ExitManager = ExitManagerImpl(activity), exitManager: ExitManager = ExitManagerImpl(activity),
biometricsManager: BiometricsManager = BiometricsManagerImpl(activity), biometricsManager: BiometricsManager = BiometricsManagerImpl(activity),
qrCodeAnalyzer: QrCodeAnalyzer = QrCodeAnalyzerImpl(),
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
CompositionLocalProvider( CompositionLocalProvider(
@ -41,6 +45,7 @@ fun LocalManagerProvider(
LocalIntentManager provides intentManager, LocalIntentManager provides intentManager,
LocalExitManager provides exitManager, LocalExitManager provides exitManager,
LocalBiometricsManager provides biometricsManager, LocalBiometricsManager provides biometricsManager,
LocalQrCodeAnalyzer provides qrCodeAnalyzer,
content = content, content = content,
) )
} }

View File

@ -37,10 +37,11 @@ class QrCodeScanScreenTest : AuthenticatorComposeTest() {
@Before @Before
fun setup() { fun setup() {
setContent { setContent(
qrCodeAnalyzer = qrCodeAnalyzer,
) {
QrCodeScanScreen( QrCodeScanScreen(
viewModel = viewModel, viewModel = viewModel,
qrCodeAnalyzer = qrCodeAnalyzer,
onNavigateBack = { onNavigateBackCalled = true }, onNavigateBack = { onNavigateBackCalled = true },
onNavigateToManualCodeEntryScreen = { onNavigateToManualCodeEntryScreen = {
onNavigateToManualCodeEntryScreenCalled = true onNavigateToManualCodeEntryScreenCalled = true

View File

@ -6,6 +6,7 @@ import com.bitwarden.authenticator.ui.platform.manager.biometrics.BiometricsMana
import com.bitwarden.authenticator.ui.platform.manager.exit.ExitManager import com.bitwarden.authenticator.ui.platform.manager.exit.ExitManager
import com.bitwarden.authenticator.ui.platform.manager.permissions.PermissionsManager import com.bitwarden.authenticator.ui.platform.manager.permissions.PermissionsManager
import com.bitwarden.ui.platform.base.BaseComposeTest import com.bitwarden.ui.platform.base.BaseComposeTest
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer
import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.bitwarden.ui.platform.manager.IntentManager import com.bitwarden.ui.platform.manager.IntentManager
import com.bitwarden.ui.platform.theme.BitwardenTheme import com.bitwarden.ui.platform.theme.BitwardenTheme
@ -28,6 +29,7 @@ abstract class AuthenticatorComposeTest : BaseComposeTest() {
intentManager: IntentManager = mockk(), intentManager: IntentManager = mockk(),
exitManager: ExitManager = mockk(), exitManager: ExitManager = mockk(),
biometricsManager: BiometricsManager = mockk(), biometricsManager: BiometricsManager = mockk(),
qrCodeAnalyzer: QrCodeAnalyzer = mockk(),
test: @Composable () -> Unit, test: @Composable () -> Unit,
) { ) {
setTestContent { setTestContent {
@ -37,6 +39,7 @@ abstract class AuthenticatorComposeTest : BaseComposeTest() {
intentManager = intentManager, intentManager = intentManager,
exitManager = exitManager, exitManager = exitManager,
biometricsManager = biometricsManager, biometricsManager = biometricsManager,
qrCodeAnalyzer = qrCodeAnalyzer,
content = test, content = test,
) )
} }

View File

@ -2,6 +2,7 @@ package com.bitwarden.ui.platform.composition
import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import com.bitwarden.ui.platform.feature.qrcodescan.util.QrCodeAnalyzer
import com.bitwarden.ui.platform.manager.IntentManager import com.bitwarden.ui.platform.manager.IntentManager
/** /**
@ -10,3 +11,10 @@ import com.bitwarden.ui.platform.manager.IntentManager
val LocalIntentManager: ProvidableCompositionLocal<IntentManager> = compositionLocalOf { val LocalIntentManager: ProvidableCompositionLocal<IntentManager> = compositionLocalOf {
error("CompositionLocal LocalIntentManager not present") error("CompositionLocal LocalIntentManager not present")
} }
/**
* Provides access to the QR Code Analyzer throughout the app.
*/
val LocalQrCodeAnalyzer: ProvidableCompositionLocal<QrCodeAnalyzer> = compositionLocalOf {
error("CompositionLocal LocalQrCodeAnalyzer not present")
}