Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +12 −8 Original line number Diff line number Diff line Loading @@ -214,17 +214,21 @@ class CredentialManagerRepo( GetCredentialProviderData.Builder("io.enpass.app") .setCredentialEntries( listOf<Entry>( 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( Loading @@ -247,12 +251,12 @@ class CredentialManagerRepo( .setCredentialEntries( listOf<Entry>( 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( Loading packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +49 −17 Original line number Diff line number Diff line Loading @@ -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 ), Loading @@ -164,9 +170,14 @@ fun PrimarySelectionCard( .padding(horizontal = 24.dp) .align(alignment = Alignment.CenterHorizontally) ) { val usernameForCredentialSize = sortedUserNameToCredentialEntryList .size val authenticationEntrySize = authenticationEntryList.size LazyColumn( verticalArrangement = Arrangement.spacedBy(2.dp) ) { // Show max 4 entries in this primary page if (usernameForCredentialSize + authenticationEntrySize <= 4) { items(sortedUserNameToCredentialEntryList) { CredentialEntryRow( credentialEntryInfo = it.sortedCredentialEntryList.first(), Loading @@ -179,6 +190,27 @@ fun PrimarySelectionCard( 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, ) } } } } Divider( Loading Loading @@ -257,7 +289,7 @@ fun AllSignInOptionCard( ) } // Locked password manager if (!authenticationEntryList.isEmpty()) { if (authenticationEntryList.isNotEmpty()) { item { LockedCredentials( authenticationEntryList = authenticationEntryList, Loading packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt +3 −3 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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( Loading Loading @@ -219,7 +219,7 @@ private fun toGetScreenState( GetScreenState.REMOTE_ONLY else GetScreenState.PRIMARY_SELECTION } internal class CredentialEntryInfoComparator : Comparator<CredentialEntryInfo> { internal class CredentialEntryInfoComparatorByTypeThenTimestamp : Comparator<CredentialEntryInfo> { override fun compare(p0: CredentialEntryInfo, p1: CredentialEntryInfo): Int { // First prefer passkey type for its security benefits if (p0.credentialType != p1.credentialType) { Loading Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +12 −8 Original line number Diff line number Diff line Loading @@ -214,17 +214,21 @@ class CredentialManagerRepo( GetCredentialProviderData.Builder("io.enpass.app") .setCredentialEntries( listOf<Entry>( 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( Loading @@ -247,12 +251,12 @@ class CredentialManagerRepo( .setCredentialEntries( listOf<Entry>( 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( Loading
packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +49 −17 Original line number Diff line number Diff line Loading @@ -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 ), Loading @@ -164,9 +170,14 @@ fun PrimarySelectionCard( .padding(horizontal = 24.dp) .align(alignment = Alignment.CenterHorizontally) ) { val usernameForCredentialSize = sortedUserNameToCredentialEntryList .size val authenticationEntrySize = authenticationEntryList.size LazyColumn( verticalArrangement = Arrangement.spacedBy(2.dp) ) { // Show max 4 entries in this primary page if (usernameForCredentialSize + authenticationEntrySize <= 4) { items(sortedUserNameToCredentialEntryList) { CredentialEntryRow( credentialEntryInfo = it.sortedCredentialEntryList.first(), Loading @@ -179,6 +190,27 @@ fun PrimarySelectionCard( 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, ) } } } } Divider( Loading Loading @@ -257,7 +289,7 @@ fun AllSignInOptionCard( ) } // Locked password manager if (!authenticationEntryList.isEmpty()) { if (authenticationEntryList.isNotEmpty()) { item { LockedCredentials( authenticationEntryList = authenticationEntryList, Loading
packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt +3 −3 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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( Loading Loading @@ -219,7 +219,7 @@ private fun toGetScreenState( GetScreenState.REMOTE_ONLY else GetScreenState.PRIMARY_SELECTION } internal class CredentialEntryInfoComparator : Comparator<CredentialEntryInfo> { internal class CredentialEntryInfoComparatorByTypeThenTimestamp : Comparator<CredentialEntryInfo> { override fun compare(p0: CredentialEntryInfo, p1: CredentialEntryInfo): Int { // First prefer passkey type for its security benefits if (p0.credentialType != p1.credentialType) { Loading