[PM-34126] feat: Add card scan screen#6721
Conversation
Bitwarden Claude Code ReviewOverall Assessment: APPROVE This PR adds a new card scan screen with camera integration for credit card scanning, including a ViewModel with duplicate-scan guarding, a shared result channel (CardScanManager), navigation setup, and a feature flag gate. The implementation closely follows the established QrCodeScanScreen pattern with appropriate window-size-based layout switching. Tests cover ViewModel actions/events, manager emission, and screen rendering. Code Review DetailsNo actionable findings. The code follows established codebase patterns consistently, including:
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6721 +/- ##
==========================================
- Coverage 85.33% 84.97% -0.36%
==========================================
Files 957 841 -116
Lines 60714 58952 -1762
Branches 8634 8563 -71
==========================================
- Hits 51808 50097 -1711
+ Misses 5900 5873 -27
+ Partials 3006 2982 -24
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
New Issues (128)Checkmarx found the following issues in this Pull Request
|
|
|
||
| // This screen should always look like it's in dark mode | ||
| CompositionLocalProvider( | ||
| LocalBitwardenColorScheme provides darkBitwardenColorScheme, |
| CompositionLocalProvider( | ||
| LocalBitwardenColorScheme provides darkBitwardenColorScheme, | ||
| ) { | ||
| StatusBarsAppearanceAffect() |
| } | ||
|
|
||
| private fun handleCameraErrorReceive() { | ||
| cardScanManager.emitCardScanResult(CardScanResult.ScanError()) |
There was a problem hiding this comment.
Do we need this too?
mutableStateFlow.update { it.copy(hasHandledScan = true) }There was a problem hiding this comment.
No. This is only fired on camera setup failure, so it will only be called once, unlike handleCardScan. Although, hasHandledScan doesn't really need to be in the state. I can make it a member of the ViewModel itself.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/cardscanner/CardScanViewModelTest.kt
Outdated
Show resolved
Hide resolved
be951b7 to
ff88fbb
Compare
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/cardscanner/CardScanViewModelTest.kt
Show resolved
Hide resolved
| ) : BaseViewModel<CardScanState, CardScanEvent, CardScanAction>( | ||
| initialState = CardScanState, | ||
| ) { | ||
| private var hasHandledScan = false |
There was a problem hiding this comment.
Can we move this into the state
35fa5f1 to
8299421
Compare
- Add Closeable to CardTextAnalyzerImpl to release ML Kit native resources - Override toString on CardScanData to mask sensitive fields - Add missing RuPay brand detection test coverage
LocalComposition doesn't provide a lifecycle hook for cleanup, so close() would never be invoked. Removes Closeable to stay consistent with QrCodeAnalyzerImpl.
Add the complete text analysis pipeline for credit card scanning: - CardNumberUtils: sanitize, Luhn validation, brand detection - CardDataParser: interface and implementation for OCR text parsing - CardTextAnalyzer: ML Kit-based camera frame analysis - CardScanOverlay: camera overlay composable - CardScanData: data class for parsed card fields - FakeCardTextAnalyzer: test fixture - LocalProviders: composition local for CardTextAnalyzer
Add the card scanner screen with camera integration: - CardScanManager: shared result channel between scanner and consumer - CardScanViewModel: state management for scan screen - CardScanScreen: composable with camera preview and overlay - CardScanNavigation: route and navigation helper - CardScanner feature flag gated behind card-scanner-mobile
Remove stale cardholderName parameter from test data, simplify ScanError verify to use direct value instead of match lambda, and fix import ordering.
Move hasHandledScan from Parcelable state to a private var since it is internal bookkeeping, not UI state. Update flag key name to pm-34171-card-scanner. Add OmitFromCoverage to navigation, fix minor formatting.
eeede50 to
d076c37
Compare


🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-34126
📔 Objective
Add the card scan screen with camera integration for credit card scanning:
uimodule (cardscanner/manager/)CardScanDatafor success/error statesDeferredBackgroundEventcard-scanner-mobileFlagKeycardTextAnalyzerparameter tosetContentIncludes ViewModel, Screen, and Manager tests.
📸 Screenshots