refactor: extract prompt authentication callback creation
This commit is contained in:
parent
fe7aee24d4
commit
7435842bd9
1 changed files with 64 additions and 58 deletions
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue