Fix fingerprint

This commit is contained in:
J-Jamet
2019-08-07 10:56:04 +02:00
parent e31ea8c916
commit ee76a35728
3 changed files with 100 additions and 88 deletions

View File

@@ -117,6 +117,7 @@ class PasswordActivity : StylishActivity(),
checkboxPasswordView = findViewById(R.id.password_checkbox) checkboxPasswordView = findViewById(R.id.password_checkbox)
checkboxKeyFileView = findViewById(R.id.keyfile_checkox) checkboxKeyFileView = findViewById(R.id.keyfile_checkox)
checkboxDefaultDatabaseView = findViewById(R.id.default_database) checkboxDefaultDatabaseView = findViewById(R.id.default_database)
fingerPrintInfoView = findViewById(R.id.fingerprint_info)
readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrPreference(this, savedInstanceState) readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrPreference(this, savedInstanceState)
@@ -152,27 +153,6 @@ class PasswordActivity : StylishActivity(),
confirmButtonView?.isEnabled = isChecked confirmButtonView?.isEnabled = isChecked
} }
} }
// Init FingerPrint elements
if (PreferencesUtil.isFingerprintEnable(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerPrintInfoView = findViewById(R.id.fingerprint_info)
fingerPrintViewsManager = FingerPrintViewsManager(this,
mDatabaseFileUri,
fingerPrintInfoView,
checkboxPasswordView,
enableButtonOnCheckedChangeListener,
passwordView) { password ->
// Load the database if password is registered or retrieve
password?.let {
// Retrieve from fingerprint
verifyKeyFileCheckboxAndLoadDatabase(password)
} ?: run {
// Register with fingerprint
verifyCheckboxesAndLoadDatabase()
}
}
fingerPrintViewsManager?.initFingerprint()
}
} }
private val onEditorActionListener = object : TextView.OnEditorActionListener { private val onEditorActionListener = object : TextView.OnEditorActionListener {
@@ -204,16 +184,6 @@ class PasswordActivity : StylishActivity(),
confirmButtonView?.isEnabled = true confirmButtonView?.isEnabled = true
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PreferencesUtil.isFingerprintEnable(this)) {
fingerPrintViewsManager?.initFingerprint()
} else {
fingerPrintViewsManager?.destroy()
}
} else {
checkboxPasswordView?.setOnCheckedChangeListener(enableButtonOnCheckedChangeListener)
}
UriIntentInitTask(WeakReference(this), this, mRememberKeyFile) UriIntentInitTask(WeakReference(this), this, mRememberKeyFile)
.execute(intent) .execute(intent)
} }
@@ -276,11 +246,6 @@ class PasswordActivity : StylishActivity(),
checkboxDefaultDatabaseView?.isChecked = true checkboxDefaultDatabaseView?.isChecked = true
} }
// checks if fingerprint is available, will also start listening for fingerprints when available
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerPrintViewsManager?.checkFingerprintAvailability()
}
// If Activity is launch with a password and want to open directly // If Activity is launch with a password and want to open directly
val intent = intent val intent = intent
val password = intent.getStringExtra(KEY_PASSWORD) val password = intent.getStringExtra(KEY_PASSWORD)
@@ -290,6 +255,39 @@ class PasswordActivity : StylishActivity(),
} }
if (launchImmediately) { if (launchImmediately) {
verifyCheckboxesAndLoadDatabase(password, keyFileUri) verifyCheckboxesAndLoadDatabase(password, keyFileUri)
} else {
// Init FingerPrint elements
var fingerPrintInit = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PreferencesUtil.isFingerprintEnable(this)) {
if (fingerPrintViewsManager == null) {
fingerPrintViewsManager = FingerPrintViewsManager(this,
mDatabaseFileUri,
fingerPrintInfoView,
checkboxPasswordView,
enableButtonOnCheckedChangeListener,
passwordView) { password ->
// Load the database if password is registered or retrieve
password?.let {
// Retrieve from fingerprint
verifyKeyFileCheckboxAndLoadDatabase(password)
} ?: run {
// Register with fingerprint
verifyCheckboxesAndLoadDatabase()
}
}
}
fingerPrintViewsManager?.initFingerprint()
// checks if fingerprint is available, will also start listening for fingerprints when available
fingerPrintViewsManager?.checkFingerprintAvailability()
fingerPrintInit = true
} else {
fingerPrintViewsManager?.destroy()
}
}
if (!fingerPrintInit) {
checkboxPasswordView?.setOnCheckedChangeListener(enableButtonOnCheckedChangeListener)
}
} }
} }
@@ -395,8 +393,10 @@ class PasswordActivity : StylishActivity(),
runOnUiThread { runOnUiThread {
// Recheck fingerprint if error // Recheck fingerprint if error
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Stay with the same mode if (PreferencesUtil.isFingerprintEnable(this@PasswordActivity)) {
fingerPrintViewsManager?.reInitWithFingerprintMode() // Stay with the same mode
fingerPrintViewsManager?.reInitWithFingerprintMode()
}
} }
if (result.isSuccess) { if (result.isSuccess) {

View File

@@ -53,9 +53,11 @@ class FingerPrintViewsManager(var context: AppCompatActivity,
fingerPrintMode = FingerPrintHelper.Mode.NOT_CONFIGURED_MODE fingerPrintMode = FingerPrintHelper.Mode.NOT_CONFIGURED_MODE
showFingerPrintViews(true)
// Start the animation // Start the animation
fingerPrintInfoView?.startFingerPrintAnimation() fingerPrintInfoView?.startFingerPrintAnimation()
// Add a check listener to change fingerprint mode
checkboxPasswordView?.setOnCheckedChangeListener { compoundButton, checked -> checkboxPasswordView?.setOnCheckedChangeListener { compoundButton, checked ->
if (!fingerprintMustBeConfigured) { if (!fingerprintMustBeConfigured) {
// encrypt or decrypt mode based on how much input or not // encrypt or decrypt mode based on how much input or not
@@ -77,50 +79,52 @@ class FingerPrintViewsManager(var context: AppCompatActivity,
fingerPrintHelper = FingerPrintHelper(context, this) fingerPrintHelper = FingerPrintHelper(context, this)
// callback for fingerprint findings // callback for fingerprint findings
fingerPrintHelper?.setAuthenticationCallback(object : FingerprintManager.AuthenticationCallback() { fingerPrintHelper?.setAuthenticationCallback(authenticationCallback)
override fun onAuthenticationError( }
errorCode: Int, }
errString: CharSequence) {
when (errorCode) { private val authenticationCallback = object : FingerprintManager.AuthenticationCallback() {
5 -> Log.i(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString") override fun onAuthenticationError(
else -> { errorCode: Int,
Log.e(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString") errString: CharSequence) {
setFingerPrintView(errString.toString(), true) when (errorCode) {
} 5 -> Log.i(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString")
else -> {
Log.e(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString")
setFingerPrintView(errString.toString(), true)
}
}
}
override fun onAuthenticationHelp(
helpCode: Int,
helpString: CharSequence) {
Log.w(TAG, "Fingerprint authentication help. Code : $helpCode Help : $helpString")
showError(helpString)
setFingerPrintView(helpString.toString(), true)
fingerPrintInfoView?.text = helpString.toString()
}
override fun onAuthenticationFailed() {
Log.e(TAG, "Fingerprint authentication failed, fingerprint not recognized")
showError(R.string.fingerprint_not_recognized)
}
override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
when (fingerPrintMode) {
FingerPrintHelper.Mode.STORE_MODE -> {
// newly store the entered password in encrypted way
fingerPrintHelper?.encryptData(passwordView?.text.toString())
}
FingerPrintHelper.Mode.OPEN_MODE -> {
// retrieve the encrypted value from preferences
prefsNoBackup?.getString(preferenceKeyValue, null)?.let {
fingerPrintHelper?.decryptData(it)
} }
} }
FingerPrintHelper.Mode.NOT_CONFIGURED_MODE -> {}
override fun onAuthenticationHelp( FingerPrintHelper.Mode.WAITING_PASSWORD_MODE -> {}
helpCode: Int, }
helpString: CharSequence) {
Log.w(TAG, "Fingerprint authentication help. Code : $helpCode Help : $helpString")
showError(helpString)
setFingerPrintView(helpString.toString(), true)
fingerPrintInfoView?.text = helpString.toString()
}
override fun onAuthenticationFailed() {
Log.e(TAG, "Fingerprint authentication failed, fingerprint not recognized")
showError(R.string.fingerprint_not_recognized)
}
override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
when (fingerPrintMode) {
FingerPrintHelper.Mode.STORE_MODE -> {
// newly store the entered password in encrypted way
fingerPrintHelper?.encryptData(passwordView?.text.toString())
}
FingerPrintHelper.Mode.OPEN_MODE -> {
// retrieve the encrypted value from preferences
prefsNoBackup?.getString(preferenceKeyValue, null)?.let {
fingerPrintHelper?.decryptData(it)
}
}
FingerPrintHelper.Mode.NOT_CONFIGURED_MODE -> {}
FingerPrintHelper.Mode.WAITING_PASSWORD_MODE -> {}
}
}
})
} }
} }
@@ -179,8 +183,13 @@ class FingerPrintViewsManager(var context: AppCompatActivity,
} }
fun destroy() { fun destroy() {
// Restore the checked listener
checkboxPasswordView?.setOnCheckedChangeListener(onCheckedPasswordChangeListener)
stopListening() stopListening()
// TODO destroy fingerPrintHelper = null
showFingerPrintViews(false)
} }
fun inflateOptionsMenu(menuInflater: MenuInflater, menu: Menu) { fun inflateOptionsMenu(menuInflater: MenuInflater, menu: Menu) {
@@ -188,8 +197,8 @@ class FingerPrintViewsManager(var context: AppCompatActivity,
menuInflater.inflate(R.menu.fingerprint, menu) menuInflater.inflate(R.menu.fingerprint, menu)
} }
private fun hideFingerPrintViews(hide: Boolean) { private fun showFingerPrintViews(show: Boolean) {
context.runOnUiThread { fingerPrintInfoView?.hide = hide } context.runOnUiThread { fingerPrintInfoView?.hide = !show }
} }
private fun setFingerPrintView(textId: Int, lock: Boolean = false) { private fun setFingerPrintView(textId: Int, lock: Boolean = false) {
@@ -210,14 +219,16 @@ class FingerPrintViewsManager(var context: AppCompatActivity,
// or manually disable // or manually disable
if (!PreferencesUtil.isFingerprintEnable(context) if (!PreferencesUtil.isFingerprintEnable(context)
|| !FingerPrintHelper.isFingerprintSupported(context.getSystemService(FingerprintManager::class.java))) { || !FingerPrintHelper.isFingerprintSupported(context.getSystemService(FingerprintManager::class.java))) {
hideFingerPrintViews(true) showFingerPrintViews(false)
} else { } else {
// all is set here so we can confirm to user and start listening for fingerprints
// show explanations // show explanations
fingerPrintInfoView?.setOnClickListener { _ -> fingerPrintInfoView?.setOnClickListener { _ ->
FingerPrintExplanationDialog().show(context.supportFragmentManager, "fingerprintDialog") FingerPrintExplanationDialog().show(context.supportFragmentManager, "fingerprintDialog")
} }
hideFingerPrintViews(false) showFingerPrintViews(true)
// fingerprint is available but not configured, show icon but in disabled state with some information
if (fingerPrintHelper?.hasEnrolledFingerprints() != true) { if (fingerPrintHelper?.hasEnrolledFingerprints() != true) {
// This happens when no fingerprints are registered. Listening won't start // This happens when no fingerprints are registered. Listening won't start
setFingerPrintView(R.string.configure_fingerprint, true) setFingerPrintView(R.string.configure_fingerprint, true)
@@ -236,9 +247,9 @@ class FingerPrintViewsManager(var context: AppCompatActivity,
} else { } else {
// listen for decryption // listen for decryption
initDecryptData() initDecryptData()
}// all is set here so we can confirm to user and start listening for fingerprints }
}// finally fingerprint available and configured so we can use it }// finally fingerprint available and configured so we can use it
}// fingerprint is available but not configured show icon but in disabled state with some information }
// Show fingerprint key deletion // Show fingerprint key deletion
context.invalidateOptionsMenu() context.invalidateOptionsMenu()

View File

@@ -66,7 +66,8 @@
<com.kunzisoft.keepass.view.FingerPrintInfoView <com.kunzisoft.keepass.view.FingerPrintInfoView
android:id="@+id/fingerprint_info" android:id="@+id/fingerprint_info"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
android:visibility="gone"/>
</LinearLayout> </LinearLayout>
<android.support.v7.widget.Toolbar <android.support.v7.widget.Toolbar