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
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
- 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<DeviceInfo, Task> 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
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-lTCP 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 (
mauicommand). As an interim solution, the extension now pollsmaui device list --jsonevery 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-devicesbased device monitoring capability to theXamarin.Android.Tools.AndroidSdkpackage, so the MAUI DevTools CLI can offer a streamingdevice watchcommand.What exists today
AdbRunner.ListDevicesAsync()— one-shot device enumeration viaadb devices -lAdbDeviceInfo— device model with serial, status, type, model, etc.What's needed
AdbRunner.WatchDevicesAsync()(or similar) — a method that opens a persistent connection to the ADB server using thehost:track-devices-lprotocol and yields device change events as they occurlocalhost:5037)host:track-devices-lcommandCancellationTokenfor clean shutdownReference implementation
The ServiceHub's
AdbdClient.csalready implements this pattern:csharp public async Task WatchDevicesAsync(CancellationToken ct, Func<DeviceInfo, Task> 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 --jsonEmitting 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?
adb devicesevery 3sPolling 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
dotnet/mauibranchmaui-client-tool-androiddotnet/vscode-mauiMauiDevicePoller.tsin vscode-maui