Skip to content

Commit e8162d1

Browse files
committed
[Xamarin.Android.Build.Tasks] Warnings and errors for compileSdkVersion, targetSdkVersion, and minSdkVersion
Context #1768 Google has the following guidance for these three values: > minSdkVersion (lowest possible) <= targetSdkVersion == compileSdkVersion (latest SDK) This commit adds a new Task `CheckGoogleSdkRequirements` which is responsible for checking these values. It will be enabled by default but the task can be disabled via the `AndroidEnableGooglePlayStoreChecks` property.
1 parent c1c71d9 commit e8162d1

File tree

11 files changed

+200
-0
lines changed

11 files changed

+200
-0
lines changed

Documentation/guides/BuildProcess.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,14 @@ when packaing Release applications.
709709

710710
Added in Xamarin.Android 8.3.
711711

712+
- **AndroidEnableGooglePlayStoreChecks** &ndash; A bool property
713+
which allows developers to disable the following Google Play
714+
Store checks, XA1004, XA1005 and XA1006. This is useful for
715+
developers who are not targeting the Google Play Store and do
716+
not wish to run those checks.
717+
718+
Added in Xamarin.Android 8.4.
719+
712720
### Binding Project Build Properties
713721

714722
The following MSBuild properties are used with

Documentation/guides/messages/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
+ [XA1000](xa1000.md): There was an problem parsing {file}. This is likely due to incomplete or invalid xml.
4747
+ [XA1001](xa1001.md): AndroidResgen: Warning while updating Resource XML '{filename}': {Message}
4848
+ [XA1002](xa1002.md): We found a matching key '{Key}' for '{Item}'. But the casing was incorrect. Please correct the casing
49+
+ [XA1003](xa1003.md): Your application is running on a version of Android ({compileSdk}) that is more recent than your targetSdkVersion specifies ({targetSdk}). Set your targetSdkVersion to the highest version of Android available to match your TargetFrameworkVersion ({compileSdk}).
50+
+ [XA1004](xa1004.md): The TargetFrameworkVersion ({compileSdk}) should not be lower than targetSdkVersion ({targetSdk})
51+
+ [XA1005](xa1005.md): The minSdkVersion ({minSdk}) is greater than targetSdkVersion. Please change the value such that minSdkVersion is less than or equal to targetSdkVersion ({targetSdk}).
4952

5053
### XA2xxx Linker
5154

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Compiler Warning XA1003
2+
3+
Your application is running on a version of Android (compileSdk) that
4+
is more recent than your targetSdkVersion specifies (targetSdk).
5+
6+
Set your targetSdkVersion to the highest version of Android available
7+
to match your TargetFrameworkVersion (compileSdk).
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Compiler Error XA1004
2+
3+
The TargetFrameworkVersion (compileSdk) should not be lower
4+
than targetSdkVersion (targetSdk).
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Compiler Error XA1005
2+
3+
The minSdkVersion (minSdk) is greater than targetSdkVersion.
4+
5+
Please change the value such that minSdkVersion is less than
6+
or equal to targetSdkVersion (targetSdk).
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Microsoft.Build.Utilities;
4+
using Microsoft.Build.Framework;
5+
using System.IO;
6+
using System.Linq;
7+
8+
using Java.Interop.Tools.Cecil;
9+
using Xamarin.Android.Tools;
10+
11+
namespace Xamarin.Android.Tasks
12+
{
13+
public class CheckGoogleSdkRequirements : Task
14+
{
15+
[Required]
16+
public string TargetFrameworkVersion { get; set; }
17+
18+
[Required]
19+
public string ManifestFile { get; set; }
20+
21+
public override bool Execute ()
22+
{
23+
ManifestDocument manifest = new ManifestDocument (ManifestFile, this.Log);
24+
25+
var compileSdk = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
26+
27+
if (!int.TryParse (manifest.GetMinimumSdk (), out int minSdk)) {
28+
minSdk = 1;
29+
}
30+
if (!int.TryParse (manifest.GetTargetSdk (), out int targetSdk)) {
31+
targetSdk = compileSdk.Value;
32+
}
33+
34+
//We should throw a warning if the targetSdkVersion is lower than compileSdkVersion(TargetFrameworkVersion).
35+
if (targetSdk < compileSdk) {
36+
Log.LogCodedWarning ("XA1003", $"Your application is running on a version of Android ({compileSdk}) that is more recent than your targetSdkVersion specifies ({targetSdk}). Set your targetSdkVersion to the highest version of Android available to match your TargetFrameworkVersion ({compileSdk}).");
37+
}
38+
//We should throw an error if the compileSdkVersion(TargetFrameworkVersion) is lower than targetSdkVersion.
39+
if (compileSdk < targetSdk) {
40+
Log.LogCodedError ("XA1004", $"The TargetFrameworkVersion ({compileSdk}) should not be lower than targetSdkVersion ({targetSdk})");
41+
}
42+
43+
//We should throw an error if the minSdkVersion is greater than targetSdkVersion.
44+
if (minSdk > targetSdk) {
45+
Log.LogCodedError ("XA1005", $"The minSdkVersion ({minSdk}) is greater than targetSdkVersion. Please change the value such that minSdkVersion is less than or equal to targetSdkVersion ({targetSdk}).");
46+
}
47+
48+
return !Log.HasLoggedErrors;
49+
}
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using Microsoft.Build.Framework;
2+
using NUnit.Framework;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.IO;
6+
using Xamarin.Android.Tasks;
7+
using Xamarin.Android.Tools;
8+
using Xamarin.ProjectTools;
9+
10+
namespace Xamarin.Android.Build.Tests {
11+
[TestFixture]
12+
public class CheckGoogleSdkRequirmentsTests : BaseTest {
13+
List<BuildErrorEventArgs> errors;
14+
List<BuildWarningEventArgs> warnings;
15+
MockBuildEngine engine;
16+
17+
[SetUp]
18+
public void Setup ()
19+
{
20+
var path = Path.Combine ("temp", TestName);
21+
engine = new MockBuildEngine (TestContext.Out, errors = new List<BuildErrorEventArgs> (), warnings = new List<BuildWarningEventArgs> ());
22+
var referencePath = CreateFauxReferencesDirectory (Path.Combine (path, "references"), new [] {
23+
new ApiInfo { Id = "27", Level = 27, Name = "Oreo", FrameworkVersion = "v8.1", Stable = true },
24+
new ApiInfo { Id = "28", Level = 28, Name = "Pie", FrameworkVersion = "v9.0", Stable = true },
25+
});
26+
MonoAndroidHelper.RefreshSupportedVersions (new [] {
27+
Path.Combine (referencePath, "MonoAndroid"),
28+
});
29+
}
30+
31+
[TearDown]
32+
public void TearDown ()
33+
{
34+
var path = Path.Combine ("temp", TestName);
35+
Directory.Delete (Path.Combine (Root, path), recursive: true);
36+
}
37+
38+
string CreateManiestFile (int minSDk, int targetSdk) {
39+
var manifest = Path.Combine (Root, "temp", TestName, "AndroidManifest.xml");
40+
File.WriteAllText (manifest, string.Format (@"<manifest xmlns:android='http://schemas.android.com/apk/res/android' android:versionCode='1' android:versionName='1.0' package='Foo.Foo'>
41+
<uses-sdk android:minSdkVersion = '{0}' android:targetSdkVersion = '{1}' />
42+
</manifest>
43+
", minSDk, targetSdk));
44+
return manifest;
45+
}
46+
47+
[Test]
48+
public void CheckManifestIsOK ()
49+
{
50+
var task = new CheckGoogleSdkRequirments () {
51+
BuildEngine = engine,
52+
TargetFrameworkVersion = "v9.0",
53+
ManifestFile = CreateManiestFile (10, 28),
54+
};
55+
Assert.True (task.Execute (), "Task should have succeeded.");
56+
Assert.AreEqual (0, errors.Count, "There should be 0 errors reported.");
57+
Assert.AreEqual (0, warnings.Count, "There should be 0 warnings reported.");
58+
}
59+
60+
[Test]
61+
public void CheckManifestTargetSdkLowerThanCompileSdk ()
62+
{
63+
var task = new CheckGoogleSdkRequirments () {
64+
BuildEngine = engine,
65+
TargetFrameworkVersion = "v9.0",
66+
ManifestFile = CreateManiestFile (10, 27),
67+
};
68+
Assert.True (task.Execute (), "Task should have succeeded.");
69+
Assert.AreEqual (0, errors.Count, "There should be 0 errors reported.");
70+
Assert.AreEqual (1, warnings.Count, "There should be 1 warning reported.");
71+
}
72+
73+
[Test]
74+
public void CheckManifestCompileSdkLowerThanTargetSdk ()
75+
{
76+
var task = new CheckGoogleSdkRequirments () {
77+
BuildEngine = engine,
78+
TargetFrameworkVersion = "v8.1",
79+
ManifestFile = CreateManiestFile (10, 28),
80+
};
81+
Assert.False (task.Execute (), "Task should have failed.");
82+
Assert.AreEqual (1, errors.Count, "There should be 1 error reported.");
83+
Assert.AreEqual (0, warnings.Count, "There should be 0 warnings reported.");
84+
}
85+
86+
[Test]
87+
public void CheckManifestMinSdkLowerThanTargetSdk ()
88+
{
89+
var task = new CheckGoogleSdkRequirments () {
90+
BuildEngine = engine,
91+
TargetFrameworkVersion = "v8.1",
92+
ManifestFile = CreateManiestFile (28, 27),
93+
};
94+
Assert.False (task.Execute (), "Task should have failed.");
95+
Assert.AreEqual (1, errors.Count, "There should be 1 error reported.");
96+
Assert.AreEqual (0, warnings.Count, "There should be 0 warnings reported.");
97+
}
98+
}
99+
}

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
<Compile Include="Tasks\ValidateJavaVersionTests.cs" />
8686
<Compile Include="ZipArchiveExTests.cs" />
8787
<Compile Include="ConvertResourcesCasesTests.cs" />
88+
<Compile Include="Tasks\CheckGoogleSdkRequirmentsTests.cs" />
8889
</ItemGroup>
8990
<ItemGroup>
9091
<Content Include="Expected\GenerateDesignerFileExpected.cs">

src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ public string GetMinimumSdk () {
111111
return minAttr.Value;
112112
}
113113

114+
public string GetTargetSdk () {
115+
var targetAttr = doc.Root.Element ("uses-sdk")?.Attribute (androidNs + "targetSdkVersion");
116+
if (targetAttr == null) {
117+
return SdkVersionName;
118+
}
119+
return targetAttr.Value;
120+
}
121+
114122
TaskLoggingHelper log;
115123

116124
public ManifestDocument (string templateFilename, TaskLoggingHelper log) : base ()

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@
568568
<Compile Include="Tasks\LayoutLocationInfo.cs" />
569569
<Compile Include="Tasks\LayoutTypeFixup.cs" />
570570
<Compile Include="Tasks\LayoutWidget.cs" />
571+
<Compile Include="Tasks\CheckGoogleSdkRequirements.cs" />
571572
<None Include="Resources\desugar_deploy.jar">
572573
<Link>desugar_deploy.jar</Link>
573574
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

0 commit comments

Comments
 (0)