-
Couldn't load subscription status.
- Fork 63
Description
Context: https://issuetracker.google.com/issues/116182838
Context: 4073f3e
In 2018-September, Google started providing various XML files which were not valid XML. We worked around this in commit 4073f3e by using HtmlAgilityPack to "loosely parse" the XML.
The problem with commit 4073f3e is that the resulting "intermediate" XML isn't "the same". Given XML of:
<!-- valid XML; API-28 -->
<item name="android.accounts.AccountManager android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)">
<annotation name="android.support.annotation.RequiresPermission">
<val name="value" val=""android.permission.MANAGE_ACCOUNTS"" />
<val name="apis" val=""..22"" />
</annotation>
</item>
<!-- invalid XML; API-29 -->
<item name="android.accounts.AccountManager android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)">
<annotation name="androidx.annotation.RequiresPermission">
<val name="value" val=""android.permission.MANAGE_ACCOUNTS"" />
<val name="apis" val=""..22"" />
</annotation>
</item>Consider this fragment:
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.AndroidTools.AnnotationSupport;
class App {
public static void Main ()
{
Console.WriteLine ("- API-28");
var a28 = AndroidAnnotationsSupport.ParseArchive ("$HOME/android-toolchain/sdk/platforms/android-28/data/annotations.zip");
Console.WriteLine ("- API-29");
var a29 = AndroidAnnotationsSupport.ParseArchive ("$HOME/android-toolchain/sdk/platforms/android-29/data/annotations.zip");
var addAccount_28 = a28.Where (a => a.TypeName == "android.accounts.AccountManager" && a.MemberName == "addAccount")
.First ();
var addAccount_29 = a29.Where (a => a.TypeName == "android.accounts.AccountManager" && a.MemberName == "addAccount")
.First ();
Console.WriteLine ($"API-28: {addAccount_28}");
foreach (var a in addAccount_28.Annotations) {
Console.WriteLine ($" Name={a.Name}");
var v = string.Join (", ", a.Values);
Console.WriteLine ($" Values={v}");
}
Console.WriteLine ($"API-29: {addAccount_29}");
foreach (var a in addAccount_29.Annotations) {
Console.WriteLine ($" Name={a.Name}");
var v = string.Join (", ", a.Values);
Console.WriteLine ($" Values={v}");
}
}
}When run, we get:
API-28: @RequiresPermission(value=System.String[], apis=System.String[]) android.accounts.AccountManager.addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)
Name=RequiresPermission
Values=value = "android.permission.MANAGE_ACCOUNTS", apis = "..22"
API-29: @RequiresPermission(value=System.String[], apis=System.String[]) android.accounts.AccountManager.addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)
Name=RequiresPermission
Values=value = "android.permission.MANAGE_ACCOUNTS", apis = "..22"
Note how the Values value changes, from android.permission.MANAGE_ACCOUNTS to "android.permission.MANAGE_ACCOUNTS". This value eventually becomes the RequiresPermission attribute value, resulting in "downstream" Mono.Android.dll changes:
-[global::Android.Runtime.RequiresPermission ("android.permission.MANAGE_ACCOUNTS")]
+[global::Android.Runtime.RequiresPermission ("quot;android.permission.MANAGE_ACCOUNTS"")]which results in hundreds of "API changes" reported by the _CheckApiCompatibility target.
For Great Sanity™, we want the "invalid XML" path to produce the same value as the "valid XML" path, especially considering that the //item/annotation/val/@val attribute value is the same.