Loading packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt +9 −8 Original line number Diff line number Diff line Loading @@ -65,29 +65,29 @@ class CredentialSelectorUiStateGetMapperTest { isLastUnlocked = true ) val passkeyCredentialEntryInfo = private val passkeyCredentialEntryInfo = createCredentialEntryInfo(credentialType = CredentialType.PASSKEY, userName = "userName") val unknownCredentialEntryInfo = private val unknownCredentialEntryInfo = createCredentialEntryInfo(credentialType = CredentialType.UNKNOWN, userName = "userName2") val passwordCredentialEntryInfo = private val passwordCredentialEntryInfo = createCredentialEntryInfo(credentialType = CredentialType.PASSWORD, userName = "userName") val recentlyUsedPasskeyCredential = private val recentlyUsedPasskeyCredential = createCredentialEntryInfo(credentialType = CredentialType.PASSKEY, lastUsedTimeMillis = 2L, userName = "userName") val recentlyUsedPasswordCredential = private val recentlyUsedPasswordCredential = createCredentialEntryInfo(credentialType = CredentialType.PASSWORD, lastUsedTimeMillis = 2L, userName = "userName") val credentialList1 = listOf( private val credentialList1 = listOf( passkeyCredentialEntryInfo, passwordCredentialEntryInfo ) val credentialList2 = listOf( private val credentialList2 = listOf( passkeyCredentialEntryInfo, passwordCredentialEntryInfo, recentlyUsedPasskeyCredential, Loading Loading @@ -118,11 +118,12 @@ class CredentialSelectorUiStateGetMapperTest { unknownCredentialEntryInfo)))).toGet(isPrimary = true) assertThat(getCredentialUiState).isEqualTo( CredentialSelectorUiState.Get.SingleEntryPerAccount( CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen( sortedEntries = listOf( passkeyCredentialEntryInfo, // userName unknownCredentialEntryInfo // userName2 ), icon = mDrawable, authenticationEntryList = listOf(authenticationEntryInfo) )) // prefer passkey from account 1, then unknown from account 2 } Loading packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +1 −1 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ class CredentialSelectorViewModel @Inject constructor( when (uiState.value) { is Get.MultipleEntry -> isPrimaryScreen.value = true is Create, Close, is Cancel, Idle -> shouldClose.value = true is Get.SingleEntry, is Get.SingleEntryPerAccount -> cancel() is Get.SingleEntry, is Get.MultipleEntryPrimaryScreen -> cancel() } } Loading packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt +5 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.credentialmanager import android.content.Intent import android.graphics.drawable.Drawable import androidx.activity.result.IntentSenderRequest import androidx.compose.runtime.Composable import com.android.credentialmanager.model.EntryInfo Loading Loading @@ -71,14 +72,14 @@ sealed class CredentialSelectorUiState { /** Getting credential UI state when there is only one credential available. */ data class SingleEntry(val entry: CredentialEntryInfo) : Get() /** * Getting credential UI state when there is only one account while with multiple * credentials, with different types(eg, passkey vs password) or providers. * Getting credential UI state on primary screen when there is are multiple accounts. */ data class SingleEntryPerAccount( data class MultipleEntryPrimaryScreen( val icon: Drawable?, val sortedEntries: List<CredentialEntryInfo>, val authenticationEntryList: List<AuthenticationEntryInfo>, ) : Get() /** Getting credential UI state when there are multiple accounts available. */ /** Getting credential UI state on secondary screen when there are multiple accounts available. */ data class MultipleEntry( val accounts: List<PerUserNameEntries>, val actionEntryList: List<ActionEntryInfo>, Loading packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt +3 −3 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState import androidx.wear.compose.navigation.rememberSwipeDismissableNavController import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState import com.android.credentialmanager.CredentialSelectorUiState import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntryPerAccount import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntry import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry import com.android.credentialmanager.FlowEngine Loading Loading @@ -95,7 +95,7 @@ fun WearApp( scrollable(Screen.MultipleCredentialsScreenFold.route) { MultiCredentialsFoldScreen( credentialSelectorUiState = (remember { uiState } as SingleEntryPerAccount), credentialSelectorUiState = (remember { uiState } as MultipleEntryPrimaryScreen), columnState = it.columnState, flowEngine = flowEngine, ) Loading Loading @@ -169,7 +169,7 @@ private fun handleGetNavigation( } } is SingleEntryPerAccount -> { is MultipleEntryPrimaryScreen -> { navController.navigateToMultipleCredentialsFoldScreen() } Loading packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt +14 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.credentialmanager.ui.mappers import android.graphics.drawable.Drawable import com.android.credentialmanager.model.Request import com.android.credentialmanager.CredentialSelectorUiState import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerUserNameEntries Loading @@ -35,10 +36,19 @@ fun Request.Get.toGet(isPrimary: Boolean): CredentialSelectorUiState.Get { entry = accounts[0].value.minWith(comparator) ) } else { CredentialSelectorUiState.Get.SingleEntryPerAccount( sortedEntries = accounts.map { val sortedEntries = accounts.map { it.value.minWith(comparator) }.sortedWith(comparator), }.sortedWith(comparator) var icon: Drawable? = null // provide icon if all entries have the same provider if (sortedEntries.all {it.providerId == sortedEntries[0].providerId}) { icon = providerInfos[0].icon } CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen( sortedEntries = sortedEntries, icon = icon, authenticationEntryList = providerInfos.flatMap { it.authenticationEntryList } ) } Loading Loading
packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt +9 −8 Original line number Diff line number Diff line Loading @@ -65,29 +65,29 @@ class CredentialSelectorUiStateGetMapperTest { isLastUnlocked = true ) val passkeyCredentialEntryInfo = private val passkeyCredentialEntryInfo = createCredentialEntryInfo(credentialType = CredentialType.PASSKEY, userName = "userName") val unknownCredentialEntryInfo = private val unknownCredentialEntryInfo = createCredentialEntryInfo(credentialType = CredentialType.UNKNOWN, userName = "userName2") val passwordCredentialEntryInfo = private val passwordCredentialEntryInfo = createCredentialEntryInfo(credentialType = CredentialType.PASSWORD, userName = "userName") val recentlyUsedPasskeyCredential = private val recentlyUsedPasskeyCredential = createCredentialEntryInfo(credentialType = CredentialType.PASSKEY, lastUsedTimeMillis = 2L, userName = "userName") val recentlyUsedPasswordCredential = private val recentlyUsedPasswordCredential = createCredentialEntryInfo(credentialType = CredentialType.PASSWORD, lastUsedTimeMillis = 2L, userName = "userName") val credentialList1 = listOf( private val credentialList1 = listOf( passkeyCredentialEntryInfo, passwordCredentialEntryInfo ) val credentialList2 = listOf( private val credentialList2 = listOf( passkeyCredentialEntryInfo, passwordCredentialEntryInfo, recentlyUsedPasskeyCredential, Loading Loading @@ -118,11 +118,12 @@ class CredentialSelectorUiStateGetMapperTest { unknownCredentialEntryInfo)))).toGet(isPrimary = true) assertThat(getCredentialUiState).isEqualTo( CredentialSelectorUiState.Get.SingleEntryPerAccount( CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen( sortedEntries = listOf( passkeyCredentialEntryInfo, // userName unknownCredentialEntryInfo // userName2 ), icon = mDrawable, authenticationEntryList = listOf(authenticationEntryInfo) )) // prefer passkey from account 1, then unknown from account 2 } Loading
packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +1 −1 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ class CredentialSelectorViewModel @Inject constructor( when (uiState.value) { is Get.MultipleEntry -> isPrimaryScreen.value = true is Create, Close, is Cancel, Idle -> shouldClose.value = true is Get.SingleEntry, is Get.SingleEntryPerAccount -> cancel() is Get.SingleEntry, is Get.MultipleEntryPrimaryScreen -> cancel() } } Loading
packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt +5 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.credentialmanager import android.content.Intent import android.graphics.drawable.Drawable import androidx.activity.result.IntentSenderRequest import androidx.compose.runtime.Composable import com.android.credentialmanager.model.EntryInfo Loading Loading @@ -71,14 +72,14 @@ sealed class CredentialSelectorUiState { /** Getting credential UI state when there is only one credential available. */ data class SingleEntry(val entry: CredentialEntryInfo) : Get() /** * Getting credential UI state when there is only one account while with multiple * credentials, with different types(eg, passkey vs password) or providers. * Getting credential UI state on primary screen when there is are multiple accounts. */ data class SingleEntryPerAccount( data class MultipleEntryPrimaryScreen( val icon: Drawable?, val sortedEntries: List<CredentialEntryInfo>, val authenticationEntryList: List<AuthenticationEntryInfo>, ) : Get() /** Getting credential UI state when there are multiple accounts available. */ /** Getting credential UI state on secondary screen when there are multiple accounts available. */ data class MultipleEntry( val accounts: List<PerUserNameEntries>, val actionEntryList: List<ActionEntryInfo>, Loading
packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt +3 −3 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState import androidx.wear.compose.navigation.rememberSwipeDismissableNavController import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState import com.android.credentialmanager.CredentialSelectorUiState import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntryPerAccount import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntry import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry import com.android.credentialmanager.FlowEngine Loading Loading @@ -95,7 +95,7 @@ fun WearApp( scrollable(Screen.MultipleCredentialsScreenFold.route) { MultiCredentialsFoldScreen( credentialSelectorUiState = (remember { uiState } as SingleEntryPerAccount), credentialSelectorUiState = (remember { uiState } as MultipleEntryPrimaryScreen), columnState = it.columnState, flowEngine = flowEngine, ) Loading Loading @@ -169,7 +169,7 @@ private fun handleGetNavigation( } } is SingleEntryPerAccount -> { is MultipleEntryPrimaryScreen -> { navController.navigateToMultipleCredentialsFoldScreen() } Loading
packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt +14 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.credentialmanager.ui.mappers import android.graphics.drawable.Drawable import com.android.credentialmanager.model.Request import com.android.credentialmanager.CredentialSelectorUiState import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerUserNameEntries Loading @@ -35,10 +36,19 @@ fun Request.Get.toGet(isPrimary: Boolean): CredentialSelectorUiState.Get { entry = accounts[0].value.minWith(comparator) ) } else { CredentialSelectorUiState.Get.SingleEntryPerAccount( sortedEntries = accounts.map { val sortedEntries = accounts.map { it.value.minWith(comparator) }.sortedWith(comparator), }.sortedWith(comparator) var icon: Drawable? = null // provide icon if all entries have the same provider if (sortedEntries.all {it.providerId == sortedEntries[0].providerId}) { icon = providerInfos[0].icon } CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen( sortedEntries = sortedEntries, icon = icon, authenticationEntryList = providerInfos.flatMap { it.authenticationEntryList } ) } Loading