Skip to content

Replace AndroidSdk NuGet with Xamarin.Android.Tools.AndroidSdk from dotnet/android-tools #141

@rmarinho

Description

@rmarinho

Summary

Migrate from the AndroidSdk + AndroidSdk.Adbd NuGet packages (v0.35.1, from redth/android-tools) to the official Xamarin.Android.Tools.AndroidSdk NuGet from dotnet/android-tools. This aligns MauiSherpa with the same Android tooling library used by the official maui CLI (dotnet/maui-labs).

Motivation

  • Single source of truth: dotnet/android-tools is the official Microsoft-maintained package used by dotnet/android and the maui CLI
  • Feature parity: The official package now includes SdkManager, AvdManagerRunner, EmulatorRunner, AdbRunner, JdkInfo, and JdkInstaller — covering all the functionality we currently get from the AndroidSdk NuGet
  • Bonus features: License acceptance API, JDK installation, SDK bootstrapping with progress, structured error results

Migration Plan

Phase 1: Core NuGet Swap (no blocking issues)

Replace AndroidSdk NuGet → Xamarin.Android.Tools.AndroidSdk in MauiSherpa.Core.csproj.

Rewrite AndroidSdkService.cs to use the new API:

Current (AndroidSdk) New (Xamarin.Android.Tools.AndroidSdk)
new AndroidSdkManager() new AndroidSdkInfo(sdkPath:, javaSdkPath:) + new SdkManager()
sdkManager.SdkManager.List() SdkManager.ListAsync()(Installed, Available)
sdkManager.SdkManager.Install(pkg) SdkManager.InstallAsync([pkg])
sdkManager.SdkManager.Uninstall(pkg) SdkManager.UninstallAsync([pkg])
sdkManager.Adb.GetDevices() AdbRunner.GetDevicesAsync()
sdkManager.Adb.EmuKill(serial) AdbRunner.StopEmulatorAsync(serial)
sdkManager.AvdManager.ListAvds() AvdManagerRunner.GetAvdsAsync()
sdkManager.AvdManager.Create(...) AvdManagerRunner.CreateAvdAsync(...)
sdkManager.AvdManager.Delete(name) AvdManagerRunner.DeleteAvdAsync(name)
sdkManager.Emulator.Start(avd, opts) EmulatorRunner.BootAsync(avd, EmulatorBootOptions)
sdkManager.Acquire() SdkManager.BootstrapAsync(targetPath)

Rewrite OpenJdkSettingsService.cs:

Current New
JdkLocator().LocateJdk() JdkInfo.GetKnownSystemJdkInfos() / GetSupportedJdkInfos()

Model mapping:

Current New
SdkPackageInfo SdkPackage (same fields)
DeviceInfo(Serial, State, Model, IsEmulator) AdbDeviceInfo (richer — has AvdName, Product, TransportId)
AvdInfo(Name, Device, Path, Target, BasedOn, Properties) AvdInfo(Name, DeviceProfile, Path) (simpler)

Phase 2: Handle Gaps (blocked on upstream issues)

Three features need upstream additions to dotnet/android-tools:

  1. Device profile listingAdd AvdManagerRunner.ListDeviceProfilesAsync() for AVD device profile enumeration dotnet/android-tools#321

    • Workaround: Parse avdmanager list device output directly (same as maui-labs CLI does)
  2. Skin enumerationAdd AVD skin enumeration API dotnet/android-tools#322

    • Workaround: Scan \/skins/ directory
  3. Real-time ADB device trackingAdd ADB device tracking (host:track-devices) for real-time device monitoring dotnet/android-tools#323

    • Workaround: Keep AndroidSdk.Adbd temporarily for just the watcher, OR poll AdbRunner.GetDevicesAsync() on a timer, OR reimplement the ~185-line ADB socket client

Phase 3: New Features (bonus)

Leverage new APIs not available in current AndroidSdk NuGet:

  • Add license acceptance UI (SdkManager.AcceptLicensesAsync())
  • Add JDK installation (JdkInstaller)
  • Use structured EmulatorBootResult (error classification)
  • Use SdkManager.BootstrapAsync() with progress reporting

Files to Modify

  • src/MauiSherpa.Core/MauiSherpa.Core.csproj — swap package references
  • src/MauiSherpa.Core/Services/AndroidSdkService.cs — main rewrite (~600 lines)
  • src/MauiSherpa.Core/Services/OpenJdkSettingsService.cs — JDK detection rewrite
  • src/MauiSherpa.Core/Services/AdbDeviceWatcherService.cs — depends on Phase 2 decision
  • src/MauiSherpa.Core/Interfaces.cs — update model records if needed
  • src/MauiSherpa.Core/Handlers/Android/*.cs — update handler return type mappings

Upstream Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions