Skip to content

Add ADB network device connection support - #9950

Open
s546126 wants to merge 6 commits into
stablyai:mainfrom
s546126:claude/adb-network-device-connection-ultecg
Open

Add ADB network device connection support#9950
s546126 wants to merge 6 commits into
stablyai:mainfrom
s546126:claude/adb-network-device-connection-ultecg

Conversation

@s546126

@s546126 s546126 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds first-class support for connecting a locally reachable Android device or cloud phone by ADB TCP address in Settings > Mobile Emulator, feeding the existing inventory → EmulatorBridge → scrcpy pipeline (no second backend, no new video transport):

  • New ADB Device Connection section (between Availability and Default Device): one persisted host:port address, Connect/Disconnect, explicit status (disconnected / connecting / connected / unauthorized / offline / failed), reachability help text and an ADB-exposure security warning. Success is verified via adb devices -l state=device, never inferred from adb connect text or exit code.
  • Platform-tools-only hosts are now valid: SDK discovery requires only adb; the emulator/avdmanager binaries moved behind an optional avdTools capability, so connected-device workflows work without Android Studio while full-SDK AVD flows are unchanged.
  • Lifecycle ownership: pane close / app quit stop the scrcpy helper only — the shared adb server keeps its connections; only the explicit Settings Disconnect runs adb disconnect. adb emu kill is guarded to local emulator-\d+ serials; TCP/USB serials can never receive it from any teardown path.
  • Routing fix: a host:port serial is classified as Android before the ownsDevice/platform fallback in EmulatorBridge, so an offline 127.0.0.1:5555 on macOS routes to Android with actionable "connect it in Settings" guidance instead of falling through to iOS or AVD boot. Connect (RPC) is the only code path that ever runs adb connect.
  • Additive RPC (emulator.adbConnect / adbDisconnect / adbConnectionStatus, local runtime only), additive emulator_adb_* error codes, one persisted setting mobileEmulatorAdbAddress, default-device hygiene that only clears a default pointing at the previous network serial, and docs/skill updates.

Also submitted upstream as #9950. The branch is rebased onto upstream main (334027cfd): 4 commits, 121e61297 → 34703f26c → a78b1a865 → 1597ffa6c. This fork's main predates the Android/scrcpy backend, so the diff shown here vs the fork's main includes upstream history; the upstream PR shows the clean 4-commit diff.

Screenshots

No screenshots available from this headless environment — the new section reuses the existing settings primitives (SettingsRow/Label/Input/Button/Badge with existing status tokens). UI behavior is covered by component tests.

Testing

  • pnpm typecheck (all three tsc projects pass, re-run after the rebase onto upstream main)
  • pnpm test for all touched areas: src/main/emulator, emulator RPC methods, settings components/shared defaults — 962 tests pass post-rebase, including new suites for endpoint grammar, connect/disconnect/status polling, emu-kill guards, bridge routing regression (offline 127.0.0.1:5555 on darwin → Android), lifecycle (tab close/app quit never disconnect), single in-flight op, defaults/hygiene, and stale-response guarding
  • oxlint clean on touched files; the branch's own i18n keys verified present in all five locale catalogs after the rebase conflict resolution
  • pnpm lint full: verify:skill-bundle-manifest cannot pass on this fork (upstream release tags absent; also fails on the clean base — see the CI-triage comment below). verify:localization-catalog currently fails on upstream main itself (pre-existing upstream drift in e.g. sleep-worktree-flow.ts), reproduced on a clean upstream checkout — intentionally not papered over in this PR
  • pnpm build not run in this environment
  • Added regression tests for every lifecycle/routing guarantee above

No live smoke test against a real reachable ADB endpoint was run; verification is via mocked-runner tests.

AI Review Report

Implemented via a staged multi-agent workflow: each stage (SDK capability split → endpoint grammar + guards → connection manager → RPC → settings UI → docs) was implemented, then independently reviewed by a stronger reviewer model that re-ran tests/typecheck and specifically hunted for: auto-connect paths outside the Connect RPC, emu kill guard gaps, success inferred without adb devices -l, error-code mutations, parser/serial-recognition grammar divergence, over-engineering, and scope creep. All blocking findings were fixed in-loop. Cross-platform was explicitly checked: SDK discovery paths for macOS/Linux/Windows incl. adb.exe/emulator.exe/avdmanager.bat via path.join (unit-tested per platform), no shortcut/label changes, no shell-specific commands.

Security Audit

  • Input handling: the address is validated by a strict pure grammar (hostname/IPv4 + port 1..65535; rejects URLs, credentials, paths, whitespace/control bytes; bracketed IPv6 explicitly unsupported) before any process execution; RPC inputs are zod-validated.
  • Command execution: all adb invocations go through the existing execFile-based AndroidCommandRunner with arg arrays (no shell interpolation); the validated address is passed as a single argv element.
  • The UI warns that ADB grants shell/install/debug access and must not be exposed to untrusted networks; Orca never opens/forwards ports itself (VPN/tunnels remain the user's concern).
  • IPC: renderer receives typed, renderer-safe status objects (no raw errors/stacks). No secrets, no new dependencies, no SSH/remote-runtime code touched.

Notes

  • emu kill guard: TCP/USB serials never receive it; local AVD shutdown behavior unchanged.
  • A later Orca launch reflects real shared adb state passively (status is read-only); nothing auto-connects on startup/availability/pane-open.
  • Known minors (documented, deliberate): currentAddress() insertion-order nuance is unobservable in v1's single-address model; a failed disconnect drops the address→serial mapping before surfacing the residual entry (mapping is address==serial today).
  • Follow-up candidates: IPv6 support, multiple saved addresses, auto-reconnect — all explicitly out of v1 scope.

ELI5

You can connect a phone or device over ADB network (host:port) in Settings → Mobile Emulator. Connect/disconnect and status feed the same emulator pipeline as USB devices—no separate video stack.

claude added 4 commits July 22, 2026 14:56
Split Android SDK discovery so platform-tools-only hosts (adb without the
emulator/avdmanager binaries) can list and drive connected devices; add a
pure host:port endpoint grammar, an adb connect/disconnect/status manager
verified through adb devices -l, route network serials to the Android
backend before ownership/platform fallback, and guard emu kill to local
emulator-* serials only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01Fk7F1By3BPUyjN8Cbcjq1o
…tus RPC

Local-only additive methods; connect is the single initiator of adb connect,
disconnect stops scrcpy helpers before dropping the adb connection, status is
passive.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01Fk7F1By3BPUyjN8Cbcjq1o
…ings

Persist one mobileEmulatorAdbAddress, add the connect/disconnect UI with
explicit status (disconnected/connecting/connected/unauthorized/offline/
failed), reachability + security help text, default-device hygiene that only
clears a default pointing at the previous network serial, and search/i18n
entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01Fk7F1By3BPUyjN8Cbcjq1o
…tools-only support

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01Fk7F1By3BPUyjN8Cbcjq1o
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds support for connecting already-reachable Android network devices through ADB host:port addresses. The change validates endpoints, manages ADB connection states and lifecycle, supports platform-tools-only installations, routes network serials through the Android backend, and exposes runtime and RPC commands. A Settings component provides connection, status, authorization, and disconnect controls with localized copy. Tests cover parsing, lifecycle behavior, concurrency, SDK discovery, backend routing, RPC schemas, UI state, and default settings. Documentation describes prerequisites and connection semantics.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding ADB network device connection support.
Description check ✅ Passed The description follows the required template and covers summary, screenshots, testing, review, security, and notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Checkov (3.3.8)
resources/skills/current-manifest.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'

resources/skills/release-mapping.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'

resources/skills/snapshot-registry.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/main/emulator/backends/android-emulator-backend.ts (1)

172-186: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Extend the network-serial guard to resolveDeviceId, not just the boot path.

android-avd-boot.ts's bootAndroidDevice now special-cases isAdbNetworkSerial(deviceOrName) to fail with an actionable "not connected, connect it in Settings > Mobile Emulator" message. resolveDeviceId here — used by tap, gesture, type, button, exec, installApp, launchApp, setPermission, accessibilityTree, logcat, and shutdownDevice — has no equivalent guard, so any of those calls against a configured-but-disconnected network address instead get the boot-oriented "is not running. Boot it first." message, which is misleading (there is nothing to "boot").

♻️ Proposed fix
   async resolveDeviceId(deviceOrName: string): Promise<string> {
     const sdk = this.requireSdk()
     const running = await listRunningAdbDevices(this.runner, sdk)
     if (running.some((device) => device.serial === deviceOrName)) {
       return deviceOrName
     }
     const serial = await findRunningAvdSerial(this.runner, sdk, deviceOrName, running)
     if (serial) {
       return serial
     }
+    if (isAdbNetworkSerial(deviceOrName)) {
+      throw new EmulatorError(
+        'emulator_adb_not_connected',
+        `ADB device ${deviceOrName} is not connected. Connect it in Settings > Mobile Emulator.`
+      )
+    }
     throw new EmulatorError(
       'emulator_device_not_found',
       `Android device "${deviceOrName}" is not running. Boot it first.`
     )
   }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4fbf01bd-2fb0-4c56-a539-1a11aec0354a

📥 Commits

Reviewing files that changed from the base of the PR and between 334027c and 1d1ca14.

📒 Files selected for processing (41)
  • docs/android-emulation.md
  • skill-guides/orca-emulator-android.md
  • skills/orca-emulator-android/SKILL.md
  • src/cli/bundled-skill-guides.ts
  • src/main/emulator/android/adb-device-connection.test.ts
  • src/main/emulator/android/adb-device-connection.ts
  • src/main/emulator/android/adb-network-endpoint.test.ts
  • src/main/emulator/android/adb-network-endpoint.ts
  • src/main/emulator/android/android-avd-boot.test.ts
  • src/main/emulator/android/android-avd-boot.ts
  • src/main/emulator/android/android-capability-operations.test.ts
  • src/main/emulator/android/android-device-inventory.test.ts
  • src/main/emulator/android/android-device-inventory.ts
  • src/main/emulator/android/android-input-commands.test.ts
  • src/main/emulator/android/android-screen-size-cache.ts
  • src/main/emulator/android/android-sdk-discovery.test.ts
  • src/main/emulator/android/android-sdk-discovery.ts
  • src/main/emulator/backends/android-emulator-backend.test.ts
  • src/main/emulator/backends/android-emulator-backend.ts
  • src/main/emulator/emulator-bridge.test.ts
  • src/main/emulator/emulator-bridge.ts
  • src/main/emulator/emulator-errors.ts
  • src/main/runtime/orca-runtime-emulator-adb.ts
  • src/main/runtime/orca-runtime-emulator.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/emulator.test.ts
  • src/main/runtime/rpc/methods/emulator.ts
  • src/renderer/src/components/settings/MobileEmulatorAdbConnection.test.tsx
  • src/renderer/src/components/settings/MobileEmulatorAdbConnection.tsx
  • src/renderer/src/components/settings/MobileEmulatorSettingsPane.tsx
  • src/renderer/src/components/settings/mobile-emulator-adb-default-device-hygiene.test.ts
  • src/renderer/src/components/settings/mobile-emulator-adb-default-device-hygiene.ts
  • src/renderer/src/components/settings/mobile-emulator-search.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/constants.test.ts
  • src/shared/constants.ts
  • src/shared/types.ts

Comment thread docs/android-emulation.md
Comment thread skill-guides/orca-emulator-android.md Outdated
Comment thread src/renderer/src/components/settings/mobile-emulator-search.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 73d372e1-664a-4095-9414-a976b2779bff

📥 Commits

Reviewing files that changed from the base of the PR and between 1d1ca14 and 1597ffa.

📒 Files selected for processing (4)
  • docs/android-emulation.md
  • skill-guides/orca-emulator-android.md
  • skills/orca-emulator-android/SKILL.md
  • src/cli/bundled-skill-guides.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/cli/bundled-skill-guides.ts
  • docs/android-emulation.md
  • skill-guides/orca-emulator-android.md

Comment thread skills/orca-emulator-android/SKILL.md Outdated
@AmethystLiang
AmethystLiang requested a review from OrcaWin July 22, 2026 17:03
@s546126 s546126 changed the title Claude/adb network device connection ultecg Add ADB network device connection suppor Jul 22, 2026
@s546126 s546126 changed the title Add ADB network device connection suppor Add ADB network device connection support Jul 22, 2026
buddhistrhythm and others added 2 commits July 22, 2026 10:21
- Disconnect button now falls back to status.address so a live ADB
  connection stays disconnectable even after the address field is
  cleared (settings.mobileEmulatorAdbAddress alone could go stale)
- Backfill 8 missing ADB search-keyword locale-catalog keys
  (adb/device/address/tcp/cloud phone/connect/disconnect/network)
  across en/es/ja/ko/zh, matching sync:localization-catalog convention

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…; align adb-only prerequisites

Address CodeRabbit review on the upstream PR: resolveDeviceId now reports
emulator_adb_not_connected with Settings guidance for a host:port serial
(shared message factory with the boot path) instead of 'Boot it first';
prerequisite copy and the missing-SDK message now lead with platform-tools
sufficiency; regenerate skill guides and the skill bundle manifest (revision
bump was previously blocked by missing release tags).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01Fk7F1By3BPUyjN8Cbcjq1o

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 969d60ef-8e4b-4fec-a630-717ff16d8ce2

📥 Commits

Reviewing files that changed from the base of the PR and between f87a1e9 and 19b9300.

📒 Files selected for processing (13)
  • docs/android-emulation.md
  • resources/skills/current-manifest.json
  • resources/skills/release-mapping.json
  • resources/skills/snapshot-registry.json
  • skill-guides/orca-emulator-android.md
  • skills/orca-emulator-android/SKILL.md
  • src/cli/bundled-skill-guides.ts
  • src/main/emulator/android/android-avd-boot.ts
  • src/main/emulator/android/android-sdk-state.ts
  • src/main/emulator/backends/android-emulator-backend.test.ts
  • src/main/emulator/backends/android-emulator-backend.ts
  • src/main/emulator/emulator-availability.test.ts
  • src/main/emulator/emulator-errors.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/main/emulator/emulator-errors.ts
  • src/cli/bundled-skill-guides.ts
  • docs/android-emulation.md
  • src/main/emulator/backends/android-emulator-backend.test.ts
  • skill-guides/orca-emulator-android.md
  • src/main/emulator/backends/android-emulator-backend.ts

Comment on lines +579 to +586
"appVersion": "1.4.150-rc.0",
"skills": {
"computer-use": 5,
"linear-tickets": 7,
"orca-cli": 35,
"orca-emulator": 4,
"orca-emulator-android": 2,
"orca-linear": 5,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Map orca-emulator-android to revision 3 for this release.

Line 585 still points 1.4.150-rc.0 to revision 2, while resources/skills/current-manifest.json and resources/skills/snapshot-registry.json declare the newly shipped snapshot as revision 3. The runtime provenance builder will therefore have no released-app entry for revision 3.

Proposed fix
-        "orca-emulator-android": 2,
+        "orca-emulator-android": 3,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"appVersion": "1.4.150-rc.0",
"skills": {
"computer-use": 5,
"linear-tickets": 7,
"orca-cli": 35,
"orca-emulator": 4,
"orca-emulator-android": 2,
"orca-linear": 5,
"appVersion": "1.4.150-rc.0",
"skills": {
"computer-use": 5,
"linear-tickets": 7,
"orca-cli": 35,
"orca-emulator": 4,
"orca-emulator-android": 3,
"orca-linear": 5,

@nwparker nwparker added the enhancement New feature or request label Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants