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?,