Skip to content

Commit 4cd2060

Browse files
authored
[Mono.Android] Use Android platform api-versions.xml (#4186)
A "funny" thing happened when we bumped `$(XAPlatformToolsVersion)` in PR #4012: ~all of the API compat checks started failing! AfterBuild: CheckApiCompatibility for ApiLevel: v10.0 CompatApi command: ../../packages/Microsoft.DotNet.ApiCompat.5.0.0-beta.19606.1/tools/net472/Microsoft.DotNet.ApiCompat.exe "../../tests/api-compatibility\reference\ApiCompatTemp" -i "F:\A\xamarin-v000006-1\_work\2\s\bin\Release\lib\xamarin.android\xbuild-frameworks\MonoAndroid\v10.0\ApiCompatTemp" --exclude-attributes ../../tests/api-compatibility\api-compat-exclude-attributes.txt Compat issues with assembly Mono.Android: CannotChangeAttribute : Attribute 'Android.Runtime.RegisterAttribute' on 'System.String Android.Manifest.Permission.AccessBackgroundLocation' changed from '[RegisterAttribute("ACCESS_BACKGROUND_LOCATION")]' in the contract to '[RegisterAttribute("ACCESS_BACKGROUND_LOCATION", ApiSince=29)]' in the implementation. ... The API compat checks are failing because of the *introduction* of `RegisterAttribute.ApiSince` property values for members added in API-29, and these errors didn't "make sense" to use because we had expected all these members to *already* have `ApiSince=29`! What Went Wrong™? For starters, our memory and expectations were...incomplete. `RegisterAttribute.ApiSince` is set based on the contents of the Android SDK file `platform-tools/api/api-versions.xml`, which is part of the "platform-tools" package. Turns Out™ that `api-versions.xml` was *not* updated by Google when the platform-tools package was updated to r29. Specifically, the `platform-tools/api/api-versions.xml` file within `platform-tools_r29.0.1-darwin.zip` doesn't contain *any* members from API-29, and `RegisterAttribute.ApiSince` is only emitted when the member is found within `api-versions.xml`. This explains why PR #4012 "caused" the API breakage: The platform-tools r29.0.5 package *does* contain an `api-versions.xml` which contains API-29 members; thus updating platform-tools "caused" the emission of the `RegisterAttribute.ApiSince` property values. Which is a long-winded way of saying that *we cannot trust* the `api-versions.xml` file within the platform-tools package. With that trust lost, what do we use instead? There is another set of `api-version.xml` files: starting with API-26, there are `platforms/android-*/data/api-versions.xml` files. Furthermore, the `api-versions.xml` file included with API-Q -- the preview for API-29 -- *did* contain the members added in API-29, and *did* indicate that those members were added in API-29. As such, we do consider this source of data to be trustworthy (this week, anyway). Update `Mono.Android.targets` to use `$(AndroidSdkDirectory)\platforms\android-$(AndroidApiLevel)\data\api-versions.xml` for `RegisterAttribute.ApiSince` information, if it exists. If it doesn't exist, we fallback and use the previously used platform-tools copy of `api-versions.xml`. Finally, two related changes: 1. Update to use `Microsoft.DotNet.GenAPI` and `Microsoft.DotNet.ApiCompat` package versions of 5.0.0-beta.20078.1, up from 5.0.0-beta.20078.1. This was done as it supposedly contains performance improvements. 2. Improve the mono crash detection from 5b1422c. With 5b1422c, sometimes there would be "odd behavior" when re-using the same `Process` object after the crash was detected. The `Process` usage recommendation is to use a new `Process` object for each process invocation; implement this recommendation.
1 parent e120647 commit 4cd2060

File tree

7 files changed

+1406
-51
lines changed

7 files changed

+1406
-51
lines changed

build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@
6262
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\JdkInfo.cs" />
6363
</ItemGroup>
6464
<ItemGroup>
65-
<PackageReference Include="Microsoft.DotNet.ApiCompat" Version="5.0.0-beta.19606.1" IncludeAssets="none" />
66-
<PackageReference Include="Microsoft.DotNet.GenAPI" Version="5.0.0-beta.19606.1" />
65+
<PackageReference Include="Microsoft.DotNet.ApiCompat" Version="5.0.0-beta.20078.1" IncludeAssets="none" />
66+
<PackageReference Include="Microsoft.DotNet.GenAPI" Version="5.0.0-beta.20078.1" />
6767
</ItemGroup>
6868
<ItemGroup>
6969
<ProjectReference Include="..\xa-prep-tasks\xa-prep-tasks.csproj">

build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/CheckApiCompatibility.cs

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -142,44 +142,41 @@ void ValidateApiCompat (string contractPath, bool validateAgainstReference)
142142
File.Copy (implementationAssembly, Path.Combine (targetImplementationPathDirectory, assemblyToValidate), true);
143143
}
144144

145-
using (var genApiProcess = new Process ()) {
145+
for (int i = 0; i < 3; i++) {
146+
using (var genApiProcess = new Process ()) {
146147

147-
genApiProcess.StartInfo.FileName = apiCompat;
148-
genApiProcess.StartInfo.Arguments = $"\"{contractPathDirectory}\" -i \"{targetImplementationPathDirectory}\" ";
148+
genApiProcess.StartInfo.FileName = apiCompat;
149+
genApiProcess.StartInfo.Arguments = $"\"{contractPathDirectory}\" -i \"{targetImplementationPathDirectory}\" ";
149150

150-
// Verify if there is an exclusion list
151-
var excludeAttributes = Path.Combine (ApiCompatibilityPath, $"api-compat-exclude-attributes.txt");
152-
if (File.Exists (excludeAttributes)) {
153-
genApiProcess.StartInfo.Arguments += $"--exclude-attributes {excludeAttributes} ";
154-
}
151+
// Verify if there is an exclusion list
152+
var excludeAttributes = Path.Combine (ApiCompatibilityPath, $"api-compat-exclude-attributes.txt");
153+
if (File.Exists (excludeAttributes)) {
154+
genApiProcess.StartInfo.Arguments += $"--exclude-attributes {excludeAttributes} ";
155+
}
155156

156-
genApiProcess.StartInfo.UseShellExecute = false;
157-
genApiProcess.StartInfo.CreateNoWindow = true;
158-
genApiProcess.StartInfo.RedirectStandardOutput = true;
159-
genApiProcess.StartInfo.RedirectStandardError = true;
160-
genApiProcess.EnableRaisingEvents = true;
161-
162-
var lines = new List<string> ();
163-
var processHasCrashed = false;
164-
void dataReceived (object sender, DataReceivedEventArgs args)
165-
{
166-
if (!string.IsNullOrWhiteSpace (args.Data)) {
167-
lines.Add (args.Data.Trim ());
168-
169-
if (args.Data.IndexOf ("Native Crash Reporting") != -1) {
170-
processHasCrashed = true;
157+
genApiProcess.StartInfo.UseShellExecute = false;
158+
genApiProcess.StartInfo.CreateNoWindow = true;
159+
genApiProcess.StartInfo.RedirectStandardOutput = true;
160+
genApiProcess.StartInfo.RedirectStandardError = true;
161+
genApiProcess.EnableRaisingEvents = true;
162+
163+
var lines = new List<string> ();
164+
var processHasCrashed = false;
165+
void dataReceived (object sender, DataReceivedEventArgs args)
166+
{
167+
if (!string.IsNullOrWhiteSpace (args.Data)) {
168+
lines.Add (args.Data.Trim ());
169+
170+
if (args.Data.IndexOf ("Native Crash Reporting") != -1) {
171+
processHasCrashed = true;
172+
}
171173
}
172174
}
173-
}
174175

175-
genApiProcess.OutputDataReceived += dataReceived;
176-
genApiProcess.ErrorDataReceived += dataReceived;
177-
178-
// Get api definition for previous Api
179-
for (int i = 0; i < 3; i++) {
180-
lines.Clear ();
181-
processHasCrashed = false;
176+
genApiProcess.OutputDataReceived += dataReceived;
177+
genApiProcess.ErrorDataReceived += dataReceived;
182178

179+
// Get api definition for previous Api
183180
compatApiCommand = $"CompatApi command: {genApiProcess.StartInfo.FileName} {genApiProcess.StartInfo.Arguments}";
184181
Log.LogMessage (MessageImportance.High, compatApiCommand);
185182

@@ -198,7 +195,8 @@ void dataReceived (object sender, DataReceivedEventArgs args)
198195

199196
if (processHasCrashed) {
200197
if (i + 1 < 3) {
201-
Log.LogWarning ($"Process has crashed.'{Environment.NewLine}Crash report:{Environment.NewLine}{String.Join (Environment.NewLine, lines)}");
198+
Log.LogWarning ($"Process has crashed.");
199+
Log.LogMessage (MessageImportance.High, String.Join (Environment.NewLine, lines));
202200
Log.LogWarning ($"We will retry.");
203201
continue;
204202
} else {
@@ -328,13 +326,15 @@ Dictionary<string, HashSet<string>> LoadIssues (IEnumerable<string> content)
328326
return issues;
329327
}
330328

331-
void LogError(string errorMessage)
329+
void LogError (string errorMessage)
332330
{
331+
var message = string.Empty;
333332
if (!string.IsNullOrWhiteSpace (compatApiCommand)) {
334-
Log.LogError ($"{compatApiCommand}{Environment.NewLine}{errorMessage}");
335-
} else {
336-
Log.LogError (errorMessage);
333+
errorMessage = $"{compatApiCommand}{Environment.NewLine}{errorMessage}";
337334
}
335+
336+
Log.LogMessage (MessageImportance.High, errorMessage);
337+
Log.LogError (errorMessage);
338338
}
339339
}
340340
}

src/Mono.Android/Mono.Android.targets

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@
7878
Inputs="metadata;enumflags;map.csv;methodmap.csv;$(IntermediateOutputPath)mcw\api.xml"
7979
Outputs="$(IntermediateOutputPath)mcw\Mono.Android.projitems">
8080
<MakeDir Directories="$(IntermediateOutputPath)mcw" />
81+
<PropertyGroup>
82+
<_ApiVersions Condition="Exists('$(AndroidSdkDirectory)\platforms\android-$(AndroidApiLevel)\data\api-versions.xml')">"$(AndroidSdkDirectory)\platforms\android-$(AndroidApiLevel)\data\api-versions.xml"</_ApiVersions>
83+
<_ApiVersions Condition="'$(_ApiVersions)'==''">"$(AndroidSdkDirectory)\platform-tools\api\api-versions.xml"</_ApiVersions>
84+
</PropertyGroup>
8185
<PropertyGroup>
8286
<Generator>"$(XAInstallPrefix)xbuild\Xamarin\Android\generator.exe"</Generator>
8387
<_GenFlags>--public --product-version=7</_GenFlags>
@@ -87,7 +91,7 @@
8791
<_Fixup>--fixup=metadata</_Fixup>
8892
<_Enums1>--preserve-enums --enumflags=enumflags --enumfields=map.csv --enummethods=methodmap.csv</_Enums1>
8993
<_Enums2>--enummetadata=$(IntermediateOutputPath)mcw\enummetadata</_Enums2>
90-
<_Versions>--apiversions="$(AndroidSdkDirectory)\platform-tools\api\api-versions.xml"</_Versions>
94+
<_Versions>--apiversions=$(_ApiVersions)</_Versions>
9195
<_Annotations>--annotations="$(AndroidSdkDirectory)\platform-tools\api\annotations.zip"</_Annotations>
9296
<_Assembly>--assembly="Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"</_Assembly>
9397
<_TypeMap>--type-map-report=$(IntermediateOutputPath)mcw\type-mapping.txt</_TypeMap>
@@ -173,7 +177,7 @@
173177
Inputs="$(TargetPath);@(ApiCompatibilityFiles)"
174178
Outputs="$(IntermediateOutputPath)CheckApiCompatibility.stamp">
175179
<CheckApiCompatibility
176-
ApiCompatPath="$(XamarinAndroidSourcePath)\packages\microsoft.dotnet.apicompat\5.0.0-beta.19606.1\tools\net472\"
180+
ApiCompatPath="$(XamarinAndroidSourcePath)\packages\microsoft.dotnet.apicompat\5.0.0-beta.20078.1\tools\net472\"
177181
ApiLevel="$(AndroidFrameworkVersion)"
178182
LastStableApiLevel="$(AndroidLatestStableFrameworkVersion)"
179183
TargetImplementationPath="$(OutputPath)"

0 commit comments

Comments
 (0)