diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs index c886772ecd0..9e21152f838 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs @@ -9,20 +9,16 @@ namespace Xamarin.Android.Tasks { /// - /// Filters a set of assemblies based on a given TargetFrameworkIdentifier or FallbackReference + /// Filters a set of assemblies to be known as "Xamarin.Android" assemblies through various checks: + /// * The presence of [assembly: System.Runtime.Versioning.TargetFramework("MonoAndroid,Version=v9.0")] + /// * A Mono.Android.dll reference + /// * An EmbeddedResource ending with *.jar + /// * An EmbeddedResource beginning with __Android /// public class FilterAssemblies : Task { - /// - /// The MonoAndroid portion of [assembly: System.Runtime.Versioning.TargetFramework("MonoAndroid,v9.0")] - /// - [Required] - public string TargetFrameworkIdentifier { get; set; } - - /// - /// If TargetFrameworkIdentifier is missing, we can look for Mono.Android.dll references instead - /// - public string FallbackReference { get; set; } + const string TargetFrameworkIdentifier = "MonoAndroid"; + const string MonoAndroidReference = "Mono.Android"; [Required] public bool DesignTimeBuild { get; set; } @@ -51,17 +47,21 @@ public override bool Execute () output.Add (assemblyItem); continue; } - // Fallback to looking at references - if (string.IsNullOrEmpty (targetFrameworkIdentifier) && !string.IsNullOrEmpty (FallbackReference)) { - Log.LogDebugMessage ($"Checking references for: {assemblyItem.ItemSpec}"); - foreach (var handle in reader.AssemblyReferences) { - var reference = reader.GetAssemblyReference (handle); - var name = reader.GetString (reference.Name); - if (FallbackReference == name) { - output.Add (assemblyItem); - break; - } - } + + // In the rare case, [assembly: TargetFramework("MonoAndroid,Version=v9.0")] may not match + Log.LogDebugMessage ($"{nameof (TargetFrameworkIdentifier)} did not match: {assemblyItem.ItemSpec}"); + + // Fallback to looking for a Mono.Android reference + if (HasReference (reader)) { + Log.LogDebugMessage ($"{MonoAndroidReference} reference found: {assemblyItem.ItemSpec}"); + output.Add (assemblyItem); + continue; + } + // Fallback to looking for *.jar or __Android EmbeddedResource files + if (HasEmbeddedResource (reader)) { + Log.LogDebugMessage ($"EmbeddedResource found: {assemblyItem.ItemSpec}"); + output.Add (assemblyItem); + continue; } } } @@ -69,5 +69,30 @@ public override bool Execute () return !Log.HasLoggedErrors; } + + bool HasReference (MetadataReader reader) + { + foreach (var handle in reader.AssemblyReferences) { + var reference = reader.GetAssemblyReference (handle); + var name = reader.GetString (reference.Name); + if (MonoAndroidReference == name) { + return true; + } + } + return false; + } + + bool HasEmbeddedResource (MetadataReader reader) + { + foreach (var handle in reader.ManifestResources) { + var resource = reader.GetManifestResource (handle); + var name = reader.GetString (resource.Name); + if (name.EndsWith (".jar", StringComparison.OrdinalIgnoreCase) || + name.StartsWith ("__Android", StringComparison.OrdinalIgnoreCase)) { + return true; + } + } + return false; + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index a75e5658faa..a4825c048f8 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -3862,6 +3862,30 @@ public void AbiDelimiters ([Values ("armeabi-v7a%3bx86", "armeabi-v7a,x86")] str Assert.IsTrue (b.Build (proj), "Build should have succeeded."); } } + + [Test] + public void WorkManager () + { + var proj = new XamarinFormsAndroidApplicationProject (); + proj.Sources.Add (new BuildItem.Source ("MyWorker.cs") { + TextContent = () => +@"using System; +using Android.Content; +using AndroidX.Work; + +public class MyWorker : Worker +{ + public MyWorker (Context c, WorkerParameters p) : base (c, p) { } + + public override Result DoWork () => Result.InvokeSuccess (); +} +" + }); + proj.PackageReferences.Add (KnownPackages.Android_Arch_Work_Runtime); + using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + } + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/FilterAssembliesTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/FilterAssembliesTests.cs index a75c14750e6..eba23511cc6 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/FilterAssembliesTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/FilterAssembliesTests.cs @@ -65,8 +65,6 @@ string [] Run (params string [] assemblies) { var task = new FilterAssemblies { BuildEngine = new MockBuildEngine (TestContext.Out), - TargetFrameworkIdentifier = "MonoAndroid", - FallbackReference = "Mono.Android", InputAssemblies = assemblies.Select (a => new TaskItem (a)).ToArray (), }; Assert.IsTrue (task.Execute (), "task.Execute() should have succeeded."); @@ -98,5 +96,16 @@ public async Task XamarinForms () }; CollectionAssert.AreEqual (expected, actual); } + + [Test] + public async Task GuavaListenableFuture () + { + var assemblies = await GetAssembliesFromNuGet ( + "https://www.nuget.org/api/v2/package/Xamarin.Google.Guava.ListenableFuture/1.0.0", + "lib/MonoAndroid50/"); + var actual = Run (assemblies); + var expected = new [] { "Xamarin.Google.Guava.ListenableFuture.dll" }; + CollectionAssert.AreEqual (expected, actual); + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs index 28a5ac1dd6e..ef0e9d19ea3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs @@ -625,6 +625,16 @@ public static class KnownPackages } } }; + public static Package Android_Arch_Work_Runtime = new Package { + Id = "Xamarin.Android.Arch.Work.Runtime", + Version = "1.0.0", + TargetFramework = "MonoAndroid90", + References = { + new BuildItem.Reference("Xamarin.Android.Arch.Work.Runtime") { + MetadataValues = "HintPath=..\\packages\\Xamarin.Android.Arch.Work.Runtime.1.0.0\\lib\\MonoAndroid90\\Xamarin.Android.Arch.Work.Runtime.dll" + } + } + }; public static Package Xamarin_Android_Crashlytics_2_9_4 = new Package { Id = "Xamarin.Android.Crashlytics", Version = "2.9.4", diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 00e2ec8a8b0..9bf4a91f0b6 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -518,8 +518,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.