diff --git a/CHANGELOG b/CHANGELOG index 7de06661e..8e6cc40ff 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +KeePassDX(2.9.10) + * Try to fix autofill #852 + * Fix database change dialog displayed too often #853 + KeePassDX(2.9.9) * Detect file changes and reload database #794 * Inline suggestions autofill with compatible keyboard (Android R) #827 diff --git a/app/build.gradle b/app/build.gradle index 928d0eaab..c9704b15f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId "com.kunzisoft.keepass" minSdkVersion 14 targetSdkVersion 30 - versionCode = 53 - versionName = "2.9.9" + versionCode = 54 + versionName = "2.9.10" multiDexEnabled true testApplicationId = "com.kunzisoft.keepass.tests" diff --git a/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt b/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt index f169c2655..aba7353a8 100644 --- a/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt +++ b/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt @@ -64,8 +64,12 @@ object AutofillHelper { fun retrieveAutofillComponent(intent: Intent?): AutofillComponent? { intent?.getParcelableExtra(EXTRA_ASSIST_STRUCTURE)?.let { assistStructure -> - return AutofillComponent(assistStructure, - intent.getParcelableExtra(EXTRA_INLINE_SUGGESTIONS_REQUEST)) + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + AutofillComponent(assistStructure, + intent.getParcelableExtra(EXTRA_INLINE_SUGGESTIONS_REQUEST)) + } else { + AutofillComponent(assistStructure, null) + } } return null } @@ -205,10 +209,14 @@ object AutofillHelper { activity.intent?.getParcelableExtra(EXTRA_ASSIST_STRUCTURE)?.let { structure -> StructureParser(structure).parse()?.let { result -> // New Response - val inlineSuggestionsRequest = activity.intent?.getParcelableExtra(EXTRA_INLINE_SUGGESTIONS_REQUEST) - val response = buildResponse(activity, entriesInfo, result, inlineSuggestionsRequest) - if (inlineSuggestionsRequest != null) { - Toast.makeText(activity.applicationContext, R.string.autofill_inline_suggestions_keyboard, Toast.LENGTH_SHORT).show() + val response = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val inlineSuggestionsRequest = activity.intent?.getParcelableExtra(EXTRA_INLINE_SUGGESTIONS_REQUEST) + if (inlineSuggestionsRequest != null) { + Toast.makeText(activity.applicationContext, R.string.autofill_inline_suggestions_keyboard, Toast.LENGTH_SHORT).show() + } + buildResponse(activity, entriesInfo, result, inlineSuggestionsRequest) + } else { + buildResponse(activity, entriesInfo, result, null) } val mReplyIntent = Intent() Log.d(activity.javaClass.name, "Successed Autofill auth.") diff --git a/app/src/main/java/com/kunzisoft/keepass/autofill/KeeAutofillService.kt b/app/src/main/java/com/kunzisoft/keepass/autofill/KeeAutofillService.kt index cccbe277e..cdd6e11a6 100644 --- a/app/src/main/java/com/kunzisoft/keepass/autofill/KeeAutofillService.kt +++ b/app/src/main/java/com/kunzisoft/keepass/autofill/KeeAutofillService.kt @@ -174,9 +174,9 @@ class KeeAutofillService : AutofillService() { } // Build inline presentation - var inlinePresentation: InlinePresentation? = null if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && autofillInlineSuggestionsEnabled) { + var inlinePresentation: InlinePresentation? = null inlineSuggestionsRequest?.let { val inlinePresentationSpecs = inlineSuggestionsRequest.inlinePresentationSpecs if (inlineSuggestionsRequest.maxSuggestionCount > 0 @@ -203,14 +203,10 @@ class KeeAutofillService : AutofillService() { } } } - } - - // Build response - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // Build response responseBuilder.setAuthentication(autofillIds, intentSender, remoteViewsUnlock, inlinePresentation) - } else { - responseBuilder.setAuthentication(autofillIds, intentSender, remoteViewsUnlock) } + responseBuilder.setAuthentication(autofillIds, intentSender, remoteViewsUnlock) callback.onSuccess(responseBuilder.build()) } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt index c2035f53d..1d192b773 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt @@ -129,17 +129,17 @@ abstract class DatabaseVersioned< val keyData = keyInputStream.readBytes() - // Check 32 bits key file - if (keyData.size == 32) { - return keyData - } - // Check XML key file val xmlKeyByteArray = loadXmlKeyFile(ByteArrayInputStream(keyData)) if (xmlKeyByteArray != null) { return xmlKeyByteArray } + // Check 32 bits key file + if (keyData.size == 32) { + return keyData + } + // Hash file as binary data try { return MessageDigest.getInstance("SHA-256").digest(keyData) diff --git a/app/src/main/java/com/kunzisoft/keepass/model/SnapFileDatabaseInfo.kt b/app/src/main/java/com/kunzisoft/keepass/model/SnapFileDatabaseInfo.kt index 4ef9acb3e..6d6bbbbd9 100644 --- a/app/src/main/java/com/kunzisoft/keepass/model/SnapFileDatabaseInfo.kt +++ b/app/src/main/java/com/kunzisoft/keepass/model/SnapFileDatabaseInfo.kt @@ -42,6 +42,26 @@ data class SnapFileDatabaseInfo(var fileUri: Uri?, return 0 } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is SnapFileDatabaseInfo) return false + + if (fileUri != other.fileUri) return false + if (exists != other.exists) return false + if (lastModification != other.lastModification) return false + if (size != other.size) return false + + return true + } + + override fun hashCode(): Int { + var result = fileUri?.hashCode() ?: 0 + result = 31 * result + exists.hashCode() + result = 31 * result + (lastModification?.hashCode() ?: 0) + result = 31 * result + (size?.hashCode() ?: 0) + return result + } + companion object CREATOR : Parcelable.Creator { override fun createFromParcel(parcel: Parcel): SnapFileDatabaseInfo { return SnapFileDatabaseInfo(parcel) diff --git a/app/src/main/java/com/kunzisoft/keepass/notifications/DatabaseTaskNotificationService.kt b/app/src/main/java/com/kunzisoft/keepass/notifications/DatabaseTaskNotificationService.kt index 3535fba62..b63b5ae54 100644 --- a/app/src/main/java/com/kunzisoft/keepass/notifications/DatabaseTaskNotificationService.kt +++ b/app/src/main/java/com/kunzisoft/keepass/notifications/DatabaseTaskNotificationService.kt @@ -66,7 +66,6 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress private var mAllowFinishAction = AtomicBoolean() private var mActionRunning = false - private var mSnapFileDatabaseInfo: SnapFileDatabaseInfo? = null private var mDatabaseInfoListeners = LinkedList() private var mIconId: Int = R.drawable.notification_ic_database_load @@ -134,15 +133,28 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress val previousDatabaseInfo = mSnapFileDatabaseInfo val lastFileDatabaseInfo = SnapFileDatabaseInfo.fromFileDatabaseInfo( FileDatabaseInfo(applicationContext, it)) - if (previousDatabaseInfo != null) { - if (previousDatabaseInfo != lastFileDatabaseInfo) { - Log.i(TAG, "Database file modified " + - "$previousDatabaseInfo != $lastFileDatabaseInfo ") - // Call listener to indicate a change in database info + + val oldDatabaseModification = previousDatabaseInfo?.lastModification + val newDatabaseModification = lastFileDatabaseInfo.lastModification + + val conditionExists = previousDatabaseInfo != null + && previousDatabaseInfo.exists != lastFileDatabaseInfo.exists + // To prevent dialog opening too often + val conditionLastModification = (oldDatabaseModification != null && newDatabaseModification != null + && oldDatabaseModification < newDatabaseModification + && mLastLocalSaveTime + 5000 < newDatabaseModification) + + if (conditionExists || conditionLastModification) { + // Show the dialog only if it's real new info and not a delay after a save + Log.i(TAG, "Database file modified " + + "$previousDatabaseInfo != $lastFileDatabaseInfo ") + // Call listener to indicate a change in database info + if (previousDatabaseInfo != null) { mDatabaseInfoListeners.forEach { listener -> listener.onDatabaseInfoChanged(previousDatabaseInfo, lastFileDatabaseInfo) } } + mSnapFileDatabaseInfo = lastFileDatabaseInfo } } } @@ -151,6 +163,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress mDatabase.fileUri?.let { mSnapFileDatabaseInfo = SnapFileDatabaseInfo.fromFileDatabaseInfo( FileDatabaseInfo(applicationContext, it)) + Log.i(TAG, "Database file saved $mSnapFileDatabaseInfo") } } @@ -235,9 +248,21 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress actionTaskListener.onStopAction(intentAction!!, result) } } finally { + // Save the database info before performing action + if (intentAction == ACTION_DATABASE_LOAD_TASK) { + saveDatabaseInfo() + } + // Save the database info after performing save action + if (intentAction == ACTION_DATABASE_SAVE + || intent?.getBooleanExtra(SAVE_DATABASE_KEY, false) == true) { + mDatabase.fileUri?.let { + val newSnapFileDatabaseInfo = SnapFileDatabaseInfo.fromFileDatabaseInfo( + FileDatabaseInfo(applicationContext, it)) + mLastLocalSaveTime = System.currentTimeMillis() + mSnapFileDatabaseInfo = newSnapFileDatabaseInfo + } + } removeIntentData(intent) - // Save the database info after performing action - saveDatabaseInfo() TimeoutHelper.releaseTemporarilyDisableTimeout() if (TimeoutHelper.checkTimeAndLockIfTimeout(this@DatabaseTaskNotificationService)) { if (!mDatabase.loaded) { @@ -884,6 +909,9 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress const val OLD_ELEMENT_KEY = "OLD_ELEMENT_KEY" // Warning type of this thing change every time const val NEW_ELEMENT_KEY = "NEW_ELEMENT_KEY" // Warning type of this thing change every time + private var mSnapFileDatabaseInfo: SnapFileDatabaseInfo? = null + private var mLastLocalSaveTime: Long = 0 + fun getListNodesFromBundle(database: Database, bundle: Bundle): List { val nodesAction = ArrayList() bundle.getParcelableArrayList>(GROUPS_ID_KEY)?.forEach { diff --git a/fastlane/metadata/android/en-US/changelogs/54.txt b/fastlane/metadata/android/en-US/changelogs/54.txt new file mode 100644 index 000000000..b96a30ff4 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/54.txt @@ -0,0 +1,2 @@ + * Try to fix autofill #852 + * Fix database change dialog displayed too often #853 \ No newline at end of file diff --git a/fastlane/metadata/android/fr-FR/changelogs/54.txt b/fastlane/metadata/android/fr-FR/changelogs/54.txt new file mode 100644 index 000000000..e11d58628 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/54.txt @@ -0,0 +1,2 @@ + * Tentative de résolution de l'autofill #852 + * Correction du dialogue de changement de base de données affiché trop souvent #853 \ No newline at end of file