Skip to content

Conversation

@jonpryor
Copy link
Contributor

@jonpryor jonpryor commented Oct 11, 2017

Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=60069
Context: https://bugzilla.xamarin.com/attachment.cgi?id=25276

API-26 added an android.os.Build.getSerial() method. Under
normal "name mangling" conventions, generator binds this as an
Android.OS.Build.Serial property.

There's just one "minor" problem with this: there is also an
android.os.Build.SERIAL field, since API-9, which generator
also binds as an Android.OS.Build.Serial property.

Thus, a question: given the Java code:

public class Build {
	public static String SERIAL = "UNKNOWN";
	public static String getSerial() {/* ... */ }
}

What will generator do?

Answer: the wrong thing: the field is ignored, and the
Build.getSerial() method is used for the Build.Serial property.

This is problematic. The managed API has not changed -- pre-API-26
and post-API-26 both have a string Build.Serial property --
but the behavior of the method has changed from reading the value of
a static field, to invoking a static method.

A static method that only exists on devices running API-26 and later.

Meaning:

  1. Create a new Xamarin.Android app.
  2. Set $(TargetFrameworkVersion) to v8.0, and
    //uses-sdk/@android:minSdkVersion to 11 within
    AndroidManifest.xml.
  3. Within e.g. MainActivity.OnCreate(), reference the
    Android.OS.Build.Serial property.
  4. Build the app, and run on e.g. an Android 7.1 device.

Expected result: it works!

Actual result: not so much:

Java.Lang.NoSuchMethodError: no static method "Landroid/os/Build;.getSerial()Ljava/lang/String;"

@atsushieno has determined that this is the only such behavioral
breakage introduced by API-26. His
referenced metadata fixup changes patch lists all the fields
which are currently being ignored by the Mono.Android build process.

In the interest of expediency (and getting this merged into d15-4),
include only the metadata changes that impact Build.getSerial(),
and force it to be bound as a Build.GetSerial() method. This
"un-hides" the Build.Serial binding of the Build.SERIAL field,
restoring semantic compatibility.

The remaining of the metadata fixup changes should be merged
separately.

Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=60069
Context: https://bugzilla.xamarin.com/attachment.cgi?id=25276

API-26 added an [`android.os.Build.getSerial()`][0] method. Under
normal "name mangling" conventions, `generator` binds this as an
`Android.OS.Build.Serial` property.

[0]: https://developer.android.com/reference/android/os/Build.html#getSerial()

There's just one "minor" problem with this: there is *also* an
[`android.os.Build.SERIAL`][1] field, since API-9, which `generator`
*also* binds as an `Android.OS.Build.Serial` property.

[1]: https://developer.android.com/reference/android/os/Build.html#SERIAL

Thus, a question: given the Java code:

```java
public class Build {
	public static String SERIAL = "UNKNOWN";
	public static String getSerial() {/* ... */ }
}
```

What will `generator` do?

Answer: the wrong thing: the field is *ignored*, and the
`Build.getSerial()` method is used for the `Build.Serial` property.

This is problematic. *The managed API has not changed* -- pre-API-26
and post-API-26 both have a string `Build.Serial` property --
but the *behavior* of the method has changed from reading the value of
a static field, to invoking a static method.

A static method that only exists on devices running API-26 and later.

Meaning:

 1. Create a new Xamarin.Android app.
 2. Set `$(TargetFrameworkVersion)` to v8.0, and
    `//uses-sdk/@android:minSdkVersion` to 11 within
		`AndroidManifest.xml`.
 3. Within e.g. `MainActivity.OnCreate()`, reference the
    `Android.OS.Build.Serial` property.
 4. Build the app, and run on e.g. an Android 7.1 device.

Expected result: it works!

Actual result: not so much:

	Java.Lang.NoSuchMethodError: no static method "Landroid/os/Build;.getSerial()Ljava/lang/String;"

@atsushieno has determined that this is the only such behavioral
breakage introduced by API-26. His
[referenced metadata fixup changes][2] patch lists all the fields
which are currently being ignored by the `Mono.Android` build process.

[2]: https://bugzilla.xamarin.com/attachment.cgi?id=25276

In the interest of expediency (and getting this merged into d15-4),
include *only* the metadata changes that impact `Build.getSerial()`,
and force it to be bound as a `Build.GetSerial()` method. This
"un-hides" the `Build.Serial` binding of the `Build.SERIAL` field,
restoring semantic compatibility.

The remaining of the metadata fixup changes should be merged
separately.
@atsushieno atsushieno merged commit 36843ae into dotnet:master Oct 12, 2017
jonpryor added a commit that referenced this pull request Oct 12, 2017
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=60069
Context: https://bugzilla.xamarin.com/attachment.cgi?id=25276

API-26 added an [`android.os.Build.getSerial()`][0] method. Under
normal "name mangling" conventions, `generator` binds this as an
`Android.OS.Build.Serial` property.

[0]: https://developer.android.com/reference/android/os/Build.html#getSerial()

There's just one "minor" problem with this: there is *also* an
[`android.os.Build.SERIAL`][1] field, since API-9, which `generator`
*also* binds as an `Android.OS.Build.Serial` property.

[1]: https://developer.android.com/reference/android/os/Build.html#SERIAL

Thus, a question: given the Java code:

```java
public class Build {
	public static String SERIAL = "UNKNOWN";
	public static String getSerial() {/* ... */ }
}
```

What will `generator` do?

Answer: the wrong thing: the field is *ignored*, and the
`Build.getSerial()` method is used for the `Build.Serial` property.

This is problematic. *The managed API has not changed* -- pre-API-26
and post-API-26 both have a string `Build.Serial` property --
but the *behavior* of the method has changed from reading the value of
a static field, to invoking a static method.

A static method that only exists on devices running API-26 and later.

Meaning:

 1. Create a new Xamarin.Android app.
 2. Set `$(TargetFrameworkVersion)` to v8.0, and
    `//uses-sdk/@android:minSdkVersion` to 11 within
		`AndroidManifest.xml`.
 3. Within e.g. `MainActivity.OnCreate()`, reference the
    `Android.OS.Build.Serial` property.
 4. Build the app, and run on e.g. an Android 7.1 device.

Expected result: it works!

Actual result: not so much:

	Java.Lang.NoSuchMethodError: no static method "Landroid/os/Build;.getSerial()Ljava/lang/String;"

@atsushieno has determined that this is the only such behavioral
breakage introduced by API-26. His
[referenced metadata fixup changes][2] patch lists all the fields
which are currently being ignored by the `Mono.Android` build process.

[2]: https://bugzilla.xamarin.com/attachment.cgi?id=25276

In the interest of expediency (and getting this merged into d15-4),
include *only* the metadata changes that impact `Build.getSerial()`,
and force it to be bound as a `Build.GetSerial()` method. This
"un-hides" the `Build.Serial` binding of the `Build.SERIAL` field,
restoring semantic compatibility.

The remaining of the metadata fixup changes should be merged
separately.
jonpryor added a commit that referenced this pull request Oct 12, 2017
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=60069
Context: https://bugzilla.xamarin.com/attachment.cgi?id=25276

API-26 added an [`android.os.Build.getSerial()`][0] method. Under
normal "name mangling" conventions, `generator` binds this as an
`Android.OS.Build.Serial` property.

[0]: https://developer.android.com/reference/android/os/Build.html#getSerial()

There's just one "minor" problem with this: there is *also* an
[`android.os.Build.SERIAL`][1] field, since API-9, which `generator`
*also* binds as an `Android.OS.Build.Serial` property.

[1]: https://developer.android.com/reference/android/os/Build.html#SERIAL

Thus, a question: given the Java code:

```java
public class Build {
	public static String SERIAL = "UNKNOWN";
	public static String getSerial() {/* ... */ }
}
```

What will `generator` do?

Answer: the wrong thing: the field is *ignored*, and the
`Build.getSerial()` method is used for the `Build.Serial` property.

This is problematic. *The managed API has not changed* -- pre-API-26
and post-API-26 both have a string `Build.Serial` property --
but the *behavior* of the method has changed from reading the value of
a static field, to invoking a static method.

A static method that only exists on devices running API-26 and later.

Meaning:

 1. Create a new Xamarin.Android app.
 2. Set `$(TargetFrameworkVersion)` to v8.0, and
    `//uses-sdk/@android:minSdkVersion` to 11 within
		`AndroidManifest.xml`.
 3. Within e.g. `MainActivity.OnCreate()`, reference the
    `Android.OS.Build.Serial` property.
 4. Build the app, and run on e.g. an Android 7.1 device.

Expected result: it works!

Actual result: not so much:

	Java.Lang.NoSuchMethodError: no static method "Landroid/os/Build;.getSerial()Ljava/lang/String;"

@atsushieno has determined that this is the only such behavioral
breakage introduced by API-26. His
[referenced metadata fixup changes][2] patch lists all the fields
which are currently being ignored by the `Mono.Android` build process.

[2]: https://bugzilla.xamarin.com/attachment.cgi?id=25276

In the interest of expediency (and getting this merged into d15-4),
include *only* the metadata changes that impact `Build.getSerial()`,
and force it to be bound as a `Build.GetSerial()` method. This
"un-hides" the `Build.Serial` binding of the `Build.SERIAL` field,
restoring semantic compatibility.

The remaining of the metadata fixup changes should be merged
separately.
Redth pushed a commit to Redth/xamarin-android that referenced this pull request Oct 30, 2017
)

Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=60069
Context: https://bugzilla.xamarin.com/attachment.cgi?id=25276

API-26 added an [`android.os.Build.getSerial()`][0] method. Under
normal "name mangling" conventions, `generator` binds this as an
`Android.OS.Build.Serial` property.

[0]: https://developer.android.com/reference/android/os/Build.html#getSerial()

There's just one "minor" problem with this: there is *also* an
[`android.os.Build.SERIAL`][1] field, since API-9, which `generator`
*also* binds as an `Android.OS.Build.Serial` property.

[1]: https://developer.android.com/reference/android/os/Build.html#SERIAL

Thus, a question: given the Java code:

```java
public class Build {
	public static String SERIAL = "UNKNOWN";
	public static String getSerial() {/* ... */ }
}
```

What will `generator` do?

Answer: the wrong thing: the field is *ignored*, and the
`Build.getSerial()` method is used for the `Build.Serial` property.

This is problematic. *The managed API has not changed* -- pre-API-26
and post-API-26 both have a string `Build.Serial` property --
but the *behavior* of the method has changed from reading the value of
a static field, to invoking a static method.

A static method that only exists on devices running API-26 and later.

Meaning:

 1. Create a new Xamarin.Android app.
 2. Set `$(TargetFrameworkVersion)` to v8.0, and
    `//uses-sdk/@android:minSdkVersion` to 11 within
		`AndroidManifest.xml`.
 3. Within e.g. `MainActivity.OnCreate()`, reference the
    `Android.OS.Build.Serial` property.
 4. Build the app, and run on e.g. an Android 7.1 device.

Expected result: it works!

Actual result: not so much:

	Java.Lang.NoSuchMethodError: no static method "Landroid/os/Build;.getSerial()Ljava/lang/String;"

@atsushieno has determined that this is the only such behavioral
breakage introduced by API-26. His
[referenced metadata fixup changes][2] patch lists all the fields
which are currently being ignored by the `Mono.Android` build process.

[2]: https://bugzilla.xamarin.com/attachment.cgi?id=25276

In the interest of expediency (and getting this merged into d15-4),
include *only* the metadata changes that impact `Build.getSerial()`,
and force it to be bound as a `Build.GetSerial()` method. This
"un-hides" the `Build.Serial` binding of the `Build.SERIAL` field,
restoring semantic compatibility.

The remaining of the metadata fixup changes should be merged
separately.
jonpryor pushed a commit that referenced this pull request Dec 8, 2019
#3884)

Fixes: #1118

Context: https://bugzilla.xamarin.com/show_bug.cgi?id=60069
Context: #930

Our current API check workflow is not able to detect some API breakage
or is flagging non-breaking API changes as breaking.

Examples of breakages not previously reported:

  * Changing the values of `[Register]` attributes may be a breaking
    change but is not flagged by `mono-html-html`.

  * Adding `abstract` methods to an `abstract` class

Examples of acceptable changes which elicit warnings:

  * Changing a base class in a compatible manner.

Instead of using `mono-api-info` + `mono-api-html`, use
[Microsoft.DotNet.ApiCompat][0] to perform API compatibility
validation, which is what the .NET and Azure teams use.

Microsoft.DotNet.ApiCompat reports `[Register]` changes:

	CannotChangeAttribute : Attribute 'Android.Runtime.RegisterAttribute' on 'Android.Database.Sqlite.SQLiteDatabase.Path.get()' changed from '[RegisterAttribute("getPath", "()Ljava/lang/String;", "")]' in the contract to '[RegisterAttribute("getPath", "()Ljava/lang/String;", "GetGetPathHandler")]' in the implementation.

and thus would have caught the `Build.SERIAL` breakage in #930.

To override the warnings produced by Microsoft.DotNet.ApiCompat,
the message can be copied into an appropriate
`tests/api-compatibility/acceptable-breakages-*.txt` file.

See `tests/api-compatibility/README.md` for details.

[0]: https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.ApiCompat
@github-actions github-actions bot locked and limited conversation to collaborators Feb 4, 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