[Experimental] Wireless ADB: USB enable step + WebSocket bridge - #7
Open
andronedev wants to merge 5 commits into
Open
[Experimental] Wireless ADB: USB enable step + WebSocket bridge#7andronedev wants to merge 5 commits into
andronedev wants to merge 5 commits into
Conversation
Browser (this repo): - Abstract the connection layer into an ActiveConnection with usb/wireless transport kinds so AdbDaemonTransport.authenticate is fed from either a WebUSB duplex or a WebSocket duplex (connection.ts). - Device-side enable over USB via adb.tcpip.setPort(5555), reusing the existing getIpAddress; persist the endpoint (wireless.ts, wireless-store). - WebSocket transport that frames the raw ADB packet stream to/from the bridge, plus a /health bridge probe (ws-connection.ts). - device-store gains connectViaWireless and a transport-agnostic finalize; WirelessPanel drives enable / reconnect UI, wired into ConnectPanel and the dashboard. i18n keys in en and fr. Bridge (new Rust crate at bridge/, polyglot monorepo): - axum WS relay on 127.0.0.1: GET /health (JSON + CORS) and GET /adb?ip=&port=5555 upgraded to a byte pipe to the device. - Security: loopback-only, Origin allowlist, RFC1918 + port 5555 target restriction, optional pinned device IP, no ADB keys held. - Features: default networking core; tls (axum-server) and desktop (tray-icon/tao + auto-launch) gated. Verified: cargo check/clippy -D warnings (core and production), and runtime smoke test of health/CORS/ origin/port/SSRF guards. Monorepo wiring: deploy.yml ignores bridge/**, new bridge.yml (clippy/test on PRs, release matrix on bridge-v* tags), biome ignores bridge, gitignore adds bridge/target. Docs: correct the --wifi-adb note in programs.md and update the PRD status, pinned bridge contract, and stack.
adb tcpip restarts adbd and tears down the live (USB) transport, so getIpAddress must run before setPort, not after. Also disconnect after a successful enable so the UI returns to the connect screen where the Wi-Fi reconnect action surfaces.
Rework the wireless UI for non-technical users. The connect screen now always offers a collapsible Wi-Fi guide (open by default once configured) with three staged steps: enable on the Portal, install and run the bridge, then connect. Each step shows a live done/active/todo state. Step 2 detects the bridge and, when absent, surfaces a download button plus an "already installed? make sure it is running, then check again" hint with a recheck action, covering both not-installed and not-running. A "why is the cable needed first?" disclosure explains the one-time USB requirement. Clarify the dashboard enable card (what happens after enabling) and add BRIDGE_DOWNLOAD_URL. New copy is in i18n en + fr.
Replace the single-device store with a per-serial fleet registry so several Portals can stay connected at once, with one "active" device driving the heavy tools (screen/terminal/logcat/files) while the rest stay connected in the background. Adds fleet UI (sidebar switcher, add-device flow, reconnect wall for known USB/Wi-Fi devices, and a bulk action bar for install/reboot/uninstall/set-flag across selected devices), turns wireless-adb's last-known-endpoint into a persisted set, and seeds three distinct mock devices in demo mode so the fleet UI is testable without hardware. Also fixes Modal/ConfirmDialog rendering trapped inside the sidebar's bounding box (a transformed ancestor becomes the containing block for fixed-position descendants) by portaling them to document.body. Claude-Session: https://claude.ai/code/session_01PDwMvqk55fZNE9hvqGe42Q
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.
What this adds
Manage a Portal over Wi-Fi, not only over the USB cable, while keeping the
browser-first, no-backend identity. Full spec in
docs/prd-wireless-adb.md.A browser tab cannot open a raw TCP socket, so this ships in two honest halves:
WebSocket to the device's ADB TCP port. It is a dumb byte pipe: ADB's RSA
handshake runs end to end in the browser, so the bridge holds no keys.
Browser (this repo)
src/lib/adb/connection.ts(ActiveConnection, usb/wirelesskinds) feeding the same
AdbDaemonTransport.authenticate.adb.tcpip.setPort(5555)reusing the existinggetIpAddress(src/lib/adb/wireless.ts); endpoint persisted inwireless-store.bridge
/health(src/lib/adb/ws-connection.ts).connectViaWirelessin device-store;WirelessPanel.tsxUI (enable on thedashboard, reconnect on the connect screen). i18n en + fr.
Bridge (new Rust crate at
bridge/, polyglot monorepo)127.0.0.1:GET /health(JSON + CORS) andGET /adb?ip=&port=5555upgraded to a byte pipe to the device.restriction, optional pinned device IP, no ADB keys held.
tls(axum-server) anddesktop(tray-icon/tao + auto-launch) gated.
Monorepo wiring
deploy.ymlignoresbridge/**; newbridge.yml(clippy/test on PRs,release matrix on
bridge-v*tags); biome ignoresbridge; gitignore addsbridge/target.--wifi-adbnote indocs/programs.md; PRD updated withstatus, pinned bridge contract, and stack.
Verified
pnpm lint+pnpm buildgreen;cargo check/clippy -D warningsgreen(core and production).
adb tcpip 5555+ wireless connectwork; the bridge relayed a real ADB
CNXNand the device answeredAUTHthrough the WebSocket; scrcpy 2.3 server runs and exposes an H.264 encoder, so
screen mirroring works over Wi-Fi (no audio, as before).
the bridge, then screen mirror.
Not ready yet (follow-ups)
local.openportal.cc(prod uses WSS;dev uses plain ws to loopback, already working).
scrcpy.ts/CLAUDE.mdsay "Android 10" but Gen 1 is Android 9(conclusion of "no audio" still holds; audio needs Android 11+).
How to test
pnpm dev, thenadb kill-server, connect over USB, click Enable wirelessADB, run
cargo run --manifest-path bridge/Cargo.toml, then Reconnect overWi-Fi and open the screen mirror.