Skip to content

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

Merged
jonathanpeppers merged 3 commits intomainfrom
dev/rumar/use-shared-adb-runner
Mar 12, 2026
Merged

Use shared AdbRunner from android-tools for device listing#10916
jonathanpeppers merged 3 commits intomainfrom
dev/rumar/use-shared-adb-runner

Conversation

@rmarinho
Copy link
Member

@rmarinho rmarinho commented Mar 11, 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).

Replaces #10880 — recreated under dev/ branch prefix so CI pipelines trigger.

Changes

Commits (3)

  1. 4a0407b2c — Use shared AdbRunner from android-tools for device listing
  2. af6af1ec8 — Update GetAvailableAndroidDevices.cs (hoist CreateTaskLogger() out of loop per @jonathanpeppers)
  3. c8c34b869 — Bump xamarin-android-tools to 1a26c0c (latest main)

Review Feedback Addressed

Reviewer Issue Fix
@jonathanpeppers ParseAdbDevicesOutput should take IEnumerable<string> Done in android-tools #283 — avoids string.Join allocation
@jonathanpeppers Add Action<TraceLevel, string> logger parameter Done in android-tools #283 — routes debug messages through MSBuild logger
@jonathanpeppers Hoist CreateTaskLogger() out of loop Done in commit af6af1ec8

CI Status

Submodule at 1a26c0c which includes the RS0026 fix (#298). CI should pass.

Dependencies

cc @jonathanpeppers

Copilot AI review requested due to automatic review settings March 11, 2026 17:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Moves Android device/emulator listing in the GetAvailableAndroidDevices MSBuild task to use the shared AdbRunner implementation from the external/xamarin-android-tools submodule, reducing duplicated parsing/merging logic and aligning behavior across consumers.

Changes:

  • Updated external/xamarin-android-tools submodule to a commit that includes AdbRunner device parsing/merging and display-name formatting.
  • Rewrote GetAvailableAndroidDevices to delegate parsing/description building/merging to AdbRunner, adding a bridge method to emit ITaskItems.
  • Refactored tests to use AdbRunner/AdbDeviceInfo directly rather than invoking private task methods via reflection.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Xamarin.Android.Build.Tasks/Tasks/GetAvailableAndroidDevices.cs Delegates adb output parsing + device/emulator merge to AdbRunner and converts results into MSBuild ITaskItems.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GetAvailableAndroidDevicesTests.cs Updates tests to validate behavior via AdbRunner and AdbDeviceInfo, removing reflection-based testing.
external/xamarin-android-tools Bumps submodule to a commit containing the shared AdbRunner logic used by the task/tests.
Comments suppressed due to low confidence (1)

external/xamarin-android-tools:1

  • The PR description notes this submodule commit causes RS0026 build failures (PublicAPI analyzer) until android-tools #298 is included. This submodule bump will keep CI red; consider updating the submodule to a commit that includes the #298 fix (or splitting this PR so the task change lands only once the submodule is buildable).

You can also share your feedback on Copilot code review. Take the survey.

var result = task.FormatDisplayName ("emulator-5554", "pixel_9_pro_xl_api_36");
var result = AdbRunner.FormatDisplayName ("pixel_9_pro_xl_api_36");

Assert.AreEqual ("Pixel 9 Pro Xl API 36", result, "Should format complex names correctly");
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

The expected value appears inconsistent with the PR description (“preserves uppercase segments like XL, SE, FE”). If AdbRunner.FormatDisplayName now preserves XL, this assertion should expect Pixel 9 Pro XL API 36 to match the new behavior.

Suggested change
Assert.AreEqual ("Pixel 9 Pro Xl API 36", result, "Should format complex names correctly");
Assert.AreEqual ("Pixel 9 Pro XL API 36", result, "Should format complex names correctly");

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

The current assertion is correct. FormatDisplayName uses ToTitleCase which only preserves words that are already fully uppercase. Since the test input is pixel_9_pro_xl_api_36 (all lowercase), xl correctly becomes Xl (title-cased). Only if the input were Pixel_9_Pro_XL (uppercase XL) would it be preserved as XL.

The API part is correct because there's an ApiRegex post-processing step that converts ApiAPI after title-casing.

So: pixel_9_pro_xl_api_36Pixel 9 Pro Xl Api 36Pixel 9 Pro Xl API 36

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.

🤖 AI Review Summary

Verdict: ✅ LGTM

No issues found. This is a clean refactor that centralizes ~200 lines of duplicated parsing/formatting/merging logic into the shared AdbRunner library.

CI Status:

  • Linux ✅, Windows ✅ (public CI passing)
  • Mac ⏳ pending
  • Internal DevDiv build ❌ — likely the RS0026 AcceptLicensesAsync issue documented in the PR description (blocked on android-tools #298)

👍 Positive callouts:

  • Centralized duplication — Moves parsing, description building, and merging into Xamarin.Android.Tools.AndroidSdk where other consumers (MAUI DevTools CLI) can reuse it. This directly follows the review rule: "Centralize duplicate algorithms" (Postmortem #54).
  • Reflection eliminated — Tests previously used BindingFlags.NonPublic | BindingFlags.Instance reflection to access ParseAdbDevicesOutput. Now they call AdbRunner and ConvertToTaskItems directly. Much more maintainable.
  • ConvertToTaskItems is internal static — Good design: stateless conversion, testable without instantiating the full task, and internal visibility follows the convention for new helpers.
  • return !Log.HasLoggedErrors — ✅ Correct RunTask() pattern.
  • IReadOnlyList<AdbDeviceInfo> parameter — ✅ Follows the IReadOnlyList<T> return type convention.
  • CreateTaskLogger() hoisted out of loop — Good catch from earlier review feedback, avoids repeated allocation.
  • Mono formatting — Tabs, spaces before parens, IsNullOrEmpty() extensions, #nullable enable — all correct.

Review generated by android-reviewer from review guidelines.

rmarinho and others added 2 commits March 11, 2026 20:10
Refactor GetAvailableAndroidDevices MSBuild task to delegate parsing
and merging logic to AdbRunner from Xamarin.Android.Tools.AndroidSdk
(via the xamarin-android-tools submodule at d3c269d).

- Remove local Regex-based parsing, DeviceType enum, and helper methods
- Use AdbRunner.ParseAdbDevicesOutput, BuildDeviceDescription,
  MergeDevicesAndEmulators, FormatDisplayName, MapAdbStateToStatus
- Update tests to use AdbRunner APIs and AdbDeviceInfo/AdbDeviceType

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho force-pushed the dev/rumar/use-shared-adb-runner branch from 8c20e70 to e158bf1 Compare March 11, 2026 20:12
Comment on lines +509 to 511
var result = AdbRunner.FormatDisplayName ("pixel_9_pro_xl_api_36");

Assert.AreEqual ("Pixel 9 Pro Xl API 36", result, "Should format complex names correctly");
Copy link
Member

@jonathanpeppers jonathanpeppers Mar 11, 2026

Choose a reason for hiding this comment

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

Wait, I thought we fixed this? It says Xl.

If it only preserves casing of XL, like AdbRunner.FormatDisplayName ("pixel_9_pro_XL_api_36") do we have at least one test for that?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right but we didn t change the test right? I was also confused, so you are saying we should have a special case for XL ?

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho force-pushed the dev/rumar/use-shared-adb-runner branch from e158bf1 to c8c34b8 Compare March 12, 2026 09:01
@jonathanpeppers jonathanpeppers merged commit f715c14 into main Mar 12, 2026
6 checks passed
@jonathanpeppers jonathanpeppers deleted the dev/rumar/use-shared-adb-runner branch March 12, 2026 13:39
@jonathanpeppers jonathanpeppers added the copilot `copilot-cli` or other AIs were used to author this label Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot `copilot-cli` or other AIs were used to author this

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants