Device side (bridge)¶
The Python half of the device side is hardware-independent and tested without a
phone; the JNI transport (phase B3) and the Kotlin Compose renderer (phase B4)
are implemented in android-host/ and verified on a real arm64 device.
Style → Compose translator¶
to_compose(style)(tempestroid.renderers.compose) — a serializableStyle → Composespec; the secondStyletranslator (pairs withStyle → Qt). Both are pinned by the conformance suite (phase D).
Serialization¶
serialize_node/serialize_patch— lower the IR/patches to JSON-able dicts: handlers become path tokens,Stylebecomes the Compose spec.
Wire protocol¶
Messages cross a single marshalling boundary (the JNI bridge on the device, an in-memory channel in tests).
MountMessage—mountcarries the full serialized tree.PatchMessage—patchcarries an incremental patch list.EventMessage—eventcarries a device→Python callback addressed by a handler token.
A handler token identifies a handler by its node's path in the tree plus the
prop name (e.g. "0/1:on_click"). It is path-based (not key-based) so the emit
side (serializer) and the dispatch side (registry) compute identical tokens from
the same tree.
Transport and device app¶
DeviceApp+Bridge/LoopbackBridge— wire anAppto a device transport; the device-side analogue ofrun_qt. Events come back by handler token, are validated byparse_event, and trigger coalesced patches.JniBridge+run_device— the real on-device transport (phase B3):JniBridgeships messages to Kotlin via the native_tempest_hostmodule;run_device(state, view)boots aDeviceAppon a fresh asyncio loop and marshals incoming events back onto it. Imports cleanly off-device (the native module is loaded lazily), so the framework still develops/tests on the desktop.
Dev server — LAN code-push (phase B5)¶
The Expo-style on-device inner loop: edit on the dev machine, hot-restart on the
phone without rebuilding the APK (tempest serve <app>).
DevServer— serves the app source (/version,/app) and relays device logs (/log) over HTTP.run_dev_client— the device poll loop: fetch on change → re-exec source → hot-restart theDeviceApp.serve_device(url)— device entry point wiring the realJniBridge+ the native sink + anurllibfetch intorun_dev_client.render_qr(url)— ASCII QR for pairing (falls back to the plain URL).
Native capabilities (phase B6)¶
Device-native features driven from Python as {"kind": "native"} commands the
Kotlin host routes to capability modules.
notify(title, body="")— post a system notification from a handler. The extension pattern (native_commandenvelope + a host module router) is in place for further capabilities (camera, sensors, …).