diff --git a/src/Mono.Android.Runtime/Mono.Android.Runtime.csproj b/src/Mono.Android.Runtime/Mono.Android.Runtime.csproj index aac8b3bfe4c..7ac3e7d3063 100644 --- a/src/Mono.Android.Runtime/Mono.Android.Runtime.csproj +++ b/src/Mono.Android.Runtime/Mono.Android.Runtime.csproj @@ -52,11 +52,11 @@ - + diff --git a/src/Mono.Android/Android.Runtime/AndroidRuntimeInternal.cs b/src/Mono.Android/Android.Runtime/AndroidRuntimeInternal.cs index c8d3452af40..73d20f6397b 100644 --- a/src/Mono.Android/Android.Runtime/AndroidRuntimeInternal.cs +++ b/src/Mono.Android/Android.Runtime/AndroidRuntimeInternal.cs @@ -1,36 +1,10 @@ #if INSIDE_MONO_ANDROID_RUNTIME using System; using System.Reflection; +using Microsoft.Android.Runtime; namespace Android.Runtime { - // The existence of InternalRuntimeTypeHolder and DotNetRuntimeTypeConverter classes looks weird, but - // we must handle a weird situation. AndroidRuntimeInternal needs to know in its static constructor - // what is the current runtime type, but it cannot query JNIEnvInit.RuntimeType, since that type lives - // in the Mono.Android assembly, while AndroidRuntimeInternal lives in Mono.Android.Runtime and it cannot - // access JNIEnvInit and Mono.Android.Runtime doesn't reference Mono.Android but Mono.Android **does** reference - // Mono.Android.Runtime and has access to its internals. - // - // Mono.Android.Runtime, also, includes several source files from Mono.Android - **both** assemblies - // include the same source files. In case of the DotNetRuntimeType enum, this declares two distinct types - one - // in Mono.Android and another in Mono.Android.Runtime, and so if JNIEnvInit.Initialize were to try to set the - // `DotNetRuntimeType RuntimeType;` field/property in either of the classes below, we'd get a compilation error - // to the effect of it being unable to cast `Android.Runtime.DotNetRuntimeType` to `Android.Runtime.DotNetRuntimeType`, - // which is usually as clear as mud :) - // - // To solve this and not duplicate code, the InternalRuntimeTypeHolder class is introduced which acts as a proxy since - // the AndroidRuntimeInternal static constructor must know the runtime type and JNIEnvInit.Initialize takes care of it by - // calling `SetRuntimeType` below long before AndroidRuntimeInternal cctor is invoked. - public static class InternalRuntimeTypeHolder - { - internal static DotNetRuntimeType RuntimeType = DotNetRuntimeType.Unknown; - - internal static void SetRuntimeType (uint runtimeType) - { - RuntimeType = DotNetRuntimeTypeConverter.Convert (runtimeType); - } - } - public static class AndroidRuntimeInternal { internal static readonly Action mono_unhandled_exception; @@ -41,11 +15,13 @@ public static class AndroidRuntimeInternal static AndroidRuntimeInternal () { - mono_unhandled_exception = InternalRuntimeTypeHolder.RuntimeType switch { - DotNetRuntimeType.MonoVM => MonoUnhandledException, - DotNetRuntimeType.CoreCLR => CoreClrUnhandledException, - _ => throw new NotSupportedException ($"Internal error: runtime type {InternalRuntimeTypeHolder.RuntimeType} not supported") - }; + if (RuntimeFeature.IsMonoRuntime) { + mono_unhandled_exception = MonoUnhandledException; + } else if (RuntimeFeature.IsCoreClrRuntime) { + mono_unhandled_exception = CoreClrUnhandledException; + } else { + throw new NotSupportedException ("Internal error: unknown runtime not supported"); + } } static void CoreClrUnhandledException (Exception ex) diff --git a/src/Mono.Android/Android.Runtime/DotNetRuntimeType.cs b/src/Mono.Android/Android.Runtime/DotNetRuntimeType.cs deleted file mode 100644 index db0afcd495e..00000000000 --- a/src/Mono.Android/Android.Runtime/DotNetRuntimeType.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace Android.Runtime; - -enum DotNetRuntimeType -{ - Unknown, - MonoVM, - CoreCLR, - NativeAOT, -} - -// This looks weird, see comments in RuntimeTypeInternal.cs -class DotNetRuntimeTypeConverter -{ - // Values for the JnienvInitializeArgs.runtimeType field - // - // NOTE: Keep this in sync with managed side in src/native/common/include/managed-interface.hh - const uint RuntimeTypeMonoVM = 0x0001; - const uint RuntimeTypeCoreCLR = 0x0002; - const uint RuntimeTypeNativeAOT = 0x0004; - - public static DotNetRuntimeType Convert (uint runtimeType) - { - return runtimeType switch { - RuntimeTypeMonoVM => DotNetRuntimeType.MonoVM, - RuntimeTypeCoreCLR => DotNetRuntimeType.CoreCLR, - RuntimeTypeNativeAOT => DotNetRuntimeType.NativeAOT, - _ => throw new NotSupportedException ($"Internal error: unsupported runtime type {runtimeType:x}") - }; - } -} diff --git a/src/Mono.Android/Android.Runtime/JNIEnv.cs b/src/Mono.Android/Android.Runtime/JNIEnv.cs index 305d44081f6..1c35c0a3db9 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnv.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnv.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Reflection; @@ -12,7 +13,7 @@ using Java.Interop; using Java.Interop.Tools.TypeNameMappings; -using System.Diagnostics.CodeAnalysis; +using Microsoft.Android.Runtime; namespace Android.Runtime { public static partial class JNIEnv { @@ -100,16 +101,12 @@ internal static void PropagateUncaughtException (IntPtr env, IntPtr javaThreadPt Logger.Log (LogLevel.Info, "MonoDroid", "UNHANDLED EXCEPTION:"); Logger.Log (LogLevel.Info, "MonoDroid", javaException.ToString ()); - switch (JNIEnvInit.RuntimeType) { - case DotNetRuntimeType.MonoVM: - MonoDroidUnhandledException (innerException ?? javaException); - break; - case DotNetRuntimeType.CoreCLR: - // TODO: what to do here? - break; - - default: - throw new NotSupportedException ($"Internal error: runtime type {JNIEnvInit.RuntimeType} not supported"); + if (RuntimeFeature.IsMonoRuntime) { + MonoDroidUnhandledException (innerException ?? javaException); + } else if (RuntimeFeature.IsCoreClrRuntime) { + // TODO: what to do here? + } else { + throw new NotSupportedException ("Internal error: unknown runtime not supported"); } } catch (Exception e) { Logger.Log (LogLevel.Error, "monodroid", "Exception thrown while raising AppDomain.UnhandledException event: " + e.ToString ()); @@ -453,11 +450,13 @@ static unsafe IntPtr monovm_typemap_managed_to_java (Type type, byte* mvidptr) IntPtr ret; fixed (byte* mvidptr = mvid_data) { - ret = JNIEnvInit.RuntimeType switch { - DotNetRuntimeType.MonoVM => monovm_typemap_managed_to_java (type, mvidptr), - DotNetRuntimeType.CoreCLR => RuntimeNativeMethods.clr_typemap_managed_to_java (type.FullName, (IntPtr)mvidptr), - _ => throw new NotSupportedException ($"Internal error: runtime type {JNIEnvInit.RuntimeType} not supported") - }; + if (RuntimeFeature.IsMonoRuntime) { + ret = monovm_typemap_managed_to_java (type, mvidptr); + } else if (RuntimeFeature.IsCoreClrRuntime) { + ret = RuntimeNativeMethods.clr_typemap_managed_to_java (type.FullName, (IntPtr)mvidptr); + } else { + throw new NotSupportedException ("Internal error: unknown runtime not supported"); + } } if (ret == IntPtr.Zero) { diff --git a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs index 8b11ff74d9e..f0c6947f8ee 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs @@ -34,7 +34,6 @@ internal struct JnienvInitializeArgs { public bool jniRemappingInUse; public bool marshalMethodsEnabled; public IntPtr grefGCUserPeerable; - public uint runtimeType; public bool managedMarshalMethodsLookupEnabled; } #pragma warning restore 0649 @@ -50,8 +49,6 @@ internal struct JnienvInitializeArgs { internal static JniRuntime? androidRuntime; - public static DotNetRuntimeType RuntimeType { get; private set; } = DotNetRuntimeType.Unknown; - [UnmanagedCallersOnly] static unsafe void RegisterJniNatives (IntPtr typeName_ptr, int typeName_len, IntPtr jniClass, IntPtr methods_ptr, int methods_len) { @@ -91,9 +88,10 @@ internal static void InitializeJniRuntime (JniRuntime runtime) [UnmanagedCallersOnly] internal static unsafe void Initialize (JnienvInitializeArgs* args) { - // This looks weird, see comments in RuntimeTypeInternal.cs - RuntimeType = DotNetRuntimeTypeConverter.Convert (args->runtimeType); - InternalRuntimeTypeHolder.SetRuntimeType (args->runtimeType); + // Should not be allowed + if (RuntimeFeature.IsMonoRuntime && RuntimeFeature.IsCoreClrRuntime) { + throw new NotSupportedException ("Internal error: both RuntimeFeature.IsMonoRuntime and RuntimeFeature.IsCoreClrRuntime are enabled"); + } IntPtr total_timing_sequence = IntPtr.Zero; IntPtr partial_timing_sequence = IntPtr.Zero; @@ -114,12 +112,13 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args) } else { typeManager = new AndroidTypeManager (args->jniAddNativeMethodRegistrationAttributePresent != 0); } - valueManager = RuntimeType switch - { - DotNetRuntimeType.MonoVM => new AndroidValueManager(), - DotNetRuntimeType.CoreCLR => ManagedValueManager.GetOrCreateInstance(), - _ => throw new NotSupportedException ($"No value manager for runtime type: {RuntimeType}"), - }; + if (RuntimeFeature.IsMonoRuntime) { + valueManager = new AndroidValueManager (); + } else if (RuntimeFeature.IsCoreClrRuntime) { + valueManager = ManagedValueManager.GetOrCreateInstance (); + } else { + throw new NotSupportedException ("Internal error: unknown runtime not supported"); + } androidRuntime = new AndroidRuntime ( args->env, args->javaVm, diff --git a/src/Mono.Android/Java.Interop/TypeManager.cs b/src/Mono.Android/Java.Interop/TypeManager.cs index 07577dc0c27..b43cc3ba31e 100644 --- a/src/Mono.Android/Java.Interop/TypeManager.cs +++ b/src/Mono.Android/Java.Interop/TypeManager.cs @@ -8,6 +8,7 @@ using Java.Interop.Tools.TypeNameMappings; using Android.Runtime; +using Microsoft.Android.Runtime; namespace Java.Interop { @@ -267,11 +268,13 @@ static Type monovm_typemap_java_to_managed (string java_type_name) return type; } - type = JNIEnvInit.RuntimeType switch { - DotNetRuntimeType.MonoVM => monovm_typemap_java_to_managed (class_name), - DotNetRuntimeType.CoreCLR => clr_typemap_java_to_managed (class_name), - _ => throw new NotSupportedException ($"Internal error: runtime type {JNIEnvInit.RuntimeType} not supported") - }; + if (RuntimeFeature.IsMonoRuntime) { + type = monovm_typemap_java_to_managed (class_name); + } else if (RuntimeFeature.IsCoreClrRuntime) { + type = clr_typemap_java_to_managed (class_name); + } else { + throw new NotSupportedException ("Internal error: unknown runtime not supported"); + } if (type != null) { TypeManagerMapDictionaries.JniToManaged.Add (class_name, type); diff --git a/src/Mono.Android/Microsoft.Android.Runtime/RuntimeFeature.cs b/src/Mono.Android/Microsoft.Android.Runtime/RuntimeFeature.cs index 814b8c5ab7e..a25462d9b29 100644 --- a/src/Mono.Android/Microsoft.Android.Runtime/RuntimeFeature.cs +++ b/src/Mono.Android/Microsoft.Android.Runtime/RuntimeFeature.cs @@ -5,9 +5,21 @@ namespace Microsoft.Android.Runtime; static class RuntimeFeature { + const bool ManagedTypeMapEnabledByDefault = false; + const bool IsMonoRuntimeEnabledByDefault = true; + const bool IsCoreClrRuntimeEnabledByDefault = false; + const string FeatureSwitchPrefix = "Microsoft.Android.Runtime.RuntimeFeature."; [FeatureSwitchDefinition ($"{FeatureSwitchPrefix}{nameof (ManagedTypeMap)}")] internal static bool ManagedTypeMap { get; } = - AppContext.TryGetSwitch ($"{FeatureSwitchPrefix}{nameof (ManagedTypeMap)}", out bool isEnabled) ? isEnabled : false; + AppContext.TryGetSwitch ($"{FeatureSwitchPrefix}{nameof (ManagedTypeMap)}", out bool isEnabled) ? isEnabled : ManagedTypeMapEnabledByDefault; + + [FeatureSwitchDefinition ($"{FeatureSwitchPrefix}{nameof (IsMonoRuntime)}")] + internal static bool IsMonoRuntime { get; } = + AppContext.TryGetSwitch ($"{FeatureSwitchPrefix}{nameof (IsMonoRuntime)}", out bool isEnabled) ? isEnabled : IsMonoRuntimeEnabledByDefault; + + [FeatureSwitchDefinition ($"{FeatureSwitchPrefix}{nameof (IsCoreClrRuntime)}")] + internal static bool IsCoreClrRuntime { get; } = + AppContext.TryGetSwitch ($"{FeatureSwitchPrefix}{nameof (IsCoreClrRuntime)}", out bool isEnabled) ? isEnabled : IsCoreClrRuntimeEnabledByDefault; } diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index a3d26c20b45..18b95b5ae92 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -220,7 +220,6 @@ - diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets index cc8c0e39945..705237961ab 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets @@ -20,6 +20,18 @@ This file contains the CoreCLR-specific MSBuild logic for .NET for Android. true + + + + + + diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.MonoVM.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.MonoVM.targets new file mode 100644 index 00000000000..8b49df77580 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.MonoVM.targets @@ -0,0 +1,22 @@ + + + + + + + + + + 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 83a301a92ee..c47637cd367 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 @@ -29,6 +29,18 @@ This file contains the NativeAOT-specific MSBuild logic for .NET for Android. false + + + + + + diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets index 349345ff6a7..b43c7913576 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets @@ -33,7 +33,6 @@ - - + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index 59aacae52d3..88a20c92f27 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -11,13 +11,13 @@ "Size": 18288 }, "lib/arm64-v8a/lib_Java.Interop.dll.so": { - "Size": 88472 + "Size": 88000 }, "lib/arm64-v8a/lib_Mono.Android.dll.so": { - "Size": 124040 + "Size": 118240 }, "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { - "Size": 23424 + "Size": 23480 }, "lib/arm64-v8a/lib_System.Console.dll.so": { "Size": 24408 @@ -26,10 +26,10 @@ "Size": 25488 }, "lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": { - "Size": 692528 + "Size": 635296 }, "lib/arm64-v8a/lib_System.Runtime.dll.so": { - "Size": 20104 + "Size": 20136 }, "lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": { "Size": 21528 @@ -38,13 +38,13 @@ "Size": 20024 }, "lib/arm64-v8a/libarc.bin.so": { - "Size": 18984 + "Size": 19112 }, "lib/arm64-v8a/libmono-component-marshal-ilgen.so": { "Size": 36616 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 1508312 + "Size": 1508296 }, "lib/arm64-v8a/libmonosgen-2.0.so": { "Size": 3119744 @@ -62,10 +62,10 @@ "Size": 165240 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 19800 + "Size": 19808 }, "META-INF/BNDLTOOL.RSA": { - "Size": 1223 + "Size": 1221 }, "META-INF/BNDLTOOL.SF": { "Size": 3266 @@ -98,5 +98,5 @@ "Size": 1904 } }, - "PackageSize": 3148309 + "PackageSize": 3090965 } \ No newline at end of file diff --git a/src/native/clr/host/host.cc b/src/native/clr/host/host.cc index ea8ccbc5215..3fd2e3ba959 100644 --- a/src/native/clr/host/host.cc +++ b/src/native/clr/host/host.cc @@ -422,7 +422,6 @@ void Host::Java_mono_android_Runtime_initInternal ( ); struct JnienvInitializeArgs init = {}; - init.runtimeType = RuntimeTypeCoreCLR; init.javaVm = jvm; init.env = env; init.logCategories = log_categories; diff --git a/src/native/common/include/managed-interface.hh b/src/native/common/include/managed-interface.hh index 489252ed04e..f40690d4030 100644 --- a/src/native/common/include/managed-interface.hh +++ b/src/native/common/include/managed-interface.hh @@ -5,13 +5,6 @@ #include namespace xamarin::android { - // Values for the JnienvInitializeArgs.runtimeType field - // - // NOTE: Keep this in sync with managed side in src/Mono.Android/Android.Runtime/DotNetRuntimeType.cs - static inline constexpr uint32_t RuntimeTypeMonoVM = 0x0001; - static inline constexpr uint32_t RuntimeTypeCoreCLR = 0x0002; - static inline constexpr uint32_t RuntimeTypeNativeAOT = 0x0004; - // Values must be identical to those in src/Mono.Android/Android.Runtime/RuntimeNativeMethods.cs enum class TraceKind : uint32_t { @@ -39,7 +32,6 @@ namespace xamarin::android { bool jniRemappingInUse; bool marshalMethodsEnabled; jobject grefGCUserPeerable; - uint32_t runtimeType; bool managedMarshalMethodsLookupEnabled; }; diff --git a/src/native/mono/monodroid/monodroid-glue.cc b/src/native/mono/monodroid/monodroid-glue.cc index 78474e27dd7..17a379cf19f 100644 --- a/src/native/mono/monodroid/monodroid-glue.cc +++ b/src/native/mono/monodroid/monodroid-glue.cc @@ -822,7 +822,6 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec mono_add_internal_call ("Android.Runtime.RuntimeNativeMethods::monodroid_unhandled_exception", reinterpret_cast(monodroid_unhandled_exception)); struct JnienvInitializeArgs init = {}; - init.runtimeType = RuntimeTypeMonoVM; init.javaVm = osBridge.get_jvm (); init.env = env; init.logCategories = log_categories;