@@ -21,10 +21,13 @@ import android.content.Context
2121import android.content.Intent
2222import android.util.Base64
2323import android.util.Log
24+ import androidx.credentials.CreateDigitalCredentialRequest
25+ import androidx.credentials.CreateDigitalCredentialResponse
2426import androidx.credentials.DigitalCredential
2527import androidx.credentials.ExperimentalDigitalCredentialApi
2628import androidx.credentials.GetCredentialResponse
2729import androidx.credentials.GetDigitalCredentialOption
30+ import androidx.credentials.exceptions.CreateCredentialUnknownException
2831import androidx.credentials.exceptions.GetCredentialUnknownException
2932import androidx.credentials.provider.PendingIntentHandler
3033import androidx.credentials.provider.ProviderGetCredentialRequest
@@ -33,6 +36,7 @@ import androidx.credentials.registry.digitalcredentials.mdoc.MdocField
3336import androidx.credentials.registry.digitalcredentials.openid4vp.OpenId4VpRegistry
3437import androidx.credentials.registry.digitalcredentials.sdjwt.SdJwtClaim
3538import androidx.credentials.registry.digitalcredentials.sdjwt.SdJwtEntry
39+ import androidx.credentials.registry.provider.RegisterCreationOptionsRequest
3640import androidx.credentials.registry.provider.RegistryManager
3741import androidx.credentials.registry.provider.digitalcredentials.DigitalCredentialEntry
3842import androidx.credentials.registry.provider.digitalcredentials.EntryDisplayProperties
@@ -94,9 +98,14 @@ class DigitalCredentialHolderActivity : Activity() {
9498 }
9599 // [END android_identity_mapto_mdoc_entries]
96100
97- suspend fun registerCredentials (sdJwtsFromStorage : List <StoredSdJwtEntry >, mdocsFromStorage : List <StoredMdocEntry >, registryManager : RegistryManager ) {
101+ suspend fun registerCredentials (
102+ sdJwtsFromStorage : List <StoredSdJwtEntry >,
103+ mdocsFromStorage : List <StoredMdocEntry >,
104+ registryManager : RegistryManager
105+ ) {
98106 // [START android_identity_register_credential_entries]
99- val credentialEntries = mapToSdJwtEntries(sdJwtsFromStorage) + mapToMdocEntries(mdocsFromStorage)
107+ val credentialEntries =
108+ mapToSdJwtEntries(sdJwtsFromStorage) + mapToMdocEntries(mdocsFromStorage)
100109
101110 val openidRegistryRequest = OpenId4VpRegistry (
102111 credentialEntries = credentialEntries,
@@ -140,9 +149,11 @@ class DigitalCredentialHolderActivity : Activity() {
140149 // [END android_identity_get_credential_origin]
141150
142151 // [START android_identity_get_signing_cert_hash]
143- val appSigningInfo = request?.callingAppInfo?.signingInfoCompat?.signingCertificateHistory[0 ]?.toByteArray()
152+ val appSigningInfo =
153+ request?.callingAppInfo?.signingInfoCompat?.signingCertificateHistory[0 ]?.toByteArray()
144154 val md = MessageDigest .getInstance(" SHA-256" )
145- val certHash = Base64 .encodeToString(md.digest(appSigningInfo), Base64 .NO_WRAP or Base64 .NO_PADDING )
155+ val certHash =
156+ Base64 .encodeToString(md.digest(appSigningInfo), Base64 .NO_WRAP or Base64 .NO_PADDING )
146157 return " android:apk-key-hash:$certHash "
147158 // [END android_identity_get_signing_cert_hash]
148159 }
@@ -169,18 +180,86 @@ class DigitalCredentialHolderActivity : Activity() {
169180 // [END android_identity_get_credential_response_exception]
170181 }
171182 }
183+
184+ @OptIn(ExperimentalDigitalCredentialApi ::class )
185+ suspend fun registerIssuance (context : Context ) {
186+ // [START android_identity_register_issuance_create_options]
187+ val registryManager = RegistryManager .create(context)
188+
189+ try {
190+ registryManager.registerCreationOptions(object :
191+ RegisterCreationOptionsRequest (
192+ creationOptions = buildIssuanceData(),
193+ matcher = loadIssuanceMatcher(),
194+ type = DigitalCredential .TYPE_DIGITAL_CREDENTIAL ,
195+ id = " openid4vci" ,
196+ ) {}
197+ )
198+ } catch (e: Exception ) {
199+ Log .e(TAG , " Issuance registration failed." , e)
200+ }
201+ // [END android_identity_register_issuance_create_options]
202+
203+ // [START android_identity_handle_issuance_create_option_selected]
204+ val pendingIntentRequest =
205+ PendingIntentHandler .retrieveProviderCreateCredentialRequest(intent)
206+ val request = pendingIntentRequest!! .callingRequest
207+ if (request is CreateDigitalCredentialRequest ) {
208+ Log .i(TAG , " Got DC creation request: ${request.requestJson} " )
209+ processCreationRequest(request.requestJson)
210+ }
211+ // [END android_identity_handle_issuance_create_option_selected]
212+ }
213+
214+ fun buildIssuanceData (): ByteArray {
215+ return byteArrayOf()
216+ }
217+
218+ fun loadIssuanceMatcher (): ByteArray {
219+ return byteArrayOf()
220+ }
221+
222+ fun processCreationRequest (requestJson : String ) {}
223+
224+ @OptIn(ExperimentalDigitalCredentialApi ::class )
225+ fun processIssuanceCreationResponse (response : CreateDigitalCredentialResponse ) {
226+ // [START android_identity_issuance_return_credential_response]
227+ val resultData = Intent ()
228+ PendingIntentHandler .setCreateCredentialResponse(
229+ resultData,
230+ CreateDigitalCredentialResponse (response.responseJson)
231+ )
232+ setResult(RESULT_OK , resultData)
233+ finish()
234+ // [END android_identity_issuance_return_credential_response]
235+ }
236+
237+ fun processIssuanceCreationResponseException () {
238+ // [START android_identity_issuance_handle_credential_exception]
239+ val resultData = Intent ()
240+ PendingIntentHandler .setCreateCredentialException(
241+ resultData,
242+ CreateCredentialUnknownException () // Configure the proper exception
243+ )
244+ setResult(RESULT_OK , resultData)
245+ finish()
246+ // [END android_identity_issuance_handle_credential_exception]
247+ }
172248}
173249
174250sealed class StoredSdJwtEntry {
175251 fun getVCT (): String {
176252 return " "
177253 }
254+
178255 fun getClaimsList (): List <SdJwtClaim > {
179256 return emptyList()
180257 }
258+
181259 fun toDisplayProperties (): Set <EntryDisplayProperties > {
182260 return emptySet()
183261 }
262+
184263 fun getId (): String {
185264 return " "
186265 }
@@ -190,12 +269,15 @@ sealed class StoredMdocEntry {
190269 fun retrieveDocType (): String {
191270 return " "
192271 }
272+
193273 fun getFields (): List <MdocField > {
194274 return emptyList()
195275 }
276+
196277 fun toDisplayProperties (): Set <EntryDisplayProperties > {
197278 return emptySet()
198279 }
280+
199281 fun getId (): String {
200282 return " "
201283 }
0 commit comments