Commit Graph
4 Commits
Author SHA1 Message Date
Kelvin Amoaba be3d9b7e86 fix(emulator): type and paste into the Android emulator pane (#37139)
The pane's keyboard only sent serve-sim HID frames over the iOS WebSocket.
Android sessions have no serve-sim socket, so every key was dropped and every
paste failed with "device is not ready".

Android panes now send typed characters, paste and editing keys over a new
emulator:scrcpyKeyboard IPC beside emulator:scrcpyTouch, keyed by the streamed
serial. Main writes them straight to the live scrcpy control socket (text
injection, and keycodes with SHIFT_LEFT held for Shift), so keys keep their
order with touches. iOS keeps the HID path.
2026-11-01 20:21:15 +00:00
Carlos MoránandKelvin Amoaba 7ed518562c fix(emulator): send Android input through the scrcpy control socket (#36530)
* fix(emulator): restore scrcpy control encoders and track the video size

Bring back the scrcpy v2.4 control-message encoders removed as unwired
in #13528 (touch, keycode, text), re-checked against control_msg.c and
the server's ControlMessageReader: generic-finger pointer id, the
official u16 pressure fixed point, and text split into <=300-byte
messages on code point boundaries.

The server drops touch events whose screen size differs from the
current video size. v2.4 reports the size once in its codec meta; after
a rotation the new size is only in the next SPS, so the session reads it
from every config packet. ScrcpyStreamSession.sendControl() returns,
the control socket disables Nagle, and the registry keeps the live
session's control target next to its video.

* fix(emulator): send Android input through the scrcpy control socket

Android pane input ran one `adb shell input` process per action (~150 ms
each on a USB phone) and replayed drags only on pointer-up as a fixed
300 ms straight swipe between the endpoints.

Pane pointer phases now go to main as they happen over a new
fire-and-forget `emulator:scrcpyTouch` IPC and are written to the live
session's scrcpy control socket, so drags and scrolls track the pointer.
CLI and agent tap, gesture, type and button use the same socket whenever
a stream is live; `adb shell input` remains the fallback without one.
Input routing and the `wm size` cache the fallback needs move into
AndroidDeviceInput. iOS is unchanged.

* test(emulator): keep the adb fallback test from leaking a failing sendControl

* docs(emulator): explain why pane touches have no per-phase adb fallback

* fix(emulator): keep iOS touch callback stable across interact changes

sendTouch depended on canInteract only for the scrcpy branch, but the new
dep also rebuilt it for iOS, so a canInteract flip mid-drag ran the frame's
cleanup, ended the live touch early and replayed the drag over RPC. The
frame already gates touch begins on canInteract.

* fix(emulator): narrow scrcpy touch payloads without a type assertion

The changed-code casting gate forbids `as`; use `in` narrowing like
the other IPC payload guards.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-01 04:58:23 +00:00
Neil 401664298f fix(preload): make a dropped bridge key a compile error
The split silently dropped jira.searchUsers and
runtimeEnvironments.retryControlConnection. Neither failed typecheck: the bridge
modules carried no satisfies annotation and the composed api object was
unannotated, so a missing key was only a runtime TypeError in the renderer.

Annotates each module against PreloadApi, the type window.api is already
declared as, so the contract supplies the shape rather than a parallel copy.
Deleting jira.searchUsers now fails with TS2741 naming the key.

Turning this on surfaced 106 places where a bridge locally annotated
Promise<unknown> or unknown[] over a contract that declares concrete types --
the bridge was erasing types the renderer relied on. Those annotations are gone.

Also exposes app.awaitBeforeUnloadCheckpoint, which was declared and called but
never actually on the bridge, so the lazy-chunk recovery reload optional-chained
to a no-op and navigated without joining the checkpoint. The missing key was
caught by the new annotation rather than by hand.
2026-09-01 18:24:49 -07:00
Neil d1abe28471 refactor(preload): split bridge API modules
(cherry picked from commit b77e31873b)
2026-09-01 00:57:54 -07:00