Skip to content

Commit

Permalink
Hopefully final PR updates
Browse files Browse the repository at this point in the history
- Refactored EvidenceRequestDetailedMessage to EvidenceRequestCompletionMessage and removed the generic detailed message composable.
- Comment nits.

Signed-off-by: dritan-x <[email protected]>
  • Loading branch information
dritan-x committed Nov 8, 2024
1 parent 263bf6a commit b998c8a
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, ByteString>,
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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<String, ByteString>,
Expand All @@ -46,8 +45,7 @@ class ProofingGraphBuilder {

) {
val evidenceRequest =
EvidenceRequestDetailedMessage(
messageType,
EvidenceRequestCompletionMessage(
messageTitle,
message,
assets,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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,
Expand Down Expand Up @@ -303,7 +230,7 @@ fun EvidenceRequestCompleteScreen(
modifier = Modifier.size(100.dp),
contentDescription = stringResource(
R.string.accessibility_artwork_for,
evidenceRequest.messageTitle!!
evidenceRequest.messageTitle
)
)
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1103,7 +1030,6 @@ fun <ResultT> 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 -> ""
}
)
}
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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(
Expand All @@ -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)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 -> {
Expand Down

0 comments on commit b998c8a

Please sign in to comment.