Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbac773c authored by Helen Qin's avatar Helen Qin
Browse files

UI bug fixes.

1. As a temporary solution while jetpack isn't ready, use the agreed
   constant to directly pull the authentication title values.
2. Don't show the "more option" button when there's nothing to show.
3. Updated the test data based on new jetpack updates.
4. Removed/fixed some TODOs.

Bug: 268297826
Fix: 268208819
Test: manual
Change-Id: I28fa57d6db26406981ad99384e079287dd1af557
parent 8c60a525
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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"
+17 −12
Original line number Diff line number Diff line
@@ -49,7 +49,12 @@ import androidx.credentials.CreatePasswordRequest

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 @@ class CredentialManagerRepo(
                    GetCredentialProviderData::class.java
                ) ?: testGetCredentialProviderList()
            else -> {
                // TODO: fail gracefully
                throw IllegalStateException("Unrecognized request type: ${requestInfo.type}")
            }
        }
@@ -167,9 +171,9 @@ class CredentialManagerRepo(
        )
    }

    // 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 @@ class CredentialManagerRepo(
        )
    }

    // 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 @@ class CredentialManagerRepo(
        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,8 +289,11 @@ class CredentialManagerRepo(
                        ),
                    )
                ).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(
@@ -315,9 +322,8 @@ class CredentialManagerRepo(
                        ),
                    )
                ).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 @@ class CredentialManagerRepo(
            CreateCredentialRequest(
                "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL",
                credentialData,
                // TODO: populate with actual data
                /*candidateQueryData=*/ Bundle(),
                /*isSystemProviderRequired=*/ false
            ),
+10 −3
Original line number Diff line number Diff line
@@ -92,13 +92,20 @@ class CredentialSelectorActivity : ComponentActivity() {
            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 (getCredentialUiState != null) {
            GetCredentialScreen(
                viewModel = viewModel,
                getCredentialUiState = getCredentialUiState,
                providerActivityLauncher = launcher
            )
        } else if (viewModel.uiState.getCredentialUiState != null) {
            GetCredentialScreen(viewModel = viewModel, providerActivityLauncher = launcher)
        } else {
            Log.d(Constants.LOG_TAG, "UI wasn't able to render neither get nor create flow")
            reportInstantiationErrorAndFinishActivity(credManRepo)
+2 −2
Original line number Diff line number Diff line
@@ -255,14 +255,14 @@ class CredentialSelectorViewModel(
    }

    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() {
+33 −10
Original line number Diff line number Diff line
@@ -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 @@ class GetFlowUtils {
        }


        /* 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 @@ class GetFlowUtils {
            }
        }

        /**
         * Note: caller required handle empty list due to parsing error.
         */
        private fun getAuthenticationEntryList(
            providerId: String,
            providerDisplayName: String,
@@ -262,16 +268,24 @@ class GetFlowUtils {
            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 @@ class GetFlowUtils {
        }

        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 @@ class GetFlowUtils {
            )
        }

        /**
         * Note: caller required handle empty list due to parsing error.
         */
        private fun getActionEntryList(
            providerId: String,
            actionEntries: List<Entry>,
@@ -321,7 +337,9 @@ class GetFlowUtils {

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 @@ class CreateFlowUtils {
            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 @@ class CreateFlowUtils {
            } else null
        }

        /**
         * Note: caller required handle empty list due to parsing error.
         */
        private fun toCreationOptionInfoList(
            providerId: String,
            creationEntries: List<Entry>,
Loading