aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ui/src/main/java/com/wireguard/android/util/BiometricAuthenticator.kt
diff options
context:
space:
mode:
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.kt36
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)