aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-05 09:13:38 +0100
committerDanilo M. <danix@danix.xyz>2026-11-05 09:13:38 +0100
commit3c421d6449e30e65753b42977646f3d24f1e31ef (patch)
tree90c30bb62a4af37133e8b4dd3705523da969af38
parentebddebeb6c4f7bc4d48196e21bf4a942c5a8b176 (diff)
downloadHardenedPass-3c421d6449e30e65753b42977646f3d24f1e31ef.tar.gz
HardenedPass-3c421d6449e30e65753b42977646f3d24f1e31ef.zip
fix(autofill-parser): open the save window on top on Android 14+
From Android 14 the framework sends the save IntentSender from the app being filled. Firefox targets SDK 34 or later and does not opt in to background activity starts, so the launch was blocked and AutofillSaveActivity opened hidden behind it: tapping Save seemed to do nothing. FixedSaveCallback now starts it from the service, which the system has bound, and opts in as the sender. Tested on an Android 14 tablet with Firefox release: the editor comes up on its own and the entry is saved. The same run confirmed the stale cached passphrase prompt, so both items leave TODO.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--AGENTS.md8
-rw-r--r--TODO.md7
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt29
3 files changed, 28 insertions, 16 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 7497bf20..3c6e99d7 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -122,8 +122,8 @@ instead:
Last full emulator run (2026-11-04, Compose UI): clone over SSH, PGP import, decrypt, TOTP,
create and push, conflict recovery (abort rebase, push a new branch), hard reset and
-fingerprint unlock passed. Last Firefox autofill run on the tablet: 2026-11-04 (fill, passphrase
-cache rule, no keys flow, picker, settings dialog), all passed.
+fingerprint unlock passed. Last Firefox autofill run on the tablet: 2026-11-05 (fill, save, stale
+cached passphrase), all passed.
## Verified facts and gotchas
@@ -161,6 +161,10 @@ cache rule, no keys flow, picker, settings dialog), all passed.
AES-GCM encrypted under Android Keystore keys by `util/crypto/KeystorePreferences.kt`.
androidx security-crypto was removed; `removeSecurityCryptoData` in `Migrations.kt` deleted
its data once on upgrade from 0.1.x.
+- Autofill save on Android 14+: the framework sends the save `IntentSender` from the app being
+ filled, which is not opted in to background activity starts, so `AutofillSaveActivity` opens
+ hidden behind it (`Background activity launch blocked` in logcat). `FixedSaveCallback` starts it
+ from the service instead, which the system has bound. Firefox's own save prompt shows as well.
- JGit is on 5.13.x, the last line that needs only Java 8 APIs. JGit 6+ needs Java 11 APIs
Android only partly desugars; moving to it is a large, separate job. Window cache JMX is off
in `Application` and GC runs without JGit's PID lock, because Android has no JMX.
diff --git a/TODO.md b/TODO.md
index 132aef17..4b105542 100644
--- a/TODO.md
+++ b/TODO.md
@@ -9,10 +9,3 @@ Open work after 0.2.0. Remove an item in the commit that finishes it.
- Git dialogs to Compose: the git operations' View dialogs (`BaseGitActivity`, `GitOperation`,
`CredentialFinder`, `BreakOutOfDetached`, `StoreActions`) and the `snackbar` helper still use
Material Components (Views). Moving them lets that dependency go.
-
-## Fixes
-
-- Firefox release (`org.mozilla.firefox`) is not in the autofill save list, so saving from it
- does not work (fill and generate do). First check that it sends save requests.
-- A stale cached passphrase (the key's passphrase changed) makes every autofill fail until the
- cache is cleared; the entry view asks for the passphrase instead. Do the same in autofill.
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt
index bac5d7f6..9ff646c9 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt
@@ -5,6 +5,7 @@
package com.github.androidpasswordstore.autofillparser
import android.annotation.SuppressLint
+import android.app.ActivityOptions
import android.app.assist.AssistStructure
import android.content.Context
import android.content.IntentSender
@@ -105,13 +106,27 @@ public class FixedSaveCallback(private val context: Context, private val callbac
}
public fun onSuccess(intentSender: IntentSender) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- callback.onSuccess(intentSender)
- } else {
- callback.onSuccess()
- // On SDKs < 28, we cannot advise the Autofill framework to launch the save intent in
- // the context of the app that triggered the save request. Hence, we launch it here.
- applicationContext.startIntentSender(intentSender, null, 0, 0, 0)
+ when {
+ // From Android 14 the framework sends this intent from the app being filled, which does not
+ // opt in to background activity starts when it targets SDK 34 or later: the save window
+ // opens hidden behind it. This service is bound by the system, so it may start it itself.
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> {
+ val options =
+ ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
+ .toBundle()
+ applicationContext.startIntentSender(intentSender, null, 0, 0, 0, options)
+ callback.onSuccess()
+ }
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> callback.onSuccess(intentSender)
+ else -> {
+ callback.onSuccess()
+ // On SDKs < 28, we cannot advise the Autofill framework to launch the save intent in
+ // the context of the app that triggered the save request. Hence, we launch it here.
+ applicationContext.startIntentSender(intentSender, null, 0, 0, 0)
+ }
}
}
}