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
10 changes: 10 additions & 0 deletions src/Mono.Android/ILLink/ILLink.Substitutions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<linker>
<assembly fullname="Mono.Android">
<type fullname="Java.Interop.TypeManager" feature="Java.Interop.TypeManager.TypeRegistrationFallbackIsEnabled" featurevalue="false">
<method signature="System.Boolean get_TypeRegistrationFallbackIsEnabled()" body="stub" value="false" />
<method signature="System.Type TypeRegistrationFallback()" body="stub" value="null" />
<method signature="System.Void RegisterPackage(System.String,System.Converter`2&lt;System.String,System.Type&gt;)" body="stub" />
<method signature="System.Void RegisterPackages(System.String[],System.Converter`2&lt;System.String,System.Type&gt;[])" body="stub" />
</type>
</assembly>
</linker>
28 changes: 25 additions & 3 deletions src/Mono.Android/Java.Interop/TypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ static Exception CreateJavaLocationException ()
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern Type monodroid_typemap_java_to_managed (string java_type_name);

static bool TypeRegistrationFallbackIsEnabled { get; } = InitializeTypeRegistrationFallbackIsEnabled ();
static bool InitializeTypeRegistrationFallbackIsEnabled () =>
!AppContext.TryGetSwitch ("Java.Interop.TypeManager.TypeRegistrationFallbackIsEnabled", out bool isEnabled) || isEnabled;

internal static Type? GetJavaToManagedType (string class_name)
{
Type? type = monodroid_typemap_java_to_managed (class_name);
Expand All @@ -225,10 +229,18 @@ static Exception CreateJavaLocationException ()
return null;
}

if (TypeRegistrationFallbackIsEnabled)
return TypeRegistrationFallback (class_name);

return null;
}

internal static Type? TypeRegistrationFallback (string class_name)
{
__TypeRegistrations.RegisterPackages ();

type = null;
int ls = class_name.LastIndexOf ('/');
Type? type = null;
int ls = class_name.LastIndexOf ('/');
var package = ls >= 0 ? class_name.Substring (0, ls) : "";
if (packageLookup.TryGetValue (package, out var mappers)) {
foreach (Converter<string, Type?> c in mappers) {
Expand Down Expand Up @@ -353,10 +365,18 @@ public static void RegisterType (string java_class, Type t)
}
}

static Dictionary<string, List<Converter<string, Type?>>> packageLookup = new Dictionary<string, List<Converter<string, Type?>>> ();
static Dictionary<string, List<Converter<string, Type?>>>? packageLookup;

static void LazyInitPackageLookup ()
{
if (packageLookup == null)
packageLookup = new Dictionary<string, List<Converter<string, Type?>>> (StringComparer.Ordinal);
}

public static void RegisterPackage (string package, Converter<string, Type> lookup)
{
LazyInitPackageLookup ();

lock (packageLookup) {
if (!packageLookup.TryGetValue (package, out var lookups))
packageLookup.Add (package, lookups = new List<Converter<string, Type?>> ());
Expand All @@ -366,6 +386,8 @@ public static void RegisterPackage (string package, Converter<string, Type> look

public static void RegisterPackages (string[] packages, Converter<string, Type?>[] lookups)
{
LazyInitPackageLookup ();

if (packages == null)
throw new ArgumentNullException ("packages");
if (lookups == null)
Expand Down
3 changes: 3 additions & 0 deletions src/Mono.Android/Mono.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@
<EmbeddedResource Include="ILLink/ILLink.LinkAttributes.xml">
<LogicalName>ILLink.LinkAttributes.xml</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="ILLink/ILLink.Substitutions.xml">
<LogicalName>ILLink.Substitutions.xml</LogicalName>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@ This file contains the .NET 5-specific targets to customize ILLink
<UseSystemResourceKeys Condition="'$(UseSystemResourceKeys)' == ''">true</UseSystemResourceKeys>
<HttpActivityPropagationSupport Condition="'$(HttpActivityPropagationSupport)' == ''">false</HttpActivityPropagationSupport>
<StartupHookSupport Condition="'$(StartupHookSupport)' == ''">false</StartupHookSupport>
<XATypeRegistrationFallback Condition="'$(XATypeRegistrationFallback)' == ''">false</XATypeRegistrationFallback>
</PropertyGroup>

<Target Name="_PrepareLinking"
Condition=" '$(PublishTrimmed)' == 'true' "
AfterTargets="ComputeResolvedFilesToPublishList"
DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache">
<ItemGroup>
<RuntimeHostConfigurationOption Include="Java.Interop.TypeManager.TypeRegistrationFallbackIsEnabled"
Condition="'$(XATypeRegistrationFallback)' != ''"
Value="$(XATypeRegistrationFallback)"
Trim="true" />
Comment thread
radekdoulik marked this conversation as resolved.
<!-- Mark all assemblies to be linked for AndroidLinkMode=Full -->
<ResolvedFileToPublish
Update="@(ResolvedFileToPublish)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,5 +394,28 @@ public unsafe bool MyMethod (Android.OS.IBinder windowToken, [global::Android.Ru
}
}
}

[Test]
public void TypeRegistrationsFallback ([Values (true, false)] bool enabled)
{
if (!Builder.UseDotNet)
Assert.Ignore ("Test only valid on .NET 6");

var proj = new XamarinAndroidApplicationProject () { IsRelease = true };
if (enabled)
proj.SetProperty (proj.ActiveConfigurationProperties, "XATypeRegistrationFallback", "true");

using (var b = CreateApkBuilder ()) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
var assemblyFile = "Mono.Android.dll";
var assemblyPath = BuildTest.GetLinkedPath (b, true, assemblyFile);
using (var assembly = AssemblyDefinition.ReadAssembly (assemblyPath)) {
Assert.IsTrue (assembly != null);

var td = assembly.MainModule.GetType ("Java.Interop.__TypeRegistrations");
Assert.IsTrue ((td != null) == enabled);
}
}
}
}
}