docs: record the QEMU clock-dilation lead for the FGS video
Chasing the video on the emulator found one lever that actually attacks the failure, and it is worth writing down even though it did not hold: emulator -avd phone ... -qemu -icount shift=1,sleep=off Without -icount the guest clock is tied to the host's wall clock, so Android's five-second startForegroundService() deadline means five real seconds however slowly TCG executes - which is what kills the app here every time. With -icount the guest clock advances per executed instruction, and it measured 2.30x slow (30.9 s host to 13.4 s guest uptime). On that boot a scan start succeeded: the app's notification appeared five seconds after the tap and there was no am_crash, the only success recorded on this machine. It then stopped reproducing - later attempts produced neither a notification nor a crash. Two possibilities, and the second is an app-side diagnosability gap: either the tap never reached the app, or ScanService.start() swallowed a ForegroundServiceStartNotAllowedException, which it does silently (it catches IllegalStateException and does nothing with it, so logcat shows nothing at all). Notes say so, and point at SETTLE_SECONDS / WARM_SECONDS for scaling the waits, because a dilated guest is slower at everything - uiautomator dumps included. The script also retries a tap (up to three times, re-reading the coordinates) before falling back to a cold restart, since on a slow emulator the window can still be settling while the accessibility tree already lists the button - and a restart costs another cold start. The recommendation stands: record the take on the phone.
This commit is contained in:
@@ -29,6 +29,15 @@
|
||||
#
|
||||
# It also writes a checkpoint PNG at each milestone, so the recording can be checked without
|
||||
# decoding the video. `ffprobe` is used for the duration when it is installed.
|
||||
#
|
||||
# On a host with no KVM the one lever that ever got the service started here was QEMU's clock
|
||||
# dilation, which makes Android's deadline be measured in slower time than the host's:
|
||||
#
|
||||
# emulator -avd <name> ... -qemu -icount shift=1,sleep=off # guest clock ran 2.30x slow
|
||||
#
|
||||
# That worked once and then not again, so treat it as a lead rather than a recipe: scale the two
|
||||
# timing knobs up for a dilated clock (the guest is slower at everything, dumps included) and expect
|
||||
# to iterate. docs/PLAY_RELEASE_CHECKLIST.md step 5 has the long version of this note.
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "$0")" && pwd)"
|
||||
@@ -209,9 +218,23 @@ while [ "$attempt" -lt 4 ]; do
|
||||
started=no
|
||||
# dumpsys only while the service starts: every `uiautomator dump` spawns a JVM on the device and
|
||||
# competes for exactly the CPU that the five-second deadline is measured against.
|
||||
for _ in $(seq 1 12); do
|
||||
if fgs_started; then started=yes; break; fi
|
||||
sleep 3
|
||||
for tap_try in 1 2 3; do
|
||||
for _ in $(seq 1 12); do
|
||||
if fgs_started; then started=yes; break; fi
|
||||
sleep 3
|
||||
done
|
||||
if [ "$started" = yes ]; then break; fi
|
||||
printf ' tap %s did not start the service' "$tap_try"
|
||||
# On a slowed emulator the window can still be settling even though the accessibility tree
|
||||
# already lists the button, so the tap goes nowhere. Tapping again is far cheaper than the
|
||||
# cold restart the outer loop would otherwise resort to.
|
||||
if start="$(wait_for 'Start scan' 60)"; then
|
||||
printf ' - tapping again\n'
|
||||
"${adb[@]}" shell input tap $start
|
||||
else
|
||||
printf ' - the intro is gone, so restarting instead\n'
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$started" = yes ]; then
|
||||
printf ' attempt %s: the service started (notification posted)\n' "$attempt"
|
||||
|
||||
Reference in New Issue
Block a user