From 59d362a4bdc63d6d50a30fe254b3e45595a15501 Mon Sep 17 00:00:00 2001 From: Qinmei Du Date: Wed, 21 Dec 2022 18:01:12 +0000 Subject: [PATCH] Change the sorting logic to only sort by lastUsed on primary selection screen and only show at most 4 items screencast: https://drive.google.com/file/d/1UnOGsUKi_MmcaZSwq2UgRxnkmLPc03Xg/view?usp=sharing&resourcekey=0-Sg46xXpyt81uZd_-XLwBVg Test: deployed locally Bug: 253157237 Change-Id: I1970fa4f282b18696fc2400e3e2fba5c4b2889fa --- .../CredentialManagerRepo.kt | 20 +++--- .../getflow/GetCredentialComponents.kt | 66 ++++++++++++++----- .../getflow/GetCredentialViewModel.kt | 6 +- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt index 6a6a3c5d6387f..31803da74e712 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt @@ -214,17 +214,21 @@ class CredentialManagerRepo( GetCredentialProviderData.Builder("io.enpass.app") .setCredentialEntries( listOf( + newGetEntry( + "key1", "subkey-1", TYPE_PASSWORD_CREDENTIAL, "Password", + "elisa.family@outlook.com", null, 3L + ), newGetEntry( "key1", "subkey-1", TYPE_PUBLIC_KEY_CREDENTIAL, "Passkey", - "elisa.bakery@gmail.com", "Elisa Beckett", 300L + "elisa.bakery@gmail.com", "Elisa Beckett", 0L ), newGetEntry( "key1", "subkey-2", TYPE_PASSWORD_CREDENTIAL, "Password", - "elisa.bakery@gmail.com", null, 300L + "elisa.bakery@gmail.com", null, 10L ), newGetEntry( - "key1", "subkey-3", TYPE_PASSWORD_CREDENTIAL, "Password", - "elisa.family@outlook.com", null, 100L + "key1", "subkey-3", TYPE_PUBLIC_KEY_CREDENTIAL, "Passkey", + "elisa.family@outlook.com", "Elisa Beckett", 1L ), ) ).setAuthenticationEntry( @@ -247,12 +251,12 @@ class CredentialManagerRepo( .setCredentialEntries( listOf( newGetEntry( - "key1", "subkey-1", TYPE_PASSWORD_CREDENTIAL, "Password", - "elisa.family@outlook.com", null, 600L + "key1", "subkey-2", TYPE_PASSWORD_CREDENTIAL, "Password", + "elisa.family@outlook.com", null, 4L ), newGetEntry( - "key1", "subkey-2", TYPE_PUBLIC_KEY_CREDENTIAL, "Passkey", - "elisa.family@outlook.com", null, 100L + "key1", "subkey-3", TYPE_PASSWORD_CREDENTIAL, "Password", + "elisa.work@outlook.com", null, 11L ), ) ).setAuthenticationEntry( diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt index 5e7f1e0a2f471..ac0db5adfe209 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt @@ -146,13 +146,19 @@ fun PrimarySelectionCard( textAlign = TextAlign.Center, style = MaterialTheme.typography.headlineSmall, text = stringResource( - if (sortedUserNameToCredentialEntryList.size == 1) { - if (sortedUserNameToCredentialEntryList.first().sortedCredentialEntryList - .first().credentialType + if (sortedUserNameToCredentialEntryList + .size == 1 && authenticationEntryList.isEmpty() + ) { + if (sortedUserNameToCredentialEntryList.first() + .sortedCredentialEntryList.first().credentialType == PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL - ) - R.string.get_dialog_title_use_passkey_for + ) R.string.get_dialog_title_use_passkey_for else R.string.get_dialog_title_use_sign_in_for + } else if ( + sortedUserNameToCredentialEntryList + .isEmpty() && authenticationEntryList.size == 1 + ) { + R.string.get_dialog_title_use_sign_in_for } else R.string.get_dialog_title_choose_sign_in_for, requestDisplayInfo.appDomainName ), @@ -164,20 +170,46 @@ fun PrimarySelectionCard( .padding(horizontal = 24.dp) .align(alignment = Alignment.CenterHorizontally) ) { + val usernameForCredentialSize = sortedUserNameToCredentialEntryList + .size + val authenticationEntrySize = authenticationEntryList.size LazyColumn( verticalArrangement = Arrangement.spacedBy(2.dp) ) { - items(sortedUserNameToCredentialEntryList) { - CredentialEntryRow( - credentialEntryInfo = it.sortedCredentialEntryList.first(), - onEntrySelected = onEntrySelected, - ) - } - items(authenticationEntryList) { - AuthenticationEntryRow( - authenticationEntryInfo = it, - onEntrySelected = onEntrySelected, - ) + // Show max 4 entries in this primary page + if (usernameForCredentialSize + authenticationEntrySize <= 4) { + items(sortedUserNameToCredentialEntryList) { + CredentialEntryRow( + credentialEntryInfo = it.sortedCredentialEntryList.first(), + onEntrySelected = onEntrySelected, + ) + } + items(authenticationEntryList) { + AuthenticationEntryRow( + authenticationEntryInfo = it, + onEntrySelected = onEntrySelected, + ) + } + } else if (usernameForCredentialSize < 4) { + items(sortedUserNameToCredentialEntryList) { + CredentialEntryRow( + credentialEntryInfo = it.sortedCredentialEntryList.first(), + onEntrySelected = onEntrySelected, + ) + } + items(authenticationEntryList.take(4 - usernameForCredentialSize)) { + AuthenticationEntryRow( + authenticationEntryInfo = it, + onEntrySelected = onEntrySelected, + ) + } + } else { + items(sortedUserNameToCredentialEntryList.take(4)) { + CredentialEntryRow( + credentialEntryInfo = it.sortedCredentialEntryList.first(), + onEntrySelected = onEntrySelected, + ) + } } } } @@ -257,7 +289,7 @@ fun AllSignInOptionCard( ) } // Locked password manager - if (!authenticationEntryList.isEmpty()) { + if (authenticationEntryList.isNotEmpty()) { item { LockedCredentials( authenticationEntryList = authenticationEntryList, diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt index c182397b8aeca..294e4689b977b 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt @@ -182,7 +182,7 @@ private fun toProviderDisplayInfo( Preconditions.checkState(remoteEntryList.size <= 1) // Compose sortedUserNameToCredentialEntryList - val comparator = CredentialEntryInfoComparator() + val comparator = CredentialEntryInfoComparatorByTypeThenTimestamp() // Sort per username userNameToCredentialEntryMap.values.forEach { it.sortWith(comparator) @@ -191,7 +191,7 @@ private fun toProviderDisplayInfo( val sortedUserNameToCredentialEntryList = userNameToCredentialEntryMap.map { PerUserNameCredentialEntryList(it.key, it.value) }.sortedWith( - compareBy(comparator) { it.sortedCredentialEntryList.first() } + compareByDescending{ it.sortedCredentialEntryList.first().lastUsedTimeMillis } ) return ProviderDisplayInfo( @@ -219,7 +219,7 @@ private fun toGetScreenState( GetScreenState.REMOTE_ONLY else GetScreenState.PRIMARY_SELECTION } -internal class CredentialEntryInfoComparator : Comparator { +internal class CredentialEntryInfoComparatorByTypeThenTimestamp : Comparator { override fun compare(p0: CredentialEntryInfo, p1: CredentialEntryInfo): Int { // First prefer passkey type for its security benefits if (p0.credentialType != p1.credentialType) {