fix: prove the FGS video's scan start by notification, not by the service record
The script could report "scan started" on runs where the app was being killed, which sent me
chasing a "mid-scan death" that never happened. The mistake was the signal: dumpsys activity
services lists a service *record* from the moment startForegroundService() is called, so it says
nothing about whether startForeground() was reached - and that gap is exactly what the platform's
deadline measures. logcat's events buffer shows what really happened on every attempt:
am_crash: [..., android.app.ForegroundServiceDidNotStartInTimeException,
Context.startForegroundService() did not then call
Service.startForeground(): .../ScanService]
am_proc_died: [...]
No am_kill, no low-memory record: not memory pressure, and not a crash in the app's own code. The
script now waits for the app's notification, which only exists once startForeground() has been
called, and prints that am_crash line when the service never starts, so a failure is never
mistaken for a success again.
Also in the script:
- let the emulator settle before the run (first-boot work competes for the same CPU) and give the
process time to load its classes before asking it to start a service inside the budget, both
overridable as SETTLE_SECONDS and WARM_SECONDS,
- give up with a non-zero exit and an explicit "record this on a real device" message rather than
carrying on to record a video whose scan never started,
- read the events buffer rather than the main one when reporting the reason.
Verdict for the docs, corrected: this capture cannot be done on a KVM-less emulator, and the
previous "second failure mode" was this one misread. The last crash landed on a process that had
been alive and idle for over a minute, so no amount of warming fixes it - while on the phone the
same build scans 5,363 photos in 20 s with the notification up the whole time. The take belongs on
the phone; the script is the checklist for what it has to show.
This commit is contained in:
@@ -289,21 +289,31 @@ action except the items marked **[code]**.
|
||||
|
||||
Keep it under two minutes and don't cut mid-way; a reviewer has to be able to follow
|
||||
the trigger and see the service doing its job after the app leaves the screen.
|
||||
⚠️ **Record it on a real device.** The capture proved unreliable on this machine's
|
||||
software-emulated AVD (no KVM), and both failures are platform-level rather than
|
||||
app-level:
|
||||
⚠️ **Record it on a real device — it cannot be done on a KVM-less emulator.** Every
|
||||
attempt to start a scan on this machine's software-emulated AVD ended the same way, and
|
||||
logcat's events buffer names the cause each time:
|
||||
|
||||
- A **cold** app can miss Android's 5-second `startForeground` deadline and get killed
|
||||
(`ForegroundServiceDidNotStartInTimeException` → *Force finishing activity*), so the
|
||||
launcher appears where the scan should have started. The script's warm-up phase gets a
|
||||
process past that — a process that has already started the service once succeeds — but
|
||||
- the app also died **mid-scan** on the emulator during testing, and the launcher was on
|
||||
screen afterwards with no exception from the app in logcat at all. A warmer process
|
||||
does not fix that one.
|
||||
```
|
||||
am_crash: [..., android.app.ForegroundServiceDidNotStartInTimeException,
|
||||
Context.startForegroundService() did not then call
|
||||
Service.startForeground(): .../ScanService]
|
||||
am_proc_died: [...]
|
||||
```
|
||||
|
||||
Neither failure has been seen on the real test device, where the same 22-photo library
|
||||
scans without incident. So treat `tools/record-fgs-demo.sh` as the checklist for the
|
||||
journey it records, and run it against the phone.
|
||||
The platform kills the app and force-finishes the activity, so the launcher appears
|
||||
where the scan should have started. It is not a crash in the app's own code, it is not
|
||||
memory pressure (there is no `am_kill` or low-memory record), and it is not something a
|
||||
warm-up can fix: the last one happened on a process that had been alive and idle for over
|
||||
a minute. Software emulation is simply too slow to get from `startForegroundService()` to
|
||||
`startForeground()` inside Android's budget — while on the phone this app scans a
|
||||
5,363-photo library in 20 s with the notification up throughout.
|
||||
|
||||
An earlier version of this note claimed a second, unexplained mid-scan death. That was
|
||||
this same failure misread: the script's old "is a scan running?" check matched the
|
||||
service *record*, which exists from the moment `startForegroundService()` is called, so
|
||||
it reported success on runs that were already dying. `tools/record-fgs-demo.sh` now waits
|
||||
for the app's notification instead, which is the only honest proof the service started,
|
||||
and reports the `am_crash` line when it never does.
|
||||
|
||||
The declaration is **per type**: if a new foreground-service type is ever added to
|
||||
the manifest, it has to be declared here too.
|
||||
|
||||
Reference in New Issue
Block a user