diff options
Diffstat (limited to 'ui/src/main/java/com/wireguard/android/util/BiometricAuthenticator.kt')
-rw-r--r-- | ui/src/main/java/com/wireguard/android/util/BiometricAuthenticator.kt | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/ui/src/main/java/com/wireguard/android/util/BiometricAuthenticator.kt b/ui/src/main/java/com/wireguard/android/util/BiometricAuthenticator.kt index cf81f768..aed8a4f2 100644 --- a/ui/src/main/java/com/wireguard/android/util/BiometricAuthenticator.kt +++ b/ui/src/main/java/com/wireguard/android/util/BiometricAuthenticator.kt @@ -5,15 +5,21 @@ package com.wireguard.android.util +import android.annotation.SuppressLint +import android.app.KeyguardManager +import android.content.Context +import android.os.Build import android.os.Handler import android.util.Log import androidx.annotation.StringRes import androidx.biometric.BiometricConstants import androidx.biometric.BiometricManager import androidx.biometric.BiometricPrompt -import androidx.fragment.app.FragmentActivity +import androidx.core.content.getSystemService +import androidx.fragment.app.Fragment import com.wireguard.android.R + object BiometricAuthenticator { private const val TAG = "WireGuard/BiometricAuthenticator" private val handler = Handler() @@ -25,12 +31,25 @@ object BiometricAuthenticator { object Cancelled : Result() } + @SuppressLint("PrivateApi") + private fun isPinEnabled(context: Context): Boolean { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + return context.getSystemService<KeyguardManager>()!!.isDeviceSecure + return try { + val lockUtilsClass = Class.forName("com.android.internal.widget.LockPatternUtils") + val lockUtils = lockUtilsClass.getConstructor(Context::class.java).newInstance(context) + val method = lockUtilsClass.getMethod("isLockScreenDisabled") + !(method.invoke(lockUtils) as Boolean) + } catch (e: Exception) { + false + } + } + fun authenticate( @StringRes dialogTitleRes: Int, - fragmentActivity: FragmentActivity, + fragment: Fragment, callback: (Result) -> Unit ) { - val biometricManager = BiometricManager.from(fragmentActivity) val authCallback = object : BiometricPrompt.AuthenticationCallback() { override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { super.onAuthenticationError(errorCode, errString) @@ -44,13 +63,13 @@ object BiometricAuthenticator { BiometricConstants.ERROR_NO_BIOMETRICS, BiometricConstants.ERROR_NO_DEVICE_CREDENTIAL -> { Result.HardwareUnavailableOrDisabled } - else -> Result.Failure(errorCode, fragmentActivity.getString(R.string.biometric_auth_error_reason, errString)) + else -> Result.Failure(errorCode, fragment.getString(R.string.biometric_auth_error_reason, errString)) }) } override fun onAuthenticationFailed() { super.onAuthenticationFailed() - callback(Result.Failure(null, fragmentActivity.getString(R.string.biometric_auth_error))) + callback(Result.Failure(null, fragment.getString(R.string.biometric_auth_error))) } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { @@ -58,13 +77,12 @@ object BiometricAuthenticator { callback(Result.Success(result.cryptoObject)) } } - val biometricPrompt = BiometricPrompt(fragmentActivity, { handler.post(it) }, authCallback) + val biometricPrompt = BiometricPrompt(fragment, { handler.post(it) }, authCallback) val promptInfo = BiometricPrompt.PromptInfo.Builder() - .setTitle(fragmentActivity.getString(dialogTitleRes)) + .setTitle(fragment.getString(dialogTitleRes)) .setDeviceCredentialAllowed(true) .build() - - if (biometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) { + if (BiometricManager.from(fragment.requireContext()).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS || isPinEnabled(fragment.requireContext())) { biometricPrompt.authenticate(promptInfo) } else { callback(Result.HardwareUnavailableOrDisabled) |