diff --git a/Xamarin.Android.sln b/Xamarin.Android.sln
index 5227e5fd898..782b20c69db 100644
--- a/Xamarin.Android.sln
+++ b/Xamarin.Android.sln
@@ -125,6 +125,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Android.Sdk.Analy
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proguard-android", "src\proguard-android\proguard-android.csproj", "{5FD0133B-69E5-4474-9B67-9FD1D0150C70}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Android.Runtime.NativeAOT", "src\Microsoft.Android.Runtime.NativeAOT\Microsoft.Android.Runtime.NativeAOT.csproj", "{E8831F32-11D7-D42C-E43C-711998BC357A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AnyCPU = Debug|AnyCPU
@@ -347,6 +349,10 @@ Global
{5FD0133B-69E5-4474-9B67-9FD1D0150C70}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{5FD0133B-69E5-4474-9B67-9FD1D0150C70}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{5FD0133B-69E5-4474-9B67-9FD1D0150C70}.Release|AnyCPU.Build.0 = Release|Any CPU
+ {E8831F32-11D7-D42C-E43C-711998BC357A}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
+ {E8831F32-11D7-D42C-E43C-711998BC357A}.Debug|AnyCPU.Build.0 = Debug|Any CPU
+ {E8831F32-11D7-D42C-E43C-711998BC357A}.Release|AnyCPU.ActiveCfg = Release|Any CPU
+ {E8831F32-11D7-D42C-E43C-711998BC357A}.Release|AnyCPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -406,6 +412,7 @@ Global
{A39B6D7C-6616-40D6-8AE4-C6CEE93D2708} = {CAB438D8-B0F5-4AF0-BEBD-9E2ADBD7B483}
{5E806C9F-1B67-4B6B-A6AB-258834250DBB} = {FFCF518F-2A4A-40A2-9174-2EE13B76C723}
{5FD0133B-69E5-4474-9B67-9FD1D0150C70} = {FFCF518F-2A4A-40A2-9174-2EE13B76C723}
+ {E8831F32-11D7-D42C-E43C-711998BC357A} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {53A1F287-EFB2-4D97-A4BB-4A5E145613F6}
diff --git a/build-tools/create-packs/Microsoft.Android.Runtime.proj b/build-tools/create-packs/Microsoft.Android.Runtime.proj
index 9c3c22c1390..5f19f16ffdc 100644
--- a/build-tools/create-packs/Microsoft.Android.Runtime.proj
+++ b/build-tools/create-packs/Microsoft.Android.Runtime.proj
@@ -37,7 +37,11 @@ projects that use the Microsoft.Android framework in .NET 6+.
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETDefaultOutDir)Java.Interop.dll" />
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETDefaultOutDir)Mono.Android.dll" />
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETDefaultOutDir)Mono.Android.Runtime.dll" />
-
+
+ <_AndroidRuntimePackAssemblies
+ Include="$(_MonoAndroidNETOutputRoot)$(AndroidLatestStableApiLevel)\Microsoft.Android.Runtime.NativeAOT.dll"
+ Condition=" '$(AndroidRuntime)' == 'NativeAOT' "
+ />
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETOutputRoot)$(AndroidLatestStableApiLevel)\Mono.Android.Export.dll" />
diff --git a/samples/NativeAOT/AndroidManifest.xml b/samples/NativeAOT/AndroidManifest.xml
index 70e89c99003..3fead98ca0f 100644
--- a/samples/NativeAOT/AndroidManifest.xml
+++ b/samples/NativeAOT/AndroidManifest.xml
@@ -1,13 +1,6 @@
-
-
\ No newline at end of file
diff --git a/samples/NativeAOT/NativeAOT.csproj b/samples/NativeAOT/NativeAOT.csproj
index e392eaa7646..18922a65b67 100644
--- a/samples/NativeAOT/NativeAOT.csproj
+++ b/samples/NativeAOT/NativeAOT.csproj
@@ -9,10 +9,6 @@
1
1.0
apk
- true
-
- true
- ..\..\product.snk
android-arm64
@@ -29,8 +25,4 @@
<_FastDeploymentDiagnosticLogging>true
-
-
-
-
\ No newline at end of file
diff --git a/samples/NativeAOT/JavaInteropRuntime.cs b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/JavaInteropRuntime.cs
similarity index 95%
rename from samples/NativeAOT/JavaInteropRuntime.cs
rename to src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/JavaInteropRuntime.cs
index 8c86e5d264b..869d82b1cd5 100644
--- a/samples/NativeAOT/JavaInteropRuntime.cs
+++ b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/JavaInteropRuntime.cs
@@ -2,7 +2,7 @@
using Java.Interop;
using System.Runtime.InteropServices;
-namespace NativeAOT;
+namespace Microsoft.Android.Runtime;
static class JavaInteropRuntime
{
@@ -35,7 +35,7 @@ static void init (IntPtr jnienv, IntPtr klass)
{
try {
var typeManager = new NativeAotTypeManager ();
- var options = new JreRuntimeOptions {
+ var options = new NativeAotRuntimeOptions {
EnvironmentPointer = jnienv,
TypeManager = typeManager,
ValueManager = new NativeAotValueManager (typeManager),
diff --git a/samples/NativeAOT/Logging.cs b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/Logging.cs
similarity index 98%
rename from samples/NativeAOT/Logging.cs
rename to src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/Logging.cs
index 5073ba9e5a3..880e107e72f 100644
--- a/samples/NativeAOT/Logging.cs
+++ b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/Logging.cs
@@ -6,7 +6,7 @@
using System.Runtime.InteropServices;
using System.Text;
-namespace NativeAOT;
+namespace Microsoft.Android.Runtime;
internal sealed class LogcatTextWriter : TextWriter {
diff --git a/samples/NativeAOT/NativeAotTypeManager.cs b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/NativeAotTypeManager.cs
similarity index 83%
rename from samples/NativeAOT/NativeAotTypeManager.cs
rename to src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/NativeAotTypeManager.cs
index baffdef8859..b2f864587f3 100644
--- a/samples/NativeAOT/NativeAotTypeManager.cs
+++ b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/NativeAotTypeManager.cs
@@ -3,7 +3,7 @@
using Java.Interop;
using Java.Interop.Tools.TypeNameMappings;
-namespace NativeAOT;
+namespace Microsoft.Android.Runtime;
partial class NativeAotTypeManager : JniRuntime.JniTypeManager {
@@ -11,25 +11,27 @@ partial class NativeAotTypeManager : JniRuntime.JniTypeManager {
internal const DynamicallyAccessedMemberTypes Methods = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
internal const DynamicallyAccessedMemberTypes MethodsAndPrivateNested = Methods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;
- // TODO: list of types specific to this application
- Dictionary typeMappings = new () {
- ["android/app/Activity"] = typeof (Android.App.Activity),
- ["android/app/Application"] = typeof (Android.App.Application),
- ["android/content/Context"] = typeof (Android.Content.Context),
- ["android/content/ContextWrapper"] = typeof (Android.Content.ContextWrapper),
- ["android/os/BaseBundle"] = typeof (Android.OS.BaseBundle),
- ["android/os/Bundle"] = typeof (Android.OS.Bundle),
- ["android/view/ContextThemeWrapper"] = typeof (Android.Views.ContextThemeWrapper),
- ["my/MainActivity"] = typeof (MainActivity),
- ["my/MainApplication"] = typeof (MainApplication),
- };
+ readonly IDictionary TypeMappings = new Dictionary (StringComparer.Ordinal);
public NativeAotTypeManager ()
{
- AndroidLog.Print (AndroidLogLevel.Info, "NativeAotTypeManager", $"# jonp: NativeAotTypeManager()");
+ AndroidLog.Print (AndroidLogLevel.Info, "NativeAotTypeManager", $"NativeAotTypeManager()");
+ var startTicks = global::System.Environment.TickCount;
+ InitializeTypeMappings ();
+ var endTicks = global::System.Environment.TickCount;
+ AndroidLog.Print (AndroidLogLevel.Info, "NativeAotTypeManager", $"InitializeTypeMappings() took {endTicks - startTicks}ms");
}
- protected override Type? GetInvokerTypeCore (Type type)
+ void InitializeTypeMappings ()
+ {
+ // Should be replaced by src/Microsoft.Android.Sdk.ILLink/TypeMappingStep.cs
+ throw new InvalidOperationException ("TypeMappings should be replaced during trimming!");
+ }
+
+ [return: DynamicallyAccessedMembers (Constructors)]
+ protected override Type? GetInvokerTypeCore (
+ [DynamicallyAccessedMembers (Constructors)]
+ Type type)
{
const string suffix = "Invoker";
@@ -68,6 +70,10 @@ static Type MakeGenericType (
return MakeGenericType (suffixDefinition, arguments);
}
+ // NOTE: suppressions below also in `src/Mono.Android/Android.Runtime/AndroidRuntime.cs`
+ [UnconditionalSuppressMessage ("Trimming", "IL2057", Justification = "Type.GetType() can never statically know the string value parsed from parameter 'methods'.")]
+ [UnconditionalSuppressMessage ("Trimming", "IL2067", Justification = "Delegate.CreateDelegate() can never statically know the string value parsed from parameter 'methods'.")]
+ [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Delegate.CreateDelegate() can never statically know the string value parsed from parameter 'methods'.")]
public override void RegisterNativeMembers (
JniType nativeClass,
[DynamicallyAccessedMembers (MethodsAndPrivateNested)]
@@ -143,7 +149,7 @@ public override void RegisterNativeMembers (
protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference)
{
AndroidLog.Print (AndroidLogLevel.Info, "NativeAotTypeManager", $"# jonp: GetTypesForSimpleReference: jniSimpleReference=`{jniSimpleReference}`");
- if (typeMappings.TryGetValue (jniSimpleReference, out var target)) {
+ if (TypeMappings.TryGetValue (jniSimpleReference, out var target)) {
Console.WriteLine ($"# jonp: GetTypesForSimpleReference: jniSimpleReference=`{jniSimpleReference}` -> `{target}`");
yield return target;
}
@@ -161,9 +167,7 @@ protected override IEnumerable GetSimpleReferences (Type type)
IEnumerable CreateSimpleReferencesEnumerator (Type type)
{
- if (typeMappings == null)
- yield break;
- foreach (var e in typeMappings) {
+ foreach (var e in TypeMappings) {
if (e.Value == type)
yield return e.Key;
}
diff --git a/samples/NativeAOT/NativeAotValueManager.cs b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/NativeAotValueManager.cs
similarity index 87%
rename from samples/NativeAOT/NativeAotValueManager.cs
rename to src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/NativeAotValueManager.cs
index b1996b88b30..e54d49ca7e4 100644
--- a/samples/NativeAOT/NativeAotValueManager.cs
+++ b/src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/NativeAotValueManager.cs
@@ -4,6 +4,7 @@
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -13,9 +14,9 @@
using Android.Runtime;
using Java.Interop;
-namespace NativeAOT;
+namespace Microsoft.Android.Runtime;
-internal class NativeAotValueManager : JniRuntime.JniValueManager
+class NativeAotValueManager : JniRuntime.JniValueManager
{
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
@@ -113,12 +114,12 @@ void WarnNotReplacing (int key, IJavaPeerable ignoreValue, IJavaPeerable keepVal
"Warning: Not registering PeerReference={0} IdentityHashCode=0x{1} Instance={2} Instance.Type={3} Java.Type={4}; " +
"keeping previously registered PeerReference={5} Instance={6} Instance.Type={7} Java.Type={8}.",
ignoreValue.PeerReference.ToString (),
- key.ToString ("x"),
- RuntimeHelpers.GetHashCode (ignoreValue).ToString ("x"),
+ key.ToString ("x", CultureInfo.InvariantCulture),
+ RuntimeHelpers.GetHashCode (ignoreValue).ToString ("x", CultureInfo.InvariantCulture),
ignoreValue.GetType ().FullName,
JniEnvironment.Types.GetJniTypeNameFromInstance (ignoreValue.PeerReference),
keepValue.PeerReference.ToString (),
- RuntimeHelpers.GetHashCode (keepValue).ToString ("x"),
+ RuntimeHelpers.GetHashCode (keepValue).ToString ("x", CultureInfo.InvariantCulture),
keepValue.GetType ().FullName,
JniEnvironment.Types.GetJniTypeNameFromInstance (keepValue.PeerReference));
}
@@ -186,8 +187,8 @@ public override void FinalizePeer (IJavaPeerable value)
if (o.LogGlobalReferenceMessages) {
o.WriteGlobalReferenceLine ("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}",
h.ToString (),
- value.JniIdentityHashCode.ToString ("x"),
- RuntimeHelpers.GetHashCode (value).ToString ("x"),
+ value.JniIdentityHashCode.ToString ("x", CultureInfo.InvariantCulture),
+ RuntimeHelpers.GetHashCode (value).ToString ("x", CultureInfo.InvariantCulture),
value.GetType ().ToString ());
}
RemovePeer (value);
@@ -200,8 +201,8 @@ public override void FinalizePeer (IJavaPeerable value)
if (o.LogGlobalReferenceMessages) {
o.WriteGlobalReferenceLine ("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}",
h.ToString (),
- value.JniIdentityHashCode.ToString ("x"),
- RuntimeHelpers.GetHashCode (value).ToString ("x"),
+ value.JniIdentityHashCode.ToString ("x", CultureInfo.InvariantCulture),
+ RuntimeHelpers.GetHashCode (value).ToString ("x", CultureInfo.InvariantCulture),
value.GetType ().ToString ());
}
value.SetPeerReference (new JniObjectReference ());
@@ -214,9 +215,11 @@ public override void ActivatePeer (IJavaPeerable? self, JniObjectReference refer
try {
ActivateViaReflection (reference, cinfo, argumentValues);
} catch (Exception e) {
- var m = string.Format ("Could not activate {{ PeerReference={0} IdentityHashCode=0x{1} Java.Type={2} }} for managed type '{3}'.",
+ var m = string.Format (
+ CultureInfo.InvariantCulture,
+ "Could not activate {{ PeerReference={0} IdentityHashCode=0x{1} Java.Type={2} }} for managed type '{3}'.",
reference,
- GetJniIdentityHashCode (reference).ToString ("x"),
+ GetJniIdentityHashCode (reference).ToString ("x", CultureInfo.InvariantCulture),
JniEnvironment.Types.GetJniTypeNameFromInstance (reference),
cinfo.DeclaringType?.FullName);
Debug.WriteLine (m);
@@ -257,7 +260,11 @@ public override List GetSurfacedPeers ()
static readonly Type[] XAConstructorSignature = new Type [] { typeof (IntPtr), typeof (JniHandleOwnership) };
- protected override IJavaPeerable? TryCreatePeer (ref JniObjectReference reference, JniObjectReferenceOptions options, Type type)
+ protected override IJavaPeerable? TryCreatePeer (
+ ref JniObjectReference reference,
+ JniObjectReferenceOptions options,
+ [DynamicallyAccessedMembers (Constructors)]
+ Type type)
{
var c = type.GetConstructor (ActivationConstructorBindingFlags, null, XAConstructorSignature, null);
if (c != null) {
diff --git a/src/Microsoft.Android.Runtime.NativeAOT/AssemblyInfo.cs b/src/Microsoft.Android.Runtime.NativeAOT/AssemblyInfo.cs
new file mode 100644
index 00000000000..00c8d7afa79
--- /dev/null
+++ b/src/Microsoft.Android.Runtime.NativeAOT/AssemblyInfo.cs
@@ -0,0 +1,5 @@
+using System.Runtime.Versioning;
+
+// NOTE: silences the CA1416 analyzer about supported Android APIs
+[assembly: TargetPlatformAttribute("Android35.0")]
+[assembly: SupportedOSPlatformAttribute("Android21.0")]
diff --git a/src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/JreRuntime.cs b/src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/JreRuntime.cs
new file mode 100644
index 00000000000..630707a17cc
--- /dev/null
+++ b/src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/JreRuntime.cs
@@ -0,0 +1,98 @@
+// Originally from: https://github.com/dotnet/java-interop/blob/dd3c1d0514addfe379f050627b3e97493e985da6/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Microsoft.Android.Runtime;
+
+namespace Java.Interop {
+
+ struct JavaVMInitArgs {
+ #pragma warning disable CS0649 // Field is never assigned to;
+ public JniVersion version; /* use JNI_VERSION_1_2 or later */
+
+ public int nOptions;
+ public IntPtr /* JavaVMOption[] */ options;
+ public byte ignoreUnrecognized;
+ #pragma warning restore CS0649
+ }
+
+ class NativeAotRuntimeOptions : JniRuntime.CreationOptions {
+
+ public bool IgnoreUnrecognizedOptions {get; set;}
+
+ public TextWriter? JniGlobalReferenceLogWriter {get; set;}
+ public TextWriter? JniLocalReferenceLogWriter {get; set;}
+
+ public NativeAotRuntimeOptions ()
+ {
+ JniVersion = JniVersion.v1_2;
+ }
+
+ public JreRuntime CreateJreVM ()
+ {
+ return new JreRuntime (this);
+ }
+ }
+
+ class JreRuntime : JniRuntime
+ {
+ static JreRuntime ()
+ {
+ }
+
+ static NativeAotRuntimeOptions CreateJreVM (NativeAotRuntimeOptions builder)
+ {
+ if (builder == null)
+ throw new ArgumentNullException ("builder");
+ if (builder.InvocationPointer == IntPtr.Zero &&
+ builder.EnvironmentPointer == IntPtr.Zero &&
+ string.IsNullOrEmpty (builder.JvmLibraryPath))
+ throw new InvalidOperationException ($"Member `{nameof (NativeAotRuntimeOptions)}.{nameof (NativeAotRuntimeOptions.JvmLibraryPath)}` must be set.");
+
+#if NET
+ builder.TypeManager ??= new NativeAotTypeManager ();
+#endif // NET
+
+ builder.ValueManager ??= new NativeAotValueManager (builder.TypeManager);
+ builder.ObjectReferenceManager ??= new ManagedObjectReferenceManager (builder.JniGlobalReferenceLogWriter, builder.JniLocalReferenceLogWriter);
+
+ if (builder.InvocationPointer != IntPtr.Zero || builder.EnvironmentPointer != IntPtr.Zero)
+ return builder;
+
+ throw new NotImplementedException ();
+ }
+
+ [UnconditionalSuppressMessage ("Trimming", "IL3000", Justification = "We check for a null Assembly.Location value!")]
+ internal static string? GetAssemblyLocation (Assembly assembly)
+ {
+ var location = assembly.Location;
+ if (!string.IsNullOrEmpty (location))
+ return location;
+ return null;
+ }
+
+ internal protected JreRuntime (NativeAotRuntimeOptions builder)
+ : base (CreateJreVM (builder))
+ {
+ }
+
+ public override string? GetCurrentManagedThreadName ()
+ {
+ return Thread.CurrentThread.Name;
+ }
+
+ public override string GetCurrentManagedThreadStackTrace (int skipFrames, bool fNeedFileInfo)
+ {
+ return new StackTrace (skipFrames, fNeedFileInfo)
+ .ToString ();
+ }
+ }
+}
diff --git a/src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/ManagedObjectReferenceManager.cs b/src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/ManagedObjectReferenceManager.cs
new file mode 100644
index 00000000000..b152ff5b797
--- /dev/null
+++ b/src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/ManagedObjectReferenceManager.cs
@@ -0,0 +1,229 @@
+// Originally from: https://github.com/dotnet/java-interop/blob/dd3c1d0514addfe379f050627b3e97493e985da6/src/Java.Runtime.Environment/Java.Interop/ManagedObjectReferenceManager.cs
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+namespace Java.Interop {
+
+ class ManagedObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
+
+ TextWriter? grefLog;
+ TextWriter? lrefLog;
+
+ int grefCount;
+ int wgrefCount;
+
+
+ public override int GlobalReferenceCount => grefCount;
+ public override int WeakGlobalReferenceCount => wgrefCount;
+
+ public override bool LogLocalReferenceMessages => lrefLog != null;
+ public override bool LogGlobalReferenceMessages => grefLog != null;
+
+ public ManagedObjectReferenceManager (TextWriter? grefLog, TextWriter? lrefLog)
+ {
+ if (grefLog != null && lrefLog != null && object.ReferenceEquals (grefLog, lrefLog)) {
+ this.grefLog = this.lrefLog = TextWriter.Synchronized (grefLog);
+ return;
+ }
+
+ var grefPath = Environment.GetEnvironmentVariable ("JAVA_INTEROP_GREF_LOG");
+ var lrefPath = Environment.GetEnvironmentVariable ("JAVA_INTEROP_LREF_LOG");
+
+ bool samePath = !string.IsNullOrEmpty (grefPath) &&
+ !string.IsNullOrEmpty (lrefPath) &&
+ grefPath == lrefPath;
+
+ if (grefLog != null) {
+ this.grefLog = TextWriter.Synchronized (grefLog);
+ }
+ if (lrefLog != null) {
+ this.lrefLog = TextWriter.Synchronized (lrefLog);
+ }
+
+ if (this.grefLog == null && !string.IsNullOrEmpty (grefPath)) {
+ this.grefLog = TextWriter.Synchronized (CreateTextWriter (grefPath));
+ }
+ if (this.lrefLog == null && samePath) {
+ this.lrefLog = this.grefLog;
+ }
+ if (this.lrefLog == null && !string.IsNullOrEmpty (lrefPath)) {
+ this.lrefLog = TextWriter.Synchronized (CreateTextWriter (lrefPath));
+ }
+ }
+
+ public override void OnSetRuntime (JniRuntime runtime)
+ {
+ base.OnSetRuntime (runtime);
+ }
+
+ static TextWriter CreateTextWriter (string path)
+ {
+ return new StreamWriter (path, append: false, encoding: new UTF8Encoding (encoderShouldEmitUTF8Identifier: false));
+ }
+
+ public override void WriteLocalReferenceLine (string format, params object[] args)
+ {
+ if (lrefLog == null)
+ return;
+ lrefLog.WriteLine (format, args);
+ lrefLog.Flush ();
+ }
+
+ public override JniObjectReference CreateLocalReference (JniObjectReference reference, ref int localReferenceCount)
+ {
+ if (!reference.IsValid)
+ return reference;
+
+ var r = base.CreateLocalReference (reference, ref localReferenceCount);
+
+ CreatedReference (lrefLog, "+l+ lrefc", localReferenceCount, reference, r, Runtime);
+
+ return r;
+ }
+
+ public override void DeleteLocalReference (ref JniObjectReference reference, ref int localReferenceCount)
+ {
+ if (!reference.IsValid)
+ return;
+
+ var r = reference;
+
+ base.DeleteLocalReference (ref reference, ref localReferenceCount);
+
+ DeletedReference (lrefLog, "-l- lrefc", localReferenceCount, r, Runtime);
+ }
+
+ public override void CreatedLocalReference (JniObjectReference reference, ref int localReferenceCount)
+ {
+ if (!reference.IsValid)
+ return;
+ base.CreatedLocalReference (reference, ref localReferenceCount);
+ CreatedReference (lrefLog, "+l+ lrefc", localReferenceCount, reference, Runtime);
+ }
+
+ public override IntPtr ReleaseLocalReference (ref JniObjectReference reference, ref int localReferenceCount)
+ {
+ if (!reference.IsValid)
+ return IntPtr.Zero;
+ var r = reference;
+ var p = base.ReleaseLocalReference (ref reference, ref localReferenceCount);
+ DeletedReference (lrefLog, "-l- lrefc", localReferenceCount, r, Runtime);
+ return p;
+ }
+
+ public override void WriteGlobalReferenceLine (string format, params object?[]? args)
+ {
+ if (grefLog == null)
+ return;
+ grefLog.WriteLine (format, args!);
+ grefLog.Flush ();
+ }
+
+ public override JniObjectReference CreateGlobalReference (JniObjectReference reference)
+ {
+ if (!reference.IsValid)
+ return reference;
+ var n = base.CreateGlobalReference (reference);
+ int c = Interlocked.Increment (ref grefCount);
+ CreatedReference (grefLog, "+g+ grefc", c, reference, n, Runtime);
+ return n;
+ }
+
+ public override void DeleteGlobalReference (ref JniObjectReference reference)
+ {
+ if (!reference.IsValid)
+ return;
+ int c = Interlocked.Decrement (ref grefCount);
+ DeletedReference (grefLog, "-g- grefc", c, reference, Runtime);
+ base.DeleteGlobalReference (ref reference);
+ }
+
+ public override JniObjectReference CreateWeakGlobalReference (JniObjectReference reference)
+ {
+ if (!reference.IsValid)
+ return reference;
+ var n = base.CreateWeakGlobalReference (reference);
+
+ int wc = Interlocked.Increment (ref wgrefCount);
+ int gc = grefCount;
+ if (grefLog != null) {
+ string message = $"+w+ grefc {gc} gwrefc {wc} obj-handle {reference.ToString ()} -> new-handle {n.ToString ()} " +
+ $"from thread '{Runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
+ Environment.NewLine +
+ Runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
+ grefLog.WriteLine (message);
+ grefLog.Flush ();
+ }
+
+ return n;
+ }
+
+ public override void DeleteWeakGlobalReference (ref JniObjectReference reference)
+ {
+ if (!reference.IsValid)
+ return;
+
+ int wc = Interlocked.Decrement (ref wgrefCount);
+ int gc = grefCount;
+
+ if (grefLog != null) {
+ string message = $"-w- grefc {gc} gwrefc {wc} handle {reference.ToString ()} " +
+ $"from thread '{Runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
+ Environment.NewLine +
+ Runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
+ grefLog.WriteLine (message);
+ grefLog.Flush ();
+ }
+
+ base.DeleteWeakGlobalReference (ref reference);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ }
+
+ static void CreatedReference (TextWriter? writer, string kind, int count, JniObjectReference reference, JniRuntime runtime)
+ {
+ if (writer == null)
+ return;
+ string message = $"{kind} {count} handle {reference.ToString ()} " +
+ $"from thread '{runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
+ Environment.NewLine +
+ runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
+ writer.WriteLine (message);
+ writer.Flush ();
+ }
+
+ static void CreatedReference (TextWriter? writer, string kind, int count, JniObjectReference reference, JniObjectReference newReference, JniRuntime runtime)
+ {
+ if (writer == null)
+ return;
+ string message = $"{kind} {count} obj-handle {reference.ToString ()} -> new-handle {newReference.ToString ()} " +
+ $"from thread '{runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
+ Environment.NewLine +
+ runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
+ writer.WriteLine (message);
+ writer.Flush ();
+ }
+
+ static void DeletedReference (TextWriter? writer, string kind, int count, JniObjectReference reference, JniRuntime runtime)
+ {
+ if (writer == null)
+ return;
+ string message = $"{kind} {count} handle {reference.ToString ()} " +
+ $"from thread '{runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
+ Environment.NewLine +
+ runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
+ writer.WriteLine (message);
+ writer.Flush ();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.Android.Runtime.NativeAOT/Microsoft.Android.Runtime.NativeAOT.csproj b/src/Microsoft.Android.Runtime.NativeAOT/Microsoft.Android.Runtime.NativeAOT.csproj
new file mode 100644
index 00000000000..5ae08596c98
--- /dev/null
+++ b/src/Microsoft.Android.Runtime.NativeAOT/Microsoft.Android.Runtime.NativeAOT.csproj
@@ -0,0 +1,41 @@
+
+
+
+
+
+ $(DotNetTargetFramework)
+ enable
+ enable
+ false
+ ..\..\product.snk
+ true
+ $(_MonoAndroidNETDefaultOutDir)
+ Microsoft.Android.Runtime
+
+
+
+
+
+
+
+
+
+
+ $(BuildDependsOn);
+ _CopyToPackDirs;
+
+
+
+
+
+ <_RuntimePackFiles Include="$(OutputPath)Microsoft.Android.Runtime.NativeAOT.dll" AndroidRID="%(AndroidAbiAndRuntimeFlavor.AndroidRID)" AndroidRuntime="%(AndroidAbiAndRuntimeFlavor.AndroidRuntime)" />
+
+
+
+
+
+
diff --git a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj
index 0f7136c2746..393ef9077c1 100644
--- a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj
+++ b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj
@@ -2,10 +2,11 @@
$(DotNetTargetFramework)
- ILLINK
+ ILLINK;HAVE_CECIL
false
$(MicrosoftAndroidSdkOutDir)
annotations
+ true
@@ -26,8 +27,13 @@
+
+
+
+
+
diff --git a/src/Microsoft.Android.Sdk.ILLink/TypeMappingStep.cs b/src/Microsoft.Android.Sdk.ILLink/TypeMappingStep.cs
new file mode 100644
index 00000000000..9b82e500fd8
--- /dev/null
+++ b/src/Microsoft.Android.Sdk.ILLink/TypeMappingStep.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Java.Interop.Tools.Cecil;
+using Java.Interop.Tools.TypeNameMappings;
+using Mono.Cecil;
+using Mono.Linker;
+using Mono.Linker.Steps;
+
+namespace Microsoft.Android.Sdk.ILLink;
+
+///
+/// MVP "typemap" implementation for NativeAOT
+///
+public class TypeMappingStep : BaseStep
+{
+ const string AssemblyName = "Microsoft.Android.Runtime.NativeAOT";
+ const string TypeName = "Microsoft.Android.Runtime.NativeAotTypeManager";
+ readonly IDictionary TypeMappings = new Dictionary (StringComparer.Ordinal);
+ AssemblyDefinition? MicrosoftAndroidRuntimeNativeAot;
+
+ protected override void ProcessAssembly (AssemblyDefinition assembly)
+ {
+ if (assembly.Name.Name == AssemblyName) {
+ MicrosoftAndroidRuntimeNativeAot = assembly;
+ return;
+ }
+ if (Annotations?.GetAction (assembly) == AssemblyAction.Delete)
+ return;
+
+ foreach (var type in assembly.MainModule.Types) {
+ ProcessType (assembly, type);
+ }
+ }
+
+ protected override void EndProcess ()
+ {
+ if (MicrosoftAndroidRuntimeNativeAot is null) {
+ Context.LogMessage ($"Unable to find {AssemblyName} assembly");
+ return;
+ }
+
+ var module = MicrosoftAndroidRuntimeNativeAot.MainModule;
+ var type = module.GetType (TypeName);
+ if (type is null) {
+ Context.LogMessage ($"Unable to find {TypeName} type");
+ return;
+ }
+
+ var method = type.Methods.FirstOrDefault (m => m.Name == "InitializeTypeMappings");
+ if (method is null) {
+ Context.LogMessage ($"Unable to find {TypeName}.InitializeTypeMappings() method");
+ return;
+ }
+
+ var field = type.Fields.FirstOrDefault (f => f.Name == "TypeMappings");
+ if (field is null) {
+ Context.LogMessage ($"Unable to find {TypeName}.TypeMappings field");
+ return;
+ }
+
+ // Clear IL in method body
+ method.Body.Instructions.Clear ();
+
+ Context.LogMessage ($"Writing {TypeMappings.Count} typemap entries");
+ var il = method.Body.GetILProcessor ();
+ var addMethod = module.ImportReference (typeof (IDictionary).GetMethod ("Add"));
+ var getTypeFromHandle = module.ImportReference (typeof (Type).GetMethod ("GetTypeFromHandle"));
+ foreach (var (javaKey, typeDefinition) in TypeMappings) {
+ /*
+ * IL_0000: ldarg.0
+ * IL_0001: ldfld class [System.Runtime]System.Collections.Generic.IDictionary`2 Microsoft.Android.Runtime.NativeAotTypeManager::TypeMappings
+ * IL_0006: ldstr "java/lang/Object"
+ * IL_000b: ldtoken [Mono.Android]Java.Lang.Object
+ * IL_0010: call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle)
+ * IL_0015: callvirt instance void class [System.Runtime]System.Collections.Generic.IDictionary`2::Add(!0, !1)
+ */
+ il.Emit (Mono.Cecil.Cil.OpCodes.Ldarg_0);
+ il.Emit (Mono.Cecil.Cil.OpCodes.Ldfld, field);
+ il.Emit (Mono.Cecil.Cil.OpCodes.Ldstr, javaKey);
+ il.Emit (Mono.Cecil.Cil.OpCodes.Ldtoken, module.ImportReference (typeDefinition));
+ il.Emit (Mono.Cecil.Cil.OpCodes.Call, getTypeFromHandle);
+ il.Emit (Mono.Cecil.Cil.OpCodes.Callvirt, addMethod);
+ }
+
+ il.Emit (Mono.Cecil.Cil.OpCodes.Ret);
+ }
+
+ void ProcessType (AssemblyDefinition assembly, TypeDefinition type)
+ {
+ if (type.HasJavaPeer (Context)) {
+ var javaName = JavaNativeTypeManager.ToJniName (type, Context);
+ if (!TypeMappings.TryAdd (javaName, type)) {
+ Context.LogMessage ($"Duplicate typemap entry for {javaName}");
+ }
+ }
+
+ if (!type.HasNestedTypes)
+ return;
+
+ foreach (TypeDefinition nested in type.NestedTypes)
+ ProcessType (assembly, nested);
+ }
+}
diff --git a/src/Mono.Android/Properties/AssemblyInfo.cs.in b/src/Mono.Android/Properties/AssemblyInfo.cs.in
index 9d8b6f5694b..f083dafcd92 100644
--- a/src/Mono.Android/Properties/AssemblyInfo.cs.in
+++ b/src/Mono.Android/Properties/AssemblyInfo.cs.in
@@ -45,7 +45,6 @@ using System.Runtime.Versioning;
[assembly: InternalsVisibleTo("Mono.Android-TestsMultiDex, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
[assembly: InternalsVisibleTo("Mono.Android-TestsAppBundle, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
[assembly: InternalsVisibleTo("Mono.Android.NET-Tests, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
-// Temporary for samples/NativeAOT
-[assembly: InternalsVisibleTo("NativeAOT, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
+[assembly: InternalsVisibleTo("Microsoft.Android.Runtime.NativeAOT, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
[assembly: SuppressMessage ("ApiDesign", "RS0016:Add public types and members to the declared API", Justification = "Analyzer fails due to extended characters.", Scope = "member", Target = "~F:Android.Util.Patterns.GoodIriChar")]
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets
index 6e783fdf500..ecddf43795d 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets
@@ -84,11 +84,18 @@ This file contains the .NET 5-specific targets to customize ILLink
BeforeStep="MarkStep"
Type="MonoDroid.Tuner.FixLegacyResourceDesignerStep"
/>
+ <_TrimmerCustomSteps
+ Condition=" '$(_AndroidRuntime)' == 'NativeAOT' "
+ Include="$(_AndroidLinkerCustomStepAssembly)"
+ AfterStep="CleanStep"
+ Type="Microsoft.Android.Sdk.ILLink.TypeMappingStep"
+ />
<_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" />
+
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets
index 64dd729f9ed..292a86e28ad 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets
@@ -81,6 +81,8 @@ This file contains the NativeAOT-specific MSBuild logic for .NET for Android.
+
+
diff --git a/samples/NativeAOT/JavaInteropRuntime.java b/src/Xamarin.Android.Build.Tasks/Resources/JavaInteropRuntime.java
similarity index 60%
rename from samples/NativeAOT/JavaInteropRuntime.java
rename to src/Xamarin.Android.Build.Tasks/Resources/JavaInteropRuntime.java
index 1eb07e9f2e5..cb0474682f9 100644
--- a/samples/NativeAOT/JavaInteropRuntime.java
+++ b/src/Xamarin.Android.Build.Tasks/Resources/JavaInteropRuntime.java
@@ -4,8 +4,8 @@
public class JavaInteropRuntime {
static {
- Log.d("JavaInteropRuntime", "Loading NativeAOT.so...");
- System.loadLibrary("NativeAOT");
+ Log.d("JavaInteropRuntime", "Loading @MAIN_ASSEMBLY_NAME@.so...");
+ System.loadLibrary("@MAIN_ASSEMBLY_NAME@");
}
private JavaInteropRuntime() {
diff --git a/samples/NativeAOT/NativeAotRuntimeProvider.java b/src/Xamarin.Android.Build.Tasks/Resources/NativeAotRuntimeProvider.java
similarity index 100%
rename from samples/NativeAOT/NativeAotRuntimeProvider.java
rename to src/Xamarin.Android.Build.Tasks/Resources/NativeAotRuntimeProvider.java
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs
index 2fa90dca06e..a908645c829 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs
@@ -98,6 +98,9 @@ public class GenerateJavaStubs : AndroidTask
public string CodeGenerationTarget { get; set; } = "";
+ [Required]
+ public string TargetName { get; set; } = "";
+
AndroidRuntime androidRuntime;
JavaPeerStyle codeGenerationTarget;
@@ -304,18 +307,33 @@ Dictionary MaybeGetArchAssemblies (Dictionary additionalProviders)
{
- if (androidRuntime != Xamarin.Android.Tasks.AndroidRuntime.MonoVM) {
- Log.LogDebugMessage ($"Skipping MonoRuntimeProvider generation for: {androidRuntime}");
- } else {
+ if (androidRuntime != Xamarin.Android.Tasks.AndroidRuntime.CoreCLR) {
// Create additional runtime provider java sources.
- string providerTemplateFile = "MonoRuntimeProvider.Bundled.java";
+ bool isMonoVM = androidRuntime == Xamarin.Android.Tasks.AndroidRuntime.MonoVM;
+ string providerTemplateFile = isMonoVM ?
+ "MonoRuntimeProvider.Bundled.java" :
+ "NativeAotRuntimeProvider.java";
string providerTemplate = GetResource (providerTemplateFile);
foreach (var provider in additionalProviders) {
- var contents = providerTemplate.Replace ("MonoRuntimeProvider", provider);
- var real_provider = Path.Combine (OutputDirectory, "src", "mono", provider + ".java");
+ var contents = providerTemplate.Replace (isMonoVM ? "MonoRuntimeProvider" : "NativeAotRuntimeProvider", provider);
+ var real_provider = isMonoVM ?
+ Path.Combine (OutputDirectory, "src", "mono", provider + ".java") :
+ Path.Combine (OutputDirectory, "src", "net", "dot", "jni", "nativeaot", provider + ".java");
Files.CopyIfStringChanged (contents, real_provider);
}
+ } else {
+ Log.LogDebugMessage ($"Skipping android.content.ContentProvider generation for: {androidRuntime}");
+ }
+
+ // For NativeAOT, generate JavaInteropRuntime.java
+ if (androidRuntime == Xamarin.Android.Tasks.AndroidRuntime.NativeAOT) {
+ const string fileName = "JavaInteropRuntime.java";
+ string template = GetResource (fileName);
+ var contents = template.Replace ("@MAIN_ASSEMBLY_NAME@", TargetName);
+ var path = Path.Combine (OutputDirectory, "src", "net", "dot", "jni", "nativeaot", fileName);
+ Log.LogDebugMessage ($"Writing: {path}");
+ Files.CopyIfStringChanged (contents, path);
}
// Create additional application java sources.
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs
index 7cb28b4942e..0930f930428 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs
@@ -673,12 +673,15 @@ XElement CreateApplicationElement (XElement manifest, string applicationClass, L
IList AddMonoRuntimeProviders (XElement app)
{
- if (AndroidRuntime != AndroidRuntime.MonoVM) {
- //TODO: implement provider logic for non-Mono runtimes
+ if (AndroidRuntime == AndroidRuntime.CoreCLR) {
+ //TODO: implement provider logic for CoreCLR
return [];
}
- app.Add (CreateMonoRuntimeProvider ("mono.MonoRuntimeProvider", null, --AppInitOrder));
+ bool isMonoVM = AndroidRuntime == AndroidRuntime.MonoVM;
+ string packageName = isMonoVM ? "mono" : "net.dot.jni.nativeaot";
+ string className = isMonoVM ? "MonoRuntimeProvider" : "NativeAotRuntimeProvider";
+ app.Add (CreateMonoRuntimeProvider ($"{packageName}.{className}", null, --AppInitOrder));
var providerNames = new List ();
@@ -702,9 +705,9 @@ IList AddMonoRuntimeProviders (XElement app)
case "activity":
case "receiver":
case "service":
- string providerName = "MonoRuntimeProvider_" + procs.Count;
+ string providerName = $"{className}_{procs.Count}";
providerNames.Add (providerName);
- app.Add (CreateMonoRuntimeProvider ("mono." + providerName, proc.Value, --AppInitOrder));
+ app.Add (CreateMonoRuntimeProvider ($"{packageName}.{providerName}", proc.Value, --AppInitOrder));
break;
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
index db23eeb6fe4..dd9b72972a8 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
@@ -204,26 +204,11 @@
-
- machine.config
-
-
- MonoRuntimeProvider.Bundled.java
-
-
- proguard_xamarin.cfg
-
-
- ApplicationRegistration.java
-
-
- net.android.init.gradle.kts
-
JavaInteropTypeManager.java
-
- Resource.Designer.snk
+
+ %(Filename)%(Extension)
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index d93711c4262..3123c94ff3b 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -1387,6 +1387,11 @@ because xbuild doesn't support framework reference assemblies.
ResourceName="MonoRuntimeProvider.Bundled.java"
OutputPath="$(_AndroidIntermediateJavaSourceDirectory)mono\MonoRuntimeProvider.java"
/>
+