Skip to content

Use shared AdbRunner from android-tools for device listing#10880

Draft
rmarinho wants to merge 5 commits intomainfrom
feature/use-shared-adb-runner
Draft

Use shared AdbRunner from android-tools for device listing#10880
rmarinho wants to merge 5 commits intomainfrom
feature/use-shared-adb-runner

Conversation

@rmarinho
Copy link
Member

@rmarinho rmarinho commented Mar 3, 2026

Summary

Delegates the adb devices -l parsing, description building, and device/emulator merging logic from the GetAvailableAndroidDevices MSBuild task to the shared AdbRunner in Xamarin.Android.Tools.AndroidSdk (via the external/xamarin-android-tools submodule).

This removes ~200 lines of duplicated parsing/formatting/merging code from dotnet/android and consolidates it in the shared android-tools library where it can be reused by other consumers (e.g., the MAUI DevTools CLI).

Changes

  • Submodule update: external/xamarin-android-toolsfeature/adb-runner branch (82de0a1)
    • Includes TCP console fallback for AVD name resolution (fixes macOS issue where adb emu avd name returns empty)
    • Bare catch fix with exception logging
    • Regex fix for explicit adb states and tab support
    • Nullable reference type fixes
  • GetAvailableAndroidDevices.cs: Rewritten to delegate to AdbRunner.ParseAdbDevicesOutput(IEnumerable<string>), AdbRunner.BuildDeviceDescription, and AdbRunner.MergeDevicesAndEmulators instead of having its own parsing logic. Added ConvertToTaskItems to bridge AdbDeviceInfoITaskItem.
  • GetAvailableAndroidDevicesTests.cs: Updated to use AdbRunner/AdbDeviceInfo directly instead of reflection. All tests preserved with equivalent coverage.

Key improvements from updated submodule

The updated AdbRunner includes a TCP console fallback for AVD name resolution. On macOS, adb -s emulator-XXXX emu avd name often returns exit code 0 but with empty output, causing:

  1. Running emulators to show as "sdk gphone64 arm64" instead of their AVD name
  2. MergeDevicesAndEmulators unable to match running emulators with AVD definitions (potential duplicates)

The fallback connects to the emulator console port and queries avd name directly, which reliably returns the correct name.

Review feedback addressed

  • ParseAdbDevicesOutput accepts IEnumerable<string> to avoid string.Join allocation — callers pass List<string> directly
  • BuildDeviceDescription and MergeDevicesAndEmulators accept optional Action<TraceLevel, string> logger callback following existing CreateTaskLogger pattern, restoring MSBuild debug diagnostics
  • GetAvailableAndroidDevices still extends AndroidAdb (needs base.RunTask(), ToolPath/ToolExe, LogEventsFromTextOutput)

Dependencies

/cc @jonathanpeppers

Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

All the calls here need to make it to the MSBuild logger, we lost some log messages with this change.

MSBuild tasks have a TaskLoggingHelper Log property, we need to pass this in to android-tools to use it for logging.

We could setup something like this:

https://github.com/dotnet/android-tools/blob/6a6de1f24572d93048f3bbaa997bcfcf43a472dd/src/Microsoft.Android.Build.BaseTasks/MSBuildExtensions.cs#L191-L207

So, from the MSBuild task, it passes in a Action<TraceLevel, string> for dotnet/android-tools to log with.

rmarinho added a commit to dotnet/android-tools that referenced this pull request Mar 4, 2026
Avoids allocating a joined string when callers already have individual
lines (e.g., MSBuild LogEventsFromTextOutput). The existing string
overload now delegates to the new one.

Addresses review feedback from @jonathanpeppers on dotnet/android#10880.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho
Copy link
Member Author

rmarinho commented Mar 4, 2026

Done — added optional Action<TraceLevel, string>? logger parameters to BuildDeviceDescription and MergeDevicesAndEmulators in android-tools (dotnet/android-tools@9d4b4f5), following the existing CreateTaskLogger pattern from MSBuildExtensions.

Restored debug messages:

  • AVD name formatting (original → formatted)
  • Running emulator AVD names set
  • Skipping already-running emulators
  • Added non-running emulators

GetAvailableAndroidDevices now passes this.CreateTaskLogger() to both calls so all messages route through the MSBuild logger.

@rmarinho rmarinho force-pushed the feature/use-shared-adb-runner branch from 0995ff2 to 30124fa Compare March 4, 2026 14:48
Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

CI fails with:

2026-03-04T15:12:54.1988548Z D:\a\_work\1\s\external\xamarin-android-tools\src\Xamarin.Android.Tools.AndroidSdk\Runners\AdbRunner.cs(139,55): error CS8620: Argument of type 'string?[]' cannot be used for parameter 'args' of type 'string[]' in 'ProcessStartInfo ProcessUtils.CreateProcessStartInfo(string fileName, params string[] args)' due to differences in the nullability of reference types. [D:\a\_work\1\s\external\xamarin-android-tools\src\Xamarin.Android.Tools.AndroidSdk\Xamarin.Android.Tools.AndroidSdk.csproj::TargetFramework=netstandard2.0]
2026-03-04T15:12:54.1989406Z     1 Warning(s)
2026-03-04T15:12:54.1989550Z     3 Error(s)
2026-03-04T15:12:54.1989613Z 
2026-03-04T15:12:54.1989758Z Time Elapsed 00:10:16.48

rmarinho and others added 4 commits March 5, 2026 12:05
Delegates adb devices parsing, description building, and device/emulator
merging from GetAvailableAndroidDevices to AdbRunner in the shared
xamarin-android-tools submodule. Removes ~200 lines of duplicated logic.

- ParseAdbDevicesOutput accepts IEnumerable<string> to avoid string.Join
- BuildDeviceDescription/MergeDevicesAndEmulators accept optional
  Action<TraceLevel, string> logger for MSBuild diagnostics
- Tests updated to use AdbRunner/AdbDeviceInfo directly

Depends on dotnet/android-tools#283.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bumps external/xamarin-android-tools from 9d4b4f5 to f8fbca3 on
feature/adb-runner. The new commit fixes CS8601/CS8620 nullable
reference type warnings that are treated as errors by this project
(WarningsAsErrors=Nullable).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Updates xamarin-android-tools to dbf54f9 which fixes the device
parsing regex to handle tab-separated adb output and use explicit
state names to prevent false positives.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…82de0a1)

Picks up:
- TCP console fallback for AVD name resolution when adb emu avd name fails
- Bare catch fix with exception logging
- Regex fix for explicit adb states and tab support
- Nullable reference type fixes for compatibility

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho force-pushed the feature/use-shared-adb-runner branch from b5df11c to 91b9ca6 Compare March 5, 2026 12:05
rmarinho added a commit to dotnet/android-tools that referenced this pull request Mar 5, 2026
Avoids allocating a joined string when callers already have individual
lines (e.g., MSBuild LogEventsFromTextOutput). The existing string
overload now delegates to the new one.

Addresses review feedback from @jonathanpeppers on dotnet/android#10880.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Submodule updated from 82de0a1 to 3cadb58 (feature/adb-runner rebased on main).
Changes in submodule:
- Constructor refactor: Func<string?> → string adbPath
- ThrowIfFailed StringWriter overload
- Delete ParseAdbDevicesOutput(string) overload
- Replace null-forgiving with property patterns
- MapAdbStateToStatus switch expression

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.

2 participants