From 78a3bea4f2724e6cb0c7e2ebcfcbea020ce39528 Mon Sep 17 00:00:00 2001 From: pjf-dev <28768673+pjf-dev@users.noreply.github.com> Date: Sat, 19 Apr 2025 14:03:43 -0400 Subject: [PATCH] Fix incorrect error being reported in certain cases with fallback allowed --- .../src/main/java/BiometricActivity.kt | 53 ++++++++++--------- .../android/src/main/java/BiometricPlugin.kt | 2 +- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/plugins/biometric/android/src/main/java/BiometricActivity.kt b/plugins/biometric/android/src/main/java/BiometricActivity.kt index 011de4d5..bc6205db 100644 --- a/plugins/biometric/android/src/main/java/BiometricActivity.kt +++ b/plugins/biometric/android/src/main/java/BiometricActivity.kt @@ -38,41 +38,38 @@ class BiometricActivity : AppCompatActivity() { var title = intent.getStringExtra(BiometricPlugin.TITLE) val subtitle = intent.getStringExtra(BiometricPlugin.SUBTITLE) val description = intent.getStringExtra(BiometricPlugin.REASON) - allowDeviceCredential = false + allowDeviceCredential = intent.getBooleanExtra(BiometricPlugin.DEVICE_CREDENTIAL, false) + // Android docs say we should check if the device is secure before enabling device credential fallback val manager = getSystemService( Context.KEYGUARD_SERVICE ) as KeyguardManager - if (manager.isDeviceSecure) { - allowDeviceCredential = - intent.getBooleanExtra(BiometricPlugin.DEVICE_CREDENTIAL, false) - } - - if (title.isNullOrEmpty()) { - title = "Authenticate" - } - - builder.setTitle(title).setSubtitle(subtitle).setDescription(description) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - var authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK - if (allowDeviceCredential) { - authenticators = authenticators or BiometricManager.Authenticators.DEVICE_CREDENTIAL + if (allowDeviceCredential && manager.isDeviceSecure) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + var authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK + if (allowDeviceCredential) { + authenticators = authenticators or BiometricManager.Authenticators.DEVICE_CREDENTIAL + } + builder.setAllowedAuthenticators(authenticators) + } else { + @Suppress("DEPRECATION") + builder.setDeviceCredentialAllowed(allowDeviceCredential) } - builder.setAllowedAuthenticators(authenticators) } else { - @Suppress("DEPRECATION") - builder.setDeviceCredentialAllowed(allowDeviceCredential) - } - - // From the Android docs: - // You can't call setNegativeButtonText() and setAllowedAuthenticators(... or DEVICE_CREDENTIAL) - // at the same time on a BiometricPrompt.PromptInfo.Builder instance. - if (!allowDeviceCredential) { + // From the Android docs: + // You can't call setNegativeButtonText() and setAllowedAuthenticators(... or DEVICE_CREDENTIAL) + // at the same time on a BiometricPrompt.PromptInfo.Builder instance. val negativeButtonText = intent.getStringExtra(BiometricPlugin.CANCEL_TITLE) builder.setNegativeButtonText( if (negativeButtonText.isNullOrEmpty()) "Cancel" else negativeButtonText ) } + + if (title.isNullOrEmpty()) { + title = "Authenticate" + } + builder.setTitle(title).setSubtitle(subtitle).setDescription(description) + builder.setConfirmationRequired( intent.getBooleanExtra(BiometricPlugin.CONFIRMATION_REQUIRED, true) ) @@ -85,6 +82,14 @@ class BiometricActivity : AppCompatActivity() { errorCode: Int, errorMessage: CharSequence ) { + var errorCode = errorCode + var errorMessage = errorMessage + // override error to properly report no device credential if needed + if (allowDeviceCredential + && errorCode == BiometricPrompt.ERROR_NO_BIOMETRICS) { + errorCode = BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL + errorMessage = "No device credential set" + } super.onAuthenticationError(errorCode, errorMessage) finishActivity( BiometryResultType.ERROR, diff --git a/plugins/biometric/android/src/main/java/BiometricPlugin.kt b/plugins/biometric/android/src/main/java/BiometricPlugin.kt index b3436fd4..b9b7ab05 100644 --- a/plugins/biometric/android/src/main/java/BiometricPlugin.kt +++ b/plugins/biometric/android/src/main/java/BiometricPlugin.kt @@ -73,7 +73,7 @@ class BiometricPlugin(private val activity: Activity): Plugin(activity) { biometryErrorCodeMap[BiometricPrompt.ERROR_LOCKOUT_PERMANENT] = "biometryLockout" biometryErrorCodeMap[BiometricPrompt.ERROR_NEGATIVE_BUTTON] = "userCancel" biometryErrorCodeMap[BiometricPrompt.ERROR_NO_BIOMETRICS] = "biometryNotEnrolled" - biometryErrorCodeMap[BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL] = "noDeviceCredential" + biometryErrorCodeMap[BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL] = "passcodeNotSet" biometryErrorCodeMap[BiometricPrompt.ERROR_NO_SPACE] = "systemCancel" biometryErrorCodeMap[BiometricPrompt.ERROR_TIMEOUT] = "systemCancel" biometryErrorCodeMap[BiometricPrompt.ERROR_UNABLE_TO_PROCESS] = "systemCancel"