diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index 6178efcf86c01..2cdee4eef6edb 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -15,14 +15,16 @@
Save your password to %1$s?
Save your sign-in info to %1$s?
Use saved sign in
- Create passkey at
+ Create passkey in
+ Save password to
+ Save sign-in to
Use %1$s for all your sign-ins?
Set as default
Use once
You can use saved %1$s on any device. It will be saved to %2$s for %3$s
- %1$s for %2$s
- %1$s
- %1$s passwords and %2$s passkeys saved
+ %1$s passwords, %2$s passkeys
+ %1$s passwords
+ %1$s passkeys
passkeys
passwords
sign-ins
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index 70bb867a5de41..21190e7dc8c4e 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -34,12 +34,12 @@ open class EntryInfo (
class CreateOptionInfo(
entryKey: String,
entrySubkey: String,
- val userProviderDisplayName: String,
+ val userProviderDisplayName: String?,
val credentialTypeIcon: Drawable,
val profileIcon: Drawable,
- val passwordCount: Int,
- val passkeyCount: Int,
- val totalCredentialCount: Int,
+ val passwordCount: Int?,
+ val passkeyCount: Int?,
+ val totalCredentialCount: Int?,
val lastUsedTimeMillis: Long?,
) : EntryInfo(entryKey, entrySubkey)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt
index 278b8352f8d12..dddbd0b5af743 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreatePasskeyComponents.kt
@@ -73,6 +73,7 @@ fun CreatePasskeyScreen(
onMoreOptionsSelected = viewModel::onMoreOptionsSelected
)
CreateScreenState.MORE_OPTIONS_SELECTION -> MoreOptionsSelectionCard(
+ requestDisplayInfo = uiState.requestDisplayInfo,
providerList = uiState.providers,
onBackButtonSelected = viewModel::onBackButtonSelected,
onOptionSelected = viewModel::onMoreOptionsRowSelected
@@ -209,6 +210,7 @@ fun ProviderSelectionCard(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MoreOptionsSelectionCard(
+ requestDisplayInfo: RequestDisplayInfo,
providerList: List,
onBackButtonSelected: () -> Unit,
onOptionSelected: (ActiveEntry) -> Unit
@@ -218,7 +220,11 @@ fun MoreOptionsSelectionCard(
TopAppBar(
title = {
Text(
- text = stringResource(R.string.string_more_options),
+ text = when (requestDisplayInfo.type) {
+ TYPE_PUBLIC_KEY_CREDENTIAL -> stringResource(R.string.create_passkey_in)
+ TYPE_PASSWORD_CREDENTIAL -> stringResource(R.string.save_password_to)
+ else -> stringResource(R.string.save_sign_in_to)
+ },
style = MaterialTheme.typography.titleMedium
)
},
@@ -231,15 +237,9 @@ fun MoreOptionsSelectionCard(
}
)
Divider(
- thickness = 24.dp,
+ thickness = 8.dp,
color = Color.Transparent
)
- Text(
- text = stringResource(R.string.create_passkey_at),
- style = MaterialTheme.typography.bodyLarge,
- modifier = Modifier.padding(horizontal = 28.dp),
- textAlign = TextAlign.Center
- )
Card(
shape = MaterialTheme.shapes.large,
modifier = Modifier
@@ -249,7 +249,6 @@ fun MoreOptionsSelectionCard(
LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
- // TODO: change the order according to usage frequency
providerList.forEach { providerInfo ->
providerInfo.createOptions.forEach { createOptionInfo ->
item {
@@ -385,20 +384,22 @@ fun CreationSelectionCard(
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.align(alignment = Alignment.CenterHorizontally)
)
- Text(
- text = stringResource(
- R.string.choose_create_option_description,
- when (requestDisplayInfo.type) {
- TYPE_PUBLIC_KEY_CREDENTIAL -> stringResource(R.string.passkeys)
- TYPE_PASSWORD_CREDENTIAL -> stringResource(R.string.passwords)
- else -> stringResource(R.string.sign_ins)
- },
- providerInfo.displayName,
- createOptionInfo.userProviderDisplayName
- ),
- style = MaterialTheme.typography.bodyLarge,
- modifier = Modifier.padding(all = 24.dp).align(alignment = Alignment.CenterHorizontally)
- )
+ if (createOptionInfo.userProviderDisplayName != null) {
+ Text(
+ text = stringResource(
+ R.string.choose_create_option_description,
+ when (requestDisplayInfo.type) {
+ TYPE_PUBLIC_KEY_CREDENTIAL -> stringResource(R.string.passkeys)
+ TYPE_PASSWORD_CREDENTIAL -> stringResource(R.string.passwords)
+ else -> stringResource(R.string.sign_ins)
+ },
+ providerInfo.displayName,
+ createOptionInfo.userProviderDisplayName
+ ),
+ style = MaterialTheme.typography.bodyLarge,
+ modifier = Modifier.padding(all = 24.dp).align(alignment = Alignment.CenterHorizontally)
+ )
+ }
Card(
shape = MaterialTheme.shapes.large,
modifier = Modifier
@@ -504,30 +505,57 @@ fun MoreOptionsInfoRow(
onClick = onOptionSelected,
icon = {
Image(modifier = Modifier.size(24.dp, 24.dp).padding(start = 10.dp),
- bitmap = createOptionInfo.profileIcon.toBitmap().asImageBitmap(),
- // painter = painterResource(R.drawable.ic_passkey),
- // TODO: add description.
- contentDescription = "")
+ bitmap = createOptionInfo.credentialTypeIcon.toBitmap().asImageBitmap(),
+ contentDescription = stringResource(R.string.createOptionInfo_icon_description))
},
shape = MaterialTheme.shapes.large,
label = {
Column() {
- Text(
+ Text(
+ text = providerInfo.displayName,
+ style = MaterialTheme.typography.titleLarge,
+ modifier = Modifier.padding(top = 16.dp)
+ )
+ if (createOptionInfo.userProviderDisplayName != null) {
+ Text(
+ text = createOptionInfo.userProviderDisplayName,
+ style = MaterialTheme.typography.bodyMedium)
+ }
+ if (createOptionInfo.passwordCount != null && createOptionInfo.passkeyCount != null) {
+ Text(
text =
- if (providerInfo.createOptions.size > 1)
- {stringResource(R.string.more_options_title_multiple_options,
- providerInfo.displayName, createOptionInfo.userProviderDisplayName)} else {
- stringResource(R.string.more_options_title_one_option,
- providerInfo.displayName)},
- style = MaterialTheme.typography.titleLarge,
- modifier = Modifier.padding(top = 16.dp)
- )
- Text(
- text = stringResource(R.string.more_options_usage_data,
- createOptionInfo.passwordCount, createOptionInfo.passkeyCount),
+ stringResource(
+ R.string.more_options_usage_passwords_passkeys,
+ createOptionInfo.passwordCount,
+ createOptionInfo.passkeyCount
+ ),
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(bottom = 16.dp)
- )
+ )
+ } else if (createOptionInfo.passwordCount != null) {
+ Text(
+ text =
+ stringResource(
+ R.string.more_options_usage_passwords,
+ createOptionInfo.passwordCount
+ ),
+ style = MaterialTheme.typography.bodyMedium,
+ modifier = Modifier.padding(bottom = 16.dp)
+ )
+ } else if (createOptionInfo.passkeyCount != null) {
+ Text(
+ text =
+ stringResource(
+ R.string.more_options_usage_passkeys,
+ createOptionInfo.passkeyCount
+ ),
+ style = MaterialTheme.typography.bodyMedium,
+ modifier = Modifier.padding(bottom = 16.dp)
+ )
+ } else if (createOptionInfo.totalCredentialCount != null) {
+ // TODO: Handle the case when there is total count
+ // but no passwords and passkeys after design is set
+ }
}
}
)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/SaveEntryUi.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/SaveEntryUi.kt
index b260cf63587cf..bcc05315cfc0f 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/SaveEntryUi.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/SaveEntryUi.kt
@@ -26,7 +26,7 @@ import android.graphics.drawable.Icon
* TODO: move to jetpack.
*/
class SaveEntryUi(
- val userProviderAccountName: CharSequence,
+ val userProviderAccountName: CharSequence?,
val credentialTypeIcon: Icon?,
val profileIcon: Icon?,
val passwordCount: Int?,