Repository navigation
fix(android): read a child that vanished mid-read as gone - #3901
Conversation
AccessibilityNodeInfo.getChild can throw a NullPointerException from the framework's result integrity check when the child's window closes during the read, for example while an alert dialog closes after `alert accept`. The persistent helper session reported that as a capture failure, so the host force-killed the session, answered with a one-shot capture, and kept the session off for about 40 s. Treat the throw as the null that the framework answers for a vanished child. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Size Report
Startup median (7 runs, lower is better):
|
|
The PR is ready at 8e38852. The catch in Not blocking, and you can take or leave these: the fix sits in a static method that calls the final Android CI shows one failure: the lint step reports packages/platform-apple/src/snapshot-route.test.ts is over the line cap, which is the main-only cap tracked in #3890. This diff only touches one Android Java file, so it is unrelated. I ran no device and no Java tests, and I did not check which Android frames can throw here. The emulator numbers are yours. I know of no conflicts. This should merge once #3890 is resolved. |
|
* origin/main: feat(test-app): add a Bluesky-depth heavy feed screen (#3884) fix(android): read a child that vanished mid-read as gone (#3901) feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895) Prepare shared resource ownership and selection for #3325 (#3887) refactor(kernel): track held execution locks in keyed-lock (#3879) perf(ios): ask a ready runner about surface hosts before spawning probes (#3877) fix(ios): keep the bridge while a surface host only lingers (#3873) perf(ios): synthesize taps on resolved in-app back controls (#3880) fix(macos): open a running app by its own path instead of its bundle id (#3889) fix(macos): accept mixed-case bundle ids in open (#3867) fix(macos-helper): scroll SwiftUI forms whose rows are scroll-area children (#3888)
* origin/main: fix(android): read a child that vanished mid-read as gone (#3901) feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895) Prepare shared resource ownership and selection for #3325 (#3887) refactor(kernel): track held execution locks in keyed-lock (#3879) perf(ios): ask a ready runner about surface hosts before spawning probes (#3877) fix(ios): keep the bridge while a surface host only lingers (#3873) perf(ios): synthesize taps on resolved in-app back controls (#3880) fix(macos): open a running app by its own path instead of its bundle id (#3889) fix(macos): accept mixed-case bundle ids in open (#3867) fix(macos-helper): scroll SwiftUI forms whose rows are scroll-area children (#3888)
|
Applied the non-blocking notes in the follow-up #3905, because this PR is already merged. It adds a |
Summary
The Android snapshot helper can throw
NullPointerException: ... java.util.List.size() on a null object referencefrom insideAccessibilityNodeInfo.getChild(frameworkAccessibilityInteractionClient.checkFindAccessibilityNodeInfoResultIntegrity) when the child's window closes during the read. The fixture'salert accepthits it while the dialog closes. The persistent session reports a capture error, so the host force-kills the session, answers with a one-shotam instrumentcapture, and keeps the session off for about 40 s. Every capture in that window is slower.AccessibilityNodeReads.child, the single owner of child reads, now treats that throw as thenullthat the framework answers for a vanished child. 1 file changed.The new Android perf suite (#3885 stack) found this as
automation/alert-accept→android_snapshot_helper_session_fallback.Validation
Head 8e38852:
pnpm check:affected --run --head 8e3885218apassed (exactCommit). Theandroid-helperscheck is GitHub-authoritative (Android / Smoke Tests).Device: an API 35
pixel_7emulator (google_apis arm64) with the fixture Release APK. Each iteration pressesautomation-open-alert, runsalert wait, thenalert accept --debug. The NPE session fallbacks were counted from the request logs:All 60 accepts were handled in both runs.
I logged the framework stack trace with a temporary
Log.ethat is not in this commit.🤖 Generated with Claude Code