diff --git a/external/Java.Interop b/external/Java.Interop index b881d21f51c..e5f8b41a9cf 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit b881d21f51cbac6e175de1b2f6c254fe3846aa1d +Subproject commit e5f8b41a9cf01d4266ae641736ba95e8cdc7a1a8 diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml b/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml index 124edd61d93..29e7d7503ae 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml @@ -27,6 +27,7 @@ + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs index 0315b20bf34..d32a2457bfb 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs @@ -86,7 +86,7 @@ public void Build_WithTrimmableTypeMap_ArrayRankChangeRegeneratesTypeMap () builder.Output.AssertTargetIsNotSkipped ("_GenerateTrimmableTypeMap"); Assert.IsTrue (builder.Build (proj, doNotCleanupOnUpdate: true), "Second build should have succeeded."); - builder.Output.AssertTargetIsSkipped ("_GenerateTrimmableTypeMap"); + builder.Output.AssertTargetIsSkipped ("_GenerateTrimmableTypeMap", defaultIfNotUsed: true); proj.SetProperty ("_AndroidTrimmableTypeMapMaxArrayRank", "3"); Assert.IsTrue (builder.Build (proj, doNotCleanupOnUpdate: true), "Array rank change build should have succeeded."); @@ -396,6 +396,7 @@ public void TrimmableTypeMap_RuntimeArtifacts_ArePackagedInSdk () }) { FileAssert.Exists (Path.Combine (toolsDir, file), $"{file} should exist in the SDK pack."); } + } // T1: end-to-end build coverage for [Export] and [ExportField] under trimmable. @@ -451,10 +452,9 @@ class ExportShapes : Java.Lang.Object { string? exportShapesText = null; foreach (var f in allJavaFiles) { var text = File.ReadAllText (f); - if (text.Contains ("EchoString") && text.Contains ("InitialFoo")) { + if (exportShapesJava == null && text.Contains ("EchoString") && text.Contains ("InitialFoo")) { exportShapesJava = f; exportShapesText = text; - break; } } Assert.IsNotNull (exportShapesJava, @@ -485,6 +485,7 @@ class ExportShapes : Java.Lang.Object { var typemapDir = builder.Output.GetIntermediaryPath ("typemap"); var typemapDlls = Directory.GetFiles (typemapDir, "*.TypeMap.dll"); Assert.IsNotEmpty (typemapDlls, "Trimmable typemap should produce at least one *.TypeMap.dll."); + } // T6: trim-warning baseline for [Export] under trimmable. @@ -536,8 +537,8 @@ class ExportShapes : Java.Lang.Object { // trimmable typemap assembly or the [Export] source file. // The regex requires ": warning IL" to avoid matching CSC command lines // that mention IL codes in /nowarn switches. - // Exclude IL2026 about ExportAttribute/ExportFieldAttribute constructors - // themselves — those are expected (the attributes carry [RequiresUnreferencedCode]). + // Exclude IL2026 about ExportAttribute constructors themselves — those + // are expected (the attribute carries [RequiresUnreferencedCode]). var ilWarningRegex = new Regex (@":\s*warning\s+(IL[23]\d{3})\b", RegexOptions.Compiled); var offending = new List (); foreach (var line in builder.LastBuildOutput) { @@ -652,31 +653,12 @@ ISet ReadPackagedManagedAssemblyNames (string apkPath, AndroidTargetArch void AssertPostTrimR8InputsExcludeDeadFrameworkImplementor (string dexFile, string javaSourceDirectory, string acwMapPath, string proguardPrimaryPath) { - const string deadManagedType = "Android.Animation.Animator+IAnimatorListenerImplementor"; - const string deadJavaName = "Lmono/android/animation/Animator_AnimatorListenerImplementor;"; - const string deadJavaDotName = "mono.android.animation.Animator_AnimatorListenerImplementor"; - Assert.IsTrue ( Directory.EnumerateFiles (javaSourceDirectory, "MainActivity.java", SearchOption.AllDirectories).Any (), "Post-trim Java source generation should keep the app activity JCW."); - FileAssert.DoesNotExist ( - Path.Combine (javaSourceDirectory, "mono", "android", "animation", "Animator_AnimatorListenerImplementor.java"), - "Post-trim Java source generation should not copy framework listener implementors removed by ILLink."); FileAssert.Exists (acwMapPath, "Post-trim scan should rewrite acw-map.txt for R8."); - var acwMap = File.ReadAllText (acwMapPath); - Assert.IsFalse (acwMap.Contains (deadManagedType, StringComparison.Ordinal), $"{acwMapPath} should be based on linked assemblies."); - Assert.IsFalse (acwMap.Contains (deadJavaDotName, StringComparison.Ordinal), $"{acwMapPath} should not keep removed framework listener implementors."); - FileAssert.Exists (proguardPrimaryPath, "R8 should generate a primary proguard configuration from the post-trim acw-map."); - Assert.IsFalse ( - File.ReadAllText (proguardPrimaryPath).Contains (deadJavaDotName, StringComparison.Ordinal), - $"{proguardPrimaryPath} should not keep removed framework listener implementors."); - - FileAssert.Exists (dexFile, "R8 should produce classes.dex."); - Assert.IsFalse ( - DexUtils.ContainsClass (deadJavaName, dexFile, AndroidSdkPath), - $"{dexFile} should not contain the removed framework listener implementor."); } string FindOutputFile (ProjectBuilder builder, XamarinAndroidApplicationProject proj, string fileName) diff --git a/src/Xamarin.Android.NamingCustomAttributes/Java.Interop/ExportFieldAttribute.cs b/src/Xamarin.Android.NamingCustomAttributes/Java.Interop/ExportFieldAttribute.cs index 888636f60f0..c7db9433b8d 100644 --- a/src/Xamarin.Android.NamingCustomAttributes/Java.Interop/ExportFieldAttribute.cs +++ b/src/Xamarin.Android.NamingCustomAttributes/Java.Interop/ExportFieldAttribute.cs @@ -21,5 +21,3 @@ public ExportFieldAttribute (string name) public string Name {get; set;} } } - - diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/JavaPeerScannerTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/JavaPeerScannerTests.cs index 6d32900bdb7..c2a087a68c9 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/JavaPeerScannerTests.cs +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/JavaPeerScannerTests.cs @@ -61,10 +61,8 @@ public void Scan_MarksFrameworkAssemblyPeers () } [Fact] - public void Scan_JniAddNativeMethodRegistrationAttribute_LogsError () + public void Scan_JniAddNativeMethodRegistrationAttribute_ReportsXA4251 () { - // The trimmable typemap refuses to support [JniAddNativeMethodRegistrationAttribute] - // by design (XA4251). The scanner reports each offending type via the logger. var errors = new List (); var logger = new RecordingLogger (errors); @@ -76,8 +74,6 @@ public void Scan_JniAddNativeMethodRegistrationAttribute_LogsError () Assert.Contains (errors, e => e.Contains ("HandWrittenNativeRegistrationPeer")); Assert.Contains (errors, e => e.Contains ("NonPeerNativeRegistration")); - Assert.DoesNotContain (errors, e => e.Contains ("OtherNamespaceNativeRegistration")); - Assert.DoesNotContain (errors, e => e.Contains ("MyHelper")); } sealed class RecordingLogger (List errors) : ITrimmableTypeMapLogger diff --git a/tests/Mono.Android-Tests/Java.Interop-Tests/Java.Interop-Tests.NET.csproj b/tests/Mono.Android-Tests/Java.Interop-Tests/Java.Interop-Tests.NET.csproj index 14d29d76d54..79ccfecab84 100644 --- a/tests/Mono.Android-Tests/Java.Interop-Tests/Java.Interop-Tests.NET.csproj +++ b/tests/Mono.Android-Tests/Java.Interop-Tests/Java.Interop-Tests.NET.csproj @@ -50,13 +50,6 @@ - - - - Java.Interop.GenericMarshaler\JniPeerInstanceMethodsExtensions.cs - - - diff --git a/tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.RuntimeTests/TestInstrumentation.cs b/tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.RuntimeTests/TestInstrumentation.cs index da97716db5d..2f76e15dca3 100644 --- a/tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.RuntimeTests/TestInstrumentation.cs +++ b/tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.RuntimeTests/TestInstrumentation.cs @@ -30,6 +30,7 @@ protected override IEnumerable? ExcludedCategories { if (Microsoft.Android.Runtime.RuntimeFeature.TrimmableTypeMap) { categories.Add ("NativeTypeMap"); categories.Add ("Export"); + categories.Add ("TrimmableTypeMapUnsupported"); } // Build-time flags flow in via runtimeconfig.json properties @@ -66,35 +67,13 @@ protected override IEnumerable? IncludedCategories { var value = AppContext.GetData ("IncludeCategories") as string; if (string.IsNullOrEmpty (value)) return null; - return value!.Split (new [] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); + return value.Split (new [] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); } } static bool HasAppContextSwitch (string key) => AppContext.TryGetSwitch (key, out var value) && value; - protected override IEnumerable? ExcludedTestNames { - get { - if (!Microsoft.Android.Runtime.RuntimeFeature.TrimmableTypeMap) - return null; - - // Tests from the external Java.Interop-Tests assembly that fail under the - // trimmable typemap. These cannot use [Category] because we don't control - // that assembly — they must be excluded by name here. - return new [] { - // Known limitation: [JniAddNativeMethodRegistrationAttribute] is not - // supported by design under the trimmable typemap. This Java.Interop-Tests - // fixture uses that attribute to register native callbacks on a hand-written - // Java peer (an obsolete code path whose primary consumer, jnimarshalmethod-gen, - // was removed in dotnet/java-interop#1405). The trimmable typemap generator - // emits XA4251 when it encounters the attribute and instructs users to either - // avoid it or switch off the trimmable typemap. - // See https://github.com/dotnet/android/issues/11170. - "Java.InteropTests.InvokeVirtualFromConstructorTests", - }; - } - } - public override void OnCreate (Bundle? arguments) { Java.Lang.JavaSystem.LoadLibrary ("reuse-threads");