From 1d564b91ecb1b52c585e21f10596e80bc69292d4 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Wed, 4 Nov 2026 11:28:40 +0100 Subject: feat(app): move the autofill decryption prompts to Compose AutofillDecryptActivity shows the no keys dialog and the entry view's passphrase dialog in Compose over its transparent FLAG_SECURE window. The flow starts once, on the first window focus, instead of on every onStart: Android 14 evicts a screen lock prompt shown before the activity is on top, and a restart showed a second passphrase dialog. After a key import it restarts on the next focus. Dismissing the no keys dialog now finishes instead of leaving an invisible window. Rotation and resizing no longer recreate the activity; other recreations cancel the fill. The passphrase is now cached only after a successful screen lock prompt, as the entry view does: a passphrase typed after a cancelled or unavailable prompt was cached whenever the cache feature was on. PasswordDialog, its layout, dimens.xml and requireKeysExist lose their last user and go. Co-Authored-By: Claude Opus 5.5 --- .../app/passwordstore/ui/autofill/AutofillModelTest.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'app/src/test/java') diff --git a/app/src/test/java/app/passwordstore/ui/autofill/AutofillModelTest.kt b/app/src/test/java/app/passwordstore/ui/autofill/AutofillModelTest.kt index 8907aa54..39f7f358 100644 --- a/app/src/test/java/app/passwordstore/ui/autofill/AutofillModelTest.kt +++ b/app/src/test/java/app/passwordstore/ui/autofill/AutofillModelTest.kt @@ -5,10 +5,13 @@ package app.passwordstore.ui.autofill +import app.passwordstore.util.auth.BiometricAuthenticator.Result as BiometricResult import app.passwordstore.util.settings.DirectoryStructure import java.io.File import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue class AutofillModelTest { @@ -70,4 +73,19 @@ class AutofillModelTest { rows(DirectoryStructure.FileBased, "b.org.gpg", "a.org.gpg").map { it.second }, ) } + + @Test + fun passphraseIsCachedOnlyAfterTheScreenLock() { + assertTrue(cachesPassphrase(true, BiometricResult.Success(null))) + val notConfirmed = + listOf( + BiometricResult.CanceledByUser, + BiometricResult.CanceledBySystem, + BiometricResult.HardwareUnavailableOrDisabled, + BiometricResult.Failure(null, "failed"), + BiometricResult.Retry, + ) + for (auth in notConfirmed) assertFalse(cachesPassphrase(true, auth), auth.toString()) + assertFalse(cachesPassphrase(false, BiometricResult.Success(null))) + } } -- cgit v1.2.3