From 2946f9b37b1d98c12fb0a8af06c00383a8fa8a27 Mon Sep 17 00:00:00 2001 From: Ross Schulman Date: Tue, 5 Nov 2024 13:29:17 -0500 Subject: [PATCH] 18013-5 Reader in Kotlin (#20) Co-authored-by: Juliano Cezar Chagas Tavares --- .idea/deploymentTargetSelector.xml | 3 + .idea/runConfigurations.xml | 4 + .../mobile/sdk/CredentialsViewModel.kt | 9 +- .../spruceid/mobile/sdk/IsoMdlPresentation.kt | 5 +- .../com/spruceid/mobile/sdk/IsoMdlReader.kt | 54 +++ .../java/com/spruceid/mobile/sdk/Transport.kt | 11 +- .../com/spruceid/mobile/sdk/TransportBle.kt | 60 ++- .../sdk/TransportBleCentralClientHolder.kt | 17 +- .../sdk/TransportBlePeripheralServerHolder.kt | 42 ++- .../sdk/TransportBlePeripheralServerReader.kt | 186 ++++++++++ .../mobilesdkexample/navigation/Screen.kt | 2 + .../navigation/SetupNavGraph.kt | 4 + .../mobilesdkexample/ui/theme/Color.kt | 6 + .../mobilesdkexample/ui/theme/Theme.kt | 2 +- .../mobilesdkexample/ui/theme/Type.kt | 89 ++++- .../verifier/VerifierHomeView.kt | 13 +- .../verifier/VerifierMDocResultView.kt | 348 ++++++++++++++++++ .../mobilesdkexample/verifier/VerifyDLView.kt | 2 +- .../verifier/VerifyMDocView.kt | 196 ++++++++++ .../wallet/ShareableCredentialListItem.kt | 8 +- .../src/main/res/font/switzer_variable.ttf | Bin 0 -> 141020 bytes .../main/res/font/switzer_variable_italic.ttf | Bin 0 -> 85128 bytes 22 files changed, 1008 insertions(+), 53 deletions(-) create mode 100644 MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlReader.kt create mode 100644 MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerReader.kt create mode 100644 example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierMDocResultView.kt create mode 100644 example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyMDocView.kt create mode 100644 example/src/main/res/font/switzer_variable.ttf create mode 100644 example/src/main/res/font/switzer_variable_italic.ttf diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 040567e..953d5c1 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -5,6 +5,9 @@ + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml index 931b96c..16660f1 100644 --- a/.idea/runConfigurations.xml +++ b/.idea/runConfigurations.xml @@ -5,8 +5,12 @@ diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/CredentialsViewModel.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/CredentialsViewModel.kt index ff8a52d..b74301b 100644 --- a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/CredentialsViewModel.kt +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/CredentialsViewModel.kt @@ -1,7 +1,9 @@ package com.spruceid.mobile.sdk +import android.app.Application import android.bluetooth.BluetoothManager import android.util.Log +import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.ViewModel import com.spruceid.mobile.sdk.rs.ItemsRequest import com.spruceid.mobile.sdk.rs.MdlPresentationSession @@ -15,7 +17,7 @@ import java.security.KeyStore import java.security.Signature import java.util.UUID -class CredentialsViewModel : ViewModel() { +class CredentialsViewModel(application: Application) : AndroidViewModel(application) { private val _credentials = MutableStateFlow>(arrayListOf()) val credentials = _credentials.asStateFlow() @@ -44,7 +46,7 @@ class CredentialsViewModel : ViewModel() { _credentials.value.add(credential) } - private fun firstMdoc(): Mdoc { + private fun firstMdoc(): Mdoc { val mdoc = _credentials.value .map { credential -> credential.asMsoMdoc() } .firstOrNull() @@ -103,6 +105,7 @@ class CredentialsViewModel : ViewModel() { "Central", _session.value!!.getBleIdent(), ::updateRequestData, + getApplication().applicationContext, null ) } @@ -116,7 +119,7 @@ class CredentialsViewModel : ViewModel() { fun submitNamespaces(allowedNamespaces: Map>>) { val mdoc = this.firstMdoc() - if(allowedNamespaces.isEmpty()) { + if (allowedNamespaces.isEmpty()) { val e = Error("Select at least one namespace") Log.e("CredentialsViewModel.submitNamespaces", e.toString()) _currState.value = PresentmentState.ERROR diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlPresentation.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlPresentation.kt index e36b091..bb44a10 100644 --- a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlPresentation.kt +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlPresentation.kt @@ -1,6 +1,7 @@ package com.spruceid.mobile.sdk import android.bluetooth.BluetoothManager +import android.content.Context import android.util.Log import com.spruceid.mobile.sdk.rs.ItemsRequest import com.spruceid.mobile.sdk.rs.MdlPresentationSession @@ -20,7 +21,8 @@ class IsoMdlPresentation( val mdoc: Mdoc, val keyAlias: String, val bluetoothManager: BluetoothManager, - val callback: BLESessionStateDelegate + val callback: BLESessionStateDelegate, + val context: Context ) { val uuid: UUID = UUID.randomUUID() var session: MdlPresentationSession? = null @@ -39,6 +41,7 @@ class IsoMdlPresentation( "Central", session!!.getBleIdent(), ::updateRequestData, + context, callback ) this.callback.update(mapOf(Pair("engagingQRCode", session!!.getQrCodeUri()))) diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlReader.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlReader.kt new file mode 100644 index 0000000..a97304a --- /dev/null +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/IsoMdlReader.kt @@ -0,0 +1,54 @@ +package com.spruceid.mobile.sdk + +import android.bluetooth.BluetoothManager +import android.content.Context +import android.util.Log +import com.spruceid.mobile.sdk.rs.MDocItem +import com.spruceid.mobile.sdk.rs.MdlReaderResponseException +import com.spruceid.mobile.sdk.rs.MdlSessionManager +import com.spruceid.mobile.sdk.rs.establishSession +import java.util.UUID + +class IsoMdlReader( + val callback: BLESessionStateDelegate, + uri: String, + requestedItems: Map>, + trustAnchorRegistry: List?, + platformBluetooth: BluetoothManager, + context: Context +) { + private lateinit var session: MdlSessionManager + private lateinit var bleManager: Transport + + init { + try { + val sessionData = establishSession(uri, requestedItems, trustAnchorRegistry) + + session = sessionData.state + bleManager = Transport(platformBluetooth) + bleManager.initialize( + "Reader", + UUID.fromString(sessionData.uuid), + "BLE", + "Peripheral", + sessionData.bleIdent, + null, + context, + callback, + sessionData.request + ) + + } catch (e: Error) { + Log.e("BleSessionManager.constructor", e.toString()) + } + } + + fun handleResponse(response: ByteArray): Map> { + try { + val responseData = com.spruceid.mobile.sdk.rs.handleResponse(session, response) + return responseData.verifiedResponse + } catch (e: MdlReaderResponseException) { + throw e + } + } +} \ No newline at end of file diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/Transport.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/Transport.kt index 73c7b99..d47c47c 100644 --- a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/Transport.kt +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/Transport.kt @@ -1,6 +1,7 @@ package com.spruceid.mobile.sdk import android.bluetooth.BluetoothManager +import android.content.Context import android.util.Log import java.util.* @@ -21,8 +22,10 @@ class Transport(private var bluetoothManager: BluetoothManager) { deviceRetrieval: String, deviceRetrievalOption: String, ident: ByteArray, - updateRequestData: (data: ByteArray) -> Unit, - callback: BLESessionStateDelegate? + updateRequestData: ((data: ByteArray) -> Unit)? = null, + context: Context, + callback: BLESessionStateDelegate?, + encodedEDeviceKeyBytes: ByteArray = ByteArray(0) ) { /** @@ -42,7 +45,9 @@ class Transport(private var bluetoothManager: BluetoothManager) { deviceRetrievalOption, ident, updateRequestData, - callback + context, + callback, + encodedEDeviceKeyBytes ) } diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBle.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBle.kt index 373b1dd..f7da336 100644 --- a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBle.kt +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBle.kt @@ -1,6 +1,7 @@ package com.spruceid.mobile.sdk import android.bluetooth.BluetoothManager +import android.content.Context import android.util.Log import java.util.* @@ -11,6 +12,7 @@ class TransportBle(private var bluetoothManager: BluetoothManager) { private lateinit var transportBleCentralClientHolder: TransportBleCentralClientHolder private lateinit var transportBlePeripheralServerHolder: TransportBlePeripheralServerHolder + private lateinit var transportBlePeripheralServerReader: TransportBlePeripheralServerReader /** * Reserved for later matching with available cbor options. @@ -29,8 +31,10 @@ class TransportBle(private var bluetoothManager: BluetoothManager) { fun initialize( application: String, serviceUUID: UUID, deviceRetrievalOption: String, ident: ByteArray, - updateRequestData: (data: ByteArray) -> Unit, - callback: BLESessionStateDelegate? + updateRequestData: ((data: ByteArray) -> Unit)? = null, + context: Context, + callback: BLESessionStateDelegate?, + encodedEDeviceKeyBytes: ByteArray ) { /** @@ -38,15 +42,17 @@ class TransportBle(private var bluetoothManager: BluetoothManager) { */ if (deviceRetrievalOption == "Central" && application == "Holder") { Log.d("TransportBle.initialize", "-- Selecting Transport Central Client Holder --") - - transportBleCentralClientHolder = TransportBleCentralClientHolder( - application, - bluetoothManager, - serviceUUID, - updateRequestData, - callback, - ) - transportBleCentralClientHolder.connect(ident) + if (updateRequestData != null) { + transportBleCentralClientHolder = TransportBleCentralClientHolder( + application, + bluetoothManager, + serviceUUID, + updateRequestData, + context, + callback, + ) + transportBleCentralClientHolder.connect(ident) + } } /** @@ -56,9 +62,31 @@ class TransportBle(private var bluetoothManager: BluetoothManager) { Log.d("TransportBle.initialize", "-- Selecting Peripheral Server Holder --") transportBlePeripheralServerHolder = - TransportBlePeripheralServerHolder(application, bluetoothManager, serviceUUID) + TransportBlePeripheralServerHolder( + application, + bluetoothManager, + serviceUUID, + context + ) transportBlePeripheralServerHolder.start() } + + /** + * Transport Peripheral Server Reader + */ + if (deviceRetrievalOption == "Peripheral" && application == "Reader") { + Log.d("TransportBle.initialize", "-- Selecting Peripheral Server Reader --") + + transportBlePeripheralServerReader = + TransportBlePeripheralServerReader( + callback, + application, + bluetoothManager, + serviceUUID, + context + ) + transportBlePeripheralServerReader.start(ident, encodedEDeviceKeyBytes) + } } /** @@ -85,6 +113,10 @@ class TransportBle(private var bluetoothManager: BluetoothManager) { if (this::transportBlePeripheralServerHolder.isInitialized) { transportBlePeripheralServerHolder.stop() } + + if (this::transportBlePeripheralServerReader.isInitialized) { + transportBlePeripheralServerReader.stop() + } } /** @@ -98,5 +130,9 @@ class TransportBle(private var bluetoothManager: BluetoothManager) { if (this::transportBlePeripheralServerHolder.isInitialized) { transportBlePeripheralServerHolder.hardReset() } + + if (this::transportBlePeripheralServerReader.isInitialized) { + transportBlePeripheralServerReader.hardReset() + } } } \ No newline at end of file diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBleCentralClientHolder.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBleCentralClientHolder.kt index 375c907..1c2a87d 100644 --- a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBleCentralClientHolder.kt +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBleCentralClientHolder.kt @@ -17,11 +17,9 @@ class TransportBleCentralClientHolder( private var bluetoothManager: BluetoothManager, private var serviceUUID: UUID, private var updateRequestData: (data: ByteArray) -> Unit, + private var context: Context, private var callback: BLESessionStateDelegate?, -) : Activity() { - - private var context: Context = this - +) { private var bluetoothAdapter: BluetoothAdapter? = null private lateinit var previousAdapterName: String @@ -98,10 +96,17 @@ class TransportBleCentralClientHolder( "progress: $progress max: $max" ) - if(progress == max) { + if (progress == max) { callback?.update(mapOf(Pair("success", ""))) } else { - callback?.update(mapOf(Pair("uploadProgress", mapOf(Pair("curr", progress), Pair("max", max))))) + callback?.update( + mapOf( + Pair( + "uploadProgress", + mapOf(Pair("curr", progress), Pair("max", max)) + ) + ) + ) } } diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerHolder.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerHolder.kt index 95bdccb..133ed5c 100644 --- a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerHolder.kt +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerHolder.kt @@ -1,4 +1,5 @@ package com.spruceid.mobile.sdk + import android.app.Activity import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothManager @@ -12,11 +13,12 @@ import java.util.* * The responsibility of this class is to advertise data and be available for connection. AKA Holder. * 18013-5 section 8.3.3.1.1.4 Table 12. */ -class TransportBlePeripheralServerHolder(private var application: String, - private var bluetoothManager: BluetoothManager, - private var serviceUUID: UUID): Activity() { - - private var context: Context = this +class TransportBlePeripheralServerHolder( + private var application: String, + private var bluetoothManager: BluetoothManager, + private var serviceUUID: UUID, + private var context: Context +) { private var bluetoothAdapter: BluetoothAdapter? = null @@ -56,15 +58,25 @@ class TransportBlePeripheralServerHolder(private var application: String, */ val gattServerCallback: GattServerCallback = object : GattServerCallback() { override fun onPeerConnected() { - Log.d("TransportBlePeripheralServerHolder.gattServerCallback.onPeerConnected", "Peer Connected") + Log.d( + "TransportBlePeripheralServerHolder.gattServerCallback.onPeerConnected", + "Peer Connected" + ) } + override fun onPeerDisconnected() { - Log.d("TransportBlePeripheralServerHolder.gattServerCallback.onPeerDisconnected", "Peer Disconnected") + Log.d( + "TransportBlePeripheralServerHolder.gattServerCallback.onPeerDisconnected", + "Peer Disconnected" + ) gattServer.stop() } override fun onMessageSendProgress(progress: Int, max: Int) { - Log.d("TransportBlePeripheralServerHolder.gattServerCallback.onMessageSendProgress", "progress:$progress max:$max") + Log.d( + "TransportBlePeripheralServerHolder.gattServerCallback.onMessageSendProgress", + "progress:$progress max:$max" + ) blePeripheral.stopAdvertise() } @@ -100,9 +112,17 @@ class TransportBlePeripheralServerHolder(private var application: String, return } - gattServer = GattServer(gattServerCallback, context, bluetoothManager, serviceUUID, - characteristicStateUuid, characteristicClient2ServerUuid, characteristicServer2ClientUuid, - null, characteristicL2CAPUuid) + gattServer = GattServer( + gattServerCallback, + context, + bluetoothManager, + serviceUUID, + characteristicStateUuid, + characteristicClient2ServerUuid, + characteristicServer2ClientUuid, + null, + characteristicL2CAPUuid + ) blePeripheral = BlePeripheral(blePeripheralCallback, serviceUUID, bluetoothAdapter!!) blePeripheral.advertise() diff --git a/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerReader.kt b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerReader.kt new file mode 100644 index 0000000..9135a52 --- /dev/null +++ b/MobileSdk/src/main/java/com/spruceid/mobile/sdk/TransportBlePeripheralServerReader.kt @@ -0,0 +1,186 @@ +/** + * TransportBlePeripheralServerReader.kt + * + * SPRUCE SYSTEMS, INC. PROPRIETARY AND CONFIDENTIAL. + * + * Spruce Systems, Inc. Copyright 2023-2024. All Rights Reserved. Spruce Systems, + * Inc. retains sole and exclusive, right, title and interest in and to all code, + * Work Product and other deliverables, and all copies, modifications, and + * derivative works thereof, including all proprietary or intellectual property + * rights contained therein. The file may not be used or distributed without + * express permission of Spruce Systems, Inc. + */ + +package com.spruceid.mobile.sdk + +import android.app.Activity +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothManager +import android.bluetooth.le.AdvertiseSettings +import android.content.Context +import android.util.Log +import java.util.* + +/** + * The responsibility of this class is to advertise data and be available for connection. AKA Reader. + * 18013-5 section 8.3.3.1.1.4 Table 11. + */ +class TransportBlePeripheralServerReader( + private val callback: BLESessionStateDelegate?, + private var application: String, + private var bluetoothManager: BluetoothManager, + private var serviceUUID: UUID, + private val context: Context +) { + private var bluetoothAdapter: BluetoothAdapter? = null + + private lateinit var previousAdapterName: String + private lateinit var blePeripheral: BlePeripheral + private lateinit var gattServer: GattServer + private lateinit var identValue: ByteArray + + private var characteristicStateUuid: UUID = + UUID.fromString("00000005-a123-48ce-896b-4c76973373e6") + private var characteristicClient2ServerUuid: UUID = + UUID.fromString("00000006-a123-48ce-896b-4c76973373e6") + private var characteristicServer2ClientUuid: UUID = + UUID.fromString("00000007-a123-48ce-896b-4c76973373e6") + private var characteristicIdentUuid: UUID = + UUID.fromString("00000008-a123-48ce-896b-4c76973373e6") + private var characteristicL2CAPUuid: UUID = + UUID.fromString("0000000b-a123-48ce-896b-4c76973373e6") + + private var logIndex: Int = 0 + + /** + * Sets up peripheral with GATT server mode. + */ + fun start(ident: ByteArray, encodedEDeviceKeyBytes: ByteArray) { + + /** + * Should be generated based on the 18013-5 section 8.3.3.1.1.3. + */ + identValue = ident + + /** + * BLE Peripheral callback. + */ + val blePeripheralCallback: BlePeripheralCallback = object : BlePeripheralCallback() { + override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {} + override fun onStartFailure(errorCode: Int) {} + + override fun onLog(message: String) { + Log.d("TransportBlePeripheralServerReader.blePeripheralCallback.onLog", message) + } + + override fun onState(state: String) { + Log.d("TransportBlePeripheralServerReader.blePeripheralCallback.onState", state) + } + } + + /** + * GATT server callback. + */ + val gattServerCallback: GattServerCallback = object : GattServerCallback() { + override fun onPeerConnected() { + + blePeripheral.stopAdvertise() + gattServer.sendMessage(encodedEDeviceKeyBytes) + + Log.d( + "TransportBlePeripheralServerReader.gattCallback.onPeerConnected", + "Peer connected" + ) + } + + override fun onPeerDisconnected() { + gattServer.stop() + } + + override fun onMessageSendProgress(progress: Int, max: Int) {} + override fun onMessageReceived(data: ByteArray) { + + Log.d( + "TransportBlePeripheralServerReader.gattCallback.messageReceived", + data.toString() + ) + gattServer.sendTransportSpecificTermination() + gattServer.stop() + + callback?.update(mapOf(Pair("mdl", data))) + } + + override fun onTransportSpecificSessionTermination() { + Log.d("TransportBlePeripheralServerReader.gattCallback.termination", "Terminated") + } + + override fun onError(error: Throwable) { + Log.d("TransportBlePeripheralServerReader.gattCallback.onError", error.toString()) + } + + override fun onLog(message: String) { + Log.d("TransportBlePeripheralServerReader.gattCallback.onLog", message) + } + + override fun onState(state: String) { + callback?.update(mapOf(Pair("state", state))) + } + } + + bluetoothAdapter = bluetoothManager.adapter + + /** + * Setting up device name for easier identification after connection - too large to be in + * advertisement data. + */ + try { + previousAdapterName = bluetoothAdapter!!.name + bluetoothAdapter!!.name = "mDL $application Device" + } catch (error: SecurityException) { + println(error) + } + + if (bluetoothAdapter == null) { + println("No Bluetooth Adapter") + return + } + + gattServer = GattServer( + gattServerCallback, + context, + bluetoothManager, + serviceUUID, + characteristicStateUuid, + characteristicClient2ServerUuid, + characteristicServer2ClientUuid, + characteristicIdentUuid, + characteristicL2CAPUuid + ) + + blePeripheral = BlePeripheral(blePeripheralCallback, serviceUUID, bluetoothAdapter!!) + blePeripheral.advertise() + gattServer.start(identValue) + } + + fun stop() { + if (this::previousAdapterName.isInitialized) { + try { + bluetoothAdapter!!.name = previousAdapterName + } catch (error: SecurityException) { + println(error) + } + } + + blePeripheral.stopAdvertise() + gattServer.stop() + } + + /** + * Terminates and resets all connections to ensure a clean state. + */ + fun hardReset() { + blePeripheral.stopAdvertise() + gattServer.stop() + gattServer.reset() + } +} diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/navigation/Screen.kt b/example/src/main/java/com/spruceid/mobilesdkexample/navigation/Screen.kt index 4357c34..64f766e 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/navigation/Screen.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/navigation/Screen.kt @@ -4,6 +4,7 @@ const val HOME_SCREEN_PATH = "home" const val VERIFY_DL_PATH = "verify_dl" const val VERIFY_EA_PATH = "verify_ea" const val VERIFY_VC_PATH = "verify_vc" +const val VERIFY_MDOC_PATH = "verify_mdoc" const val VERIFY_DELEGATED_OID4VP_PATH = "verify_delegated_oid4vp/{id}" const val VERIFIER_SETTINGS_HOME_PATH = "verifier_settings_home" const val ADD_VERIFICATION_METHOD_PATH = "add_verification_method" @@ -18,6 +19,7 @@ sealed class Screen(val route: String) { object VerifyDLScreen : Screen(VERIFY_DL_PATH) object VerifyEAScreen : Screen(VERIFY_EA_PATH) object VerifyVCScreen : Screen(VERIFY_VC_PATH) + object VerifyMDocScreen : Screen(VERIFY_MDOC_PATH) object VerifyDelegatedOid4vpScreen : Screen(VERIFY_DELEGATED_OID4VP_PATH) object VerifierSettingsHomeScreen : Screen(VERIFIER_SETTINGS_HOME_PATH) object AddVerificationMethodScreen : Screen(ADD_VERIFICATION_METHOD_PATH) diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/navigation/SetupNavGraph.kt b/example/src/main/java/com/spruceid/mobilesdkexample/navigation/SetupNavGraph.kt index 10c78ad..8697216 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/navigation/SetupNavGraph.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/navigation/SetupNavGraph.kt @@ -11,6 +11,7 @@ import com.spruceid.mobilesdkexample.verifier.AddVerificationMethodView import com.spruceid.mobilesdkexample.verifier.VerifyDLView import com.spruceid.mobilesdkexample.verifier.VerifyDelegatedOid4vpView import com.spruceid.mobilesdkexample.verifier.VerifyEAView +import com.spruceid.mobilesdkexample.verifier.VerifyMDocView import com.spruceid.mobilesdkexample.verifier.VerifyVCView import com.spruceid.mobilesdkexample.verifiersettings.VerifierSettingsHomeView import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModel @@ -42,6 +43,9 @@ fun SetupNavGraph( composable( route = Screen.VerifyVCScreen.route, ) { VerifyVCView(navController) } + composable( + route = Screen.VerifyMDocScreen.route, + ) { VerifyMDocView(navController) } composable( route = Screen.VerifyDelegatedOid4vpScreen.route, ) { backStackEntry -> diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Color.kt b/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Color.kt index 943d34b..0f6ecbd 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Color.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Color.kt @@ -20,17 +20,23 @@ val VerifierCloseButton = Color(0xFF44403C) // Design system colors val ColorBase300 = Color(0xFFE6E1D6) val ColorBase800 = Color(0xFF75675C) +val ColorBase900 = Color(0xFF584C43) val ColorBlue600 = Color(0xFF2F6AE1) val ColorStone50 = Color(0xFFFAFAF9) +val ColorStone200 = Color(0xFFE7E5E4) val ColorStone300 = Color(0xFFD6D3D1) val ColorStone400 = Color(0xFFA8A29E) val ColorStone500 = Color(0xFF78716C) val ColorStone600 = Color(0xFF57534E) val ColorStone950 = Color(0xFF0C0A09) +val ColorEmerald700 = Color(0xFF087455) val ColorEmerald900 = Color(0xFF084C3A) val ColorRose600 = Color(0xFFE11D48) val ColorPurple600 = Color(0xFF926CE6) val ColorTerracotta600 = Color(0xFFE1674C) val TextBase = Color(0xFFFBF9F6) +val TextPrimary = Color(0xFF0C0A09) val BgSurfacePureBlue = Color(0xFF2F6AE1) +val BgSurfacePureWhite = Color(0xFFFDFDFC) +val BgSurfacePrimaryContrast = Color(0xFF44403C) val BorderSecondary = Color(0xFFD6D3D1) \ No newline at end of file diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Theme.kt b/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Theme.kt index 24ab403..d976817 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Theme.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Theme.kt @@ -46,7 +46,7 @@ fun MobileSdkTheme( MaterialTheme( colorScheme = colorScheme, - typography = Typography, + //typography = Typography, content = content ) } \ No newline at end of file diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Type.kt b/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Type.kt index e57835d..02bb938 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Type.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/ui/theme/Type.kt @@ -1,10 +1,14 @@ package com.spruceid.mobilesdkexample.ui.theme +import android.os.Build import androidx.compose.material3.Typography +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontVariation import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp import com.spruceid.mobilesdkexample.R @@ -31,13 +35,80 @@ val Inter = Font(R.font.inter_thin_italic, FontWeight.Thin, FontStyle.Italic), ) -// Set of Material typography styles to start with -val Typography = Typography( - bodyLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp +object BodyMdDefault { + const val WEIGHT = 500 +} + +val Switzer = + FontFamily( + Font( + R.font.switzer_variable, + ) ) -) \ No newline at end of file + + +// Set of Material typography styles to start with +val Typography.bodyMdDefault: TextStyle + @Composable + get() { + return TextStyle( + fontFamily = Switzer, + fontWeight = FontWeight.W500, + fontSize = 18.sp, + lineHeight = 27.sp + ) + } + +val Typography.bodyXsRegular: TextStyle + @Composable + get() { + return TextStyle( + fontFamily = Switzer, + fontWeight = FontWeight.W400, + fontSize = 16.sp, + lineHeight = 24.sp + ) + } + +val Typography.headerH2: TextStyle + @Composable + get() { + return TextStyle( + fontFamily = Switzer, + fontWeight = FontWeight.W500, + fontSize = 24.sp, + lineHeight = 30.sp + ) + } + +val Typography.buttonText: TextStyle + @Composable + get() { + return TextStyle( + fontFamily = Switzer, + fontWeight = FontWeight.SemiBold, + fontSize = 16.sp, + lineHeight = 24.sp + ) + } + +val Typography.buttonTextSmall: TextStyle + @Composable + get() { + return TextStyle( + fontFamily = Switzer, + fontWeight = FontWeight.W500, + fontSize = 14.sp, + lineHeight = 21.sp + ) + } + + +// bodyMd = TextStyle( +// fontFamily = FontFamily.Default, +// fontWeight = FontWeight.Normal, +// fontSize = 16.sp, +// lineHeight = 24.sp, +// letterSpacing = 0.5.sp +// ) +// ) \ No newline at end of file diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierHomeView.kt b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierHomeView.kt index ae2122e..bac2978 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierHomeView.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierHomeView.kt @@ -2,7 +2,6 @@ package com.spruceid.mobilesdkexample.verifier import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -14,9 +13,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -31,9 +28,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController -import com.spruceid.mobile.sdk.CredentialPack import com.spruceid.mobilesdkexample.R -import com.spruceid.mobilesdkexample.credentials.GenericCredentialItem import com.spruceid.mobilesdkexample.navigation.Screen import com.spruceid.mobilesdkexample.ui.theme.ColorBlue600 import com.spruceid.mobilesdkexample.ui.theme.ColorPurple600 @@ -163,6 +158,14 @@ fun VerifierHomeBody( // navController.navigate(Screen.VerifyEAScreen.route) // } // ) + VerifierListItem( + title = "Mobile Driver's Licence", + description = "Verifies an ISO formatted mobile driver's license by reading a QR code", + type = VerifierListItemTagType.SCAN_QR_CODE, + modifier = Modifier.clickable { + navController.navigate(Screen.VerifyMDocScreen.route) + } + ) VerifierListItem( title = "Verifiable Credential", description = "Verifies a verifiable credential by reading the verifiable presentation QR code", diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierMDocResultView.kt b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierMDocResultView.kt new file mode 100644 index 0000000..4e31866 --- /dev/null +++ b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifierMDocResultView.kt @@ -0,0 +1,348 @@ +package com.spruceid.mobilesdkexample.verifier + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.Refresh +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import androidx.navigation.compose.rememberNavController +import com.spruceid.mobile.sdk.rs.MDocItem +import com.spruceid.mobilesdkexample.R +import com.spruceid.mobilesdkexample.navigation.Screen +import com.spruceid.mobilesdkexample.ui.theme.BgSurfacePrimaryContrast +import com.spruceid.mobilesdkexample.ui.theme.BgSurfacePureWhite +import com.spruceid.mobilesdkexample.ui.theme.BorderSecondary +import com.spruceid.mobilesdkexample.ui.theme.ColorBase900 +import com.spruceid.mobilesdkexample.ui.theme.ColorEmerald700 +import com.spruceid.mobilesdkexample.ui.theme.ColorStone200 +import com.spruceid.mobilesdkexample.ui.theme.ColorStone600 +import com.spruceid.mobilesdkexample.ui.theme.ColorStone950 +import com.spruceid.mobilesdkexample.ui.theme.TextBase +import com.spruceid.mobilesdkexample.ui.theme.TextPrimary +import com.spruceid.mobilesdkexample.ui.theme.bodyMdDefault +import com.spruceid.mobilesdkexample.ui.theme.bodyXsRegular +import com.spruceid.mobilesdkexample.ui.theme.buttonText +import com.spruceid.mobilesdkexample.ui.theme.buttonTextSmall +import com.spruceid.mobilesdkexample.ui.theme.headerH2 + +fun getDiscriminant(element: MDocItem): String = + when (element) { + is MDocItem.Array -> "" + is MDocItem.Bool -> element.v1.toString() + is MDocItem.Integer -> element.v1.toString() + is MDocItem.ItemMap -> "" + is MDocItem.Text -> element.v1 + } + +fun intToGender(repr: MDocItem.Integer): String = + when (repr.v1) { + 0L -> "Not Known" + 1L -> "Male" + 2L -> "Female" + else -> "Other" + } + +fun mDocArrayToByteArray(repr: MDocItem.Array): ByteArray = + repr.v1.filterIsInstance().map { + it.v1.toInt().toByte() + }.toByteArray() + + +@Composable +fun VerifierMDocResultView( + navController: NavController, + result: Map> +) { + val givenName = getDiscriminant(result["org.iso.18013.5.1"]?.get("given_name")!!) + val familyName = getDiscriminant(result["org.iso.18013.5.1"]?.get("family_name")!!) + val dob = getDiscriminant(result["org.iso.18013.5.1"]?.get("birth_date")!!) + val address = getDiscriminant(result["org.iso.18013.5.1"]?.get("resident_address")!!) + val expires = getDiscriminant(result["org.iso.18013.5.1"]?.get("expiry_date")!!) + val height = getDiscriminant(result["org.iso.18013.5.1"]?.get("height")!!) + val weight = getDiscriminant(result["org.iso.18013.5.1"]?.get("weight")!!) + val gender = intToGender(result["org.iso.18013.5.1"]?.get("sex")!! as MDocItem.Integer) + val eyeColor = getDiscriminant(result["org.iso.18013.5.1"]?.get("eye_colour")!!) + val hairColor = getDiscriminant(result["org.iso.18013.5.1"]?.get("hair_colour")!!) + val portrait = result["org.iso.18013.5.1"]?.get("portrait")!! as MDocItem.Array + + val portraitBytes = mDocArrayToByteArray(portrait) + Box( + Modifier + .fillMaxSize() + .background(Color.White), + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp) + .padding(top = 48.dp, bottom = 64.dp) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()) + .weight(1f), + Arrangement.spacedBy(18.dp) + ) { + Column(verticalArrangement = Arrangement.spacedBy(11.dp)) { + //BitmapImage(portraitBytes, "Holder's Portrait", Modifier) + Text( + text = "Driver's License", + color = ColorStone950, + style = MaterialTheme.typography.headerH2 + ) + Text( + text = "Issuer", + color = ColorStone600, + style = MaterialTheme.typography.bodyMdDefault + ) + } + HorizontalDivider(color = ColorStone200) + Column(verticalArrangement = Arrangement.spacedBy(16.dp)) { + Text( + text = "Status", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Box( + modifier = Modifier + .fillMaxWidth() + .height(53.dp) + .clip(RoundedCornerShape(8.dp)) + .background(color = ColorEmerald700) + .border(width = 1.dp, color = ColorBase900) + .padding(horizontal = 12.dp, vertical = 5.dp), + contentAlignment = Alignment.Center + ) { + Row(verticalAlignment = Alignment.CenterVertically) + { + Icon( + painter = painterResource(id = R.drawable.valid_check), + contentDescription = "Valid Checkmark", + tint = Color.White, + ) + Spacer(modifier = Modifier.width(12.dp)) + Text( + text = "VALID", + color = TextBase, + style = MaterialTheme.typography.bodyMdDefault + ) + } + } + + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Name", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = "${ + givenName.lowercase().replaceFirstChar(Char::titlecase) + } ${familyName.lowercase().replaceFirstChar(Char::titlecase)}", + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Date of Birth", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = dob, + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Address", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = address, + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Height", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = "${height}cm", + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Weight", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = "${weight}kg", + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Eye Color", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = eyeColor.replaceFirstChar(Char::titlecase), + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Hair Color", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = hairColor.replaceFirstChar(Char::titlecase), + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + Column(verticalArrangement = Arrangement.spacedBy(3.dp)) { + Text( + text = "Gender", + color = ColorStone600, + style = MaterialTheme.typography.bodyXsRegular + ) + Text( + text = gender, + color = ColorStone950, + style = MaterialTheme.typography.bodyMdDefault + ) + } + } + } + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Button( + modifier = Modifier + .fillMaxWidth(), + shape = RoundedCornerShape(8.dp), + onClick = { navController.popBackStack() }, + colors = ButtonColors( + containerColor = BgSurfacePrimaryContrast, contentColor = TextBase, + disabledContainerColor = Color.Black, + disabledContentColor = TextBase + ) + ) { + Row( + modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp), + verticalAlignment = Alignment.CenterVertically + ) + { + Icon( + Icons.Rounded.Refresh, + contentDescription = "Rescan Icon", + tint = Color.White, + ) + Spacer(modifier = Modifier.width(6.dp)) + Text( + text = "Rescan", + color = TextBase, + style = MaterialTheme.typography.buttonText + ) + } + } + Button( + modifier = Modifier + .fillMaxWidth() + .border(width = 1.dp, color = BorderSecondary), + shape = RoundedCornerShape(8.dp), + onClick = { + navController.navigate(Screen.HomeScreen.route) { + popUpTo(0) + } + }, + colors = ButtonColors( + containerColor = BgSurfacePureWhite, contentColor = TextPrimary, + disabledContainerColor = BgSurfacePureWhite, + disabledContentColor = TextPrimary + ) + + ) { + Row(modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp)) + { + Text( + text = "Close", + color = TextPrimary, + style = MaterialTheme.typography.buttonTextSmall + ) + } + } + } + } + } +} + + +@Preview +@Composable +fun MDocVerifyPreview() { + val example: Map> = + mapOf( + "org.iso.18013.5.1" to mapOf( + "portrait" to MDocItem.Array(listOf()), + "family_name" to MDocItem.Text("ONEZERO"), + "given_name" to MDocItem.Text("IRVINGTEST"), + "birth_date" to MDocItem.Text("1999-03-13"), + "expiry_date" to MDocItem.Text("2038-03-16"), + "sex" to MDocItem.Integer(9), + "height" to MDocItem.Integer(185), + "weight" to MDocItem.Integer(55), + "eye_colour" to MDocItem.Text("green"), + "hair_colour" to MDocItem.Text("unknown"), + "resident_address" to MDocItem.Text("2415 1ST AVE, SACRAMENTO 95818"), + "document_number" to MDocItem.Text("I8882610") + ), + "org.iso.18013.5.1.aamva" to mapOf( + "DHS_compliance" to MDocItem.Text("F"), + "domestic_driving_privileges" to MDocItem.Array(listOf()), + "veteran" to MDocItem.Integer(1) + ) + ) + VerifierMDocResultView(rememberNavController(), example) +} \ No newline at end of file diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyDLView.kt b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyDLView.kt index 6d3b5f8..5359408 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyDLView.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyDLView.kt @@ -17,7 +17,7 @@ import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class, ExperimentalPermissionsApi::class) @Composable fun VerifyDLView( - navController: NavController + navController: NavController, ) { var success by remember { mutableStateOf(null) diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyMDocView.kt b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyMDocView.kt new file mode 100644 index 0000000..0fb1f2c --- /dev/null +++ b/example/src/main/java/com/spruceid/mobilesdkexample/verifier/VerifyMDocView.kt @@ -0,0 +1,196 @@ +package com.spruceid.mobilesdkexample.verifier + +import android.util.Log +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowColumn +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import androidx.navigation.compose.rememberNavController +import com.google.accompanist.permissions.ExperimentalPermissionsApi +import com.spruceid.mobile.sdk.BLESessionStateDelegate +import com.spruceid.mobile.sdk.IsoMdlReader +import com.spruceid.mobile.sdk.getBluetoothManager +import com.spruceid.mobile.sdk.getPermissions +import com.spruceid.mobile.sdk.rs.MDocItem +import com.spruceid.mobile.sdk.ui.QRCodeScanner +import com.spruceid.mobilesdkexample.LoadingView +import com.spruceid.mobilesdkexample.ScanningComponent +import com.spruceid.mobilesdkexample.ScanningType +import com.spruceid.mobilesdkexample.utils.checkAndRequestBluetoothPermissions +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + +val trustAnchorCerts = listOf( + """ +-----BEGIN CERTIFICATE----- +MIICLjCCAdSgAwIBAgIUXrDPrioY9PCUO5hCXJTsVIZwI0cwCgYIKoZIzj0EAwIw +UDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVVTLUNBMQwwCgYDVQQKDANETVYxIzAh +BgNVBAMMGkNhbGlmb3JuaWEgRE1WIFJvb3QgQ0EgVUFUMB4XDTIzMDQxNDE3MjQ0 +N1oXDTMzMDIyMDE3MjQ0N1owUDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVVTLUNB +MQwwCgYDVQQKDANETVYxIzAhBgNVBAMMGkNhbGlmb3JuaWEgRE1WIFJvb3QgQ0Eg +VUFUMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEORXa3DGvoGS0s6S71Vw5oKEw +DdPubWyg75A2p1hca4b66MA0LXUWjoz1cIKUJpyEket9ajEx5+hQvB3yvycKVqOB +izCBiDAdBgNVHQ4EFgQUSWhCfS8C3wEPseC28ScmFn0j25UwEgYDVR0TAQH/BAgw +BgEB/wIBADALBgNVHQ8EBAMCAQYwHQYDVR0SBBYwFIESZXhhbXBsZUBkbXYuY2Eu +Z292MCcGA1UdHwQgMB4wHKAaoBiGFmh0dHBzOi8vZG12LmNhLmdvdi9jcmwwCgYI +KoZIzj0EAwIDSAAwRQIgbpRE08g3aId6e2QULkmlTqnGq0+6kqLltHfjmO6/5MEC +IQDJdY3WnkpFhPw+Ej3ANlFzwvaDgfaacODGR0pFvBQwlg== +-----END CERTIFICATE-----""" +) + +val defaultElements: Map> = + mapOf( + "org.iso.18013.5.1" to mapOf( + "portrait" to false, + "family_name" to false, + "given_name" to false, + "birth_date" to false, + "expiry_date" to false, + "sex" to false, + "height" to false, + "weight" to false, + "eye_colour" to false, + "hair_colour" to false, + "resident_address" to false, + "document_number" to false + ), + "org.iso.18013.5.1.aamva" to mapOf( + "DHS_compliance" to false, + "domestic_driving_privileges" to false, + "veteran" to false + ) + ) + +enum class State { + SCANNING, TRANSMITTING, DONE +} + +@OptIn( + ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class, + ExperimentalPermissionsApi::class +) +@Composable +fun VerifyMDocView(navController: NavController) { + val context = LocalContext.current + var reader: IsoMdlReader? = null + + var scanProcessState by remember { + mutableStateOf(State.SCANNING) + } + + var result by remember { + mutableStateOf>?>(null) + } + + var isBluetoothEnabled by remember { + mutableStateOf(getBluetoothManager(context)!!.adapter.isEnabled) + } + + val launcherMultiplePermissions = rememberLauncherForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { permissionsMap -> + val areGranted = permissionsMap.values.reduce { acc, next -> acc && next } + if (!areGranted) { + // @TODO: Show dialog + } + } + + val bleCallback: BLESessionStateDelegate = object : BLESessionStateDelegate() { + override fun update(state: Map) { + Log.d("VerifyMDocView", state.toString()) + if (state.containsKey("mdl")) { + result = reader?.handleResponse(state["mdl"] as ByteArray) + scanProcessState = State.DONE + } + } + + override fun error(error: Exception) { + TODO("Not yet implemented") + } + } + + fun elementMapToList(elements: Map>): List { + val elementList = listOf(elements.values.map { it.keys.toList() }) + return elementList.flatten().flatten() + } + + fun onRead(content: String) { + scanProcessState = State.TRANSMITTING + checkAndRequestBluetoothPermissions( + context, + getPermissions().toTypedArray(), + launcherMultiplePermissions + ) + Log.d("VerifyMDocView", "Scanned: $content") + val bluetooth = getBluetoothManager(context) + GlobalScope.launch { + reader = IsoMdlReader( + bleCallback, + content, + defaultElements, + trustAnchorCerts, + bluetooth!!, + context + ) + } + } + + fun onCancel() { + navController.popBackStack() + } + + val elementsList = elementMapToList(defaultElements) + + when (scanProcessState) { + State.SCANNING -> Column { + ScanningComponent( + navController, + ScanningType.QRCODE, + title = "", + subtitle = "", + onRead = ::onRead, + onCancel = ::onCancel + ) + HorizontalDivider(thickness = 1.dp) + Text("Requesting the following:") + FlowColumn(Modifier.fillMaxWidth()) { + repeat(elementsList.size) { + Box( + Modifier + .fillMaxColumnWidth() + .padding(12.dp) + ) { + Text( + text = elementsList[it], + ) + } + } + } + } + + State.TRANSMITTING -> LoadingView("Verifying...", "Cancel", ::onCancel) + State.DONE -> VerifierMDocResultView( + navController = navController, + result = result!!, + ) + } +} \ No newline at end of file diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/wallet/ShareableCredentialListItem.kt b/example/src/main/java/com/spruceid/mobilesdkexample/wallet/ShareableCredentialListItem.kt index 176880d..1363385 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/wallet/ShareableCredentialListItem.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/wallet/ShareableCredentialListItem.kt @@ -1,5 +1,6 @@ package com.spruceid.mobilesdkexample.wallet +import android.app.Application import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -28,12 +29,14 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.ViewModelProvider import com.spruceid.mobile.sdk.CredentialPack import com.spruceid.mobile.sdk.CredentialsViewModel import com.spruceid.mobile.sdk.rs.Mdoc @@ -188,12 +191,15 @@ fun ShareableCredentialListItem(credential: ParsedCredential) { @Composable fun ShareableCredentialListItemQRCode(credential: ParsedCredential) { + val context = LocalContext.current + val application = context.applicationContext as Application var showQRCode by remember { mutableStateOf(false) } fun newCredentialViewModel(): CredentialsViewModel { - val credentialViewModel = CredentialsViewModel() + val credentialViewModel = ViewModelProvider.AndroidViewModelFactory(application) + .create(CredentialsViewModel::class.java) credentialViewModel.storeCredential(credential) return credentialViewModel } diff --git a/example/src/main/res/font/switzer_variable.ttf b/example/src/main/res/font/switzer_variable.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d6e5cc4ab0db278982e03aecd7a22de66604608d GIT binary patch literal 141020 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 _=t@0jgQ~Ch#EgzHYI^P5gK1m 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 literal 0 HcmV?d00001 diff --git a/example/src/main/res/font/switzer_variable_italic.ttf b/example/src/main/res/font/switzer_variable_italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..993833a62ff8cdca3e626418494aff1407d5706f GIT binary patch literal 85128 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 literal 0 HcmV?d00001