Repository navigation
fix(android): bound the dumpsys reads behind dialog and foreground checks - #3936
Conversation
…ecks The blocking-dialog and foreground observations ran `adb shell dumpsys` with no timeout before and after every Android interaction, so a hung read waited for the client envelope and reset the daemon. Each dump read now carries a 10 s bound. A timed-out read counts as unanswered, the same `unknown` a read that printed nothing produces, so a slow probe still never refuses the command; the reader then skips its remaining variants, so one observation costs at most one bound. This unblocks the longpress envelope ledger in callstack#3326, which cannot prove an envelope while these reads are unbounded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This is ready at defd554: the dumpsys reads behind the dialog and foreground checks are now bounded, and a timeout maps to an unanswered result as intended. All 11 checks pass at this head, and there are no conflicts. I read the code and did not run the tests locally; the emulator run and its exec trace come from the PR body only. Not blocking, and you can take or leave these: |
A per-read bound still let one observation walk every dumpsys variant that answered without a focus line, each spending up to its own 10 s. All reads of one observation now draw on a single 10 s budget, so an observation costs at most one bound however many variants it reads; a spent budget or a timed-out read leaves the question unanswered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks. On the three non-blocking points:
🤖 Addressed by Claude Code |
|
This PR is ready. At 8a582e7 the code looks correct to me, and the 11 checks are all green. I have no other concerns with the change since the earlier review. I did not run the tests or a device; the regression judgment comes from reading the diff, and the emulator run and exec trace come from the PR body. I also did not trace the timeout error shape of provider-backed adb executors, only the local path in exec.ts. Not blocking, and you can take or leave it: in observation.ts the dump deadline starts when the reader is created, so in |
The budget started when the reader was created, so the helper focus call that readBlockingDialog (and readAppFocus, for a shared reader) makes first spent up to 2 s of the 10 s dump budget. The deadline now starts at the first dump read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Taken in 🤖 Addressed by Claude Code |
Matches the other platform-android modules that bound a sequence of steps, instead of computing the deadline and remainder by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This PR is ready at f02edea. The change since the earlier review only moves where the deadline starts, and I found one small edge case, described below. CI is green with 11 checks and none failing, and there are no conflicts. I did not run the tests. I judged the regression from the pre-change code path and the virtual-clock mechanics. The live emulator evidence in the PR body is from 8a582e7, not f02edea, and no hung dumpsys was reproduced live. The earlier review accepted that evidence. Not blocking, and you can take or leave it: observation.ts now calls |
isExpired() and remainingMs() read the clock separately, so a millisecond rollover between them passed timeoutMs 0, which the exec layer treats as no timeout and runs the dump unbounded. The reader now reads the remaining budget once and uses it for both the check and the timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Good catch. Fixed in 🤖 Addressed by Claude Code |
* origin/main: fix(android): bound the dumpsys reads behind dialog and foreground checks (#3936) feat(android): detect Fire OS devices as Android TV targets and document Fire TV support (#3923) docs(macos): document Electron/Chromium app automation through the accessibility tree (#3932) test(capture-kit): encode solid test PNGs unfiltered to stay inside the unit budget (#3933) fix: guard bounded lifecycle and claim recovery (#3911) fix(ios): clear a long text value wherever the caret lands (#3908) fix(snapshot): stop iOS 27 floating-bar containers from covering content (#3912) ci: cache and bound the Linux desktop dependency install (#3919) fix: refuse resource operations in bounded composites (#3910) refactor(ios): decide bridge-failure scope and warning once (#3914) refactor(capture-kit): encode post-gesture stabilization baseline provenance (#3915) perf: expect the persistent session on Android snapshot-raw (#3913) test(ios): hold the fill read-count pin to the route it measures (#3909) perf(ios): admit tap text-input probes from fresh target evidence (#3881) feat(perf): time every Android command against the fixture app (#3902) chore: mark 0.21.31 as released
* origin/main: fix(android): bound the dumpsys reads behind dialog and foreground checks (#3936) feat(android): detect Fire OS devices as Android TV targets and document Fire TV support (#3923) docs(macos): document Electron/Chromium app automation through the accessibility tree (#3932) test(capture-kit): encode solid test PNGs unfiltered to stay inside the unit budget (#3933) fix: guard bounded lifecycle and claim recovery (#3911) fix(ios): clear a long text value wherever the caret lands (#3908) fix(snapshot): stop iOS 27 floating-bar containers from covering content (#3912) ci: cache and bound the Linux desktop dependency install (#3919)
* origin/main: fix(android): bound the dumpsys reads behind dialog and foreground checks (#3936) feat(android): detect Fire OS devices as Android TV targets and document Fire TV support (#3923) docs(macos): document Electron/Chromium app automation through the accessibility tree (#3932) test(capture-kit): encode solid test PNGs unfiltered to stay inside the unit budget (#3933) fix: guard bounded lifecycle and claim recovery (#3911) fix(ios): clear a long text value wherever the caret lands (#3908) fix(snapshot): stop iOS 27 floating-bar containers from covering content (#3912) ci: cache and bound the Linux desktop dependency install (#3919)
Summary
The blocking-dialog and foreground observations ran
adb shell dumpsys window …anddumpsys activity …with no timeout around every Android interaction. A hung read waited for the client envelope, which resets the daemon. Now every variant one observation reads (createDumpReader,packages/platform-android/src/observation.ts) shares one 10 s budget, counted from its first dump read.unknown/{}), like an empty dump. The command proceeds: "a failed probe has never been a refusal".AndroidObservationHost.runAdboptions gaintimeoutMs.tapandwm sizeare unchanged.3 files. This unblocks the #3326 ledger (#3937).
Validation
pnpm check:affected --run --head cc4dd4a2f: passed,exactCommit=true(basec48d27a81).defd554a9.8a582e78c(before the budget-start commit) on a Pixel 7 API 36 emulator (android-helper0.21.32-dev,AGENT_DEVICE_EXEC_TRACE=1):open --relaunch,press 'label="Network & internet"',backandlongpress 540 1200 1500passed 3 of 3 runs.timeoutMs. It settled at 4.6 s afterandroid_touch_helper_install, outside the observation reads. The trace has no args, so I could not identify it.pressbecause Clock came to the foreground after boot. It passed on rerun.dumpsyslive.🤖 Generated with Claude Code