Allow weaker unlock methods (closes #4265)

This commit is contained in:
arkon 2021-04-03 11:35:33 -04:00
parent dac2072eaa
commit 68600b337e
5 changed files with 39 additions and 9 deletions

View file

@ -5,6 +5,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricPrompt import androidx.biometric.BiometricPrompt
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.widget.BiometricUtil
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.Date import java.util.Date
import java.util.concurrent.Executors import java.util.concurrent.Executors
@ -38,12 +39,15 @@ class BiometricUnlockActivity : AppCompatActivity() {
} }
) )
val promptInfo = BiometricPrompt.PromptInfo.Builder() var promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(getString(R.string.unlock_app)) .setTitle(getString(R.string.unlock_app))
.setDeviceCredentialAllowed(true) .setAllowedAuthenticators(BiometricUtil.getSupportedAuthenticators(this))
.setConfirmationRequired(false) .setConfirmationRequired(false)
.build()
biometricPrompt.authenticate(promptInfo) if (!BiometricUtil.isDeviceCredentialAllowed(this)) {
promptInfo = promptInfo.setNegativeButtonText(getString(R.string.action_cancel))
}
biometricPrompt.authenticate(promptInfo.build())
} }
} }

View file

@ -2,10 +2,10 @@ package eu.kanade.tachiyomi.ui.security
import android.content.Intent import android.content.Intent
import android.view.WindowManager import android.view.WindowManager
import androidx.biometric.BiometricManager
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.widget.BiometricUtil
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -29,7 +29,7 @@ class SecureActivityDelegate(private val activity: FragmentActivity) {
fun onResume() { fun onResume() {
val lockApp = preferences.useBiometricLock().get() val lockApp = preferences.useBiometricLock().get()
if (lockApp && BiometricManager.from(activity).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) { if (lockApp && BiometricUtil.isSupported(activity)) {
if (isAppLocked()) { if (isAppLocked()) {
val intent = Intent(activity, BiometricUnlockActivity::class.java) val intent = Intent(activity, BiometricUnlockActivity::class.java)
activity.startActivity(intent) activity.startActivity(intent)

View file

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.setting package eu.kanade.tachiyomi.ui.setting
import androidx.biometric.BiometricManager
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.data.preference.asImmediateFlow
@ -9,6 +8,7 @@ import eu.kanade.tachiyomi.util.preference.intListPreference
import eu.kanade.tachiyomi.util.preference.summaryRes import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.widget.BiometricUtil
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
@ -17,7 +17,7 @@ class SettingsSecurityController : SettingsController() {
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
titleRes = R.string.pref_category_security titleRes = R.string.pref_category_security
if (BiometricManager.from(context).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) { if (BiometricUtil.isSupported(context)) {
switchPreference { switchPreference {
key = Keys.useBiometricLock key = Keys.useBiometricLock
titleRes = R.string.lock_with_biometrics titleRes = R.string.lock_with_biometrics

View file

@ -0,0 +1,26 @@
package eu.kanade.tachiyomi.widget
import android.content.Context
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators
object BiometricUtil {
fun getSupportedAuthenticators(context: Context): Int {
return listOf(
Authenticators.BIOMETRIC_STRONG,
Authenticators.BIOMETRIC_WEAK,
Authenticators.DEVICE_CREDENTIAL,
)
.filter { BiometricManager.from(context).canAuthenticate(it) == BiometricManager.BIOMETRIC_SUCCESS }
.fold(0) { acc, auth -> acc or auth }
}
fun isSupported(context: Context): Boolean {
return getSupportedAuthenticators(context) != 0
}
fun isDeviceCredentialAllowed(context: Context): Boolean {
return getSupportedAuthenticators(context) and Authenticators.DEVICE_CREDENTIAL != 0
}
}

View file

@ -167,7 +167,7 @@
<string name="pref_manage_notifications">Manage notifications</string> <string name="pref_manage_notifications">Manage notifications</string>
<string name="pref_category_security">Security</string> <string name="pref_category_security">Security</string>
<string name="lock_with_biometrics">Lock with biometrics</string> <string name="lock_with_biometrics">Require unlock</string>
<string name="lock_when_idle">Lock when idle</string> <string name="lock_when_idle">Lock when idle</string>
<string name="lock_always">Always</string> <string name="lock_always">Always</string>
<string name="lock_never">Never</string> <string name="lock_never">Never</string>