diff --git a/build.gradle b/build.gradle
index 296bd87097..d64e7e78a5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -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('\\.', ''))
diff --git a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java
index 97b1364265..0026c72789 100644
--- a/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java
+++ b/play-services-basement/src/main/java/org/microg/gms/common/GmsService.java
@@ -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),
diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle
index a348337ce1..b9697bd561 100644
--- a/play-services-core/build.gradle
+++ b/play-services-core/build.gradle
@@ -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')
diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml
index a17d7f03ef..ec46dd59de 100644
--- a/play-services-core/src/main/AndroidManifest.xml
+++ b/play-services-core/src/main/AndroidManifest.xml
@@ -649,6 +649,13 @@
android:theme="@style/Theme.App.Translucent"
android:excludeFromRecents="true"/>
+
+
{
+ 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).orEmpty()
+ if (serverClientId.isBlank()) {
+ return finishWithGetException(NoCredentialException("GoogleIdToken option missing serverClientId"))
+ }
+ val nonce = data.getString(GOOGLE_ID_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 readNestedParcelable(name: String, clazz: Class): 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"
+ }
+}
diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/GoogleIdService.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/GoogleIdService.kt
index 36e00c4fdb..56bb5aa903 100644
--- a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/GoogleIdService.kt
+++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/GoogleIdService.kt
@@ -168,7 +168,10 @@ const val GOOGLE_ID_ANDROIDX_AUTO_SELECT = "androidx.credentials.BUNDLE_KEY_IS_A
const val GOOGLE_ID_BUNDLE_KEY_ID = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_ID"
const val GOOGLE_ID_BUNDLE_KEY_ID_TOKEN = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_ID_TOKEN"
const val GOOGLE_ID_BUNDLE_KEY_DISPLAY_NAME = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_DISPLAY_NAME"
+const val GOOGLE_ID_BUNDLE_KEY_GIVEN_NAME = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_GIVEN_NAME"
+const val GOOGLE_ID_BUNDLE_KEY_FAMILY_NAME = "com.google.android.libraries.identity.googleid.BUNDLE_KEY_FAMILY_NAME"
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"
diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/PublicKeyProxyActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/PublicKeyProxyActivity.kt
index c2d4076990..72c35dc181 100644
--- a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/PublicKeyProxyActivity.kt
+++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/PublicKeyProxyActivity.kt
@@ -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 -> {
diff --git a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/SignInProxyActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/SignInProxyActivity.kt
index 16ff2da1f4..2407293b25 100644
--- a/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/SignInProxyActivity.kt
+++ b/play-services-core/src/main/kotlin/org/microg/gms/auth/credentials/provider/SignInProxyActivity.kt
@@ -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) {
diff --git a/play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/transport/screenlock/ScreenLockTransportHandler.kt b/play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/transport/screenlock/ScreenLockTransportHandler.kt
index ec4bcf8b55..64300b7076 100644
--- a/play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/transport/screenlock/ScreenLockTransportHandler.kt
+++ b/play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/transport/screenlock/ScreenLockTransportHandler.kt
@@ -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.hasValidLeafCertificate(): Boolean {
+ val leaf = firstOrNull() as? X509Certificate ?: return false
+ return runCatching { leaf.checkValidity() }.isSuccess
+ }
+
private suspend fun createSafetyNetAttestation(
authenticatorData: AuthenticatorData,
clientDataHash: ByteArray
diff --git a/play-services-identity-credentials/build.gradle b/play-services-identity-credentials/build.gradle
new file mode 100644
index 0000000000..6f374dbff5
--- /dev/null
+++ b/play-services-identity-credentials/build.gradle
@@ -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')
+}
diff --git a/play-services-identity-credentials/core/build.gradle b/play-services-identity-credentials/core/build.gradle
new file mode 100644
index 0000000000..30ef5927c3
--- /dev/null
+++ b/play-services-identity-credentials/core/build.gradle
@@ -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'
diff --git a/play-services-identity-credentials/core/src/main/AndroidManifest.xml b/play-services-identity-credentials/core/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..f474e84df9
--- /dev/null
+++ b/play-services-identity-credentials/core/src/main/AndroidManifest.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/play-services-identity-credentials/core/src/main/kotlin/org/microg/gms/identitycredentials/IdentityCredentialApiService.kt b/play-services-identity-credentials/core/src/main/kotlin/org/microg/gms/identitycredentials/IdentityCredentialApiService.kt
new file mode 100644
index 0000000000..4573d1a51c
--- /dev/null
+++ b/play-services-identity-credentials/core/src/main/kotlin/org/microg/gms/identitycredentials/IdentityCredentialApiService.kt
@@ -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(Bundle.EMPTY), 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)!!
+ }
+
+}
diff --git a/play-services-identity-credentials/src/main/AndroidManifest.xml b/play-services-identity-credentials/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..8bdb7e14b3
--- /dev/null
+++ b/play-services-identity-credentials/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCreationOptionsRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCreationOptionsRequest.aidl
new file mode 100644
index 0000000000..a9069fdf40
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCreationOptionsRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearCreationOptionsRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCreationOptionsResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCreationOptionsResponse.aidl
new file mode 100644
index 0000000000..f877c7b611
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCreationOptionsResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearCreationOptionsResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCredentialStateRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCredentialStateRequest.aidl
new file mode 100644
index 0000000000..73923bbcc6
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCredentialStateRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearCredentialStateRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCredentialStateResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCredentialStateResponse.aidl
new file mode 100644
index 0000000000..18cb0c4957
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearCredentialStateResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearCredentialStateResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearExportRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearExportRequest.aidl
new file mode 100644
index 0000000000..b483e6fac6
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearExportRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearExportRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearExportResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearExportResponse.aidl
new file mode 100644
index 0000000000..a64474f1b0
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearExportResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearExportResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearRegistryRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearRegistryRequest.aidl
new file mode 100644
index 0000000000..586d1c4359
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearRegistryRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearRegistryRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearRegistryResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearRegistryResponse.aidl
new file mode 100644
index 0000000000..f6ea9b8c75
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ClearRegistryResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ClearRegistryResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialHandle.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialHandle.aidl
new file mode 100644
index 0000000000..100d74aa1d
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialHandle.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable CreateCredentialHandle;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialRequest.aidl
new file mode 100644
index 0000000000..3fa9e19661
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable CreateCredentialRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialResponse.aidl
new file mode 100644
index 0000000000..a78de7c617
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CreateCredentialResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable CreateCredentialResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialInformationRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialInformationRequest.aidl
new file mode 100644
index 0000000000..02180d175e
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialInformationRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable CredentialInformationRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialInformationResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialInformationResponse.aidl
new file mode 100644
index 0000000000..7704b5cce0
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialInformationResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable CredentialInformationResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialOption.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialOption.aidl
new file mode 100644
index 0000000000..d8efeec230
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialOption.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable CredentialOption;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialTransferCapabilities.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialTransferCapabilities.aidl
new file mode 100644
index 0000000000..f6ef69abbd
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/CredentialTransferCapabilities.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable CredentialTransferCapabilities;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupRequest.aidl
new file mode 100644
index 0000000000..aa24fa68f2
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ExportCredentialsToDeviceSetupRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupResponse.aidl
new file mode 100644
index 0000000000..7bf033ae9b
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ExportCredentialsToDeviceSetupResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/GetCredentialRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/GetCredentialRequest.aidl
new file mode 100644
index 0000000000..595d594c1e
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/GetCredentialRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable GetCredentialRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/GetCredentialTransferCapabilitiesRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/GetCredentialTransferCapabilitiesRequest.aidl
new file mode 100644
index 0000000000..86bb3fbfc3
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/GetCredentialTransferCapabilitiesRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable GetCredentialTransferCapabilitiesRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupRequest.aidl
new file mode 100644
index 0000000000..8ce822b3d4
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ImportCredentialsForDeviceSetupRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupResponse.aidl
new file mode 100644
index 0000000000..23a7832ea9
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ImportCredentialsForDeviceSetupResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsRequest.aidl
new file mode 100644
index 0000000000..03d4a4cdae
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/ImportCredentialsRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable ImportCredentialsRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/PendingGetCredentialHandle.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/PendingGetCredentialHandle.aidl
new file mode 100644
index 0000000000..f39b7be3a2
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/PendingGetCredentialHandle.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable PendingGetCredentialHandle;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/PendingImportCredentialsHandle.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/PendingImportCredentialsHandle.aidl
new file mode 100644
index 0000000000..ba6c013532
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/PendingImportCredentialsHandle.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable PendingImportCredentialsHandle;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterCreationOptionsRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterCreationOptionsRequest.aidl
new file mode 100644
index 0000000000..c98462fe33
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterCreationOptionsRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable RegisterCreationOptionsRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterCreationOptionsResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterCreationOptionsResponse.aidl
new file mode 100644
index 0000000000..78a4981f50
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterCreationOptionsResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable RegisterCreationOptionsResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterExportRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterExportRequest.aidl
new file mode 100644
index 0000000000..404814b38b
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterExportRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable RegisterExportRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterExportResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterExportResponse.aidl
new file mode 100644
index 0000000000..0c43c73cd3
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegisterExportResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable RegisterExportResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegistrationRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegistrationRequest.aidl
new file mode 100644
index 0000000000..af6a88ff30
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegistrationRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable RegistrationRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegistrationResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegistrationResponse.aidl
new file mode 100644
index 0000000000..8af24f09ef
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/RegistrationResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable RegistrationResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/SignalCredentialStateRequest.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/SignalCredentialStateRequest.aidl
new file mode 100644
index 0000000000..8b7fbde20a
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/SignalCredentialStateRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable SignalCredentialStateRequest;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/SignalCredentialStateResponse.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/SignalCredentialStateResponse.aidl
new file mode 100644
index 0000000000..3195d46c7a
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/SignalCredentialStateResponse.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+parcelable SignalCredentialStateResponse;
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/internal/IIdentityCredentialCallbacks.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/internal/IIdentityCredentialCallbacks.aidl
new file mode 100644
index 0000000000..69b38a5ae4
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/internal/IIdentityCredentialCallbacks.aidl
@@ -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;
+}
diff --git a/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/internal/IIdentityCredentialService.aidl b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/internal/IIdentityCredentialService.aidl
new file mode 100644
index 0000000000..80749deee2
--- /dev/null
+++ b/play-services-identity-credentials/src/main/aidl/com/google/android/gms/identitycredentials/internal/IIdentityCredentialService.aidl
@@ -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;
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCreationOptionsRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCreationOptionsRequest.java
new file mode 100644
index 0000000000..c61bcb6556
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCreationOptionsRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearCreationOptionsRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearCreationOptionsRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearCreationOptionsRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCreationOptionsResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCreationOptionsResponse.java
new file mode 100644
index 0000000000..e4e542b787
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCreationOptionsResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearCreationOptionsResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearCreationOptionsResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearCreationOptionsResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCredentialStateRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCredentialStateRequest.java
new file mode 100644
index 0000000000..55b61ee7bd
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCredentialStateRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearCredentialStateRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearCredentialStateRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearCredentialStateRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCredentialStateResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCredentialStateResponse.java
new file mode 100644
index 0000000000..8ffe0e4105
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearCredentialStateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearCredentialStateResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearCredentialStateResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearCredentialStateResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearExportRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearExportRequest.java
new file mode 100644
index 0000000000..bfaf69136f
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearExportRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearExportRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearExportRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearExportRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearExportResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearExportResponse.java
new file mode 100644
index 0000000000..3768972716
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearExportResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearExportResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearExportResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearExportResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearRegistryRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearRegistryRequest.java
new file mode 100644
index 0000000000..6c1cbc3a5e
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearRegistryRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearRegistryRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearRegistryRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearRegistryRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearRegistryResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearRegistryResponse.java
new file mode 100644
index 0000000000..7a81a721a0
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ClearRegistryResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ClearRegistryResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ClearRegistryResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ClearRegistryResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialHandle.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialHandle.java
new file mode 100644
index 0000000000..a06230cbdd
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialHandle.java
@@ -0,0 +1,45 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+import org.microg.gms.common.Hide;
+
+@SafeParcelable.Class
+@Hide
+public class CreateCredentialHandle extends AbstractSafeParcelable {
+ @Field(1)
+ @Nullable
+ public final PendingIntent pendingIntent;
+ @Field(2)
+ @Nullable
+ public final CreateCredentialResponse createCredentialResponse;
+
+ @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;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CreateCredentialHandle.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialRequest.java
new file mode 100644
index 0000000000..761bdd8ccd
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialRequest.java
@@ -0,0 +1,59 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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 org.microg.gms.common.Hide;
+
+@SafeParcelable.Class
+@Hide
+public class CreateCredentialRequest extends AbstractSafeParcelable {
+ @Field(1)
+ @NonNull
+ public final String type;
+ @Field(2)
+ @NonNull
+ public final Bundle credentialData;
+ @Field(3)
+ @NonNull
+ public final Bundle candidateQueryData;
+ @Field(4)
+ @Nullable
+ public final String origin;
+ @Field(5)
+ @Nullable
+ public final String requestJson;
+ @Field(6)
+ @Nullable
+ public final ResultReceiver resultReceiver;
+
+ @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;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CreateCredentialRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialResponse.java
new file mode 100644
index 0000000000..5fc6f04f58
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CreateCredentialResponse.java
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class CreateCredentialResponse extends AbstractSafeParcelable {
+ @Field(1)
+ @NonNull
+ public final String type;
+ @Field(2)
+ @NonNull
+ public final Bundle data;
+
+ @Constructor
+ public CreateCredentialResponse(@Param(1) @NonNull String type, @Param(2) @NonNull Bundle data) {
+ this.type = type;
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CreateCredentialResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformation.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformation.java
new file mode 100644
index 0000000000..e00473d4d1
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformation.java
@@ -0,0 +1,49 @@
+/*
+ * 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(1)
+ @Nullable
+ public final String packageName;
+ @Field(2)
+ public final int hasPasswordCredential;
+ @Field(3)
+ public final int hasPublicKeyCredential;
+ @Field(4)
+ public final int hasGoogleAccount;
+ @Field(5)
+ public final int reserved;
+
+ @Constructor
+ public CredentialInformation(@Param(1) @Nullable String packageName, @Param(2) int hasPasswordCredential, @Param(3) int hasPublicKeyCredential, @Param(4) int hasGoogleAccount, @Param(5) int reserved) {
+ this.packageName = packageName;
+ this.hasPasswordCredential = hasPasswordCredential;
+ this.hasPublicKeyCredential = hasPublicKeyCredential;
+ this.hasGoogleAccount = hasGoogleAccount;
+ this.reserved = reserved;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CredentialInformation.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformationRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformationRequest.java
new file mode 100644
index 0000000000..c80ef87414
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformationRequest.java
@@ -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 packageNames;
+
+ @Constructor
+ public CredentialInformationRequest(@Param(1) @Nullable List packageNames) {
+ this.packageNames = packageNames;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CredentialInformationRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformationResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformationResponse.java
new file mode 100644
index 0000000000..cca84dc9d0
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialInformationResponse.java
@@ -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 CredentialInformationResponse extends AbstractSafeParcelable {
+ @Field(1)
+ @Nullable
+ public final List credentialInformationList;
+
+ @Constructor
+ public CredentialInformationResponse(@Param(1) @Nullable List credentialInformationList) {
+ this.credentialInformationList = credentialInformationList;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CredentialInformationResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialOption.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialOption.java
new file mode 100644
index 0000000000..966bb48555
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialOption.java
@@ -0,0 +1,51 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class CredentialOption extends AbstractSafeParcelable {
+ @Field(1)
+ public final String type;
+ @Field(2)
+ public final Bundle credentialRetrievalData;
+ @Field(3)
+ public final Bundle candidateQueryData;
+ @Field(4)
+ public final String requestMatcher;
+ @Field(5)
+ public final String requestType;
+ @Field(6)
+ public final String protocolType;
+
+ @Constructor
+ public CredentialOption(@Param(1) String type, @Param(2) Bundle credentialRetrievalData, @Param(3) Bundle candidateQueryData, @Param(4) String requestMatcher, @Param(5) String requestType, @Param(6) String protocolType) {
+ this.type = type;
+ this.credentialRetrievalData = credentialRetrievalData;
+ this.candidateQueryData = candidateQueryData;
+ this.requestMatcher = requestMatcher;
+ this.requestType = requestType;
+ this.protocolType = protocolType;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CredentialOption.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialTransferCapabilities.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialTransferCapabilities.java
new file mode 100644
index 0000000000..9668eb980b
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/CredentialTransferCapabilities.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class CredentialTransferCapabilities extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public CredentialTransferCapabilities(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(CredentialTransferCapabilities.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupRequest.java
new file mode 100644
index 0000000000..68c5ad96bf
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ExportCredentialsToDeviceSetupRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ExportCredentialsToDeviceSetupRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ExportCredentialsToDeviceSetupRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupResponse.java
new file mode 100644
index 0000000000..ff5d66df1f
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ExportCredentialsToDeviceSetupResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ExportCredentialsToDeviceSetupResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ExportCredentialsToDeviceSetupResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ExportCredentialsToDeviceSetupResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/GetCredentialRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/GetCredentialRequest.java
new file mode 100644
index 0000000000..1cbdd043ce
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/GetCredentialRequest.java
@@ -0,0 +1,48 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.identitycredentials;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.ResultReceiver;
+
+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;
+
+import java.util.List;
+
+@SafeParcelable.Class
+@Hide
+public class GetCredentialRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final List credentialOptions;
+ @Field(2)
+ public final Bundle data;
+ @Field(3)
+ public final String origin;
+ @Field(4)
+ public final ResultReceiver resultReceiver;
+
+ @Constructor
+ public GetCredentialRequest(@Param(1) List credentialOptions, @Param(2) Bundle data, @Param(3) String origin, @Param(4) ResultReceiver resultReceiver) {
+ this.credentialOptions = credentialOptions;
+ this.data = data;
+ this.origin = origin;
+ this.resultReceiver = resultReceiver;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(GetCredentialRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/GetCredentialTransferCapabilitiesRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/GetCredentialTransferCapabilitiesRequest.java
new file mode 100644
index 0000000000..42a98463ea
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/GetCredentialTransferCapabilitiesRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class GetCredentialTransferCapabilitiesRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public GetCredentialTransferCapabilitiesRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(GetCredentialTransferCapabilitiesRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/IdentityCredentialClient.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/IdentityCredentialClient.java
new file mode 100644
index 0000000000..7bf508480a
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/IdentityCredentialClient.java
@@ -0,0 +1,116 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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 {
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link ClearCreationOptionsResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the clear creation options operation.
+ */
+ @NonNull
+ Task clearCreationOptions(@NonNull ClearCreationOptionsRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link ClearCredentialStateResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the clear credential state operation.
+ */
+ @NonNull
+ Task clearCredentialState(@NonNull ClearCredentialStateRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link ClearExportResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the clear export operation.
+ */
+ @NonNull
+ Task clearExport(@NonNull ClearExportRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link ClearRegistryResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the clear registry operation.
+ */
+ @NonNull
+ Task clearRegistry(@NonNull ClearRegistryRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link CreateCredentialHandle} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the create credential operation.
+ */
+ @NonNull
+ Task createCredential(@NonNull CreateCredentialRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link PendingGetCredentialHandle} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the get credential operation.
+ */
+ @NonNull
+ Task getCredential(@NonNull GetCredentialRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link PendingImportCredentialsHandle} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the import credentials operation.
+ */
+ @NonNull
+ Task importCredentials(@NonNull ImportCredentialsRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link RegisterCreationOptionsResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the register creation options operation.
+ */
+ @NonNull
+ Task registerCreationOptions(@NonNull RegisterCreationOptionsRequest request);
+
+ /**
+ * Register the credential options described in the given {@link RegistrationRequest}.
+ *
+ * @param request configuration for the register credentials operation.
+ * @return a {@link Task} which asynchronously generates a {@link RegistrationResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ */
+ @NonNull
+ Task registerCredentials(@NonNull RegistrationRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link RegisterExportResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the register export operation.
+ */
+ @NonNull
+ Task registerExport(@NonNull RegisterExportRequest request);
+
+ /**
+ * Returns a {@link Task} which asynchronously generates a {@link SignalCredentialStateResponse} on success, or throws an
+ * {@code OperationException} on failure.
+ *
+ * @param request configuration for the signal credential state operation.
+ */
+ @NonNull
+ Task signalCredentialState(@NonNull SignalCredentialStateRequest request);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/IdentityCredentialManager.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/IdentityCredentialManager.java
new file mode 100644
index 0000000000..a5070fdb08
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/IdentityCredentialManager.java
@@ -0,0 +1,39 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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() {
+ }
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupRequest.java
new file mode 100644
index 0000000000..e04ce8f072
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ImportCredentialsForDeviceSetupRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ImportCredentialsForDeviceSetupRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ImportCredentialsForDeviceSetupRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupResponse.java
new file mode 100644
index 0000000000..8e35cea699
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsForDeviceSetupResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ImportCredentialsForDeviceSetupResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ImportCredentialsForDeviceSetupResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ImportCredentialsForDeviceSetupResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsRequest.java
new file mode 100644
index 0000000000..50668bb514
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/ImportCredentialsRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class ImportCredentialsRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public ImportCredentialsRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ImportCredentialsRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/PendingGetCredentialHandle.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/PendingGetCredentialHandle.java
new file mode 100644
index 0000000000..1a1cbeeb3d
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/PendingGetCredentialHandle.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+import org.microg.gms.common.Hide;
+
+@SafeParcelable.Class
+@Hide
+public class PendingGetCredentialHandle extends AbstractSafeParcelable {
+ @Field(1)
+ public final PendingIntent pendingIntent;
+
+ @Constructor
+ public PendingGetCredentialHandle(@Param(1) PendingIntent pendingIntent) {
+ this.pendingIntent = pendingIntent;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(PendingGetCredentialHandle.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/PendingImportCredentialsHandle.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/PendingImportCredentialsHandle.java
new file mode 100644
index 0000000000..ddbd4e259c
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/PendingImportCredentialsHandle.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class PendingImportCredentialsHandle extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public PendingImportCredentialsHandle(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(PendingImportCredentialsHandle.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterCreationOptionsRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterCreationOptionsRequest.java
new file mode 100644
index 0000000000..1e89730834
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterCreationOptionsRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class RegisterCreationOptionsRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public RegisterCreationOptionsRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(RegisterCreationOptionsRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterCreationOptionsResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterCreationOptionsResponse.java
new file mode 100644
index 0000000000..efee52e0a6
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterCreationOptionsResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class RegisterCreationOptionsResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public RegisterCreationOptionsResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(RegisterCreationOptionsResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterExportRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterExportRequest.java
new file mode 100644
index 0000000000..4736e47729
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterExportRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class RegisterExportRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public RegisterExportRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(RegisterExportRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterExportResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterExportResponse.java
new file mode 100644
index 0000000000..7b1d4b1b3b
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegisterExportResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class RegisterExportResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public RegisterExportResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(RegisterExportResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegistrationRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegistrationRequest.java
new file mode 100644
index 0000000000..52d0617680
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegistrationRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class RegistrationRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public RegistrationRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(RegistrationRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegistrationResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegistrationResponse.java
new file mode 100644
index 0000000000..680674620d
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/RegistrationResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class RegistrationResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public RegistrationResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(RegistrationResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/SignalCredentialStateRequest.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/SignalCredentialStateRequest.java
new file mode 100644
index 0000000000..a9c1f76df0
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/SignalCredentialStateRequest.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class SignalCredentialStateRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public SignalCredentialStateRequest(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(SignalCredentialStateRequest.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/SignalCredentialStateResponse.java b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/SignalCredentialStateResponse.java
new file mode 100644
index 0000000000..5fe330f7e9
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/com/google/android/gms/identitycredentials/SignalCredentialStateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2026 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
+
+@SafeParcelable.Class
+@Hide
+public class SignalCredentialStateResponse extends AbstractSafeParcelable {
+ @Field(1)
+ public final Bundle data;
+
+ @Constructor
+ public SignalCredentialStateResponse(@Param(1) Bundle data) {
+ this.data = data;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(SignalCredentialStateResponse.class);
+}
diff --git a/play-services-identity-credentials/src/main/java/org/microg/gms/identitycredentials/IdentityCredentialApiClient.java b/play-services-identity-credentials/src/main/java/org/microg/gms/identitycredentials/IdentityCredentialApiClient.java
new file mode 100644
index 0000000000..d71f3a356f
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/org/microg/gms/identitycredentials/IdentityCredentialApiClient.java
@@ -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 {
+ public static final Api 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) {
+ }
+ }
+}
diff --git a/play-services-identity-credentials/src/main/java/org/microg/gms/identitycredentials/IdentityCredentialClientImpl.java b/play-services-identity-credentials/src/main/java/org/microg/gms/identitycredentials/IdentityCredentialClientImpl.java
new file mode 100644
index 0000000000..e82d7d8cf5
--- /dev/null
+++ b/play-services-identity-credentials/src/main/java/org/microg/gms/identitycredentials/IdentityCredentialClientImpl.java
@@ -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 implements IdentityCredentialClient {
+ public IdentityCredentialClientImpl(Context context) {
+ super(context, IdentityCredentialApiClient.API, Api.ApiOptions.NO_OPTIONS);
+ }
+
+ @NonNull
+ @Override
+ public Task clearCreationOptions(@NonNull ClearCreationOptionsRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 clearCredentialState(@NonNull ClearCredentialStateRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 clearExport(@NonNull ClearExportRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 clearRegistry(@NonNull ClearRegistryRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 createCredential(@NonNull CreateCredentialRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 getCredential(@NonNull GetCredentialRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 importCredentials(@NonNull ImportCredentialsRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 registerCreationOptions(@NonNull RegisterCreationOptionsRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 registerCredentials(@NonNull RegistrationRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 registerExport(@NonNull RegisterExportRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (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 signalCredentialState(@NonNull SignalCredentialStateRequest request) {
+ return scheduleTask((PendingGoogleApiCall) (client, source) ->
+ client.signalCredentialState(new BaseCallbacks() {
+ @Override
+ public void onSignalCredentialState(Status status, SignalCredentialStateResponse response, ApiMetadata apiMetadata) {
+ complete(source, status, response);
+ }
+ }, request));
+ }
+
+ private static void complete(TaskCompletionSource 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) {}
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index 1ab99b9000..91af1a53b0 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -42,6 +42,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'
@@ -97,6 +98,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'