dotnet / dotnet/android

Add ADB track-devices support for efficient device monitoring

Open
#12,073 0 comments 0 reactions 0 assignees View on GitHub
android-tools needs-triage
Dominant language
C#
Stars
2.1k
Forks
579
Avg merge
1d 20h
Merged PRs (30d)
257

Description

## Context

The VS Code MAUI extension currently uses a C# ServiceHub (Microsoft.VisualStudio.Maui.Devices.AndroidDeviceManager) for real-time device connect/disconnect detection. This works via the ADB `host:track-devices-l` TCP protocol, which provides push-based notifications over a persistent socket connection to the ADB server.

We are migrating Android operations from the ServiceHub to the MAUI DevTools CLI tool (`maui` command). As an interim solution, the extension now polls `maui device list --json` every 3 seconds and diffs the results to detect device changes. This works but is less efficient than a native event-driven approach.

## Proposal

Add an ADB `track-devices` based device monitoring capability to the `Xamarin.Android.Tools.AndroidSdk` package, so the MAUI DevTools CLI can offer a streaming `device watch` command.

### What exists today

- **`AdbRunner.ListDevicesAsync()`** — one-shot device enumeration via `adb devices -l`
- **`AdbDeviceInfo`** — device model with serial, status, type, model, etc.

### What's needed

1. **`AdbRunner.WatchDevicesAsync()`** (or similar) — a method that opens a persistent connection to the ADB server using the `host:track-devices-l` protocol and yields device change events as they occur
2. The method should:
- Connect to ADB server TCP socket (default `localhost:5037`)
- Send `host:track-devices-l` command
- Parse the continuous stream of device status lines
- Emit structured events: device added, device removed, device state changed
- Support `CancellationToken` for clean shutdown
- Handle ADB server restarts gracefully (reconnect with backoff)

### Reference implementation

The ServiceHub's `AdbdClient.cs` already implements this pattern:

`csharp
public async Task WatchDevicesAsync(CancellationToken ct, Func handle)
{
await SendCommandAsync("host:track-devices-l", ct);
while (true)
{
var reply = await ReadNextReplyAsync(ct);
// Parse: "SERIAL STATE [key:value ...]"
var d = new DeviceInfo(serial, state, product, model, device, transportId);
handle?.Invoke(d);
}
}
`

### CLI integration

Once available, the MAUI DevTools CLI would expose:
`ash
maui device watch --platform android --json
`
Emitting newline-delimited JSON (NDJSON) events:
`json
{"event":"initial","devices":[...]}
{"event":"added","device":{...}}
{"event":"removed","identifier":"emulator-5554"}
{"event":"changed","device":{...},"previous_state":"offline","new_state":"device"}
`

### Why not just poll?

| Approach | Latency | CPU/IO cost | Battery impact |
|----------|---------|-------------|----------------|
| Polling 3s | 0–3s delay | Spawns `adb devices` every 3s | Higher |
| track-devices | Near-instant | Single persistent connection | Minimal |

Polling works as a v1 but the track-devices protocol is the proper long-term solution used by Android Studio, VS, and all major IDEs.

## Related

- MAUI DevTools CLI: `dotnet/maui` branch `maui-client-tool-android`
- VS Code extension: `dotnet/vscode-maui`
- Interim polling implementation: `MauiDevicePoller.ts` in vscode-maui

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.