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

Commit 317fa77f authored by Helen Qin's avatar Helen Qin
Browse files

Support autoselect for create flows.

Bug: 281078569
Test: manual
Change-Id: I5e0a395bba4712b7fc1f22b5c51977bc0db667b0
parent 9e1f5f9a
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.credentialmanager.createflow.RequestDisplayInfo
import com.android.credentialmanager.getflow.GetCredentialUiState
import com.android.credentialmanager.getflow.findAutoSelectEntry
import com.android.credentialmanager.common.ProviderActivityState
import com.android.credentialmanager.createflow.isFlowAutoSelectable

/**
 * Client for interacting with Credential Manager. Also holds data inputs from it.
@@ -113,8 +114,7 @@ class CredentialManagerRepo(
                val providerDisableListUiState = getCreateProviderDisableListInitialUiState()
                val requestDisplayInfoUiState =
                    getCreateRequestDisplayInfoInitialUiState(originName)!!
                UiState(
                    createCredentialUiState = CreateFlowUtils.toCreateCredentialUiState(
                val createCredentialUiState = CreateFlowUtils.toCreateCredentialUiState(
                    enabledProviders = providerEnableListUiState,
                    disabledProviders = providerDisableListUiState,
                    defaultProviderIdPreferredByApp =
@@ -124,10 +124,20 @@ class CredentialManagerRepo(
                    requestDisplayInfo = requestDisplayInfoUiState,
                    isOnPasskeyIntroStateAlready = false,
                    isPasskeyFirstUse = isPasskeyFirstUse,
                    )!!,
                )!!
                val isFlowAutoSelectable = isFlowAutoSelectable(createCredentialUiState)
                UiState(
                    createCredentialUiState = createCredentialUiState,
                    getCredentialUiState = null,
                    cancelRequestState = cancelUiRequestState,
                    isInitialRender = isNewActivity,
                    isAutoSelectFlow = isFlowAutoSelectable,
                    providerActivityState =
                    if (isFlowAutoSelectable) ProviderActivityState.READY_TO_LAUNCH
                    else ProviderActivityState.NOT_APPLICABLE,
                    selectedEntry =
                    if (isFlowAutoSelectable) createCredentialUiState.activeEntry?.activeEntryInfo
                    else null,
                )
            }
            RequestInfo.TYPE_GET -> {
+23 −13
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.android.credentialmanager.common.DialogState
import com.android.credentialmanager.common.ProviderActivityResult
import com.android.credentialmanager.common.ProviderActivityState
import com.android.credentialmanager.createflow.ActiveEntry
import com.android.credentialmanager.createflow.isFlowAutoSelectable
import com.android.credentialmanager.createflow.CreateCredentialUiState
import com.android.credentialmanager.createflow.CreateScreenState
import com.android.credentialmanager.getflow.GetCredentialUiState
@@ -262,30 +263,39 @@ class CredentialSelectorViewModel(
    /*****                     Create Flow Callbacks                      *****/
    /**************************************************************************/
    fun createFlowOnConfirmIntro() {
        userConfigRepo.setIsPasskeyFirstUse(false)
        val prevUiState = uiState.createCredentialUiState
        if (prevUiState == null) {
            Log.d(Constants.LOG_TAG, "Encountered unexpected null create ui state")
            onInternalError()
            return
        }
        val newUiState = CreateFlowUtils.toCreateCredentialUiState(
            enabledProviders = prevUiState.enabledProviders,
            disabledProviders = prevUiState.disabledProviders,
            defaultProviderIdPreferredByApp =
            prevUiState.requestDisplayInfo.appPreferredDefaultProviderId,
            defaultProviderIdsSetByUser =
            prevUiState.requestDisplayInfo.userSetDefaultProviderIds,
            requestDisplayInfo = prevUiState.requestDisplayInfo,
        val newScreenState = CreateFlowUtils.toCreateScreenState(
            createOptionSize = prevUiState.sortedCreateOptionsPairs.size,
            isOnPasskeyIntroStateAlready = true,
            isPasskeyFirstUse = userConfigRepo.getIsPasskeyFirstUse()
            requestDisplayInfo = prevUiState.requestDisplayInfo,
            remoteEntry = prevUiState.remoteEntry,
            isPasskeyFirstUse = true,
        )
        if (newUiState == null) {
            Log.d(Constants.LOG_TAG, "Unable to update create ui state")
        if (newScreenState == null) {
            Log.d(Constants.LOG_TAG, "Unexpected: couldn't resolve new screen state")
            onInternalError()
            return
        }
        uiState = uiState.copy(createCredentialUiState = newUiState)
        userConfigRepo.setIsPasskeyFirstUse(false)
        val newCreateCredentialUiState = prevUiState.copy(
            currentScreenState = newScreenState,
        )
        val isFlowAutoSelectable = isFlowAutoSelectable(newCreateCredentialUiState)
        uiState = uiState.copy(
            createCredentialUiState = newCreateCredentialUiState,
            isAutoSelectFlow = isFlowAutoSelectable,
            providerActivityState =
            if (isFlowAutoSelectable) ProviderActivityState.READY_TO_LAUNCH
            else ProviderActivityState.NOT_APPLICABLE,
            selectedEntry =
            if (isFlowAutoSelectable) newCreateCredentialUiState.activeEntry?.activeEntryInfo
            else null,
        )
    }

    fun createFlowOnMoreOptionsSelectedOnCreationSelection() {
+13 −2
Original line number Diff line number Diff line
@@ -487,6 +487,7 @@ class CreateFlowUtils {
                    createCredentialRequestJetpack.preferImmediatelyAvailableCredentials,
                    appPreferredDefaultProviderId = appPreferredDefaultProviderId,
                    userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(),
                    isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed,
                )
                is CreatePublicKeyCredentialRequest -> {
                    newRequestDisplayInfoFromPasskeyJson(
@@ -497,6 +498,7 @@ class CreateFlowUtils {
                        createCredentialRequestJetpack.preferImmediatelyAvailableCredentials,
                        appPreferredDefaultProviderId = appPreferredDefaultProviderId,
                        userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(),
                        isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed,
                    )
                }
                is CreateCustomCredentialRequest -> {
@@ -515,6 +517,7 @@ class CreateFlowUtils {
                        createCredentialRequestJetpack.preferImmediatelyAvailableCredentials,
                        appPreferredDefaultProviderId = appPreferredDefaultProviderId,
                        userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(),
                        isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed,
                    )
                }
                else -> null
@@ -602,7 +605,7 @@ class CreateFlowUtils {
            )
        }

        private fun toCreateScreenState(
        fun toCreateScreenState(
            createOptionSize: Int,
            isOnPasskeyIntroStateAlready: Boolean,
            requestDisplayInfo: RequestDisplayInfo,
@@ -662,7 +665,13 @@ class CreateFlowUtils {
                    passkeyCount = createEntry.getPublicKeyCredentialCount(),
                    totalCredentialCount = createEntry.getTotalCredentialCount(),
                    lastUsedTime = createEntry.lastUsedTime ?: Instant.MIN,
                    footerDescription = createEntry.description?.toString()
                    footerDescription = createEntry.description?.toString(),
                    // TODO(b/281065680): replace with official library constant once available
                    allowAutoSelect =
                    it.slice.items.firstOrNull {
                        it.hasHint("androidx.credentials.provider.createEntry.SLICE_HINT_AUTO_" +
                            "SELECT_ALLOWED")
                    }?.text == "true",
                ))
            }
            return result.sortedWith(
@@ -694,6 +703,7 @@ class CreateFlowUtils {
            preferImmediatelyAvailableCredentials: Boolean,
            appPreferredDefaultProviderId: String?,
            userSetDefaultProviderIds: Set<String>,
            isAutoSelectRequest: Boolean
        ): RequestDisplayInfo? {
            val json = JSONObject(requestJson)
            var passkeyUsername = ""
@@ -716,6 +726,7 @@ class CreateFlowUtils {
                preferImmediatelyAvailableCredentials,
                appPreferredDefaultProviderId,
                userSetDefaultProviderIds,
                isAutoSelectRequest,
            )
        }
    }
+4 −2
Original line number Diff line number Diff line
@@ -39,14 +39,16 @@ fun ModalBottomSheet(
    onDismiss: () -> Unit,
    isInitialRender: Boolean,
    onInitialRenderComplete: () -> Unit,
    isAutoSelectFlow: Boolean,
) {
    val scope = rememberCoroutineScope()
    val state = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Hidden,
        initialValue = if (isAutoSelectFlow) ModalBottomSheetValue.Expanded
        else ModalBottomSheetValue.Hidden,
        skipHalfExpanded = true
    )
    val sysUiController = rememberSystemUiController()
    if (state.targetValue == ModalBottomSheetValue.Hidden) {
    if (state.targetValue == ModalBottomSheetValue.Hidden || isAutoSelectFlow) {
        setTransparentSystemBarsColor(sysUiController)
    } else {
        setBottomSheetSystemBarsColor(sysUiController)
+1 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ fun CreateCredentialScreen(
        },
        onDismiss = viewModel::onUserCancel,
        isInitialRender = viewModel.uiState.isInitialRender,
        isAutoSelectFlow = viewModel.uiState.isAutoSelectFlow,
        onInitialRenderComplete = viewModel::onInitialRenderComplete,
    )
}
Loading