Skip to content

Add AvdManagerRunner.ListDeviceProfilesAsync() for device profile enumeration#325

Open
rmarinho wants to merge 2 commits intomainfrom
features/321-list-device-profiles
Open

Add AvdManagerRunner.ListDeviceProfilesAsync() for device profile enumeration#325
rmarinho wants to merge 2 commits intomainfrom
features/321-list-device-profiles

Conversation

@rmarinho
Copy link
Copy Markdown
Member

@rmarinho rmarinho commented Apr 8, 2026

Summary

Add a method to enumerate available AVD device profiles (hardware definitions) using avdmanager list device --compact.

Uses the --compact flag for clean, script-friendly output (one device ID per line) instead of the verbose multi-line format.

Changes

  • Added AvdDeviceProfile record (Id) in Models/
  • Added AvdManagerRunner.ListDeviceProfilesAsync() — runs avdmanager list device --compact and parses output
  • Internal ParseCompactDeviceListOutput() static method for testability
  • 5 unit tests covering multiple profiles, empty output, Windows newlines, blank lines
  • Updated PublicAPI.Unshipped.txt for both net10.0 and netstandard2.0

Closes #321

Copilot AI review requested due to automatic review settings April 8, 2026 16:35
Copy link
Copy Markdown
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

Adds first-class support in Xamarin.Android.Tools.AndroidSdk for enumerating AVD device profiles (hardware definitions) by running avdmanager list device, returning strongly-typed results for consumers (IDE extensions, GUI tools, CLIs).

Changes:

  • Introduced AvdDeviceProfile record model (Id, Name, Oem, Tag).
  • Added AvdManagerRunner.ListDeviceProfilesAsync() plus ParseDeviceListOutput() to parse avdmanager list device output.
  • Added unit tests for parsing behavior across multiple profiles, empty/header-only output, missing name fallback, and Windows newlines; updated PublicAPI unshipped entries for both TFMs.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/Xamarin.Android.Tools.AndroidSdk-Tests/AvdManagerRunnerTests.cs Adds parsing-focused unit tests for device profile enumeration.
src/Xamarin.Android.Tools.AndroidSdk/Runners/AvdManagerRunner.cs Implements the new API to run avdmanager list device and parse results.
src/Xamarin.Android.Tools.AndroidSdk/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt Declares the new public API surface for netstandard2.0.
src/Xamarin.Android.Tools.AndroidSdk/PublicAPI/net10.0/PublicAPI.Unshipped.txt Declares the new public API surface for net10.0.
src/Xamarin.Android.Tools.AndroidSdk/Models/AvdDeviceProfile.cs Adds the new public model type representing a device profile.

Comment thread src/Xamarin.Android.Tools.AndroidSdk/Runners/AvdManagerRunner.cs Outdated
@rmarinho rmarinho force-pushed the features/321-list-device-profiles branch from 02bb295 to 8b87399 Compare April 30, 2026 13:04
@rmarinho rmarinho requested a review from Copilot April 30, 2026 13:22
@jonathanpeppers

This comment was marked as outdated.

Copy link
Copy Markdown
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

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Comment on lines +125 to +129
/// <summary>
/// Lists available device profiles (hardware definitions) using <c>avdmanager list device --compact</c>.
/// </summary>
public async Task<IReadOnlyList<AvdDeviceProfile>> ListDeviceProfilesAsync (CancellationToken cancellationToken = default)
{
Comment on lines +6 to +9
/// <summary>
/// Represents a hardware device profile (e.g., "pixel_7", "Nexus 5X") from <c>avdmanager list device --compact</c>.
/// </summary>
public record AvdDeviceProfile (string Id);
Comment on lines +202 to +206
Xamarin.Android.Tools.AvdManagerRunner.ListDeviceProfilesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Xamarin.Android.Tools.AvdDeviceProfile!>!>!
Xamarin.Android.Tools.AvdDeviceProfile
Xamarin.Android.Tools.AvdDeviceProfile.AvdDeviceProfile(string! Id) -> void
Xamarin.Android.Tools.AvdDeviceProfile.Id.get -> string!
Xamarin.Android.Tools.AvdDeviceProfile.Id.init -> void
Comment on lines +202 to +206
Xamarin.Android.Tools.AvdManagerRunner.ListDeviceProfilesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Xamarin.Android.Tools.AvdDeviceProfile!>!>!
Xamarin.Android.Tools.AvdDeviceProfile
Xamarin.Android.Tools.AvdDeviceProfile.AvdDeviceProfile(string! Id) -> void
Xamarin.Android.Tools.AvdDeviceProfile.Id.get -> string!
Xamarin.Android.Tools.AvdDeviceProfile.Id.init -> void
Comment thread tests/Xamarin.Android.Tools.AndroidSdk-Tests/AvdManagerRunnerTests.cs Outdated
…meration

Add ListDeviceProfilesAsync() and ParseDeviceListOutput() to
AvdManagerRunner. Runs 'avdmanager list device' and parses the output
into AvdDeviceProfile records (Id, Name, Oem, Tag).

Includes AvdDeviceProfile record model, 6 unit tests, and PublicAPI
entries for both net10.0 and netstandard2.0.

Closes #321

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho force-pushed the features/321-list-device-profiles branch from 8b87399 to ca2c633 Compare April 30, 2026 13:26
@jonathanpeppers
Copy link
Copy Markdown
Member

/review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

Android Tools PR Reviewer completed successfully!

jonathanpeppers added a commit that referenced this pull request Apr 30, 2026
The gh-aw safe_outputs framework requires at least one
create_pull_request_review_comment before submit_pull_request_review
will work. When the reviewer gives a clean LGTM with no inline
comments, the review silently fails with "No review context set."

Update the workflow prompt and SKILL.md to require at least one
inline comment on every review, even for clean PRs.

### Example

- PR that triggered the bug: #325
- Broken workflow run: https://github.com/dotnet/android-tools/actions/runs/25168175699
  - See the `safe_outputs` → `Process Safe Outputs` step: `"Submitting PR review (body-only, no inline comments)"` → `"No review context set - cannot submit review"`
- Completion comment (with no actual review posted): #325 (comment)

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

/review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

Android Tools PR Reviewer completed successfully!

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ LGTM — Clean, well-structured addition

Summary: Adds ListDeviceProfilesAsync() to AvdManagerRunner and a companion AvdDeviceProfile record, with solid test coverage.

Positives:

  • Follows existing patterns exactly: ProcessUtils.CreateProcessStartInfo, StartProcess, ThrowIfFailed, logger invocation — mirrors ListAvdsAsync and DeleteAvdAsync.
  • AvdDeviceProfile is a positional record in its own file under Models/ — matches AvdInfo, SdkPackage, etc.
  • Parser is internal static for testability without exposing implementation detail.
  • Return type is IReadOnlyList<T> — correct per API design conventions.
  • ThrowIfFailed includes both stderr and stdout — actually improves on the older ListAvdsAsync pattern.
  • PublicAPI files updated for both net10.0 and netstandard2.0.
  • Tests cover multiple profiles, empty output, Windows \r\n newlines, blank lines, and return type — good coverage.
  • init accessor on netstandard2.0 works via the existing IsExternalInit.cs polyfill.

CI: license/cla ✅ passed. No build/test CI runs visible on this check — ensure the full build pipeline passes before merge.

No issues found. One 💡 observation posted inline about a positive pattern worth backporting.

Generated by Android Tools PR Reviewer for issue #325 · ● 1.6M

logger.Invoke (TraceLevel.Verbose, "Running: avdmanager list device --compact");
var exitCode = await ProcessUtils.StartProcess (psi, stdout, stderr, cancellationToken, environmentVariables).ConfigureAwait (false);

ProcessUtils.ThrowIfFailed (exitCode, "avdmanager list device --compact", stderr, stdout);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 💡 Pattern — Nice: passing both stderr and stdout to ThrowIfFailed follows the recommended convention for including all output in error diagnostics. Worth noting that the existing ListAvdsAsync (line 46) only passes stderr — a follow-up PR could bring it in line with this improved pattern.

Rule: Include stdout in error diagnostics (Postmortem #48)

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.

Add AvdManagerRunner.ListDeviceProfilesAsync() for AVD device profile enumeration

3 participants