Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +5 −5 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ import com.android.credentialmanager.createflow.DisabledProviderInfo import com.android.credentialmanager.createflow.EnabledProviderInfo import com.android.credentialmanager.createflow.RequestDisplayInfo import com.android.credentialmanager.getflow.GetCredentialUiState import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toBundle import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toCredentialDataBundle import com.android.credentialmanager.jetpack.developer.CreatePublicKeyCredentialRequest import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL import com.android.credentialmanager.jetpack.provider.Action Loading Loading @@ -325,7 +325,7 @@ class CredentialManagerRepo( key, subkey, CredentialEntry.toSlice(credentialEntry), null Intent() ) } Loading @@ -348,7 +348,7 @@ class CredentialManagerRepo( android.service.credentials.CallingAppInfo( context.applicationInfo.packageName, SigningInfo()), TYPE_PASSWORD_CREDENTIAL, toBundle("beckett-bakert@gmail.com", "password123") toCredentialDataBundle("beckett-bakert@gmail.com", "password123") ) val fillInIntent = Intent().putExtra( CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST, Loading Loading @@ -417,7 +417,7 @@ class CredentialManagerRepo( " \"residentKey\": \"required\",\n" + " \"requireResidentKey\": true\n" + " }}") val credentialData = request.data val credentialData = request.credentialData return RequestInfo.newCreateRequestInfo( Binder(), CreateCredentialRequest( Loading @@ -432,7 +432,7 @@ class CredentialManagerRepo( } private fun testCreatePasswordRequestInfo(): RequestInfo { val data = toBundle("beckett-bakert@gmail.com", "password123") val data = toCredentialDataBundle("beckett-bakert@gmail.com", "password123") return RequestInfo.newCreateRequestInfo( Binder(), CreateCredentialRequest( Loading packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt +2 −2 Original line number Diff line number Diff line Loading @@ -242,7 +242,7 @@ class CreateFlowUtils { packageName = it.providerFlattenedComponentName } val pkgInfo = packageManager .getPackageInfo(packageName, .getPackageInfo(packageName!!, PackageManager.PackageInfoFlags.of(0)) DisabledProviderInfo( icon = pkgInfo.applicationInfo.loadIcon(packageManager)!!, Loading @@ -264,7 +264,7 @@ class CreateFlowUtils { val createCredentialRequest = requestInfo.createCredentialRequest val createCredentialRequestJetpack = createCredentialRequest?.let { CreateCredentialRequest.createFrom( it it.type, it.credentialData, it.candidateQueryData, it.requireSystemProvider() ) } when (createCredentialRequestJetpack) { Loading packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt +31 −13 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.credentialmanager.jetpack.developer import android.credentials.Credential import android.os.Bundle import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE /** * Base request class for registering a credential. Loading @@ -28,27 +29,44 @@ import android.os.Bundle * otherwise */ open class CreateCredentialRequest( val type: String, val data: Bundle, val requireSystemProvider: Boolean, open val type: String, open val credentialData: Bundle, open val candidateQueryData: Bundle, open val requireSystemProvider: Boolean ) { companion object { @JvmStatic fun createFrom(from: android.credentials.CreateCredentialRequest): CreateCredentialRequest { fun createFrom( type: String, credentialData: Bundle, candidateQueryData: Bundle, requireSystemProvider: Boolean ): CreateCredentialRequest { return try { when (from.type) { when (type) { Credential.TYPE_PASSWORD_CREDENTIAL -> CreatePasswordRequest.createFrom(from.credentialData) CreatePasswordRequest.createFrom(credentialData) PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> CreatePublicKeyCredentialBaseRequest.createFrom(from.credentialData) else -> CreateCredentialRequest( from.type, from.credentialData, from.requireSystemProvider() ) when (credentialData.getString(BUNDLE_KEY_SUBTYPE)) { CreatePublicKeyCredentialRequest .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST -> CreatePublicKeyCredentialRequest.createFrom(credentialData) CreatePublicKeyCredentialRequestPrivileged .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV -> CreatePublicKeyCredentialRequestPrivileged .createFrom(credentialData) else -> throw FrameworkClassParsingException() } else -> throw FrameworkClassParsingException() } } catch (e: FrameworkClassParsingException) { CreateCredentialRequest( from.type, from.credentialData, from.requireSystemProvider() // Parsing failed but don't crash the process. Instead just output a request with // the raw framework values. CreateCustomCredentialRequest( type, credentialData, candidateQueryData, requireSystemProvider ) } } Loading packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt→packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -19,41 +19,32 @@ package com.android.credentialmanager.jetpack.developer import android.os.Bundle /** * Base request class for getting a registered public key credential. * Base custom create request class for registering a credential. * * @property requestJson the request in JSON format * @throws NullPointerException If [requestJson] is null - auto handled by the * Kotlin runtime * @throws IllegalArgumentException If [requestJson] is empty * An application can construct a subtype custom request and call * [CredentialManager.executeCreateCredential] to launch framework UI flows to collect consent and * any other metadata needed from the user to register a new user credential. * * @hide * @property type the credential type determined by the credential-type-specific subclass for custom * use cases * @property credentialData the full credential creation request data in the [Bundle] format for * custom use cases * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to * the provider during the initial candidate query stage, which should not contain sensitive user * credential information * @property requireSystemProvider true if must only be fulfilled by a system provider and false * otherwise * @throws IllegalArgumentException If [type] is empty * @throws NullPointerException If [type] or [credentialData] are null */ abstract class GetPublicKeyCredentialBaseOption constructor( val requestJson: String, type: String, data: Bundle, requireSystemProvider: Boolean, ) : GetCredentialOption(type, data, requireSystemProvider) { open class CreateCustomCredentialRequest( final override val type: String, final override val credentialData: Bundle, final override val candidateQueryData: Bundle, @get:JvmName("requireSystemProvider") final override val requireSystemProvider: Boolean ) : CreateCredentialRequest(type, credentialData, candidateQueryData, requireSystemProvider) { init { require(requestJson.isNotEmpty()) { "request json must not be empty" } } companion object { const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON" const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE" @JvmStatic fun createFrom(data: Bundle): GetPublicKeyCredentialBaseOption { return when (data.getString(BUNDLE_KEY_SUBTYPE)) { GetPublicKeyCredentialOption .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION -> GetPublicKeyCredentialOption.createFrom(data) GetPublicKeyCredentialOptionPrivileged .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED -> GetPublicKeyCredentialOptionPrivileged.createFrom(data) else -> throw FrameworkClassParsingException() } } require(type.isNotEmpty()) { "type should not be empty" } } } No newline at end of file packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt +14 −5 Original line number Diff line number Diff line Loading @@ -32,9 +32,11 @@ class CreatePasswordRequest constructor( val id: String, val password: String, ) : CreateCredentialRequest( Credential.TYPE_PASSWORD_CREDENTIAL, toBundle(id, password), false, type = Credential.TYPE_PASSWORD_CREDENTIAL, credentialData = toCredentialDataBundle(id, password), // No credential data should be sent during the query phase. candidateQueryData = Bundle(), requireSystemProvider = false, ) { init { Loading @@ -46,7 +48,7 @@ class CreatePasswordRequest constructor( const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD" @JvmStatic internal fun toBundle(id: String, password: String): Bundle { internal fun toCredentialDataBundle(id: String, password: String): Bundle { val bundle = Bundle() bundle.putString(BUNDLE_KEY_ID, id) bundle.putString(BUNDLE_KEY_PASSWORD, password) Loading @@ -54,7 +56,14 @@ class CreatePasswordRequest constructor( } @JvmStatic fun createFrom(data: Bundle): CreatePasswordRequest { internal fun toCandidateDataBundle(id: String): Bundle { val bundle = Bundle() bundle.putString(BUNDLE_KEY_ID, id) return bundle } @JvmStatic internal fun createFrom(data: Bundle): CreatePasswordRequest { try { val id = data.getString(BUNDLE_KEY_ID) val password = data.getString(BUNDLE_KEY_PASSWORD) Loading Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +5 −5 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ import com.android.credentialmanager.createflow.DisabledProviderInfo import com.android.credentialmanager.createflow.EnabledProviderInfo import com.android.credentialmanager.createflow.RequestDisplayInfo import com.android.credentialmanager.getflow.GetCredentialUiState import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toBundle import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toCredentialDataBundle import com.android.credentialmanager.jetpack.developer.CreatePublicKeyCredentialRequest import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL import com.android.credentialmanager.jetpack.provider.Action Loading Loading @@ -325,7 +325,7 @@ class CredentialManagerRepo( key, subkey, CredentialEntry.toSlice(credentialEntry), null Intent() ) } Loading @@ -348,7 +348,7 @@ class CredentialManagerRepo( android.service.credentials.CallingAppInfo( context.applicationInfo.packageName, SigningInfo()), TYPE_PASSWORD_CREDENTIAL, toBundle("beckett-bakert@gmail.com", "password123") toCredentialDataBundle("beckett-bakert@gmail.com", "password123") ) val fillInIntent = Intent().putExtra( CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST, Loading Loading @@ -417,7 +417,7 @@ class CredentialManagerRepo( " \"residentKey\": \"required\",\n" + " \"requireResidentKey\": true\n" + " }}") val credentialData = request.data val credentialData = request.credentialData return RequestInfo.newCreateRequestInfo( Binder(), CreateCredentialRequest( Loading @@ -432,7 +432,7 @@ class CredentialManagerRepo( } private fun testCreatePasswordRequestInfo(): RequestInfo { val data = toBundle("beckett-bakert@gmail.com", "password123") val data = toCredentialDataBundle("beckett-bakert@gmail.com", "password123") return RequestInfo.newCreateRequestInfo( Binder(), CreateCredentialRequest( Loading
packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt +2 −2 Original line number Diff line number Diff line Loading @@ -242,7 +242,7 @@ class CreateFlowUtils { packageName = it.providerFlattenedComponentName } val pkgInfo = packageManager .getPackageInfo(packageName, .getPackageInfo(packageName!!, PackageManager.PackageInfoFlags.of(0)) DisabledProviderInfo( icon = pkgInfo.applicationInfo.loadIcon(packageManager)!!, Loading @@ -264,7 +264,7 @@ class CreateFlowUtils { val createCredentialRequest = requestInfo.createCredentialRequest val createCredentialRequestJetpack = createCredentialRequest?.let { CreateCredentialRequest.createFrom( it it.type, it.credentialData, it.candidateQueryData, it.requireSystemProvider() ) } when (createCredentialRequestJetpack) { Loading
packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt +31 −13 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.credentialmanager.jetpack.developer import android.credentials.Credential import android.os.Bundle import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE /** * Base request class for registering a credential. Loading @@ -28,27 +29,44 @@ import android.os.Bundle * otherwise */ open class CreateCredentialRequest( val type: String, val data: Bundle, val requireSystemProvider: Boolean, open val type: String, open val credentialData: Bundle, open val candidateQueryData: Bundle, open val requireSystemProvider: Boolean ) { companion object { @JvmStatic fun createFrom(from: android.credentials.CreateCredentialRequest): CreateCredentialRequest { fun createFrom( type: String, credentialData: Bundle, candidateQueryData: Bundle, requireSystemProvider: Boolean ): CreateCredentialRequest { return try { when (from.type) { when (type) { Credential.TYPE_PASSWORD_CREDENTIAL -> CreatePasswordRequest.createFrom(from.credentialData) CreatePasswordRequest.createFrom(credentialData) PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> CreatePublicKeyCredentialBaseRequest.createFrom(from.credentialData) else -> CreateCredentialRequest( from.type, from.credentialData, from.requireSystemProvider() ) when (credentialData.getString(BUNDLE_KEY_SUBTYPE)) { CreatePublicKeyCredentialRequest .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST -> CreatePublicKeyCredentialRequest.createFrom(credentialData) CreatePublicKeyCredentialRequestPrivileged .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV -> CreatePublicKeyCredentialRequestPrivileged .createFrom(credentialData) else -> throw FrameworkClassParsingException() } else -> throw FrameworkClassParsingException() } } catch (e: FrameworkClassParsingException) { CreateCredentialRequest( from.type, from.credentialData, from.requireSystemProvider() // Parsing failed but don't crash the process. Instead just output a request with // the raw framework values. CreateCustomCredentialRequest( type, credentialData, candidateQueryData, requireSystemProvider ) } } Loading
packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt→packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -19,41 +19,32 @@ package com.android.credentialmanager.jetpack.developer import android.os.Bundle /** * Base request class for getting a registered public key credential. * Base custom create request class for registering a credential. * * @property requestJson the request in JSON format * @throws NullPointerException If [requestJson] is null - auto handled by the * Kotlin runtime * @throws IllegalArgumentException If [requestJson] is empty * An application can construct a subtype custom request and call * [CredentialManager.executeCreateCredential] to launch framework UI flows to collect consent and * any other metadata needed from the user to register a new user credential. * * @hide * @property type the credential type determined by the credential-type-specific subclass for custom * use cases * @property credentialData the full credential creation request data in the [Bundle] format for * custom use cases * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to * the provider during the initial candidate query stage, which should not contain sensitive user * credential information * @property requireSystemProvider true if must only be fulfilled by a system provider and false * otherwise * @throws IllegalArgumentException If [type] is empty * @throws NullPointerException If [type] or [credentialData] are null */ abstract class GetPublicKeyCredentialBaseOption constructor( val requestJson: String, type: String, data: Bundle, requireSystemProvider: Boolean, ) : GetCredentialOption(type, data, requireSystemProvider) { open class CreateCustomCredentialRequest( final override val type: String, final override val credentialData: Bundle, final override val candidateQueryData: Bundle, @get:JvmName("requireSystemProvider") final override val requireSystemProvider: Boolean ) : CreateCredentialRequest(type, credentialData, candidateQueryData, requireSystemProvider) { init { require(requestJson.isNotEmpty()) { "request json must not be empty" } } companion object { const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON" const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE" @JvmStatic fun createFrom(data: Bundle): GetPublicKeyCredentialBaseOption { return when (data.getString(BUNDLE_KEY_SUBTYPE)) { GetPublicKeyCredentialOption .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION -> GetPublicKeyCredentialOption.createFrom(data) GetPublicKeyCredentialOptionPrivileged .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED -> GetPublicKeyCredentialOptionPrivileged.createFrom(data) else -> throw FrameworkClassParsingException() } } require(type.isNotEmpty()) { "type should not be empty" } } } No newline at end of file
packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt +14 −5 Original line number Diff line number Diff line Loading @@ -32,9 +32,11 @@ class CreatePasswordRequest constructor( val id: String, val password: String, ) : CreateCredentialRequest( Credential.TYPE_PASSWORD_CREDENTIAL, toBundle(id, password), false, type = Credential.TYPE_PASSWORD_CREDENTIAL, credentialData = toCredentialDataBundle(id, password), // No credential data should be sent during the query phase. candidateQueryData = Bundle(), requireSystemProvider = false, ) { init { Loading @@ -46,7 +48,7 @@ class CreatePasswordRequest constructor( const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD" @JvmStatic internal fun toBundle(id: String, password: String): Bundle { internal fun toCredentialDataBundle(id: String, password: String): Bundle { val bundle = Bundle() bundle.putString(BUNDLE_KEY_ID, id) bundle.putString(BUNDLE_KEY_PASSWORD, password) Loading @@ -54,7 +56,14 @@ class CreatePasswordRequest constructor( } @JvmStatic fun createFrom(data: Bundle): CreatePasswordRequest { internal fun toCandidateDataBundle(id: String): Bundle { val bundle = Bundle() bundle.putString(BUNDLE_KEY_ID, id) return bundle } @JvmStatic internal fun createFrom(data: Bundle): CreatePasswordRequest { try { val id = data.getString(BUNDLE_KEY_ID) val password = data.getString(BUNDLE_KEY_PASSWORD) Loading