refactor: extract prompt authentication callback creation

This commit is contained in:
Harsh Shandilya 2023-07-09 18:03:41 +05:30
parent fe7aee24d4
commit 7435842bd9
No known key found for this signature in database

View file

@ -56,63 +56,7 @@ object BiometricAuthenticator {
@StringRes dialogTitleRes: Int = R.string.biometric_prompt_title, @StringRes dialogTitleRes: Int = R.string.biometric_prompt_title,
callback: (Result) -> Unit callback: (Result) -> Unit
) { ) {
val authCallback = val authCallback = createPromptAuthenticationCallback(activity, callback)
object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
logcat(TAG) { "onAuthenticationError(errorCode=$errorCode, msg=$errString)" }
when (errorCode) {
BiometricPrompt.ERROR_CANCELED,
BiometricPrompt.ERROR_USER_CANCELED,
BiometricPrompt.ERROR_NEGATIVE_BUTTON -> {
callback(Result.Cancelled)
}
BiometricPrompt.ERROR_HW_NOT_PRESENT,
BiometricPrompt.ERROR_HW_UNAVAILABLE,
BiometricPrompt.ERROR_NO_BIOMETRICS,
BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> {
callback(Result.HardwareUnavailableOrDisabled)
}
BiometricPrompt.ERROR_LOCKOUT,
BiometricPrompt.ERROR_LOCKOUT_PERMANENT,
BiometricPrompt.ERROR_NO_SPACE,
BiometricPrompt.ERROR_TIMEOUT,
BiometricPrompt.ERROR_VENDOR -> {
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
}
BiometricPrompt.ERROR_UNABLE_TO_PROCESS -> {
callback(Result.Retry)
}
// We cover all guaranteed values above, but [errorCode] is still an Int
// at the end of the day so a catch-all else will always be required.
else -> {
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
}
}
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
logcat(TAG) { "onAuthenticationFailed()" }
callback(Result.Retry)
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
logcat(TAG) { "onAuthenticationSucceeded()" }
callback(Result.Success(result.cryptoObject))
}
}
val deviceHasKeyguard = activity.getSystemService<KeyguardManager>()?.isDeviceSecure == true val deviceHasKeyguard = activity.getSystemService<KeyguardManager>()?.isDeviceSecure == true
if (canAuthenticate(activity) || deviceHasKeyguard) { if (canAuthenticate(activity) || deviceHasKeyguard) {
val promptInfo = val promptInfo =
@ -123,11 +67,73 @@ object BiometricAuthenticator {
BiometricPrompt( BiometricPrompt(
activity, activity,
ContextCompat.getMainExecutor(activity.applicationContext), ContextCompat.getMainExecutor(activity.applicationContext),
authCallback authCallback,
) )
.authenticate(promptInfo) .authenticate(promptInfo)
} else { } else {
callback(Result.HardwareUnavailableOrDisabled) callback(Result.HardwareUnavailableOrDisabled)
} }
} }
private fun createPromptAuthenticationCallback(
activity: FragmentActivity,
callback: (Result) -> Unit,
): BiometricPrompt.AuthenticationCallback {
return object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
logcat(TAG) { "onAuthenticationError(errorCode=$errorCode, msg=$errString)" }
when (errorCode) {
BiometricPrompt.ERROR_CANCELED,
BiometricPrompt.ERROR_USER_CANCELED,
BiometricPrompt.ERROR_NEGATIVE_BUTTON -> {
callback(Result.Cancelled)
}
BiometricPrompt.ERROR_HW_NOT_PRESENT,
BiometricPrompt.ERROR_HW_UNAVAILABLE,
BiometricPrompt.ERROR_NO_BIOMETRICS,
BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> {
callback(Result.HardwareUnavailableOrDisabled)
}
BiometricPrompt.ERROR_LOCKOUT,
BiometricPrompt.ERROR_LOCKOUT_PERMANENT,
BiometricPrompt.ERROR_NO_SPACE,
BiometricPrompt.ERROR_TIMEOUT,
BiometricPrompt.ERROR_VENDOR -> {
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
}
BiometricPrompt.ERROR_UNABLE_TO_PROCESS -> {
callback(Result.Retry)
}
// We cover all guaranteed values above, but [errorCode] is still an Int
// at the end of the day so a catch-all else will always be required.
else -> {
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
}
}
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
logcat(TAG) { "onAuthenticationFailed()" }
callback(Result.Retry)
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
logcat(TAG) { "onAuthenticationSucceeded()" }
callback(Result.Success(result.cryptoObject))
}
}
}
} }