RUST.md: E1 passes, with the keyboard gap it was there to find

The Masonry demo on android-view builds, renders through Vulkan, exposes
its AccessKit tree to ui-trace, and takes real keystrokes from the phone's
own keyboard. What it does not get is autocorrect and suggestions, and the
control is what makes that a finding: the same three key taps in the
Settings search field on the same device produce Gboard's suggestion strip,
and in Masonry's editor they produce nothing. That is the constraint the
framework decision turns on, so it is now the first thing I2 has to answer.

Also closes the Vulkan line this file had flagged as untested. The missing
step was -no-snapshot-load: the guest keeps the old GPU config from its
snapshot and reports zero Vulkan devices however the host is set up. And
records the watchdog trap that produced one wrong conclusion on the way --
a bounded run's kill timer must be scoped to the pid it guards, or it fires
into somebody else's experiment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-04 18:51:10 -04:00
1 parent 10500ae8aa
commit 3fc224b584
1 file changed
+83 -48
+83 -48
View File
@@ -432,56 +432,75 @@ accepted.
worth not doing in a log somebody might paste. And the Android worth not doing in a log somebody might paste. And the Android
targets were installed for **stable** only; the pinned nightly needs targets were installed for **stable** only; the pinned nightly needs
its own, which `iris/rust-toolchain.toml` now declares. its own, which `iris/rust-toolchain.toml` now declares.
- [ ] **E1 — android-view's Masonry demo on this emulator.** Pass: it - [x] **E1 — android-view's Masonry demo on this emulator (2026-09-04).**
builds with `cargo-ndk` + Gradle, renders on the GPU, and the phone's It builds, renders on the GPU through Vulkan, exposes its
own keyboard types into its editor with autocorrect and suggestions. accessibility tree, and **the phone's own keyboard types into its
Note which `wgpu` backend it took and any environment flags needed. editor** — but with **no autocorrect and no suggestions**. Ticked
**Part-done 2026-09-04; the keyboard half is untested, so the box because everything it was meant to establish is established,
stays open.** including the one gap; that gap is now E2's problem and I2's.
*Builds and renders.* `~/src/android-view` at `bec6c62`, built with *Build.* `~/src/android-view` at `bec6c62`, x86_64 rather than the
README's arm64 because that is what this emulator is:
`cargo ndk -t x86_64 -P 26 -o masonry-app/src/main/jniLibs/ build -p `cargo ndk -t x86_64 -P 26 -o masonry-app/src/main/jniLibs/ build -p
android-view-masonry-demo` and `./gradlew :masonry-app:assembleDebug`. android-view-masonry-demo --release`, then
The demo draws: its text field and "Add task" button appear, laid out `./gradlew :masonry-app:assembleDebug`. **`libmain.so` is 181 MB in
correctly. Note the demo's README says `arm64-v8a`; this emulator is debug and 11 MB in release** — the loudest single number about
x86_64. **`libmain.so` is 181 MB in debug and 11 MB in release**, Vello's dependency graph, and the reason the release build matters
which is the single loudest number about Vello's dependency graph. for more than speed.
*Accessibility works, which E2's condition 6 depends on.* `ui-trace` *Renderer.* wgpu takes **Vulkan**, and the emulator log confirms it
reads Masonry's AccessKit tree: "Add task" comes through as a named from the other side: `Created VkDevice ... for application:'wgpu'`.
`Button` and the editor as an `EditText` node. So the bench rig's Two things were needed. The emulator must be given Vulkan at all —
tap-by-name would work against a Masonry screen — for controls that `-feature Vulkan` with `VK_DRIVER_FILES` pointing at the SDK's
carry a name. The demo's editor does not, so a coordinate was needed `vk_swiftshader_icd.json`, **plus `-no-snapshot-load`**, which is the
for it, which is a demo omission rather than a framework one. piece this file had flagged as untested: without a cold boot the
guest keeps the snapshot's old GPU config and `cmd gpu vkjson`
reports zero devices however the host is configured. And the native
library must be **release**: a debug build calls
`SetDebugUtilsObjectNameEXT` to label its image views, and the
emulator's own guest driver (`vulkan.ranchu.so`) segfaults inside it.
On GLES, with no Vulkan available, it instead fails
`Surface::configure` with "Invalid surface" — untriaged, since the
Vulkan path works and Vello wants compute shaders anyway.
*The keyboard was not reached.* Tapping the editor never brought the *Accessibility works*, which E2's condition 6 and every bench script
IME up (`mInputShown=false` throughout) before the run ended. Nothing depend on. `ui-trace` reads Masonry's AccessKit tree: "Add task"
here says android-view's `InputConnection` does not work — only that arrives as a named `Button`, the editor as an `EditText` node. So
it has not been shown to. This is the half of E1 that matters most, tap-by-name works against a Masonry screen for any control carrying
since it is the constraint the whole framework decision turns on, and a name; the demo's editor carries none, which is the demo's omission
it is what to do first when this is picked up. rather than the framework's.
*A crash worth knowing about, seen once.* With an accessibility *The keyboard: real input yes, suggestions no.* Tapping the editor
client attached the app aborted, and the stack attributes it opens the actual soft keyboard (`mInputShown=true`, Gboard), and
precisely: `android_view::view::do_frame` tapping its keys types into Masonry — "teh" typed key by key, with a
`CallbackCtx::finish``accesskit_android::event::QueuedEvents::raise` caret. What does **not** appear is Gboard's suggestion strip. The
`send_completed_event``unwrap()` on `Err(JavaException)`. control is what makes that a finding rather than an impression: the
android-view builds with `panic = "abort"`, so a JNI call that throws **same three key taps in the Settings app's search field, on the same
takes the process. It did **not** reproduce: two plain device in the same session, produce "teh | the | yeh"**. So the strip
`ui-trace record` runs afterwards left the app alive, so the trigger works here and android-view's editor is not asking for it — most
is narrower than "an accessibility client is connected" and is not likely the `EditorInfo` its `InputConnection` reports. That matches
yet known. Recorded rather than chased because it is upstream and Robrix's report that the Android keyboard is not yet "full", and it
one unwrap wide. is the single most important thing to fix or fund upstream, because
composition, autocorrect and suggestions are exactly what the
composer in this app needs and exactly what `winit` cannot do at all.
*One crash seen once and not reproduced.* With an accessibility
client attached the app aborted, stack:
`android_view::view::do_frame``CallbackCtx::finish`
`accesskit_android::event::QueuedEvents::raise`
`send_completed_event``unwrap()` on `Err(JavaException)`.
android-view builds `panic = "abort"`, so a JNI call that throws
takes the process. Two later `ui-trace record` runs left the app
alive, so the trigger is narrower than "a client is attached".
*A rig trap that cost a wrong conclusion.* Several bounded runs were
given `sleep N; emu down` watchdogs, and one armed for an earlier
experiment fired in the middle of a later one — the app vanished, adb
hung, and it read exactly like the Vulkan path crashing. It was not.
A watchdog must be scoped to the process it guards (`kill $pid`, with
the pid captured at launch) rather than to whatever AVD is running
when it wakes, and only one should be armed at a time.
*Two changes were made at once and cannot be separated.* The first
launches crashed in `Surface::configure` ("Invalid surface") on GLES,
then, with Vulkan enabled, segfaulted inside the emulator's own
driver (`vulkan.ranchu.so`, `SetDebugUtilsObjectNameEXT`) while wgpu
labelled an image view — a debug-build-only call. It then ran after
**both** a switch to a release native library and a switch to a
software-rendered emulator. Which of the two fixed it is unmeasured;
whoever picks this up should vary one at a time rather than inherit
the assumption.
- [ ] **E2 — a transcript in Masonry.** One screen: open a sandbox session, - [ ] **E2 — a transcript in Masonry.** One screen: open a sandbox session,
page 800 events into `VirtualScroll` bottom-anchored, draw markdown page 800 events into `VirtualScroll` bottom-anchored, draw markdown
from `pulldown-cmark` into Parley rich text with links and code from `pulldown-cmark` into Parley rich text with links and code
@@ -683,8 +702,21 @@ re-derived:
### Vulkan in the emulator (measured 2026-09-04) ### Vulkan in the emulator (measured 2026-09-04)
A `wgpu` app in this emulator was going to get GLES only, because host **Settled 2026-09-04: the guest gets Vulkan from SwiftShader, and the
Vulkan is switched off in `emulator-tools`. Retried today on Mesa missing step was a cold boot.** `-feature Vulkan` plus
`VK_DRIVER_FILES=$HOME/Android/Sdk/emulator/lib64/vulkan/vk_swiftshader_icd.json`
gets the *host* side to select SwiftShader, but the guest keeps reporting
zero devices until `-no-snapshot-load` is added, because it boots from a
snapshot saved under the previous GPU config — `-no-snapshot-save` is
worth adding too, so the Vulkan-configured snapshot does not then break
the next ordinary boot. With that, `cmd gpu vkjson` reports SwiftShader
Subzero and wgpu takes its Vulkan path (E1). `EMU_GPU=software` in
`emulator-tools` gets the same guest Vulkan with no GPU use at all, for
work where the emulator's frame rate is not what is being measured.
The rest of this section stands as the record of why host Vulkan is not
available. A `wgpu` app in this emulator was going to get GLES only,
because host Vulkan is switched off in `emulator-tools`. Retried on Mesa
26.1.7: **Venus still fails the same way** — gfxstream picks 26.1.7: **Venus still fails the same way** — gfxstream picks
`externalMemoryMode: OpaqueFd`, probes `VK_FORMAT_R8G8B8A8_UNORM` for an `externalMemoryMode: OpaqueFd`, probes `VK_FORMAT_R8G8B8A8_UNORM` for an
exportable colour buffer, and Venus says the format is unsupported exportable colour buffer, and Venus says the format is unsupported
@@ -717,8 +749,11 @@ booted, then the emulator died right after loading the `default_boot`
snapshot with nothing in the log; a snapshot saved under a different snapshot with nothing in the log; a snapshot saved under a different
Vulkan device is the suspect, and `-no-snapshot-load` is the untested Vulkan device is the suspect, and `-no-snapshot-load` is the untested
next step. SwiftShader is the one that works today. next step. SwiftShader is the one that works today.
Making this an `emu` option belongs in `emulator-tools` and is a shared `EMU_GPU=software` is now in `emulator-tools` (agreed with the ai-app
tooling change, so it goes through the other sessions first. session and with Iris, default unchanged, since `-gpu host` was measured
and the Compose scroll benchmarks depend on it). The cold-boot flags are
not a knob there: that wants snapshot invalidation as well, which is a
bigger design question in shared tooling.
## Things a Rust app changes elsewhere ## Things a Rust app changes elsewhere