diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Linux.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Linux.cs
index d65f02e2955..4cdd9f67ab7 100644
--- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Linux.cs
+++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Linux.cs
@@ -4,6 +4,8 @@ namespace Xamarin.Android.Prepare
{
partial class Configurables
{
+ const string JetBrainsOpenJDKOperatingSystem = "linux-x64";
+
partial class Urls
{
public static readonly Uri Corretto = new Uri ($"{Corretto_BaseUri}{CorrettoUrlPathVersion}/amazon-corretto-{CorrettoDistVersion}-linux-x64.tar.gz");
diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs
index 5b75ed09f4b..bf86871d059 100644
--- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs
+++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.MacOS.cs
@@ -4,6 +4,7 @@ namespace Xamarin.Android.Prepare
{
partial class Configurables
{
+ const string JetBrainsOpenJDKOperatingSystem = "osx-x64";
partial class Urls
{
public static readonly Uri Corretto = new Uri ($"{Corretto_BaseUri}{CorrettoUrlPathVersion}/amazon-corretto-{CorrettoDistVersion}-macosx-x64.tar.gz");
diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Windows.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Windows.cs
index f11e83793ce..fc1e7d19b70 100644
--- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Windows.cs
+++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.Windows.cs
@@ -5,6 +5,8 @@ namespace Xamarin.Android.Prepare
{
partial class Configurables
{
+ const string JetBrainsOpenJDKOperatingSystem = "windows-x64";
+
partial class Urls
{
public static Uri Corretto => GetWindowsCorrettoUrl ();
diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs
index d7a9483f748..203f361a1b9 100644
--- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs
+++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs
@@ -15,6 +15,10 @@ namespace Xamarin.Android.Prepare
//
partial class Configurables
{
+ const string JetBrainsOpenJDKVersion = "11.0.4";
+ const string JetBrainsOpenJDKRelease = "546.1";
+ static readonly string JetBrainsOpenJDKDownloadVersion = JetBrainsOpenJDKVersion.Replace ('.', '_');
+
const string CorrettoDistVersion = "8.242.08.1";
const string CorrettoUrlPathVersion = CorrettoDistVersion;
@@ -22,6 +26,11 @@ partial class Configurables
public static partial class Urls
{
+ // https://bintray.com/jetbrains/intellij-jdk/download_file?file_path=jbrsdk-11_0_4-linux-x64-b546.1.tar.gz
+ // https://bintray.com/jetbrains/intellij-jdk/download_file?file_path=jbrsdk-11_0_4-osx-x64-b546.1.tar.gz
+ // https://bintray.com/jetbrains/intellij-jdk/download_file?file_path=jbrsdk-11_0_4-windows-x64-b546.1.tar.gz
+ public static readonly Uri JetBrainsOpenJDK = new Uri ($"https://bintray.com/jetbrains/intellij-jdk/download_file?file_path=jbrsdk-{JetBrainsOpenJDKDownloadVersion}-{JetBrainsOpenJDKOperatingSystem}-b{JetBrainsOpenJDKRelease}.tar.gz");
+
// Keep the trailing slash here - OS-specific code assumes it's there.
public const string Corretto_BaseUri = "https://corretto.aws/downloads/resources/";
@@ -39,6 +48,9 @@ public static partial class Defaults
{
public static readonly char[] PropertyListSeparator = new [] { ':' };
+ public static readonly Version JetBrainsOpenJDKVersion = new Version (Configurables.JetBrainsOpenJDKVersion);
+ public static readonly Version JetBrainsOpenJDKRelease = new Version (Configurables.JetBrainsOpenJDKRelease);
+
// Mono runtimes
public const string DebugFileExtension = ".pdb";
public const string MonoHostMingwRuntimeNativeLibraryExtension = WindowsDLLSuffix;
@@ -104,9 +116,9 @@ public static partial class Defaults
public const int DefaultMaximumParallelTasks = 5;
///
- /// The maximum JDK version we support. Note: this will probably go away with Corretto
+ /// The maximum JDK version we support.
///
- public const int MaxJDKVersion = 8;
+ public static readonly Version MaxJDKVersion = new Version (11, 99, 0);
///
/// Prefix for all the log files created by the bootstrapper.
@@ -318,6 +330,10 @@ public static partial class Paths
public static string CorrettoCacheDir => GetCachedPath (ref correttoCacheDir, () => ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory));
public static string CorrettoInstallDir => GetCachedPath (ref correttoInstallDir, () => Path.Combine (ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainDirectory), "jdk"));
+ // JetBrains OpenJDK
+ public static string OpenJDKInstallDir => GetCachedPath (ref openJDKInstallDir, () => Path.Combine (ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainDirectory), "jdk"));
+ public static string OpenJDKCacheDir => GetCachedPath (ref openJDKCacheDir, () => ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory));
+
// bundle
public static string BCLTestsArchiveName = "bcl-tests.zip";
@@ -403,6 +419,8 @@ static string GetCachedPath (ref string variable, Func creator)
static string monoSdksTpnExternalPath;
static string monoSDKSIncludeDestDir;
static string monoLlvmTpnPath;
+ static string openJDKInstallDir;
+ static string openJDKCacheDir;
}
}
}
diff --git a/build-tools/xaprepare/xaprepare/Scenarios/Scenario_AndroidToolchain.cs b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_AndroidToolchain.cs
index 9ef78958a54..687ea5d09da 100644
--- a/build-tools/xaprepare/xaprepare/Scenarios/Scenario_AndroidToolchain.cs
+++ b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_AndroidToolchain.cs
@@ -6,12 +6,12 @@ namespace Xamarin.Android.Prepare
partial class Scenario_AndroidToolchain : ScenarioNoStandardEndSteps
{
public Scenario_AndroidToolchain ()
- : base ("AndroidToolchain", "Install Android SDK, NDK and Corretto JDK.", Context.Instance)
+ : base ("AndroidToolchain", "Install Android SDK, NDK and OpenJDK.", Context.Instance)
{}
protected override void AddSteps (Context context)
{
- Steps.Add (new Step_InstallCorrettoOpenJDK ());
+ Steps.Add (new Step_InstallJetBrainsOpenJDK ());
Steps.Add (new Step_Android_SDK_NDK ());
// disable installation of missing programs...
diff --git a/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs
index e6a239f64b5..ecc5a4aed34 100644
--- a/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs
+++ b/build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs
@@ -19,7 +19,7 @@ protected override void AddSteps (Context context)
throw new ArgumentNullException (nameof (context));
Steps.Add (new Step_ShowEnabledRuntimes ());
- Steps.Add (new Step_InstallCorrettoOpenJDK ());
+ Steps.Add (new Step_InstallJetBrainsOpenJDK ());
Steps.Add (new Step_Android_SDK_NDK ());
Steps.Add (new Step_GenerateFiles (atBuildStart: true));
Steps.Add (new Step_PrepareProps ());
diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Linux.cs b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Linux.cs
new file mode 100644
index 00000000000..d41d9cf0ad8
--- /dev/null
+++ b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Linux.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Xamarin.Android.Prepare
+{
+ partial class Step_InstallJetBrainsOpenJDK
+ {
+ void MoveContents (string sourceDir, string destinationDir)
+ {
+ Utilities.MoveDirectoryContentsRecursively (sourceDir, destinationDir);
+ }
+ }
+}
diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.MacOS.cs b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.MacOS.cs
new file mode 100644
index 00000000000..0cd7d04819d
--- /dev/null
+++ b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.MacOS.cs
@@ -0,0 +1,14 @@
+using System;
+using System.IO;
+
+namespace Xamarin.Android.Prepare
+{
+ partial class Step_InstallJetBrainsOpenJDK
+ {
+ void MoveContents (string sourceDir, string destinationDir)
+ {
+ string realSourceDir = Path.Combine (sourceDir, "Contents", "Home");
+ Utilities.MoveDirectoryContentsRecursively (realSourceDir, destinationDir);
+ }
+ }
+}
diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Unix.cs b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Unix.cs
new file mode 100644
index 00000000000..951f837aad6
--- /dev/null
+++ b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Unix.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Xamarin.Android.Prepare
+{
+ partial class Step_InstallJetBrainsOpenJDK
+ {
+ async Task Unpack (string fullArchivePath, string destinationDirectory, bool cleanDestinationBeforeUnpacking = false)
+ {
+ return await Utilities.Unpack (fullArchivePath, destinationDirectory, cleanDestinatioBeforeUnpacking: true);
+ }
+ }
+}
diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Windows.cs b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Windows.cs
new file mode 100644
index 00000000000..ae9aa1e010c
--- /dev/null
+++ b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.Windows.cs
@@ -0,0 +1,43 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace Xamarin.Android.Prepare
+{
+ partial class Step_InstallJetBrainsOpenJDK
+ {
+ async Task Unpack (string fullArchivePath, string destinationDirectory, bool cleanDestinationBeforeUnpacking = false)
+ {
+ // On Windows we don't have Tar available and the Windows package is a .tar.gz
+ // 7zip can unpack tar.gz but it's a two-stage process - first it decompresses the package, then it can be
+ // invoked again to extract the actual tar contents.
+
+ if (cleanDestinationBeforeUnpacking)
+ Utilities.DeleteDirectorySilent (destinationDirectory);
+ Utilities.CreateDirectory (destinationDirectory);
+
+ var sevenZip = new SevenZipRunner (Context.Instance);
+ Log.DebugLine ($"Uncompressing {fullArchivePath} to {destinationDirectory}");
+ if (!await sevenZip.Extract (fullArchivePath, destinationDirectory)) {
+ Log.DebugLine ($"Failed to decompress {fullArchivePath}");
+ return false;
+ }
+
+ string tarPath = Path.Combine (destinationDirectory, Path.GetFileNameWithoutExtension (fullArchivePath));
+ bool ret = await sevenZip.Extract (tarPath, destinationDirectory);
+ Utilities.DeleteFileSilent (tarPath);
+
+ if (!ret) {
+ Log.DebugLine ($"Failed to extract TAR contents from {tarPath}");
+ return false;
+ }
+
+ return true;
+ }
+
+ void MoveContents (string sourceDir, string destinationDir)
+ {
+ Utilities.MoveDirectoryContentsRecursively (sourceDir, destinationDir);
+ }
+ }
+}
diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.cs b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.cs
new file mode 100644
index 00000000000..80226a609a8
--- /dev/null
+++ b/build-tools/xaprepare/xaprepare/Steps/Step_InstallJetBrainsOpenJDK.cs
@@ -0,0 +1,237 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace Xamarin.Android.Prepare
+{
+ partial class Step_InstallJetBrainsOpenJDK : StepWithDownloadProgress
+ {
+ const string ProductName = "JetBrains OpenJDK";
+ const string RootDirName = "jbrsdk";
+ const string XAVersionInfoFile = "xa_jdk_version.txt";
+ const string URLQueryFilePathField = "file_path";
+
+ static readonly char[] QuerySeparator = new char[] { ';', '&' };
+
+ // Paths relative to JDK installation root, just for a cursory check whether we have a sane JDK instance
+ // NOTE: file extensions are not necessary here
+ static readonly List jdkFiles = new List {
+ Path.Combine ("bin", "java"),
+ Path.Combine ("bin", "javac"),
+ Path.Combine ("include", "jni.h"),
+ };
+
+ public Step_InstallJetBrainsOpenJDK ()
+ : base ($"Installing {ProductName} 11")
+ {}
+
+ protected override async Task Execute (Context context)
+ {
+ string jdkInstallDir = Configurables.Paths.OpenJDKInstallDir;
+ if (OpenJDKExistsAndIsValid (jdkInstallDir, out string installedVersion)) {
+ Log.Status ($"{ProductName} version ");
+ Log.Status (installedVersion, ConsoleColor.Yellow);
+ Log.StatusLine (" already installed in: ", jdkInstallDir, tailColor: ConsoleColor.Cyan);
+ return true;
+ }
+
+ Log.StatusLine ($"JetBrains JDK {Configurables.Defaults.JetBrainsOpenJDKVersion} r{Configurables.Defaults.JetBrainsOpenJDKRelease} will be installed");
+ Uri jdkURL = Configurables.Urls.JetBrainsOpenJDK;
+ if (jdkURL == null)
+ throw new InvalidOperationException ($"{ProductName} URL must not be null");
+
+ string[] queryParams = jdkURL.Query.TrimStart ('?').Split (QuerySeparator, StringSplitOptions.RemoveEmptyEntries);
+ if (queryParams.Length == 0) {
+ Log.ErrorLine ($"Unable to extract file name from {ProductName} URL as it contains no query component");
+ return false;
+ }
+
+ string packageName = null;
+ foreach (string p in queryParams) {
+ if (!p.StartsWith (URLQueryFilePathField, StringComparison.Ordinal)) {
+ continue;
+ }
+
+ int idx = p.IndexOf ('=');
+ if (idx < 0) {
+ Log.DebugLine ($"{ProductName} URL query field '{URLQueryFilePathField}' has no value, unable to detect file name");
+ break;
+ }
+
+ packageName = p.Substring (idx + 1).Trim ();
+ }
+
+ if (String.IsNullOrEmpty (packageName)) {
+ Log.ErrorLine ($"Unable to extract file name from {ProductName} URL");
+ return false;
+ }
+
+ string localPackagePath = Path.Combine (Configurables.Paths.OpenJDKCacheDir, packageName);
+ if (!await DownloadOpenJDK (context, localPackagePath, jdkURL))
+ return false;
+
+ string tempDir = $"{jdkInstallDir}.temp";
+ try {
+ if (!await Unpack (localPackagePath, tempDir, cleanDestinationBeforeUnpacking: true)) {
+ Log.ErrorLine ($"Failed to install {ProductName}");
+ return false;
+ }
+
+ string rootDir = Path.Combine (tempDir, RootDirName);
+ if (!Directory.Exists (rootDir)) {
+ Log.ErrorLine ($"JetBrains root directory not found after unpacking: {RootDirName}");
+ return false;
+ }
+
+ MoveContents (rootDir, jdkInstallDir);
+ File.WriteAllText (Path.Combine (jdkInstallDir, XAVersionInfoFile), $"{Configurables.Defaults.JetBrainsOpenJDKRelease}{Environment.NewLine}");
+ } finally {
+ Utilities.DeleteDirectorySilent (tempDir);
+ // Clean up zip after extraction if running on a hosted azure pipelines agent.
+ if (context.IsRunningOnHostedAzureAgent)
+ Utilities.DeleteFileSilent (localPackagePath);
+ }
+
+ return true;
+ }
+
+ async Task DownloadOpenJDK (Context context, string localPackagePath, Uri url)
+ {
+ if (File.Exists (localPackagePath)) {
+ Log.StatusLine ($"{ProductName} archive already downloaded");
+ return true;
+ }
+
+ Log.StatusLine ($"Downloading {ProductName} from ", url.ToString (), tailColor: ConsoleColor.White);
+ (bool success, ulong size, HttpStatusCode status) = await Utilities.GetDownloadSizeWithStatus (url);
+ if (!success) {
+ if (status == HttpStatusCode.NotFound)
+ Log.ErrorLine ($"{ProductName} archive URL not found");
+ else
+ Log.ErrorLine ($"Failed to obtain {ProductName} size. HTTP status code: {status} ({(int)status})");
+ return false;
+ }
+
+ DownloadStatus downloadStatus = Utilities.SetupDownloadStatus (context, size, context.InteractiveSession);
+ Log.StatusLine ($" {context.Characters.Link} {url}", ConsoleColor.White);
+ await Download (context, url, localPackagePath, ProductName, Path.GetFileName (localPackagePath), downloadStatus);
+
+ if (!File.Exists (localPackagePath)) {
+ Log.ErrorLine ($"Download of {ProductName} from {url} failed.");
+ return false;
+ }
+
+ return true;
+ }
+
+ bool OpenJDKExistsAndIsValid (string installDir, out string installedVersion)
+ {
+ installedVersion = null;
+ if (!Directory.Exists (installDir)) {
+ Log.DebugLine ($"{ProductName} directory {installDir} does not exist");
+ return false;
+ }
+
+ string corettoVersionFile = Path.Combine (installDir, "version.txt");
+ if (File.Exists (corettoVersionFile)) {
+ Log.DebugLine ($"Corretto version file {corettoVersionFile} found, will replace Corretto with {ProductName}");
+ return false;
+ }
+
+ string jetBrainsReleaseFile = Path.Combine (installDir, "release");
+ if (!File.Exists (jetBrainsReleaseFile)) {
+ Log.DebugLine ($"{ProductName} release file {jetBrainsReleaseFile} does not exist, cannot determine version");
+ return false;
+ }
+
+ string[] lines = File.ReadAllLines (jetBrainsReleaseFile);
+ if (lines == null || lines.Length == 0) {
+ Log.DebugLine ($"{ProductName} release file {jetBrainsReleaseFile} is empty, cannot determine version");
+ return false;
+ }
+
+ string cv = null;
+ foreach (string l in lines) {
+ string line = l.Trim ();
+ if (!line.StartsWith ("JAVA_VERSION=", StringComparison.Ordinal)) {
+ continue;
+ }
+
+ cv = line.Substring (line.IndexOf ('=') + 1).Trim ('"');
+ break;
+ }
+
+ if (String.IsNullOrEmpty (cv)) {
+ Log.DebugLine ($"Unable to find version of {ProductName} in release file {jetBrainsReleaseFile}");
+ return false;
+ }
+
+ string xaVersionFile = Path.Combine (installDir, XAVersionInfoFile);
+ if (!File.Exists (xaVersionFile)) {
+ installedVersion = cv;
+ Log.DebugLine ($"Unable to find Xamarin.Android version file {xaVersionFile}");
+ return false;
+ }
+
+ lines = File.ReadAllLines (xaVersionFile);
+ if (lines == null || lines.Length == 0) {
+ Log.DebugLine ($"Xamarin.Android version file {xaVersionFile} is empty, cannot determine release version");
+ return false;
+ }
+
+ string rv = lines[0].Trim ();
+ if (String.IsNullOrEmpty (rv)) {
+ Log.DebugLine ($"Xamarin.Android version file {xaVersionFile} does not contain release version information");
+ return false;
+ }
+
+ installedVersion = $"{cv} r{rv}";
+
+ if (!Version.TryParse (cv, out Version cversion)) {
+ Log.DebugLine ($"Unable to parse {ProductName} version from: {cv}");
+ return false;
+ }
+
+ if (cversion != Configurables.Defaults.JetBrainsOpenJDKVersion) {
+ Log.DebugLine ($"Invalid {ProductName} version. Need {Configurables.Defaults.JetBrainsOpenJDKVersion}, found {cversion}");
+ return false;
+ }
+
+ if (!Version.TryParse (rv, out cversion)) {
+ Log.DebugLine ($"Unable to parse {ProductName} release version from: {rv}");
+ return false;
+ }
+
+ if (cversion != Configurables.Defaults.JetBrainsOpenJDKRelease) {
+ Log.DebugLine ($"Invalid {ProductName} version. Need {Configurables.Defaults.JetBrainsOpenJDKRelease}, found {cversion}");
+ return false;
+ }
+
+ foreach (string f in jdkFiles) {
+ string file = Path.Combine (installDir, f);
+ if (!File.Exists (file)) {
+ bool foundExe = false;
+ foreach (string exe in Utilities.FindExecutable (f)) {
+ file = Path.Combine (installDir, exe);
+ if (File.Exists (file)) {
+ foundExe = true;
+ break;
+ }
+ }
+
+ if (!foundExe) {
+ Log.DebugLine ($"JDK file {file} missing from {ProductName}");
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_PrepareExternalJavaInterop.Unix.cs b/build-tools/xaprepare/xaprepare/Steps/Step_PrepareExternalJavaInterop.Unix.cs
index 2da742d8e1c..ce59185c1fb 100644
--- a/build-tools/xaprepare/xaprepare/Steps/Step_PrepareExternalJavaInterop.Unix.cs
+++ b/build-tools/xaprepare/xaprepare/Steps/Step_PrepareExternalJavaInterop.Unix.cs
@@ -18,6 +18,7 @@ async Task ExecuteOSSpecific (Context context)
workingDirectory: javaInteropDir,
arguments: new List {
"prepare",
+ "V=1",
$"CONFIGURATION={context.Configuration}",
$"JAVA_HOME={context.OS.JavaHome}",
$"JI_MAX_JDK={Configurables.Defaults.MaxJDKVersion}",
diff --git a/build-tools/xaprepare/xaprepare/xaprepare.csproj b/build-tools/xaprepare/xaprepare/xaprepare.csproj
index ecf2e7b9adc..4ece6942c9b 100644
--- a/build-tools/xaprepare/xaprepare/xaprepare.csproj
+++ b/build-tools/xaprepare/xaprepare/xaprepare.csproj
@@ -138,6 +138,7 @@
+
@@ -195,6 +196,7 @@
+
@@ -220,6 +222,7 @@
+
@@ -237,6 +240,7 @@
+
@@ -259,6 +263,7 @@
+
diff --git a/external/xamarin-android-tools b/external/xamarin-android-tools
index 12f52acd440..36d7fee5f7e 160000
--- a/external/xamarin-android-tools
+++ b/external/xamarin-android-tools
@@ -1 +1 @@
-Subproject commit 12f52acd4407323b2e1b48ca56bab80ffd97b31e
+Subproject commit 36d7fee5f7e0ef6ffa28970687db85b36947a3e6
diff --git a/src/Xamarin.Android.Sdk/targets/Xamarin.Android.Sdk.props b/src/Xamarin.Android.Sdk/targets/Xamarin.Android.Sdk.props
index d36569344a6..1c3f164efea 100644
--- a/src/Xamarin.Android.Sdk/targets/Xamarin.Android.Sdk.props
+++ b/src/Xamarin.Android.Sdk/targets/Xamarin.Android.Sdk.props
@@ -4,7 +4,7 @@
true
- 1.8.0
+ 11.99.0
1.8.0
false
true