镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[Xamarin.Installer.Build.Tasks] Use Android CLI to install SDK packages - #13513

Merged
simonrozsival merged 6 commits into
mainfrom
jonathanpeppers-android-cli-license
Nov 13, 2026
Merged

simonrozsival merged 6 commits into
mainfrom
jonathanpeppers-android-cli-license

Conversation

@jonathanpeppers

@jonathanpeppers jonathanpeppers commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

The InstallAndroidDependencies target used our own copy of the Android SDK manager (Xamarin.Installer.AndroidSDK and Xamarin.Installer.Common) to read the Xamarin manifest, download archives, and extract them. That is a lot of code to maintain. Google now ships the Android CLI, which does the same job.

This PR removes both projects. InstallAndroidDependencies now:

  1. Downloads a pinned Android CLI from dl.google.com.
  2. Checks its SHA-256 against the hashes in Xamarin.Installer.Common.targets.
  3. Caches it in dotnet-android/AndroidCli/<version>, in the same per-user cache folder as $(MavenCacheDirectory). For example, on Windows this is %LOCALAPPDATA%\dotnet-android\AndroidCli\<version>.
  4. Runs android sdk install.

After the CLI exits, the task checks the SDK again, because the CLI can exit with 0 for an unknown package.

JDK installation stays. A simplified JavaDependencyInstaller is copied from the removed project, and it now downloads from aka.ms/download-jdk. OpenJDK signature verification (XA5305) does not change.

The Android CLI accepts the Android SDK licenses without a prompt. Thus $(AcceptAndroidSDKLicenses) is the only consent, and its error message now links to the Android SDK License Agreement.

These properties are removed: $(AndroidManifestType), $(AndroidManifestSource), and $(_AndroidIgnoreSdkArchiveChecksumErrors). The docs list them as removed in .NET 12.

Known limitation: Google does not ship a Windows Arm64 build of the Android CLI, so on Windows Arm64 the task reports an unsupported platform error.

Testing

With a local SDK build on Windows x64:

dotnet test bin\TestDebug\net11.0\Xamarin.Android.Build.Tests.dll --filter "FullyQualifiedName~AndroidDependenciesTests|FullyQualifiedName~OpenJdkSignatureTests"

Result: passed, 73 of 73. This includes a new test that checks the arguments passed to a fake Android CLI. The run downloaded the Android CLI to %LOCALAPPDATA%\dotnet-android\AndroidCli\1.1.16717390\android-cli.exe.

I also ran android sdk install platform-tools into an empty folder by hand. The CLI wrote licenses/android-sdk-license and did not show a prompt.

The `InstallAndroidDependencies` target used our own copy of the
Android SDK manager (`Xamarin.Installer.AndroidSDK` and
`Xamarin.Installer.Common`) to read the Xamarin manifest, download
archives, and extract them.  This is a lot of code to maintain, and
Google now ships the Android CLI, which does the same job.

Remove both projects.  `InstallAndroidDependencies` now downloads a
pinned Android CLI from dl.google.com, checks its SHA-256 against
hashes in `Xamarin.Installer.Common.targets`, caches it under
`LocalApplicationData/Android/android-cli/<version>`, and runs
`android sdk install`.  After the CLI exits, the task checks the SDK
again, because the CLI can exit with 0 for an unknown package.

JDK installation stays.  A simplified `JavaDependencyInstaller` is
copied from the removed project, and it now downloads from
aka.ms/download-jdk.  OpenJDK signature verification (XA5305) does
not change.

The Android CLI accepts the Android SDK licenses without a prompt,
so `$(AcceptAndroidSDKLicenses)` is the only consent.  The error
message now links to the Android SDK License Agreement.

`$(AndroidManifestType)`, `$(AndroidManifestSource)`, and
`$(_AndroidIgnoreSdkArchiveChecksumErrors)` are removed.  The docs
list them as removed in .NET 12.

Google does not ship a Windows Arm64 build of the Android CLI, so
the task reports an unsupported platform error there.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 11, 2026 22:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Clean SDK packaging still references an INIFileParser.dll dependency that is no longer produced, while new failures lack coded diagnostics and Windows cancellation can still replace the existing JDK.

3 open issues
What changed in this PR

This PR replaces the legacy Xamarin SDK installer with Google’s Android CLI, reducing the SDK-management code maintained by .NET for Android while retaining JDK installation and signature verification.

Changes:

  • Configures a pinned, SHA-256-verified Android CLI and updates installation diagnostics and license-consent documentation.
  • Removes the legacy installer projects, supporting models and parsers, and associated build dependencies.
  • Introduces a simplified JDK installer and updates tests, workload-feed references, and contributor guidance.
File Description
tools/​workload-dependencies/​WorkloadDependencies.proj Uses the relocated workload manifest feed.
tests/​Xamarin.Android.Tools.AndroidSdk-Tests/​Xamarin.Android.Tools.AndroidSdk-Tests.csproj Removes legacy installer and ZIP dependencies.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​XmlElementExtensions.cs Removes legacy XML helpers.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​OperationStatus.cs Removes legacy operation status.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​Log.cs Removes legacy logging infrastructure.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​InstallationProgressEventArgs.cs Removes legacy progress events.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​ILogAdapter.cs Removes legacy logging interfaces.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​Extensions.Version.cs Removes legacy version helpers.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​Extensions.String.cs Removes legacy string helpers.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common/​Extensions.cs Removes shared installer extensions.
src/​Xamarin.Installer.Common/​Xamarin.Installer.Common.csproj Removes the common installer project.
src/​Xamarin.Installer.Common/​Properties/​Resources.Designer.cs Removes legacy resource accessors.
src/​Xamarin.Installer.Common/​Properties/​AssemblyInfoTemplate.tt Removes assembly metadata generation template.
src/​Xamarin.Installer.Common/​Properties/​AssemblyInfoTemplate.cs Removes generated assembly metadata.
src/​Xamarin.Installer.Common/​Properties/​AssemblyInfo.cs Removes common installer assembly attributes.
src/​Xamarin.Installer.Build.Tasks/​Xamarin.Installer.Common.targets Supplies CLI pins, hashes, and task parameters.
src/​Xamarin.Installer.Build.Tasks/​Xamarin.Installer.Common.props Removes the legacy feed-version default.
src/​Xamarin.Installer.Build.Tasks/​Xamarin.Installer.Build.Tasks.csproj Replaces legacy references with shared Android tooling.
src/​Xamarin.Installer.Build.Tasks/​Properties/​Resources.resx Updates license guidance and CLI failure messages.
src/​Xamarin.Installer.Build.Tasks/​Properties/​Resources.Designer.cs Updates installation resource accessors.
src/​Xamarin.Installer.Build.Tasks/​JavaDependencyInstaller.cs Adds standalone Microsoft JDK download and extraction support.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Xamarin/​XamarinPackage.cs Removes Xamarin package representation.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​ParserErrorLevel.cs Removes parser error levels.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​MonitorWithTotalProgress.cs Removes legacy progress aggregation.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​LocalManifestProvider.cs Removes manifest caching infrastructure.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​JavaDependencyInstaller.cs Removes the manifest-backed JDK installer.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​IProgressMonitor.cs Removes installer progress interfaces.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Helpers.cs Removes manifest parsing helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​RemotePackageMetadata.cs Removes remote package metadata.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsSystemImageParser.cs Removes system-image metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsSourceParser.cs Removes source-package metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsPlatformParser.cs Removes platform metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsParser.cs Removes shared type-detail parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsMavenParser.cs Removes Maven metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsGenericParser.cs Removes generic package metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsExtraParser.cs Removes extra-package metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​TypeDetailsAddOnParser.cs Removes add-on metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​RevisionParser.cs Removes manifest revision parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​RepositoryParser.cs Removes repository manifest parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​ParserContext.cs Removes shared parser context.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​PackageVendorParser.cs Removes vendor metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​PackageTagParser.cs Removes package-tag parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​LicenseParser.cs Removes license metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​LibraryParser.cs Removes individual library parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​LibrariesParser.cs Removes library-list parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​ElementParser.cs Removes the shared XML parser base.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​DependencyParser.cs Removes individual dependency parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​DependenciesParser.cs Removes dependency-list parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​ArchivesParser.cs Removes archive-list parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​ArchivePatchParser.cs Removes individual archive-patch parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​ArchivePatchesParser.cs Removes archive-patch list parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​ArchiveParser.cs Removes archive metadata parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​ArchiveMetadataExtractor.cs Removes archive download metadata extraction.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​AddonSiteParser.cs Removes add-on site parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Parsing/​AddonList3Parser.cs Removes add-on repository-list parsing.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​IParserErrorHandler.cs Removes parser error handling interface.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​Extensions.IParserErrorHandler.cs Removes parser diagnostic helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​AddonSiteType.cs Removes add-on site classification.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​GoogleV2/​AddonSite.cs Removes the add-on site model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.XName.cs Removes XML-name helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.XElement.cs Removes XML-element helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.String.cs Removes parsing conversion helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.Properties.cs Removes installer property conversion helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.IXmlLineInfo.cs Removes XML-location formatting helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.Int32.cs Removes hash-combination helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.IListOfT.cs Removes collection comparison helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Extensions.IAndroidComponent.cs Removes component cloning helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​Platform.cs Removes legacy host-platform detection.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​PackageVendor.cs Removes package vendor model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​PackageTag.cs Removes package tag model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​PackageMetadata.cs Removes shared package metadata model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​PackageLibrary.cs Removes package library model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​License.cs Removes package license model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​JdkPackage.cs Removes manifest-backed JDK package model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​JdkArchive.cs Removes legacy JDK archive model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​ItemWithIDAndDisplay.cs Removes named-item base class.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​ItemWithID.cs Removes identifier-based model base class.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​ILicensesStorage.cs Removes legacy license storage interface.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​IJdkComponent.cs Removes JDK component interface.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​IArchive.cs Removes archive metadata interface.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​IAndroidComponentInternal.cs Removes internal component lifecycle interface.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​IAndroidApiLevel.cs Removes component API-level interface.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​HttpClientProvider.cs Removes legacy HTTP client provider.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​Dependency.cs Removes package dependency model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​Constants.cs Removes legacy component constants.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​ConfigManager.cs Removes SDK manager configuration storage.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​Channel.cs Removes repository channel model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​ArchivePatch.cs Removes archive patch model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​ArchiveBase.cs Removes shared archive model base.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​AndroidComponentStatusChangeEventArgs.cs Removes component status events.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​AndroidComponentStatus.cs Removes component lifecycle statuses.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​AndroidComponentInfoSource.cs Removes source-package component metadata.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​AndroidComponentInfoMaven.cs Removes Maven component metadata.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​AndroidComponentInfoGeneric.cs Removes generic component metadata.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​Common/​AndroidComponentInfoExtra.cs Removes extra-package component metadata.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidSystemImageAbi.cs Removes legacy system-image architecture enumeration.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidSDKPlatform.cs Removes installer platform enumeration.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidSDKContext.cs Removes global installer context.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidSDKComponentInstallationResult.cs Removes legacy installation result model.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidManifestType.cs Removes manifest-provider selection enumeration.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidExtensions.cs Removes legacy package revision helpers.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidComponentType.cs Removes component type enumeration.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK/​AndroidAddonDependencyInfo.cs Removes add-on dependency metadata.
src/​Xamarin.Installer.AndroidSDK/​Xamarin.Installer.AndroidSDK.csproj Removes the legacy Android SDK installer project.
src/​Xamarin.Installer.AndroidSDK/​Properties/​Resources.Designer.cs Removes SDK installer resource accessors.
src/​Xamarin.Installer.AndroidSDK/​Properties/​AssemblyInfo.cs Removes SDK installer assembly attributes.
src/​Xamarin.Installer.AndroidSDK/​CodeGenerator.targets Removes legacy component-version generation.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Xamarin.Android.Build.Tests.csproj Removes the legacy installer test reference.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​OpenJdkSignatureTests.cs Adapts signature tests to the replacement archive type.
Microsoft.Android.slnx Removes deleted installer projects from the solution.
Documentation/​guides/​InstallBuildsFromMain.md Removes the obsolete manifest-selection argument.
Documentation/​docs-mobile/​building-apps/​build-targets.md Documents CLI installation, consent, and directory defaults.
Documentation/​docs-mobile/​building-apps/​build-properties.md Marks manifest-selection properties as removed.
Directory.Build.props Removes warning exemptions for deleted projects.
build-tools/​installers/​create-installers.targets Removes legacy installer and ZIP-library package entries.
.github/​skills/​update-androidsdk-packages/​SKILL.md Updates the manifest-feed path in maintenance guidance.
.github/​skills/​update-androidsdk-packages/​references/​package-catalog.md Updates the command-line-tools manifest-feed reference.

Review effort: Balanced

Use the same per-user cache locations as `$(MavenCacheDirectory)`
instead of a generic `Android/android-cli` directory:

  * Windows: `%LOCALAPPDATA%\dotnet-android\AndroidCli\<version>`
  * macOS: `~/Library/Caches/dotnet-android/AndroidCli/<version>`
  * Linux: `~/.cache/dotnet-android/AndroidCli/<version>`

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers and others added 4 commits November 12, 2026 08:25
…o original

Use the same member order, names, and structure as the original
`JavaDependencyInstaller` from `Xamarin.Installer.AndroidSDK`.
`GetJdkRevision()` again returns `false` when `JAVA_VERSION` is
missing, and `tar` again runs in the extract directory.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ixes

aka.ms sends an unknown JDK link to an HTML page on bing.com with
status 200.  The task then downloaded that page, and the signature
check failed with a misleading XA5305 error.
`GetFirstValidJdkArchiveWithVersion()` now reads the response headers
first and returns `null` for an error status or an HTML page.  The
task then reports `Invalid_JavaSdkVersion`, as the old manifest-based
code did.

Also:

  * Check cancellation before `RemoveJdk()`, so a canceled build keeps
    the existing JDK.
  * Remove `INIFileParser.dll` from packaging and signing, and remove
    `$(IniParserNetstandardVersion)`.  Only the removed
    `Xamarin.Installer.AndroidSDK` project used it.
  * Explain why the JDK is extracted next to `JdkPath`.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The new Android CLI errors used uncoded `LogError()`, so they had no
diagnostic code or documentation page.  Report them with
`LogCodedError()`:

  * XA5306: The Android CLI is not available for this operating
    system and architecture.
  * XA5307: The SHA-256 hash of the downloaded Android CLI is not
    correct.
  * XA5308: The Android CLI failed while it installed Android SDK
    packages.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…id-cli-license

# Conflicts:
#	build-tools/installers/create-installers.targets
#	src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK.csproj
#	src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/AndroidUtilities.cs
#	src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/LocalSDK/LocalSDKRepository.cs
#	tests/Xamarin.Android.Tools.AndroidSdk-Tests/AndroidSdkInstallerTests.cs
@simonrozsival
simonrozsival merged commit ec3c1cc into main Nov 13, 2026
40 checks passed
@simonrozsival
simonrozsival deleted the jonathanpeppers-android-cli-license branch November 13, 2026 10:02
simonrozsival added a commit that referenced this pull request Nov 13, 2026
…MABT

Context: #12981
Context: https://devblogs.microsoft.com/dotnet/process-api-improvements-in-dotnet-11/
Context: https://learn.microsoft.com/visualstudio/msbuild/update-task-multithreaded

After #13513, `InstallAndroidDependencies` installs SDK packages with Google's Android CLI, but it still lived in the netstandard2.0 `Xamarin.Installer.Build.Tasks.dll`. There it had to start the Android CLI, `/usr/bin/tar`, and `chmod` through `ProcessUtils`, and it could not run in multithreaded MSBuild (`-mt`).

Move the task, `JavaDependencyInstaller`, and `OpenJdkSignatureVerifier` into `Microsoft.Android.Build.Tasks.dll`, which runs on .NET:

  * Register the task with the paired Full/Core `Runtime="NET"` `<UsingTask/>`. MABT links the existing localized messages and deploys `Xamarin.Installer.Common.props` and `.targets` to `tools`, so `Xamarin.Android.Common.targets` and the localization files are unchanged. Remove `Xamarin.Installer.Build.Tasks.csproj`.
  * Run the Android CLI with `Process.ReadAllLinesAsync()` and `WaitForExitAsync()`, keeping only the tail of its output as before, and kill its process tree when the task fails or is canceled. Extract JDK `.tar.gz` archives with `TarFile`, and mark the downloaded Android CLI executable with `File.SetUnixFileMode()`.
  * Derive from `MultithreadedAndroidTask` with `[MSBuildMultiThreadableTask]` and `ICancelableTask`. `RunTask()` runs the existing async workflow on the thread pool and forwards log messages to the thread that called `Execute()`, as `AsyncTask` did. Environment variables, the child process start info, and all paths come from `TaskEnvironment`; resolved paths are passed around as `AbsolutePath`. The default SDK and JDK locations come from the task's `LOCALAPPDATA` or `HOME`.

Three analyzer findings are suppressed with justifications: `Process.Start()` (its `ProcessStartInfo` comes from `TaskEnvironment.GetProcessStartInfo()`), `Path.GetTempFileName()` (no `TaskEnvironment` alternative yet), and `Environment.GetFolderPath(ProgramFiles)` (a machine location).

`OpenJdkSignatureTests` and the unit tests that create the task move to the net12.0 `Microsoft.Android.Build.Tasks.Tests`. The fake Android CLI test now also checks that a relative `AndroidSdkPath` resolves against the project directory and that messages are logged on the `Execute()` thread.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival added a commit that referenced this pull request Nov 13, 2026
…MABT

Context: #12981
Context: https://devblogs.microsoft.com/dotnet/process-api-improvements-in-dotnet-11/
Context: https://learn.microsoft.com/visualstudio/msbuild/update-task-multithreaded

After #13513, `InstallAndroidDependencies` installs SDK packages with Google's Android CLI, but it still lived in the netstandard2.0 `Xamarin.Installer.Build.Tasks.dll`. There it had to start the Android CLI, `/usr/bin/tar`, and `chmod` through `ProcessUtils`, and it could not run in multithreaded MSBuild (`-mt`).

Move the task, `JavaDependencyInstaller`, and `OpenJdkSignatureVerifier` into `Microsoft.Android.Build.Tasks.dll`, which runs on .NET:

  * Register the task with the paired Full/Core `Runtime="NET"` `<UsingTask/>`. MABT links the existing localized messages and deploys `Xamarin.Installer.Common.props` and `.targets` to `tools`, so `Xamarin.Android.Common.targets` and the localization files are unchanged. Remove `Xamarin.Installer.Build.Tasks.csproj`.
  * Run the Android CLI with `Process.ReadAllLinesAsync()` and `WaitForExitAsync()`, keeping only the tail of its output as before, and kill its process tree when the task fails or is canceled. Extract JDK `.tar.gz` archives with `TarFile`, and mark the downloaded Android CLI executable with `File.SetUnixFileMode()`.
  * Derive from `MultithreadedAndroidTask` with `[MSBuildMultiThreadableTask]` and `ICancelableTask`. `RunTask()` runs the existing async workflow on the thread pool and forwards log messages to the thread that called `Execute()`, as `AsyncTask` did. Environment variables, the child process start info, and all paths come from `TaskEnvironment`; resolved paths are passed around as `AbsolutePath`. The default SDK and JDK locations come from the task's `LOCALAPPDATA` or `HOME`.

Three analyzer findings are suppressed with justifications: `Process.Start()` (its `ProcessStartInfo` comes from `TaskEnvironment.GetProcessStartInfo()`), `Path.GetTempFileName()` (no `TaskEnvironment` alternative yet), and `Environment.GetFolderPath(ProgramFiles)` (a machine location).

`OpenJdkSignatureTests` and the unit tests that create the task move to the net12.0 `Microsoft.Android.Build.Tasks.Tests`. The fake Android CLI test now also checks that a relative `AndroidSdkPath` resolves against the project directory and that messages are logged on the `Execute()` thread.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival added a commit that referenced this pull request Nov 13, 2026
Coxntext: #13513

The legacy Android SDK installer used `Mono.Unix.Native.Syscall.chmod` to set file permissions. #13513 removed that installer in favor of the Android CLI, removing the last product call to Mono.Unix. The shared MSBuild references still restore the package, and the build still copies and packages its managed and native libraries even though there are no remaining callers.

Remove the package reference and version properties, the native-library copy and macOS universal-library build, the SDK packaging and signing entries, and the obsolete configuration and test import. This removes the dependency; it does not replace all Unix interop with .NET APIs. Existing libc and `chmod` uses remain unchanged.
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.

3 participants