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

Commit 3c71b99a authored by Arpan Kaphle's avatar Arpan Kaphle Committed by Android (Google) Code Review
Browse files

Merge "Fix Error Propagation and No Device Lock" into main

parents a1571973 96b30a4b
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.android.credentialmanager.common.BiometricError
import com.android.credentialmanager.common.BiometricFlowType
import com.android.credentialmanager.common.BiometricPromptState
import com.android.credentialmanager.common.BiometricResult
@@ -128,13 +129,22 @@ class CredentialSelectorViewModel(
            uiState = uiState.copy(providerActivityState = ProviderActivityState.PENDING)
            val entryIntent = entry.fillInIntent
            entryIntent?.putExtra(Constants.IS_AUTO_SELECTED_KEY, uiState.isAutoSelectFlow)
            if (biometricState.biometricResult != null) {
            if (biometricState.biometricResult != null || biometricState.biometricError != null) {
                if (uiState.isAutoSelectFlow) {
                    Log.w(Constants.LOG_TAG, "Unexpected biometric result exists when " +
                            "autoSelect is preferred.")
                }
                entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_TYPE,
                    biometricState.biometricResult.biometricAuthenticationResult.authenticationType)
                // TODO(b/333445754) : Decide whether to propagate info on prompt launch
                if (biometricState.biometricResult != null) {
                    entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_RESULT,
                        biometricState.biometricResult.biometricAuthenticationResult
                            .authenticationType)
                } else if (biometricState.biometricError != null){
                    entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_ERROR_CODE,
                        biometricState.biometricError.errorCode)
                    entryIntent?.putExtra(Constants.BIOMETRIC_AUTH_ERROR_MESSAGE,
                        biometricState.biometricError.errorMessage)
                }
            }
            val intentSenderRequest = IntentSenderRequest.Builder(pendingIntent)
                .setFillInIntent(entryIntent).build()
@@ -219,7 +229,8 @@ class CredentialSelectorViewModel(
    /**************************************************************************/
    fun getFlowOnEntrySelected(
        entry: EntryInfo,
        authResult: BiometricPrompt.AuthenticationResult? = null
        authResult: BiometricPrompt.AuthenticationResult? = null,
        authError: BiometricError? = null,
    ) {
        Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
            ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
@@ -227,10 +238,11 @@ class CredentialSelectorViewModel(
            uiState.copy(
                selectedEntry = entry,
                providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
                biometricState = if (authResult == null) uiState.biometricState else uiState
                biometricState = if (authResult == null && authError == null)
                    uiState.biometricState else if (authResult != null) uiState
                    .biometricState.copy(biometricResult = BiometricResult(
                            biometricAuthenticationResult = authResult)
                )
                            biometricAuthenticationResult = authResult)) else uiState
                    .biometricState.copy(biometricError = authError)
            )
        } else {
            credManRepo.onOptionSelected(entry.providerId, entry.entryKey, entry.entrySubkey)
@@ -350,7 +362,8 @@ class CredentialSelectorViewModel(

    fun createFlowOnEntrySelected(
        selectedEntry: EntryInfo,
        authResult: AuthenticationResult? = null
        authResult: AuthenticationResult? = null,
        authError: BiometricError? = null,
    ) {
        val providerId = selectedEntry.providerId
        val entryKey = selectedEntry.entryKey
@@ -362,9 +375,11 @@ class CredentialSelectorViewModel(
            uiState = uiState.copy(
                selectedEntry = selectedEntry,
                providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
                biometricState = if (authResult == null) uiState.biometricState else uiState
                biometricState = if (authResult == null && authError == null)
                    uiState.biometricState else if (authResult != null) uiState
                    .biometricState.copy(biometricResult = BiometricResult(
                        biometricAuthenticationResult = authResult))
                        biometricAuthenticationResult = authResult)) else uiState
                    .biometricState.copy(biometricError = authError)
            )
        } else {
            credManRepo.onOptionSelected(
+9 −6
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ data class BiometricDisplayInfo(
 */
data class BiometricState(
    val biometricResult: BiometricResult? = null,
    val biometricError: BiometricError? = null,
    val biometricStatus: BiometricPromptState = BiometricPromptState.INACTIVE
)

@@ -92,7 +93,7 @@ data class BiometricResult(
 */
data class BiometricError(
    val errorCode: Int,
    val errString: CharSequence? = null
    val errorMessage: CharSequence? = null
)

/**
@@ -113,7 +114,7 @@ fun runBiometricFlowForGet(
    biometricEntry: EntryInfo,
    context: Context,
    openMoreOptionsPage: () -> Unit,
    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult?, BiometricError?) -> Unit,
    onCancelFlowAndFinish: () -> Unit,
    onIllegalStateAndFinish: (String) -> Unit,
    getBiometricPromptState: () -> BiometricPromptState,
@@ -158,7 +159,7 @@ fun runBiometricFlowForCreate(
    biometricEntry: EntryInfo,
    context: Context,
    openMoreOptionsPage: () -> Unit,
    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult?, BiometricError?) -> Unit,
    onCancelFlowAndFinish: () -> Unit,
    onIllegalStateAndFinish: (String) -> Unit,
    getBiometricPromptState: () -> BiometricPromptState,
@@ -285,7 +286,7 @@ private fun removeDeviceCredential(requestAllowedAuthenticators: Int): Int {
 * Sets up the biometric authentication callback.
 */
private fun setupBiometricAuthenticationCallback(
    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
    sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult?, BiometricError?) -> Unit,
    selectedEntry: EntryInfo,
    onCancelFlowAndFinish: () -> Unit,
    onIllegalStateAndFinish: (String) -> Unit,
@@ -301,7 +302,7 @@ private fun setupBiometricAuthenticationCallback(
                try {
                    if (authResult != null) {
                        onBiometricPromptStateChange(BiometricPromptState.COMPLETE)
                        sendDataToProvider(selectedEntry, authResult)
                        sendDataToProvider(selectedEntry, authResult, /*authError=*/null)
                    } else {
                        onIllegalStateAndFinish("The biometric flow succeeded but unexpectedly " +
                                "returned a null value.")
@@ -326,8 +327,10 @@ private fun setupBiometricAuthenticationCallback(
                    // into the selector, parity applies to the selector's cancellation instead
                    // of the provider's biometric prompt cancellation.
                    onCancelFlowAndFinish()
                } else {
                    sendDataToProvider(selectedEntry, /*authResult=*/null, /*authError=*/
                        BiometricError(errorCode, errString))
                }
                // TODO(b/333445772) : Propagate to provider
            }

            override fun onAuthenticationFailed() {
+4 −2
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ class Constants {
        const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
            "androidx.credentials.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED"
        const val IS_AUTO_SELECTED_KEY = "IS_AUTO_SELECTED"
        const val BIOMETRIC_AUTH_TYPE = "BIOMETRIC_AUTH_TYPE"
        const val BIOMETRIC_AUTH_FAILURE = "BIOMETRIC_AUTH_FAILURE"
        // TODO(b/333445772) : Qualify error codes fully for propagation
        const val BIOMETRIC_AUTH_RESULT = "BIOMETRIC_AUTH_RESULT"
        const val BIOMETRIC_AUTH_ERROR_CODE = "BIOMETRIC_AUTH_ERROR_CODE"
        const val BIOMETRIC_AUTH_ERROR_MESSAGE = "BIOMETRIC_AUTH_ERROR_MESSAGE"
    }
}
+6 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import androidx.core.graphics.drawable.toBitmap
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.credentialmanager.CredentialSelectorViewModel
import com.android.credentialmanager.R
import com.android.credentialmanager.common.BiometricError
import com.android.credentialmanager.common.BiometricFlowType
import com.android.credentialmanager.common.BiometricPromptState
import com.android.credentialmanager.model.EntryInfo
@@ -581,7 +582,11 @@ internal fun BiometricSelectionPage(
    onMoreOptionSelected: () -> Unit,
    requestDisplayInfo: RequestDisplayInfo,
    enabledProviderInfo: EnabledProviderInfo,
    onBiometricEntrySelected: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
    onBiometricEntrySelected: (
        EntryInfo,
        BiometricPrompt.AuthenticationResult?,
        BiometricError?
    ) -> Unit,
    onCancelFlowAndFinish: () -> Unit,
    onIllegalScreenStateAndFinish: (String) -> Unit,
    fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
+6 −1
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import androidx.compose.ui.unit.dp
import androidx.core.graphics.drawable.toBitmap
import com.android.credentialmanager.CredentialSelectorViewModel
import com.android.credentialmanager.R
import com.android.credentialmanager.common.BiometricError
import com.android.credentialmanager.common.BiometricFlowType
import com.android.credentialmanager.common.BiometricPromptState
import com.android.credentialmanager.common.ProviderActivityState
@@ -223,7 +224,11 @@ internal fun BiometricSelectionPage(
    requestDisplayInfo: RequestDisplayInfo,
    providerInfoList: List<ProviderInfo>,
    providerDisplayInfo: ProviderDisplayInfo,
    onBiometricEntrySelected: (EntryInfo, BiometricPrompt.AuthenticationResult?) -> Unit,
    onBiometricEntrySelected: (
        EntryInfo,
        BiometricPrompt.AuthenticationResult?,
        BiometricError?
    ) -> Unit,
    fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
    getBiometricPromptState: () -> BiometricPromptState,
    onBiometricPromptStateChange: (BiometricPromptState) -> Unit,