Merge "UI bug fixes."
diff --git a/packages/CredentialManager/AndroidManifest.xml b/packages/CredentialManager/AndroidManifest.xml
index 5a4d256..499d130 100644
--- a/packages/CredentialManager/AndroidManifest.xml
+++ b/packages/CredentialManager/AndroidManifest.xml
@@ -32,7 +32,6 @@
       android:supportsRtl="true"
       android:theme="@style/Theme.CredentialSelector">
 
-    <!--TODO: make sure implementing singleTop on NewIntent-->
     <activity
         android:name=".CredentialSelectorActivity"
         android:exported="true"
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index 8c50271..51dc233 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -49,7 +49,12 @@
 
 import java.time.Instant
 
-// Consider repo per screen, similar to view model?
+/**
+ * Client for interacting with Credential Manager. Also holds data inputs from it.
+ *
+ * IMPORTANT: instantiation of the object can fail if the data inputs aren't valid. Callers need
+ * to be equipped to handle this gracefully.
+ */
 class CredentialManagerRepo(
     private val context: Context,
     intent: Intent,
@@ -81,7 +86,6 @@
                     GetCredentialProviderData::class.java
                 ) ?: testGetCredentialProviderList()
             else -> {
-                // TODO: fail gracefully
                 throw IllegalStateException("Unrecognized request type: ${requestInfo.type}")
             }
         }
@@ -167,9 +171,9 @@
         )
     }
 
+    // IMPORTANT: new invocation should be mindful that this method can throw.
     private fun getCredentialInitialUiState(): GetCredentialUiState? {
         val providerEnabledList = GetFlowUtils.toProviderList(
-            // TODO: handle runtime cast error
             providerEnabledList as List<GetCredentialProviderData>, context
         )
         val requestDisplayInfo = GetFlowUtils.toRequestDisplayInfo(requestInfo, context)
@@ -179,9 +183,9 @@
         )
     }
 
+    // IMPORTANT: new invocation should be mindful that this method can throw.
     private fun getCreateProviderEnableListInitialUiState(): List<EnabledProviderInfo> {
         val providerEnabledList = CreateFlowUtils.toEnabledProviderList(
-            // Handle runtime cast error
             providerEnabledList as List<CreateCredentialProviderData>, context
         )
         return providerEnabledList
@@ -266,7 +270,7 @@
         return listOf(
             GetCredentialProviderData.Builder("io.enpass.app")
                 .setCredentialEntries(
-                    listOf<Entry>(
+                    listOf(
                         GetTestUtils.newPasswordEntry(
                             context, "key1", "subkey-1", "elisa.family@outlook.com", null,
                             Instant.ofEpochSecond(8000L)
@@ -285,9 +289,12 @@
                         ),
                     )
                 ).setAuthenticationEntries(
-            listOf<Entry>(
-                    GetTestUtils.newAuthenticationEntry(context, "key2", "subkey-1"),
-            )
+                    listOf(
+                        GetTestUtils.newAuthenticationEntry(
+                            context, "key2", "subkey-1", "locked-user1@gmail.com"),
+                        GetTestUtils.newAuthenticationEntry(
+                            context, "key2", "subkey-2", "locked-user2@gmail.com"),
+                    )
                 ).setActionChips(
                     listOf(
                         GetTestUtils.newActionEntry(
@@ -315,9 +322,8 @@
                         ),
                     )
                 ).setAuthenticationEntries(
-                     listOf<Entry>(
-                    GetTestUtils.newAuthenticationEntry(context, "key2", "subkey-1"),
-                     )
+                     listOf(GetTestUtils.newAuthenticationEntry(
+                         context, "key2", "subkey-1", "foo@email.com"))
                 ).setActionChips(
                     listOf(
                         GetTestUtils.newActionEntry(
@@ -388,7 +394,6 @@
             CreateCredentialRequest(
                 "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL",
                 credentialData,
-                // TODO: populate with actual data
                 /*candidateQueryData=*/ Bundle(),
                 /*isSystemProviderRequired=*/ false
             ),
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index 5136f04..bf69ef4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -92,13 +92,20 @@
             handleDialogState(viewModel.uiState.dialogState)
         }
 
-        if (viewModel.uiState.createCredentialUiState != null) {
+        val createCredentialUiState = viewModel.uiState.createCredentialUiState
+        val getCredentialUiState = viewModel.uiState.getCredentialUiState
+        if (createCredentialUiState != null) {
             CreateCredentialScreen(
                 viewModel = viewModel,
+                createCredentialUiState = createCredentialUiState,
                 providerActivityLauncher = launcher
             )
-        } else if (viewModel.uiState.getCredentialUiState != null) {
-            GetCredentialScreen(viewModel = viewModel, providerActivityLauncher = launcher)
+        } else if (getCredentialUiState != null) {
+            GetCredentialScreen(
+                viewModel = viewModel,
+                getCredentialUiState = getCredentialUiState,
+                providerActivityLauncher = launcher
+            )
         } else {
             Log.d(Constants.LOG_TAG, "UI wasn't able to render neither get nor create flow")
             reportInstantiationErrorAndFinishActivity(credManRepo)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 6bf1513..30b4b86 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -255,14 +255,14 @@
     }
 
     fun createFlowOnEntrySelectedFromFirstUseScreen(activeEntry: ActiveEntry) {
+        val providerId = activeEntry.activeProvider.id
+        createFlowOnDefaultChanged(providerId)
         uiState = uiState.copy(
             createCredentialUiState = uiState.createCredentialUiState?.copy(
                 currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
                 activeEntry = activeEntry
             )
         )
-        val providerId = uiState.createCredentialUiState?.activeEntry?.activeProvider?.id
-        createFlowOnDefaultChanged(providerId)
     }
 
     fun createFlowOnDisabledProvidersSelected() {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index 167b956..ae87d95 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -17,6 +17,7 @@
 package com.android.credentialmanager
 
 import android.app.slice.Slice
+import android.app.slice.SliceItem
 import android.content.ComponentName
 import android.content.Context
 import android.content.pm.PackageManager
@@ -176,7 +177,9 @@
         }
 
 
-        /* From service data structure to UI credential entry list representation. */
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         private fun getCredentialOptionInfoList(
             providerId: String,
             credentialEntries: List<Entry>,
@@ -255,6 +258,9 @@
             }
         }
 
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         private fun getAuthenticationEntryList(
             providerId: String,
             providerDisplayName: String,
@@ -262,16 +268,24 @@
             authEntryList: List<Entry>,
         ): List<AuthenticationEntryInfo> {
             val result: MutableList<AuthenticationEntryInfo> = mutableListOf()
-            authEntryList.forEach {
+            authEntryList.forEach { entry ->
                 val structuredAuthEntry =
-                    AuthenticationAction.fromSlice(it.slice) ?: return@forEach
+                    AuthenticationAction.fromSlice(entry.slice) ?: return@forEach
+
+                // TODO: replace with official jetpack code.
+                val titleItem: SliceItem? = entry.slice.items.firstOrNull {
+                    it.hasHint(
+                        "androidx.credentials.provider.authenticationAction.SLICE_HINT_TITLE")
+                }
+                val title: String = titleItem?.text?.toString() ?: providerDisplayName
+
                 result.add(AuthenticationEntryInfo(
                     providerId = providerId,
-                    entryKey = it.key,
-                    entrySubkey = it.subkey,
+                    entryKey = entry.key,
+                    entrySubkey = entry.subkey,
                     pendingIntent = structuredAuthEntry.pendingIntent,
-                    fillInIntent = it.frameworkExtrasIntent,
-                    title = providerDisplayName,
+                    fillInIntent = entry.frameworkExtrasIntent,
+                    title = title,
                     icon = providerIcon,
                 ))
             }
@@ -279,7 +293,6 @@
         }
 
         private fun getRemoteEntry(providerId: String, remoteEntry: Entry?): RemoteEntryInfo? {
-            // TODO: should also call fromSlice after getting the official jetpack code.
             if (remoteEntry == null) {
                 return null
             }
@@ -294,6 +307,9 @@
             )
         }
 
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         private fun getActionEntryList(
             providerId: String,
             actionEntries: List<Entry>,
@@ -321,7 +337,9 @@
 
 class CreateFlowUtils {
     companion object {
-        // Returns the list (potentially empty) of enabled provider.
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         fun toEnabledProviderList(
             providerDataList: List<CreateCredentialProviderData>,
             context: Context,
@@ -346,7 +364,9 @@
             return providerList
         }
 
-        // Returns the list (potentially empty) of disabled provider.
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         fun toDisabledProviderList(
             providerDataList: List<DisabledProviderData>?,
             context: Context,
@@ -532,6 +552,9 @@
             } else null
         }
 
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         private fun toCreationOptionInfoList(
             providerId: String,
             creationEntries: List<Entry>,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
index e3bbaeb..a580c6c 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
@@ -23,10 +23,11 @@
 import android.content.Intent
 import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
 import android.credentials.ui.Entry
-import android.graphics.drawable.Icon
 import android.net.Uri
 import android.provider.Settings
 import androidx.credentials.provider.CreateEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
 
 import java.time.Instant
 
@@ -37,6 +38,7 @@
             context: Context,
             key: String,
             subkey: String,
+            title: String,
         ): Entry {
             val slice = Slice.Builder(
                 Uri.EMPTY, SliceSpec("AuthenticationAction", 0)
@@ -52,6 +54,11 @@
                     .build(),
                 /*subType=*/null
             )
+            slice.addText(
+                title,
+                null,
+                listOf("androidx.credentials.provider.authenticationAction.SLICE_HINT_TITLE")
+            )
             return Entry(
                 key,
                 subkey,
@@ -94,23 +101,6 @@
             )
         }
 
-        private const val SLICE_HINT_TYPE_DISPLAY_NAME =
-            "androidx.credentials.provider.passwordCredentialEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
-        private const val SLICE_HINT_TITLE =
-            "androidx.credentials.provider.passwordCredentialEntry.SLICE_HINT_USER_NAME"
-        private const val SLICE_HINT_SUBTITLE =
-            "androidx.credentials.provider.passwordCredentialEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
-        private const val SLICE_HINT_LAST_USED_TIME_MILLIS =
-            "androidx.credentials.provider.passwordCredentialEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
-        private const val SLICE_HINT_ICON =
-            "androidx.credentials.provider.passwordCredentialEntry.SLICE_HINT_PROFILE_ICON"
-        private const val SLICE_HINT_PENDING_INTENT =
-            "androidx.credentials.provider.passwordCredentialEntry.SLICE_HINT_PENDING_INTENT"
-        private const val SLICE_HINT_AUTO_ALLOWED =
-            "androidx.credentials.provider.passwordCredentialEntry.SLICE_HINT_AUTO_ALLOWED"
-        private const val AUTO_SELECT_TRUE_STRING = "true"
-        private const val AUTO_SELECT_FALSE_STRING = "false"
-
         internal fun newPasswordEntry(
             context: Context,
             key: String,
@@ -125,90 +115,13 @@
             val pendingIntent = PendingIntent.getActivity(
                 context, 1,
                 intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
-                    or PendingIntent.FLAG_ONE_SHOT)
+                or PendingIntent.FLAG_ONE_SHOT)
             )
-            return Entry(
-                key,
-                subkey,
-                toPasswordSlice(userName, userDisplayName, pendingIntent, lastUsedTime),
-                Intent()
-            )
+            val passwordEntry = PasswordCredentialEntry.Builder(context, userName, pendingIntent)
+                .setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
+            return Entry(key, subkey, passwordEntry.slice, Intent())
         }
 
-        private fun toPasswordSlice(
-            title: CharSequence,
-            subTitle: CharSequence?,
-            pendingIntent: PendingIntent,
-            lastUsedTime: Instant?,
-            icon: Icon? = null,
-            isAutoSelectAllowed: Boolean = true
-        ): Slice {
-            val type = TYPE_PASSWORD_CREDENTIAL
-            val autoSelectAllowed = if (isAutoSelectAllowed) {
-                AUTO_SELECT_TRUE_STRING
-            } else {
-                AUTO_SELECT_FALSE_STRING
-            }
-            val sliceBuilder = Slice.Builder(
-                Uri.EMPTY, SliceSpec(
-                    type, 1
-                )
-            )
-                .addText(
-                    "Password", /*subType=*/null,
-                    listOf(SLICE_HINT_TYPE_DISPLAY_NAME)
-                )
-                .addText(
-                    title, /*subType=*/null,
-                    listOf(SLICE_HINT_TITLE)
-                )
-                .addText(
-                    subTitle, /*subType=*/null,
-                    listOf(SLICE_HINT_SUBTITLE)
-                )
-                .addText(
-                    autoSelectAllowed, /*subType=*/null,
-                    listOf(SLICE_HINT_AUTO_ALLOWED)
-                )
-            if (lastUsedTime != null) {
-                sliceBuilder.addLong(
-                    lastUsedTime.toEpochMilli(),
-                    /*subType=*/null,
-                    listOf(SLICE_HINT_LAST_USED_TIME_MILLIS)
-                )
-            }
-            if (icon != null) {
-                sliceBuilder.addIcon(
-                    icon, /*subType=*/null,
-                    listOf(SLICE_HINT_ICON)
-                )
-            }
-            sliceBuilder.addAction(
-                pendingIntent,
-                Slice.Builder(sliceBuilder)
-                    .addHints(listOf(SLICE_HINT_PENDING_INTENT))
-                    .build(),
-                /*subType=*/null
-            )
-            return sliceBuilder.build()
-        }
-
-
-        private const val PASSKEY_SLICE_HINT_TYPE_DISPLAY_NAME =
-            "androidx.credentials.provider.publicKeyCredEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
-        private const val PASSKEY_SLICE_HINT_TITLE =
-            "androidx.credentials.provider.publicKeyCredEntry.SLICE_HINT_USER_NAME"
-        private const val PASSKEY_SLICE_HINT_SUBTITLE =
-            "androidx.credentials.provider.publicKeyCredEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
-        private const val PASSKEY_SLICE_HINT_LAST_USED_TIME_MILLIS =
-            "androidx.credentials.provider.publicKeyCredEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
-        private const val PASSKEY_SLICE_HINT_ICON =
-            "androidx.credentials.provider.publicKeyCredEntry.SLICE_HINT_PROFILE_ICON"
-        private const val PASSKEY_SLICE_HINT_PENDING_INTENT =
-            "androidx.credentials.provider.publicKeyCredEntry.SLICE_HINT_PENDING_INTENT"
-        private const val PASSKEY_SLICE_HINT_AUTO_ALLOWED =
-            "androidx.credentials.provider.publicKeyCredEntry.SLICE_HINT_AUTO_ALLOWED"
-
         internal fun newPasskeyEntry(
             context: Context,
             key: String,
@@ -223,72 +136,11 @@
             val pendingIntent = PendingIntent.getActivity(
                 context, 1,
                 intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
-                    or PendingIntent.FLAG_ONE_SHOT)
+                or PendingIntent.FLAG_ONE_SHOT)
             )
-            return Entry(
-                key, subkey, toPasskeySlice(
-                    userName, userDisplayName, pendingIntent, lastUsedTime
-                ),
-                Intent()
-            )
-        }
-
-        private fun toPasskeySlice(
-            title: CharSequence,
-            subTitle: CharSequence?,
-            pendingIntent: PendingIntent,
-            lastUsedTime: Instant?,
-            icon: Icon? = null,
-            isAutoSelectAllowed: Boolean = true
-        ): Slice {
-            val type = "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
-            val autoSelectAllowed = if (isAutoSelectAllowed) {
-                AUTO_SELECT_TRUE_STRING
-            } else {
-                AUTO_SELECT_FALSE_STRING
-            }
-            val sliceBuilder = Slice.Builder(
-                Uri.EMPTY, SliceSpec(
-                    type, 1
-                )
-            )
-                .addText(
-                    "Passkey", /*subType=*/null,
-                    listOf(PASSKEY_SLICE_HINT_TYPE_DISPLAY_NAME)
-                )
-                .addText(
-                    title, /*subType=*/null,
-                    listOf(PASSKEY_SLICE_HINT_TITLE)
-                )
-                .addText(
-                    subTitle, /*subType=*/null,
-                    listOf(PASSKEY_SLICE_HINT_SUBTITLE)
-                )
-                .addText(
-                    autoSelectAllowed, /*subType=*/null,
-                    listOf(PASSKEY_SLICE_HINT_AUTO_ALLOWED)
-                )
-            if (lastUsedTime != null) {
-                sliceBuilder.addLong(
-                    lastUsedTime.toEpochMilli(),
-                    /*subType=*/null,
-                    listOf(PASSKEY_SLICE_HINT_LAST_USED_TIME_MILLIS)
-                )
-            }
-            if (icon != null) {
-                sliceBuilder.addIcon(
-                    icon, /*subType=*/null,
-                    listOf(PASSKEY_SLICE_HINT_ICON)
-                )
-            }
-            sliceBuilder.addAction(
-                pendingIntent,
-                Slice.Builder(sliceBuilder)
-                    .addHints(listOf(PASSKEY_SLICE_HINT_PENDING_INTENT))
-                    .build(),
-                /*subType=*/null
-            )
-            return sliceBuilder.build()
+            val passkeyEntry = PublicKeyCredentialEntry.Builder(context, userName, pendingIntent)
+                .setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
+            return Entry(key, subkey, passkeyEntry.slice, Intent())
         }
     }
 }
@@ -326,7 +178,7 @@
             val pendingIntent = PendingIntent.getActivity(
                 context, 1,
                 intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
-                    or PendingIntent.FLAG_ONE_SHOT)
+                or PendingIntent.FLAG_ONE_SHOT)
             )
             val credCountMap = mutableMapOf<String, Int>()
             passwordCount?.let { credCountMap.put(TYPE_PASSWORD_CREDENTIAL, it) }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index adb5467..558c229 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -62,9 +62,9 @@
 @Composable
 fun CreateCredentialScreen(
     viewModel: CredentialSelectorViewModel,
+    createCredentialUiState: CreateCredentialUiState,
     providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
 ) {
-    val createCredentialUiState = viewModel.uiState.createCredentialUiState ?: return
     ModalBottomSheet(
         sheetContent = {
             // Hide the sheet content as opposed to the whole bottom sheet to maintain the scrim
@@ -94,6 +94,7 @@
                             requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
                             enabledProviderList = createCredentialUiState.enabledProviders,
                             providerInfo = createCredentialUiState.activeEntry?.activeProvider!!,
+                            hasDefaultProvider = createCredentialUiState.hasDefaultProvider,
                             createOptionInfo =
                             createCredentialUiState.activeEntry.activeEntryInfo
                                 as CreateOptionInfo,
@@ -264,7 +265,6 @@
     }
 }
 
-@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun ProviderSelectionCard(
     requestDisplayInfo: RequestDisplayInfo,
@@ -351,7 +351,6 @@
                 thickness = 24.dp,
                 color = Color.Transparent
             )
-            // TODO: handle the error situation that if multiple remoteInfos exists
             enabledProviderList.forEach { enabledProvider ->
                 if (enabledProvider.remoteEntry != null) {
                     Row(
@@ -363,6 +362,7 @@
                             onMoreOptionsSelected
                         )
                     }
+                    return@forEach
                 }
             }
             Divider(
@@ -463,7 +463,6 @@
                             )
                         }
                     }
-                    // TODO: handle the error situation that if multiple remoteInfos exists
                     enabledProviderList.forEach {
                         if (it.remoteEntry != null) {
                             item {
@@ -472,6 +471,7 @@
                                     onRemoteEntrySelected = onRemoteEntrySelected,
                                 )
                             }
+                            return@forEach
                         }
                     }
                 }
@@ -549,6 +549,7 @@
     onOptionSelected: (BaseEntry) -> Unit,
     onConfirm: () -> Unit,
     onMoreOptionsSelected: () -> Unit,
+    hasDefaultProvider: Boolean,
 ) {
     ContainerCard() {
         Column() {
@@ -601,7 +602,6 @@
                     onOptionSelected = onOptionSelected
                 )
             }
-            var shouldShowMoreOptionsButton = false
             var createOptionsSize = 0
             var remoteEntry: RemoteInfo? = null
             enabledProviderList.forEach { enabledProvider ->
@@ -610,8 +610,13 @@
                 }
                 createOptionsSize += enabledProvider.createOptions.size
             }
-            if (createOptionsSize > 1 || remoteEntry != null) {
-                shouldShowMoreOptionsButton = true
+            val shouldShowMoreOptionsButton = if (!hasDefaultProvider) {
+                // User has already been presented with all options on the default provider
+                // selection screen. Don't show them again. Therefore, only show the more option
+                // button if remote option is present.
+                remoteEntry != null
+            } else {
+                createOptionsSize > 1 || remoteEntry != null
             }
             Row(
                 horizontalArrangement =
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 8b311fe..48ee287 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -76,9 +76,9 @@
 @Composable
 fun GetCredentialScreen(
     viewModel: CredentialSelectorViewModel,
+    getCredentialUiState: GetCredentialUiState,
     providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
 ) {
-    val getCredentialUiState = viewModel.uiState.getCredentialUiState ?: return
     if (getCredentialUiState.currentScreenState != GetScreenState.REMOTE_ONLY) {
         ModalBottomSheet(
             sheetContent = {