diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 655f23847a..23e1d85a84 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ - + diff --git a/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt b/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt index 676bcd024f..23be616211 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt @@ -5,6 +5,7 @@ import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.os.Build +import android.provider.Settings import androidx.activity.result.contract.ActivityResultContract import androidx.biometric.BiometricManager import androidx.biometric.BiometricPrompt @@ -36,20 +37,35 @@ class BiometricDeviceAuthentication( private val DISALLOWED_BIOMETRIC_VERSIONS = setOf(28, 29) } + private fun isDeviceSecure(context: Context): Boolean { + return if (Build.VERSION.SDK_INT > 23) { + ServiceUtil.getKeyguardManager(context).isDeviceSecure + } else { + ServiceUtil.getKeyguardManager(context).isKeyguardSecure + } + } + fun canAuthenticate(context: Context): Boolean { - val isKeyGuardSecure = ServiceUtil.getKeyguardManager(context).isKeyguardSecure - return isKeyGuardSecure && biometricManager.canAuthenticate(ALLOWED_AUTHENTICATORS) == BiometricManager.BIOMETRIC_SUCCESS + return isDeviceSecure(context) && biometricManager.canAuthenticate(ALLOWED_AUTHENTICATORS) == BiometricManager.BIOMETRIC_SUCCESS + } + + private fun isDontKeepActivitiesOn(context: Context): Boolean { + return Build.VERSION.SDK_INT < 30 && Settings.Global.getInt(context.contentResolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0 } fun authenticate(context: Context, force: Boolean, showConfirmDeviceCredentialIntent: () -> Unit): Boolean { - val isKeyGuardSecure = ServiceUtil.getKeyguardManager(context).isKeyguardSecure + val isDeviceSecure = isDeviceSecure(context) - if (!isKeyGuardSecure) { - Log.w(TAG, "Keyguard not secure...") + if (!isDeviceSecure) { + Log.w(TAG, "Device not secure...") return false } - return if (!DISALLOWED_BIOMETRIC_VERSIONS.contains(Build.VERSION.SDK_INT) && biometricManager.canAuthenticate(ALLOWED_AUTHENTICATORS) == BiometricManager.BIOMETRIC_SUCCESS) { + return if ( + !isDontKeepActivitiesOn(context) && + !DISALLOWED_BIOMETRIC_VERSIONS.contains(Build.VERSION.SDK_INT) && + biometricManager.canAuthenticate(ALLOWED_AUTHENTICATORS) == BiometricManager.BIOMETRIC_SUCCESS + ) { if (force) { Log.i(TAG, "Listening for biometric authentication...") try { @@ -89,10 +105,9 @@ class BiometricDeviceLockContract : ActivityResultContract() { return keyguardManager.createConfirmDeviceCredentialIntent(input, "") } - override fun parseResult(resultCode: Int, intent: Intent?) = - if (resultCode != Activity.RESULT_OK) { - BiometricDeviceAuthentication.NOT_AUTHENTICATED - } else { - BiometricDeviceAuthentication.AUTHENTICATED - } + override fun parseResult(resultCode: Int, intent: Intent?) = if (resultCode != Activity.RESULT_OK) { + BiometricDeviceAuthentication.NOT_AUTHENTICATED + } else { + BiometricDeviceAuthentication.AUTHENTICATED + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt index eb55cd63b7..ff6ef10e0c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt @@ -260,7 +260,11 @@ class LinkDeviceFragment : ComposeFragment() { private inner class BiometricAuthenticationListener : BiometricPrompt.AuthenticationCallback() { override fun onAuthenticationError(errorCode: Int, errorString: CharSequence) { Log.w(TAG, "Authentication error: $errorCode") - onAuthenticationFailed() + if (errorCode == BiometricPrompt.ERROR_CANCELED) { + findNavController().safeNavigate(R.id.action_linkDeviceFragment_to_addLinkDeviceFragment) + } else { + onAuthenticationFailed() + } } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {