Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Unify Android minimum API level to 24 for all runtimes - #11331

Merged
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel
May 20, 2026
Merged

Unify Android minimum API level to 24 for all runtimes#11331
jonathanpeppers merged 16 commits into
mainfrom
dev/sbomer/apilevel

Conversation

@sbomer

Copy link
Copy Markdown
Member

Summary

Unify the Android minimum NDK API level to 24 for all runtimes (MonoVM, CoreCLR, NativeAOT), matching what dotnet/runtime already uses.

Motivation

dotnet/runtime builds all runtimes — including MonoVM — against API level 24 (AndroidApiLevelMin=24 in Directory.Build.props). The separate AndroidMinimumNonMonoApiLevel property in dotnet/android was unnecessary since the Mono .so files from runtime were already compiled at API 24 regardless. The only effect of the API 21 setting was selecting older CRT/DSO linker stubs from the NDK sysroot.

Related: dotnet/runtime#126838

Changes

  • Bump AndroidMinimumDotNetApiLevel from 21 to 24
  • Remove AndroidMinimumNonMonoApiLevel and all related properties, constants, template placeholders, and conditional logic
  • Remove nonmono-common-* CMake presets; NativeAOT/CoreCLR presets now inherit from regular common-* presets directly
  • Remove ArchToApiLevelNonMono dictionary from XABuildConfig
  • Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
  • Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
  • Remove runtime-conditional AndroidMinimumSupportedApiLevel items

sbomerand others added 2 commits May 12, 2026 14:33
dotnet/runtime builds all runtimes (MonoVM, CoreCLR, NativeAOT) against
API level 24. The separate AndroidMinimumNonMonoApiLevel property and all
NonMono-specific API level plumbing in dotnet/android was unnecessary
since MonoVM was already being compiled at API 24 by runtime.
Changes:
- Bump AndroidMinimumDotNetApiLevel from 21 to 24
- Remove AndroidMinimumNonMonoApiLevel and all related properties,
constants, template placeholders, and conditional logic
- Simplify CMake presets: nonmono-common-* now inherit from common-*
- Remove ArchToApiLevelNonMono dictionary from XABuildConfig
- Simplify MonoAndroidHelper.GetMinimumApiLevel (no runtime branching)
- Remove MinimumNonMonoApiLevel from GenerateSupportedPlatforms task
- Remove runtime-conditional AndroidMinimumSupportedApiLevel items
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
Remove the nonmono-common-* preset definitions (now redundant) and
update all consumers to inherit from common-arm64-v8a / common-x86_64
directly.
Related: dotnet/runtime#126838
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
CopilotAI review requested due to automatic review settings May 12, 2026 21:40

CopilotAI 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.

Pull request overview

This PR unifies the Android minimum NDK/API level to 24 across all runtimes (MonoVM, CoreCLR, NativeAOT) and removes the now-redundant “non-mono” minimum API level plumbing throughout build tasks, templates, and native CMake presets.

Changes:

  • Bump AndroidMinimumDotNetApiLevel default from 21 → 24 and remove AndroidMinimumNonMonoApiLevel.
  • Remove runtime-conditional min-API selection (MSBuild item conditions, GenerateSupportedPlatforms conditional output, XABuildConfig non-mono maps, helper branching).
  • Simplify native preset inheritance by dropping nonmono-common-* CMake presets and inheriting from standard common-* presets.
Show a summary per file
FileDescription
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.inRemoves runtime-conditional min API items and uses unified NDK API placeholders.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targetsRemoves placeholder replacements and task inputs tied to non-mono min API.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.csSimplifies minimum API lookup to a single architecture→API mapping.
src/native/CMakePresets.json.inDrops nonmono-common-* presets; CoreCLR/NativeAOT inherit from common-* directly.
Configuration.propsSets unified default AndroidMinimumDotNetApiLevel to 24 and removes non-mono property.
build-tools/xaprepare/xaprepare/xaprepare.targetsRemoves generation-time placeholder replacement for the non-mono min API property.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.csRemoves non-mono placeholder generation for presets/build config/projitems.
build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.csRemoves non-mono min API accessor; uses unified min API.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.inRemoves default property wiring for AndroidMinimumNonMonoApiLevel.
build-tools/xaprepare/xaprepare/Application/KnownProperties.csRemoves AndroidMinimumNonMonoApiLevel constant.
build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateSupportedPlatforms.csRemoves non-mono conditional output generation for supported platforms.
build-tools/scripts/XABuildConfig.cs.inRemoves non-mono minimum API version and non-mono arch→API dictionary.
build-tools/scripts/Ndk.projitems.inRemoves non-mono API-level properties/metadata from NDK projitems.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 1

Comment threadsrc/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
Member

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24
The branch dev/sbomer/apilevel appears to raise the minimum supported Android API level from 23 to 24. This causes widespread failures:
MAUI Integration build fails with XA4216 because MAUI projects still set SupportedOSPlatformVersion to 23.
Hundreds of MSBuild unit tests fail because test projects build with the default (old) minimum API level and hit FailedBuildException.
Windows Build & Smoke Test has untracked .sarif files from Guardian analysis.

…n tests and MAUI CI
Agent-Logs-Url: https://github.com/dotnet/android/sessions/cf359a88-368d-4ed1-8b97-2b96b4b3a8d5
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

@copilot CI is failing with this root cause analysis, fix it:

Root Cause: Minimum API Level Raised to 24

...

Fixed in cd8f3e8. The changes address all three CI failure categories:

  1. MSBuild unit tests — Updated default SupportedOSPlatformVersion from "21.0" to "24.0" in XamarinAndroidApplicationProject (fixes hundreds of tests that use this default), plus updated all other test files that explicitly set API levels 21/22/23: WearApplicationProject, ManifestTest.cs, PackagingTest.cs, WearTests.cs, GenerateTrimmableTypeMapTests.cs, BuildTest.cs, AndroidGradleProjectTests.cs, and TrimmableTypeMapGeneratorTests.cs. Also updated expected version codes in ManifestTest.cs for version code patterns that include {minSDK}.

  2. MAUI Integration XA4216 — Added -p:SupportedOSPlatformVersion=24 to both Debug and Release MAUI template builds in azure-pipelines.yaml to override MAUI's template default (which still sets API 23) while MAUI hasn't yet updated their minimum.

  3. NativeAOT sample and DefaultProperties.targets comment updated for consistency.

Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
Comment threadbuild-tools/automation/azure-pipelines.yaml Outdated
@sbomersbomer self-assigned this May 13, 2026
sbomerand others added 5 commits May 13, 2026 11:10
The MAUI template on the net11.0 branch (which CI checks out) already
defaults SupportedOSPlatformVersion to 24.0 for Android, so the
-p:SupportedOSPlatformVersion=24 build argument is unnecessary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With min SDK 24+, apksigner uses v2/v3 signature schemes only and skips
v1 JAR signing, so META-INF/MANIFEST.MF is no longer present in signed
APKs. Replace the ZIP entry check with an AssertApkIsSigned helper that
runs 'apksigner verify' to validate signatures regardless of scheme.
AAB signing still uses jarsigner (which always produces META-INF), so
those assertions are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
With API level 24 unified across all runtimes, the separate
redist-nativeaot directory (which copied CRT/DSO stubs from the API 24
sysroot) is redundant — the regular redist directory already uses API 24.
Remove the NativeAOT-specific copy in Step_Android_SDK_NDK, point the
NativeAOT pack at the common redist directory, and remove the
redist-nativeaot glob from native.targets.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
github-actionsBot pushed a commit to dotnet/maui that referenced this pull request May 15, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 5 commits May 15, 2026 11:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
R8 9.1.31 crashes with a NullPointerException when processing
androidx.core.core.aar (LocationManagerCompat) in the old AndroidX
packages used by Xamarin.Forms. This only manifests for NativeAOT
because it's the only runtime that runs as Release (which enables R8).
Remove NativeAOT from the test parameters entirely and simplify
the remaining code (IsRelease is always false now).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…entalClean
XamarinFormsAndroidApplicationProject uses old AndroidX packages that
trigger an R8 9.1.31 internal crash (NullPointerException processing
LocationManagerCompat). The test only validates incremental clean
behavior, not Xamarin.Forms-specific functionality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The redist-nativeaot removal (cd7f135) accidentally dropped the
toolchain library entries (crtbegin_so.o, crtend_so.o, libc++_static.a,
libc++abi.a, libclang_rt.builtins, libunwind.a) from the NativeAOT
runtime pack. These are required for NativeAOT's native linking step.
Share the toolchain entries between CoreCLR and NativeAOT since both
do native linking. Also consolidate the system lib stubs (libc.so, etc.)
into an unconditional ItemGroup since all runtimes need them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude:claude-opus-4.6-1m
sbomerand others added 2 commits May 19, 2026 11:48
The NativeAOT section in native.targets only copied .a files from the
redist directory into the runtime pack, but not .o files (crtbegin_so.o,
crtend_so.o). These CRT object files are needed by the workload-provided
linker (now the default for NativeAOT builds).
Unify the CoreCLR and NativeAOT redist copy blocks since they now use
the same redist directory and need the same file types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit to dotnet/maui that referenced this pull request May 20, 2026
dotnet/android is unifying the minimum Android API level to 24 for all
runtimes (dotnet/android#11331). Update MAUI's centralized Android
minimum in Directory.Build.targets and all project-level overrides to
match.
Note: this targets net11.0 because we don't want to bump the versions in
main.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit be30e62 into mainMay 20, 2026
2 of 3 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/sbomer/apilevel branch May 20, 2026 15:16
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 20, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sbomer@simonrozsival@jonathanpeppers