1
0
Fork 0

For #5547: Reuse biometricPrompt when authenticating

This fixes an issue with Samsung devices where an invisible DeviceCredentialHandler because the executor was "null" (it wasn't actually)

You *must* reuse the biometric object instead of creating a new one.
master
Sawyer Blatz 2019-11-07 13:17:37 -08:00 committed by Emily Kager
parent 3e2b88cc91
commit 4183dea591
2 changed files with 43 additions and 33 deletions

View File

@ -36,10 +36,51 @@ import java.util.concurrent.Executors
@Suppress("TooManyFunctions")
class LoginsFragment : PreferenceFragmentCompat(), AccountObserver {
@TargetApi(M)
private lateinit var biometricPromptCallback: BiometricPrompt.AuthenticationCallback
@TargetApi(M)
private val executor = Executors.newSingleThreadExecutor()
@TargetApi(M)
private lateinit var biometricPrompt: BiometricPrompt
@TargetApi(M)
private lateinit var promptInfo: BiometricPrompt.PromptInfo
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.logins_preferences, rootKey)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
biometricPromptCallback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
// Authentication Error
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
lifecycleScope.launch(Main) {
navigateToSavedLoginsFragment()
}
}
override fun onAuthenticationFailed() {
// Authenticated Failed
}
}
biometricPrompt = BiometricPrompt(this, executor, biometricPromptCallback)
promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(getString(R.string.logins_biometric_prompt_message))
.setDeviceCredentialAllowed(true)
.build()
}
override fun onResume() {
super.onResume()
activity?.title = getString(R.string.preferences_passwords_logins_and_passwords)
@ -48,7 +89,7 @@ class LoginsFragment : PreferenceFragmentCompat(), AccountObserver {
val savedLoginsKey = getPreferenceKey(R.string.pref_key_saved_logins)
findPreference<Preference>(savedLoginsKey)?.setOnPreferenceClickListener {
if (Build.VERSION.SDK_INT >= M && isHardwareAvailable && hasBiometricEnrolled) {
showBiometricPrompt()
biometricPrompt.authenticate(promptInfo)
} else {
verifyPinOrShowSetupWarning()
}
@ -137,37 +178,6 @@ class LoginsFragment : PreferenceFragmentCompat(), AccountObserver {
}
}
@TargetApi(M)
private fun showBiometricPrompt() {
val biometricPromptCallback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
// Authentication Error
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
lifecycleScope.launch(Main) {
navigateToSavedLoginsFragment()
}
}
override fun onAuthenticationFailed() {
// Authenticated Failed
}
}
val executor = Executors.newSingleThreadExecutor()
val biometricPrompt = BiometricPrompt(this, executor, biometricPromptCallback)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(getString(R.string.logins_biometric_prompt_message))
.setDeviceCredentialAllowed(true)
.build()
biometricPrompt.authenticate(promptInfo)
}
private fun verifyPinOrShowSetupWarning() {
val manager = activity?.getSystemService(KEYGUARD_SERVICE) as KeyguardManager
if (manager.isKeyguardSecure) {

View File

@ -18,7 +18,7 @@ object Versions {
const val osslicenses_library = "17.0.0"
const val androidx_appcompat = "1.1.0"
const val androidx_biometric = "1.0.0-rc02"
const val androidx_biometric = "1.0.0"
const val androidx_coordinator_layout = "1.1.0-beta01"
const val androidx_constraint_layout = "2.0.0-beta2"
const val androidx_preference = "1.1.0"