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 0f24f1ac54a..e30998962d0 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
@@ -1832,14 +1832,53 @@ public void BuildPropsBreaksConvertResourcesCasesOnSecondBuild ([Values (Android
Assert.IsTrue (secondAssemblyWrite > firstAssemblyWrite,
$"Assembly write time was not updated on partially incremental build. Before: {firstAssemblyWrite}. After: {secondAssemblyWrite}.");
- // TODO: NativeAOT fails this with "Apk write time was not updated on partially incremental build. Before: 1/1/1981 1:01:02 AM. After: 1/1/1981 1:01:02 AM."
- if (runtime != AndroidRuntime.NativeAOT) {
- Assert.IsTrue (secondApkWrite > firstApkWrite,
- $"Apk write time was not updated on partially incremental build. Before: {firstApkWrite}. After: {secondApkWrite}.");
- }
+ Assert.IsTrue (secondApkWrite > firstApkWrite,
+ $"Apk write time was not updated on partially incremental build. Before: {firstApkWrite}. After: {secondApkWrite}.");
}
}
+ [Test]
+ public void UniversalApkFromBundleIsIncremental ()
+ {
+ if (IgnoreUnsupportedConfiguration (AndroidRuntime.CoreCLR, release: true)) {
+ return;
+ }
+
+ var proj = new XamarinAndroidApplicationProject {
+ IsRelease = true,
+ };
+ proj.SetRuntime (AndroidRuntime.CoreCLR);
+ proj.SetProperty (KnownProperties.RuntimeIdentifier, "android-arm64");
+ proj.SetProperty ("AndroidPackageFormats", "aab;apk");
+
+ using var builder = CreateApkBuilder ();
+ Assert.IsTrue (builder.Build (proj), "First build should have succeeded.");
+ builder.Output.AssertTargetIsNotSkipped ("_CreateUniversalApkFromBundle");
+
+ var outputDirectory = Path.Combine (Root, builder.ProjectDirectory, proj.OutputPath);
+ var signedApk = Directory.GetFiles (outputDirectory, "*-Signed.apk", SearchOption.AllDirectories).Single ();
+ var firstWriteTime = File.GetLastWriteTimeUtc (signedApk);
+
+ Assert.IsTrue (builder.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "No-op build should have succeeded.");
+ builder.Output.AssertTargetIsSkipped ("_CreateUniversalApkFromBundle");
+ Assert.AreEqual (firstWriteTime, File.GetLastWriteTimeUtc (signedApk), "No-op builds should preserve the signed APK timestamp.");
+
+ Assert.IsTrue (
+ builder.Build (proj, parameters: new [] { "AndroidBundleToolExtraArgs=--overwrite" }, doNotCleanupOnUpdate: true, saveProject: false),
+ "Changing bundletool arguments should have succeeded.");
+ builder.Output.AssertTargetIsNotSkipped ("_CreateUniversalApkFromBundle");
+
+ Assert.IsTrue (
+ builder.Build (proj, parameters: new [] { "AndroidBundleToolExtraArgs=" }, doNotCleanupOnUpdate: true, saveProject: false),
+ "Clearing bundletool arguments should have succeeded.");
+ builder.Output.AssertTargetIsNotSkipped ("_CreateUniversalApkFromBundle");
+
+ Assert.IsTrue (
+ builder.Build (proj, parameters: new [] { "AndroidBundleToolExtraArgs=" }, doNotCleanupOnUpdate: true, saveProject: false),
+ "No-op build after clearing bundletool arguments should have succeeded.");
+ builder.Output.AssertTargetIsSkipped ("_CreateUniversalApkFromBundle");
+ }
+
[Test]
public void AfterILLinkAdditionalStepsIsSkippedOnSecondBuild ([Values (AndroidRuntime.CoreCLR, AndroidRuntime.NativeAOT)] AndroidRuntime runtime)
{
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index 1e57801422e..f050205a471 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -976,11 +976,15 @@ because xbuild doesn't support framework reference assemblies.
<_PropertyCacheItems Include="AndroidDexTool=$(AndroidDexTool)" />
<_PropertyCacheItems Include="AndroidLinkTool=$(AndroidLinkTool)" />
<_PropertyCacheItems Include="AndroidLinkResources=$(AndroidLinkResources)" />
+ <_PropertyCacheItems Include="AndroidBundleToolExtraArgs=$(AndroidBundleToolExtraArgs)" />
+ <_PropertyCacheItems Include="AndroidKeyStore=$(AndroidKeyStore)" />
<_PropertyCacheItems Include="AndroidPackageFormat=$(AndroidPackageFormat)" />
<_PropertyCacheItems Include="EmbedAssembliesIntoApk=$(EmbedAssembliesIntoApk)" />
<_PropertyCacheItems Include="AndroidLinkMode=$(AndroidLinkMode)" />
<_PropertyCacheItems Include="AndroidLinkSkip=$(AndroidLinkSkip)" />
<_PropertyCacheItems Include="AndroidSdkBuildToolsVersion=$(AndroidSdkBuildToolsVersion)" />
+ <_PropertyCacheItems Include="Aapt2ToolPath=$(Aapt2ToolPath)" />
+ <_PropertyCacheItems Include="Aapt2ToolExe=$(Aapt2ToolExe)" />
<_PropertyCacheItems Include="AndroidSdkPath=$(_AndroidSdkDirectory)" />
<_PropertyCacheItems Include="AndroidNdkPath=$(_AndroidNdkDirectory)" />
<_PropertyCacheItems Include="JavaSdkPath=$(_JavaSdkDirectory)" />
@@ -2672,12 +2676,26 @@ because xbuild doesn't support framework reference assemblies.
+
+
+ <_UniversalApkAapt2ToolExe Condition=" '$(Aapt2ToolExe)' != '' ">$(Aapt2ToolExe)
+ <_UniversalApkAapt2ToolExe Condition=" '$(_UniversalApkAapt2ToolExe)' == '' and '$(OS)' == 'Windows_NT' ">aapt2.exe
+ <_UniversalApkAapt2ToolExe Condition=" '$(_UniversalApkAapt2ToolExe)' == '' ">aapt2
+ <_UniversalApkAapt2ToolPath>$([System.IO.Path]::Combine('$(Aapt2ToolPath)', '$(_UniversalApkAapt2ToolExe)'))
+
+ <_UniversalApkAlwaysRunInput Condition=" '$(AndroidKeyStore)' == 'True' or '$(AndroidBundleToolExtraArgs)' != '' ">$(IntermediateOutputPath)__always_rebuild_universal_apk__
+
+
+
-
+
+
+