Skip to content

Add AVD skin enumeration API#326

Open
rmarinho wants to merge 2 commits intomainfrom
features/322-list-avd-skins
Open

Add AVD skin enumeration API#326
rmarinho wants to merge 2 commits intomainfrom
features/322-list-avd-skins

Conversation

@rmarinho
Copy link
Copy Markdown
Member

@rmarinho rmarinho commented Apr 8, 2026

Summary

Add a method to list available Android emulator skins from the SDK's skins/ directory and system image skin directories.

Changes

  • Added AvdManagerRunner.ListAvdSkinsAsync(sdkPath) static method
  • Scans <sdk>/skins/ for standalone skins
  • Scans <sdk>/system-images/<api>/<tag>/<abi>/skins/ for bundled skins
  • Returns deduplicated, sorted IReadOnlyList<string>
  • Internal EnumerateSkins() method for testability
  • 6 unit tests covering standalone skins, system image skins, deduplication, missing directories
  • Updated PublicAPI.Unshipped.txt for both net10.0 and netstandard2.0

Related

Closes #322

Add AvdManagerRunner.ListAvdSkinsAsync() static method to enumerate
available AVD skins from the SDK skins/ directory and system image
skin directories. Returns a deduplicated, sorted list of skin names.

Includes 6 unit tests with temp directory structures and PublicAPI
entries for both net10.0 and netstandard2.0.

Closes #322

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 8, 2026 16:38
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 a new AvdManagerRunner API to enumerate available Android emulator skins by scanning the Android SDK install, enabling tooling (IDE/extensions/CLI) to offer skin selection when creating AVDs.

Changes:

  • Added AvdManagerRunner.ListAvdSkinsAsync(sdkPath) plus internal EnumerateSkins() implementation.
  • Added NUnit coverage for standalone skins, system image skins, sorting/deduping, and invalid inputs.
  • Updated PublicAPI.Unshipped.txt for netstandard2.0 and net10.0.

Reviewed changes

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

File Description
tests/Xamarin.Android.Tools.AndroidSdk-Tests/AvdManagerRunnerTests.cs Adds unit tests validating skin enumeration behavior and input validation.
src/Xamarin.Android.Tools.AndroidSdk/Runners/AvdManagerRunner.cs Implements skin enumeration and exposes the new public API.
src/Xamarin.Android.Tools.AndroidSdk/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt Declares the new public API for netstandard2.0.
src/Xamarin.Android.Tools.AndroidSdk/PublicAPI/net10.0/PublicAPI.Unshipped.txt Declares the new public API for net10.0.

- Rename ListAvdSkinsAsync → ListAvdSkins (synchronous API that
  doesn't hide sync I/O behind Task.FromResult)
- Check CancellationToken during directory enumeration loops
- Catch IOException/UnauthorizedAccessException per subtree so one
  bad directory doesn't fail the entire listing
- Fix doc comment to mention system-images scan
- Update PublicAPI files and tests to match new signature

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 4 out of 4 changed files in this pull request and generated 2 comments.

Comment on lines +125 to +133
/// <summary>
/// Lists available AVD skins by scanning the SDK <c>skins/</c> directory
/// and <c>system-images/.../skins/</c> directories.
/// </summary>
/// <param name="sdkPath">Root path of the Android SDK.</param>
/// <param name="cancellationToken">Cancellation token checked during directory enumeration.</param>
/// <returns>Sorted list of unique skin directory names.</returns>
public static IReadOnlyList<string> ListAvdSkins (string sdkPath, CancellationToken cancellationToken = default)
{
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

PR description says the new API is ListAvdSkinsAsync(sdkPath) but the implementation adds a synchronous ListAvdSkins(...) method. Either update the PR description/issues to match the shipped API, or rename/shape the API to match the intended async contract so consumers aren’t surprised.

Copilot uses AI. Check for mistakes.
Comment on lines +148 to +158
// System image skins: <sdk>/system-images/<api>/<tag>/<abi>/skins/<skinName>/
var systemImagesDir = Path.Combine (sdkPath, "system-images");
if (Directory.Exists (systemImagesDir)) {
try {
foreach (var apiDir in Directory.EnumerateDirectories (systemImagesDir)) {
cancellationToken.ThrowIfCancellationRequested ();
try {
foreach (var tagDir in Directory.EnumerateDirectories (apiDir)) {
foreach (var abiDir in Directory.EnumerateDirectories (tagDir)) {
var imgSkinsDir = Path.Combine (abiDir, "skins");
AddSkinDirectories (skins, imgSkinsDir);
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

cancellationToken is documented as being checked during directory enumeration, but it’s only checked once per API directory and isn’t checked while iterating tag/ABI/skin directories (and AddSkinDirectories doesn’t observe it). Please either tighten cancellation handling (check in inner loops and/or pass the token down) or update the docs/parameter if cancellation isn’t intended to be honored for the full scan.

Copilot uses AI. Check for mistakes.
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 AVD skin enumeration API

2 participants