Skip to content

Conversation

jpobst
Copy link
Contributor

@jpobst jpobst commented May 11, 2020

Today we populate bound members with ApiSince info in their [Register] attribute. This denotes which platform level the api was added in, allowing the IDE to provide correct cues of which apis are available based on which platform a project targets.

This information is provided via some xml files that Google provides with each platform sdk. Unfortunately these files are not always provided, are not always updated, or not always correct. This leads to issues where we are missing information, or updating platform sdks causes "api breakage" because the info changes.

We generate equivalent data via our api-merge process that we will now use to populate ApiSince instead of the Google-provided files. This data is computed directly from the various android.jar files, so it should always be updated and correct.

Notable differences

Our current method provides data for API levels that we do not use for api-merge, such as 2, 4, 11, 14. However we feel it is ok to lose this data, as it isn't really useful to our users. That is, if the minimum Xamarin.Android can target is API-21, it is not useful to know that an API was added in API-9, since there is no way to target an API level where the member is not available.

As such, we are not collecting data for API levels 21 or below, and all members added in any of those levels are considered to "always" have been available. (No ApiSince.)

ApiCompat

This change creates a significant amount of API "breakages" where ApiSince is either getting added or removed. Rather than add an additional 25K lines to acceptable-breakages, we are updating the reference assembly.

Attached is a file describing the ApiSince info that changed as a result of this for reference. There are no non-ApiSince changes.

~12.3K members previously had no ApiSince and now have ApiSince=22-29.
~12.1K members previously had ApiSince=1-21 and now have no ApiSince.
~200 related fields changed from 28 to 29, this seems to be correct from looking at the source files.

api-compat-parsed.txt

Also ignored attribute T:System.Diagnostics.DebuggerStepThroughAttribute which seems to be generated in some versions of Roslyn when using an async Task method. My local compiler (VS2019 16.5) generates it but apparently the version on the Mac agents does not.

@jpobst jpobst force-pushed the api-since branch 6 times, most recently from 94fe2db to 1f4ddf6 Compare May 12, 2020 19:09
@jpobst jpobst marked this pull request as ready for review May 12, 2020 22:09
@jpobst jpobst requested a review from jonpryor as a code owner May 12, 2020 22:09
@jonpryor jonpryor merged commit 3f438e4 into master May 13, 2020
@jonpryor jonpryor deleted the api-since branch May 13, 2020 01:40
jonpryor pushed a commit that referenced this pull request May 15, 2020
Context: #4012 (comment)
Context: #4012 (comment)
Context: dotnet/java-interop@005e273
Context: a348617

Changes: dotnet/java-interop@e599781...d6024f1

  * dotnet/java-interop@d6024f1: [generator] Use //*/@api-since for RegisterAttribute.ApiSince (#644)
  * dotnet/java-interop@3968236: [generator] slnf file should use relative path. (#641)
  * dotnet/java-interop@67b6f70: [CI] Add a .NET Core Windows lane. (#640)

When `generator --apiversions=FILE` is used, then the
`RegisterAttribute.ApiSince` field will be set to contain the API
version which introduced a method, e.g. when building
`src/Mono.Android`:

	$ generator.exe --apiversions=$HOME/android-toolchain/sdk/platform-tools/api/api-versions.xml …

and `$HOME/android-toolchain/sdk/platform-tools/api/api-versions.xml`
contains:

	<class name="android/view/inspector/IntFlagMapping" since="29">
	  <extends name="java/lang/Object"/>

then `generator` will emit:

	[Register ("android/view/inspector/IntFlagMapping", DoNotGenerateAcw=true, ApiSince=29)]
	partial class IntFlagMapping {}

Unfortunately, we have found that Google's support of this file isn't
guaranteed.  Sometimes it is missing, other times it changes in
unexpected ways; either can causes `ApiCompat` breakage when
building `Mono.Android`, resulting in the removal or modification of
the `RegisterAttribute.ApiSince` values.

In short, we have lost faith in `api-versions.xml`.

dotnet/java-interop@186174c updates `generator` so that *instead of*
using an `api-versions.xml` file to provide `RegisterAttribute.ApiSince`
values, those values can instead come from `//*/@api-since` attributes.

The `//*/@api-since` attributes in turn can come from
`src/Mono.Android/metadata`, based on the `//*/@merge.SourceFile`
attribute values that `build-tools/api-merge` emits (a073d99).  This
data is computed directly from the `android.jar` files, and should
always be updated and (reasonably) correct.

~~ Notable differences ~~

Our current method provides data for API levels that we do not use for
`api-merge`, such as 2, 4, 11, and 14.  However we feel it is ok to
"lose" this data, as it isn't really useful to our users.  That is, if
the minimum Xamarin.Android can target is API-21 (a648981), it is not
useful to know that an API was added in API-9, since there is no way to
target an API level where the member is not available.

As such, we are not collecting data for API levels 21 or below, and all
members added in any of those levels are considered to "always" have
been available, with no `RegisterAttribute.ApiSince` value.

~~ ApiCompat ~~

This change creates a significant amount of API "breakages" where
`RegisterAttribute.ApiSince` is either getting added or removed.
Rather than add an additional 25K lines to `acceptable-breakages`, we
are updating the reference assembly.

[Elsewhere][0] is a list of the `ApiSince` info that changed as a
result, for reference.  There are no non-`ApiSince` changes.

  * ~12.3K members previously had no `ApiSince` and now have
    `ApiSince=22-29`.

  * ~12.1K members previously had `ApiSince=1-21` and now have
    no `ApiSince` value.

  * ~200 related fields changed from `28` to `29`, this seems to be
    correct from looking at the source files.

A snippet of the file:

	System.String Android.Service.Carrier.CarrierMessagingService.ServiceInterface - 0 => 22
	Android.Service.Carrier.CarrierMessagingService..ctor() - 0 => 22
	Android.Service.Carrier.CarrierMessagingService.OnBind(Android.Content.Intent) - 0 => 22
	Android.Service.Carrier.CarrierMessagingService.OnDownloadMms(Android.Net.Uri, System.Int32, Android.Net.Uri, Android.Service.Carrier.CarrierMessagingService.IResultCallback) - 0 => 22
	…

Finally, ignore the attribute
`T:System.Diagnostics.DebuggerStepThroughAttribute`, which seems to be
generated in some versions of Roslyn when using an `async Task` method.
My local compiler (VS2019 16.5) generates it but apparently the version
on the Mac agents does not.

[0]: https://github.com/xamarin/xamarin-android/files/4616691/api-compat-parsed.txt
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants