diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs index 71d84632289..cd37887aca0 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs @@ -90,8 +90,9 @@ public override bool Execute () var stampFile = !string.IsNullOrEmpty (stamp) ? stamp : $"{filename}.stamp"; Log.LogDebugMessage ($"{filename} {stampFile}"); output.Add (new TaskItem (file, new Dictionary { - { "StampFile" , $"{stampFile}" }, - { "Hash" , $"{filename}" }, + { "StampFile" , stampFile }, + { "Hash" , filename }, + { "ResourceDirectory", resdir.ItemSpec } })); } Processed = output.ToArray (); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs index 516808375d7..c9e28e2950b 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs @@ -525,6 +525,88 @@ public void ProduceReferenceAssembly () } } + [Test] + public void ConvertCustomView ([Values (true, false)] bool useAapt2) + { + var path = Path.Combine ("temp", TestName); + var app = new XamarinAndroidApplicationProject { + ProjectName = "MyApp", + Sources = { + new BuildItem.Source ("Foo.cs") { + TextContent = () => "public class Foo : Bar { }" + }, + new BuildItem.Source ("CustomTextView.cs") { + TextContent = () => + @"using Android.Widget; + using Android.Content; + using Android.Util; + namespace MyApp + { + public class CustomTextView : TextView + { + public CustomTextView(Context context, IAttributeSet attributes) : base(context, attributes) + { + } + } + }" + } + } + }; + // Use a custom view + app.LayoutMain = app.LayoutMain.Replace ("", ""); + //NOTE: so _BuildApkEmbed runs in commercial tests + app.SetProperty ("EmbedAssembliesIntoApk", "True"); + app.SetProperty ("AndroidUseSharedRuntime", "False"); + app.SetProperty ("AndroidUseAapt2", useAapt2.ToString ()); + + int count = 0; + var lib = new DotNetStandard { + ProjectName = "MyLibrary", + Sdk = "Microsoft.NET.Sdk", + TargetFramework = "netstandard2.0", + Sources = { + new BuildItem.Source ("Bar.cs") { + TextContent = () => "public class Bar { public Bar () { System.Console.WriteLine (" + count++ + "); } }" + }, + } + }; + //NOTE: this test is checking when $(ProduceReferenceAssembly) is False + lib.SetProperty ("ProduceReferenceAssembly", "False"); + app.References.Add (new BuildItem.ProjectReference ($"..\\{lib.ProjectName}\\{lib.ProjectName}.csproj", lib.ProjectName, lib.ProjectGuid)); + + using (var libBuilder = CreateDllBuilder (Path.Combine (path, lib.ProjectName), false)) + using (var appBuilder = CreateApkBuilder (Path.Combine (path, app.ProjectName))) { + Assert.IsTrue (libBuilder.Build (lib), "first library build should have succeeded."); + Assert.IsTrue (appBuilder.Build (app), "first app build should have succeeded."); + + lib.Touch ("Bar.cs"); + + Assert.IsTrue (libBuilder.Build (lib, doNotCleanupOnUpdate: true, saveProject: false), "second library build should have succeeded."); + Assert.IsTrue (appBuilder.Build (app, doNotCleanupOnUpdate: true, saveProject: false), "second app build should have succeeded."); + + var targetsShouldSkip = new [] { + "_BuildLibraryImportsCache", + "_ResolveLibraryProjectImports", + "_ConvertCustomView", + }; + foreach (var target in targetsShouldSkip) { + Assert.IsTrue (appBuilder.Output.IsTargetSkipped (target), $"`{target}` should be skipped!"); + } + + var targetsShouldRun = new [] { + //MyLibrary.dll changed and $(ProduceReferenceAssembly)=False + "CoreCompile", + "_GenerateJavaStubs", + "_BuildApkEmbed", + "_CopyPackage", + "_Sign", + }; + foreach (var target in targetsShouldRun) { + Assert.IsFalse (appBuilder.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped!"); + } + } + } + [Test] public void ResolveLibraryProjectImports () { diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index d40e85e6d61..e254f4ae235 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -2309,34 +2309,41 @@ because xbuild doesn't support framework reference assemblies. + + + + + CustomViewMapFile="$(_CustomViewMapFile)" + AcwMapFile="$(_AcwMapFile)" + ResourceDirectories="$(MonoAndroidResDirIntermediate);@(_LibraryResourceHashDirectories)" + ResourceNameCaseMap="$(_AndroidResourceNameCaseMap)"> - + Condition=" '$(AndroidUseAapt2)' == 'True' And '@(_ProcessedCustomViews)' != '' " + ContinueOnError="$(DesignTimeBuild)" + ResourceDirectories="@(_ProcessedCustomViews->'%(ResourceDirectory)'->Distinct())" + ExplicitCrunch="$(AndroidExplicitCrunch)" + ExtraArgs="$(AndroidAapt2CompileExtraArgs)" + FlatArchivesDirectory="$(_AndroidLibraryFlatArchivesDirectory)" + ToolPath="$(Aapt2ToolPath)" + ToolExe="$(Aapt2ToolExe)"> - - + <_GeneratePackageManagerJavaDependsOn> _GenerateJavaStubs; + _ConvertCustomView; _GenerateEnvironmentFiles; _AddStaticResources; $(_AfterAddStaticResources); @@ -2453,6 +2461,7 @@ because xbuild doesn't support framework reference assemblies. <_CreateBaseApkDependsOnTargets> _GenerateJavaStubs; + _ConvertCustomView; _GenerateEnvironmentFiles; _GetLibraryImports; _CheckDuplicateJavaLibraries; @@ -2578,7 +2587,7 @@ because xbuild doesn't support framework reference assemblies. - + @@ -2944,6 +2953,7 @@ because xbuild doesn't support framework reference assemblies. _CopyMdbFiles; _LinkAssemblies; _GenerateJavaStubs; + _ConvertCustomView; _GenerateEnvironmentFiles; _CompileJava; _CompileDex;