Skip to content

Commit

Permalink
[Mono.Android] Fix incorrect Bluetooth enumification (#6214)
Browse files Browse the repository at this point in the history
Fixes: https://developercommunity2.visualstudio.com/t/xamarin-android-bluetooth-the-advertisin/841102
Fixes: #2595

Update enumification of various
`Android.Bluetooth.LE.AdvertisingSetParameters.Builder` and
`Android.Bluetooth.BluetoothDevice` methods to use the
`Android.Bluetooth.BluetoothPhy` enum instead of the
`Android.Bluetooth.LE.ScanSettingsPhy` enum, introduced in e33eb53.

Backwards compatibility is achieved by creating overloads for the
existing methods in `Additions`, and marking them as `[Obsolete]`.

The API "breakage" is because the `[Register]` attribute has moved
from the incorrect methods to the correct methods.  As the signature
change is an enum, the marshalled type is still an `int`, so moving
the `[Register]` should not cause issues.

For example:

	// Current
	[Register]
	public void DoSomething (BadEnum value) { ... }

	// Fixed
	[Register]
	public void DoSomething (GoodEnum value) { ... }

	[Obsolete ("Use DoSomething(GoodEnum)")]
	public void DoSomething (BadEnum value) => DoSomething ((GoodEnum)value);

Note: this is only generally save to do when `DoSomething()` is a
*non-`virtual`* method (i.e. Java `final` method).  Fortunately, this
is the case with the methods involved here.
  • Loading branch information
jpobst committed Aug 25, 2021
1 parent 2677028 commit 5f408eb
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 3 deletions.
@@ -0,0 +1,24 @@
#if ANDROID_26

namespace Android.Bluetooth.LE
{
public sealed partial class AdvertisingSetParameters
{
public sealed partial class Builder
{
// These methods were obsoleted as a warning in API-31
[global::System.Obsolete ("This method has the wrong enumeration. Use the version that takes an 'Android.Bluetooth.BluetoothPhy' instead.")]
[global::System.Runtime.Versioning.SupportedOSPlatformAttribute ("android26.0")]
public unsafe Android.Bluetooth.LE.AdvertisingSetParameters.Builder? SetPrimaryPhy ([global::Android.Runtime.GeneratedEnum] Android.Bluetooth.LE.ScanSettingsPhy primaryPhy)
=> SetPrimaryPhy ((Android.Bluetooth.BluetoothPhy) primaryPhy);

[global::System.Obsolete ("This method has the wrong enumeration. Use the version that takes an 'Android.Bluetooth.BluetoothPhy' instead.")]
[global::System.Runtime.Versioning.SupportedOSPlatformAttribute ("android26.0")]
public unsafe Android.Bluetooth.LE.AdvertisingSetParameters.Builder? SetSecondaryPhy ([global::Android.Runtime.GeneratedEnum] Android.Bluetooth.LE.ScanSettingsPhy secondaryPhy)
=> SetSecondaryPhy ((Android.Bluetooth.BluetoothPhy) secondaryPhy);
}
}
}

#endif

21 changes: 21 additions & 0 deletions src/Mono.Android/Android.Bluetooth/BluetoothDevice.cs
@@ -0,0 +1,21 @@
#if ANDROID_26

namespace Android.Bluetooth
{
public sealed partial class BluetoothDevice
{
// These methods were obsoleted as a warning in API-31
[global::System.Obsolete ("This method has the wrong enumeration. Use the version that takes an 'Android.Bluetooth.BluetoothPhy' instead.")]
[global::System.Runtime.Versioning.SupportedOSPlatformAttribute ("android26.0")]
public unsafe Android.Bluetooth.BluetoothGatt? ConnectGatt (Android.Content.Context? context, bool autoConnect, Android.Bluetooth.BluetoothGattCallback? @callback, [global::Android.Runtime.GeneratedEnum] Android.Bluetooth.BluetoothTransports transport, [global::Android.Runtime.GeneratedEnum] Android.Bluetooth.LE.ScanSettingsPhy phy)
=> ConnectGatt (context, autoConnect, @callback, transport, (Android.Bluetooth.BluetoothPhy) phy);

[global::System.Obsolete ("This method has the wrong enumeration. Use the version that takes an 'Android.Bluetooth.BluetoothPhy' instead.")]
[global::System.Runtime.Versioning.SupportedOSPlatformAttribute ("android26.0")]
public unsafe Android.Bluetooth.BluetoothGatt? ConnectGatt (Android.Content.Context? context, bool autoConnect, Android.Bluetooth.BluetoothGattCallback? @callback, [global::Android.Runtime.GeneratedEnum] Android.Bluetooth.BluetoothTransports transport, [global::Android.Runtime.GeneratedEnum] Android.Bluetooth.LE.ScanSettingsPhy phy, Android.OS.Handler? handler)
=> ConnectGatt (context, autoConnect, @callback, transport, (Android.Bluetooth.BluetoothPhy) phy, handler);
}
}

#endif

2 changes: 2 additions & 0 deletions src/Mono.Android/Mono.Android.csproj
Expand Up @@ -172,6 +172,8 @@
<Compile Include="Android.App\UsesLibraryAttribute.cs" />
<Compile Include="Android.App\UsesPermissionAttribute.cs" />
<Compile Include="Android.App.Admin\DevicePolicyManager.cs" />
<Compile Include="Android.Bluetooth\AdvertisingSetParametersBuilder.cs" />
<Compile Include="Android.Bluetooth\BluetoothDevice.cs" />
<Compile Include="Android.Bluetooth\BluetoothGattServer.cs" />
<Compile Include="Android.Bluetooth\BluetoothGattServerCallback.cs" />
<Compile Include="Android.Content\ContentProvider.cs" />
Expand Down
6 changes: 3 additions & 3 deletions src/Mono.Android/methodmap.csv
Expand Up @@ -2189,8 +2189,8 @@
26, android.bluetooth, BluetoothGatt, setPreferredPhy, phyOptions, Android.Bluetooth.BluetoothPhyOption
26, android.bluetooth.le, ScanSettings.Builder, setPhy, phy, Android.Bluetooth.BluetoothPhy
26, android.bluetooth.le, ScanSettings, getPhy, return, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth.le, AdvertisingSetParameters.Builder, setPrimaryPhy, primaryPhy, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth.le, AdvertisingSetParameters.Builder, setSecondaryPhy, secondaryPhy, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth.le, AdvertisingSetParameters.Builder, setPrimaryPhy, primaryPhy, Android.Bluetooth.BluetoothPhy
26, android.bluetooth.le, AdvertisingSetParameters.Builder, setSecondaryPhy, secondaryPhy, Android.Bluetooth.BluetoothPhy
26, android.bluetooth.le, AdvertisingSetParameters.Builder, setTxPowerLevel, txPowerLevel, Android.Bluetooth.LE.AdvertiseTxPower
26, android.bluetooth.le, ScanResult, ctor, primaryPhy, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth.le, ScanResult, ctor, secondaryPhy, Android.Bluetooth.LE.ScanSettingsPhy
Expand All @@ -2205,7 +2205,7 @@
26, android.bluetooth, BluetoothGattServerCallback, onPhyUpdate, txPhy, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth, BluetoothGattServerCallback, onPhyUpdate, rxPhy, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth, BluetoothGattServerCallback, onPhyUpdate, status, Android.Bluetooth.GattStatus
26, android.bluetooth, BluetoothDevice, connectGatt, phy, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth, BluetoothDevice, connectGatt, phy, Android.Bluetooth.BluetoothPhy
26, android.bluetooth, BluetoothDevice, connectGatt, transport, Android.Bluetooth.BluetoothTransports
26, android.bluetooth, BluetoothGattCallback, onPhyRead, txPhy, Android.Bluetooth.LE.ScanSettingsPhy
26, android.bluetooth, BluetoothGattCallback, onPhyRead, rxPhy, Android.Bluetooth.LE.ScanSettingsPhy
Expand Down
4 changes: 4 additions & 0 deletions tests/api-compatibility/acceptable-breakages-vReference.txt
@@ -1 +1,5 @@
Compat issues with assembly Mono.Android:
CannotRemoveAttribute : Attribute 'Android.Runtime.RegisterAttribute' exists on 'Android.Bluetooth.BluetoothDevice.ConnectGatt(Android.Content.Context, System.Boolean, Android.Bluetooth.BluetoothGattCallback, Android.Bluetooth.BluetoothTransports, Android.Bluetooth.LE.ScanSettingsPhy)' in the contract but not the implementation.
CannotRemoveAttribute : Attribute 'Android.Runtime.RegisterAttribute' exists on 'Android.Bluetooth.BluetoothDevice.ConnectGatt(Android.Content.Context, System.Boolean, Android.Bluetooth.BluetoothGattCallback, Android.Bluetooth.BluetoothTransports, Android.Bluetooth.LE.ScanSettingsPhy, Android.OS.Handler)' in the contract but not the implementation.
CannotRemoveAttribute : Attribute 'Android.Runtime.RegisterAttribute' exists on 'Android.Bluetooth.LE.AdvertisingSetParameters.Builder.SetPrimaryPhy(Android.Bluetooth.LE.ScanSettingsPhy)' in the contract but not the implementation.
CannotRemoveAttribute : Attribute 'Android.Runtime.RegisterAttribute' exists on 'Android.Bluetooth.LE.AdvertisingSetParameters.Builder.SetSecondaryPhy(Android.Bluetooth.LE.ScanSettingsPhy)' in the contract but not the implementation.

0 comments on commit 5f408eb

Please sign in to comment.