diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs index 25e9db22008..a1805b8253b 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs @@ -226,7 +226,7 @@ static bool IsUnconditionalEntry (JavaPeerInfo peer) // User-defined ACW types (not MCW bindings, not interfaces) are unconditional // because Android can instantiate them from Java at any time. - if (!peer.DoNotGenerateAcw && !peer.IsInterface) { + if (!peer.IsFrameworkAssembly && !peer.DoNotGenerateAcw && !peer.IsInterface) { return true; } diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs index 97606a4b5af..6b30ec1d3ef 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs @@ -43,6 +43,13 @@ public sealed record JavaPeerInfo /// public required string AssemblyName { get; init; } + /// + /// True when the type belongs to a framework assembly supplied by the Android SDK. + /// Framework ACWs are generated by the SDK and can be trimmed like bindings unless + /// another rule explicitly roots them. + /// + public bool IsFrameworkAssembly { get; set; } + /// /// JNI name of the base Java type, e.g., "android/app/Activity" for a type /// that extends Activity. Null for java/lang/Object or types without a Java base. diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/TrimmableTypeMapGenerator.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/TrimmableTypeMapGenerator.cs index 4851fde0857..35c55c6834f 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/TrimmableTypeMapGenerator.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/TrimmableTypeMapGenerator.cs @@ -48,6 +48,7 @@ public TrimmableTypeMapResult Execute ( logger.LogNoJavaPeerTypesFound (); return new TrimmableTypeMapResult ([], [], allPeers); } + MarkFrameworkAssemblyPeers (allPeers, frameworkAssemblyNames); RootManifestReferencedTypes (allPeers, PrepareManifestForRooting (manifestTemplate, manifestConfig)); PropagateDeferredRegistrationToBaseClasses (allPeers); @@ -188,6 +189,15 @@ List GenerateTypeMapAssemblies (List allPeers, return generatedAssemblies; } + static void MarkFrameworkAssemblyPeers (List allPeers, HashSet frameworkAssemblyNames) + { + foreach (var peer in allPeers) { + if (frameworkAssemblyNames.Contains (peer.AssemblyName)) { + peer.IsFrameworkAssembly = true; + } + } + } + /// /// Groups peers by assembly, merging cross-assembly aliases into a single group. /// When the same JNI name appears in multiple assemblies (e.g. Java.Lang.Object diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets index d0ca9742e30..4d3b1470ee2 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets @@ -5,6 +5,10 @@ <_TrimmableRuntimeProviderJavaName Condition=" '$(_TrimmableRuntimeProviderJavaName)' == '' ">mono.MonoRuntimeProvider + + <_GenerateProguardAfterTargets Condition=" '$(_GenerateProguardAfterTargets)' == '' ">ILLink + + %(Filename)%(Extension) + true @@ -20,9 +25,33 @@ + + <_TrimmableTypeMapEntryAssemblies Include="$(_TypeMapOutputDirectory)*.TypeMap.dll" /> + - <_ExtraTrimmerArgs>--typemap-entry-assembly $(_TypeMapAssemblyName) $(_ExtraTrimmerArgs) + <_ExtraTrimmerArgs>@(_TrimmableTypeMapEntryAssemblies->'--typemap-entry-assembly %(Filename)', ' ') $(_ExtraTrimmerArgs) + + <_TrimmableTypeMapEntryAssemblies Remove="@(_TrimmableTypeMapEntryAssemblies)" /> + + + + + + <_LinkedAssemblyForProguard Include="@(ResolvedFileToPublish)" Condition=" '%(Extension)' == '.dll' " /> + + + + +