Add ADB network device connection support - #9950
Conversation
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
1d1ca14 to
1597ffa
Compare
📝 WalkthroughWalkthroughAdds support for connecting already-reachable Android network devices through ADB 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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.jsonTraceback (most recent call last): resources/skills/release-mapping.jsonTraceback (most recent call last): resources/skills/snapshot-registry.jsonTraceback (most recent call last): 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/main/emulator/backends/android-emulator-backend.ts (1)
172-186: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winExtend the network-serial guard to
resolveDeviceId, not just the boot path.
android-avd-boot.ts'sbootAndroidDevicenow special-casesisAdbNetworkSerial(deviceOrName)to fail with an actionable "not connected, connect it in Settings > Mobile Emulator" message.resolveDeviceIdhere — used bytap,gesture,type,button,exec,installApp,launchApp,setPermission,accessibilityTree,logcat, andshutdownDevice— 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
📒 Files selected for processing (41)
docs/android-emulation.mdskill-guides/orca-emulator-android.mdskills/orca-emulator-android/SKILL.mdsrc/cli/bundled-skill-guides.tssrc/main/emulator/android/adb-device-connection.test.tssrc/main/emulator/android/adb-device-connection.tssrc/main/emulator/android/adb-network-endpoint.test.tssrc/main/emulator/android/adb-network-endpoint.tssrc/main/emulator/android/android-avd-boot.test.tssrc/main/emulator/android/android-avd-boot.tssrc/main/emulator/android/android-capability-operations.test.tssrc/main/emulator/android/android-device-inventory.test.tssrc/main/emulator/android/android-device-inventory.tssrc/main/emulator/android/android-input-commands.test.tssrc/main/emulator/android/android-screen-size-cache.tssrc/main/emulator/android/android-sdk-discovery.test.tssrc/main/emulator/android/android-sdk-discovery.tssrc/main/emulator/backends/android-emulator-backend.test.tssrc/main/emulator/backends/android-emulator-backend.tssrc/main/emulator/emulator-bridge.test.tssrc/main/emulator/emulator-bridge.tssrc/main/emulator/emulator-errors.tssrc/main/runtime/orca-runtime-emulator-adb.tssrc/main/runtime/orca-runtime-emulator.tssrc/main/runtime/orca-runtime.tssrc/main/runtime/rpc/methods/emulator.test.tssrc/main/runtime/rpc/methods/emulator.tssrc/renderer/src/components/settings/MobileEmulatorAdbConnection.test.tsxsrc/renderer/src/components/settings/MobileEmulatorAdbConnection.tsxsrc/renderer/src/components/settings/MobileEmulatorSettingsPane.tsxsrc/renderer/src/components/settings/mobile-emulator-adb-default-device-hygiene.test.tssrc/renderer/src/components/settings/mobile-emulator-adb-default-device-hygiene.tssrc/renderer/src/components/settings/mobile-emulator-search.tssrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/shared/constants.test.tssrc/shared/constants.tssrc/shared/types.ts
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 73d372e1-664a-4095-9414-a976b2779bff
📒 Files selected for processing (4)
docs/android-emulation.mdskill-guides/orca-emulator-android.mdskills/orca-emulator-android/SKILL.mdsrc/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
- 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
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 969d60ef-8e4b-4fec-a630-717ff16d8ce2
📒 Files selected for processing (13)
docs/android-emulation.mdresources/skills/current-manifest.jsonresources/skills/release-mapping.jsonresources/skills/snapshot-registry.jsonskill-guides/orca-emulator-android.mdskills/orca-emulator-android/SKILL.mdsrc/cli/bundled-skill-guides.tssrc/main/emulator/android/android-avd-boot.tssrc/main/emulator/android/android-sdk-state.tssrc/main/emulator/backends/android-emulator-backend.test.tssrc/main/emulator/backends/android-emulator-backend.tssrc/main/emulator/emulator-availability.test.tssrc/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
| "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, |
There was a problem hiding this comment.
🗄️ 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.
| "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, |
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):
host:portaddress, Connect/Disconnect, explicit status (disconnected / connecting / connected / unauthorized / offline / failed), reachability help text and an ADB-exposure security warning. Success is verified viaadb devices -lstate=device, never inferred fromadb connecttext or exit code.adb; theemulator/avdmanagerbinaries moved behind an optionalavdToolscapability, so connected-device workflows work without Android Studio while full-SDK AVD flows are unchanged.adb disconnect.adb emu killis guarded to localemulator-\d+serials; TCP/USB serials can never receive it from any teardown path.host:portserial is classified as Android before theownsDevice/platform fallback inEmulatorBridge, so an offline127.0.0.1:5555on 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 runsadb connect.emulator.adbConnect/adbDisconnect/adbConnectionStatus, local runtime only), additiveemulator_adb_*error codes, one persisted settingmobileEmulatorAdbAddress, 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'smainpredates the Android/scrcpy backend, so the diff shown here vs the fork'smainincludes 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 upstreammain)pnpm testfor 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 (offline127.0.0.1:5555on darwin → Android), lifecycle (tab close/app quit never disconnect), single in-flight op, defaults/hygiene, and stale-response guardingoxlintclean on touched files; the branch's own i18n keys verified present in all five locale catalogs after the rebase conflict resolutionpnpm lintfull:verify:skill-bundle-manifestcannot pass on this fork (upstream release tags absent; also fails on the clean base — see the CI-triage comment below).verify:localization-catalogcurrently fails on upstreammainitself (pre-existing upstream drift in e.g.sleep-worktree-flow.ts), reproduced on a clean upstream checkout — intentionally not papered over in this PRpnpm buildnot run in this environmentNo 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 killguard gaps, success inferred withoutadb 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.batviapath.join(unit-tested per platform), no shortcut/label changes, no shell-specific commands.Security Audit
execFile-basedAndroidCommandRunnerwith arg arrays (no shell interpolation); the validated address is passed as a single argv element.Notes
emu killguard: TCP/USB serials never receive it; local AVD shutdown behavior unchanged.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).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.