Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions Configuration.props
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,18 @@
<MicrosoftAndroidSdkPackName Condition="$([MSBuild]::IsOSPlatform('osx'))">Microsoft.Android.Sdk.Darwin</MicrosoftAndroidSdkPackName>
</PropertyGroup>
<PropertyGroup>
<MicrosoftAndroidPacksRootDir>$(BuildOutputDirectory)lib\packs\</MicrosoftAndroidPacksRootDir>
<AutoProvision Condition=" '$(AutoProvision)' == '' ">False</AutoProvision>
<AutoProvisionUsesSudo Condition=" '$(AutoProvisionUsesSudo)' == '' ">False</AutoProvisionUsesSudo>
<_XABinRelativeInstallPrefix>lib\xamarin.android</_XABinRelativeInstallPrefix>
<XAInstallPrefix Condition=" '$(XAInstallPrefix)' == '' ">$(MSBuildThisFileDirectory)bin\$(Configuration)\$(_XABinRelativeInstallPrefix)\</XAInstallPrefix>
<_MonoAndroidNETOutputRoot>$(XAInstallPrefix)xbuild-frameworks\Microsoft.Android\</_MonoAndroidNETOutputRoot>
<_MonoAndroidNETDefaultOutDir>$(_MonoAndroidNETOutputRoot)$(AndroidApiLevel)\</_MonoAndroidNETDefaultOutDir>
<MicrosoftAndroidRefPackDir>$(BuildOutputDirectory)lib\packs\Microsoft.Android.Ref.$(AndroidApiLevel)\$(AndroidPackVersion)\ref\$(DotNetTargetFramework)\</MicrosoftAndroidRefPackDir>
<MicrosoftAndroidSdkPackDir>$(BuildOutputDirectory)lib\packs\$(MicrosoftAndroidSdkPackName)\$(AndroidPackVersion)\</MicrosoftAndroidSdkPackDir>
<NativeRuntimeOutputRootDir>$(BuildOutputDirectory)lib\runtimes\</NativeRuntimeOutputRootDir>
<MicrosoftAndroidRefPackDir>$(MicrosoftAndroidPacksRootDir)Microsoft.Android.Ref.$(AndroidApiLevel)\$(AndroidPackVersion)\ref\$(DotNetTargetFramework)\</MicrosoftAndroidRefPackDir>
<MicrosoftAndroidSdkPackDir>$(MicrosoftAndroidPacksRootDir)$(MicrosoftAndroidSdkPackName)\$(AndroidPackVersion)\</MicrosoftAndroidSdkPackDir>
<MicrosoftAndroidSdkOutDir>$(MicrosoftAndroidSdkPackDir)\tools\</MicrosoftAndroidSdkOutDir>
<MicrosoftAndroidSdkAnalysisOutDir>$(BuildOutputDirectory)lib\packs\Microsoft.Android.Ref.$(AndroidLatestStableApiLevel)\$(AndroidPackVersion)\analyzers\dotnet\cs\</MicrosoftAndroidSdkAnalysisOutDir>
<MicrosoftAndroidSdkAnalysisOutDir>$(MicrosoftAndroidPacksRootDir)Microsoft.Android.Ref.$(AndroidLatestStableApiLevel)\$(AndroidPackVersion)\analyzers\dotnet\cs\</MicrosoftAndroidSdkAnalysisOutDir>
<MakeConcurrency Condition=" '$(MakeConcurrency)' == '' And '$(HostCpuCount)' != '' ">-j$(HostCpuCount)</MakeConcurrency>
<ManagedRuntime Condition=" '$(ManagedRuntime)' == '' And '$(OS)' != 'Windows_NT' ">mono</ManagedRuntime>
<ManagedRuntimeArgs Condition=" '$(ManagedRuntimeArgs)' == '' And '$(ManagedRuntime)' == 'mono' ">--debug=casts</ManagedRuntimeArgs>
Expand Down
27 changes: 22 additions & 5 deletions build-tools/create-packs/Microsoft.Android.Runtime.proj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ projects that use the Microsoft.Android framework in .NET 6+.
DependsOnTargets="_GetLicense">
<PropertyGroup>
<FrameworkListFile Condition="'$(FrameworkListFile)' == ''">$(IntermediateOutputPath)$(AndroidRID)\RuntimeList.xml</FrameworkListFile>
<_RuntimeFlavorDirName Condition=" '$(AndroidRuntime)' == 'CoreCLR' ">clr</_RuntimeFlavorDirName>
<_RuntimeFlavorDirName Condition=" '$(AndroidRuntime)' == 'Mono' Or '$(AndroidRuntime)' == '' ">mono</_RuntimeFlavorDirName>
</PropertyGroup>

<ItemGroup>
Expand All @@ -45,12 +47,27 @@ projects that use the Microsoft.Android framework in .NET 6+.
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETOutputRoot)$(AndroidLatestStableApiLevel)\Mono.Android.Export.dll" />
</ItemGroup>

<ItemGroup Condition=" '$(AndroidRuntime)' == 'CoreCLR' ">
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libnet-android.debug.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libnet-android.debug.so" />
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libnet-android.release.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libnet-android.release.so" />
</ItemGroup>

<ItemGroup Condition=" '$(AndroidRuntime)' == 'Mono' ">
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libmono-android.debug.so" />
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libmono-android.release.so" />
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libxamarin-debug-app-helper.so" />
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libxamarin-native-tracing.so" />
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libunwind_xamarin.a" />
<_AndroidRuntimePackAssets Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libmono-android.debug.so" />
<_AndroidRuntimePackAssets Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libmono-android.release.so" />
<_AndroidRuntimePackAssets Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libxamarin-debug-app-helper.so" />
<_AndroidRuntimePackAssets Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libxamarin-native-tracing.so" />
<_AndroidRuntimePackAssets Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libunwind_xamarin.a" />
</ItemGroup>

<ItemGroup Condition=" '$(AndroidRuntime)' == 'CoreCLR' ">
<!-- TODO: the Exists() checks must go away once we build CoreCLR host for all the targets -->
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc.so" />
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libdl.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libdl.so" />
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\liblog.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\liblog.so" />
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libm.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libm.so" />
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libz.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libz.so" />
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libarchive-dso-stub.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libarchive-dso-stub.so" />
</ItemGroup>

<ItemGroup>
Expand Down
32 changes: 32 additions & 0 deletions src/Mono.Android/Android.Runtime/DotNetRuntimeType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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}")
};
}
}
7 changes: 6 additions & 1 deletion src/Mono.Android/Android.Runtime/JNIEnvInit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Android.Runtime
static internal class JNIEnvInit
{
#pragma warning disable 0649
// NOTE: Keep this in sync with the native side in src/native/monodroid/monodroid-glue-internal.hh
// NOTE: Keep this in sync with the native side in src/native/common/include/managed-interface.hh
internal struct JnienvInitializeArgs {
public IntPtr javaVm;
public IntPtr env;
Expand All @@ -32,6 +32,7 @@ internal struct JnienvInitializeArgs {
public bool jniRemappingInUse;
public bool marshalMethodsEnabled;
public IntPtr grefGCUserPeerable;
public uint runtimeType;
}
#pragma warning restore 0649

Expand All @@ -48,6 +49,8 @@ internal struct JnienvInitializeArgs {

internal static JniRuntime? androidRuntime;

public static DotNetRuntimeType RuntimeType { get; private set; } = DotNetRuntimeType.Unknown;
Copy link
Member

Choose a reason for hiding this comment

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

Could this value be set by a trimmer switch instead of passing it in?

The build knows the runtime it targets, so it could do the work at build time.

This would make this property treated as a constant and code for other runtimes would be trimmed away.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that eventually turning it into a trimmer feature is the goal. But right now, I need it to be a runtime check since I sometimes work without the trimmer

Copy link
Member

Choose a reason for hiding this comment

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

Trimmer feature switches use AppContext.TryGetSwitch() if the app isn't trimmed, here is an example:

Copy link
Contributor

Choose a reason for hiding this comment

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

I disagree on both counts: I'd rather avoid the trimmer switch until we actually need it, and I don't see why we want/need this RuntimeType field as well.

See e.g. #9812: any place that would be "switching" on RuntimeType is probably better served as a virtual method invocation on JNIEnvInit.androidRuntime or equivalent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That might be the better solution, but we can make that change at a later time, when everything is in main, I think


[UnmanagedCallersOnly]
static unsafe void RegisterJniNatives (IntPtr typeName_ptr, int typeName_len, IntPtr jniClass, IntPtr methods_ptr, int methods_len)
{
Expand Down Expand Up @@ -87,6 +90,8 @@ internal static void InitializeJniRuntime (JniRuntime runtime)
[UnmanagedCallersOnly]
internal static unsafe void Initialize (JnienvInitializeArgs* args)
{
RuntimeType = DotNetRuntimeTypeConverter.Convert (args->runtimeType);

IntPtr total_timing_sequence = IntPtr.Zero;
IntPtr partial_timing_sequence = IntPtr.Zero;

Expand Down
1 change: 1 addition & 0 deletions src/Mono.Android/Mono.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@
<Compile Include="Android.Runtime\BoundExceptionType.cs" />
<Compile Include="Android.Runtime\CharSequence.cs" />
<Compile Include="Android.Runtime\CPUArchitecture.cs" />
<Compile Include="Android.Runtime\DotNetRuntimeType.cs" />
<Compile Include="Android.Runtime\Extensions.cs" />
<Compile Include="Android.Runtime\GeneratedEnumAttribute.cs" />
<Compile Include="Android.Runtime\IJavaObject.cs" />
Expand Down
10 changes: 9 additions & 1 deletion src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,16 @@ void SaveResource (string resource, string filename, string destDir, Func<string

void WriteTypeMappings (NativeCodeGenState state)
{
if (androidRuntime == Xamarin.Android.Tasks.AndroidRuntime.NativeAOT) {
// NativeAOT typemaps are generated in `Microsoft.Android.Sdk.ILLink.TypeMappingStep`
return;
}
if (androidRuntime == Xamarin.Android.Tasks.AndroidRuntime.CoreCLR) {
// TODO: CoreCLR typemaps will be emitted later
return;
}
Log.LogDebugMessage ($"Generating type maps for architecture '{state.TargetArch}'");
var tmg = new TypeMapGenerator (Log, state);
var tmg = new TypeMapGenerator (Log, state, androidRuntime);
if (!tmg.Generate (Debug, SkipJniAddNativeMethodRegistrationAttributeScan, TypemapOutputDirectory, GenerateNativeAssembly)) {
throw new XamarinAndroidException (4308, Properties.Resources.XA4308);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public override string GetComment (object data, string fieldName)
}
}

// Disable "Field 'X' is never assigned to, and will always have its default value Y"
// Classes below are used in native code generation, thus all the fields must be present
// but they aren't always assigned values (which is fine).
#pragma warning disable CS0649

// Order of fields and their type must correspond *exactly* (with exception of the
// ignored managed members) to that in
// src/monodroid/jni/xamarin-app.hh DSOCacheEntry structure
Expand Down Expand Up @@ -147,6 +152,7 @@ sealed class XamarinAndroidBundledAssembly
[NativeAssembler (UsesDataProvider = true), NativePointer (PointsToPreAllocatedBuffer = true)]
public string name;
}
#pragma warning restore CS0649

// Keep in sync with FORMAT_TAG in src/monodroid/jni/xamarin-app.hh
const ulong FORMAT_TAG = 0x00025E6972616D58; // 'Xmari^XY' where XY is the format version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ string Generate (string baseOutputDirectory, AndroidTargetArch arch, List<Assemb
// We'll start writing to the stream after we seek to the position just after the header, index, descriptors and name data.
ulong curPos = assemblyDataStart;

Directory.CreateDirectory (Path.GetDirectoryName (storePath));
using var fs = File.Open (storePath, FileMode.Create, FileAccess.Write, FileShare.Read);
fs.Seek ((long)curPos, SeekOrigin.Begin);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,9 @@ void WriteStructureValue (GeneratorWriteContext context, StructureInstance? inst

for (int i = 0; i < info.Members.Count; i++) {
StructureMemberInfo smi = info.Members[i];
if (!smi.IsSupportedForTarget (context.Target)) {
continue;
}

context.Output.Write (context.CurrentIndent);
WriteType (context, instance, smi, out _);
Expand Down Expand Up @@ -810,7 +813,7 @@ void WriteStructureValue (GeneratorWriteContext context, StructureInstance? inst
var sb = new StringBuilder (" ");
sb.Append (MapManagedTypeToNative (context, smi));
sb.Append (' ');
sb.Append (smi.Info.Name);
sb.Append (smi.MappedName);
comment = sb.ToString ();
}
WriteCommentLine (context, comment);
Expand Down Expand Up @@ -848,6 +851,7 @@ void WriteArrayEntries (GeneratorWriteContext context, LlvmIrVariable variable,
bool ignoreComments = stride > 1;
string? prevItemComment = null;
ulong counter = 0;
bool writeStringInComment = !ignoreComments && (elementType == typeof(string) || elementType == typeof(StringHolder));

if (entries != null) {
foreach (object entry in entries) {
Expand All @@ -871,7 +875,13 @@ void WriteArrayEntries (GeneratorWriteContext context, LlvmIrVariable variable,
}

if (writeIndices && String.IsNullOrEmpty (prevItemComment)) {
prevItemComment = $" {counter}";
string stringComment = String.Empty;
if (writeStringInComment) {
var holder = StringHolder.AsHolder (entry);
stringComment = $" ('{holder.Data}')";
}

prevItemComment = $" {counter}{stringComment}";
}
}

Expand Down Expand Up @@ -1098,6 +1108,10 @@ void WriteStructureDeclaration (GeneratorWriteContext context, StructureInfo si)
context.IncreaseIndent ();
for (int i = 0; i < si.Members.Count; i++) {
StructureMemberInfo info = si.Members[i];
if (!info.IsSupportedForTarget (context.Target)) {
continue;
}

string nativeType = MapManagedTypeToNative (info.MemberType);

// TODO: nativeType can be an array, update to indicate that (and get the size)
Expand All @@ -1108,7 +1122,7 @@ void WriteStructureDeclaration (GeneratorWriteContext context, StructureInfo si)
arraySize = String.Empty;
}

var comment = $" {nativeType} {info.Info.Name}{arraySize}";
var comment = $" {nativeType} {info.MappedName}{arraySize}";
WriteStructureDeclarationField (info.IRType, comment, i == si.Members.Count - 1);
}
context.DecreaseIndent ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ public static LlvmIrStringEncoding GetStringEncoding (this MemberInfo mi, LlvmIr
return attr.IsUTF16 ? LlvmIrStringEncoding.Unicode : DefaultStringEncoding;
}

public static string? GetOverriddenName (this MemberInfo mi, LlvmIrTypeCache cache)
{
var attr = cache.GetNativeAssemblerAttribute (mi);
return attr != null ? attr.MemberName : null;
}

public static NativeAssemblerValidTarget GetValidTarget (this MemberInfo mi, LlvmIrTypeCache cache)
{
var attr = cache.GetNativeAssemblerAttribute (mi);
return attr != null ? attr.ValidTarget : NativeAssemblerValidTarget.Any;
}

public static bool ShouldBeIgnored (this MemberInfo mi, LlvmIrTypeCache cache)
{
var attr = cache.GetNativeAssemblerAttribute (mi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

namespace Xamarin.Android.Tasks
{
enum NativeAssemblerValidTarget
{
Any,
ThirtyTwoBit,
SixtyFourBit,
}

[AttributeUsage (AttributeTargets.Field | AttributeTargets.Property, Inherited = true)]
class NativeAssemblerAttribute : Attribute
{
Expand Down Expand Up @@ -41,6 +48,22 @@ class NativeAssemblerAttribute : Attribute
/// the native assembly file.
/// </summary>
public bool IsUTF16 { get; set; }

/// <summary>
/// Allows choosing that a structure/class field/property will be considered only for the target of
/// specific bitness. Mainly useful when dealing with hash fields.
/// </summary>
public NativeAssemblerValidTarget ValidTarget { get; set; } = NativeAssemblerValidTarget.Any;

/// <summary>
/// Allows overriding of the field name when mapping the structure. This is purely cosmetic, but allows to avoid
/// confusion when dealing with fields/properties that have a different size for 32-bit and 64-bit targets. In such
/// case the structure being mapped will have a separate member per bitness, with the members requiring different names
/// while in reality they have the same name in the native world, regardless of bitness.
///
/// This field is only considered only when <see cref="ValidTarget" /> is not set to <see cref="NativeAssemblerValidTarget.Any"/>
/// </summary>
public string? MemberName { get; set; }
}

[AttributeUsage (AttributeTargets.Class, Inherited = true)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,25 @@ sealed class StructureMemberInfo
public bool IsInlineArray { get; }
public bool NeedsPadding { get; }

/// <summary>
/// Some fields/properties may override their name for presentation purposes, <see cref="NativeAssemblerAttribute.MemberName" />.
/// In such instances, this property will return the overridden/mapped name, otherwise it returns <see cref="Info.Name"/>.
/// This property should be used only for "presentation" purposes - for instance when generating comments which refer to
/// native field names.
/// </summary>
public string MappedName {
get {
string? name = Info.GetOverriddenName (typeCache);
return String.IsNullOrEmpty (name) ? Info.Name : name;
}
}

readonly LlvmIrTypeCache typeCache;

public StructureMemberInfo (MemberInfo mi, LlvmIrModule module, LlvmIrTypeCache cache)
{
Info = mi;
typeCache = cache;

MemberType = mi switch {
FieldInfo fi => fi.FieldType,
Expand Down Expand Up @@ -97,6 +113,17 @@ public StructureMemberInfo (MemberInfo mi, LlvmIrModule module, LlvmIrTypeCache
}
}

public bool IsSupportedForTarget (LlvmIrModuleTarget target)
{
NativeAssemblerValidTarget validTarget = Info.GetValidTarget (typeCache);
return validTarget switch {
NativeAssemblerValidTarget.Any => true,
NativeAssemblerValidTarget.ThirtyTwoBit => !target.Is64Bit,
NativeAssemblerValidTarget.SixtyFourBit => target.Is64Bit,
_ => throw new NotSupportedException ($"Internal error: unsupported native assembler valid target value: {validTarget}")
};
}

public object? GetValue (object instance)
{
if (Info is FieldInfo fi) {
Expand Down
13 changes: 6 additions & 7 deletions src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -673,14 +673,13 @@ XElement CreateApplicationElement (XElement manifest, string applicationClass, L

IList<string> AddMonoRuntimeProviders (XElement app)
{
if (AndroidRuntime == AndroidRuntime.CoreCLR) {
//TODO: implement provider logic for CoreCLR
return [];
}
(string packageName, string className) = AndroidRuntime switch {
AndroidRuntime.MonoVM => ("mono", "MonoRuntimeProvider"),
AndroidRuntime.CoreCLR => ("mono", "MonoRuntimeProvider"),
AndroidRuntime.NativeAOT => ("net.dot.jni.nativeaot", "NativeAotRuntimeProvider"),
_ => throw new NotSupportedException ($"Internal error: unsupported runtime type: {AndroidRuntime}")
};

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<string> ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public static string ArchToAbi (AndroidTargetArch arch)
}

public static bool IsValidAbi (string abi) => AbiToRidMap.ContainsKey (abi);
public static bool IsValidRID (string rid) => RidToAbiMap.ContainsKey (rid);

public static string? CultureInvariantToString (object? obj)
{
Expand Down Expand Up @@ -228,6 +229,7 @@ public static ulong GetMangledAssemblyNameSizeOverhead ()
}

public static byte[] Utf8StringToBytes (string str) => Encoding.UTF8.GetBytes (str);
public static byte[] Utf16StringToBytes (string str) => Encoding.Unicode.GetBytes (str);

public static ulong GetXxHash (string str, bool is64Bit) => GetXxHash (Utf8StringToBytes (str), is64Bit);

Expand Down
Loading
Loading