summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/credentials/Credential.java3
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt4
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt52
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt67
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialBaseRequest.kt58
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt69
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt143
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/Credential.kt27
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt25
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt52
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt68
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt34
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt59
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt67
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt141
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt58
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/ActionUi.kt (renamed from packages/CredentialManager/src/com/android/credentialmanager/jetpack/ActionUi.kt)2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt (renamed from packages/CredentialManager/src/com/android/credentialmanager/jetpack/CredentialEntryUi.kt)2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/PasskeyCredentialEntryUi.kt (renamed from packages/CredentialManager/src/com/android/credentialmanager/jetpack/PasskeyCredentialEntryUi.kt)2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/PasswordCredentialEntryUi.kt (renamed from packages/CredentialManager/src/com/android/credentialmanager/jetpack/PasswordCredentialEntryUi.kt)2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/SaveEntryUi.kt (renamed from packages/CredentialManager/src/com/android/credentialmanager/jetpack/SaveEntryUi.kt)2
22 files changed, 930 insertions, 9 deletions
diff --git a/core/java/android/credentials/Credential.java b/core/java/android/credentials/Credential.java
index fed259254239..db89170b0cd7 100644
--- a/core/java/android/credentials/Credential.java
+++ b/core/java/android/credentials/Credential.java
@@ -36,7 +36,8 @@ public final class Credential implements Parcelable {
*
* @hide
*/
- @NonNull public static final String TYPE_PASSWORD = "android.credentials.TYPE_PASSWORD";
+ @NonNull public static final String TYPE_PASSWORD_CREDENTIAL =
+ "android.credentials.TYPE_PASSWORD_CREDENTIAL";
/**
* The credential type.
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index 56fb1a91aa90..0988cba2f424 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -36,7 +36,7 @@ import com.android.credentialmanager.createflow.CreateScreenState
import com.android.credentialmanager.createflow.RequestDisplayInfo
import com.android.credentialmanager.getflow.GetCredentialUiState
import com.android.credentialmanager.getflow.GetScreenState
-import com.android.credentialmanager.jetpack.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
+import com.android.credentialmanager.jetpack.provider.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
// Consider repo per screen, similar to view model?
class CredentialManagerRepo(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt
index 8e30208e75d9..aeea46a85caf 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt
@@ -39,8 +39,8 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.core.graphics.drawable.toBitmap
import com.android.credentialmanager.R
-import com.android.credentialmanager.jetpack.CredentialEntryUi.Companion.TYPE_PASSWORD_CREDENTIAL
-import com.android.credentialmanager.jetpack.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
+import com.android.credentialmanager.jetpack.provider.CredentialEntryUi.Companion.TYPE_PASSWORD_CREDENTIAL
+import com.android.credentialmanager.jetpack.provider.CredentialEntryUi.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
import com.android.credentialmanager.ui.theme.Grey100
import com.android.credentialmanager.ui.theme.Shapes
import com.android.credentialmanager.ui.theme.Typography
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt
new file mode 100644
index 000000000000..7e7dbde8655a
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.credentials.Credential
+import android.os.Bundle
+
+/**
+ * Base request class for registering a credential.
+ *
+ * @property type the credential type
+ * @property data the request data in the [Bundle] format
+ * @property requireSystemProvider true if must only be fulfilled by a system provider and false
+ * otherwise
+ */
+open class CreateCredentialRequest(
+ val type: String,
+ val data: Bundle,
+ val requireSystemProvider: Boolean,
+) {
+ companion object {
+ @JvmStatic
+ fun createFrom(from: android.credentials.CreateCredentialRequest): CreateCredentialRequest {
+ return try {
+ when (from.type) {
+ Credential.TYPE_PASSWORD_CREDENTIAL ->
+ CreatePasswordRequest.createFrom(from.data)
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
+ CreatePublicKeyCredentialBaseRequest.createFrom(from.data)
+ else ->
+ CreateCredentialRequest(from.type, from.data, from.requireSystemProvider())
+ }
+ } catch (e: FrameworkClassParsingException) {
+ CreateCredentialRequest(from.type, from.data, from.requireSystemProvider())
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt
new file mode 100644
index 000000000000..f0da9f9d1866
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.credentials.Credential
+import android.os.Bundle
+
+/**
+ * A request to save the user password credential with their password provider.
+ *
+ * @property id the user id associated with the password
+ * @property password the password
+ * @throws NullPointerException If [id] is null
+ * @throws NullPointerException If [password] is null
+ * @throws IllegalArgumentException If [password] is empty
+ */
+class CreatePasswordRequest constructor(
+ val id: String,
+ val password: String,
+) : CreateCredentialRequest(
+ Credential.TYPE_PASSWORD_CREDENTIAL,
+ toBundle(id, password),
+ false,
+) {
+
+ init {
+ require(password.isNotEmpty()) { "password should not be empty" }
+ }
+
+ companion object {
+ const val BUNDLE_KEY_ID = "androidx.credentials.BUNDLE_KEY_ID"
+ const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
+
+ @JvmStatic
+ internal fun toBundle(id: String, password: String): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_ID, id)
+ bundle.putString(BUNDLE_KEY_PASSWORD, password)
+ return bundle
+ }
+
+ @JvmStatic
+ fun createFrom(data: Bundle): CreatePasswordRequest {
+ try {
+ val id = data.getString(BUNDLE_KEY_ID)
+ val password = data.getString(BUNDLE_KEY_PASSWORD)
+ return CreatePasswordRequest(id!!, password!!)
+ } catch (e: Exception) {
+ throw FrameworkClassParsingException()
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialBaseRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialBaseRequest.kt
new file mode 100644
index 000000000000..26d61f9eb7a9
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialBaseRequest.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * Base request class for registering a public key credential.
+ *
+ * @property requestJson The request in JSON format
+ * @throws NullPointerException If [requestJson] is null. This is handled by the Kotlin runtime
+ * @throws IllegalArgumentException If [requestJson] is empty
+ *
+ * @hide
+ */
+abstract class CreatePublicKeyCredentialBaseRequest constructor(
+ val requestJson: String,
+ type: String,
+ data: Bundle,
+ requireSystemProvider: Boolean,
+) : CreateCredentialRequest(type, data, requireSystemProvider) {
+
+ init {
+ require(requestJson.isNotEmpty()) { "request json must not be empty" }
+ }
+
+ companion object {
+ const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+ const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
+
+ @JvmStatic
+ fun createFrom(data: Bundle): CreatePublicKeyCredentialBaseRequest {
+ return when (data.getString(BUNDLE_KEY_SUBTYPE)) {
+ CreatePublicKeyCredentialRequest
+ .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST ->
+ CreatePublicKeyCredentialRequestPrivileged.createFrom(data)
+ CreatePublicKeyCredentialRequestPrivileged
+ .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED ->
+ CreatePublicKeyCredentialRequestPrivileged.createFrom(data)
+ else -> throw FrameworkClassParsingException()
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt
new file mode 100644
index 000000000000..2eda90b827dc
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * A request to register a passkey from the user's public key credential provider.
+ *
+ * @property requestJson the request in JSON format
+ * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
+ * true by default
+ * @throws NullPointerException If [requestJson] or [allowHybrid] is null. This is handled by the
+ * Kotlin runtime
+ * @throws IllegalArgumentException If [requestJson] is empty
+ *
+ * @hide
+ */
+class CreatePublicKeyCredentialRequest @JvmOverloads constructor(
+ requestJson: String,
+ @get:JvmName("allowHybrid")
+ val allowHybrid: Boolean = true
+) : CreatePublicKeyCredentialBaseRequest(
+ requestJson,
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ toBundle(requestJson, allowHybrid),
+ false,
+) {
+ companion object {
+ const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+ const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST"
+
+ @JvmStatic
+ internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_SUBTYPE,
+ BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST)
+ bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+ bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ return bundle
+ }
+
+ @JvmStatic
+ fun createFrom(data: Bundle): CreatePublicKeyCredentialRequest {
+ try {
+ val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
+ val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
+ return CreatePublicKeyCredentialRequest(requestJson!!, (allowHybrid!!) as Boolean)
+ } catch (e: Exception) {
+ throw FrameworkClassParsingException()
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt
new file mode 100644
index 000000000000..36324f83a7e5
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * A privileged request to register a passkey from the user’s public key credential provider, where
+ * the caller can modify the rp. Only callers with privileged permission, e.g. user’s default
+ * brower, caBLE, can use this.
+ *
+ * @property requestJson the privileged request in JSON format
+ * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
+ * true by default
+ * @property rp the expected true RP ID which will override the one in the [requestJson]
+ * @property clientDataHash a hash that is used to verify the [rp] Identity
+ * @throws NullPointerException If any of [allowHybrid], [requestJson], [rp], or [clientDataHash] is
+ * null. This is handled by the Kotlin runtime
+ * @throws IllegalArgumentException If any of [requestJson], [rp], or [clientDataHash] is empty
+ *
+ * @hide
+ */
+class CreatePublicKeyCredentialRequestPrivileged @JvmOverloads constructor(
+ requestJson: String,
+ val rp: String,
+ val clientDataHash: String,
+ @get:JvmName("allowHybrid")
+ val allowHybrid: Boolean = true
+) : CreatePublicKeyCredentialBaseRequest(
+ requestJson,
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ toBundle(requestJson, rp, clientDataHash, allowHybrid),
+ false,
+) {
+
+ init {
+ require(rp.isNotEmpty()) { "rp must not be empty" }
+ require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
+ }
+
+ /** A builder for [CreatePublicKeyCredentialRequestPrivileged]. */
+ class Builder(var requestJson: String, var rp: String, var clientDataHash: String) {
+
+ private var allowHybrid: Boolean = true
+
+ /**
+ * Sets the privileged request in JSON format.
+ */
+ fun setRequestJson(requestJson: String): Builder {
+ this.requestJson = requestJson
+ return this
+ }
+
+ /**
+ * Sets whether hybrid credentials are allowed to fulfill this request, true by default.
+ */
+ fun setAllowHybrid(allowHybrid: Boolean): Builder {
+ this.allowHybrid = allowHybrid
+ return this
+ }
+
+ /**
+ * Sets the expected true RP ID which will override the one in the [requestJson].
+ */
+ fun setRp(rp: String): Builder {
+ this.rp = rp
+ return this
+ }
+
+ /**
+ * Sets a hash that is used to verify the [rp] Identity.
+ */
+ fun setClientDataHash(clientDataHash: String): Builder {
+ this.clientDataHash = clientDataHash
+ return this
+ }
+
+ /** Builds a [CreatePublicKeyCredentialRequestPrivileged]. */
+ fun build(): CreatePublicKeyCredentialRequestPrivileged {
+ return CreatePublicKeyCredentialRequestPrivileged(this.requestJson,
+ this.rp, this.clientDataHash, this.allowHybrid)
+ }
+ }
+
+ companion object {
+ const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
+ const val BUNDLE_KEY_CLIENT_DATA_HASH =
+ "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
+ const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+ const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_" +
+ "PRIVILEGED"
+
+ @JvmStatic
+ internal fun toBundle(
+ requestJson: String,
+ rp: String,
+ clientDataHash: String,
+ allowHybrid: Boolean
+ ): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_SUBTYPE,
+ BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED)
+ bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+ bundle.putString(BUNDLE_KEY_RP, rp)
+ bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
+ bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ return bundle
+ }
+
+ @JvmStatic
+ fun createFrom(data: Bundle): CreatePublicKeyCredentialRequestPrivileged {
+ try {
+ val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
+ val rp = data.getString(BUNDLE_KEY_RP)
+ val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
+ val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
+ return CreatePublicKeyCredentialRequestPrivileged(
+ requestJson!!,
+ rp!!,
+ clientDataHash!!,
+ (allowHybrid!!) as Boolean,
+ )
+ } catch (e: Exception) {
+ throw FrameworkClassParsingException()
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/Credential.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/Credential.kt
new file mode 100644
index 000000000000..ee08e9e30649
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/Credential.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * Base class for a credential with which the user consented to authenticate to the app.
+ *
+ * @property type the credential type
+ * @property data the credential data in the [Bundle] format.
+ */
+open class Credential(val type: String, val data: Bundle)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
new file mode 100644
index 000000000000..497c272750ac
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+/**
+ * Internal exception used to indicate a parsing error while converting from a framework type to
+ * a jetpack type.
+ *
+ * @hide
+ */
+internal class FrameworkClassParsingException : Exception() \ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt
new file mode 100644
index 000000000000..eb65241ed4df
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.credentials.Credential
+import android.os.Bundle
+
+/**
+ * Base request class for getting a registered credential.
+ *
+ * @property type the credential type
+ * @property data the request data in the [Bundle] format
+ * @property requireSystemProvider true if must only be fulfilled by a system provider and false
+ * otherwise
+ */
+open class GetCredentialOption(
+ val type: String,
+ val data: Bundle,
+ val requireSystemProvider: Boolean,
+) {
+ companion object {
+ @JvmStatic
+ fun createFrom(from: android.credentials.GetCredentialOption): GetCredentialOption {
+ return try {
+ when (from.type) {
+ Credential.TYPE_PASSWORD_CREDENTIAL ->
+ GetPasswordOption.createFrom(from.data)
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
+ GetPublicKeyCredentialBaseOption.createFrom(from.data)
+ else ->
+ GetCredentialOption(from.type, from.data, from.requireSystemProvider())
+ }
+ } catch (e: FrameworkClassParsingException) {
+ GetCredentialOption(from.type, from.data, from.requireSystemProvider())
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt
new file mode 100644
index 000000000000..7f9256ed6c75
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+/**
+ * Encapsulates a request to get a user credential.
+ *
+ * @property getCredentialOptions the list of [GetCredentialOption] from which the user can choose
+ * one to authenticate to the app
+ * @throws IllegalArgumentException If [getCredentialOptions] is empty
+ */
+class GetCredentialRequest constructor(
+ val getCredentialOptions: List<GetCredentialOption>,
+) {
+
+ init {
+ require(getCredentialOptions.isNotEmpty()) { "credentialRequests should not be empty" }
+ }
+
+ /** A builder for [GetCredentialRequest]. */
+ class Builder {
+ private var getCredentialOptions: MutableList<GetCredentialOption> = mutableListOf()
+
+ /** Adds a specific type of [GetCredentialOption]. */
+ fun addGetCredentialOption(getCredentialOption: GetCredentialOption): Builder {
+ getCredentialOptions.add(getCredentialOption)
+ return this
+ }
+
+ /** Sets the list of [GetCredentialOption]. */
+ fun setGetCredentialOptions(getCredentialOptions: List<GetCredentialOption>): Builder {
+ this.getCredentialOptions = getCredentialOptions.toMutableList()
+ return this
+ }
+
+ /**
+ * Builds a [GetCredentialRequest].
+ *
+ * @throws IllegalArgumentException If [getCredentialOptions] is empty
+ */
+ fun build(): GetCredentialRequest {
+ return GetCredentialRequest(getCredentialOptions.toList())
+ }
+ }
+
+ companion object {
+ @JvmStatic
+ fun createFrom(from: android.credentials.GetCredentialRequest): GetCredentialRequest {
+ return GetCredentialRequest(
+ from.getCredentialOptions.map {GetCredentialOption.createFrom(it)}
+ )
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt
new file mode 100644
index 000000000000..2facad17b04e
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.credentials.Credential
+import android.os.Bundle
+
+/** A request to retrieve the user's saved application password from their password provider. */
+class GetPasswordOption : GetCredentialOption(
+ Credential.TYPE_PASSWORD_CREDENTIAL,
+ Bundle(),
+ false,
+) {
+ companion object {
+ @JvmStatic
+ fun createFrom(data: Bundle): GetPasswordOption {
+ return GetPasswordOption()
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt
new file mode 100644
index 000000000000..9b51b306dd6b
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * Base request class for getting a registered public key credential.
+ *
+ * @property requestJson the request in JSON format
+ * @throws NullPointerException If [requestJson] is null - auto handled by the
+ * Kotlin runtime
+ * @throws IllegalArgumentException If [requestJson] is empty
+ *
+ * @hide
+ */
+abstract class GetPublicKeyCredentialBaseOption constructor(
+ val requestJson: String,
+ type: String,
+ data: Bundle,
+ requireSystemProvider: Boolean,
+) : GetCredentialOption(type, data, requireSystemProvider) {
+
+ init {
+ require(requestJson.isNotEmpty()) { "request json must not be empty" }
+ }
+
+ companion object {
+ const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+ const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
+
+ @JvmStatic
+ fun createFrom(data: Bundle): GetPublicKeyCredentialBaseOption {
+ return when (data.getString(BUNDLE_KEY_SUBTYPE)) {
+ GetPublicKeyCredentialOption
+ .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION ->
+ GetPublicKeyCredentialOption.createFrom(data)
+ GetPublicKeyCredentialOptionPrivileged
+ .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED ->
+ GetPublicKeyCredentialOptionPrivileged.createFrom(data)
+ else -> throw FrameworkClassParsingException()
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt
new file mode 100644
index 000000000000..6f13c17f9b6e
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * A request to get passkeys from the user's public key credential provider.
+ *
+ * @property requestJson the request in JSON format
+ * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
+ * true by default
+ * @throws NullPointerException If [requestJson] or [allowHybrid] is null. It is handled by the
+ * Kotlin runtime
+ * @throws IllegalArgumentException If [requestJson] is empty
+ *
+ * @hide
+ */
+class GetPublicKeyCredentialOption @JvmOverloads constructor(
+ requestJson: String,
+ @get:JvmName("allowHybrid")
+ val allowHybrid: Boolean = true,
+) : GetPublicKeyCredentialBaseOption(
+ requestJson,
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ toBundle(requestJson, allowHybrid),
+ false
+) {
+ companion object {
+ const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+ const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION"
+
+ @JvmStatic
+ internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+ bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ return bundle
+ }
+
+ @JvmStatic
+ fun createFrom(data: Bundle): GetPublicKeyCredentialOption {
+ try {
+ val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
+ val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
+ return GetPublicKeyCredentialOption(requestJson!!, (allowHybrid!!) as Boolean)
+ } catch (e: Exception) {
+ throw FrameworkClassParsingException()
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt
new file mode 100644
index 000000000000..79c62a1cdfbe
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * A privileged request to get passkeys from the user's public key credential provider. The caller
+ * can modify the RP. Only callers with privileged permission (e.g. user's public browser or caBLE)
+ * can use this.
+ *
+ * @property requestJson the privileged request in JSON format
+ * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
+ * true by default
+ * @property rp the expected true RP ID which will override the one in the [requestJson]
+ * @property clientDataHash a hash that is used to verify the [rp] Identity
+ * @throws NullPointerException If any of [allowHybrid], [requestJson], [rp], or [clientDataHash]
+ * is null. This is handled by the Kotlin runtime
+ * @throws IllegalArgumentException If any of [requestJson], [rp], or [clientDataHash] is empty
+ *
+ * @hide
+ */
+class GetPublicKeyCredentialOptionPrivileged @JvmOverloads constructor(
+ requestJson: String,
+ val rp: String,
+ val clientDataHash: String,
+ @get:JvmName("allowHybrid")
+ val allowHybrid: Boolean = true
+) : GetPublicKeyCredentialBaseOption(
+ requestJson,
+ PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ toBundle(requestJson, rp, clientDataHash, allowHybrid),
+ false,
+) {
+
+ init {
+ require(rp.isNotEmpty()) { "rp must not be empty" }
+ require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
+ }
+
+ /** A builder for [GetPublicKeyCredentialOptionPrivileged]. */
+ class Builder(var requestJson: String, var rp: String, var clientDataHash: String) {
+
+ private var allowHybrid: Boolean = true
+
+ /**
+ * Sets the privileged request in JSON format.
+ */
+ fun setRequestJson(requestJson: String): Builder {
+ this.requestJson = requestJson
+ return this
+ }
+
+ /**
+ * Sets whether hybrid credentials are allowed to fulfill this request, true by default.
+ */
+ fun setAllowHybrid(allowHybrid: Boolean): Builder {
+ this.allowHybrid = allowHybrid
+ return this
+ }
+
+ /**
+ * Sets the expected true RP ID which will override the one in the [requestJson].
+ */
+ fun setRp(rp: String): Builder {
+ this.rp = rp
+ return this
+ }
+
+ /**
+ * Sets a hash that is used to verify the [rp] Identity.
+ */
+ fun setClientDataHash(clientDataHash: String): Builder {
+ this.clientDataHash = clientDataHash
+ return this
+ }
+
+ /** Builds a [GetPublicKeyCredentialOptionPrivileged]. */
+ fun build(): GetPublicKeyCredentialOptionPrivileged {
+ return GetPublicKeyCredentialOptionPrivileged(this.requestJson,
+ this.rp, this.clientDataHash, this.allowHybrid)
+ }
+ }
+
+ companion object {
+ const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
+ const val BUNDLE_KEY_CLIENT_DATA_HASH =
+ "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
+ const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+ const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION" +
+ "_PRIVILEGED"
+
+ @JvmStatic
+ internal fun toBundle(
+ requestJson: String,
+ rp: String,
+ clientDataHash: String,
+ allowHybrid: Boolean
+ ): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+ bundle.putString(BUNDLE_KEY_RP, rp)
+ bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
+ bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ return bundle
+ }
+
+ @JvmStatic
+ fun createFrom(data: Bundle): GetPublicKeyCredentialOptionPrivileged {
+ try {
+ val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
+ val rp = data.getString(BUNDLE_KEY_RP)
+ val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
+ val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
+ return GetPublicKeyCredentialOptionPrivileged(
+ requestJson!!,
+ rp!!,
+ clientDataHash!!,
+ (allowHybrid!!) as Boolean,
+ )
+ } catch (e: Exception) {
+ throw FrameworkClassParsingException()
+ }
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt
new file mode 100644
index 000000000000..b45a63bcf4ec
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * Represents the user's passkey credential granted by the user for app sign-in.
+ *
+ * @property authenticationResponseJson the public key credential authentication response in
+ * JSON format that follows the standard webauthn json format shown at
+ * [this w3c link](https://w3c.github.io/webauthn/#dictdef-authenticationresponsejson)
+ * @throws NullPointerException If [authenticationResponseJson] is null. This is handled by the
+ * kotlin runtime
+ * @throws IllegalArgumentException If [authenticationResponseJson] is empty
+ *
+ * @hide
+ */
+class PublicKeyCredential constructor(
+ val authenticationResponseJson: String
+) : Credential(
+ TYPE_PUBLIC_KEY_CREDENTIAL,
+ toBundle(authenticationResponseJson)
+) {
+
+ init {
+ require(authenticationResponseJson.isNotEmpty()) {
+ "authentication response JSON must not be empty" }
+ }
+ companion object {
+ /** The type value for public key credential related operations. */
+ const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
+ "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
+ const val BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON =
+ "androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"
+
+ @JvmStatic
+ internal fun toBundle(authenticationResponseJson: String): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON, authenticationResponseJson)
+ return bundle
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/ActionUi.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/ActionUi.kt
index d4341b498fe0..1e639fe6bd55 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/ActionUi.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/ActionUi.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.credentialmanager.jetpack
+package com.android.credentialmanager.jetpack.provider
import android.app.slice.Slice
import android.credentials.ui.Entry
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/CredentialEntryUi.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt
index d6f1b5f5c8e9..12ab436e1507 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/CredentialEntryUi.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.credentialmanager.jetpack
+package com.android.credentialmanager.jetpack.provider
import android.app.slice.Slice
import android.graphics.drawable.Icon
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/PasskeyCredentialEntryUi.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/PasskeyCredentialEntryUi.kt
index bb3b206500b4..c5dbe66e8dbb 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/PasskeyCredentialEntryUi.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/PasskeyCredentialEntryUi.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.credentialmanager.jetpack
+package com.android.credentialmanager.jetpack.provider
import android.app.slice.Slice
import android.credentials.ui.Entry
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/PasswordCredentialEntryUi.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/PasswordCredentialEntryUi.kt
index 7311b7081343..5049503b32c1 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/PasswordCredentialEntryUi.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/PasswordCredentialEntryUi.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.credentialmanager.jetpack
+package com.android.credentialmanager.jetpack.provider
import android.app.slice.Slice
import android.credentials.ui.Entry
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/SaveEntryUi.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/SaveEntryUi.kt
index fad3309fb86f..b260cf63587c 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/SaveEntryUi.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/SaveEntryUi.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.credentialmanager.jetpack
+package com.android.credentialmanager.jetpack.provider
import android.app.slice.Slice
import android.credentials.ui.Entry