Skip to content

Remote: scrcpy control channel + remote/detection improvements#72

Merged
bryanroscoe merged 7 commits into
mainfrom
feat/remote-control-channel
Jun 15, 2026
Merged

Remote: scrcpy control channel + remote/detection improvements#72
bryanroscoe merged 7 commits into
mainfrom
feat/remote-control-channel

Conversation

@bryanroscoe

@bryanroscoe bryanroscoe commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Replaces the Remote tab's transport with a persistent scrcpy-server control socket — key presses drop from ~690 ms to network RTT — plus several remote and device-detection fixes found while testing on a live Shield.

Remote control channel

  • Persistent scrcpy-server control socket instead of one adb shell input per press (~690 ms → ~ms). Lazy per-device session, full UTF-8 typing, hold-to-repeat D-pad, live ● instant / ○ compatible transport cue, transparent fallback to input when the channel can't start.
  • Force compatible mode toggle — escape hatch to skip the channel and use the universal input path (persisted).

Remote buttons

  • Added Recents (KEYCODE_APP_SWITCH).
  • Added ⚙ Settings — opens Settings via am start -a android.settings.SETTINGS (the Shield gear/hamburger button is an intent launch; injected KEYCODE_SETTINGS/MENU no-op).

Device detection

  • Wireless-debugging serials (Android 11+ mDNS ._adb-tls-connect._tcp) now classify as Network, not USB.
  • Devices are typed by the tv build characteristic, not brand alone — Google Pixel phones are no longer mislabeled as Google TV.

Validated: clippy -D warnings clean, 168 unit tests + 1 live test, svelte-check 0/0, vite build green.

The Remote tab's transport is now a persistent scrcpy-server control
socket instead of one `adb shell input ...` (and one JVM cold-start on
the TV) per key press. Verified on hardware end-to-end.

Backend (adb/remote_input.rs):
- RemoteInputSession per serial: push the bundled scrcpy-server v3.1
  jar (Apache-2.0, pinned SHA-256), adb forward a fresh local port to
  localabstract:scrcpy_<scid>, spawn the server resident via
  app_process (control-only mode), connect and complete the dummy-byte
  handshake. Connect retry covers the handshake read — adb forward
  accepts TCP before the device-side socket listens, so only a 0x00
  read proves the server is up.
- INJECT_KEYCODE / INJECT_TEXT encoders, byte-exact tested. UTF-8 text
  now works (the input-text fallback remains ASCII-only).
- Driver grows spawn() for resident children, with stdin pinned to
  /dev/null — app_process aborts at startup if the adb client's stdin
  is fully closed (found the hard way).
- Session registry on AppState; slow start runs outside the lock.
  Teardown: socket close (server self-exits), narrow pkill matching
  our jar name only, child kill, forward removal. disconnect_device
  drops the session.
- Live integration test (ignored in CI): full roundtrip against a real
  device incl. SLEEP/WAKEUP injection verified via dumpsys and a
  no-leftover-process check after close.

Commands: send_key/send_text try the channel first and fall back
transparently to `input` if it can't start; a failed channel send
drops the session so the next press retries fresh. Results carry
which transport served them.

Remote tab: hold-to-repeat D-pad (pointer events; channel only — the
shell queue would lag the finger), near-immediate typing flush on the
channel (250ms batching kept for shell), live "instant / compatible"
transport cue.

Found by the live test, fixed here: adb forward calls without -s fail
with "more than one device" the moment a second device is connected.
@bryanroscoe bryanroscoe force-pushed the feat/remote-control-channel branch from 223c552 to f176f29 Compare June 15, 2026 03:39
@bryanroscoe bryanroscoe changed the title Remote: scrcpy control channel — key presses drop from ~690 ms to ~ms Remote: scrcpy control channel + remote/detection improvements Jun 15, 2026
@bryanroscoe bryanroscoe merged commit 0701b39 into main Jun 15, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant