M1-06: Foreground service, audio focus, and route hardening #6
Labels
No labels
area/agent
area/capture
area/editor
area/geo
area/security
area/sync
area/transcription
area/ui
area/vault
area/voice-memos
blocked
milestone/M1
milestone/M2
milestone/M3
milestone/M4
needs-decision
needs-hardware
p0
p1
p2
type/bug
type/enhancement
type/feature
type/idea
type/infrastructure
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Stash/stash-android#6
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Record with the screen off, and stop losing recordings to route changes and interruptions.
This is the single biggest reliability complaint about v2, restated for Android.
Wes, on what this has to be: "It handles microphone grabbing beautifully. It doesn't crash like
the other one, or lock up, like the other one."
The three failure modes to design against
They were observed on iOS, and every one of them has an Android analogue that is at least as likely:
1 — Holding a stale microphone instead of probing the current default. Recorded on Bluetooth,
backgrounded for an hour, reconnected, started a new recording — and the app was still holding the
old route.
2 — Swapping to wired headphones produced a recording of nothing. The recording UI appeared,
nothing was captured, and stopping froze the app on "saving" for what turned out to be four seconds
of silence.
3 — A declined phone call ended the recording. "I didn't answer it. I declined it. But the
recording had already stopped." On Android this arrives as a transient audio focus loss, and the
default behaviour of most implementations is exactly the bug.
Scope
FOREGROUND_SERVICE_MICROPHONE, started before capture begins.Android 14 requires the type and the matching permission, and a service without them is killed
with an exception that does not explain itself.
POST_NOTIFICATIONS(Android 13+), because a foreground service with no visible notification isnot a thing that exists.
AudioFocusRequest. Transient loss — the declined call — must resume, notterminate. Permanent loss is the only case that ends a recording, and it says so.
AudioDeviceCallbackfor route changes: follow the current input rather than caching one.Seamless mid-recording if achievable; if not, it must at minimum never silently record nothing.
survivable, but a foreground service is the thing standing between a forty-minute walk and a
truncated memo.
Done when — Wes validates all five on the Pixel
Milestone 1 of Stash for Android, mirroring
stash-iosM1. M1 is a functioning app on the testdevice with no sync at all — record voice memos reliably and get them off the device by hand.
Sync arrives in M3.
Test device is a Pixel 6 (Tensor G1) borrowed from a friend, until something better turns up.
Stock Android, so no OEM battery-killer behaviour to fight — worth remembering that a phone from
another manufacturer may not be as forgiving about background work.
Translation of
Stash/stash-ios#6. Where the platform forces a different answer this issue says so; where itdoes not, the iOS issue is the fuller statement of intent and should be read alongside this one.
Working agreement for every issue in this repo: feature branch, tested before the PR opens
(on-device where the label says so), then Wes reviews the PR and we walk the code together. Docs
update in the same commit. A PR that takes more than 20 minutes to review is too big — say so and
split it.