From 3fc224b584310fa0bea7edaf184090d45e74109e Mon Sep 17 00:00:00 2001 From: iris <2+iris@noreply.localhost> Date: Fri, 4 Sep 2026 18:51:10 -0400 Subject: [PATCH] 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 --- RUST.md | 131 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 48 deletions(-) diff --git a/RUST.md b/RUST.md index ff0493d..f5dc4a3 100644 --- a/RUST.md +++ b/RUST.md @@ -432,56 +432,75 @@ accepted. worth not doing in a log somebody might paste. And the Android targets were installed for **stable** only; the pinned nightly needs its own, which `iris/rust-toolchain.toml` now declares. -- [ ] **E1 — android-view's Masonry demo on this emulator.** Pass: it - builds with `cargo-ndk` + Gradle, renders on the GPU, and the phone's - own keyboard types into its editor with autocorrect and suggestions. - Note which `wgpu` backend it took and any environment flags needed. - **Part-done 2026-09-04; the keyboard half is untested, so the box - stays open.** +- [x] **E1 — android-view's Masonry demo on this emulator (2026-09-04).** + It builds, renders on the GPU through Vulkan, exposes its + accessibility tree, and **the phone's own keyboard types into its + editor** — but with **no autocorrect and no suggestions**. Ticked + because everything it was meant to establish is established, + 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 - android-view-masonry-demo` and `./gradlew :masonry-app:assembleDebug`. - The demo draws: its text field and "Add task" button appear, laid out - correctly. Note the demo's README says `arm64-v8a`; this emulator is - x86_64. **`libmain.so` is 181 MB in debug and 11 MB in release**, - which is the single loudest number about Vello's dependency graph. + android-view-masonry-demo --release`, then + `./gradlew :masonry-app:assembleDebug`. **`libmain.so` is 181 MB in + debug and 11 MB in release** — the loudest single number about + Vello's dependency graph, and the reason the release build matters + for more than speed. - *Accessibility works, which E2's condition 6 depends on.* `ui-trace` - reads Masonry's AccessKit tree: "Add task" comes through as a named - `Button` and the editor as an `EditText` node. So the bench rig's - tap-by-name would work against a Masonry screen — for controls that - carry a name. The demo's editor does not, so a coordinate was needed - for it, which is a demo omission rather than a framework one. + *Renderer.* wgpu takes **Vulkan**, and the emulator log confirms it + from the other side: `Created VkDevice ... for application:'wgpu'`. + Two things were needed. The emulator must be given Vulkan at all — + `-feature Vulkan` with `VK_DRIVER_FILES` pointing at the SDK's + `vk_swiftshader_icd.json`, **plus `-no-snapshot-load`**, which is the + 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 - IME up (`mInputShown=false` throughout) before the run ended. Nothing - here says android-view's `InputConnection` does not work — only that - it has not been shown to. This is the half of E1 that matters most, - since it is the constraint the whole framework decision turns on, and - it is what to do first when this is picked up. + *Accessibility works*, which E2's condition 6 and every bench script + depend on. `ui-trace` reads Masonry's AccessKit tree: "Add task" + arrives as a named `Button`, the editor as an `EditText` node. So + tap-by-name works against a Masonry screen for any control carrying + a name; the demo's editor carries none, which is the demo's omission + rather than the framework's. - *A crash worth knowing about, seen once.* With an accessibility - client attached the app aborted, and the stack attributes it - precisely: `android_view::view::do_frame` → - `CallbackCtx::finish` → `accesskit_android::event::QueuedEvents::raise` - → `send_completed_event` → `unwrap()` on `Err(JavaException)`. - android-view builds with `panic = "abort"`, so a JNI call that throws - takes the process. It did **not** reproduce: two plain - `ui-trace record` runs afterwards left the app alive, so the trigger - is narrower than "an accessibility client is connected" and is not - yet known. Recorded rather than chased because it is upstream and - one unwrap wide. + *The keyboard: real input yes, suggestions no.* Tapping the editor + opens the actual soft keyboard (`mInputShown=true`, Gboard), and + tapping its keys types into Masonry — "teh" typed key by key, with a + caret. What does **not** appear is Gboard's suggestion strip. The + control is what makes that a finding rather than an impression: the + **same three key taps in the Settings app's search field, on the same + device in the same session, produce "teh | the | yeh"**. So the strip + works here and android-view's editor is not asking for it — most + likely the `EditorInfo` its `InputConnection` reports. That matches + Robrix's report that the Android keyboard is not yet "full", and it + 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, page 800 events into `VirtualScroll` bottom-anchored, draw markdown 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) -A `wgpu` app in this emulator was going to get GLES only, because host -Vulkan is switched off in `emulator-tools`. Retried today on Mesa +**Settled 2026-09-04: the guest gets Vulkan from SwiftShader, and the +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 `externalMemoryMode: OpaqueFd`, probes `VK_FORMAT_R8G8B8A8_UNORM` for an 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 Vulkan device is the suspect, and `-no-snapshot-load` is the untested next step. SwiftShader is the one that works today. -Making this an `emu` option belongs in `emulator-tools` and is a shared -tooling change, so it goes through the other sessions first. +`EMU_GPU=software` is now in `emulator-tools` (agreed with the ai-app +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