Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

[generator] Add support for emitting [UnsupportedOSPlatform]. - #1307

Merged
jonpryor merged 1 commit into
mainfrom
dev/jpobst/unsupported-os
Feb 20, 2025
Merged

[generator] Add support for emitting [UnsupportedOSPlatform].#1307
jonpryor merged 1 commit into
mainfrom
dev/jpobst/unsupported-os

Conversation

@jpobst

@jpobstjpobst commented Feb 13, 2025

Copy link
Copy Markdown
Contributor

Fixes: #1309

Sometimes, Android removes APIs. For example, API-23 removed the android.Manifest.permission.CLEAR_APP_USER_DATA field.

We still list this field, though: Android.Manifest.Permission.ClearAppUserData field

We modified api-merge to add removed-since in dotnet/android#8897.

Here is the excerpt from https://github.com/dotnet/android/blob/main/src/Mono.Android/Profiles/api-Baklava.xml:

<fielddeprecated="not deprecated"final="true"name="CLEAR_APP_USER_DATA"jni-signature="Ljava/lang/String;"static="true"transient="false"type="java.lang.String"type-generic-aware="java.lang.String"value="&quot;android.permission.CLEAR_APP_USER_DATA&quot;"visibility="public"volatile="false"removed-since="23"></field>

Modify generator to consume this information and emit UnsupportedOSPlatformAttribute ("androidXX0")] as needed for API that has been removed from Mono.Android.

Tested in dotnet/android with dotnet/android#9791.

@jpobst
jpobst marked this pull request as ready for review February 20, 2025 17:47

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Files not reviewed (4)
  • tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs: Evaluated as low risk
  • tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs: Evaluated as low risk
  • tools/generator/ApiVersionsSupport.cs: Evaluated as low risk
  • tests/generator-Tests/Unit-Tests/XmlApiImporterTests.cs: Evaluated as low risk

@jonpryor

Copy link
Copy Markdown
Contributor
Fixes: https://github.com/dotnet/java-interop/issues/1309
Context: https://github.com/dotnet/android/commit/944d30615acd0924ac9adde46fca2430c30039fb
Sometimes, Android *removes* APIs. For example, API-23 *removed* the
`android.Manifest.permission.CLEAR_APP_USER_DATA` field.
We still list this field, though:
[`Android.Manifest.Permission.ClearAppUserData` field][0].
> [Android.Runtime.Register("CLEAR_APP_USER_DATA")]
> public const string ClearAppUserData;
In dotnet/android@944d3061 we updated `api-merge` to emit
`//*/@#removed-since`. Consider this snippet from
[`android/src/Mono.Android/Profiles/api-35.xml`][1]:
<field
deprecated="not deprecated" final="true"
name="CLEAR_APP_USER_DATA" jni-signature="Ljava/lang/String;"
static="true" transient="false" type="java.lang.String" type-generic-aware="java.lang.String"
value="&quot;android.permission.CLEAR_APP_USER_DATA&quot;"
visibility="public" volatile="false"
removed-since="23"
/>
Modify `generator` to consume this information and emit
`[UnsupportedOSPlatformAttribute ("androidXX.0")]` as needed for API
that has been removed from `Mono.Android`. This would update
`Android.Manifest.Permission.ClearAppUserData` to be:
[Android.Runtime.Register("CLEAR_APP_USER_DATA")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute ("android23.0")]
public const string ClearAppUserData;
[0]: https://learn.microsoft.com/en-us/dotnet/api/android.manifest.permission.clearappuserdata?view=net-android-34.0
[1]: https://github.com/dotnet/android/blob/d012fb811b4bcebe260400f5fc7a0287108336d7/src/Mono.Android/Profiles/api-35.xml

@jonpryor
jonpryor merged commit 1cfb4f4 into mainFeb 20, 2025
@jonpryor
jonpryor deleted the dev/jpobst/unsupported-os branch February 20, 2025 18:12
jonpryor pushed a commit to dotnet/android that referenced this pull request Feb 21, 2025
Changes: dotnet/java-interop@f30e420...9dea87d
* dotnet/java-interop@9dea87dc: [Java.Interop] .GetTypeSignature() supports unsigned types (dotnet/java-interop#1312)
* dotnet/java-interop@1cfb4f4d: [generator] Add support for emitting `[UnsupportedOSPlatform]` (dotnet/java-interop#1307)
Context: #9811
The .NET MAUI template + NativeAOT currently crashes with:
E AndroidRuntime: net.dot.jni.internal.JavaProxyThrowable: System.InvalidProgramException: InvalidProgram_Specific, IntPtr Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(System.Type, Byte*)
E AndroidRuntime: at Internal.Runtime.TypeLoaderExceptionHelper.CreateInvalidProgramException(ExceptionStringID, String) + 0x4c
E AndroidRuntime: at Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(Type, Byte*) + 0x18
E AndroidRuntime: at Android.Runtime.JNIEnv.TypemapManagedToJava(Type) + 0x104
E AndroidRuntime: at Android.Runtime.JNIEnv.GetJniName(Type) + 0x1c
E AndroidRuntime: at Android.Runtime.JNIEnv.FindClass(Type) + 0x38
E AndroidRuntime: at Android.Runtime.JNIEnv.NewArray(IJavaObject[]) + 0x28
E AndroidRuntime: at Android.Runtime.JNIEnv.NewArray[T](T[]) + 0x94
E AndroidRuntime: at Android.Graphics.Drawables.LayerDrawable..ctor(Drawable[] layers) + 0xd4
E AndroidRuntime: at Microsoft.Maui.Platform.MauiRippleDrawableExtensions.UpdateMauiRippleDrawableBackground(View, Paint, IButtonStroke, Func`1, Func`1, Action) + 0x2ac
This appears to be related to array usage, such as
`LayerDrawable.ctor(Drawable[])` in this example.
I can reproduce the same crash using a
`ColorStateList.ctor(int[][], int[])` in `samples/NativeAOT`:
E AndroidRuntime: net.dot.jni.internal.JavaProxyThrowable: System.InvalidProgramException: InvalidProgram_Specific, IntPtr Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(System.Type, Byte*)
E AndroidRuntime: at Internal.Runtime.TypeLoaderExceptionHelper.CreateInvalidProgramException(ExceptionStringID, String) + 0x4c
E AndroidRuntime: at Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(Type, Byte*) + 0x18
E AndroidRuntime: at Android.Runtime.JNIEnv.TypemapManagedToJava(Type) + 0x104
E AndroidRuntime: at Android.Runtime.JNIEnv.GetJniName(Type) + 0x1c
E AndroidRuntime: at Android.Runtime.JNIEnv.FindClass(Type) + 0x38
E AndroidRuntime: at Android.Runtime.JNIEnv.NewArray[T](T[]) + 0xa8
E AndroidRuntime: at Android.Content.Res.ColorStateList..ctor(Int32[][], Int32[]) + 0xdc
E AndroidRuntime: at NativeAOT.MainActivity.OnCreate(Bundle savedInstanceState) + 0xb8
Update `JNIEnv.FindClass(Type)` to go through `TypeManager` instead
of using `TypemapManagedToJava`. This avoids the P/Invoke which is
causing the crash (f800c1a).
Note that we can't directly use
`JniRuntime.JniTypeManager.GetTypeSignature()`, as the previous use
of `JavaNativeTypeManager.ToJniName(Type)` would default to using
`java/lang/Object` if there was no typemap entry for `type`.
After this change, the sample works and prints a log message
indicating `ColorStateList` is created successfully:
D NativeAOT: MainActivity.OnCreate() ColorStateList: ColorStateList{mThemeAttrs=nullmChangingConfigurations=0mStateSpecs=[[0, 1]]mColors=[0, 1]mDefaultColor=0}
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 23, 2025
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.

Need to track API removals, mark bindings with [UnsupportedOSPlatform]

3 participants

@jpobst@jonpryor