diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CollectNonEmptyDirectories.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CollectNonEmptyDirectories.cs index 0be8215d470..c595863f6c7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CollectNonEmptyDirectories.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CollectNonEmptyDirectories.cs @@ -21,9 +21,11 @@ public override bool Execute () foreach (var directory in Directories) { var firstFile = Directory.EnumerateFiles(directory.ItemSpec, "*.*", SearchOption.AllDirectories).FirstOrDefault (); if (firstFile != null) { - output.Add (new TaskItem (directory.ItemSpec, new Dictionary () { + var taskItem = new TaskItem (directory.ItemSpec, new Dictionary () { {"FileFound", firstFile} - })); + }); + directory.CopyMetadataTo (taskItem); + output.Add (taskItem); } } return !Log.HasLoggedErrors; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs index 3db88d758ae..8532487c5a9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs @@ -47,11 +47,18 @@ public override bool Execute () return true; } - void FixupResources (Dictionary acwMap) { - foreach (var dir in ResourceDirectories) + foreach (var dir in ResourceDirectories) { + var skipResourceProcessing = dir.GetMetadata (ResolveLibraryProjectImports.SkipAndroidResourceProcessing); + if (skipResourceProcessing != null && skipResourceProcessing.Equals ("true", StringComparison.OrdinalIgnoreCase)) { + var originalFile = dir.GetMetadata (ResolveLibraryProjectImports.OriginalFile); + Log.LogDebugMessage ($"Skipping: `{dir.ItemSpec}` via `{ResolveLibraryProjectImports.SkipAndroidResourceProcessing}`, original file: `{originalFile}`..."); + continue; + } + FixupResources (dir, acwMap); + } } void FixupResources (ITaskItem item, Dictionary acwMap) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs index 6cab8158450..45d08c8a7dc 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs @@ -42,6 +42,8 @@ public class ResolveLibraryProjectImports : Task public string CacheFile { get; set; } + public string [] AssembliesToSkipCases { get; set; } + [Required] public bool DesignTimeBuild { get; set; } @@ -60,7 +62,15 @@ public class ResolveLibraryProjectImports : Task [Output] public ITaskItem [] ResolvedResourceDirectoryStamps { get; set; } + internal const string OriginalFile = "OriginalFile"; + internal const string SkipAndroidResourceProcessing = "SkipAndroidResourceProcessing"; + static readonly string [] knownMetadata = new [] { + OriginalFile, + SkipAndroidResourceProcessing + }; + AssemblyIdentityMap assemblyMap = new AssemblyIdentityMap(); + HashSet assembliesToSkip; public ResolveLibraryProjectImports () { @@ -70,20 +80,13 @@ public ResolveLibraryProjectImports () // Extracts library project contents under e.g. obj/Debug/[lp/*.jar | res/*/*] public override bool Execute () { - Log.LogDebugMessage ("ResolveLibraryProjectImports Task"); - Log.LogDebugMessage (" ImportsDirectory: {0}", ImportsDirectory); - Log.LogDebugMessage (" OutputDirectory: {0}", OutputDirectory); - Log.LogDebugMessage (" OutputImportDirectory: {0}", OutputImportDirectory); - Log.LogDebugMessage (" UseShortFileNames: {0}", UseShortFileNames); - Log.LogDebugTaskItems (" Assemblies: ", Assemblies); - Log.LogDebugTaskItems (" AarLibraries: ", AarLibraries); - var jars = new List (); - var resolvedResourceDirectories = new List (); + var resolvedResourceDirectories = new List (); var resolvedAssetDirectories = new List (); var resolvedEnvironmentFiles = new List (); assemblyMap.Load (AssemblyIdentityMapFile); + assembliesToSkip = new HashSet (AssembliesToSkipCases ?? new string [0], StringComparer.OrdinalIgnoreCase); using (var resolver = new DirectoryAssemblyResolver (this.CreateTaskLogger (), loadDebugSymbols: false)) { try { @@ -95,9 +98,7 @@ public override bool Execute () } Jars = jars.ToArray (); - ResolvedResourceDirectories = resolvedResourceDirectories - .Select (s => new TaskItem (Path.GetFullPath (s))) - .ToArray (); + ResolvedResourceDirectories = resolvedResourceDirectories.ToArray (); ResolvedAssetDirectories = resolvedAssetDirectories.ToArray (); ResolvedEnvironmentFiles = resolvedEnvironmentFiles.ToArray (); @@ -120,7 +121,15 @@ public override bool Execute () new XElement ("Jars", Jars.Select(e => new XElement ("Jar", e))), new XElement ("ResolvedResourceDirectories", - ResolvedResourceDirectories.Select(e => new XElement ("ResolvedResourceDirectory", e))), + ResolvedResourceDirectories.Select(dir => { + var e = new XElement ("ResolvedResourceDirectory", dir.ItemSpec); + foreach (var name in knownMetadata) { + var value = dir.GetMetadata (name); + if (!string.IsNullOrEmpty (value)) + e.SetAttributeValue (name, value); + } + return e; + })), new XElement ("ResolvedAssetDirectories", ResolvedAssetDirectories.Select(e => new XElement ("ResolvedAssetDirectory", e))), new XElement ("ResolvedEnvironmentFiles", @@ -133,10 +142,10 @@ public override bool Execute () assemblyMap.Save (AssemblyIdentityMapFile); - Log.LogDebugTaskItems (" Jars: ", Jars.Select (s => new TaskItem (s)).ToArray ()); - Log.LogDebugTaskItems (" ResolvedResourceDirectories: ", ResolvedResourceDirectories.Select (s => new TaskItem (s)).ToArray ()); - Log.LogDebugTaskItems (" ResolvedAssetDirectories: ", ResolvedAssetDirectories.Select (s => new TaskItem (s)).ToArray ()); - Log.LogDebugTaskItems (" ResolvedEnvironmentFiles: ", ResolvedEnvironmentFiles.Select (s => new TaskItem (s)).ToArray ()); + Log.LogDebugTaskItems (" Jars: ", Jars); + Log.LogDebugTaskItems (" ResolvedResourceDirectories: ", ResolvedResourceDirectories); + Log.LogDebugTaskItems (" ResolvedAssetDirectories: ", ResolvedAssetDirectories); + Log.LogDebugTaskItems (" ResolvedEnvironmentFiles: ", ResolvedEnvironmentFiles); Log.LogDebugTaskItems (" ResolvedResourceDirectoryStamps: ", ResolvedResourceDirectoryStamps); return !Log.HasLoggedErrors; @@ -160,7 +169,7 @@ static string GetTargetAssembly (ITaskItem assemblyName) void Extract ( DirectoryAssemblyResolver res, ICollection jars, - ICollection resolvedResourceDirectories, + ICollection resolvedResourceDirectories, ICollection resolvedAssetDirectories, ICollection resolvedEnvironments) { @@ -183,9 +192,10 @@ void Extract ( .Select (a => GetTargetAssembly (a)) .Where (a => a != null) .Distinct ()) { - string assemblyIdentName = Path.GetFileNameWithoutExtension (assemblyPath); + string assemblyFileName = Path.GetFileNameWithoutExtension (assemblyPath); + string assemblyIdentName = assemblyFileName; if (UseShortFileNames) { - assemblyIdentName = assemblyMap.GetLibraryImportDirectoryNameForAssembly (assemblyIdentName); + assemblyIdentName = assemblyMap.GetLibraryImportDirectoryNameForAssembly (assemblyFileName); } string outDirForDll = Path.Combine (OutputImportDirectory, assemblyIdentName); string importsDir = Path.Combine (outDirForDll, ImportsDirectory); @@ -210,8 +220,14 @@ void Extract ( if (Directory.Exists (binAssemblyDir)) resolvedAssetDirectories.Add (binAssemblyDir); #endif - if (Directory.Exists (resDir)) - resolvedResourceDirectories.Add (resDir); + if (Directory.Exists (resDir)) { + var taskItem = new TaskItem (resDir, new Dictionary { + { OriginalFile, assemblyPath }, + }); + if (assembliesToSkip.Contains (assemblyFileName)) + taskItem.SetMetadata (SkipAndroidResourceProcessing, "True"); + resolvedResourceDirectories.Add (taskItem); + } if (Directory.Exists (assemblyDir)) resolvedAssetDirectories.Add (assemblyDir); foreach (var env in Directory.EnumerateFiles (outDirForDll, "__AndroidEnvironment__*", SearchOption.TopDirectoryOnly)) { @@ -308,8 +324,14 @@ void Extract ( if (Directory.Exists (binAssemblyDir)) resolvedAssetDirectories.Add (binAssemblyDir); #endif - if (Directory.Exists (resDir)) - resolvedResourceDirectories.Add (resDir); + if (Directory.Exists (resDir)) { + var taskItem = new TaskItem (resDir, new Dictionary { + { OriginalFile, assemblyPath } + }); + if (assembliesToSkip.Contains (assemblyFileName)) + taskItem.SetMetadata (SkipAndroidResourceProcessing, "True"); + resolvedResourceDirectories.Add (taskItem); + } if (Directory.Exists (assemblyDir)) resolvedAssetDirectories.Add (assemblyDir); @@ -362,7 +384,10 @@ void Extract ( } } if (Directory.Exists (resDir)) - resolvedResourceDirectories.Add (resDir); + resolvedResourceDirectories.Add (new TaskItem (resDir, new Dictionary { + { OriginalFile, Path.GetFullPath (aarFile.ItemSpec) }, + { SkipAndroidResourceProcessing, "True" }, + })); if (Directory.Exists (assetsDir)) resolvedAssetDirectories.Add (assetsDir); } 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 b25e90234b9..50a3d9e180c 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 @@ -56,6 +56,64 @@ public void BuildBasicApplicationReleaseFSharp () } } + [Test] + public void SkipConvertResourcesCases () + { + var target = "ConvertResourcesCases"; + var proj = new XamarinFormsAndroidApplicationProject (); + proj.OtherBuildItems.Add (new BuildItem ("AndroidAarLibrary", "Jars\\material-menu-1.1.0.aar") { + WebContent = "https://repo.jfrog.org/artifactory/libs-release-bintray/com/balysv/material-menu/1.1.0/material-menu-1.1.0.aar" + }); + using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should not be skipped."); + + List skipped = new List (), processed = new List (); + bool convertResourcesCases = false; + foreach (var line in b.LastBuildOutput) { + if (!convertResourcesCases) { + convertResourcesCases = line.StartsWith ($"Task \"{target}\"", StringComparison.OrdinalIgnoreCase); + } else if (line.StartsWith ($"Done executing task \"{target}\"", StringComparison.OrdinalIgnoreCase)) { + break; //end of target + } else if (line.IndexOf ("Processing:", StringComparison.OrdinalIgnoreCase) >= 0) { + //Processing: obj\Debug\res\layout\main.xml 10/29/2018 8:19:36 PM > 1/1/0001 12:00:00 AM + processed.Add (line); + } else if (line.IndexOf ("Skipping:", StringComparison.OrdinalIgnoreCase) >= 0) { + //Skipping: `obj\Debug\lp\5\jl\res` via `SkipAndroidResourceProcessing`, original file: `bin\TestDebug\temp\packages\Xamarin.Android.Support.Compat.27.0.2.1\lib\MonoAndroid81\Xamarin.Android.Support.Compat.dll`... + skipped.Add (line); + } + } + + var resources = new [] { + Path.Combine ("layout", "main.xml"), + Path.Combine ("layout", "tabbar.xml"), + Path.Combine ("layout", "toolbar.xml"), + Path.Combine ("values", "colors.xml"), + Path.Combine ("values", "strings.xml"), + Path.Combine ("values", "styles.xml"), + }; + foreach (var resource in resources) { + Assert.IsTrue (StringAssertEx.ContainsText (processed, resource), $"`{target}` should process `{resource}`."); + } + + var files = new [] { + "Xamarin.Android.Support.Compat.dll", + "Xamarin.Android.Support.Design.dll", + "Xamarin.Android.Support.Media.Compat.dll", + "Xamarin.Android.Support.Transition.dll", + "Xamarin.Android.Support.v4.dll", + "Xamarin.Android.Support.v7.AppCompat.dll", + "Xamarin.Android.Support.v7.CardView.dll", + "Xamarin.Android.Support.v7.MediaRouter.dll", + "Xamarin.Android.Support.v7.RecyclerView.dll", + "material-menu-1.1.0.aar", + }; + foreach (var file in skipped) { + Assert.IsTrue (StringAssertEx.ContainsText (skipped, file), $"`{target}` should skip `{file}`."); + } + } + } + [Test] public void BuildInParallel () { diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs b/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs index 37fe163ad2c..49f85eaee4c 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs @@ -10,16 +10,28 @@ namespace Xamarin.Android.Tasks { public static class XDocumentExtensions { + const string PathsElementName = "Paths"; + public static ITaskItem[] GetPathsAsTaskItems (this XDocument doc, params string[] paths) { - return doc.GetPaths (paths) - .Select(x => new TaskItem(x)) - .ToArray (); + var e = doc.Elements (PathsElementName); + foreach (var p in paths) + e = e.Elements (p); + return e.Select (ToTaskItem).ToArray (); + } + + static ITaskItem ToTaskItem (XElement element) + { + var taskItem = new TaskItem (element.Value); + foreach (var attribute in element.Attributes ()) { + taskItem.SetMetadata (attribute.Name.LocalName, attribute.Value); + } + return taskItem; } public static string[] GetPaths (this XDocument doc, params string[] paths) { - var e = doc.Elements ("Paths"); + var e = doc.Elements (PathsElementName); foreach (var p in paths) e = e.Elements (p); return e.Select (p => p.Value).ToArray (); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets index fb6499f4fb7..e855c737843 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets @@ -109,6 +109,9 @@ PreserveNewest + + PreserveNewest + <_SharedRuntimeAssemblies Include="@(MonoProfileAssembly->'$(_SharedRuntimeBuildPath)v1.0\%(Identity)')" /> diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index fb3950df16b..7f10df0b46a 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -369,6 +369,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. --> + @@ -1346,7 +1347,8 @@ because xbuild doesn't support framework reference assemblies. UseShortFileNames="$(UseShortFileNames)" OutputDirectory="$(IntermediateOutputPath)" AssemblyIdentityMapFile="$(_AndroidLibrayProjectAssemblyMapFile)" - OutputImportDirectory="$(_AndroidLibrayProjectIntermediatePath)"> + OutputImportDirectory="$(_AndroidLibrayProjectIntermediatePath)" + AssembliesToSkipCases="@(_AndroidAssemblySkipCases)"> diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.SkipCases.projitems b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.SkipCases.projitems new file mode 100644 index 00000000000..60cc3ac40d6 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.SkipCases.projitems @@ -0,0 +1,182 @@ + + + + + + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Core.Common" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Core.Runtime" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Lifecycle.Common" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Lifecycle.Extensions" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Lifecycle.LiveData" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Lifecycle.LiveData.Core" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Lifecycle.Runtime" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Arch.Lifecycle.ViewModel" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Animated.Vector.Drawable" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Annotations" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.AsyncLayoutInflater" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Collections" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Compat" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Constraint.Layout" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Constraint.Layout.Solver" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Content" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.CoordinaterLayout" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Core.UI" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Core.Utils" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.CursorAdapter" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.CustomTabs" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.CustomView" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Design" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.DocumentFile" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.DrawerLayout" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Dynamic.Animation" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Emoji" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Emoji.AppCompat" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Emoji.Bundled" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Exif" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Fragment" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.HeifWriter" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.InstantVideo" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Interpolator" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Loader" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.LocalBroadcastManager" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Media.Compat" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Percent" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Print" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Recommendation" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Recommendation" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.RecyclerView.Selection" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Slices.Builders" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Slices.Core" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Slices.View" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.SlidingPaneLayout" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.SwipeRefreshLayout" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Transition" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.TV.Provider" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v13" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v14.Preference" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v17.Leanback" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v17.Preference.Leanback" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v4" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v7.AppCompat" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v7.CardView" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v7.GridLayout" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v7.MediaRouter" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v7.Palette" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v7.Preference" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v7.RecyclerView" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.v8.RenderScript" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Vector.Drawable" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.VersionedParcelable" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.ViewPager" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Wear" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.Wearable" /> + <_AndroidAssemblySkipCases Include="Xamarin.Android.Support.WebKit" /> + + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Ads" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Ads.Base" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Ads.Identifier" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Ads.Lite" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Analytics" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Analytics.Impl" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.AppIndexing" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.AppInvite" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.AppState" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Audience" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Auth" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Auth.Api.Phone" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Auth.Base" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Awareness" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Base" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Basement" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Cast" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Cast.Framework" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Clearcut" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.ContextManager" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Drive" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Fido" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Fitness" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Flags" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Games" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Gass" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Gcm" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Identity" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Iid" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.InstantApps" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Location" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Maps" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Measurement" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Measurement.Base" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Nearby" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Oss.Licenses" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Panorama" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Phenotype" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Places" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Places.PlaceReport" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Plus" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.SafetyNet" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Stats" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.TagManager" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.TagManager.Api" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.TagManager.V4.Impl" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Tasks" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Vision" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Vision.Common" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Vision.ImageLabel" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Wallet" /> + <_AndroidAssemblySkipCases Include="Xamarin.GooglePlayServices.Wearable" /> + + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Abt" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Ads" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Ads.Lite" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Analytics" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Analytics.Impl" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.AppIndexing" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Auth" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Auth.Common" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Auth.Interop" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Auth.Module" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Common" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Config" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Core" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Crash" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Database" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Database.Collection" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Database.Connection" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Dynamic.Links" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Firestore" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Functions" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Iid" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Iid.Interop" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Invites" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.JobDispatcher" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Measurement.Connector" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Measurement.Connector.Impl" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Messaging" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.ML.Common" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.ML.Model.Interpreter" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.ML.Vision" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.ML.Vision.Image.Label.Model" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Perf" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.ProtoliteWellKnownTypes" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Storage" /> + <_AndroidAssemblySkipCases Include="Xamarin.Firebase.Storage.Common" /> + + <_AndroidAssemblySkipCases Include="Square.OkHttp" /> + <_AndroidAssemblySkipCases Include="Xamarin.Protobuf.Lite" /> + <_AndroidAssemblySkipCases Include="Xamarin.TensorFlow.Lite" /> + +