From 5f408ebb22df51b598c62f776ee0f82f92661b58 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 24 Aug 2021 19:42:43 -0500 Subject: [PATCH] [Mono.Android] Fix incorrect Bluetooth enumification (#6214) Fixes: https://developercommunity2.visualstudio.com/t/xamarin-android-bluetooth-the-advertisin/841102 Fixes: https://github.com/xamarin/xamarin-android/issues/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 e33eb53407. 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. --- .../AdvertisingSetParametersBuilder.cs | 24 +++++++++++++++++++ .../Android.Bluetooth/BluetoothDevice.cs | 21 ++++++++++++++++ src/Mono.Android/Mono.Android.csproj | 2 ++ src/Mono.Android/methodmap.csv | 6 ++--- .../acceptable-breakages-vReference.txt | 4 ++++ 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/Mono.Android/Android.Bluetooth/AdvertisingSetParametersBuilder.cs create mode 100644 src/Mono.Android/Android.Bluetooth/BluetoothDevice.cs diff --git a/src/Mono.Android/Android.Bluetooth/AdvertisingSetParametersBuilder.cs b/src/Mono.Android/Android.Bluetooth/AdvertisingSetParametersBuilder.cs new file mode 100644 index 00000000000..e5140a5bec1 --- /dev/null +++ b/src/Mono.Android/Android.Bluetooth/AdvertisingSetParametersBuilder.cs @@ -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 + diff --git a/src/Mono.Android/Android.Bluetooth/BluetoothDevice.cs b/src/Mono.Android/Android.Bluetooth/BluetoothDevice.cs new file mode 100644 index 00000000000..334995cbdcc --- /dev/null +++ b/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 + diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 444dfbfdf0e..f96fdd296d4 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -172,6 +172,8 @@ + + diff --git a/src/Mono.Android/methodmap.csv b/src/Mono.Android/methodmap.csv index 22cd2136edd..8d06b1e9a0d 100644 --- a/src/Mono.Android/methodmap.csv +++ b/src/Mono.Android/methodmap.csv @@ -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 @@ -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 diff --git a/tests/api-compatibility/acceptable-breakages-vReference.txt b/tests/api-compatibility/acceptable-breakages-vReference.txt index 9916b31e8dd..c10071c2921 100644 --- a/tests/api-compatibility/acceptable-breakages-vReference.txt +++ b/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.