Headed mode + iOS-from-Windows (TCP daemon + MJPEG viewer)#3
Merged
Conversation
…aded CLI + docs
D3 — Screen stream RPC (iphone_harness + android_harness):
- Daemon class: _stream_task/_stream_frame/_stream_fps/_stream_quality/_stream_max_dim state
- _m_screen_stream_start(fps, quality, max_dim): spawn capture loop, idempotent
- _m_screen_stream_frame(): pull latest JPEG (base64) — single-consumer
- _m_screen_stream_stop(): cancel loop, clear buffer
- PIL lazy-imported (already a project dep via pillow>=10)
- Frame loop logs+continues on transient errors; doesn't kill stream
- Helpers: screen_stream_start/frame/stop wrappers (drop conn first to avoid stale cache)
- Mock daemons: synthetic 67-byte JPEG stub so tests don't need PIL
D4 — HTTP MJPEG viewer sidecar (mobile_use/viewer/):
- server.py:ViewerServer(platform, port, fps, quality, max_dim)
- Routes: GET / (embedded HTML), /stream (multipart/x-mixed-replace),
/still (single JPEG), /healthz (JSON status)
- Threaded HTTP server (daemon threads) so /healthz doesn't block behind /stream
- Lifecycle: start() spawns thread + tells daemon to start capture loop;
stop() shuts server down, releases port, stops daemon capture
- Stdlib only — no new pip deps
D5 — CLI --headed / --headless flag wiring:
- main(): parses flags, sets MOBILE_USE_HEADED env (with try/finally restore
so in-process tests don't leak state to siblings)
- _maybe_start_viewer(platform): used by _run_ios + _run_android + agent_loop;
opens browser via webbrowser.open (silent fallback if unavailable); soft
warning + None on failure (viewer never blocks the -c script)
- HELP text: 'iOS FROM WINDOWS / LINUX' section; --headed/--headless documented
D6 — End-to-end smoke tests (tests/test_e2e_headed.py):
- e2e_headed_ios: mock daemon → ViewerServer → /stream returns multipart JPEG
- e2e_headed_android: parity
- e2e_remote_iphone: TCP daemon endpoint + client-only mode + RPC works
- e2e_stream_loop_progresses: frame_no strictly increasing across polls
D7 — Docs (SETUP.md + README.md):
- SETUP.md: 'Part A* — iOS from Windows / Linux (remote Mac bridge)' section
with Mac-side setup, daemon TCP launch, Windows/Linux client connect,
SSH tunnel pattern, security caveat, troubleshooting checklist
- README.md: 'Headed mode' section (--headed launches MJPEG viewer in
browser); 'iOS from Windows / Linux' quick-start pointing at SETUP.md
Tests: 38 new (12 screen_stream + 12 viewer_mjpeg + 7 cli_headed + 4 e2e + 3 sanity);
full suite: 572 passed, 1 pre-existing Linux test failure (008-linux-device-support).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
IPH_BIND/IPH_CONNECTandANH_BIND/ANH_CONNECTaccepttcp://host:port.--remote-daemon tcp://mac.local:5550). Skips local Xcode / WDA preflight when client-only.--headed/--headlessCLI flags onagent,--ios -c,--android -c. Headed launches the viewer + opens browser; headless is the default.Replaces #1
PR #1 was 30 commits ahead of main after the Linux squash-merge (#2). This branch is the same headed-mode + Windows-iOS feature set re-cherry-picked onto the post-#2 main, with the cli.py conflict resolved by keeping both the new env-preflight (from goal/010 D2) and the viewer-lifecycle wrapping. Net: 16 files, ~1750 insertions.
Test plan
python3 -m pytest tests/ -q→ 591 passed locally on macOSmobile-use --android -c 'print(active_app())' --headedopens browser viewer--remote-daemon tcp://mac.local:5550