Skip to content

feat: Android Wi-Fi device pairing (QR + pairing code) with remember/auto-reconnect#30

Draft
DevSrSouza wants to merge 1 commit into
mainfrom
feat/android-wifi-pairing
Draft

feat: Android Wi-Fi device pairing (QR + pairing code) with remember/auto-reconnect#30
DevSrSouza wants to merge 1 commit into
mainfrom
feat/android-wifi-pairing

Conversation

@DevSrSouza

Copy link
Copy Markdown
Contributor

What

Pair physical Android devices over Wi-Fi from Jaca — a sheet launched from the Devices area, driving the adb CLI. Supports both pairing modes plus a remember/auto-reconnect layer that adb itself lacks.

  • QR mode — generate a service name + password, render the QR (CoreImage, no deps), and auto-pair the moment the phone advertises _adb-tls-pairing._tcp under our name.
  • Pairing-code mode — a live mDNS discovery list plus a manual ip:port field (the phone shows it) so pairing still works on networks that block multicast.
  • Better than the silent failures — parses and shows adb's actual error, detects a disabled mDNS daemon via adb mdns check, and offers a one-click adb kill-server recovery.
  • Remember + auto-recover — persists paired devices (name, last IP, method, last-seen) under Application Support and reattaches them in the background when their _adb-tls-connect service reappears.

Why

Android Studio's wireless pairing fails silently and doesn't auto-recover or remember devices. This mirrors the official flow (researched against the AOSP adb and Android Studio tools-base/adblib sources) and fills those gaps.

Files

Area File
mDNS model + pure parser Core/Devices/MdnsService.swift
adb wrapper + pure result/health parsers Core/Devices/AdbPairingService.swift
QR payload + credentials (pure) Core/Devices/QrPairing.swift
Paired-device persistence + reconnect join Core/Devices/PairedDeviceStore.swift
State machine + discovery loop Model/PairingModel.swift
Sheet UI (QR + code tabs) Features/Pairing/PairDeviceSheet.swift
Factory + background reconnect loop Model/AppModel.swift
Header + empty-state entry points Features/Sidebar/DeviceSidebarView.swift

Design notes

  • Discovery polls the text adb mdns services every ~1s rather than the protobuf host:track-mdns-services stream (that stream is new-adb-2025+ only; polling text is universal, sub-second, and trivially testable). Upgrading to the live stream is a possible follow-up.
  • No blind subnet scan — pairing/connect ports are random, ephemeral, and only open briefly, so scanning is low-value and can trip network security. The manual ip:port fallback + targeted remembered-host reconnect cover the mDNS-blocked case instead.

Test plan

  • Tests/PairingTests.swift — 17 cases over the pure logic (mDNS parser, PairResult, MdnsHealth, QR payload/credentials, paired-device store + reconnect join). All green.
  • ✅ Release build installs and launches; sheet opens full-size with the QR pre-rendered and an ✕ close button.
  • ⚠️ Not yet exercised end-to-end against a physical device — the live SPAKE2 pair handshake needs a real Android phone to confirm. Draft until that's verified.

🤖 Generated with Claude Code

…auto-reconnect

Pair physical Android devices over Wi-Fi from a sheet in the Devices area,
driving the `adb` CLI — both QR-code and pairing-code modes.

- QR mode: generate service name + password, render the QR (CoreImage), and
  auto-pair when the phone advertises `_adb-tls-pairing._tcp` under our name.
- Pairing-code mode: live mDNS discovery list + a manual `ip:port` fallback
  (the phone shows it) for networks that block multicast.
- Surfaces adb's failure message instead of failing silently, detects a disabled
  mDNS daemon via `adb mdns check`, and offers a one-click `adb kill-server` recovery.
- Remembers paired devices (name, last IP, method, last-seen) in Application
  Support and reattaches them in the background when their `_adb-tls-connect`
  service reappears — the auto-recover adb skips.

New: Core/Devices/{MdnsService,AdbPairingService,QrPairing,PairedDeviceStore},
Model/PairingModel, Features/Pairing/PairDeviceSheet. Wired into AppModel
(factory + reconnect loop) and DeviceSidebarView (button + sheet).

Tests: Tests/PairingTests.swift covers the pure logic — mDNS parser, PairResult,
MdnsHealth, QR payload/credentials, and the paired-device store (17 cases).
Not yet exercised end-to-end against a physical device.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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