# Agent container ↔ host emulator setup How the testing loop between the JTube TV agent container and the host emulator works, and what needs to exist again after a rebuild. ## Topology - **Emulator**: runs on the **host** (`/opt/android-sdk`, launched by `scripts/start-emulator.sh`). **Headless is the default**; set `JTUBE_EMU_MODE=windowed` if you want the Qt window (e.g. for desktop interaction testing). View it via scrcpy either way. - **Only the host can start the emulator** (by design — no SSH from the container to the host, no SDK/KVM inside the container). If the agent finds no emulator, it should tell the user to run `./scripts/start-emulator.sh` on the host rather than try to work around it. Reachability check: `adb connect rutherford:5556` then `adb -s rutherford:5556 shell getprop sys.boot_completed` → `1`. - **Agent container**: image `agent-container:latest`, container name pattern `ac--`, launched with **`--network host`** — it shares the host's network namespace. This is load-bearing: see below. ## Why host networking makes adb trivial With `--network host`, the container's `localhost` *is* the host's localhost. So inside the container: - `adb connect 127.0.0.1:5556` → hits the host's socat bridge → emulator adbd. - The adb **server** running on 127.0.0.1:5037 is also shared with the host, so the container inherits whatever authorization the host adb server has. No separate RSA handshake is needed. (Caveat: whoever's adb server grabs port 5037 first owns it; all clients share it.) ## What must be (re)installed after a container rebuild 1. **`android-tools` in the container** (provides `adb`; installed into the running container with `sudo pacman -S --noconfirm android-tools`, but that is ephemeral). To make rebuilds self-sufficient, bake it into the `agent-container` image at build time. 2. **Nothing else is needed for adb**: key handling is inherited from the shared host adb server (see above). If the container is ever switched to bridge networking, use `adb connect rutherford:5556` — remote keys are handled by the emulator's `ADB_VENDOR_KEYS` (next section). ## Emulator-side facts (host) - Ports: console `5600`, adbd `5601` (`-port 5600` ⇒ console+1), LAN bridge `socat TCP-LISTEN:5556 → 127.0.0.1:5601` (0.0.0.0, so remote machines can `adb connect rutherford:5556`). - Remote key whitelisting: the TV system image is a user build — adb `push`/`shell` writes to `/data/misc/adb/adb_keys` are blocked. The script therefore builds `/tmp/jtube-adbkeys-combined` (host key + every `/tmp/jtube-adbkeys/*.pub`) and launches the emulator with `ADB_VENDOR_KEYS` pointing at it. To trust a new client: put its `~/.android/adbkey.pub` into `/tmp/jtube-adbkeys/` **before** launching. - Logs: `/tmp/jtube-emu.log` (QEMU), `/tmp/jtube-socat.log` (bridge), `/tmp/jtube-adbkeys-combined` (rebuilt each launch). - Viewing: `scrcpy -s emulator-5600` on the host, or from any LAN machine: `adb connect rutherford:5556 && scrcpy -s 127.0.0.1:5556`. ## Known quirks - Emulator Qt toolbar (back/home buttons) is a detached XWayland window that misbehaves on Hyprland — drive the emulator via scrcpy or adb instead. - The TV image is a user build: no `adb root`. - Under the Android TV AVD, keyboard input in the Qt window works, but the reliable inputs are scrcpy (`b` = back, `h` = home) or `adb shell input keyevent`.