More flexible password change when fingerprint is saved
This commit is contained in:
parent
7cdfc32c31
commit
4df1086734
@ -1,11 +1,13 @@
|
||||
package sushi.hardcore.droidfs
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import sushi.hardcore.droidfs.databinding.ActivityChangePasswordBinding
|
||||
@ -24,6 +26,9 @@ class ChangePasswordActivity: BaseActivity() {
|
||||
private lateinit var volumeDatabase: VolumeDatabase
|
||||
private var fingerprintProtector: FingerprintProtector? = null
|
||||
private var usfFingerprint: Boolean = false
|
||||
private val inputMethodManager by lazy {
|
||||
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -38,8 +43,7 @@ class ChangePasswordActivity: BaseActivity() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
fingerprintProtector = FingerprintProtector.new(this, themeValue, volumeDatabase)
|
||||
if (fingerprintProtector != null && volume.encryptedHash != null) {
|
||||
binding.textCurrentPasswordLabel.visibility = View.GONE
|
||||
binding.editCurrentPassword.visibility = View.GONE
|
||||
binding.fingerprintSwitchContainer.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
if (!usfFingerprint || fingerprintProtector == null) {
|
||||
@ -50,6 +54,20 @@ class ChangePasswordActivity: BaseActivity() {
|
||||
it.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD
|
||||
}
|
||||
}
|
||||
binding.fingerprintSwitchContainer.setOnClickListener {
|
||||
binding.switchUseFingerprint.toggle()
|
||||
}
|
||||
binding.switchUseFingerprint.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked && binding.editCurrentPassword.hasFocus()) {
|
||||
binding.editCurrentPassword.clearFocus()
|
||||
inputMethodManager.hideSoftInputFromWindow(binding.editCurrentPassword.windowToken, 0)
|
||||
}
|
||||
}
|
||||
binding.editCurrentPassword.setOnFocusChangeListener { _, hasFocus ->
|
||||
if (hasFocus) {
|
||||
binding.switchUseFingerprint.isChecked = false
|
||||
}
|
||||
}
|
||||
binding.editPasswordConfirm.setOnEditorActionListener { _, _, _ ->
|
||||
changeVolumePassword()
|
||||
true
|
||||
@ -81,22 +99,24 @@ class ChangePasswordActivity: BaseActivity() {
|
||||
volume.encryptedHash?.let { encryptedHash ->
|
||||
volume.iv?.let { iv ->
|
||||
fingerprintProtector?.let {
|
||||
changeWithCurrentPassword = false
|
||||
it.listener = object : FingerprintProtector.Listener {
|
||||
override fun onHashStorageReset() {
|
||||
showCurrentPasswordInput()
|
||||
volume.encryptedHash = null
|
||||
volume.iv = null
|
||||
}
|
||||
override fun onPasswordHashDecrypted(hash: ByteArray) {
|
||||
changeVolumePassword(newPassword, hash)
|
||||
}
|
||||
override fun onPasswordHashSaved() {}
|
||||
override fun onFailed(pending: Boolean) {
|
||||
Arrays.fill(newPassword, 0)
|
||||
if (binding.switchUseFingerprint.isChecked) {
|
||||
changeWithCurrentPassword = false
|
||||
it.listener = object : FingerprintProtector.Listener {
|
||||
override fun onHashStorageReset() {
|
||||
showCurrentPasswordInput()
|
||||
volume.encryptedHash = null
|
||||
volume.iv = null
|
||||
}
|
||||
override fun onPasswordHashDecrypted(hash: ByteArray) {
|
||||
changeVolumePassword(newPassword, hash)
|
||||
}
|
||||
override fun onPasswordHashSaved() {}
|
||||
override fun onFailed(pending: Boolean) {
|
||||
Arrays.fill(newPassword, 0)
|
||||
}
|
||||
}
|
||||
it.loadPasswordHash(volume.name, encryptedHash, iv)
|
||||
}
|
||||
it.loadPasswordHash(volume.name, encryptedHash, iv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener {
|
||||
removeVolumes(selectedVolumes)
|
||||
true
|
||||
}
|
||||
R.id.forget_password -> {
|
||||
R.id.delete_password_hash -> {
|
||||
for (i in volumeAdapter.selectedItems) {
|
||||
if (volumeDatabase.removeHash(volumeAdapter.volumes[i]))
|
||||
volumeAdapter.onVolumeChanged(i)
|
||||
@ -349,7 +349,7 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener {
|
||||
val isSelecting = volumeAdapter.selectedItems.isNotEmpty()
|
||||
menu.findItem(R.id.select_all).isVisible = isSelecting
|
||||
menu.findItem(R.id.remove).isVisible = isSelecting
|
||||
menu.findItem(R.id.forget_password).isVisible =
|
||||
menu.findItem(R.id.delete_password_hash).isVisible =
|
||||
isSelecting &&
|
||||
!volumeAdapter.selectedItems.any { i -> volumeAdapter.volumes[i].encryptedHash == null }
|
||||
val onlyOneSelected = volumeAdapter.selectedItems.size == 1
|
||||
|
@ -31,15 +31,37 @@
|
||||
android:id="@+id/edit_current_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/volume_operation_vertical_gap"
|
||||
android:autofillHints="password"
|
||||
android:hint="@string/current_password_hint"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fingerprint_switch_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:src="@drawable/icon_fingerprint"
|
||||
android:layout_marginEnd="5dp"/>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/switch_use_fingerprint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/use_fingerprint"
|
||||
android:checked="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/volume_operation_vertical_gap"
|
||||
android:text="@string/new_password_label" />
|
||||
|
||||
<EditText
|
||||
|
@ -23,10 +23,10 @@
|
||||
android:icon="@drawable/icon_settings"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/forget_password"
|
||||
android:id="@+id/delete_password_hash"
|
||||
app:showAsAction="never"
|
||||
android:visible="false"
|
||||
android:title="@string/forget_password"/>
|
||||
android:title="@string/remove_fingerprint"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/change_password"
|
||||
|
@ -186,7 +186,6 @@
|
||||
<string name="remove">إزالة</string>
|
||||
<string name="settings">إعدادات</string>
|
||||
<string name="select_all">تحديد الكل</string>
|
||||
<string name="forget_password">نسيان كلمة المرور</string>
|
||||
<string name="unrecoverable_key_exception_msg">%s. فشل تحميل مفتاح التشفير.</string>
|
||||
<string name="unrecoverable_key_exception">UnrecoverableKeyException</string>
|
||||
<string name="delete_hidden_volume_question">%s مخفي ، هل تريد فقط نسيان مسار المجلد أو حذف كل محتوياته أيضًا?</string>
|
||||
|
@ -186,7 +186,6 @@
|
||||
<string name="remove">Eliminar</string>
|
||||
<string name="settings">Ajustes</string>
|
||||
<string name="select_all">Seleccionar todo</string>
|
||||
<string name="forget_password">Olvidar la contraseña</string>
|
||||
<string name="unrecoverable_key_exception_msg">%s. No se puede cargar la clave de encriptación.</string>
|
||||
<string name="unrecoverable_key_exception">UnrecoverableKeyException</string>
|
||||
<string name="delete_hidden_volume_question">%s está oculto, ¿sólo quieres olvidar la ruta del volumen o también BORRAR todo su CONTENIDO?</string>
|
||||
|
@ -180,7 +180,6 @@
|
||||
<string name="remove">Remover</string>
|
||||
<string name="settings">Configurações</string>
|
||||
<string name="select_all">Selecionar tudo</string>
|
||||
<string name="forget_password">Abandonar a senha</string>
|
||||
<string name="unrecoverable_key_exception_msg">%s. Não foi possível carregar a chave de criptografia.</string>
|
||||
<string name="unrecoverable_key_exception">UnrecoverableKeyException</string>
|
||||
<string name="delete_hidden_volume_question">%s está oculto, você só quer abandonar o caminho do volume ou também REMOVER todo o seu CONTEÚDO?</string>
|
||||
|
@ -180,7 +180,6 @@
|
||||
<string name="remove">Удалить</string>
|
||||
<string name="settings">Настройки</string>
|
||||
<string name="select_all">Выбрать все</string>
|
||||
<string name="forget_password">Забыть пароль</string>
|
||||
<string name="unrecoverable_key_exception_msg">%s. Невозможно загрузить ключ шифрования.</string>
|
||||
<string name="delete_hidden_volume_question">Том \"%s\" скрытый, вы хотите только забыть путь к нему или УДАЛИТЬ том со всем его СОДЕРЖИМЫМ?</string>
|
||||
<string name="forget_only">Только забыть</string>
|
||||
|
@ -187,7 +187,7 @@
|
||||
<string name="remove">Remove</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="select_all">Select All</string>
|
||||
<string name="forget_password">Forget password</string>
|
||||
<string name="remove_fingerprint">Remove fingerprint</string>
|
||||
<string name="unrecoverable_key_exception_msg">%s. Can\'t load encryption key.</string>
|
||||
<string name="unrecoverable_key_exception">UnrecoverableKeyException</string>
|
||||
<string name="delete_hidden_volume_question">%s is hidden, do you just want to forget the path of the volume or also DELETE all its CONTENT?</string>
|
||||
@ -249,4 +249,5 @@
|
||||
<string name="volume_type">(%s)</string>
|
||||
<string name="volume_type_read_only">(%s, read-only)</string>
|
||||
<string name="io_error">I/O Error.</string>
|
||||
<string name="use_fingerprint">Use fingerprint instead of current password</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user