From 830a2a622bacd85b9c3f8c3033867a974d2c4474 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 3 May 2022 16:21:42 -0500 Subject: [PATCH] [Xamarin.Build.Download] remove AndroidAarFixups Context: https://github.com/dotnet/runtime/issues/68734 A breaking chang in in .NET 7 has uncovered an issue when using Xamarin.Build.Download: Renaming: AndroidManifest.xml to AndroidManifest.xml ... (_XamarinBuildDownloadCore target) -> /Users/runner/.nuget/packages/xamarin.build.download/0.11.0/buildTransitive/Xamarin.Build.Download.targets(52,3): error XBD001: Download failed. Please download https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/17.6.0/play-services-basement-17.6.0.aar to a file called /Users/runner/Library/Caches/XamarinBuildDownload/playservicesbasement-17.6.0.aar. /Users/runner/.nuget/packages/xamarin.build.download/0.11.0/buildTransitive/Xamarin.Build.Download.targets(52,3): error XBD001: Download failed. Please download https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-tasks/17.2.1/play-services-tasks-17.2.1.aar to a file called /Users/runner/Library/Caches/XamarinBuildDownload/playservicestasks-17.2.1.aar. /Users/runner/.nuget/packages/xamarin.build.download/0.11.0/buildTransitive/Xamarin.Build.Download.targets(52,3): error XBD001: Download failed. Please download https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-base/17.6.0/play-services-base-17.6.0.aar to a file called /Users/runner/Library/Caches/XamarinBuildDownload/playservicesbase-17.6.0.aar. /Users/runner/.nuget/packages/xamarin.build.download/0.11.0/buildTransitive/Xamarin.Build.Download.targets(52,3): error XBD001: Download failed. Please download https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-maps/17.0.1/play-services-maps-17.0.1.aar to a file called /Users/runner/Library/Caches/XamarinBuildDownload/playservicesmaps-17.0.1.aar. 1 Warning(s) 4 Error(s) The exception is somewhat swallowed here, the underlying error is something like: System.InvalidOperationException : An entry named 'AndroidManifest.xml' already exists in the archive. This class had various "fixups" to workaround issues in Xamarin.Android. Many of these issues have long since been fixed. 1. Removal of `aapt/AndroidManifest.xml`. Xamarin.Android has been handling this since ~Sept 2018: https://github.com/xamarin/xamarin-android/commit/f6c3288dd5a7f82c178ef30ad25c11d475f1daf4 2. Removal of `internal_impl-*.jar`. Xamarin.Android has been handling this since ~Feb 2018: https://github.com/xamarin/xamarin-android/commit/6a8ea2bbdbad65f1f46ba60a343506c92d1e0a1e 3. Replacement of `android:name=".SomeService"` as shorthand for `androidx.foo.SomeService` in the `androidx.foo` package. The use of `manifest-merger` solves this issue completely. This setting is the default for .NET 6, and has been the default for AndroidX since ~July 2020: https://github.com/xamarin/AndroidX/commit/c6c0e5033c825e0b13e5a5a0aa896dcafe43e6f6 --- .../AndroidAarFixups.cs | 124 ------------------ .../Xamarin.Build.Download.targets | 3 - .../XamarinDownloadArchives.cs | 6 - .../XamarinDownloadPartialZips.cs | 6 - 4 files changed, 139 deletions(-) delete mode 100644 Util/Xamarin.Build.Download/source/Xamarin.Build.Download/AndroidAarFixups.cs diff --git a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/AndroidAarFixups.cs b/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/AndroidAarFixups.cs deleted file mode 100644 index 6429df7e59..0000000000 --- a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/AndroidAarFixups.cs +++ /dev/null @@ -1,124 +0,0 @@ -using Microsoft.Build.Utilities; -using System; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Xml.Linq; - -namespace Xamarin.Build.Download -{ - static class AndroidAarFixups - { - internal static void FixupAar(string filename, bool androidFixManifests, TaskLoggingHelper loggingHelper) - { - using (var fileStream = new FileStream(filename, FileMode.Open)) - using (var zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Update, true)) - { - var entryNames = zipArchive.Entries.Select(zae => zae.FullName).ToList(); - - loggingHelper.LogMessage("Found {0} entries in {1}", entryNames.Count, filename); - - foreach (var entryName in entryNames) - { - var newName = entryName; - - // Open the old entry - var oldEntry = zipArchive.GetEntry(entryName); - - // Some .aars contain an AndroidManifest.xml in the aapt folder which is essentially a duplicate of the main one - // but a sanitized version with placeholders like ${applicationId} being escaped to _dollar blah - // we don't care about these for xamarin.android, which picks up both manifests and merges both - // This will ensure the 'sanitized' version doesn't get packaged - if (entryName.TrimStart('/').Equals("aapt/AndroidManifest.xml", StringComparison.InvariantCultureIgnoreCase)) - { - loggingHelper.LogMessage("Found aapt/AndroidManifest.xml, skipping..."); - // Delete the entry entirely and continue - oldEntry.Delete(); - continue; - } - - // We are only re-adding non empty folders, otherwise we end up with a corrupt zip in mono - if (!string.IsNullOrEmpty(oldEntry.Name)) - { - - // SPOILER ALERT: UGLY WORKAROUND - // In the Android Support libraries, there exist multiple .aar files which have a `libs/internal_impl-25.0.0` file. - // In Xamarin.Android, there is a Task "CheckDuplicateJavaLibraries" which inspects jar files being pulled in from .aar files - // in assemblies to see if there exist any files with the same name but different content, and will throw an error if it finds any. - // However, for us, it is perfectly valid to have this scenario and we should not see an error. - // We are working around this by detecting files named like this, and renaming them to some unique value - // in this case, a part of the hash of the assembly name. - var newFile = Path.GetFileName(newName); - var newDir = Path.GetDirectoryName(newName); - - if (newFile.StartsWith("internal_impl", StringComparison.InvariantCulture)) - newName = Path.Combine(newDir, "internal_impl-" + DownloadUtils.Crc64(filename).Substring(0, 6) + ".jar"); - - loggingHelper.LogMessage("Renaming: {0} to {1}", entryName, newName); - - // Create a new entry based on our new name - var newEntry = zipArchive.CreateEntry(newName); - - // Since Xamarin.Android's AndoridManifest.xml merging code is not as sophisticated as gradle's yet, we may need - // to fix some things up in the manifest file to get it to merge properly into our applications - // Here we will check to see if Fixing manifests was enabled, and if the entry we are on is the AndroidManifest.xml file - if (androidFixManifests && oldEntry.Length > 0 && newName.EndsWith("AndroidManifest.xml", StringComparison.OrdinalIgnoreCase)) - { - - // android: namespace - XNamespace xns = "http://schemas.android.com/apk/res/android"; - - using (var oldStream = oldEntry.Open()) - using (var xmlReader = System.Xml.XmlReader.Create(oldStream)) - { - var xdoc = XDocument.Load(xmlReader); - - // BEGIN FIXUP #1 - // Some `android:name` attributes will start with a . indicating, that the `package` value of the `manifest` element - // should be prefixed dynamically/at merge to this attribute value. Xamarin.Android doesn't handle this case yet - // so we are going to manually take care of it. - - // Get the package name from the manifest node - var packageName = xdoc.Document.Descendants("manifest")?.FirstOrDefault()?.Attribute("package")?.Value; - - if (!string.IsNullOrEmpty(packageName)) - { - // Find all elements in the xml document that have a `android:name` attribute which starts with a . - // Select all of them, and then change the `android:name` attribute value to be the - // package name we found in the `manifest` element previously + the original attribute value - xdoc.Document.Descendants() - .Where(elem => elem.Attribute(xns + "name")?.Value?.StartsWith(".", StringComparison.Ordinal) ?? false) - .ToList() - .ForEach(elem => elem.SetAttributeValue(xns + "name", packageName + elem.Attribute(xns + "name").Value)); - } - // END FIXUP #1 - - using (var newStream = newEntry.Open()) - using (var xmlWriter = System.Xml.XmlWriter.Create(newStream)) - { - xdoc.WriteTo(xmlWriter); - } - } - - } - else - { - // Copy file contents over if they exist - if (oldEntry.Length > 0) - { - using (var oldStream = oldEntry.Open()) - using (var newStream = newEntry.Open()) - { - oldStream.CopyTo(newStream); - } - } - } - } - - // Delete the old entry regardless of if it's a folder or not - oldEntry.Delete(); - } - } - } - } -} diff --git a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/Xamarin.Build.Download.targets b/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/Xamarin.Build.Download.targets index 90825c8563..388b6fa092 100644 --- a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/Xamarin.Build.Download.targets +++ b/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/Xamarin.Build.Download.targets @@ -20,7 +20,6 @@ <_XamarinBuildDownloadIsAndroid>true <_XamarinBuildDownloadMasterBeforeTargets>_ResolveLibraryProjectImports <_XamarinBuildDownloadMasterDependsOnTargets>ResolveAssemblyReferences;_XamarinBuildDownload;_XamarinBuildDownloadAarRestore;_XamarinBuildDownloadAarInclude - <_XamarinBuildDownloadAndroidFixManifests Condition="'$(_XamarinBuildDownloadAndroidFixManifests)' == ''">true @@ -58,7 +57,6 @@ User7ZipPath="$(XamarinBuildDownloadUser7ZipPath)" VsInstallRoot="$(VsInstallRoot)" IsAndroid="$(_XamarinBuildDownloadIsAndroid)" - AndroidFixManifests="$(_XamarinBuildDownloadAndroidFixManifests)" /> @@ -69,7 +67,6 @@ Parts="@(XamarinBuildDownloadPartialZip)" CacheDirectory="$(XamarinBuildDownloadDir)" IsAndroid="$(_XamarinBuildDownloadIsAndroid)" - AndroidFixManifests="$(_XamarinBuildDownloadAndroidFixManifests)" /> diff --git a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadArchives.cs b/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadArchives.cs index f592a4f4db..254f38d5e0 100644 --- a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadArchives.cs +++ b/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadArchives.cs @@ -32,8 +32,6 @@ public class XamarinDownloadArchives : AsyncTask, ILogger public bool IsAndroid { get; set; } - public bool AndroidFixManifests { get; set; } - DownloadUtils downloadUtils; public override bool Execute () @@ -171,10 +169,6 @@ async Task MakeSureLibraryIsInPlace (XamarinBuildDownload xbd, Cancellatio LogMessage (" Downloading {0} to {1}", xbd.Url, xbd.CacheFile); client.DownloadFileTaskAsync (xbd.Url, xbd.CacheFile).Wait (token); - // Run through our AAR fixups if it's android - if (IsAndroid) - AndroidAarFixups.FixupAar(xbd.CacheFile, AndroidFixManifests, Log); - LogMessage (" Downloading Complete"); client.DownloadProgressChanged -= downloadHandler; } diff --git a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadPartialZips.cs b/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadPartialZips.cs index d9f99d7eee..3ea05326dd 100644 --- a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadPartialZips.cs +++ b/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/XamarinDownloadPartialZips.cs @@ -21,8 +21,6 @@ public class XamarinDownloadPartialZips : AsyncTask, ILogger public bool IsAndroid { get; set; } - public bool AndroidFixManifests { get; set; } - HttpClient http; public override bool Execute () @@ -178,10 +176,6 @@ async Task ExtractPartAndValidate (PartialZipDownload part, Stream partInp return false; } - // Run through our AAR fixups if it's android - if (IsAndroid) - AndroidAarFixups.FixupAar(outputPath, AndroidFixManifests, Log); - return true; }