From b998c8ae54c06e51cb90b66dd24696beeb5eaa58 Mon Sep 17 00:00:00 2001 From: dritan-x Date: Fri, 8 Nov 2024 04:32:47 -0800 Subject: [PATCH] Hopefully final PR updates - Refactored EvidenceRequestDetailedMessage to EvidenceRequestCompletionMessage and removed the generic detailed message composable. - Comment nits. Signed-off-by: dritan-x --- ...kt => EvidenceRequestCompletionMessage.kt} | 10 +- .../issuance/proofing/ProofingGraphBuilder.kt | 10 +- .../issuance/proofing/defaultGraph.kt | 3 +- .../provisioncredential/EvidenceRequest.kt | 129 ++++-------------- .../ProvisionCredentialScreen.kt | 26 ++-- 5 files changed, 40 insertions(+), 138 deletions(-) rename identity-issuance/src/main/java/com/android/identity/issuance/evidence/{EvidenceRequestDetailedMessage.kt => EvidenceRequestCompletionMessage.kt} (52%) diff --git a/identity-issuance/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestDetailedMessage.kt b/identity-issuance/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestCompletionMessage.kt similarity index 52% rename from identity-issuance/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestDetailedMessage.kt rename to identity-issuance/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestCompletionMessage.kt index 1ce184602..095201150 100644 --- a/identity-issuance/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestDetailedMessage.kt +++ b/identity-issuance/src/main/java/com/android/identity/issuance/evidence/EvidenceRequestCompletionMessage.kt @@ -3,21 +3,15 @@ package com.android.identity.issuance.evidence import kotlinx.io.bytestring.ByteString /** - * Detailed rich-text message building on top of [EvidenceRequestMessage] that additionally contains - * a [messageTitle] and a [messageType] that is used to identify the classification of the detailed - * message (such as "completed", "info", "confirmation_XYZ") that allows showing tailored UI - * pertaining to the message. + * Message shown after completing the Evidence-gathering steps for Provisioning a document. * - * [messageType] identifier used for classifying message types (success, error, info, ..) to show - * the appropriate UI pertaining to the detailed message. * [messageTitle] title to show above the message * [message] message formatted as markdown * [assets] images that can be referenced in markdown, type (PNG, JPEG, or SVG) determined by the extension * [acceptButtonText] button label to continue to the next screen * [rejectButtonText] optional button label to continue without accepting */ -data class EvidenceRequestDetailedMessage( - val messageType: String, +data class EvidenceRequestCompletionMessage( val messageTitle: String, val message: String, val assets: Map, diff --git a/identity-issuance/src/main/java/com/android/identity/issuance/proofing/ProofingGraphBuilder.kt b/identity-issuance/src/main/java/com/android/identity/issuance/proofing/ProofingGraphBuilder.kt index f2b878925..a372792b0 100644 --- a/identity-issuance/src/main/java/com/android/identity/issuance/proofing/ProofingGraphBuilder.kt +++ b/identity-issuance/src/main/java/com/android/identity/issuance/proofing/ProofingGraphBuilder.kt @@ -1,7 +1,7 @@ package com.android.identity.issuance.proofing +import com.android.identity.issuance.evidence.EvidenceRequestCompletionMessage import com.android.identity.issuance.evidence.EvidenceRequestCreatePassphrase -import com.android.identity.issuance.evidence.EvidenceRequestDetailedMessage import com.android.identity.issuance.evidence.EvidenceRequestGermanEid import com.android.identity.issuance.evidence.EvidenceRequestIcaoPassiveAuthentication import com.android.identity.issuance.evidence.EvidenceRequestMessage @@ -34,10 +34,9 @@ class ProofingGraphBuilder { chain.add { followUp -> ProofingGraph.SimpleNode(id, followUp, evidenceRequest) } } - /** Sends [EvidenceRequestMessage]. */ - fun detailedMessage( + /** Sends [EvidenceRequestCompletionMessage]. */ + fun completionMessage( id: String, - messageType: String, messageTitle: String, message: String, assets: Map, @@ -46,8 +45,7 @@ class ProofingGraphBuilder { ) { val evidenceRequest = - EvidenceRequestDetailedMessage( - messageType, + EvidenceRequestCompletionMessage( messageTitle, message, assets, diff --git a/identity-issuance/src/main/java/com/android/identity/issuance/proofing/defaultGraph.kt b/identity-issuance/src/main/java/com/android/identity/issuance/proofing/defaultGraph.kt index e1fd2b76f..cef1ca906 100644 --- a/identity-issuance/src/main/java/com/android/identity/issuance/proofing/defaultGraph.kt +++ b/identity-issuance/src/main/java/com/android/identity/issuance/proofing/defaultGraph.kt @@ -199,9 +199,8 @@ fun defaultGraph( } } } - detailedMessage( + completionMessage( id = "detailedMessage", - messageType = "evidence_request_complete", messageTitle = "Document Scanning Complete", message = "Your application is now under ID issuer verification. This process might take a few hours.", assets = mapOf(), diff --git a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt index a2afe70e7..4821e6ab8 100644 --- a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt +++ b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/EvidenceRequest.kt @@ -71,8 +71,8 @@ import com.android.identity.appsupport.ui.PassphraseEntryField import com.android.identity.document.DocumentStore import com.android.identity.issuance.ApplicationSupport import com.android.identity.issuance.LandingUrlUnknownException +import com.android.identity.issuance.evidence.EvidenceRequestCompletionMessage import com.android.identity.issuance.evidence.EvidenceRequestCreatePassphrase -import com.android.identity.issuance.evidence.EvidenceRequestDetailedMessage import com.android.identity.issuance.evidence.EvidenceRequestGermanEid import com.android.identity.issuance.evidence.EvidenceRequestIcaoNfcTunnel import com.android.identity.issuance.evidence.EvidenceRequestIcaoPassiveAuthentication @@ -165,90 +165,17 @@ fun EvidenceRequestMessageView( Text(evidenceRequest.acceptButtonText) } } -} -/** - * Show a generic "detailed message" screen whose [detailedMessage.messageType] is not handled. - * Composes a screen containing the "info" icon, message title, message text and the accept button. - */ -@Composable -fun EvidenceRequestGenericDetailedMessageScreen( - detailedMessage: EvidenceRequestDetailedMessage, - provisioningViewModel: ProvisioningViewModel, - walletServerProvider: WalletServerProvider, - documentStore: DocumentStore -) { - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 10.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 20.dp, bottom = 100.dp), - horizontalArrangement = Arrangement.Center - ) { - Icon( - painter = painterResource(id = android.R.drawable.ic_dialog_info), - tint = MaterialTheme.colorScheme.background.inverse(), - modifier = Modifier.size(80.dp), - contentDescription = stringResource( - R.string.accessibility_artwork_for, - detailedMessage.messageTitle - ) - ) - } - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center - ) { - Text( - text = detailedMessage.messageTitle, - modifier = Modifier.padding(16.dp), - textAlign = TextAlign.Left, - fontWeight = FontWeight.Bold, - style = MaterialTheme.typography.headlineLarge - ) - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 200.dp), - horizontalArrangement = Arrangement.Absolute.Left - ) { - Text( - modifier = Modifier.padding(start = 16.dp, end = 16.dp), - text = detailedMessage.message, - style = MaterialTheme.typography.bodyLarge - ) - } - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End - ) { - Button( - modifier = Modifier.padding(8.dp), - onClick = { - provisioningViewModel.provideEvidence( - evidence = EvidenceResponseMessage(true), - walletServerProvider = walletServerProvider, - documentStore = documentStore - ) - }) { - Text(detailedMessage.acceptButtonText) - } - } - } } /** - * Show the "Document Scanning Complete" screen after completing all steps of for evidence gathering - * of the "Provisioning a Personal ID" flow. + * Show the "Document Scanning Complete" screen after completing all steps of for evidence gathering. + * Since it occupies the entire visible screen real estate, this function can be appropriately + * classified as a "Screen" (rather than a generic "View"). */ @Composable -fun EvidenceRequestCompleteScreen( - evidenceRequest: EvidenceRequestDetailedMessage, +fun EvidenceRequestCompletedScreen( + evidenceRequest: EvidenceRequestCompletionMessage, provisioningViewModel: ProvisioningViewModel, walletServerProvider: WalletServerProvider, documentStore: DocumentStore @@ -263,7 +190,7 @@ fun EvidenceRequestCompleteScreen( tint = MaterialTheme.colorScheme.background.inverse(), contentDescription = stringResource( R.string.accessibility_artwork_for, - evidenceRequest.messageTitle!! + evidenceRequest.messageTitle ), modifier = Modifier .size(48.dp) @@ -274,7 +201,7 @@ fun EvidenceRequestCompleteScreen( horizontalArrangement = Arrangement.Center ) { Text( - text = evidenceRequest.messageTitle!!, + text = evidenceRequest.messageTitle, modifier = Modifier.padding(16.dp), textAlign = TextAlign.Left, fontWeight = FontWeight.Bold, @@ -303,7 +230,7 @@ fun EvidenceRequestCompleteScreen( modifier = Modifier.size(100.dp), contentDescription = stringResource( R.string.accessibility_artwork_for, - evidenceRequest.messageTitle!! + evidenceRequest.messageTitle ) ) } @@ -842,8 +769,8 @@ fun EvidenceRequestIcaoNfcTunnelView( IcaoMrtdCommunicationModel.Route.CAMERA_SCAN } - // if developer mode not enabled, simply show the MRZ or NFC screen without briefly showing - // transitional success screen after successfully scanning an NFC document + // If developer mode not enabled, simply show the MRZ or NFC screen without briefly showing + // transitional success screen after successfully scanning an NFC document. if (!developerMode){ EvidenceRequestIcaoView(tunnelScanner, permissionTracker, initialRoute) { // upon completion of nfc scanning, finish the tunneling process @@ -1103,7 +1030,6 @@ fun EvidenceRequestIcaoView( // this is here for completeness sake and is not really visible // due to the screen changing before this view is composed. is MrtdNfc.Finished -> stringResource(R.string.nfc_status_finished) - else -> "" } ) } @@ -1165,18 +1091,20 @@ enum class NfcAnimationStatus { } /** - * Compose the NFC "Heartbeat" animation. + * Compose the NFC "Heartbeat" animation according to the passed-in [nfcAnimationStatus] while + * following the device's Light/Dark theme colors, where the color scheme for Dark theme is the + * inverse of Light. */ @Composable fun NfcHeartbeatAnimation(nfcAnimationStatus: NfcAnimationStatus) { val infiniteTransition = rememberInfiniteTransition(label = "repeating transition") - // duration of all animation transitions + // Duration of all animation transitions. val transitionDurationMs = 1500 - // adjust size of contactless icon here + // Adjust size of contactless icon here. val iconSize = 80.dp - // define the starting alpha of background color of radius animation + // Define the starting alpha of background color of radius animation. val animationBgAlpha = 0.1F - // transition animation that grows the radius around the contactless icon + // Transition animation that grows the radius around the contactless icon. val scale by infiniteTransition.animateFloat( initialValue = 1f, targetValue = 2f, @@ -1188,7 +1116,7 @@ fun NfcHeartbeatAnimation(nfcAnimationStatus: NfcAnimationStatus) { repeatMode = RepeatMode.Restart ), label = "scaling animation" ) - // transition animation for changing alpha of background color of radius animation + // Transition animation for changing alpha of background color of radius animation. val alpha by infiniteTransition.animateFloat( initialValue = animationBgAlpha, targetValue = 0f, @@ -1202,12 +1130,11 @@ fun NfcHeartbeatAnimation(nfcAnimationStatus: NfcAnimationStatus) { } else { colorResource(id = R.color.contactless_blue).inverse() } - - // start composing the "nfc heartbeat" animation + // Start composing the "NFC heartbeat" animation. Box( contentAlignment = Alignment.Center, ) { - // don't show the radius animation when encountering an error + // Don't show the radius animation when encountering an error. if (nfcAnimationStatus != NfcAnimationStatus.Error) { Box( modifier = Modifier @@ -1217,25 +1144,22 @@ fun NfcHeartbeatAnimation(nfcAnimationStatus: NfcAnimationStatus) { .background(tintColorThemed, CircleShape) ) } - // Clip the icon to be circular Box( modifier = Modifier.clip(CircleShape) ) { // get the main and background colors of the "contactless" icon val (tintColor, bgColor) = when (nfcAnimationStatus) { - // waiting to begin reading an NFC document - // contactless blue color icon with the same color for background having a low alpha + // Idling/waiting to begin reading an NFC document. NfcAnimationStatus.Initial -> Pair( tintColorThemed, tintColorThemed.copy(alpha = animationBgAlpha) ) - // once an NFC document is detected, inverse colors of "Initial" status + // Once an NFC document is detected, inverse colors of "Initial" status. NfcAnimationStatus.Connected -> Pair( MaterialTheme.colorScheme.background, tintColorThemed ) - // Error while initializing/reading NFC card - // white icon with light red background with a lower alpha + // Error while initializing/reading NFC card. NfcAnimationStatus.Error -> Pair( MaterialTheme.colorScheme.background, Color.Red.copy( @@ -1247,21 +1171,18 @@ fun NfcHeartbeatAnimation(nfcAnimationStatus: NfcAnimationStatus) { } ) ) - // NFC scan complete -- colors are not used b/c icon is changed entirely + // NFC scan complete -- colors are not used b/c icon is changed entirely. else -> Pair(Color.Transparent, Color.Transparent) } - // compose the "contactless" icon Icon( painter = painterResource(id = R.drawable.contactless), contentDescription = stringResource( R.string.accessibility_artwork_for, stringResource(id = R.string.evidence_nfc_scan_title) ), - // icon color tint = tintColor, modifier = Modifier .size(iconSize) - // background color .background(bgColor) ) } diff --git a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/ProvisionCredentialScreen.kt b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/ProvisionCredentialScreen.kt index f08aa0a68..26372966c 100644 --- a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/ProvisionCredentialScreen.kt +++ b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/provisioncredential/ProvisionCredentialScreen.kt @@ -31,8 +31,8 @@ import com.android.identity.crypto.Crypto import com.android.identity.document.DocumentStore import com.android.identity.issuance.DocumentExtensions.documentConfiguration import com.android.identity.issuance.IssuingAuthorityException +import com.android.identity.issuance.evidence.EvidenceRequestCompletionMessage import com.android.identity.issuance.evidence.EvidenceRequestCreatePassphrase -import com.android.identity.issuance.evidence.EvidenceRequestDetailedMessage import com.android.identity.issuance.evidence.EvidenceRequestGermanEid import com.android.identity.issuance.evidence.EvidenceRequestIcaoNfcTunnel import com.android.identity.issuance.evidence.EvidenceRequestIcaoPassiveAuthentication @@ -195,23 +195,13 @@ fun ProvisionDocumentScreen( ) } - is EvidenceRequestDetailedMessage -> { - // show detailed message according to the messageType - if (evidenceRequest.messageType=="evidence_request_complete"){ - EvidenceRequestCompleteScreen( - evidenceRequest = evidenceRequest, - provisioningViewModel = provisioningViewModel, - walletServerProvider = walletServerProvider, - documentStore = documentStore - ) - } else { - EvidenceRequestGenericDetailedMessageScreen( - detailedMessage = evidenceRequest, - provisioningViewModel = provisioningViewModel, - walletServerProvider = walletServerProvider, - documentStore = documentStore - ) - } + is EvidenceRequestCompletionMessage -> { + EvidenceRequestCompletedScreen( + evidenceRequest = evidenceRequest, + provisioningViewModel = provisioningViewModel, + walletServerProvider = walletServerProvider, + documentStore = documentStore + ) } is EvidenceRequestNotificationPermission -> {