mirror of
https://github.com/microg/GmsCore
synced 2026-08-06 12:26:08 -04:00
Identity: Add IdentityCredentialApiService dummy (#3484)
Co-authored-by: Marvin W <git@larma.de>
This commit is contained in:
parent
67c1bb7501
commit
4e8200a1ea
89 changed files with 4117 additions and 61 deletions
|
|
@ -73,7 +73,7 @@ def execResult(... args) {
|
|||
}
|
||||
|
||||
def ignoreGit = providers.environmentVariable('GRADLE_MICROG_VERSION_WITHOUT_GIT').getOrElse('0') == '1'
|
||||
def gmsVersion = "25.09.32"
|
||||
def gmsVersion = "25.24.32"
|
||||
def gmsVersionCode = Integer.parseInt(gmsVersion.replaceAll('\\.', ''))
|
||||
def vendingVersion = "40.2.26"
|
||||
def vendingVersionCode = Integer.parseInt(vendingVersion.replaceAll('\\.', ''))
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ public enum GmsService {
|
|||
GOOGLESETTINGS(349),
|
||||
HTTPFLAGS(350),
|
||||
SETUP_SERVICES_REMOTE_SETUP(351),
|
||||
IDENTITY_CREDENTIALS(352),
|
||||
IDENTITY_CREDENTIALS(352, "com.google.android.gms.identitycredentials.service.START"),
|
||||
AMBIENT_CONTEXT(353),
|
||||
SAFE_BROWSING(354),
|
||||
MULTIDEVICE_API_FEATURE_SETTINGS(355),
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ dependencies {
|
|||
implementation project(':play-services-fido-core')
|
||||
implementation project(':play-services-fitness-core')
|
||||
implementation project(':play-services-gmscompliance-core')
|
||||
implementation project(':play-services-identity-credentials-core')
|
||||
implementation project(':play-services-location-core')
|
||||
implementation project(':play-services-location-core-base')
|
||||
implementation project(':play-services-oss-licenses-core')
|
||||
|
|
|
|||
|
|
@ -649,6 +649,13 @@
|
|||
android:theme="@style/Theme.App.Translucent"
|
||||
android:excludeFromRecents="true"/>
|
||||
|
||||
<activity
|
||||
android:name="org.microg.gms.auth.credentials.identity.IdentityCredentialChooserActivity"
|
||||
android:exported="false"
|
||||
android:process=":ui"
|
||||
android:theme="@style/Theme.App.Translucent"
|
||||
android:excludeFromRecents="true"/>
|
||||
|
||||
<activity
|
||||
android:theme="@style/Theme.AppCompat.Dialog.Alert"
|
||||
android:name="org.microg.gms.auth.signin.AssistedSignInActivity"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.auth.credentials
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer
|
||||
import org.microg.gms.auth.signin.ACTION_ASSISTED_SIGN_IN
|
||||
import org.microg.gms.auth.signin.CLIENT_PACKAGE_NAME
|
||||
import org.microg.gms.auth.signin.GOOGLE_SIGN_IN_OPTIONS
|
||||
import org.microg.gms.common.GmsService
|
||||
import org.microg.gms.fido.core.ui.ACTION_FIDO_AUTHENTICATE
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_CALLER
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_CREDENTIAL_ID
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_OPTIONS
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_SERVICE
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_SOURCE
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_TYPE
|
||||
|
||||
fun Context.buildFidoAuthenticateIntent(
|
||||
source: String,
|
||||
optionsBytes: ByteArray,
|
||||
callingPackage: String?,
|
||||
type: String,
|
||||
credentialIdString: String? = null,
|
||||
): Intent = Intent(ACTION_FIDO_AUTHENTICATE).apply {
|
||||
`package` = packageName
|
||||
putExtra(KEY_SERVICE, GmsService.FIDO2_API.SERVICE_ID)
|
||||
putExtra(KEY_SOURCE, source)
|
||||
putExtra(KEY_TYPE, type)
|
||||
putExtra(KEY_OPTIONS, optionsBytes)
|
||||
callingPackage?.let { putExtra(KEY_CALLER, it) }
|
||||
credentialIdString?.let { putExtra(KEY_CREDENTIAL_ID, it) }
|
||||
}
|
||||
|
||||
fun Context.buildAssistedSignInIntent(
|
||||
requestExtraKey: String,
|
||||
serializedRequest: ByteArray,
|
||||
googleSignInOptions: GoogleSignInOptions,
|
||||
callingPackage: String?,
|
||||
): Intent = Intent(ACTION_ASSISTED_SIGN_IN).apply {
|
||||
`package` = packageName
|
||||
putExtra(requestExtraKey, serializedRequest)
|
||||
putExtra(GOOGLE_SIGN_IN_OPTIONS, SafeParcelableSerializer.serializeToBytes(googleSignInOptions))
|
||||
callingPackage?.let { putExtra(CLIENT_PACKAGE_NAME, it) }
|
||||
}
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.auth.credentials.identity
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.BundleCompat
|
||||
import androidx.credentials.PasswordCredential
|
||||
import androidx.credentials.PublicKeyCredential
|
||||
import androidx.credentials.exceptions.CreateCredentialNoCreateOptionException
|
||||
import androidx.credentials.exceptions.CreateCredentialUnknownException
|
||||
import androidx.credentials.exceptions.GetCredentialCancellationException
|
||||
import androidx.credentials.exceptions.GetCredentialUnknownException
|
||||
import androidx.credentials.exceptions.NoCredentialException
|
||||
import com.google.android.gms.auth.api.identity.BeginSignInRequest
|
||||
import com.google.android.gms.auth.api.identity.SignInCredential
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer
|
||||
import com.google.android.gms.fido.Fido.FIDO2_KEY_CREDENTIAL_EXTRA
|
||||
import com.google.android.gms.fido.fido2.api.common.AuthenticatorErrorResponse
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialRequest
|
||||
import com.google.android.gms.identitycredentials.CredentialOption
|
||||
import com.google.android.gms.identitycredentials.GetCredentialRequest
|
||||
import org.json.JSONObject
|
||||
import org.microg.gms.auth.AuthConstants
|
||||
import org.microg.gms.auth.credentials.buildAssistedSignInIntent
|
||||
import org.microg.gms.auth.credentials.buildFidoAuthenticateIntent
|
||||
import org.microg.gms.identitycredentials.EXTRA_CALLING_PACKAGE
|
||||
import org.microg.gms.identitycredentials.EXTRA_CREATE_REQUEST
|
||||
import org.microg.gms.identitycredentials.EXTRA_GET_REQUEST
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_ANDROIDX_AUTO_SELECT
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_BUNDLE_KEY_DISPLAY_NAME
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_BUNDLE_KEY_FAMILY_NAME
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_BUNDLE_KEY_GIVEN_NAME
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_BUNDLE_KEY_ID
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_BUNDLE_KEY_ID_TOKEN
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_BUNDLE_KEY_PROFILE_PICTURE_URI
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_FILTER_BY_AUTHORIZED_ACCOUNTS
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_NONCE
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_SERVER_CLIENT_ID
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_SIWG_NONCE
|
||||
import org.microg.gms.auth.credentials.provider.GOOGLE_ID_SIWG_SERVER_CLIENT_ID
|
||||
import org.microg.gms.auth.credentials.provider.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
|
||||
import org.microg.gms.auth.credentials.provider.parsePublicKeyCredentialCreationOptions
|
||||
import org.microg.gms.auth.credentials.provider.parsePublicKeyCredentialRequestOptions
|
||||
import org.microg.gms.auth.credentials.provider.toJson
|
||||
import org.microg.gms.auth.signin.BEGIN_SIGN_IN_REQUEST
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.SOURCE_APP
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.TYPE_REGISTER
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.TYPE_SIGN
|
||||
|
||||
private const val TAG = "IdentityCredChooser"
|
||||
|
||||
class IdentityCredentialChooserActivity : AppCompatActivity() {
|
||||
|
||||
private var callingPackage: String = ""
|
||||
private var isCreatePath = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
callingPackage = intent.getStringExtra(EXTRA_CALLING_PACKAGE).orEmpty()
|
||||
runCatching {
|
||||
val getReq: GetCredentialRequest? = readNestedParcelable(EXTRA_GET_REQUEST, GetCredentialRequest::class.java)
|
||||
val createReq: CreateCredentialRequest? = readNestedParcelable(EXTRA_CREATE_REQUEST, CreateCredentialRequest::class.java)
|
||||
when {
|
||||
getReq != null -> {
|
||||
isCreatePath = false
|
||||
Log.d(TAG, "onCreate get pkg=$callingPackage options=${getReq.credentialOptions.size}")
|
||||
routeGet(getReq)
|
||||
}
|
||||
createReq != null -> {
|
||||
isCreatePath = true
|
||||
Log.d(TAG, "onCreate create pkg=$callingPackage type=${createReq.type} origin=${createReq.origin}")
|
||||
routeCreate(createReq)
|
||||
}
|
||||
else -> finishWithGetException(GetCredentialUnknownException("Missing request payload"))
|
||||
}
|
||||
}.onFailure { e ->
|
||||
Log.e(TAG, "onCreate parse failed", e)
|
||||
if (isCreatePath) finishWithCreateException(CreateCredentialUnknownException(e.message ?: "Internal error"))
|
||||
else finishWithGetException(GetCredentialUnknownException(e.message ?: "Internal error"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun routeGet(req: GetCredentialRequest) {
|
||||
val option = req.credentialOptions.firstOrNull()
|
||||
?: return finishWithGetException(NoCredentialException("No credential options requested"))
|
||||
when (option.type) {
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> startPasskeyGet(option)
|
||||
TYPE_GOOGLE_ID_TOKEN_CREDENTIAL -> startGoogleSignIn(option)
|
||||
PasswordCredential.TYPE_PASSWORD_CREDENTIAL ->
|
||||
finishWithGetException(NoCredentialException("Password credentials are not stored"))
|
||||
else -> finishWithGetException(NoCredentialException("Unsupported type: ${option.type}"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun routeCreate(req: CreateCredentialRequest) {
|
||||
Log.d(TAG, "routeCreate type=${req.type} pkg=$callingPackage")
|
||||
when (req.type) {
|
||||
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> startPasskeyCreate(req)
|
||||
else -> finishWithCreateException(CreateCredentialNoCreateOptionException("Unsupported create type: ${req.type}"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun startPasskeyGet(option: CredentialOption) {
|
||||
val data = option.credentialRetrievalData
|
||||
val requestJson = data?.getString(PUBKEY_REQ_JSON_KEY)
|
||||
?: return finishWithGetException(NoCredentialException("Passkey request missing requestJson"))
|
||||
val pkOptions = runCatching {
|
||||
JSONObject(requestJson).parsePublicKeyCredentialRequestOptions()
|
||||
}.getOrElse {
|
||||
Log.e(TAG, "Passkey JSON parse failed", it)
|
||||
return finishWithGetException(GetCredentialUnknownException("Invalid passkey requestJson"))
|
||||
}
|
||||
val fidoIntent = buildFidoAuthenticateIntent(SOURCE_APP, pkOptions.serializeToBytes(), callingPackage, TYPE_SIGN)
|
||||
startActivityForResult(fidoIntent, REQ_CODE_FIDO)
|
||||
}
|
||||
|
||||
private fun startPasskeyCreate(req: CreateCredentialRequest) {
|
||||
val requestJson = req.requestJson ?: req.credentialData.getString(PUBKEY_REQ_JSON_KEY)
|
||||
if (requestJson.isNullOrBlank()) {
|
||||
return finishWithCreateException(CreateCredentialUnknownException("Passkey create missing requestJson"))
|
||||
}
|
||||
val pkOptions = runCatching {
|
||||
JSONObject(requestJson).parsePublicKeyCredentialCreationOptions()
|
||||
}.getOrElse {
|
||||
Log.e(TAG, "Passkey create JSON parse failed", it)
|
||||
return finishWithCreateException(CreateCredentialUnknownException("Invalid passkey requestJson"))
|
||||
}
|
||||
val fidoIntent = buildFidoAuthenticateIntent(SOURCE_APP, pkOptions.serializeToBytes(), callingPackage, TYPE_REGISTER)
|
||||
startActivityForResult(fidoIntent, REQ_CODE_FIDO)
|
||||
}
|
||||
|
||||
private fun startGoogleSignIn(option: CredentialOption) {
|
||||
val data = option.credentialRetrievalData ?: Bundle()
|
||||
val serverClientId = (data.getString(GOOGLE_ID_SERVER_CLIENT_ID) ?: data.getString(GOOGLE_ID_SIWG_SERVER_CLIENT_ID)).orEmpty()
|
||||
if (serverClientId.isBlank()) {
|
||||
return finishWithGetException(NoCredentialException("GoogleIdToken option missing serverClientId"))
|
||||
}
|
||||
val nonce = data.getString(GOOGLE_ID_NONCE) ?: data.getString(GOOGLE_ID_SIWG_NONCE)
|
||||
val filterByAuthorized = data.getBoolean(GOOGLE_ID_FILTER_BY_AUTHORIZED_ACCOUNTS, false)
|
||||
val autoSelect = data.getBoolean(GOOGLE_ID_ANDROIDX_AUTO_SELECT, false)
|
||||
|
||||
val signInRequest = BeginSignInRequest.Builder()
|
||||
.setGoogleIdTokenRequestOptions(
|
||||
BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
|
||||
.setSupported(true)
|
||||
.setServerClientId(serverClientId)
|
||||
.setFilterByAuthorizedAccounts(filterByAuthorized)
|
||||
.apply { nonce?.let { setNonce(it) } }
|
||||
.build()
|
||||
)
|
||||
.setAutoSelectEnabled(autoSelect)
|
||||
.build()
|
||||
|
||||
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestEmail()
|
||||
.requestIdToken(serverClientId)
|
||||
.build()
|
||||
|
||||
val signInIntent = buildAssistedSignInIntent(
|
||||
requestExtraKey = BEGIN_SIGN_IN_REQUEST,
|
||||
serializedRequest = SafeParcelableSerializer.serializeToBytes(signInRequest),
|
||||
googleSignInOptions = gso,
|
||||
callingPackage = callingPackage
|
||||
)
|
||||
startActivityForResult(signInIntent, REQ_CODE_SIGN_IN)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
Log.d(TAG, "onActivityResult: requestCode: $requestCode resultCode: $resultCode")
|
||||
when (requestCode) {
|
||||
REQ_CODE_FIDO -> handleFidoResult(resultCode, data)
|
||||
REQ_CODE_SIGN_IN -> handleSignInResult(resultCode, data)
|
||||
else -> finishWithGetException(GetCredentialUnknownException("Unexpected requestCode=$requestCode"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleFidoResult(resultCode: Int, data: Intent?) {
|
||||
Log.d(TAG, "handleFidoResult: data: $data")
|
||||
if (resultCode != RESULT_OK || data == null) {
|
||||
return if (isCreatePath) finishWithCreateException(CreateCredentialUnknownException("Passkey flow canceled"))
|
||||
else finishWithGetException(GetCredentialCancellationException("Passkey flow canceled"))
|
||||
}
|
||||
runCatching {
|
||||
val credentialBytes = data.getByteArrayExtra(FIDO2_KEY_CREDENTIAL_EXTRA)
|
||||
?: throw IllegalStateException("FIDO returned no credential")
|
||||
val publicKeyCredential = com.google.android.gms.fido.fido2.api.common.PublicKeyCredential
|
||||
.deserializeFromBytes(credentialBytes)
|
||||
(publicKeyCredential.response as? AuthenticatorErrorResponse)?.let { err ->
|
||||
throw IllegalStateException(err.errorMessage ?: err.errorCode.toString())
|
||||
}
|
||||
val json = publicKeyCredential.toJson()
|
||||
val credData = Bundle().apply {
|
||||
putString(if (isCreatePath) PUBKEY_RES_REG_JSON_KEY else PUBKEY_RES_AUTH_JSON_KEY, json)
|
||||
}
|
||||
Log.d(TAG, "handleFidoResult: $credData")
|
||||
finishWithCredential(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL, credData)
|
||||
}.onFailure { e ->
|
||||
Log.e(TAG, "handleFidoResult failed", e)
|
||||
val msg = e.message ?: "FIDO result error"
|
||||
if (isCreatePath) finishWithCreateException(CreateCredentialUnknownException(msg))
|
||||
else finishWithGetException(GetCredentialUnknownException(msg))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSignInResult(resultCode: Int, data: Intent?) {
|
||||
if (resultCode != RESULT_OK || data == null) {
|
||||
return finishWithGetException(GetCredentialCancellationException("Sign-in canceled"))
|
||||
}
|
||||
runCatching {
|
||||
val bytes = data.getByteArrayExtra(AuthConstants.SIGN_IN_CREDENTIAL)
|
||||
?: throw IllegalStateException("Sign-in result missing credential")
|
||||
val credential = SafeParcelableSerializer.deserializeFromBytes(bytes, SignInCredential.CREATOR)
|
||||
val credData = Bundle().apply {
|
||||
putString(GOOGLE_ID_BUNDLE_KEY_ID, credential.id)
|
||||
credential.googleIdToken?.let { putString(GOOGLE_ID_BUNDLE_KEY_ID_TOKEN, it) }
|
||||
credential.displayName?.let { putString(GOOGLE_ID_BUNDLE_KEY_DISPLAY_NAME, it) }
|
||||
credential.givenName?.let { putString(GOOGLE_ID_BUNDLE_KEY_GIVEN_NAME, it) }
|
||||
credential.familyName?.let { putString(GOOGLE_ID_BUNDLE_KEY_FAMILY_NAME, it) }
|
||||
credential.profilePictureUri?.let { putString(GOOGLE_ID_BUNDLE_KEY_PROFILE_PICTURE_URI, it.toString()) }
|
||||
}
|
||||
finishWithCredential(TYPE_GOOGLE_ID_TOKEN_CREDENTIAL, credData)
|
||||
}.onFailure { e ->
|
||||
Log.e(TAG, "handleSignInResult failed", e)
|
||||
finishWithGetException(GetCredentialUnknownException(e.message ?: "Sign-in result error"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun finishWithCredential(type: String, credentialData: Bundle) {
|
||||
val responseBundle = Bundle().apply {
|
||||
if (isCreatePath) {
|
||||
putString(PROVIDER_EXTRA_CREATE_RESPONSE_TYPE, type)
|
||||
putBundle(PROVIDER_EXTRA_CREATE_REQUEST_DATA, credentialData)
|
||||
} else {
|
||||
putString(PROVIDER_EXTRA_CREDENTIAL_TYPE, type)
|
||||
putBundle(PROVIDER_EXTRA_CREDENTIAL_DATA, credentialData)
|
||||
}
|
||||
}
|
||||
val extraKey = if (isCreatePath) EXTRA_CREATE_RESPONSE_BUNDLE else EXTRA_GET_RESPONSE_BUNDLE
|
||||
Log.d(TAG, "finishWithCredential: extraKey: $extraKey responseBundle: $responseBundle")
|
||||
setResult(RESULT_OK, Intent().putExtra(extraKey, responseBundle))
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun finishWithGetException(e: androidx.credentials.exceptions.GetCredentialException) {
|
||||
finishWithExceptionBundle(EXTRA_GET_EXCEPTION_BUNDLE, e.type, e.message ?: e.javaClass.simpleName)
|
||||
}
|
||||
|
||||
private fun finishWithCreateException(e: androidx.credentials.exceptions.CreateCredentialException) {
|
||||
finishWithExceptionBundle(EXTRA_CREATE_EXCEPTION_BUNDLE, e.type, e.message ?: e.javaClass.simpleName)
|
||||
}
|
||||
|
||||
private fun finishWithExceptionBundle(extraKey: String, type: String, message: String) {
|
||||
val bundle = Bundle().apply {
|
||||
putString(PROVIDER_EXTRA_EXCEPTION_TYPE, type)
|
||||
putString(PROVIDER_EXTRA_EXCEPTION_MESSAGE, message)
|
||||
}
|
||||
setResult(RESULT_OK, Intent().putExtra(extraKey, bundle))
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun <T : Parcelable> readNestedParcelable(name: String, clazz: Class<T>): T? =
|
||||
intent.getBundleExtra(name)?.let { bundle ->
|
||||
bundle.classLoader = clazz.classLoader
|
||||
BundleCompat.getParcelable(bundle, name, clazz)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQ_CODE_FIDO = 0x1001
|
||||
private const val REQ_CODE_SIGN_IN = 0x1002
|
||||
|
||||
private const val EXTRA_GET_RESPONSE_BUNDLE = "android.service.credentials.extra.GET_CREDENTIAL_RESPONSE"
|
||||
private const val EXTRA_GET_EXCEPTION_BUNDLE = "android.service.credentials.extra.GET_CREDENTIAL_EXCEPTION"
|
||||
private const val EXTRA_CREATE_RESPONSE_BUNDLE = "android.service.credentials.extra.CREATE_CREDENTIAL_RESPONSE"
|
||||
private const val EXTRA_CREATE_EXCEPTION_BUNDLE = "android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION"
|
||||
private const val PROVIDER_EXTRA_CREDENTIAL_TYPE = "androidx.credentials.provider.extra.EXTRA_CREDENTIAL_TYPE"
|
||||
private const val PROVIDER_EXTRA_CREDENTIAL_DATA = "androidx.credentials.provider.extra.EXTRA_CREDENTIAL_DATA"
|
||||
private const val PROVIDER_EXTRA_CREATE_RESPONSE_TYPE = "androidx.credentials.provider.extra.CREATE_CREDENTIAL_RESPONSE_TYPE"
|
||||
private const val PROVIDER_EXTRA_CREATE_REQUEST_DATA = "androidx.credentials.provider.extra.CREATE_CREDENTIAL_REQUEST_DATA"
|
||||
private const val PROVIDER_EXTRA_EXCEPTION_TYPE = "androidx.credentials.provider.extra.CREATE_CREDENTIAL_EXCEPTION_TYPE"
|
||||
private const val PROVIDER_EXTRA_EXCEPTION_MESSAGE = "androidx.credentials.provider.extra.CREATE_CREDENTIAL_EXCEPTION_MESSAGE"
|
||||
|
||||
private const val PUBKEY_REQ_JSON_KEY = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
|
||||
private const val PUBKEY_RES_AUTH_JSON_KEY = "androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"
|
||||
private const val PUBKEY_RES_REG_JSON_KEY = "androidx.credentials.BUNDLE_KEY_REGISTRATION_RESPONSE_JSON"
|
||||
}
|
||||
}
|
||||
|
|
@ -172,6 +172,7 @@ const val GOOGLE_ID_BUNDLE_KEY_GIVEN_NAME = "com.google.android.libraries.identi
|
|||
const val GOOGLE_ID_BUNDLE_KEY_FAMILY_NAME = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_FAMILY_NAME"
|
||||
const val GOOGLE_ID_BUNDLE_KEY_PHONE_NUMBER = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_PHONE_NUMBER"
|
||||
const val GOOGLE_ID_BUNDLE_KEY_PROFILE_PICTURE_URI = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_PROFILE_PICTURE_URI"
|
||||
const val GOOGLE_ID_FILTER_BY_AUTHORIZED_ACCOUNTS = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_FILTER_BY_AUTHORIZED_ACCOUNTS"
|
||||
|
||||
// Credential types
|
||||
const val TYPE_GOOGLE_ID_TOKEN_CREDENTIAL = "com.google.android.libraries.identity.googleid.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL"
|
||||
|
|
|
|||
|
|
@ -18,14 +18,8 @@ import androidx.credentials.provider.ProviderGetCredentialRequest
|
|||
import com.google.android.gms.fido.Fido.FIDO2_KEY_CREDENTIAL_EXTRA
|
||||
import com.google.android.gms.fido.fido2.api.common.*
|
||||
import org.json.JSONObject
|
||||
import org.microg.gms.common.GmsService
|
||||
import org.microg.gms.fido.core.ui.ACTION_FIDO_AUTHENTICATE
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_CALLER
|
||||
import org.microg.gms.auth.credentials.buildFidoAuthenticateIntent
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_CREDENTIAL_ID
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_OPTIONS
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_SERVICE
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_SOURCE
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.KEY_TYPE
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.SOURCE_APP
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.SOURCE_BROWSER
|
||||
import org.microg.gms.fido.core.ui.AuthenticatorActivity.Companion.TYPE_REGISTER
|
||||
|
|
@ -50,7 +44,7 @@ class PublicKeyProxyActivity : CredentialProviderActivity() {
|
|||
val credentialIdString = intent.getStringExtra(KEY_CREDENTIAL_ID)
|
||||
|
||||
val (optionsBytes, source) = buildRequestOptions(options, isBrowserRequest, request.callingAppInfo.origin, option.clientDataHash)
|
||||
val fidoIntent = createFidoIntent(source, optionsBytes, request.callingAppInfo.packageName, TYPE_SIGN, credentialIdString)
|
||||
val fidoIntent = buildFidoAuthenticateIntent(source, optionsBytes, request.callingAppInfo.packageName, TYPE_SIGN, credentialIdString)
|
||||
startActivityForResult(fidoIntent, REQUEST_CODE_FIDO)
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +70,7 @@ class PublicKeyProxyActivity : CredentialProviderActivity() {
|
|||
Log.d(TAG, "handlePasskeyCreate: options: $options")
|
||||
|
||||
val (optionsBytes, source) = buildCreationOptions(options, isBrowserRequest, origin, publicKeyRequest.clientDataHash)
|
||||
val fidoIntent = createFidoIntent(source, optionsBytes, callingPackage, TYPE_REGISTER)
|
||||
val fidoIntent = buildFidoAuthenticateIntent(source, optionsBytes, callingPackage, TYPE_REGISTER)
|
||||
|
||||
startActivityForResult(fidoIntent, REQUEST_CODE_FIDO)
|
||||
Log.d(TAG, "Launched FIDO authenticator by PasskeyCreate")
|
||||
|
|
@ -118,19 +112,6 @@ class PublicKeyProxyActivity : CredentialProviderActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
fun createFidoIntent(
|
||||
source: String, optionsBytes: ByteArray, callingPackage: String, type: String, credentialIdString: String? = null
|
||||
): Intent = Intent(ACTION_FIDO_AUTHENTICATE).apply {
|
||||
`package` = packageName
|
||||
putExtra(KEY_SERVICE, GmsService.FIDO2_API.SERVICE_ID)
|
||||
putExtra(KEY_SOURCE, source)
|
||||
putExtra(KEY_TYPE, type)
|
||||
putExtra(KEY_OPTIONS, optionsBytes)
|
||||
putExtra(KEY_CALLER, callingPackage)
|
||||
credentialIdString?.let { putExtra(KEY_CREDENTIAL_ID, it) }
|
||||
}
|
||||
|
||||
|
||||
private fun handleFidoSuccess(publicKeyCredential: PublicKeyCredential) = runCatching {
|
||||
when (val response = publicKeyCredential.response) {
|
||||
is AuthenticatorAttestationResponse -> {
|
||||
|
|
|
|||
|
|
@ -20,10 +20,8 @@ import com.google.android.gms.auth.api.identity.SignInCredential
|
|||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer
|
||||
import org.microg.gms.auth.AuthConstants
|
||||
import org.microg.gms.auth.signin.ACTION_ASSISTED_SIGN_IN
|
||||
import org.microg.gms.auth.signin.CLIENT_PACKAGE_NAME
|
||||
import org.microg.gms.auth.credentials.buildAssistedSignInIntent
|
||||
import org.microg.gms.auth.signin.GET_SIGN_IN_INTENT_REQUEST
|
||||
import org.microg.gms.auth.signin.GOOGLE_SIGN_IN_OPTIONS
|
||||
|
||||
private const val TAG = "SignInProxyActivity"
|
||||
private const val REQUEST_CODE_SIGN_IN = 100
|
||||
|
|
@ -32,31 +30,23 @@ private const val REQUEST_CODE_SIGN_IN = 100
|
|||
class SignInProxyActivity : CredentialProviderActivity() {
|
||||
|
||||
override fun onProviderGetCredentialRequest(request: ProviderGetCredentialRequest) {
|
||||
val bundle = Bundle().apply {
|
||||
val signInRequest = GetSignInIntentRequest.builder()
|
||||
.setServerClientId(intent.getStringExtra(GOOGLE_ID_SIWG_SERVER_CLIENT_ID) ?: "")
|
||||
.apply {
|
||||
intent.getStringExtra(GOOGLE_ID_SIWG_NONCE)?.let { setNonce(it) }
|
||||
}
|
||||
.build()
|
||||
|
||||
val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestEmail()
|
||||
.requestIdToken(intent.getStringExtra(GOOGLE_ID_SIWG_SERVER_CLIENT_ID) ?: "")
|
||||
.apply { intent.getStringExtra(GOOGLE_ID_SIWG_ACCOUNT_NAME)?.let { setAccountName(it) } }
|
||||
.build()
|
||||
|
||||
putByteArray(GET_SIGN_IN_INTENT_REQUEST, SafeParcelableSerializer.serializeToBytes(signInRequest))
|
||||
putByteArray(GOOGLE_SIGN_IN_OPTIONS, SafeParcelableSerializer.serializeToBytes(googleSignInOptions))
|
||||
putString(CLIENT_PACKAGE_NAME, intent.getStringExtra(GOOGLE_ID_SIWG_CALLER_PACKAGE))
|
||||
}
|
||||
startActivityForResult(
|
||||
Intent(ACTION_ASSISTED_SIGN_IN).apply {
|
||||
`package` = packageName
|
||||
putExtras(bundle)
|
||||
},
|
||||
REQUEST_CODE_SIGN_IN
|
||||
val serverClientId = intent.getStringExtra(GOOGLE_ID_SIWG_SERVER_CLIENT_ID).orEmpty()
|
||||
val signInRequest = GetSignInIntentRequest.builder()
|
||||
.setServerClientId(serverClientId)
|
||||
.apply { intent.getStringExtra(GOOGLE_ID_SIWG_NONCE)?.let { setNonce(it) } }
|
||||
.build()
|
||||
val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestEmail()
|
||||
.requestIdToken(serverClientId)
|
||||
.apply { intent.getStringExtra(GOOGLE_ID_SIWG_ACCOUNT_NAME)?.let { setAccountName(it) } }
|
||||
.build()
|
||||
val signInIntent = buildAssistedSignInIntent(
|
||||
requestExtraKey = GET_SIGN_IN_INTENT_REQUEST,
|
||||
serializedRequest = SafeParcelableSerializer.serializeToBytes(signInRequest),
|
||||
googleSignInOptions = googleSignInOptions,
|
||||
callingPackage = intent.getStringExtra(GOOGLE_ID_SIWG_CALLER_PACKAGE)
|
||||
)
|
||||
startActivityForResult(signInIntent, REQUEST_CODE_SIGN_IN)
|
||||
}
|
||||
|
||||
override fun onProviderCreateCredentialRequest(request: ProviderCreateCredentialRequest) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import org.microg.gms.fido.core.transport.TransportHandler
|
|||
import org.microg.gms.fido.core.transport.TransportHandlerCallback
|
||||
import org.microg.gms.utils.toBase64
|
||||
import java.security.Signature
|
||||
import java.security.cert.Certificate
|
||||
import java.security.cert.X509Certificate
|
||||
import java.security.interfaces.ECPublicKey
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
|
@ -122,7 +124,6 @@ class ScreenLockTransportHandler(private val activity: FragmentActivity, callbac
|
|||
}
|
||||
}
|
||||
val (clientData, clientDataHash) = getClientDataAndHash(activity, options, callerPackage)
|
||||
val aaguid = if (options.registerOptions.skipAttestation) ByteArray(16) else AAGUID
|
||||
val keyId = store.createKey(options.rpId, clientDataHash)
|
||||
val publicKey =
|
||||
store.getPublicKey(options.rpId, keyId) ?: throw RequestHandlingException(ErrorCode.INVALID_STATE_ERR)
|
||||
|
|
@ -130,6 +131,12 @@ class ScreenLockTransportHandler(private val activity: FragmentActivity, callbac
|
|||
// We're ignoring the signature object as we don't need it for registration
|
||||
val signature = getActiveSignature(options, callerPackage, keyId)
|
||||
|
||||
val skipAttestation = options.registerOptions.skipAttestation
|
||||
val useAndroidKey = !skipAttestation && SDK_INT >= 24 &&
|
||||
runCatching { store.getCertificateChain(options.rpId, keyId).hasValidLeafCertificate() }.getOrDefault(false)
|
||||
val useSafetyNet = !skipAttestation && SDK_INT < 24
|
||||
val aaguid = if (useAndroidKey || useSafetyNet) AAGUID else ByteArray(16)
|
||||
|
||||
val (x, y) = (publicKey as ECPublicKey).w.let { it.affineX to it.affineY }
|
||||
val coseKey = CoseKey(EC2Algorithm.ES256, x, y, 1, 32)
|
||||
val credentialId = CredentialId(1, keyId, options.rpId, publicKey)
|
||||
|
|
@ -137,19 +144,20 @@ class ScreenLockTransportHandler(private val activity: FragmentActivity, callbac
|
|||
val credentialData = getCredentialData(aaguid, credentialId, coseKey)
|
||||
val authenticatorData = getAuthenticatorData(options.rpId, credentialData)
|
||||
|
||||
val attestationObject = if (options.registerOptions.skipAttestation) {
|
||||
NoneAttestationObject(authenticatorData)
|
||||
} else {
|
||||
try {
|
||||
if (SDK_INT >= 24) {
|
||||
createAndroidKeyAttestation(signature, authenticatorData, clientDataHash, options.rpId, keyId)
|
||||
} else {
|
||||
createSafetyNetAttestation(authenticatorData, clientDataHash)
|
||||
}
|
||||
val attestationObject = when {
|
||||
useAndroidKey -> try {
|
||||
createAndroidKeyAttestation(signature, authenticatorData, clientDataHash, options.rpId, keyId)
|
||||
} catch (e: Exception) {
|
||||
Log.w("FidoScreenLockTransport", e)
|
||||
NoneAttestationObject(authenticatorData)
|
||||
}
|
||||
useSafetyNet -> try {
|
||||
createSafetyNetAttestation(authenticatorData, clientDataHash)
|
||||
} catch (e: Exception) {
|
||||
Log.w("FidoScreenLockTransport", e)
|
||||
NoneAttestationObject(authenticatorData)
|
||||
}
|
||||
else -> NoneAttestationObject(authenticatorData)
|
||||
}
|
||||
|
||||
return AuthenticatorResponseWithUser(
|
||||
|
|
@ -180,6 +188,11 @@ class ScreenLockTransportHandler(private val activity: FragmentActivity, callbac
|
|||
store.getCertificateChain(rpId, keyId).map { it.encoded })
|
||||
}
|
||||
|
||||
private fun Array<Certificate>.hasValidLeafCertificate(): Boolean {
|
||||
val leaf = firstOrNull() as? X509Certificate ?: return false
|
||||
return runCatching { leaf.checkValidity() }.isSuccess
|
||||
}
|
||||
|
||||
private suspend fun createSafetyNetAttestation(
|
||||
authenticatorData: AuthenticatorData,
|
||||
clientDataHash: ByteArray
|
||||
|
|
|
|||
37
play-services-identity-credentials/build.gradle
Normal file
37
play-services-identity-credentials/build.gradle
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
namespace "com.google.android.gms.identitycredentials"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
buildFeatures {
|
||||
aidl = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
}
|
||||
|
||||
description = 'microG implementation of play-services-identity-credentials'
|
||||
|
||||
dependencies {
|
||||
api project(':play-services-base')
|
||||
api project(':play-services-basement')
|
||||
|
||||
annotationProcessor project(':safe-parcel-processor')
|
||||
}
|
||||
52
play-services-identity-credentials/core/build.gradle
Normal file
52
play-services-identity-credentials/core/build.gradle
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
dependencies {
|
||||
api project(':play-services-identity-credentials')
|
||||
|
||||
implementation project(':play-services-base-core')
|
||||
implementation project(':play-services-fido-core')
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion"
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "org.microg.gms.identitycredentials.core"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs = ['src/main/kotlin']
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'MissingTranslation'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = 1.8
|
||||
}
|
||||
}
|
||||
|
||||
description = 'microG service implementation for play-services-identity-credentials'
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
~ SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name="org.microg.gms.identitycredentials.IdentityCredentialApiService">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.gms.identitycredentials.service.START" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.identitycredentials
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.core.app.PendingIntentCompat
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.Feature
|
||||
import com.google.android.gms.common.api.ApiMetadata
|
||||
import com.google.android.gms.common.api.CommonStatusCodes
|
||||
import com.google.android.gms.common.api.Status
|
||||
import com.google.android.gms.common.internal.ConnectionInfo
|
||||
import com.google.android.gms.common.internal.GetServiceRequest
|
||||
import com.google.android.gms.common.internal.IGmsCallbacks
|
||||
import com.google.android.gms.identitycredentials.ClearCreationOptionsRequest
|
||||
import com.google.android.gms.identitycredentials.ClearCredentialStateRequest
|
||||
import com.google.android.gms.identitycredentials.ClearCredentialStateResponse
|
||||
import com.google.android.gms.identitycredentials.ClearExportRequest
|
||||
import com.google.android.gms.identitycredentials.ClearRegistryRequest
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialHandle
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialRequest
|
||||
import com.google.android.gms.identitycredentials.CredentialInformation
|
||||
import com.google.android.gms.identitycredentials.CredentialInformationRequest
|
||||
import com.google.android.gms.identitycredentials.CredentialInformationResponse
|
||||
import com.google.android.gms.identitycredentials.CredentialTransferCapabilities
|
||||
import com.google.android.gms.identitycredentials.ExportCredentialsToDeviceSetupRequest
|
||||
import com.google.android.gms.identitycredentials.GetCredentialRequest
|
||||
import com.google.android.gms.identitycredentials.GetCredentialTransferCapabilitiesRequest
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsForDeviceSetupRequest
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsRequest
|
||||
import com.google.android.gms.identitycredentials.PendingGetCredentialHandle
|
||||
import com.google.android.gms.identitycredentials.RegisterCreationOptionsRequest
|
||||
import com.google.android.gms.identitycredentials.RegisterExportRequest
|
||||
import com.google.android.gms.identitycredentials.RegistrationRequest
|
||||
import com.google.android.gms.identitycredentials.SignalCredentialStateRequest
|
||||
import com.google.android.gms.identitycredentials.internal.IIdentityCredentialCallbacks
|
||||
import com.google.android.gms.identitycredentials.internal.IIdentityCredentialService
|
||||
import kotlinx.coroutines.launch
|
||||
import org.microg.gms.BaseService
|
||||
import org.microg.gms.common.AccountUtils
|
||||
import org.microg.gms.common.GmsService
|
||||
import org.microg.gms.fido.core.Database
|
||||
import org.microg.gms.profile.Build
|
||||
import org.microg.gms.profile.ProfileManager
|
||||
|
||||
private const val TAG = "IdentityCredentialApi"
|
||||
|
||||
private const val CHOOSER_ACTIVITY_CLASS = "org.microg.gms.auth.credentials.identity.IdentityCredentialChooserActivity"
|
||||
|
||||
const val EXTRA_GET_REQUEST = "org.microg.gms.identitycredentials.EXTRA_GET_REQUEST"
|
||||
const val EXTRA_CREATE_REQUEST = "org.microg.gms.identitycredentials.EXTRA_CREATE_REQUEST"
|
||||
const val EXTRA_CALLING_PACKAGE = "org.microg.gms.identitycredentials.EXTRA_CALLING_PACKAGE"
|
||||
|
||||
private val FEATURES = arrayOf(
|
||||
Feature("GET_CREDENTIAL", 1),
|
||||
Feature("CREDENTIAL_REGISTRY", 1),
|
||||
Feature("CLEAR_REGISTRY", 2),
|
||||
Feature("CLEAR_CREATION_OPTIONS", 1),
|
||||
Feature("GET_CREDENTIAL_INFORMATION", 1),
|
||||
Feature("CLEAR_CREDENTIAL_STATE", 1),
|
||||
Feature("CREATE_CREDENTIAL", 3),
|
||||
Feature("REGISTER_CREATION_OPTIONS", 1),
|
||||
Feature("REGISTER_EXPORT", 1),
|
||||
Feature("IMPORT_CREDENTIALS", 1),
|
||||
Feature("SIGNAL_CREDENTIAL_STATE", 1),
|
||||
Feature("CLEAR_EXPORT", 1),
|
||||
Feature("IMPORT_CREDENTIALS_FOR_DEVICE_SETUP", 3),
|
||||
Feature("EXPORT_CREDENTIALS_TO_DEVICE_SETUP", 3),
|
||||
Feature("GET_CREDENTIAL_TRANSFER_CAPABILITIES", 3),
|
||||
)
|
||||
|
||||
class IdentityCredentialApiService : BaseService(TAG, GmsService.IDENTITY_CREDENTIALS) {
|
||||
|
||||
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
|
||||
Log.d(TAG, "handleServiceRequest pkg=${request.packageName}")
|
||||
val connectionInfo = ConnectionInfo()
|
||||
connectionInfo.features = FEATURES
|
||||
ProfileManager.ensureInitialized(this)
|
||||
callback.onPostInitCompleteWithConnectionInfo(
|
||||
ConnectionResult.SUCCESS,
|
||||
IdentityCredentialApiServiceImpl(this, request.packageName, lifecycle).asBinder(),
|
||||
connectionInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class IdentityCredentialApiServiceImpl(
|
||||
private val context: Context,
|
||||
private val clientPackageName: String,
|
||||
override val lifecycle: Lifecycle,
|
||||
) : IIdentityCredentialService.Stub(), LifecycleOwner {
|
||||
|
||||
override fun getCredential(callback: IIdentityCredentialCallbacks, request: GetCredentialRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "getCredential pkg=$clientPackageName options=${request.credentialOptions.size} origin=${request.origin}")
|
||||
callback.onGetCredential(Status.SUCCESS, PendingGetCredentialHandle(buildChooserPendingIntent(request)), ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun createCredential(callback: IIdentityCredentialCallbacks, request: CreateCredentialRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "createCredential pkg=$clientPackageName type=${request.type} origin=${request.origin}")
|
||||
callback.onCreateCredential(Status.SUCCESS, CreateCredentialHandle(buildCreateChooserPendingIntent(request), null), ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun clearCredentialState(callback: IIdentityCredentialCallbacks, request: ClearCredentialStateRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "clearCredentialState pkg=$clientPackageName")
|
||||
callback.onClearCredentialState(Status.SUCCESS, ClearCredentialStateResponse(), ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun getCredentialInformation(callback: IIdentityCredentialCallbacks, request: CredentialInformationRequest, apiMetadata: ApiMetadata) {
|
||||
val packageNames = request.packageNames.orEmpty()
|
||||
Log.d(TAG, "getCredentialInformation pkg=$clientPackageName count=${packageNames.size}")
|
||||
if (Build.VERSION.SDK_INT < 34) {
|
||||
callback.onGetCredentialInformation(Status.SUCCESS, CredentialInformationResponse(emptyList()))
|
||||
return
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
fun resolveCredentialInformation(packageName: String): CredentialInformation {
|
||||
val installed = runCatching { context.packageManager.getPackageInfo(packageName, 0) }.isSuccess
|
||||
if (!installed) return CredentialInformation(packageName, 0, 0, 0, 0)
|
||||
val hasPasskey = runCatching { Database(context).getKnownRegistrationInfo(packageName).isNotEmpty() }.getOrDefault(false)
|
||||
val hasGoogleAccount = AccountUtils.get(context).getSelectedAccount(packageName) != null
|
||||
return CredentialInformation(packageName, 0, if (hasPasskey) 1 else 0, if (hasGoogleAccount) 1 else 0, 0)
|
||||
}
|
||||
val infos = packageNames.filterNotNull().map { resolveCredentialInformation(it) }
|
||||
runCatching { callback.onGetCredentialInformation(Status.SUCCESS, CredentialInformationResponse(infos)) }
|
||||
.onFailure { Log.w(TAG, "getCredentialInformation callback failed", it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun register(callback: IIdentityCredentialCallbacks, request: RegistrationRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "register: not implemented")
|
||||
callback.onRegister(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun clearRegistry(callback: IIdentityCredentialCallbacks, request: ClearRegistryRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "clearRegistry: not implemented")
|
||||
callback.onClearRegistry(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun importCredentials(callback: IIdentityCredentialCallbacks, request: ImportCredentialsRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "importCredentials: not implemented")
|
||||
callback.onImportCredentials(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun registerExport(callback: IIdentityCredentialCallbacks, request: RegisterExportRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "registerExport: not implemented")
|
||||
callback.onRegisterExport(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun registerCreationOptions(callback: IIdentityCredentialCallbacks, request: RegisterCreationOptionsRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "registerCreationOptions: not implemented")
|
||||
callback.onRegisterCreationOptions(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun signalCredentialState(callback: IIdentityCredentialCallbacks, request: SignalCredentialStateRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "signalCredentialState: not implemented")
|
||||
callback.onSignalCredentialState(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun clearExport(callback: IIdentityCredentialCallbacks, request: ClearExportRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "clearExport: not implemented")
|
||||
callback.onClearExport(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun importCredentialsForDeviceSetup(callback: IIdentityCredentialCallbacks, request: ImportCredentialsForDeviceSetupRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "importCredentialsForDeviceSetup: not implemented")
|
||||
callback.onImportCredentialsForDeviceSetup(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun exportCredentialsToDeviceSetup(callback: IIdentityCredentialCallbacks, request: ExportCredentialsToDeviceSetupRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "exportCredentialsToDeviceSetup: not implemented")
|
||||
callback.onExportCredentialsToDeviceSetup(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun getCredentialTransferCapabilities(callback: IIdentityCredentialCallbacks, request: GetCredentialTransferCapabilitiesRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "getCredentialTransferCapabilities pkg=$clientPackageName")
|
||||
callback.onGetCredentialTransferCapabilities(Status.SUCCESS, CredentialTransferCapabilities(Bundle.EMPTY), ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
override fun clearCreationOptions(callback: IIdentityCredentialCallbacks, request: ClearCreationOptionsRequest, apiMetadata: ApiMetadata) {
|
||||
Log.d(TAG, "clearCreationOptions: not implemented")
|
||||
callback.onClearCreationOptions(Status(CommonStatusCodes.API_NOT_CONNECTED), null, ApiMetadata.SKIP)
|
||||
}
|
||||
|
||||
private fun buildChooserPendingIntent(request: GetCredentialRequest): PendingIntent =
|
||||
buildChooserPendingIntent(request.hashCode()) {
|
||||
putExtra(EXTRA_GET_REQUEST, Bundle().apply { putParcelable(EXTRA_GET_REQUEST, request) })
|
||||
}
|
||||
|
||||
private fun buildCreateChooserPendingIntent(request: CreateCredentialRequest): PendingIntent =
|
||||
buildChooserPendingIntent(request.hashCode()) {
|
||||
putExtra(EXTRA_CREATE_REQUEST, Bundle().apply { putParcelable(EXTRA_CREATE_REQUEST, request) })
|
||||
}
|
||||
|
||||
private inline fun buildChooserPendingIntent(requestCode: Int, configure: Intent.() -> Unit): PendingIntent {
|
||||
val intent = Intent().apply {
|
||||
component = ComponentName(context.packageName, CHOOSER_ACTIVITY_CLASS)
|
||||
putExtra(EXTRA_CALLING_PACKAGE, clientPackageName)
|
||||
configure()
|
||||
}
|
||||
val flags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT
|
||||
return PendingIntentCompat.getActivity(context, requestCode, intent, flags, true)!!
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearCreationOptionsRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearCreationOptionsResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearCredentialStateRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearCredentialStateResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearExportRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearExportResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearRegistryRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ClearRegistryResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable CreateCredentialHandle;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable CreateCredentialRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable CreateCredentialResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable CredentialInformationRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable CredentialInformationResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable CredentialOption;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable CredentialTransferCapabilities;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ExportCredentialsToDeviceSetupRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ExportCredentialsToDeviceSetupResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable GetCredentialRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable GetCredentialTransferCapabilitiesRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ImportCredentialsForDeviceSetupRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ImportCredentialsForDeviceSetupResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable ImportCredentialsRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable PendingGetCredentialHandle;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable PendingImportCredentialsHandle;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable RegisterCreationOptionsRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable RegisterCreationOptionsResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable RegisterExportRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable RegisterExportResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable RegistrationRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable RegistrationResponse;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable SignalCredentialStateRequest;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
parcelable SignalCredentialStateResponse;
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials.internal;
|
||||
|
||||
import com.google.android.gms.common.api.ApiMetadata;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.identitycredentials.ClearCreationOptionsResponse;
|
||||
import com.google.android.gms.identitycredentials.ClearCredentialStateResponse;
|
||||
import com.google.android.gms.identitycredentials.ClearExportResponse;
|
||||
import com.google.android.gms.identitycredentials.ClearRegistryResponse;
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialHandle;
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialResponse;
|
||||
import com.google.android.gms.identitycredentials.CredentialInformationResponse;
|
||||
import com.google.android.gms.identitycredentials.CredentialTransferCapabilities;
|
||||
import com.google.android.gms.identitycredentials.ExportCredentialsToDeviceSetupResponse;
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsForDeviceSetupResponse;
|
||||
import com.google.android.gms.identitycredentials.PendingGetCredentialHandle;
|
||||
import com.google.android.gms.identitycredentials.PendingImportCredentialsHandle;
|
||||
import com.google.android.gms.identitycredentials.RegisterCreationOptionsResponse;
|
||||
import com.google.android.gms.identitycredentials.RegisterExportResponse;
|
||||
import com.google.android.gms.identitycredentials.RegistrationResponse;
|
||||
import com.google.android.gms.identitycredentials.SignalCredentialStateResponse;
|
||||
|
||||
interface IIdentityCredentialCallbacks {
|
||||
void onGetCredential(in Status status, in PendingGetCredentialHandle handle, in ApiMetadata apiMetadata) = 0;
|
||||
void onRegister(in Status status, in RegistrationResponse response, in ApiMetadata apiMetadata) = 1;
|
||||
void onClearRegistry(in Status status, in ClearRegistryResponse response, in ApiMetadata apiMetadata) = 2;
|
||||
void onImportCredentials(in Status status, in PendingImportCredentialsHandle handle, in ApiMetadata apiMetadata) = 3;
|
||||
void onRegisterExport(in Status status, in RegisterExportResponse response, in ApiMetadata apiMetadata) = 4;
|
||||
void onCreateCredentialLegacy(in Status status, in CreateCredentialResponse response, in ApiMetadata apiMetadata) = 5;
|
||||
void onCreateCredential(in Status status, in CreateCredentialHandle handle, in ApiMetadata apiMetadata) = 6;
|
||||
void onRegisterCreationOptions(in Status status, in RegisterCreationOptionsResponse response, in ApiMetadata apiMetadata) = 7;
|
||||
void onClearCredentialState(in Status status, in ClearCredentialStateResponse response, in ApiMetadata apiMetadata) = 8;
|
||||
void onSignalCredentialState(in Status status, in SignalCredentialStateResponse response, in ApiMetadata apiMetadata) = 9;
|
||||
void onClearExport(in Status status, in ClearExportResponse response, in ApiMetadata apiMetadata) = 10;
|
||||
void onImportCredentialsForDeviceSetup(in Status status, in ImportCredentialsForDeviceSetupResponse response, in ApiMetadata apiMetadata) = 11;
|
||||
void onExportCredentialsToDeviceSetup(in Status status, in ExportCredentialsToDeviceSetupResponse response, in ApiMetadata apiMetadata) = 12;
|
||||
void onGetCredentialTransferCapabilities(in Status status, in CredentialTransferCapabilities capabilities, in ApiMetadata apiMetadata) = 13;
|
||||
void onClearCreationOptions(in Status status, in ClearCreationOptionsResponse response, in ApiMetadata apiMetadata) = 14;
|
||||
void onGetCredentialInformation(in Status status, in CredentialInformationResponse response) = 15;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials.internal;
|
||||
|
||||
import com.google.android.gms.common.api.ApiMetadata;
|
||||
import com.google.android.gms.identitycredentials.ClearCreationOptionsRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearCredentialStateRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearExportRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearRegistryRequest;
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialRequest;
|
||||
import com.google.android.gms.identitycredentials.CredentialInformationRequest;
|
||||
import com.google.android.gms.identitycredentials.ExportCredentialsToDeviceSetupRequest;
|
||||
import com.google.android.gms.identitycredentials.GetCredentialRequest;
|
||||
import com.google.android.gms.identitycredentials.GetCredentialTransferCapabilitiesRequest;
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsForDeviceSetupRequest;
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsRequest;
|
||||
import com.google.android.gms.identitycredentials.RegisterCreationOptionsRequest;
|
||||
import com.google.android.gms.identitycredentials.RegisterExportRequest;
|
||||
import com.google.android.gms.identitycredentials.RegistrationRequest;
|
||||
import com.google.android.gms.identitycredentials.SignalCredentialStateRequest;
|
||||
import com.google.android.gms.identitycredentials.internal.IIdentityCredentialCallbacks;
|
||||
|
||||
interface IIdentityCredentialService {
|
||||
void getCredential(IIdentityCredentialCallbacks callbacks, in GetCredentialRequest request, in ApiMetadata apiMetadata) = 0;
|
||||
void register(IIdentityCredentialCallbacks callbacks, in RegistrationRequest request, in ApiMetadata apiMetadata) = 1;
|
||||
void clearRegistry(IIdentityCredentialCallbacks callbacks, in ClearRegistryRequest request, in ApiMetadata apiMetadata) = 2;
|
||||
void importCredentials(IIdentityCredentialCallbacks callbacks, in ImportCredentialsRequest request, in ApiMetadata apiMetadata) = 3;
|
||||
void registerExport(IIdentityCredentialCallbacks callbacks, in RegisterExportRequest request, in ApiMetadata apiMetadata) = 4;
|
||||
void createCredential(IIdentityCredentialCallbacks callbacks, in CreateCredentialRequest request, in ApiMetadata apiMetadata) = 5;
|
||||
void registerCreationOptions(IIdentityCredentialCallbacks callbacks, in RegisterCreationOptionsRequest request, in ApiMetadata apiMetadata) = 7;
|
||||
void clearCredentialState(IIdentityCredentialCallbacks callbacks, in ClearCredentialStateRequest request, in ApiMetadata apiMetadata) = 8;
|
||||
void signalCredentialState(IIdentityCredentialCallbacks callbacks, in SignalCredentialStateRequest request, in ApiMetadata apiMetadata) = 9;
|
||||
void clearExport(IIdentityCredentialCallbacks callbacks, in ClearExportRequest request, in ApiMetadata apiMetadata) = 10;
|
||||
void importCredentialsForDeviceSetup(IIdentityCredentialCallbacks callbacks, in ImportCredentialsForDeviceSetupRequest request, in ApiMetadata apiMetadata) = 11;
|
||||
void exportCredentialsToDeviceSetup(IIdentityCredentialCallbacks callbacks, in ExportCredentialsToDeviceSetupRequest request, in ApiMetadata apiMetadata) = 12;
|
||||
void getCredentialTransferCapabilities(IIdentityCredentialCallbacks callbacks, in GetCredentialTransferCapabilitiesRequest request, in ApiMetadata apiMetadata) = 13;
|
||||
void clearCreationOptions(IIdentityCredentialCallbacks callbacks, in ClearCreationOptionsRequest request, in ApiMetadata apiMetadata) = 14;
|
||||
void getCredentialInformation(IIdentityCredentialCallbacks callbacks, in CredentialInformationRequest request, in ApiMetadata apiMetadata) = 15;
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Information pertaining to the calling application.
|
||||
* <p>
|
||||
* The {@code packageCertificates} will either return a single byte-array corresponding to the oldest available signature for pre-P devices; for P+
|
||||
* devices, it will return the full rotation history (including the signature used to sign the package) or an empty list. The empty list means the
|
||||
* package was not found or the package does not have any trust-worthy signatures.
|
||||
*/
|
||||
public class CallingAppInfoParcelable implements Parcelable {
|
||||
@NonNull
|
||||
private final String packageName;
|
||||
@NonNull
|
||||
private final List<byte[]> packageCertificates;
|
||||
@NonNull
|
||||
private final String origin;
|
||||
|
||||
public CallingAppInfoParcelable(@NonNull String packageName, @NonNull List<byte[]> packageCertificates, @NonNull String origin) {
|
||||
this.packageName = packageName;
|
||||
this.packageCertificates = packageCertificates;
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* the calling origin
|
||||
*/
|
||||
@NonNull
|
||||
public String getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* a list of byte arrays, one for each rotated signature in raw bytes
|
||||
*/
|
||||
@NonNull
|
||||
public List<byte[]> getPackageCertificates() {
|
||||
return packageCertificates;
|
||||
}
|
||||
|
||||
/**
|
||||
* the calling app package name
|
||||
*/
|
||||
@NonNull
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString(packageName);
|
||||
dest.writeInt(packageCertificates.size());
|
||||
for (byte[] packageCertificate : packageCertificates) {
|
||||
dest.writeInt(packageCertificate.length);
|
||||
dest.writeByteArray(packageCertificate);
|
||||
}
|
||||
dest.writeString(origin);
|
||||
}
|
||||
|
||||
public static final Creator<CallingAppInfoParcelable> CREATOR = new Creator<CallingAppInfoParcelable>() {
|
||||
@Override
|
||||
public CallingAppInfoParcelable createFromParcel(Parcel source) {
|
||||
String packageName = source.readString();
|
||||
int numPackageCertificates = source.readInt();
|
||||
if (packageName == null || numPackageCertificates < 0) {
|
||||
return null;
|
||||
}
|
||||
List<byte[]> packageCertificates = new ArrayList<>(numPackageCertificates);
|
||||
for (int i = 0; i < numPackageCertificates; i++) {
|
||||
byte[] packageCertificate = new byte[source.readInt()];
|
||||
source.readByteArray(packageCertificate);
|
||||
packageCertificates.add(packageCertificate);
|
||||
}
|
||||
String origin = source.readString();
|
||||
return new CallingAppInfoParcelable(packageName, packageCertificates, origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallingAppInfoParcelable[] newArray(int size) {
|
||||
return new CallingAppInfoParcelable[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A request to clear the registries stored for your app.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearCreationOptionsRequest extends AbstractSafeParcelable {
|
||||
|
||||
@Field(value = 1, getterName = "getDeleteAll", defaultValue = "true")
|
||||
private final boolean deleteAll;
|
||||
@Field(value = 2, getterName = "getClearTypedRegistryOption")
|
||||
@Nullable
|
||||
private final ClearTypedCreationOption clearTypedRegistryOption;
|
||||
|
||||
/**
|
||||
* Cosntructs a request to clear all registries for your app that was registered with the IdentityCredentials.registerCredentials API.
|
||||
*/
|
||||
public ClearCreationOptionsRequest() {
|
||||
this(true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearCreationOptionsRequest}
|
||||
*
|
||||
* @param deleteAll whether to delete all registries for your app
|
||||
* @param clearTypedRegistryOption an option to clear the registries for a given type that matches the {@code RegisterCreationOptionsRequest.type} provided during registration
|
||||
*/
|
||||
@Constructor
|
||||
public ClearCreationOptionsRequest(@Param(1) boolean deleteAll, @Param(2) @Nullable ClearTypedCreationOption clearTypedRegistryOption) {
|
||||
this.deleteAll = deleteAll;
|
||||
this.clearTypedRegistryOption = clearTypedRegistryOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether to delete all registries for your app
|
||||
*/
|
||||
public boolean getDeleteAll() {
|
||||
return deleteAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* an option to clear the registries for a given type that matches the RegisterCreationOptionsRequest.type provided during registration
|
||||
*/
|
||||
@Nullable
|
||||
public ClearTypedCreationOption getClearTypedRegistryOption() {
|
||||
return clearTypedRegistryOption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearCreationOptionsRequest> CREATOR = findCreator(ClearCreationOptionsRequest.class);
|
||||
|
||||
/**
|
||||
* A request to configure how to clear the registries for a given type.
|
||||
* <p>
|
||||
* The order of the conditions are important. If {@code deleteAllForType} is true, then the other conditions are ignored and all the
|
||||
* registries for the given type are deleted. Otherwise, the registries with the IDs provided in {@code registryIds} will be deleted.
|
||||
*/
|
||||
@Class
|
||||
public static class ClearTypedCreationOption extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getDeleteAllForType")
|
||||
private final boolean deleteAllForType;
|
||||
|
||||
@Field(value = 2, getterName = "getType")
|
||||
@NonNull
|
||||
private final String type;
|
||||
|
||||
@Field(value = 3, getterName = "getRegistryIds")
|
||||
@NonNull
|
||||
private final List<String> registryIds;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearTypedCreationOption}
|
||||
*
|
||||
* @param deleteAllForType whether to delete all registries for the given type
|
||||
* @param type the type of registry to clear, matching the RegistrationRequest.type provided during registration
|
||||
* @param registryIds the IDs of the registries for the given type to delete
|
||||
*/
|
||||
@Constructor
|
||||
public ClearTypedCreationOption(@Param(1) boolean deleteAllForType, @NonNull @Param(2) String type, @NonNull @Param(3) List<String> registryIds) {
|
||||
this.deleteAllForType = deleteAllForType;
|
||||
this.type = type;
|
||||
this.registryIds = registryIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether to delete all registries for the given type
|
||||
*/
|
||||
public final boolean getDeleteAllForType() {
|
||||
return this.deleteAllForType;
|
||||
}
|
||||
|
||||
/**
|
||||
* the IDs of the registries for the given type to delete
|
||||
*/
|
||||
@NonNull
|
||||
public final List<String> getRegistryIds() {
|
||||
return this.registryIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of registry to clear, matching the RegistrationRequest.type provided during registration
|
||||
*/
|
||||
@NonNull
|
||||
public final String getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearTypedCreationOption> CREATOR = findCreator(ClearTypedCreationOption.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response of a registry deletion operation.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearCreationOptionsResponse extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isDeleted")
|
||||
private final boolean isDeleted;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearCreationOptionsResponse}
|
||||
* @param isDeleted if true, indicates clear operation deleted some registries, otherwise indicates there was no data to delete; unexpected failures will be thrown as exceptions
|
||||
*/
|
||||
@Constructor
|
||||
public ClearCreationOptionsResponse(@Param(1) boolean isDeleted) {
|
||||
this.isDeleted = isDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* if true, indicates clear operation deleted some registries, otherwise indicates there was no data to delete; unexpected failures will be thrown as exceptions
|
||||
*/
|
||||
public final boolean isDeleted() {
|
||||
return this.isDeleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearCreationOptionsResponse> CREATOR = findCreator(ClearCreationOptionsResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Data interface for clearing a user's credential state from the credential providers.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearCredentialStateRequest extends AbstractSafeParcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearCredentialStateRequest> CREATOR = findCreator(ClearCredentialStateRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response of a clear credential state request.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearCredentialStateResponse extends AbstractSafeParcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearCredentialStateResponse> CREATOR = findCreator(ClearCredentialStateResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A request to clear the registries stored for your app.
|
||||
* <p>
|
||||
* The order of the conditions are important. If {@code deleteAll} is true, then the other conditions are ignored, and all the registries for your app that
|
||||
* was registered with the {@link IdentityCredentialClient#registerExport} API are deleted.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearExportRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getDeleteAll")
|
||||
private final boolean deleteAll;
|
||||
|
||||
@Field(value = 2, getterName = "getRegistryIds")
|
||||
@NonNull
|
||||
private final List<String> registryIds;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearExportRequest}
|
||||
*
|
||||
* @param deleteAll whether to delete all export registries for your app
|
||||
* @param registryIds the IDs of the registries for the given type to delete
|
||||
*/
|
||||
@Constructor
|
||||
public ClearExportRequest(@Param(1) boolean deleteAll, @NonNull @Param(2) List<String> registryIds) {
|
||||
this.deleteAll = deleteAll;
|
||||
this.registryIds = registryIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether to delete all export registries for your app
|
||||
*/
|
||||
public final boolean getDeleteAll() {
|
||||
return this.deleteAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* the IDs of the registries for the given type to delete
|
||||
*/
|
||||
@NonNull
|
||||
public final List<String> getRegistryIds() {
|
||||
return this.registryIds;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public final ClearRegistryRequest.ClearTypedRegistryOption getClearRegistryOption() {
|
||||
return new ClearRegistryRequest.ClearTypedRegistryOption(this.deleteAll, "androidx.identitycredentials.TYPE_CREDENTIALS_SYNC", false, this.registryIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearExportRequest> CREATOR = findCreator(ClearExportRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
|
||||
/**
|
||||
* Response of a registry deletion operation.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearExportResponse extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isDeleted")
|
||||
private final boolean isDeleted;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearExportResponse}
|
||||
*
|
||||
* @param isDeleted if true, indicates clear operation deleted some registries, otherwise indicates there was no data to delete; unexpected failures will be thrown as exceptions
|
||||
*/
|
||||
@Constructor
|
||||
public ClearExportResponse(@Param(1) boolean isDeleted) {
|
||||
this.isDeleted = isDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* if true, indicates clear operation deleted some registries, otherwise indicates there was no data to delete; unexpected failures will be thrown as exceptions
|
||||
*/
|
||||
public final boolean isDeleted() {
|
||||
return this.isDeleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearExportResponse> CREATOR = findCreator(ClearExportResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A request to clear the registries stored for your app.
|
||||
* <p>
|
||||
* The order of the conditions are important. If {@code deleteAll} is true, then the other conditions are ignored, and all the registries for your app that
|
||||
* was registered with the {@link IdentityCredentialClient#registerCredentials} API are deleted.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearRegistryRequest extends AbstractSafeParcelable {
|
||||
|
||||
@Field(value = 1, getterName = "getDeleteAll", defaultValue = "true")
|
||||
private final boolean deleteAll;
|
||||
|
||||
@Field(value = 2, getterName = "getClearTypedRegistryOption")
|
||||
@Nullable
|
||||
private final ClearTypedRegistryOption clearTypedRegistryOption;
|
||||
|
||||
/**
|
||||
* Cosntructs a request to clear all registries for your app that was registered with the IdentityCredentials.registerCredentials API.
|
||||
*/
|
||||
public ClearRegistryRequest() {
|
||||
this(true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearRegistryRequest}
|
||||
*
|
||||
* @param deleteAll whether to delete all registries for your app
|
||||
* @param clearTypedRegistryOption an option to clear the registries for a given type that matches the RegistrationRequest.type provided during registration
|
||||
*/
|
||||
@Constructor
|
||||
public ClearRegistryRequest(@Param(1) boolean deleteAll, @Param(2) @Nullable ClearTypedRegistryOption clearTypedRegistryOption) {
|
||||
this.deleteAll = deleteAll;
|
||||
this.clearTypedRegistryOption = clearTypedRegistryOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether to delete all registries for your app
|
||||
*/
|
||||
public final boolean getDeleteAll() {
|
||||
return this.deleteAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* an option to clear the registries for a given type that matches the RegistrationRequest.type provided during registration
|
||||
*/
|
||||
@Nullable
|
||||
public final ClearTypedRegistryOption getClearTypedRegistryOption() {
|
||||
return this.clearTypedRegistryOption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearRegistryRequest> CREATOR = findCreator(ClearRegistryRequest.class);
|
||||
|
||||
/**
|
||||
* A request to configure how to clear the registries for a given type.
|
||||
* <p>
|
||||
* The order of the conditions are important. If {@code deleteAllForType} is true, then the other conditions are ignored and all the registries for the
|
||||
* given type are deleted. Otherwise, if {@code deleteIdlessRegistry} is true, then the registry with an empty ID is deleted; at the same time, the
|
||||
* registries with the IDs provided in {@code registryIds} will also be deleted.
|
||||
*/
|
||||
public static class ClearTypedRegistryOption extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getDeleteAllForType")
|
||||
private final boolean deleteAllForType;
|
||||
|
||||
@Field(value = 2, getterName = "getType")
|
||||
@NonNull
|
||||
private final String type;
|
||||
|
||||
@Field(value = 3, getterName = "getDeleteIdlessRegistry")
|
||||
private final boolean deleteIdlessRegistry;
|
||||
|
||||
@Field(value = 4, getterName = "getRegistryIds")
|
||||
@NonNull
|
||||
private final List<String> registryIds;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearTypedRegistryOption}
|
||||
*
|
||||
* @param deleteAllForType whether to delete all registries for the given type
|
||||
* @param type the type of registry to clear, matching the RegistrationRequest.type provided during registration
|
||||
* @param deleteIdlessRegistry whether to delete the registry for the given type that was registered without an ID provided; in other words, the registry that was registered without providing RegistrationRequest.id
|
||||
* @param registryIds the IDs of the registries for the given type to delete
|
||||
*/
|
||||
@Constructor
|
||||
public ClearTypedRegistryOption(@Param(1) boolean deleteAllForType, @NonNull @Param(2) String type, @Param(3) boolean deleteIdlessRegistry, @NonNull @Param(4) List<String> registryIds) {
|
||||
this.deleteAllForType = deleteAllForType;
|
||||
this.type = type;
|
||||
this.deleteIdlessRegistry = deleteIdlessRegistry;
|
||||
this.registryIds = registryIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether to delete all registries for the given type
|
||||
*/
|
||||
public final boolean getDeleteAllForType() {
|
||||
return this.deleteAllForType;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether to delete the registry for the given type that was registered without an ID provided; in other words, the registry that was registered without providing RegistrationRequest.id
|
||||
*/
|
||||
public final boolean getDeleteIdlessRegistry() {
|
||||
return this.deleteIdlessRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* the IDs of the registries for the given type to delete
|
||||
*/
|
||||
@NonNull
|
||||
public final List<String> getRegistryIds() {
|
||||
return this.registryIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of registry to clear, matching the RegistrationRequest.type provided during registration
|
||||
*/
|
||||
@NonNull
|
||||
public final String getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearTypedRegistryOption> CREATOR = findCreator(ClearTypedRegistryOption.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response of a registry deletion operation.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ClearRegistryResponse extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isDeleted")
|
||||
private final boolean isDeleted;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link ClearRegistryResponse}
|
||||
*
|
||||
* @param isDeleted if true, indicates clear operation deleted some registries, otherwise indicates there was no data to delete; unexpected failures will be thrown as exceptions
|
||||
*/
|
||||
@Constructor
|
||||
public ClearRegistryResponse(@Param(1) boolean isDeleted) {
|
||||
this.isDeleted = isDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* if true, indicates clear operation deleted some registries, otherwise indicates there was no data to delete; unexpected failures will be thrown as exceptions
|
||||
*/
|
||||
public final boolean isDeleted() {
|
||||
return this.isDeleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ClearRegistryResponse> CREATOR = findCreator(ClearRegistryResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Returns a response for the {@link IdentityCredentialClient#createCredential} API that can be used to launch the credential selector UIs to
|
||||
* finalize on a credential of the user's choice that can be used for app sign-in, or the actual credential response itself if no UI is needed.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class CreateCredentialHandle extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getPendingIntent")
|
||||
@Nullable
|
||||
private final PendingIntent pendingIntent;
|
||||
@Field(value = 2, getterName = "getCreateCredentialResponse")
|
||||
@Nullable
|
||||
private final CreateCredentialResponse createCredentialResponse;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link CreateCredentialHandle}
|
||||
*
|
||||
* @param pendingIntent the {@link PendingIntent} to launch the credential selector UI
|
||||
* @param createCredentialResponse the {@link CreateCredentialResponse} if no UI is needed
|
||||
*/
|
||||
@Constructor
|
||||
public CreateCredentialHandle(@Param(1) @Nullable PendingIntent pendingIntent, @Param(2) @Nullable CreateCredentialResponse createCredentialResponse) {
|
||||
if (pendingIntent == null && createCredentialResponse == null) {
|
||||
throw new IllegalArgumentException("pendingIntent or createCredentialResponse must be specified.");
|
||||
}
|
||||
this.pendingIntent = pendingIntent;
|
||||
this.createCredentialResponse = createCredentialResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* the {@link CreateCredentialResponse} if no UI is needed
|
||||
*/
|
||||
@Nullable
|
||||
public CreateCredentialResponse getCreateCredentialResponse() {
|
||||
return createCredentialResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* the {@link PendingIntent} to launch the credential selector UI
|
||||
*/
|
||||
@Nullable
|
||||
public PendingIntent getPendingIntent() {
|
||||
return pendingIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CreateCredentialHandle> CREATOR = findCreator(CreateCredentialHandle.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Data interface for creating or saving a user credential.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class CreateCredentialRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getType")
|
||||
@NonNull
|
||||
private final String type;
|
||||
@Field(value = 2, getterName = "getCredentialData")
|
||||
@NonNull
|
||||
private final Bundle credentialData;
|
||||
@Field(value = 3, getterName = "getCandidateQueryData")
|
||||
@NonNull
|
||||
private final Bundle candidateQueryData;
|
||||
@Field(value = 4, getterName = "getOrigin")
|
||||
@Nullable
|
||||
private final String origin;
|
||||
@Field(value = 5, getterName = "getRequestJson")
|
||||
@Nullable
|
||||
private final String requestJson;
|
||||
@Field(value = 6, getterName = "getResultReceiver")
|
||||
@Nullable
|
||||
private final ResultReceiver resultReceiver;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link CreateCredentialRequest}
|
||||
*
|
||||
* @param type the type of the credential to be created or saved
|
||||
* @param credentialData the complete request data in {@link Bundle} format, consisting of all the data that will be sent to the provider during the final credential creation stage
|
||||
* @param candidateQueryData the partial request data in {@link Bundle} format, that will be sent to the provider during the initial candidate query stage, which will not contain sensitive user information
|
||||
* @param origin the origin of the request, only settable by a browser
|
||||
*/
|
||||
@Constructor
|
||||
public CreateCredentialRequest(@Param(1) @NonNull String type, @Param(2) @NonNull Bundle credentialData, @Param(3) @NonNull Bundle candidateQueryData, @Param(4) @Nullable String origin, @Param(5) @Nullable String requestJson, @Param(6) @Nullable ResultReceiver resultReceiver) {
|
||||
this.type = type;
|
||||
this.credentialData = credentialData;
|
||||
this.candidateQueryData = candidateQueryData;
|
||||
this.origin = origin;
|
||||
this.requestJson = requestJson;
|
||||
this.resultReceiver = resultReceiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* the partial request data in {@link Bundle} format, that will be sent to the provider during the initial candidate query stage, which will not contain sensitive user information
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getCandidateQueryData() {
|
||||
return candidateQueryData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the complete request data in {@link Bundle} format, consisting of all the data that will be sent to the provider during the final credential creation stage
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getCredentialData() {
|
||||
return credentialData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the origin of the request, only settable by a browser
|
||||
*/
|
||||
@Nullable
|
||||
public String getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getRequestJson() {
|
||||
return requestJson;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ResultReceiver getResultReceiver() {
|
||||
return resultReceiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of the credential to be created or saved
|
||||
*/
|
||||
@NonNull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CreateCredentialRequest> CREATOR = findCreator(CreateCredentialRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Data interface for the response of creating or saving a user credential.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class CreateCredentialResponse extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getType")
|
||||
@NonNull
|
||||
public final String type;
|
||||
@Field(value = 2, getterName = "getData")
|
||||
@NonNull
|
||||
public final Bundle data;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link CreateCredentialResponse}
|
||||
*/
|
||||
@Constructor
|
||||
public CreateCredentialResponse(@Param(1) @NonNull String type, @Param(2) @NonNull Bundle data) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* the data of the credential that was created or saved, in the form of a {@link Bundle}
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of the credential that was created or saved
|
||||
*/
|
||||
@NonNull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CreateCredentialResponse> CREATOR = findCreator(CreateCredentialResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Represents a user credential that can be used to authenticate to your app.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class Credential extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getType")
|
||||
@NonNull
|
||||
public final String type;
|
||||
@Field(value = 2, getterName = "getData")
|
||||
@NonNull
|
||||
public final Bundle data;
|
||||
|
||||
/**
|
||||
* constructs an instance of Credential
|
||||
* @param type the type of the credential
|
||||
* @param data the data associated with the credential
|
||||
*/
|
||||
@Constructor
|
||||
public Credential(@Param(1) @NonNull String type, @Param(2) @NonNull Bundle data) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* the data associated with the credential
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of the credential
|
||||
*/
|
||||
@NonNull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<Credential> CREATOR = findCreator(Credential.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
|
||||
@SafeParcelable.Class
|
||||
@Hide
|
||||
public class CredentialInformation extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getPackageName")
|
||||
@Nullable
|
||||
private final String packageName;
|
||||
@Field(value = 2, getterName = "getNumPasswordCredentials")
|
||||
private final int numPasswordCredentials;
|
||||
@Field(value = 3, getterName = "getNumPasskeyCredentials")
|
||||
private final int numPasskeyCredentials;
|
||||
@Field(value = 4, getterName = "getNumGoogleIdCredentials")
|
||||
private final int numGoogleIdCredentials;
|
||||
@Field(value = 5, getterName = "getNumCustomCredentials")
|
||||
private final int numCustomCredentials;
|
||||
|
||||
@Constructor
|
||||
public CredentialInformation(@Param(1) @Nullable String packageName, @Param(2) int numPasswordCredentials, @Param(3) int numPasskeyCredentials, @Param(4) int numGoogleIdCredentials, @Param(5) int numCustomCredentials) {
|
||||
this.packageName = packageName;
|
||||
this.numPasswordCredentials = numPasswordCredentials;
|
||||
this.numPasskeyCredentials = numPasskeyCredentials;
|
||||
this.numGoogleIdCredentials = numGoogleIdCredentials;
|
||||
this.numCustomCredentials = numCustomCredentials;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public int getNumPasswordCredentials() {
|
||||
return numPasswordCredentials;
|
||||
}
|
||||
|
||||
public int getNumPasskeyCredentials() {
|
||||
return numPasskeyCredentials;
|
||||
}
|
||||
|
||||
public int getNumGoogleIdCredentials() {
|
||||
return numGoogleIdCredentials;
|
||||
}
|
||||
|
||||
public int getNumCustomCredentials() {
|
||||
return numCustomCredentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CredentialInformation> CREATOR = findCreator(CredentialInformation.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SafeParcelable.Class
|
||||
@Hide
|
||||
public class CredentialInformationRequest extends AbstractSafeParcelable {
|
||||
@Field(1)
|
||||
@Nullable
|
||||
public final List<String> packageNames;
|
||||
|
||||
@Constructor
|
||||
public CredentialInformationRequest(@Param(1) @Nullable List<String> packageNames) {
|
||||
this.packageNames = packageNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CredentialInformationRequest> CREATOR = findCreator(CredentialInformationRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SafeParcelable.Class
|
||||
@Hide
|
||||
public class CredentialInformationResponse extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getCredentialInformationList")
|
||||
@Nullable
|
||||
private final List<CredentialInformation> credentialInformationList;
|
||||
|
||||
@Constructor
|
||||
public CredentialInformationResponse(@Param(1) @Nullable List<CredentialInformation> credentialInformationList) {
|
||||
this.credentialInformationList = credentialInformationList;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<CredentialInformation> getCredentialInformationList() {
|
||||
return credentialInformationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CredentialInformationResponse> CREATOR = findCreator(CredentialInformationResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
|
||||
/**
|
||||
* Base class for getting a specific type of credentials.
|
||||
* <p>
|
||||
* {@link GetCredentialRequest} will be composed of a list of {@link CredentialOption} subclasses to indicate the specific credential types and
|
||||
* configurations that your app accepts.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class CredentialOption extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getType")
|
||||
private final String type;
|
||||
@Field(value = 2, getterName = "getCredentialRetrievalData")
|
||||
private final Bundle credentialRetrievalData;
|
||||
@Field(value = 3, getterName = "getCandidateQueryData")
|
||||
private final Bundle candidateQueryData;
|
||||
@Field(value = 4, getterName = "getRequestMatcher")
|
||||
private final String requestMatcher;
|
||||
@Field(value = 5, getterName = "getRequestType")
|
||||
@Deprecated
|
||||
private final String requestType;
|
||||
@Field(value = 6, getterName = "getProtocolType")
|
||||
@Deprecated
|
||||
private final String protocolType;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link CredentialOption}
|
||||
*
|
||||
* @param type the type of the credential to be requested
|
||||
* @param credentialRetrievalData the retrieval data in {@link Bundle} format
|
||||
* @param candidateQueryData the partial request data in the {@link Bundle} format that will be sent to the provider during the initial candidate query stage, which will not contain sensitive user information
|
||||
* @param requestMatcher the criteria used to filter the request (for instance, age 21)
|
||||
* @param requestType deprecated
|
||||
* @param protocolType deprecated
|
||||
*/
|
||||
@Constructor
|
||||
public CredentialOption(@Param(1) String type, @Param(2) Bundle credentialRetrievalData, @Param(3) Bundle candidateQueryData, @Param(4) String requestMatcher, @Deprecated @Param(5) String requestType, @Deprecated @Param(6) String protocolType) {
|
||||
this.type = type;
|
||||
this.credentialRetrievalData = credentialRetrievalData;
|
||||
this.candidateQueryData = candidateQueryData;
|
||||
this.requestMatcher = requestMatcher;
|
||||
this.requestType = requestType;
|
||||
this.protocolType = protocolType;
|
||||
}
|
||||
|
||||
/**
|
||||
* the partial request data in the {@link Bundle} format that will be sent to the provider during the initial candidate query stage, which will not contain sensitive user information
|
||||
*/
|
||||
public Bundle getCandidateQueryData() {
|
||||
return candidateQueryData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the retrieval data in {@link Bundle} format
|
||||
*/
|
||||
public Bundle getCredentialRetrievalData() {
|
||||
return credentialRetrievalData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public String getProtocolType() {
|
||||
return protocolType;
|
||||
}
|
||||
|
||||
/**
|
||||
* the criteria used to filter the request (for instance, age 21)
|
||||
*/
|
||||
public String getRequestMatcher() {
|
||||
return requestMatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public String getRequestType() {
|
||||
return requestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of the credential to be requested
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CredentialOption> CREATOR = findCreator(CredentialOption.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* The state of the primary provider's credentials
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class CredentialTransferCapabilities extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getResponseBundle")
|
||||
private final Bundle responseBundle;
|
||||
|
||||
@Constructor
|
||||
public CredentialTransferCapabilities(@Param(1) Bundle responseBundle) {
|
||||
this.responseBundle = responseBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of requested credentials.
|
||||
*/
|
||||
@Nullable
|
||||
public final Integer getNumCustomCredentials(@NonNull String key) {
|
||||
if (this.responseBundle.containsKey(key)) {
|
||||
return this.responseBundle.getInt(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of passkeys.
|
||||
*/
|
||||
@Nullable
|
||||
public final Integer getNumPasskeys() {
|
||||
if (this.responseBundle.containsKey("NUM_PASSKEYS")) {
|
||||
return this.responseBundle.getInt("NUM_PASSKEYS");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of passwords.
|
||||
*/
|
||||
@Nullable
|
||||
public final Integer getNumPasswords() {
|
||||
if (this.responseBundle.containsKey("NUM_PASSWORDS")) {
|
||||
return this.responseBundle.getInt("NUM_PASSWORDS");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final CallingAppInfoParcelable getProviderAppInfo() {
|
||||
return (CallingAppInfoParcelable) this.responseBundle.getParcelable("PROVIDER_APP_INFO");
|
||||
}
|
||||
|
||||
/**
|
||||
* the bundle containing the credential transfer capabilities.
|
||||
*/
|
||||
public Bundle getResponseBundle() {
|
||||
return responseBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of credentials.
|
||||
*/
|
||||
@Nullable
|
||||
public final Integer getTotalNumCredentials() {
|
||||
if (this.responseBundle.containsKey("TOTAL_NUM_CREDENTIALS")) {
|
||||
return this.responseBundle.getInt("TOTAL_NUM_CREDENTIALS");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total size of credentials in bytes.
|
||||
*/
|
||||
@Nullable
|
||||
public final Long getTotalSizeBytes() {
|
||||
if (this.responseBundle.containsKey("TOTAL_SIZE_BYTES")) {
|
||||
return this.responseBundle.getLong("TOTAL_SIZE_BYTES");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CredentialTransferCapabilities> CREATOR = findCreator(CredentialTransferCapabilities.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Request for exporting credentials to primary credential provider.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ExportCredentialsToDeviceSetupRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getUri")
|
||||
@NonNull
|
||||
private final Uri uri;
|
||||
@Field(value = 2, getterName = "getRequestData")
|
||||
@NonNull
|
||||
private final Bundle requestData;
|
||||
|
||||
/**
|
||||
* @param uri the file URI responsible for the export transport. The export provider will write the credentials here.
|
||||
* @param requestData the request bundle
|
||||
*/
|
||||
@Constructor
|
||||
public ExportCredentialsToDeviceSetupRequest(@NonNull @Param(1) Uri uri, @NonNull @Param(2) Bundle requestData) {
|
||||
this.uri = uri;
|
||||
this.requestData = requestData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the request bundle
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getRequestData() {
|
||||
return requestData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the file URI responsible for the export transport. The export provider will write the credentials here.
|
||||
*/
|
||||
@NonNull
|
||||
public Uri getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ExportCredentialsToDeviceSetupRequest> CREATOR = findCreator(ExportCredentialsToDeviceSetupRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response for exporting the credentials to the primary provider
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ExportCredentialsToDeviceSetupResponse extends AbstractSafeParcelable {
|
||||
@Field(1)
|
||||
@NonNull
|
||||
public final Bundle responseBundle;
|
||||
|
||||
/**
|
||||
* @param responseBundle the bundle containing response extras.
|
||||
*/
|
||||
@Constructor
|
||||
public ExportCredentialsToDeviceSetupResponse(@NonNull @Param(1) Bundle responseBundle) {
|
||||
this.responseBundle = responseBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of credentials failed to stored.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public final Integer getNumFailure() {
|
||||
if (this.responseBundle.containsKey("NUM_FAILURE")) {
|
||||
return this.responseBundle.getInt("NUM_FAILURE");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of credentials that were ignored by the provider.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public final Integer getNumIgnored() {
|
||||
if (this.responseBundle.containsKey("NUM_IGNORED")) {
|
||||
return this.responseBundle.getInt("NUM_IGNORED");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of credentials successfully stored.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public final Integer getNumSuccess() {
|
||||
if (this.responseBundle.containsKey("NUM_SUCCESS")) {
|
||||
return this.responseBundle.getInt("NUM_SUCCESS");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider app info.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public final CallingAppInfoParcelable getProviderAppInfo() {
|
||||
return this.responseBundle.getParcelable("PROVIDER_APP_INFO");
|
||||
}
|
||||
|
||||
/**
|
||||
* the bundle containing response extras.
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getResponseBundle() {
|
||||
return responseBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ExportCredentialsToDeviceSetupResponse> CREATOR = findCreator(ExportCredentialsToDeviceSetupResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Data interface for retrieving a user credential.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class GetCredentialRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getCredentialOptions")
|
||||
@NonNull
|
||||
private final List<CredentialOption> credentialOptions;
|
||||
@Field(value = 2, getterName = "getData")
|
||||
@NonNull
|
||||
private final Bundle data;
|
||||
@Field(value = 3, getterName = "getOrigin")
|
||||
@Nullable
|
||||
private final String origin;
|
||||
@Field(value = 4, getterName = "getResultReceiver")
|
||||
@Deprecated
|
||||
@NonNull
|
||||
private final ResultReceiver resultReceiver;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link GetCredentialRequest}
|
||||
*
|
||||
* @param credentialOptions the list of credential options
|
||||
* @param data the additional data to be used for retrieving the credential
|
||||
* @param origin the origin of the request, only settable by a browser
|
||||
* @param resultReceiver deprecated
|
||||
*/
|
||||
@Constructor
|
||||
public GetCredentialRequest(@NonNull @Param(1) List<CredentialOption> credentialOptions, @NonNull @Param(2) Bundle data, @Nullable @Param(3) String origin, @Deprecated @NonNull @Param(4) ResultReceiver resultReceiver) {
|
||||
this.credentialOptions = credentialOptions;
|
||||
this.data = data;
|
||||
this.origin = origin;
|
||||
this.resultReceiver = resultReceiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* the list of credential options
|
||||
*/
|
||||
@NonNull
|
||||
public List<CredentialOption> getCredentialOptions() {
|
||||
return credentialOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* the additional data to be used for retrieving the credential
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* the origin of the request, only settable by a browser
|
||||
*/
|
||||
@Nullable
|
||||
public String getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public ResultReceiver getResultReceiver() {
|
||||
return resultReceiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<GetCredentialRequest> CREATOR = findCreator(GetCredentialRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Request for fetching the state of the credentials in the primary provider
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class GetCredentialTransferCapabilitiesRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getRequestData")
|
||||
private final Bundle requestData;
|
||||
|
||||
/**
|
||||
* @param requestData the request bundle
|
||||
*/
|
||||
@Constructor
|
||||
public GetCredentialTransferCapabilitiesRequest(@Param(1) Bundle requestData) {
|
||||
this.requestData = requestData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the request bundle
|
||||
*/
|
||||
public Bundle getRequestData() {
|
||||
return requestData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<GetCredentialTransferCapabilitiesRequest> CREATOR = findCreator(GetCredentialTransferCapabilitiesRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.HasApiKey;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
/**
|
||||
* A client for the Identity Credentials API.
|
||||
*/
|
||||
public interface IdentityCredentialClient extends HasApiKey<Api.ApiOptions.NoOptions> {
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link ClearCreationOptionsResponse} on success or throws an {@code ApiException} on failure,
|
||||
* when attempting to clear from the creation option registry that should match one registered with {@link IdentityCredentialClient#registerCreationOptions}.
|
||||
*
|
||||
* @param request informs the type of operation
|
||||
*/
|
||||
@NonNull
|
||||
Task<ClearCreationOptionsResponse> clearCreationOptions(@NonNull ClearCreationOptionsRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link ClearCredentialStateResponse} on success or throws an {@code ApiException} on failure,
|
||||
* when attempting to clear credential state.
|
||||
*
|
||||
* @param request specifies the clear credential state request
|
||||
*/
|
||||
@NonNull
|
||||
Task<ClearCredentialStateResponse> clearCredentialState(@NonNull ClearCredentialStateRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link ClearExportResponse} on success or throws an {@code ApiException} on failure, when
|
||||
* attempting to clear from the registry.
|
||||
*
|
||||
* @param request informs the type of operation
|
||||
*/
|
||||
@NonNull
|
||||
Task<ClearExportResponse> clearExport(@NonNull ClearExportRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link ClearRegistryResponse} on success or throws an {@code ApiException} on failure, when attempting to clear from the registry.
|
||||
*
|
||||
* @param request informs the type of operation
|
||||
*/
|
||||
@NonNull
|
||||
Task<ClearRegistryResponse> clearRegistry(@NonNull ClearRegistryRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link CreateCredentialHandle} on success or throws an {@code ApiException} on failure.
|
||||
*
|
||||
* @param request containing parameters of the credential to be created
|
||||
*/
|
||||
@NonNull
|
||||
Task<CreateCredentialHandle> createCredential(@NonNull CreateCredentialRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link PendingGetCredentialHandle} on success or throws an {@code ApiException} on failure.
|
||||
*
|
||||
* @param request the request for getting the credential
|
||||
*/
|
||||
@NonNull
|
||||
Task<PendingGetCredentialHandle> getCredential(@NonNull GetCredentialRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link PendingImportCredentialsHandle} on success or throws an {@code ApiException} on failure.
|
||||
*
|
||||
* @param request the information needed to import credentials from another provider
|
||||
*/
|
||||
@NonNull
|
||||
Task<PendingImportCredentialsHandle> importCredentials(@NonNull ImportCredentialsRequest request);
|
||||
|
||||
/**
|
||||
* Register the creation options that may serve a {@link IdentityCredentialClient#createCredential} transaction.
|
||||
* <p>
|
||||
* Returns a {@link Task} which asynchronously generates a {@link RegisterCreationOptionsResponse} on success or throws an {@code ApiException} on
|
||||
* failure, when attempting to write to the registry.
|
||||
*
|
||||
* @param request specifies the credential information being written to the registry
|
||||
*/
|
||||
@NonNull
|
||||
Task<RegisterCreationOptionsResponse> registerCreationOptions(@NonNull RegisterCreationOptionsRequest request);
|
||||
|
||||
/**
|
||||
* RRegister the credential options that may serve a {@link IdentityCredentialClient#getCredential} transaction.
|
||||
* <p>
|
||||
* Returns a {@link Task} which asynchronously generates a {@link RegistrationResponse} on success or throws an {@code ApiException} on failure, when
|
||||
* attempting to write to the registry.
|
||||
*
|
||||
* @param request specifies the credential information being written to the registry
|
||||
*/
|
||||
@NonNull
|
||||
Task<RegistrationResponse> registerCredentials(@NonNull RegistrationRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link RegisterExportResponse} on success or throws an {@code ApiException} on failure, when
|
||||
* attempting to write to the registry.
|
||||
*
|
||||
* @param request specifies the information being written to the registry
|
||||
*/
|
||||
@NonNull
|
||||
Task<RegisterExportResponse> registerExport(@NonNull RegisterExportRequest request);
|
||||
|
||||
/**
|
||||
* Returns a {@link Task} which asynchronously generates a {@link SignalCredentialStateResponse} on success or throws an {@code ApiException} on failure,
|
||||
* when attempting to signal providers with credential state.
|
||||
*
|
||||
* @param request specifies the signal credential state request
|
||||
*/
|
||||
@NonNull
|
||||
Task<SignalCredentialStateResponse> signalCredentialState(@NonNull SignalCredentialStateRequest request);
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.microg.gms.identitycredentials.IdentityCredentialClientImpl;
|
||||
|
||||
/**
|
||||
* Entry point for Identity Credential API.
|
||||
*/
|
||||
public final class IdentityCredentialManager {
|
||||
/**
|
||||
* Creates a new instance of {@link IdentityCredentialClient}.
|
||||
*
|
||||
* @param activity the activity that is using this client.
|
||||
*/
|
||||
@NonNull
|
||||
public static IdentityCredentialClient getClient(@NonNull Activity activity) {
|
||||
return new IdentityCredentialClientImpl(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link IdentityCredentialClient}.
|
||||
*
|
||||
* @param context the context that is using this client.
|
||||
*/
|
||||
@NonNull
|
||||
public static IdentityCredentialClient getClient(@NonNull Context context) {
|
||||
return new IdentityCredentialClientImpl(context);
|
||||
}
|
||||
|
||||
private IdentityCredentialManager() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Request for importing credentials from primary credential provider.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ImportCredentialsForDeviceSetupRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getRequestJson")
|
||||
@NonNull
|
||||
private final String requestJson;
|
||||
@Field(value = 2, getterName = "getUri")
|
||||
@NonNull
|
||||
private final Uri uri;
|
||||
@Field(value = 3, getterName = "getRequestData")
|
||||
@NonNull
|
||||
private final Bundle requestData;
|
||||
|
||||
/**
|
||||
* @param requestJson the request in JSON format, based on the CXF prototcol
|
||||
* @param uri the file URI responsible for the credential transport. The importing provider will read the credentials from here.
|
||||
* @param requestData the request bundle
|
||||
*/
|
||||
@Constructor
|
||||
public ImportCredentialsForDeviceSetupRequest(@NonNull @Param(1) String requestJson, @NonNull @Param(2) Uri uri, @NonNull @Param(3) Bundle requestData) {
|
||||
this.requestJson = requestJson;
|
||||
this.uri = uri;
|
||||
this.requestData = requestData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the request bundle
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getRequestData() {
|
||||
return requestData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the request in JSON format, based on the CXF prototcol
|
||||
*/
|
||||
@NonNull
|
||||
public String getRequestJson() {
|
||||
return requestJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* the file URI responsible for the credential transport. The importing provider will read the credentials from here.
|
||||
*/
|
||||
@NonNull
|
||||
public Uri getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ImportCredentialsForDeviceSetupRequest> CREATOR = findCreator(ImportCredentialsForDeviceSetupRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response for importing the credentials from the primary provider
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ImportCredentialsForDeviceSetupResponse extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getResponseBundle")
|
||||
@NonNull
|
||||
private final Bundle responseBundle;
|
||||
|
||||
/**
|
||||
* @param responseBundle the bundle containing response extras.
|
||||
*/
|
||||
@Constructor
|
||||
public ImportCredentialsForDeviceSetupResponse(@NonNull @Param(1) Bundle responseBundle) {
|
||||
this.responseBundle = responseBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* the bundle containing response extras.
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getResponseBundle() {
|
||||
return responseBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider app info.
|
||||
*/
|
||||
@Nullable
|
||||
public final CallingAppInfoParcelable getProviderAppInfo() {
|
||||
return this.responseBundle.getParcelable("PROVIDER_APP_INFO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ImportCredentialsForDeviceSetupResponse> CREATOR = findCreator(ImportCredentialsForDeviceSetupResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Request for importing credentials from another credential provider.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class ImportCredentialsRequest extends AbstractSafeParcelable {
|
||||
@NonNull
|
||||
public static final String REQUEST_TYPE = "androidx.identitycredentials.TYPE_CREDENTIALS_SYNC";
|
||||
@Field(value = 1, getterName = "getRequestJson")
|
||||
@NonNull
|
||||
private final String requestJson;
|
||||
@Field(value = 2, getterName = "getUri")
|
||||
@NonNull
|
||||
private final Uri uri;
|
||||
|
||||
/**
|
||||
* @param requestJson the request in JSON format, based on the CXF prototcol
|
||||
* @param uri the file URI responsible for the export transport
|
||||
*/
|
||||
@Constructor
|
||||
public ImportCredentialsRequest(@NonNull @Param(1) String requestJson, @NonNull @Param(2) Uri uri) {
|
||||
this.requestJson = requestJson;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* the request in JSON format, based on the CXF prototcol
|
||||
*/
|
||||
@NonNull
|
||||
public final String getRequestJson() {
|
||||
return this.requestJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* the file URI responsible for the export transport
|
||||
*/
|
||||
@NonNull
|
||||
public final Uri getUri() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<ImportCredentialsRequest> CREATOR = findCreator(ImportCredentialsRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Returns a response for the {@link IdentityCredentialClient#getCredential} API that can be used to launch the credential selector UIs to
|
||||
* finalize on a credential of the user's choice that can be used for app sign-in.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class PendingGetCredentialHandle extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getPendingIntent")
|
||||
@NonNull
|
||||
private final PendingIntent pendingIntent;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link PendingGetCredentialHandle}
|
||||
*
|
||||
* @param pendingIntent the {@link PendingIntent} to launch the credential selector UI
|
||||
*/
|
||||
@Constructor
|
||||
public PendingGetCredentialHandle(@NonNull @Param(1) PendingIntent pendingIntent) {
|
||||
this.pendingIntent = pendingIntent;
|
||||
}
|
||||
|
||||
/**
|
||||
* the {@link PendingIntent} to launch the credential selector UI
|
||||
*/
|
||||
@NonNull
|
||||
public PendingIntent getPendingIntent() {
|
||||
return pendingIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<PendingGetCredentialHandle> CREATOR = findCreator(PendingGetCredentialHandle.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response to {@link IdentityCredentialClient#importCredentials} API, containing a {@link PendingIntent} that can be used to launch a selector
|
||||
* that allows the user to select a credential provider to import credentials from
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class PendingImportCredentialsHandle extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getPendingIntent")
|
||||
@NonNull
|
||||
private final PendingIntent pendingIntent;
|
||||
|
||||
/**
|
||||
* @param pendingIntent the intent that launches the selector UI
|
||||
*/
|
||||
@Constructor
|
||||
public PendingImportCredentialsHandle(@NonNull @Param(1) PendingIntent pendingIntent) {
|
||||
this.pendingIntent = pendingIntent;
|
||||
}
|
||||
|
||||
/**
|
||||
* the intent that launches the selector UI
|
||||
*/
|
||||
@NonNull
|
||||
public PendingIntent getPendingIntent() {
|
||||
return pendingIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<PendingImportCredentialsHandle> CREATOR = findCreator(PendingImportCredentialsHandle.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* A registration request to store provision / creation candidates' metadata and matcher logic.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class RegisterCreationOptionsRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getCreateOptions")
|
||||
@NonNull
|
||||
private final byte[] createOptions;
|
||||
|
||||
@Field(value = 2, getterName = "getMatcher")
|
||||
@NonNull
|
||||
private final byte[] matcher;
|
||||
|
||||
@Field(value = 3, getterName = "getType")
|
||||
@NonNull
|
||||
private final String type;
|
||||
|
||||
@Field(value = 4, getterName = "getId")
|
||||
@NonNull
|
||||
private final String id;
|
||||
|
||||
@Field(value = 5, getterName = "getFulfillmentActionName", defaultValue = "")
|
||||
@NonNull
|
||||
private final String fulfillmentActionName;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link RegisterCreationOptionsRequest}
|
||||
*
|
||||
* @param createOptions the creation candidates data used for display and matching purpose, as a ByteArray blob
|
||||
* @param matcher the matcher for the credential info, as a ByteArray blob
|
||||
* @param type the type of the creation options registered, matching the {@code CreateCredentialRequest.type} that this registry can handle
|
||||
* @param id the id of the given registry data, so as not to overwrite existing data of different id
|
||||
* @param fulfillmentActionName optionally specify a different intent action to be used for launching the fulfillment activity when one of the registered credentials is selected by the user; otherwise, the default action {@code "androidx.credentials.registry.provider.action.CREATE_CREDENTIAL"} will be used
|
||||
*/
|
||||
@Constructor
|
||||
public RegisterCreationOptionsRequest(@NonNull @Param(1) byte[] createOptions, @NonNull @Param(2) byte[] matcher, @NonNull @Param(3) String type, @NonNull @Param(4) String id, @NonNull @Param(5) String fulfillmentActionName) {
|
||||
this.createOptions = createOptions;
|
||||
this.matcher = matcher;
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.fulfillmentActionName = fulfillmentActionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* the creation candidates data used for display and matching purpose, as a ByteArray blob
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] getCreateOptions() {
|
||||
return createOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* optionally specify a different intent action to be used for launching the fulfillment activity when one of the registered credentials is selected
|
||||
* by the user; otherwise, the default action {@code "androidx.credentials.registry.provider.action.CREATE_CREDENTIAL"} will be used
|
||||
*/
|
||||
@NonNull
|
||||
public String getFulfillmentActionName() {
|
||||
return fulfillmentActionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* the id of the given registry data, so as not to overwrite existing data of different id
|
||||
*/
|
||||
@NonNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* the matcher for the credential info, as a ByteArray blob
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] getMatcher() {
|
||||
return matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of the creation options registered, matching the {@code CreateCredentialRequest.type} that this registry can handle
|
||||
*/
|
||||
@NonNull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<RegisterCreationOptionsRequest> CREATOR = findCreator(RegisterCreationOptionsRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response object for the {@link IdentityCredentialClient#registerCredentials} API.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class RegisterCreationOptionsResponse extends AbstractSafeParcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<RegisterCreationOptionsResponse> CREATOR = findCreator(RegisterCreationOptionsResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* A registration request for declaring that the callee is a credential provider that supports exporting of credentials to other credential providers
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class RegisterExportRequest extends AbstractSafeParcelable {
|
||||
@NonNull
|
||||
public static final String REQUEST_TYPE = "androidx.identitycredentials.TYPE_CREDENTIALS_SYNC";
|
||||
|
||||
@Field(value = 1, getterName = "getMatcher")
|
||||
@NonNull
|
||||
private final byte[] matcher;
|
||||
@Field(value = 2, getterName = "getData")
|
||||
@NonNull
|
||||
private final byte[] data;
|
||||
@Field(value = 3, getterName = "getId")
|
||||
@NonNull
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* @param matcher the matcher executor that runs the matching logic
|
||||
* @param data any data to be registered along with the ability to export, typically empty for this use-case
|
||||
* @param id the ID of the given registry data, so as not to overwrite existing data of different ID
|
||||
*/
|
||||
@Constructor
|
||||
public RegisterExportRequest(@NonNull @Param(1) byte[] matcher, @NonNull @Param(2) byte[] data, @NonNull @Param(3) String id) {
|
||||
this.matcher = matcher;
|
||||
this.data = data;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* any data to be registered along with the ability to export, typically empty for this use-case
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* the ID of the given registry data, so as not to overwrite existing data of different ID
|
||||
*/
|
||||
@NonNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* the matcher executor that runs the matching logic
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] getMatcher() {
|
||||
return matcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<RegisterExportRequest> CREATOR = findCreator(RegisterExportRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response for registering the ability to export credentials to other providers
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class RegisterExportResponse extends AbstractSafeParcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<RegisterExportResponse> CREATOR = findCreator(RegisterExportResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A registration request to store credential metadata and matcher logic.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class RegistrationRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getCredentials")
|
||||
@NonNull
|
||||
private final byte[] credentials;
|
||||
@Field(value = 2, getterName = "getMatcher")
|
||||
@NonNull
|
||||
private final byte[] matcher;
|
||||
@Field(value = 3, getterName = "getType", defaultValue = "\"\"")
|
||||
@NonNull
|
||||
private final String type;
|
||||
@Field(value = 4, getterName = "getRequestType", defaultValue = "\"\"")
|
||||
@NonNull
|
||||
@Deprecated
|
||||
private final String requestType;
|
||||
@Field(value = 5, getterName = "getProtocolTypes", defaultValue = "java.util.Collections.emptyList()")
|
||||
@NonNull
|
||||
@Deprecated
|
||||
private final List<String> protocolTypes;
|
||||
@Field(value = 6, getterName = "getId", defaultValue = "\"\"")
|
||||
@NonNull
|
||||
private final String id;
|
||||
|
||||
@Field(value = 7, getterName = "getFulfillmentActionName", defaultValue = "\"\"")
|
||||
@NonNull
|
||||
private final String fulfillmentActionName;
|
||||
|
||||
public RegistrationRequest(@NonNull byte[] credentials, @NonNull byte[] matcher, @NonNull String type, @Deprecated @NonNull String requestType, @Deprecated @NonNull List<String> protocolTypes) {
|
||||
this(credentials, matcher, type, requestType, protocolTypes, "", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link RegistrationRequest}
|
||||
*
|
||||
* @param credentials the credential information as a ByteArray blob
|
||||
* @param matcher the matcher for the credential info, also as a ByteArray blob
|
||||
* @param type the type of credentials matching the given registry data
|
||||
* @param requestType deprecated
|
||||
* @param protocolTypes deprecated
|
||||
* @param id the id of the given registry data, so as not to overwrite existing data of different id
|
||||
* @param fulfillmentActionName optionally specify a different intent action to be used for launching the fulfillment activity when one of the registered credentials is selected by the user; otherwise, the default action {@code "androidx.credentials.registry.provider.action.GET_CREDENTIAL"} will be used
|
||||
*/
|
||||
@Constructor
|
||||
public RegistrationRequest(@NonNull @Param(1) byte[] credentials, @NonNull @Param(2) byte[] matcher, @NonNull @Param(3) String type, @Deprecated @NonNull @Param(4) String requestType, @Deprecated @NonNull @Param(5) List<String> protocolTypes, @NonNull @Param(6) String id, @NonNull @Param(7) String fulfillmentActionName) {
|
||||
this.credentials = credentials;
|
||||
this.matcher = matcher;
|
||||
this.type = type;
|
||||
this.requestType = requestType;
|
||||
this.protocolTypes = protocolTypes;
|
||||
this.id = id;
|
||||
this.fulfillmentActionName = fulfillmentActionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* the credential information as a ByteArray blob
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* optionally specify a different intent action to be used for launching the fulfillment activity when one of the registered credentials is selected
|
||||
* by the user; otherwise, the default action {@code "androidx.credentials.registry.provider.action.GET_CREDENTIAL"} will be used
|
||||
*/
|
||||
@NonNull
|
||||
public String getFulfillmentActionName() {
|
||||
return fulfillmentActionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* the id of the given registry data, so as not to overwrite existing data of different id
|
||||
*/
|
||||
@NonNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* the matcher for the credential info, also as a ByteArray blob
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] getMatcher() {
|
||||
return matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public List<String> getProtocolTypes() {
|
||||
return protocolTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public String getRequestType() {
|
||||
return requestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of credentials matching the given registry data
|
||||
*/
|
||||
@NonNull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<RegistrationRequest> CREATOR = findCreator(RegistrationRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response object for the IdentityCredentialClient.registerCredentials API.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class RegistrationResponse extends AbstractSafeParcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<RegistrationResponse> CREATOR = findCreator(RegistrationResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Data interface for signaling a user's credential state from the RPs to the credential providers.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class SignalCredentialStateRequest extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getType")
|
||||
@NonNull
|
||||
private final String type;
|
||||
|
||||
@Field(value = 2, getterName = "getOrigin")
|
||||
@Nullable
|
||||
private final String origin;
|
||||
|
||||
@Field(value = 3, getterName = "getRequestData")
|
||||
@NonNull
|
||||
private final Bundle requestData;
|
||||
|
||||
/**
|
||||
* constructs an instance of {@link SignalCredentialStateRequest}
|
||||
*
|
||||
* @param type the type of signal request being sent to the provider
|
||||
* @param origin the origin of the request, only settable by a browser
|
||||
* @param requestData the request data, containing the credential state information
|
||||
*/
|
||||
@Constructor
|
||||
public SignalCredentialStateRequest(@NonNull @Param(1) String type, @Param(2) @Nullable String origin, @NonNull @Param(3) Bundle requestData) {
|
||||
this.type = type;
|
||||
this.origin = origin;
|
||||
this.requestData = requestData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the origin of the request, only settable by a browser
|
||||
*/
|
||||
@Nullable
|
||||
public String getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* the request data, containing the credential state information
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getRequestData() {
|
||||
return requestData;
|
||||
}
|
||||
|
||||
/**
|
||||
* the type of signal request being sent to the provider
|
||||
*/
|
||||
@NonNull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<SignalCredentialStateRequest> CREATOR = findCreator(SignalCredentialStateRequest.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.identitycredentials;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Response of a signal credential state request.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class SignalCredentialStateResponse extends AbstractSafeParcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<SignalCredentialStateResponse> CREATOR = findCreator(SignalCredentialStateResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.identitycredentials;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.ApiMetadata;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.common.api.internal.ConnectionCallbacks;
|
||||
import com.google.android.gms.common.api.internal.OnConnectionFailedListener;
|
||||
import com.google.android.gms.identitycredentials.ClearCreationOptionsRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearCredentialStateRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearExportRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearRegistryRequest;
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialRequest;
|
||||
import com.google.android.gms.identitycredentials.GetCredentialRequest;
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsRequest;
|
||||
import com.google.android.gms.identitycredentials.RegisterCreationOptionsRequest;
|
||||
import com.google.android.gms.identitycredentials.RegisterExportRequest;
|
||||
import com.google.android.gms.identitycredentials.RegistrationRequest;
|
||||
import com.google.android.gms.identitycredentials.SignalCredentialStateRequest;
|
||||
import com.google.android.gms.identitycredentials.internal.IIdentityCredentialCallbacks;
|
||||
import com.google.android.gms.identitycredentials.internal.IIdentityCredentialService;
|
||||
import org.microg.gms.common.GmsClient;
|
||||
import org.microg.gms.common.GmsService;
|
||||
|
||||
public class IdentityCredentialApiClient extends GmsClient<IIdentityCredentialService> {
|
||||
public static final Api<Api.ApiOptions.NoOptions> API = new Api<>(
|
||||
(options, context, looper, clientSettings, callbacks, connectionFailedListener) ->
|
||||
new IdentityCredentialApiClient(context, callbacks, connectionFailedListener));
|
||||
|
||||
public IdentityCredentialApiClient(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||
super(context, callbacks, connectionFailedListener, GmsService.IDENTITY_CREDENTIALS.ACTION);
|
||||
serviceId = GmsService.IDENTITY_CREDENTIALS.SERVICE_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIdentityCredentialService interfaceFromBinder(IBinder binder) {
|
||||
return IIdentityCredentialService.Stub.asInterface(binder);
|
||||
}
|
||||
|
||||
public void getCredential(IIdentityCredentialCallbacks callbacks, GetCredentialRequest request) {
|
||||
try {
|
||||
getServiceInterface().getCredential(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onGetCredential(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerCredentials(IIdentityCredentialCallbacks callbacks, RegistrationRequest request) {
|
||||
try {
|
||||
getServiceInterface().register(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onRegister(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void clearRegistry(IIdentityCredentialCallbacks callbacks, ClearRegistryRequest request) {
|
||||
try {
|
||||
getServiceInterface().clearRegistry(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onClearRegistry(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void importCredentials(IIdentityCredentialCallbacks callbacks, ImportCredentialsRequest request) {
|
||||
try {
|
||||
getServiceInterface().importCredentials(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onImportCredentials(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerExport(IIdentityCredentialCallbacks callbacks, RegisterExportRequest request) {
|
||||
try {
|
||||
getServiceInterface().registerExport(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onRegisterExport(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void createCredential(IIdentityCredentialCallbacks callbacks, CreateCredentialRequest request) {
|
||||
try {
|
||||
getServiceInterface().createCredential(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onCreateCredential(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerCreationOptions(IIdentityCredentialCallbacks callbacks, RegisterCreationOptionsRequest request) {
|
||||
try {
|
||||
getServiceInterface().registerCreationOptions(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onRegisterCreationOptions(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCredentialState(IIdentityCredentialCallbacks callbacks, ClearCredentialStateRequest request) {
|
||||
try {
|
||||
getServiceInterface().clearCredentialState(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onClearCredentialState(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void signalCredentialState(IIdentityCredentialCallbacks callbacks, SignalCredentialStateRequest request) {
|
||||
try {
|
||||
getServiceInterface().signalCredentialState(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onSignalCredentialState(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void clearExport(IIdentityCredentialCallbacks callbacks, ClearExportRequest request) {
|
||||
try {
|
||||
getServiceInterface().clearExport(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onClearExport(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCreationOptions(IIdentityCredentialCallbacks callbacks, ClearCreationOptionsRequest request) {
|
||||
try {
|
||||
getServiceInterface().clearCreationOptions(callbacks, request, ApiMetadata.SKIP);
|
||||
} catch (RemoteException e) {
|
||||
tryNotifyError(() -> callbacks.onClearCreationOptions(Status.INTERNAL_ERROR, null, ApiMetadata.SKIP));
|
||||
}
|
||||
}
|
||||
|
||||
private interface RemoteRunnable {
|
||||
void run() throws RemoteException;
|
||||
}
|
||||
|
||||
private static void tryNotifyError(RemoteRunnable runnable) {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.identitycredentials;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.ApiMetadata;
|
||||
import com.google.android.gms.common.api.GoogleApi;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.identitycredentials.ClearCreationOptionsRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearCreationOptionsResponse;
|
||||
import com.google.android.gms.identitycredentials.ClearCredentialStateRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearCredentialStateResponse;
|
||||
import com.google.android.gms.identitycredentials.ClearExportRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearExportResponse;
|
||||
import com.google.android.gms.identitycredentials.ClearRegistryRequest;
|
||||
import com.google.android.gms.identitycredentials.ClearRegistryResponse;
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialHandle;
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialRequest;
|
||||
import com.google.android.gms.identitycredentials.CreateCredentialResponse;
|
||||
import com.google.android.gms.identitycredentials.CredentialInformationResponse;
|
||||
import com.google.android.gms.identitycredentials.CredentialTransferCapabilities;
|
||||
import com.google.android.gms.identitycredentials.ExportCredentialsToDeviceSetupResponse;
|
||||
import com.google.android.gms.identitycredentials.GetCredentialRequest;
|
||||
import com.google.android.gms.identitycredentials.IdentityCredentialClient;
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsForDeviceSetupResponse;
|
||||
import com.google.android.gms.identitycredentials.ImportCredentialsRequest;
|
||||
import com.google.android.gms.identitycredentials.PendingGetCredentialHandle;
|
||||
import com.google.android.gms.identitycredentials.PendingImportCredentialsHandle;
|
||||
import com.google.android.gms.identitycredentials.RegisterCreationOptionsRequest;
|
||||
import com.google.android.gms.identitycredentials.RegisterCreationOptionsResponse;
|
||||
import com.google.android.gms.identitycredentials.RegisterExportRequest;
|
||||
import com.google.android.gms.identitycredentials.RegisterExportResponse;
|
||||
import com.google.android.gms.identitycredentials.RegistrationRequest;
|
||||
import com.google.android.gms.identitycredentials.RegistrationResponse;
|
||||
import com.google.android.gms.identitycredentials.SignalCredentialStateRequest;
|
||||
import com.google.android.gms.identitycredentials.SignalCredentialStateResponse;
|
||||
import com.google.android.gms.identitycredentials.internal.IIdentityCredentialCallbacks;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.gms.tasks.TaskCompletionSource;
|
||||
import org.microg.gms.common.api.PendingGoogleApiCall;
|
||||
|
||||
public class IdentityCredentialClientImpl extends GoogleApi<Api.ApiOptions.NoOptions> implements IdentityCredentialClient {
|
||||
public IdentityCredentialClientImpl(Context context) {
|
||||
super(context, IdentityCredentialApiClient.API, Api.ApiOptions.NO_OPTIONS);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<ClearCreationOptionsResponse> clearCreationOptions(@NonNull ClearCreationOptionsRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<ClearCreationOptionsResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.clearCreationOptions(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onClearCreationOptions(Status status, ClearCreationOptionsResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<ClearCredentialStateResponse> clearCredentialState(@NonNull ClearCredentialStateRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<ClearCredentialStateResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.clearCredentialState(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onClearCredentialState(Status status, ClearCredentialStateResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<ClearExportResponse> clearExport(@NonNull ClearExportRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<ClearExportResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.clearExport(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onClearExport(Status status, ClearExportResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<ClearRegistryResponse> clearRegistry(@NonNull ClearRegistryRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<ClearRegistryResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.clearRegistry(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onClearRegistry(Status status, ClearRegistryResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<CreateCredentialHandle> createCredential(@NonNull CreateCredentialRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<CreateCredentialHandle, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.createCredential(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onCreateCredential(Status status, CreateCredentialHandle handle, ApiMetadata apiMetadata) {
|
||||
complete(source, status, handle);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<PendingGetCredentialHandle> getCredential(@NonNull GetCredentialRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<PendingGetCredentialHandle, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.getCredential(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onGetCredential(Status status, PendingGetCredentialHandle handle, ApiMetadata apiMetadata) {
|
||||
complete(source, status, handle);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<PendingImportCredentialsHandle> importCredentials(@NonNull ImportCredentialsRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<PendingImportCredentialsHandle, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.importCredentials(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onImportCredentials(Status status, PendingImportCredentialsHandle handle, ApiMetadata apiMetadata) {
|
||||
complete(source, status, handle);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<RegisterCreationOptionsResponse> registerCreationOptions(@NonNull RegisterCreationOptionsRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<RegisterCreationOptionsResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.registerCreationOptions(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onRegisterCreationOptions(Status status, RegisterCreationOptionsResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<RegistrationResponse> registerCredentials(@NonNull RegistrationRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<RegistrationResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.registerCredentials(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onRegister(Status status, RegistrationResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<RegisterExportResponse> registerExport(@NonNull RegisterExportRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<RegisterExportResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.registerExport(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onRegisterExport(Status status, RegisterExportResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Task<SignalCredentialStateResponse> signalCredentialState(@NonNull SignalCredentialStateRequest request) {
|
||||
return scheduleTask((PendingGoogleApiCall<SignalCredentialStateResponse, IdentityCredentialApiClient>) (client, source) ->
|
||||
client.signalCredentialState(new BaseCallbacks() {
|
||||
@Override
|
||||
public void onSignalCredentialState(Status status, SignalCredentialStateResponse response, ApiMetadata apiMetadata) {
|
||||
complete(source, status, response);
|
||||
}
|
||||
}, request));
|
||||
}
|
||||
|
||||
private static <T> void complete(TaskCompletionSource<T> source, Status status, T result) {
|
||||
if (status != null && status.isSuccess()) {
|
||||
source.trySetResult(result);
|
||||
} else {
|
||||
source.trySetException(new ApiException(status == null ? Status.INTERNAL_ERROR : status));
|
||||
}
|
||||
}
|
||||
|
||||
// Empty defaults so each scheduleTask can override only the relevant callback.
|
||||
private static abstract class BaseCallbacks extends IIdentityCredentialCallbacks.Stub {
|
||||
@Override public void onGetCredential(Status status, PendingGetCredentialHandle handle, ApiMetadata apiMetadata) {}
|
||||
@Override public void onRegister(Status status, RegistrationResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onClearRegistry(Status status, ClearRegistryResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onImportCredentials(Status status, PendingImportCredentialsHandle handle, ApiMetadata apiMetadata) {}
|
||||
@Override public void onRegisterExport(Status status, RegisterExportResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onCreateCredentialLegacy(Status status, CreateCredentialResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onCreateCredential(Status status, CreateCredentialHandle handle, ApiMetadata apiMetadata) {}
|
||||
@Override public void onRegisterCreationOptions(Status status, RegisterCreationOptionsResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onClearCredentialState(Status status, ClearCredentialStateResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onSignalCredentialState(Status status, SignalCredentialStateResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onClearExport(Status status, ClearExportResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onImportCredentialsForDeviceSetup(Status status, ImportCredentialsForDeviceSetupResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onExportCredentialsToDeviceSetup(Status status, ExportCredentialsToDeviceSetupResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onGetCredentialTransferCapabilities(Status status, CredentialTransferCapabilities capabilities, ApiMetadata apiMetadata) {}
|
||||
@Override public void onClearCreationOptions(Status status, ClearCreationOptionsResponse response, ApiMetadata apiMetadata) {}
|
||||
@Override public void onGetCredentialInformation(Status status, CredentialInformationResponse response) {}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@ include ':play-services-fido'
|
|||
include ':play-services-games'
|
||||
include ':play-services-gcm'
|
||||
include ':play-services-gmscompliance'
|
||||
include ':play-services-identity-credentials'
|
||||
include ':play-services-iid'
|
||||
include ':play-services-location'
|
||||
include ':play-services-maps'
|
||||
|
|
@ -98,6 +99,7 @@ sublude ':play-services-droidguard:core'
|
|||
sublude ':play-services-fido:core'
|
||||
sublude ':play-services-fitness:core'
|
||||
sublude ':play-services-gmscompliance:core'
|
||||
sublude ':play-services-identity-credentials:core'
|
||||
sublude ':play-services-location:core'
|
||||
sublude ':play-services-location:core:base'
|
||||
sublude ':play-services-location:core:provider'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue