RUST.md, IRIS.md, IRIS_TODO.md, DECISIONS.md: record I5's Android integration and measurements

I5's transcript screen now runs on-device against a real ai-server on
iris-android-app's new transcript-screen feature (extends I2's shell
rather than a third one), with real scrolling, real touch-drag panning
and tap-by-name accessibility all confirmed by screenshot/log evidence.
I4's own emulator-side check (tap-by-name on the tabs demo) closed the
same session, so its box ticks [x] now.

Still [~], not [x]: the render-time number RUST.md's recommendation
wants for iris couldn't be produced this pass, for a precise and
recorded reason rather than a vague one -- dumpsys gfxinfo cannot see a
SurfaceView's own GPU-drawn frames at all (0 frames reported across a
gesture loop that visibly scrolled), and a SurfaceFlinger --latency
fallback gave no per-frame history either on this Android version. The
Compose side of the same loop did produce a real number under identical
conditions (8.96% janky, 99th percentile 150ms), so this is now a
one-sided number rather than a missing one on both sides.

Also found and recorded: the AVD's saved snapshot carries a GPU config
across restarts, so switching between the documented Vulkan boot
recipes needs a cold boot (clearing snapshots/) that the emu wrapper
does not force -- cost three different-looking crashes before the
pattern was the snapshot, not the code.

DECISIONS.md's DEFERRED item is updated with the numbers Iris needs to
weigh the iris-vs-Masonry call; the call itself stays hers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Fable 5.1 committed 2026-09-05 14:09:04 -04:00
1 parent bf5087a598
commit d17040b601
4 files changed
+388 -85

No files matched your search

+30
View File
@@ -8,6 +8,36 @@ capability that moved. Small and trivial changes do not go here.
An entry gives the date, what changed, why, and a short before/after where
it helps judge the change without the session that made it. Newest first.
## 2026-09-05: `Tasks::redraw_handle` (RUST.md's I5 Android integration)
New public method on `iris::task::Tasks`, `redraw_handle(&self) ->
Arc<dyn RequestRedraw>`. Why: a caller running its own long-lived loop
*inside* one spawned task (a live SSE follow, the Android transcript
client's `select_session`) has no other way to ask for a frame after each
`TaskCtx::update` -- `Tasks::spawn`'s own wrapper only requests one, after
the whole async closure finishes, which fits a single request-then-update
but not a stream that needs to be seen redrawing after *each* event. This
is the same gap `iris/desktop-app`'s module doc names for why it uses
winit's `Proxy<AppEvent>` instead of `Tasks` -- android-view has no
`Proxy`, so this is what closes it there.
**A real bug this uncovered, not a hypothetical**: calling the returned
handle's `request_redraw()` from the background thread crashed the process
(`SIGABRT`, `Result::unwrap() on an Err value: JavaException`) the first
time an Android transcript fetch called it a second time. `android/render.rs`'s
`AndroidRedrawHandle` was already attaching the calling thread to the JVM
correctly, but its `request_redraw` called `View::post_frame_callback`,
whose Java side calls `Choreographer.getInstance()` -- which throws unless
the *calling* thread already has a `Looper`, and a tokio worker thread,
even freshly JNI-attached, has none. Fixed by routing through
`View::post_delayed(0)` instead (Android's own thread-safe "queue work onto
this View's UI thread" primitive, needing no caller-side `Looper`), landing
on a new `IrisViewPeer::delayed_callback` override that drains tasks and
renders -- same body as `do_frame`, on the UI thread where
`post_frame_callback` is safe again. Any future caller of `redraw_handle()`
from a background thread gets this for free; nothing about the fix is
specific to the transcript screen.
## 2026-09-05: `transcript_ui::build_tree` (RUST.md's E4)
`transcript_ui::build` claimed the whole window (`ui_state.set_root(tree)`)