diff --git a/Documentation/release-notes/6084.md b/Documentation/release-notes/6084.md
new file mode 100644
index 00000000000..3ac01c37505
--- /dev/null
+++ b/Documentation/release-notes/6084.md
@@ -0,0 +1,8 @@
+#### Application build and deployment
+
+- [GitHub Pull Request #6084](https://github.com/xamarin/xamarin-android/pull/6084):
+ Android API 31 and a `$(TargetFrameworkVersion)` of `v11.0.99`
+ requires JDK 11. This can be obtained manually by installing
+ [Microsoft OpenJDK 11][ms-openjdk].
+
+[ms-openjdk]: https://docs.microsoft.com/java/openjdk/download
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets
index b06d444b8ff..7ac2650b877 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets
@@ -23,6 +23,7 @@ called for "legacy" projects in Xamarin.Android.Legacy.targets.
JavaSdkPath="$(_JavaSdkDirectory)"
JavaToolExe="$(JavaToolExe)"
JavacToolExe="$(JavacToolExe)"
+ TargetPlatformVersion="$(TargetPlatformVersion)"
LatestSupportedJavaVersion="$(LatestSupportedJavaVersion)"
MinimumSupportedJavaVersion="$(MinimumSupportedJavaVersion)">
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs
index 2494270e4d7..76c60f021f3 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs
@@ -50,13 +50,8 @@ protected override bool ValidateJava (string javaExe, Regex versionRegex)
Version GetJavaVersionForFramework ()
{
var apiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
- if (apiLevel >= 30) {
- // At present, it *looks like* API-R works with Build-tools r29, but
- // historically API-X requires Build-tools rX, so if/when API-30
- // requires Build-tools r30, it will require JDK11.
- // return new Version (11, 0);
- return new Version (1, 8);
- }
+ if (apiLevel >= 31)
+ return new Version (11, 0);
if (apiLevel >= 24)
return new Version (1, 8);
else if (apiLevel == 23)
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs
index 7d42a5c328d..b8be0d2857d 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs
@@ -21,6 +21,8 @@ public class ValidateJavaVersion : AndroidTask
public string JavacToolExe { get; set; }
+ public string TargetPlatformVersion { get; set; }
+
[Required]
public string LatestSupportedJavaVersion { get; set; }
@@ -67,6 +69,9 @@ bool ValidateJava ()
protected virtual bool ValidateJava (string javaExe, Regex versionRegex)
{
var required = Version.Parse (MinimumSupportedJavaVersion);
+ if (Version.TryParse (TargetPlatformVersion, out var targetPlatformVersion) && targetPlatformVersion.Major >= 31) {
+ required = new Version (11, 0);
+ }
MinimumRequiredJdkVersion = required.ToString ();
try {
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 2d8b746354d..c53e2366002 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
@@ -48,6 +48,8 @@ public static string [] SupportedTargetFrameworks ()
[Test]
public void BuildBasicApplication ([ValueSource (nameof (SupportedTargetFrameworks))] string tfv, [Values (true, false)] bool isRelease)
{
+ AssertTargetFrameworkVersionSupported (tfv);
+
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
TargetFrameworkVersion = tfv,
@@ -1143,8 +1145,6 @@ public void BuildMultiDexApplication ([Values ("dx", "d8")] string dexTool)
}
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName), false, false)) {
- proj.TargetFrameworkVersion = b.LatestTargetFrameworkVersion ();
-
string intermediateDir;
if (IsWindows && !Builder.UseDotNet) {
intermediateDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, proj.TargetFrameworkAbbreviated);
@@ -2348,11 +2348,13 @@ public void CheckTargetFrameworkVersion ([Values (true, false)] bool isRelease)
proj.SetProperty ("AndroidUseLatestPlatformSdk", "False");
using (var builder = CreateApkBuilder ()) {
builder.GetTargetFrameworkVersionRange (out var _, out string firstFrameworkVersion, out var _, out string lastFrameworkVersion, out string[] _);
+ AssertTargetFrameworkVersionSupported (firstFrameworkVersion);
proj.SetProperty ("TargetFrameworkVersion", firstFrameworkVersion);
if (!Directory.Exists (Path.Combine (builder.FrameworkLibDirectory, firstFrameworkVersion)))
Assert.Ignore ("This is a Pull Request Build. Ignoring test.");
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, $"Output Property: TargetFrameworkVersion={firstFrameworkVersion}"), $"TargetFrameworkVerson should be {firstFrameworkVersion}");
+ AssertTargetFrameworkVersionSupported (lastFrameworkVersion);
Assert.IsTrue (builder.Build (proj, parameters: new [] { $"TargetFrameworkVersion={lastFrameworkVersion}" }), "Build should have succeeded.");
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, $"Output Property: TargetFrameworkVersion={lastFrameworkVersion}"), $"TargetFrameworkVersion should be {lastFrameworkVersion}");
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs
index 718f4df238f..8a73f093a94 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs
@@ -478,8 +478,6 @@ string[] GetBuildProperties (LocalBuilder builder, bool manyBuild, bool dtbBuild
var ret = new List {
"AndroidGenerateLayoutBindings=true"
};
- if (!Builder.UseDotNet)
- ret.Add ("TargetFrameworkVersion=" + builder.LatestTargetFrameworkVersion ());
if (manyBuild)
ret.Add ("ForceParallelBuild=true");
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs
index 394d6d3f1b1..5018a1c02f0 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs
@@ -21,7 +21,10 @@ public class ResolveSdksTaskTests : BaseTest {
new ApiInfo () { Id = "25", Level = 25, Name = "Nougat", FrameworkVersion = "v7.1", Stable = true },
new ApiInfo () { Id = "26", Level = 26, Name = "Oreo", FrameworkVersion = "v8.0", Stable = true },
new ApiInfo () { Id = "27", Level = 27, Name = "Oreo", FrameworkVersion = "v8.1", Stable = true },
- new ApiInfo () { Id = "P", Level = 28, Name = "P", FrameworkVersion = "v8.99", Stable = false },
+ new ApiInfo () { Id = "28", Level = 28, Name = "Pie", FrameworkVersion = "v9.0", Stable = false },
+ new ApiInfo () { Id = "29", Level = 29, Name = "Android10", FrameworkVersion = "v10.0", Stable = false },
+ new ApiInfo () { Id = "30", Level = 30, Name = "Android11", FrameworkVersion = "v11.0", Stable = false },
+ new ApiInfo () { Id = "S", Level = 31, Name = "S", FrameworkVersion = "v11.0.99", Stable = false },
new ApiInfo () { Id = "Z", Level = 127, Name = "Z", FrameworkVersion = "v108.1.99", Stable = false },
};
@@ -35,9 +38,9 @@ public class ResolveSdksTaskTests : BaseTest {
/* jdk */ "1.8.0",
/* apis*/ apiInfoSelection,
/* useLatestAndroidSdk */ true,
- /* targetFrameworkVersion */ "v8.99",
+ /* targetFrameworkVersion */ "v9.0",
/* expectedTaskResult */ true,
- /* expectedTargetFramework */ "v8.99",
+ /* expectedTargetFramework */ "v9.0",
/* expectedError */ "",
/* expectedErrorMessage */ "",
},
@@ -101,9 +104,9 @@ public class ResolveSdksTaskTests : BaseTest {
/* jdk */ "1.8.0",
/* apis*/ apiInfoSelection,
/* useLatestAndroidSdk */ false,
- /* targetFrameworkVersion */ "v8.99",
+ /* targetFrameworkVersion */ "v9.0",
/* expectedTaskResult */ true,
- /* expectedTargetFramework */ "v8.99",
+ /* expectedTargetFramework */ "v9.0",
/* expectedError */ "",
/* expectedErrorMessage */ "",
},
@@ -151,6 +154,17 @@ public class ResolveSdksTaskTests : BaseTest {
/* expectedError */ "XA0001",
/* expectedErrorMessage */ "Unsupported or invalid $(TargetFrameworkVersion) value of 'v6.0'. Please update your Project Options.",
},
+ new object[] {
+ /* buildtools */ "30.0.0",
+ /* jdk */ "11.0",
+ /* apis*/ apiInfoSelection,
+ /* useLatestAndroidSdk */ false,
+ /* targetFrameworkVersion */ "v11.0.99",
+ /* expectedTaskResult */ true,
+ /* expectedTargetFramework */ "v11.0.99",
+ /* expectedError */ "",
+ /* expectedErrorMessage */ "",
+ },
};
#pragma warning restore 414
[Test]
@@ -184,7 +198,7 @@ public void UseLatestAndroidSdk (string buildtools, string jdk, ApiInfo[] apis,
JavaSdkPath = javaPath,
JavaToolExe = javaExe,
JavacToolExe = javacExe,
- LatestSupportedJavaVersion = "1.8.0",
+ LatestSupportedJavaVersion = LatestSupportedJavaVersion,
MinimumSupportedJavaVersion = "1.7.0",
};
var androidTooling = new ResolveAndroidTooling {
@@ -429,6 +443,7 @@ public void LatestTFV_OldTargetSdkVersion ()
proj.TargetSdkVersion = "19";
using (var b = CreateApkBuilder ()) {
proj.TargetFrameworkVersion = b.LatestTargetFrameworkVersion ();
+ AssertTargetFrameworkVersionSupported (proj.TargetFrameworkVersion);
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs
index 1c3fb61229d..f4073426fa3 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs
@@ -212,6 +212,16 @@ protected static void AssertLLVMSupported (bool llvm)
}
}
+ protected static void AssertTargetFrameworkVersionSupported (string targetFrameworkVersion)
+ {
+ if (Builder.UseDotNet)
+ return; // N/A in .NET 6
+ if (!Version.TryParse (targetFrameworkVersion.TrimStart ('v'), out var version) || version <= new Version (11, 0))
+ return; // TFV is 11.0 or less
+ if (!TestEnvironment.IsUsingJdk11)
+ Assert.Ignore ("Test is only supported when using JDK 11.");
+ }
+
protected static void WaitFor(int milliseconds)
{
var pause = new ManualResetEvent(false);
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs
index b4a4befa793..a3e26dbbd74 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs
@@ -581,7 +581,7 @@ public void XamarinLegacySdk ()
using var b = new Builder ();
var dotnetTargetFramework = "net6.0-android30.0";
- var legacyTargetFrameworkVersion = b.LatestTargetFrameworkVersion ().TrimStart ('v');
+ var legacyTargetFrameworkVersion = "11.0";
var legacyTargetFramework = $"monoandroid{legacyTargetFrameworkVersion}";
proj.SetProperty ("TargetFramework", value: "");
proj.SetProperty ("TargetFrameworks", value: $"{dotnetTargetFramework};{legacyTargetFramework}");
diff --git a/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs b/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs
index f22aaa95b17..2ed567d90a3 100755
--- a/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs
@@ -32,6 +32,8 @@ void SetTargetFrameworkAndManifest(XamarinAndroidApplicationProject proj, Builde
proj.TargetFrameworkVersion = "v11.0";
}
+ AssertTargetFrameworkVersionSupported (proj.TargetFrameworkVersion);
+
proj.AndroidManifest = $@"