Merge tag '4.1.8' into develop

4.1.8
This commit is contained in:
J-Jamet
2025-09-12 16:04:08 +02:00
5 changed files with 59 additions and 32 deletions

View File

@@ -1,3 +1,11 @@
KeePassDX(4.1.8)
* Updated to API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
* Remember last read-only state #2099 #2100 (Thx @rmacklin)
* Fix merge deletion #1516
* Fix space in search #175
* Fix deletable recycle bin #2163
* Small fixes
KeePassDX(4.1.7) KeePassDX(4.1.7)
* Fix CipherDatabase for biometric states #2119 * Fix CipherDatabase for biometric states #2119

View File

@@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass" applicationId "com.kunzisoft.keepass"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 35 targetSdkVersion 35
versionCode = 139 versionCode = 141
versionName = "4.1.7" versionName = "4.1.8"
multiDexEnabled true multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests" testApplicationId = "com.kunzisoft.keepass.tests"

View File

@@ -43,6 +43,7 @@ import androidx.biometric.BiometricManager
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.commit import androidx.fragment.app.commit
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@@ -75,8 +76,8 @@ import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.MAIN_CREDENTIAL_KEY import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.MAIN_CREDENTIAL_KEY
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY
import com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity
import com.kunzisoft.keepass.settings.AppearanceSettingsActivity import com.kunzisoft.keepass.settings.AppearanceSettingsActivity
import com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
@@ -107,7 +108,11 @@ class MainCredentialActivity : DatabaseModeActivity() {
private var deviceUnlockFragment: DeviceUnlockFragment? = null private var deviceUnlockFragment: DeviceUnlockFragment? = null
private val mDatabaseFileViewModel: DatabaseFileViewModel by viewModels() private val mDatabaseFileViewModel: DatabaseFileViewModel by viewModels()
private val mDeviceUnlockViewModel: DeviceUnlockViewModel by viewModels() private val mDeviceUnlockViewModel: DeviceUnlockViewModel? by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ViewModelProvider(this)[DeviceUnlockViewModel::class.java]
} else null
}
private val mPasswordActivityEducation = PasswordActivityEducation(this) private val mPasswordActivityEducation = PasswordActivityEducation(this)
@@ -177,7 +182,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
// Listen password checkbox to init advanced unlock and confirmation button // Listen password checkbox to init advanced unlock and confirmation button
mainCredentialView?.onConditionToStoreCredentialChanged = { _, verified -> mainCredentialView?.onConditionToStoreCredentialChanged = { _, verified ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.checkConditionToStoreCredential( mDeviceUnlockViewModel?.checkConditionToStoreCredential(
condition = verified condition = verified
) )
} }
@@ -242,21 +247,22 @@ class MainCredentialActivity : DatabaseModeActivity() {
lifecycleScope.launch { lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) { repeatOnLifecycle(Lifecycle.State.STARTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.uiState.collect { uiState -> mDeviceUnlockViewModel?.let { deviceUnlockViewModel ->
deviceUnlockViewModel.uiState.collect { uiState ->
// New value received // New value received
uiState.credentialRequiredCipher?.let { cipher -> uiState.credentialRequiredCipher?.let { cipher ->
mDeviceUnlockViewModel.encryptCredential( deviceUnlockViewModel.encryptCredential(
credential = getCredentialForEncryption(), credential = getCredentialForEncryption(),
cipher = cipher cipher = cipher
) )
} }
uiState.cipherEncryptDatabase?.let { cipherEncryptDatabase -> uiState.cipherEncryptDatabase?.let { cipherEncryptDatabase ->
onCredentialEncrypted(cipherEncryptDatabase) onCredentialEncrypted(cipherEncryptDatabase)
mDeviceUnlockViewModel.consumeCredentialEncrypted() deviceUnlockViewModel.consumeCredentialEncrypted()
} }
uiState.cipherDecryptDatabase?.let { cipherDecryptDatabase -> uiState.cipherDecryptDatabase?.let { cipherDecryptDatabase ->
onCredentialDecrypted(cipherDecryptDatabase) onCredentialDecrypted(cipherDecryptDatabase)
mDeviceUnlockViewModel.consumeCredentialDecrypted() deviceUnlockViewModel.consumeCredentialDecrypted()
} }
uiState.exception?.let { error -> uiState.exception?.let { error ->
Snackbar.make( Snackbar.make(
@@ -264,7 +270,8 @@ class MainCredentialActivity : DatabaseModeActivity() {
deviceUnlockError(error, this@MainCredentialActivity), deviceUnlockError(error, this@MainCredentialActivity),
Snackbar.LENGTH_LONG Snackbar.LENGTH_LONG
).asError().show() ).asError().show()
mDeviceUnlockViewModel.exceptionShown() deviceUnlockViewModel.exceptionShown()
}
} }
} }
} }
@@ -517,7 +524,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
} else { } else {
// Init Biometric elements // Init Biometric elements
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.connect(databaseFileUri) mDeviceUnlockViewModel?.connect(databaseFileUri)
} }
} }
@@ -661,7 +668,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
try { try {
menu.findItem(R.id.menu_open_file_read_mode_key) menu.findItem(R.id.menu_open_file_read_mode_key)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Unable to find read mode menu") Log.e(TAG, "Unable to find read mode menu", e)
} }
performedNextEducation(menu) performedNextEducation(menu)
}, },
@@ -690,7 +697,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
}) })
} }
} }
} catch (ignored: Exception) {} } catch (_: Exception) {}
} }
} }
@@ -727,7 +734,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.disconnect() mDeviceUnlockViewModel?.disconnect()
} }
} }

View File

@@ -0,0 +1,6 @@
* Updated to API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
* Remember last read-only state #2099 #2100 (Thx @rmacklin)
* Fix merge deletion #1516
* Fix space in search #175
* Fix deletable recycle bin #2163
* Small fixes

View File

@@ -0,0 +1,6 @@
* Mise à jour vers API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
* Sauvegarde du dernier état lecture seule #2099 #2100 (Thx @rmacklin)
* Correction de la suppression lors d'un merge #1516
* Correction des espaces dans la recherche #175
* Correction de la poubelle supprimable #2163
* Petites corrections