From a2aaf856fc7d1b4bf451d659ed1a5b7c7ef0248b Mon Sep 17 00:00:00 2001 From: Sebastian Roth Date: Mon, 22 Jan 2024 10:27:42 +0000 Subject: [PATCH] ktlint 1.1.1 --- .../hue/reactivebleexample/MainActivity.kt | 4 +- .../flutterreactiveble/PluginController.kt | 145 ++++++++++++------ .../flutterreactiveble/ReactiveBlePlugin.kt | 5 +- .../hue/flutterreactiveble/ble/BleClient.kt | 35 ++++- .../hue/flutterreactiveble/ble/BleWrapper.kt | 10 ++ .../flutterreactiveble/ble/ConnectionQueue.kt | 1 - .../flutterreactiveble/ble/DeviceConnector.kt | 55 ++++--- .../ble/ReactiveBleClient.kt | 84 ++++++---- .../extensions/RxBleConnectionExtension.kt | 15 +- .../channelhandlers/BleStatusHandler.kt | 13 +- .../CharNotificationHandler.kt | 50 +++--- .../DeviceConnectionHandler.kt | 30 ++-- .../channelhandlers/ScanDevicesHandler.kt | 32 ++-- .../converters/ProtobufMessageConverter.kt | 79 +++++----- .../converters/UuidConverter.kt | 18 ++- .../debugutils/PerformanceAnalyzer.kt | 1 - .../ble/DeviceConnectorTest.kt | 2 - .../ble/ReactiveBleClientTest.kt | 66 +++++--- .../channelhandlers/ConnectionQueueTest.kt | 1 - .../ProtobufMessageConverterTest.kt | 25 +-- ...ervicesWithCharacteristicsConverterTest.kt | 10 +- .../converters/UuidConverterTest.kt | 1 - 22 files changed, 435 insertions(+), 247 deletions(-) diff --git a/example/android/app/src/main/kotlin/com/signify/hue/reactivebleexample/MainActivity.kt b/example/android/app/src/main/kotlin/com/signify/hue/reactivebleexample/MainActivity.kt index 11195b19..36dfe989 100644 --- a/example/android/app/src/main/kotlin/com/signify/hue/reactivebleexample/MainActivity.kt +++ b/example/android/app/src/main/kotlin/com/signify/hue/reactivebleexample/MainActivity.kt @@ -6,7 +6,9 @@ import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity : FlutterActivity() { - override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { + override fun configureFlutterEngine( + @NonNull flutterEngine: FlutterEngine, + ) { GeneratedPluginRegistrant.registerWith(flutterEngine) } } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/PluginController.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/PluginController.kt index 4a65c59c..22b4312c 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/PluginController.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/PluginController.kt @@ -22,23 +22,24 @@ import com.signify.hue.flutterreactiveble.ProtobufModel as pb @Suppress("TooManyFunctions") class PluginController { - private val pluginMethods = mapOf Unit>( - "initialize" to this::initializeClient, - "deinitialize" to this::deinitializeClient, - "scanForDevices" to this::scanForDevices, - "connectToDevice" to this::connectToDevice, - "clearGattCache" to this::clearGattCache, - "disconnectFromDevice" to this::disconnectFromDevice, - "readCharacteristic" to this::readCharacteristic, - "writeCharacteristicWithResponse" to this::writeCharacteristicWithResponse, - "writeCharacteristicWithoutResponse" to this::writeCharacteristicWithoutResponse, - "readNotifications" to this::readNotifications, - "stopNotifications" to this::stopNotifications, - "negotiateMtuSize" to this::negotiateMtuSize, - "requestConnectionPriority" to this::requestConnectionPriority, - "discoverServices" to this::discoverServices, - "getDiscoveredServices" to this::discoverServices, - ) + private val pluginMethods = + mapOf Unit>( + "initialize" to this::initializeClient, + "deinitialize" to this::deinitializeClient, + "scanForDevices" to this::scanForDevices, + "connectToDevice" to this::connectToDevice, + "clearGattCache" to this::clearGattCache, + "disconnectFromDevice" to this::disconnectFromDevice, + "readCharacteristic" to this::readCharacteristic, + "writeCharacteristicWithResponse" to this::writeCharacteristicWithResponse, + "writeCharacteristicWithoutResponse" to this::writeCharacteristicWithoutResponse, + "readNotifications" to this::readNotifications, + "stopNotifications" to this::stopNotifications, + "negotiateMtuSize" to this::negotiateMtuSize, + "requestConnectionPriority" to this::requestConnectionPriority, + "discoverServices" to this::discoverServices, + "getDiscoveredServices" to this::discoverServices, + ) private lateinit var bleClient: com.signify.hue.flutterreactiveble.ble.BleClient @@ -53,7 +54,10 @@ class PluginController { private val uuidConverter = UuidConverter() private val protoConverter = ProtobufMessageConverter() - internal fun initialize(messenger: BinaryMessenger, context: Context) { + internal fun initialize( + messenger: BinaryMessenger, + context: Context, + ) { bleClient = com.signify.hue.flutterreactiveble.ble.ReactiveBleClient(context) scanchannel = EventChannel(messenger, "flutter_reactive_ble_scan") @@ -77,32 +81,50 @@ class PluginController { deviceConnectionHandler.disconnectAll() } - internal fun execute(call: MethodCall, result: Result) { + internal fun execute( + call: MethodCall, + result: Result, + ) { pluginMethods[call.method]?.invoke(call, result) ?: result.notImplemented() } - private fun initializeClient(call: MethodCall, result: Result) { + private fun initializeClient( + call: MethodCall, + result: Result, + ) { bleClient.initializeClient() result.success(null) } - private fun deinitializeClient(call: MethodCall, result: Result) { + private fun deinitializeClient( + call: MethodCall, + result: Result, + ) { deinitialize() result.success(null) } - private fun scanForDevices(call: MethodCall, result: Result) { + private fun scanForDevices( + call: MethodCall, + result: Result, + ) { scanDevicesHandler.prepareScan(pb.ScanForDevicesRequest.parseFrom(call.arguments as ByteArray)) result.success(null) } - private fun connectToDevice(call: MethodCall, result: Result) { + private fun connectToDevice( + call: MethodCall, + result: Result, + ) { result.success(null) val connectDeviceMessage = pb.ConnectToDeviceRequest.parseFrom(call.arguments as ByteArray) deviceConnectionHandler.connectToDevice(connectDeviceMessage) } - private fun clearGattCache(call: MethodCall, result: Result) { + private fun clearGattCache( + call: MethodCall, + result: Result, + ) { val args = pb.ClearGattCacheRequest.parseFrom(call.arguments as ByteArray) bleClient.clearGattCache(args.deviceId) .observeOn(AndroidSchedulers.mainThread()) @@ -112,23 +134,30 @@ class PluginController { result.success(info.toByteArray()) }, { - val info = protoConverter.convertClearGattCacheError( - ClearGattCacheErrorType.UNKNOWN, - it.message, - ) + val info = + protoConverter.convertClearGattCacheError( + ClearGattCacheErrorType.UNKNOWN, + it.message, + ) result.success(info.toByteArray()) }, ) .discard() } - private fun disconnectFromDevice(call: MethodCall, result: Result) { + private fun disconnectFromDevice( + call: MethodCall, + result: Result, + ) { result.success(null) val connectDeviceMessage = pb.DisconnectFromDeviceRequest.parseFrom(call.arguments as ByteArray) deviceConnectionHandler.disconnectDevice(connectDeviceMessage.deviceId) } - private fun readCharacteristic(call: MethodCall, result: Result) { + private fun readCharacteristic( + call: MethodCall, + result: Result, + ) { result.success(null) val readCharMessage = pb.ReadCharacteristicRequest.parseFrom(call.arguments as ByteArray) @@ -146,10 +175,11 @@ class PluginController { { charResult -> when (charResult) { is com.signify.hue.flutterreactiveble.ble.CharOperationSuccessful -> { - val charInfo = protoConverter.convertCharacteristicInfo( - readCharMessage.characteristic, - charResult.value.toByteArray(), - ) + val charInfo = + protoConverter.convertCharacteristicInfo( + readCharMessage.characteristic, + charResult.value.toByteArray(), + ) charNotificationHandler.addSingleReadToStream(charInfo) } is com.signify.hue.flutterreactiveble.ble.CharOperationFailed -> { @@ -178,12 +208,26 @@ class PluginController { .discard() } - private fun writeCharacteristicWithResponse(call: MethodCall, result: Result) { - executeWriteAndPropagateResultToChannel(call, result, com.signify.hue.flutterreactiveble.ble.BleClient::writeCharacteristicWithResponse) + private fun writeCharacteristicWithResponse( + call: MethodCall, + result: Result, + ) { + executeWriteAndPropagateResultToChannel( + call, + result, + com.signify.hue.flutterreactiveble.ble.BleClient::writeCharacteristicWithResponse, + ) } - private fun writeCharacteristicWithoutResponse(call: MethodCall, result: Result) { - executeWriteAndPropagateResultToChannel(call, result, com.signify.hue.flutterreactiveble.ble.BleClient::writeCharacteristicWithoutResponse) + private fun writeCharacteristicWithoutResponse( + call: MethodCall, + result: Result, + ) { + executeWriteAndPropagateResultToChannel( + call, + result, + com.signify.hue.flutterreactiveble.ble.BleClient::writeCharacteristicWithoutResponse, + ) } private fun executeWriteAndPropagateResultToChannel( @@ -237,19 +281,28 @@ class PluginController { .discard() } - private fun readNotifications(call: MethodCall, result: Result) { + private fun readNotifications( + call: MethodCall, + result: Result, + ) { val request = pb.NotifyCharacteristicRequest.parseFrom(call.arguments as ByteArray) charNotificationHandler.subscribeToNotifications(request) result.success(null) } - private fun stopNotifications(call: MethodCall, result: Result) { + private fun stopNotifications( + call: MethodCall, + result: Result, + ) { val request = pb.NotifyNoMoreCharacteristicRequest.parseFrom(call.arguments as ByteArray) charNotificationHandler.unsubscribeFromNotifications(request) result.success(null) } - private fun negotiateMtuSize(call: MethodCall, result: Result) { + private fun negotiateMtuSize( + call: MethodCall, + result: Result, + ) { val request = pb.NegotiateMtuRequest.parseFrom(call.arguments as ByteArray) bleClient.negotiateMtuSize(request.deviceId, request.mtuSize) .observeOn(AndroidSchedulers.mainThread()) @@ -271,7 +324,10 @@ class PluginController { .discard() } - private fun requestConnectionPriority(call: MethodCall, result: Result) { + private fun requestConnectionPriority( + call: MethodCall, + result: Result, + ) { val request = pb.ChangeConnectionPriorityRequest.parseFrom(call.arguments as ByteArray) bleClient.requestConnectionPriority(request.deviceId, request.priority.toConnectionPriority()) @@ -298,7 +354,10 @@ class PluginController { .discard() } - private fun discoverServices(call: MethodCall, result: Result) { + private fun discoverServices( + call: MethodCall, + result: Result, + ) { val request = pb.DiscoverServicesRequest.parseFrom(call.arguments as ByteArray) bleClient.discoverServices(request.deviceId) diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ReactiveBlePlugin.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ReactiveBlePlugin.kt index 91e9a741..f4202c38 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ReactiveBlePlugin.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ReactiveBlePlugin.kt @@ -37,7 +37,10 @@ class ReactiveBlePlugin : FlutterPlugin, MethodChannel.MethodCallHandler { } } - override fun onMethodCall(call: MethodCall, result: Result) { + override fun onMethodCall( + call: MethodCall, + result: Result, + ) { pluginController.execute(call, result) } } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleClient.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleClient.kt index df226324..01defd84 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleClient.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleClient.kt @@ -12,39 +12,64 @@ import java.util.UUID @Suppress("TooManyFunctions") interface BleClient { - val connectionUpdateSubject: BehaviorSubject fun initializeClient() - fun scanForDevices(services: List, scanMode: ScanMode, requireLocationServicesEnabled: Boolean): Observable - fun connectToDevice(deviceId: String, timeout: Duration) + + fun scanForDevices( + services: List, + scanMode: ScanMode, + requireLocationServicesEnabled: Boolean, + ): Observable + + fun connectToDevice( + deviceId: String, + timeout: Duration, + ) + fun disconnectDevice(deviceId: String) + fun disconnectAllDevices() + fun discoverServices(deviceId: String): Single + fun clearGattCache(deviceId: String): Completable + fun readCharacteristic( deviceId: String, characteristicId: UUID, characteristicInstanceId: Int, ): Single + fun setupNotification( deviceId: String, characteristicId: UUID, characteristicInstanceId: Int, ): Observable + fun writeCharacteristicWithResponse( deviceId: String, characteristicId: UUID, characteristicInstanceId: Int, value: ByteArray, ): Single + fun writeCharacteristicWithoutResponse( deviceId: String, characteristicId: UUID, characteristicInstanceId: Int, value: ByteArray, ): Single - fun negotiateMtuSize(deviceId: String, size: Int): Single + + fun negotiateMtuSize( + deviceId: String, + size: Int, + ): Single + fun observeBleStatus(): Observable - fun requestConnectionPriority(deviceId: String, priority: ConnectionPriority): Single + + fun requestConnectionPriority( + deviceId: String, + priority: ConnectionPriority, + ): Single } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleWrapper.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleWrapper.kt index 04ab551c..8c926fa3 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleWrapper.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleWrapper.kt @@ -34,23 +34,33 @@ data class ScanInfo(val deviceId: String, val name: String, val rssi: Int, val c } sealed class ConnectionUpdate + data class ConnectionUpdateSuccess(val deviceId: String, val connectionState: Int) : ConnectionUpdate() + data class ConnectionUpdateError(val deviceId: String, val errorMessage: String) : ConnectionUpdate() sealed class EstablishConnectionResult + data class EstablishedConnection(val deviceId: String, val rxConnection: RxBleConnection) : EstablishConnectionResult() + data class EstablishConnectionFailure(val deviceId: String, val errorMessage: String) : EstablishConnectionResult() sealed class MtuNegotiateResult + data class MtuNegotiateSuccesful(val deviceId: String, val size: Int) : MtuNegotiateResult() + data class MtuNegotiateFailed(val deviceId: String, val errorMessage: String) : MtuNegotiateResult() sealed class CharOperationResult + data class CharOperationSuccessful(val deviceId: String, val value: List) : CharOperationResult() + data class CharOperationFailed(val deviceId: String, val errorMessage: String) : CharOperationResult() sealed class RequestConnectionPriorityResult + data class RequestConnectionPrioritySuccess(val deviceId: String) : RequestConnectionPriorityResult() + data class RequestConnectionPriorityFailed(val deviceId: String, val errorMessage: String) : RequestConnectionPriorityResult() enum class BleStatus(val code: Int) { diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ConnectionQueue.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ConnectionQueue.kt index 80287378..6c0343fe 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ConnectionQueue.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ConnectionQueue.kt @@ -4,7 +4,6 @@ import androidx.annotation.VisibleForTesting import io.reactivex.subjects.BehaviorSubject internal class ConnectionQueue { - private val queueSubject = BehaviorSubject.createDefault(listOf()) fun observeQueue() = queueSubject diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnector.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnector.kt index 9bde27e0..0adbca37 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnector.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnector.kt @@ -21,7 +21,6 @@ internal class DeviceConnector( private val updateListeners: (update: ConnectionUpdate) -> Unit, private val connectionQueue: ConnectionQueue, ) { - companion object { private const val minTimeMsBeforeDisconnectingIsAllowed = 200L private const val delayMsAfterClearingCache = 300L @@ -34,10 +33,11 @@ internal class DeviceConnector( @VisibleForTesting internal var connectionDisposable: Disposable? = null - private val lazyConnection = lazy { - connectionDisposable = establishConnection(device) - connectDeviceSubject - } + private val lazyConnection = + lazy { + connectionDisposable = establishConnection(device) + connectDeviceSubject + } private val currentConnection: EstablishConnectionResult? get() = if (lazyConnection.isInitialized()) connection.value else null @@ -142,7 +142,10 @@ internal class DeviceConnector( ) } - private fun connectDevice(rxBleDevice: RxBleDevice, shouldNotTimeout: Boolean): Observable = + private fun connectDevice( + rxBleDevice: RxBleDevice, + shouldNotTimeout: Boolean, + ): Observable = rxBleDevice.establishConnection(shouldNotTimeout) .compose { if (shouldNotTimeout) { @@ -157,12 +160,13 @@ internal class DeviceConnector( } } - internal fun clearGattCache(): Completable = currentConnection?.let { connection -> - when (connection) { - is EstablishedConnection -> clearGattCache(connection.rxConnection) - is EstablishConnectionFailure -> Completable.error(Throwable(connection.errorMessage)) - } - } ?: Completable.error(IllegalStateException("Connection is not established")) + internal fun clearGattCache(): Completable = + currentConnection?.let { connection -> + when (connection) { + is EstablishedConnection -> clearGattCache(connection.rxConnection) + is EstablishConnectionFailure -> Completable.error(Throwable(connection.errorMessage)) + } + } ?: Completable.error(IllegalStateException("Connection is not established")) /** * Clear GATT attribute cache using an undocumented method `BluetoothGatt.refresh()`. @@ -176,21 +180,22 @@ internal class DeviceConnector( * Known to work up to Android Q beta 2. */ private fun clearGattCache(connection: RxBleConnection): Completable { - val operation = RxBleCustomOperation { bluetoothGatt, _, _ -> - try { - val refreshMethod = bluetoothGatt.javaClass.getMethod("refresh") - val success = refreshMethod.invoke(bluetoothGatt) as Boolean - if (success) { - Observable.empty() - .delay(DeviceConnector.Companion.delayMsAfterClearingCache, TimeUnit.MILLISECONDS) - } else { - val reason = "BluetoothGatt.refresh() returned false" - Observable.error(RuntimeException(reason)) + val operation = + RxBleCustomOperation { bluetoothGatt, _, _ -> + try { + val refreshMethod = bluetoothGatt.javaClass.getMethod("refresh") + val success = refreshMethod.invoke(bluetoothGatt) as Boolean + if (success) { + Observable.empty() + .delay(DeviceConnector.Companion.delayMsAfterClearingCache, TimeUnit.MILLISECONDS) + } else { + val reason = "BluetoothGatt.refresh() returned false" + Observable.error(RuntimeException(reason)) + } + } catch (e: ReflectiveOperationException) { + Observable.error(e) } - } catch (e: ReflectiveOperationException) { - Observable.error(e) } - } return connection.queue(operation).ignoreElements() } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClient.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClient.kt index 4d75ac97..9cfd3cd7 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClient.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClient.kt @@ -67,11 +67,12 @@ open class ReactiveBleClient(private val context: Context) : BleClient { scanMode: ScanMode, requireLocationServicesEnabled: Boolean, ): Observable { - val filters = services.map { service -> - ScanFilter.Builder() - .setServiceUuid(service) - .build() - }.toTypedArray() + val filters = + services.map { service -> + ScanFilter.Builder() + .setServiceUuid(service) + .build() + }.toTypedArray() return rxBleClient.scanBleDevices( ScanSettings.Builder() @@ -101,7 +102,10 @@ open class ReactiveBleClient(private val context: Context) : BleClient { } } - override fun connectToDevice(deviceId: String, timeout: Duration) { + override fun connectToDevice( + deviceId: String, + timeout: Duration, + ) { allConnections.add( getConnection(deviceId, timeout) .subscribe({ result -> @@ -148,7 +152,11 @@ open class ReactiveBleClient(private val context: Context) : BleClient { when (connectionResult) { is EstablishedConnection -> if (rxBleClient.getBleDevice(connectionResult.deviceId).bluetoothDevice.bondState == BOND_BONDING) { - Single.error(Exception("Bonding is in progress wait for bonding to be finished before executing more operations on the device")) + Single.error( + Exception( + "Bonding is in progress wait for bonding to be finished before executing more operations on the device", + ), + ) } else { connectionResult.rxConnection.discoverServices() } @@ -239,11 +247,15 @@ open class ReactiveBleClient(private val context: Context) : BleClient { } } - override fun negotiateMtuSize(deviceId: String, size: Int): Single = + override fun negotiateMtuSize( + deviceId: String, + size: Int, + ): Single = getConnection(deviceId).flatMapSingle { connectionResult -> when (connectionResult) { - is EstablishedConnection -> connectionResult.rxConnection.requestMtu(size) - .map { value -> MtuNegotiateSuccesful(deviceId, value) } + is EstablishedConnection -> + connectionResult.rxConnection.requestMtu(size) + .map { value -> MtuNegotiateSuccesful(deviceId, value) } is EstablishConnectionFailure -> Single.just( @@ -255,13 +267,16 @@ open class ReactiveBleClient(private val context: Context) : BleClient { } }.first(MtuNegotiateFailed(deviceId, "negotiate mtu timed out")) - override fun observeBleStatus(): Observable = rxBleClient.observeStateChanges() - .startWith(rxBleClient.state) - .map { it.toBleState() } + override fun observeBleStatus(): Observable = + rxBleClient.observeStateChanges() + .startWith(rxBleClient.state) + .map { it.toBleState() } @VisibleForTesting - internal open fun createDeviceConnector(device: RxBleDevice, timeout: Duration) = - DeviceConnector(device, timeout, connectionUpdateBehaviorSubject::onNext, connectionQueue) + internal open fun createDeviceConnector( + device: RxBleDevice, + timeout: Duration, + ) = DeviceConnector(device, timeout, connectionUpdateBehaviorSubject::onNext, connectionQueue) private fun getConnection( deviceId: String, @@ -311,17 +326,20 @@ open class ReactiveBleClient(private val context: Context) : BleClient { when (deviceConnection) { is EstablishedConnection -> { if (rxBleClient.getBleDevice(deviceConnection.deviceId).bluetoothDevice.bondState == BOND_BONDING) { - Observable.error(Exception("Bonding is in progress wait for bonding to be finished before executing more operations on the device")) + Observable.error( + Exception("Bonding is in progress wait for bonding to be finished before executing more operations on the device"), + ) } else { deviceConnection.rxConnection.resolveCharacteristic( characteristicId, characteristicInstanceId, ).flatMapObservable { characteristic -> - val mode = if (characteristic.descriptors.isEmpty()) { - NotificationSetupMode.COMPAT - } else { - NotificationSetupMode.DEFAULT - } + val mode = + if (characteristic.descriptors.isEmpty()) { + NotificationSetupMode.COMPAT + } else { + NotificationSetupMode.DEFAULT + } if ((characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { deviceConnection.rxConnection.setupNotification( @@ -354,19 +372,21 @@ open class ReactiveBleClient(private val context: Context) : BleClient { .toSingle { RequestConnectionPrioritySuccess(deviceId) } - is EstablishConnectionFailure -> Single.fromCallable { - RequestConnectionPriorityFailed(deviceId, connectionResult.errorMessage) - } + is EstablishConnectionFailure -> + Single.fromCallable { + RequestConnectionPriorityFailed(deviceId, connectionResult.errorMessage) + } } }.first(RequestConnectionPriorityFailed(deviceId, "Unknown failure")) // enable this for extra debug output on the android stack - private fun enableDebugLogging() = RxBleClient - .updateLogOptions( - LogOptions.Builder().setLogLevel(LogConstants.VERBOSE) - .setMacAddressLogSetting(LogConstants.MAC_ADDRESS_FULL) - .setUuidsLogSetting(LogConstants.UUIDS_FULL) - .setShouldLogAttributeValues(true) - .build(), - ) + private fun enableDebugLogging() = + RxBleClient + .updateLogOptions( + LogOptions.Builder().setLogLevel(LogConstants.VERBOSE) + .setMacAddressLogSetting(LogConstants.MAC_ADDRESS_FULL) + .setUuidsLogSetting(LogConstants.UUIDS_FULL) + .setShouldLogAttributeValues(true) + .build(), + ) } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/extensions/RxBleConnectionExtension.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/extensions/RxBleConnectionExtension.kt index 931dd091..ac094f66 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/extensions/RxBleConnectionExtension.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/extensions/RxBleConnectionExtension.kt @@ -5,7 +5,10 @@ import com.polidea.rxandroidble2.RxBleConnection import io.reactivex.Single import java.util.UUID -fun RxBleConnection.resolveCharacteristic(uuid: UUID, instanceId: Int): Single = +fun RxBleConnection.resolveCharacteristic( + uuid: UUID, + instanceId: Int, +): Single = discoverServices().flatMap { services -> Single.just( services.bluetoothGattServices.flatMap { service -> @@ -16,12 +19,18 @@ fun RxBleConnection.resolveCharacteristic(uuid: UUID, instanceId: Int): Single { +fun RxBleConnection.writeCharWithResponse( + characteristic: BluetoothGattCharacteristic, + value: ByteArray, +): Single { characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT return writeCharacteristic(characteristic, value) } -fun RxBleConnection.writeCharWithoutResponse(characteristic: BluetoothGattCharacteristic, value: ByteArray): Single { +fun RxBleConnection.writeCharWithoutResponse( + characteristic: BluetoothGattCharacteristic, + value: ByteArray, +): Single { characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE return writeCharacteristic(characteristic, value) } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/BleStatusHandler.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/BleStatusHandler.kt index 88ef8c2c..035071eb 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/BleStatusHandler.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/BleStatusHandler.kt @@ -10,14 +10,16 @@ import java.util.concurrent.TimeUnit import com.signify.hue.flutterreactiveble.ProtobufModel as pb class BleStatusHandler(private val bleClient: BleClient) : EventChannel.StreamHandler { - companion object { private const val delayListenBleStatus = 500L } private val subscriptionDisposable = SerialDisposable() - override fun onListen(arg: Any?, eventSink: EventChannel.EventSink?) { + override fun onListen( + arg: Any?, + eventSink: EventChannel.EventSink?, + ) { subscriptionDisposable.set(eventSink?.let(::listenToBleStatus)) } @@ -30,9 +32,10 @@ class BleStatusHandler(private val bleClient: BleClient) : EventChannel.StreamHa .switchMap { bleClient.observeBleStatus() } .observeOn(AndroidSchedulers.mainThread()) .subscribe({ bleStatus -> - val message = pb.BleStatusInfo.newBuilder() - .setStatus(bleStatus.code) - .build() + val message = + pb.BleStatusInfo.newBuilder() + .setStatus(bleStatus.code) + .build() eventSink.success(message.toByteArray()) }, { throwable -> eventSink.error("ObserveBleStatusFailure", throwable.message, null) diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/CharNotificationHandler.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/CharNotificationHandler.kt index 2ad9813c..a699eb58 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/CharNotificationHandler.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/CharNotificationHandler.kt @@ -19,7 +19,10 @@ class CharNotificationHandler(private val bleClient: com.signify.hue.flutterreac private val subscriptionMap = mutableMapOf() } - override fun onListen(objectSink: Any?, eventSink: EventChannel.EventSink?) { + override fun onListen( + objectSink: Any?, + eventSink: EventChannel.EventSink?, + ) { eventSink?.let { charNotificationSink = eventSink } @@ -30,26 +33,28 @@ class CharNotificationHandler(private val bleClient: com.signify.hue.flutterreac } fun subscribeToNotifications(request: pb.NotifyCharacteristicRequest) { - val charUuid = uuidConverter - .uuidFromByteArray(request.characteristic.characteristicUuid.data.toByteArray()) - val subscription = bleClient.setupNotification( - request.characteristic.deviceId, - charUuid, - request.characteristic.characteristicInstanceId.toInt(), - ) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ value -> - handleNotificationValue(request.characteristic, value) - }, { - when (it) { - is BleDisconnectedException -> { - subscriptionMap.remove(request.characteristic)?.dispose() - } - else -> { - handleNotificationError(request.characteristic, it) + val charUuid = + uuidConverter + .uuidFromByteArray(request.characteristic.characteristicUuid.data.toByteArray()) + val subscription = + bleClient.setupNotification( + request.characteristic.deviceId, + charUuid, + request.characteristic.characteristicInstanceId.toInt(), + ) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ value -> + handleNotificationValue(request.characteristic, value) + }, { + when (it) { + is BleDisconnectedException -> { + subscriptionMap.remove(request.characteristic)?.dispose() + } + else -> { + handleNotificationError(request.characteristic, it) + } } - } - }) + }) subscriptionMap[request.characteristic] = subscription } @@ -61,7 +66,10 @@ class CharNotificationHandler(private val bleClient: com.signify.hue.flutterreac handleNotificationValue(charInfo.characteristic, charInfo.value.toByteArray()) } - fun addSingleErrorToStream(subscriptionRequest: pb.CharacteristicAddress, error: String) { + fun addSingleErrorToStream( + subscriptionRequest: pb.CharacteristicAddress, + error: String, + ) { val convertedMsg = protobufConverter.convertCharacteristicError(subscriptionRequest, error) charNotificationSink?.success(convertedMsg.toByteArray()) } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/DeviceConnectionHandler.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/DeviceConnectionHandler.kt index 7c16fe04..0ad6a25b 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/DeviceConnectionHandler.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/DeviceConnectionHandler.kt @@ -14,7 +14,10 @@ class DeviceConnectionHandler(private val bleClient: com.signify.hue.flutterreac private lateinit var connectionUpdatesDisposable: Disposable - override fun onListen(objectSink: Any?, eventSink: EventChannel.EventSink?) { + override fun onListen( + objectSink: Any?, + eventSink: EventChannel.EventSink?, + ) { eventSink?.let { connectDeviceSink = eventSink connectionUpdatesDisposable = listenToConnectionChanges() @@ -42,20 +45,21 @@ class DeviceConnectionHandler(private val bleClient: com.signify.hue.flutterreac bleClient.disconnectAllDevices() } - private fun listenToConnectionChanges() = bleClient.connectionUpdateSubject - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { update -> - when (update) { - is com.signify.hue.flutterreactiveble.ble.ConnectionUpdateSuccess -> { - handleDeviceConnectionUpdateResult(converter.convertToDeviceInfo(update)) - } - is com.signify.hue.flutterreactiveble.ble.ConnectionUpdateError -> { - handleDeviceConnectionUpdateResult( - converter.convertConnectionErrorToDeviceInfo(update.deviceId, update.errorMessage), - ) + private fun listenToConnectionChanges() = + bleClient.connectionUpdateSubject + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { update -> + when (update) { + is com.signify.hue.flutterreactiveble.ble.ConnectionUpdateSuccess -> { + handleDeviceConnectionUpdateResult(converter.convertToDeviceInfo(update)) + } + is com.signify.hue.flutterreactiveble.ble.ConnectionUpdateError -> { + handleDeviceConnectionUpdateResult( + converter.convertConnectionErrorToDeviceInfo(update.deviceId, update.errorMessage), + ) + } } } - } private fun handleDeviceConnectionUpdateResult(connectionUpdateMessage: pb.DeviceInfo) { connectDeviceSink?.success(connectionUpdateMessage.toByteArray()) diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ScanDevicesHandler.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ScanDevicesHandler.kt index 2063237a..270ab0e8 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ScanDevicesHandler.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ScanDevicesHandler.kt @@ -11,7 +11,6 @@ import io.reactivex.disposables.Disposable import com.signify.hue.flutterreactiveble.ProtobufModel as pb class ScanDevicesHandler(private val bleClient: com.signify.hue.flutterreactiveble.ble.BleClient) : EventChannel.StreamHandler { - private var scanDevicesSink: EventChannel.EventSink? = null private lateinit var scanForDevicesDisposable: Disposable private val converter = ProtobufMessageConverter() @@ -20,7 +19,10 @@ class ScanDevicesHandler(private val bleClient: com.signify.hue.flutterreactiveb private var scanParameters: ScanParameters? = null } - override fun onListen(objectSink: Any?, eventSink: EventChannel.EventSink?) { + override fun onListen( + objectSink: Any?, + eventSink: EventChannel.EventSink?, + ) { eventSink?.let { scanDevicesSink = eventSink startDeviceScan() @@ -34,16 +36,17 @@ class ScanDevicesHandler(private val bleClient: com.signify.hue.flutterreactiveb private fun startDeviceScan() { scanParameters?.let { params -> - scanForDevicesDisposable = bleClient.scanForDevices(params.filter, params.mode, params.locationServiceIsMandatory) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - { scanResult -> - handleDeviceScanResult(converter.convertScanInfo(scanResult)) - }, - { throwable -> - handleDeviceScanResult(converter.convertScanErrorInfo(throwable.message)) - }, - ) + scanForDevicesDisposable = + bleClient.scanForDevices(params.filter, params.mode, params.locationServiceIsMandatory) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { scanResult -> + handleDeviceScanResult(converter.convertScanInfo(scanResult)) + }, + { throwable -> + handleDeviceScanResult(converter.convertScanErrorInfo(throwable.message)) + }, + ) } ?: handleDeviceScanResult(converter.convertScanErrorInfo("Scanning parameters are not set")) } @@ -61,8 +64,9 @@ class ScanDevicesHandler(private val bleClient: com.signify.hue.flutterreactiveb fun prepareScan(scanMessage: pb.ScanForDevicesRequest) { stopDeviceScan() - val filter = scanMessage.serviceUuidsList - .map { ParcelUuid(UuidConverter().uuidFromByteArray(it.data.toByteArray())) } + val filter = + scanMessage.serviceUuidsList + .map { ParcelUuid(UuidConverter().uuidFromByteArray(it.data.toByteArray())) } val scanMode = createScanMode(scanMessage.scanMode) scanParameters = ScanParameters(filter, scanMode, scanMessage.requireLocationServicesEnabled) } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverter.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverter.kt index 8a10c488..33ec79c0 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverter.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverter.kt @@ -23,7 +23,6 @@ import com.signify.hue.flutterreactiveble.ProtobufModel as pb @Suppress("TooManyFunctions") class ProtobufMessageConverter { - companion object { private const val positionMostSignificantBit = 2 private const val positionLeastSignificantBit = 3 @@ -78,7 +77,10 @@ class ProtobufMessageConverter { .build() } - fun convertClearGattCacheError(code: ClearGattCacheErrorType, message: String?): pb.ClearGattCacheInfo { + fun convertClearGattCacheError( + code: ClearGattCacheErrorType, + message: String?, + ): pb.ClearGattCacheInfo { val failure = pb.GenericFailure.newBuilder().setCode(code.code) message?.let(failure::setMessage) return pb.ClearGattCacheInfo.newBuilder().setFailure(failure).build() @@ -101,9 +103,10 @@ class ProtobufMessageConverter { error: String?, ): pb.CharacteristicValueInfo { val characteristicAddress = createCharacteristicAddress(request) - val failure = pb.GenericFailure.newBuilder() - .setCode(CharacteristicErrorType.UNKNOWN.code) - .setMessage(error ?: "Unknown error") + val failure = + pb.GenericFailure.newBuilder() + .setCode(CharacteristicErrorType.UNKNOWN.code) + .setMessage(error ?: "Unknown error") return pb.CharacteristicValueInfo.newBuilder() .setCharacteristic(characteristicAddress) @@ -115,13 +118,15 @@ class ProtobufMessageConverter { request: pb.WriteCharacteristicRequest, error: String?, ): pb.WriteCharacteristicInfo { - val builder = pb.WriteCharacteristicInfo.newBuilder() - .setCharacteristic(request.characteristic) + val builder = + pb.WriteCharacteristicInfo.newBuilder() + .setCharacteristic(request.characteristic) error?.let { - val failure = pb.GenericFailure.newBuilder() - .setCode(CharacteristicErrorType.UNKNOWN.code) - .setMessage(error) + val failure = + pb.GenericFailure.newBuilder() + .setCode(CharacteristicErrorType.UNKNOWN.code) + .setMessage(error) builder.setFailure(failure) } @@ -131,15 +136,17 @@ class ProtobufMessageConverter { fun convertNegotiateMtuInfo(result: MtuNegotiateResult): pb.NegotiateMtuInfo = when (result) { - is MtuNegotiateSuccesful -> pb.NegotiateMtuInfo.newBuilder() - .setDeviceId(result.deviceId) - .setMtuSize(result.size) - .build() - is MtuNegotiateFailed -> { - val failure = pb.GenericFailure.newBuilder() - .setCode(NegotiateMtuErrorType.UNKNOWN.code) - .setMessage(result.errorMessage) + is MtuNegotiateSuccesful -> + pb.NegotiateMtuInfo.newBuilder() + .setDeviceId(result.deviceId) + .setMtuSize(result.size) .build() + is MtuNegotiateFailed -> { + val failure = + pb.GenericFailure.newBuilder() + .setCode(NegotiateMtuErrorType.UNKNOWN.code) + .setMessage(result.errorMessage) + .build() pb.NegotiateMtuInfo.newBuilder() .setDeviceId(result.deviceId) @@ -148,18 +155,18 @@ class ProtobufMessageConverter { } } - fun convertRequestConnectionPriorityInfo( - result: RequestConnectionPriorityResult, - ): pb.ChangeConnectionPriorityInfo { + fun convertRequestConnectionPriorityInfo(result: RequestConnectionPriorityResult): pb.ChangeConnectionPriorityInfo { return when (result) { - is RequestConnectionPrioritySuccess -> pb.ChangeConnectionPriorityInfo.newBuilder() - .setDeviceId(result.deviceId) - .build() - is RequestConnectionPriorityFailed -> { - val failure = pb.GenericFailure.newBuilder() - .setCode(0) - .setMessage(result.errorMessage) + is RequestConnectionPrioritySuccess -> + pb.ChangeConnectionPriorityInfo.newBuilder() + .setDeviceId(result.deviceId) .build() + is RequestConnectionPriorityFailed -> { + val failure = + pb.GenericFailure.newBuilder() + .setCode(0) + .setMessage(result.errorMessage) + .build() pb.ChangeConnectionPriorityInfo.newBuilder() .setDeviceId(result.deviceId) @@ -210,13 +217,15 @@ class ProtobufMessageConverter { } private fun convertInternalService(gattService: BluetoothGattService): pb.DiscoveredService { - val root = pb.DiscoveredService.newBuilder() - .setServiceUuid(createUuidFromParcelUuid(gattService.uuid)) - .addAllCharacteristicUuids(gattService.characteristics.map { createUuidFromParcelUuid(it.uuid) }) - - val children = gattService.includedServices.map { - convertInternalService(it) - } + val root = + pb.DiscoveredService.newBuilder() + .setServiceUuid(createUuidFromParcelUuid(gattService.uuid)) + .addAllCharacteristicUuids(gattService.characteristics.map { createUuidFromParcelUuid(it.uuid) }) + + val children = + gattService.includedServices.map { + convertInternalService(it) + } return root.addAllIncludedServices(children).build() } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverter.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverter.kt index 664e4212..f38e273d 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverter.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverter.kt @@ -21,20 +21,22 @@ class UuidConverter { @Suppress("Detekt.MagicNumber") private fun convert16BitToUuid(bytes: ByteArray): UUID { // UUID construction is retrieved from BLE corespec v5.0 page 1917 - val uuidConstruct = byteArrayOf( - 0x00, 0x00, bytes[0], bytes[1], 0x00, 0x00, 0x10, 0x00, - 0x80.toByte(), 0x00, 0x00, 0x80.toByte(), 0x5F, 0x9B.toByte(), 0x34, 0xFB.toByte(), - ) + val uuidConstruct = + byteArrayOf( + 0x00, 0x00, bytes[0], bytes[1], 0x00, 0x00, 0x10, 0x00, + 0x80.toByte(), 0x00, 0x00, 0x80.toByte(), 0x5F, 0x9B.toByte(), 0x34, 0xFB.toByte(), + ) return convert128BitNotationToUuid(uuidConstruct) } @Suppress("Detekt.MagicNumber") private fun convert32BitToUuid(bytes: ByteArray): UUID { - val uuidConstruct = byteArrayOf( - bytes[0], bytes[1], bytes[2], bytes[3], 0x00, 0x00, 0x10, 0x00, - 0x80.toByte(), 0x00, 0x00, 0x80.toByte(), 0x5F, 0x9B.toByte(), 0x34, 0xFB.toByte(), - ) + val uuidConstruct = + byteArrayOf( + bytes[0], bytes[1], bytes[2], bytes[3], 0x00, 0x00, 0x10, 0x00, + 0x80.toByte(), 0x00, 0x00, 0x80.toByte(), 0x5F, 0x9B.toByte(), 0x34, 0xFB.toByte(), + ) return convert128BitNotationToUuid(uuidConstruct) } diff --git a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/PerformanceAnalyzer.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/PerformanceAnalyzer.kt index 14bf87ae..8c105593 100644 --- a/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/PerformanceAnalyzer.kt +++ b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/PerformanceAnalyzer.kt @@ -1,7 +1,6 @@ package com.signify.hue.flutterreactiveble.debugutils object PerformanceAnalyzer { - var timer = Pair(0, 0) fun start(startTime: Long) { diff --git a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnectorTest.kt b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnectorTest.kt index 4eb5a748..31b0e83f 100644 --- a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnectorTest.kt +++ b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnectorTest.kt @@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit @DisplayName("DeviceConnector unit tests") class DeviceConnectorTest { - @MockK private lateinit var connection: RxBleConnection @@ -63,7 +62,6 @@ class DeviceConnectorTest { @Nested @DisplayName("Successfull connection") inner class SuccesfullConnectionTest { - @BeforeEach fun setup() { every { device.establishConnection(any()) }.returns(Observable.just(connection)) diff --git a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClientTest.kt b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClientTest.kt index b4cec8a7..1019d6d6 100644 --- a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClientTest.kt +++ b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClientTest.kt @@ -34,19 +34,22 @@ import org.junit.jupiter.api.Test import java.util.UUID import java.util.concurrent.TimeUnit -private class BleClientForTesting(val bleClient: RxBleClient, appContext: Context, val deviceConnector: DeviceConnector) : ReactiveBleClient(appContext) { - +private class BleClientForTesting(val bleClient: RxBleClient, appContext: Context, val deviceConnector: DeviceConnector) : ReactiveBleClient( + appContext, +) { override fun initializeClient() { rxBleClient = bleClient activeConnections = mutableMapOf() } - override fun createDeviceConnector(device: RxBleDevice, timeout: Duration): DeviceConnector = deviceConnector + override fun createDeviceConnector( + device: RxBleDevice, + timeout: Duration, + ): DeviceConnector = deviceConnector } @DisplayName("BleClient unit tests") class ReactiveBleClientTest { - @MockK private lateinit var context: Context @@ -109,7 +112,6 @@ class ReactiveBleClientTest { @DisplayName("Establishing a connection") @Nested inner class EstablishConnectionTest { - @Test fun `should use deviceconnector when connecting to a device`() { sut.connectToDevice("test", testTimeout) @@ -123,7 +125,12 @@ class ReactiveBleClientTest { inner class BleOperationsTest { @Test fun `should call readcharacteristic in case the connection is established`() { - every { rxConnection.resolveCharacteristic(any(), any()) }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) + every { + rxConnection.resolveCharacteristic( + any(), + any(), + ) + }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) sut.readCharacteristic("test", UUID.randomUUID(), 11).test() @@ -153,10 +160,20 @@ class ReactiveBleClientTest { val byteMin = Byte.MIN_VALUE val byteMax = Byte.MAX_VALUE - every { rxConnection.readCharacteristic(any()) }.returns(Single.just(byteArrayOf(byteMin, byteMax))) - every { rxConnection.resolveCharacteristic(any(), any()) }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) - val observable = sut.readCharacteristic("test", UUID.randomUUID(), 11) - .map { result -> result as CharOperationSuccessful }.test() + every { + rxConnection.readCharacteristic( + any(), + ) + }.returns(Single.just(byteArrayOf(byteMin, byteMax))) + every { + rxConnection.resolveCharacteristic( + any(), + any(), + ) + }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) + val observable = + sut.readCharacteristic("test", UUID.randomUUID(), 11) + .map { result -> result as CharOperationSuccessful }.test() assertThat(observable.values().first().value).isEqualTo(listOf(byteMin, byteMax)) } @@ -167,7 +184,12 @@ class ReactiveBleClientTest { val byteMax = Byte.MAX_VALUE val bytes = byteArrayOf(byteMin, byteMax) - every { rxConnection.resolveCharacteristic(any(), any()) }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) + every { + rxConnection.resolveCharacteristic( + any(), + any(), + ) + }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) sut.writeCharacteristicWithResponse("test", UUID.randomUUID(), 11, bytes).test() verify(exactly = 1) { rxConnection.writeCharWithResponse(any(), any()) } @@ -202,7 +224,12 @@ class ReactiveBleClientTest { val byteMax = Byte.MAX_VALUE val bytes = byteArrayOf(byteMin, byteMax) - every { rxConnection.resolveCharacteristic(any(), any()) }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) + every { + rxConnection.resolveCharacteristic( + any(), + any(), + ) + }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) sut.writeCharacteristicWithoutResponse("test", UUID.randomUUID(), 11, bytes).test() verify(exactly = 1) { rxConnection.writeCharWithoutResponse(any(), any()) } @@ -240,9 +267,15 @@ class ReactiveBleClientTest { val bytes = byteArrayOf(byteMin, byteMax) every { rxConnection.writeCharWithResponse(any(), any()) }.returns(Single.just(byteArrayOf(byteMin, byteMax))) - every { rxConnection.resolveCharacteristic(any(), any()) }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) - val observable = sut.writeCharacteristicWithResponse("test", UUID.randomUUID(), 11, bytes) - .map { result -> result as CharOperationSuccessful }.test() + every { + rxConnection.resolveCharacteristic( + any(), + any(), + ) + }.returns(Single.just(BluetoothGattCharacteristic(UUID.randomUUID(), 0, 0))) + val observable = + sut.writeCharacteristicWithResponse("test", UUID.randomUUID(), 11, bytes) + .map { result -> result as CharOperationSuccessful }.test() assertThat(observable.values().first().value).isEqualTo(bytes.toList()) } @@ -251,7 +284,6 @@ class ReactiveBleClientTest { @Nested @DisplayName("Negotiate mtu") inner class NegotiateMtuTest { - @Test fun `should return mtunegotiatesuccesful in case it succeeds`() { val mtuSize = 19 @@ -304,7 +336,6 @@ class ReactiveBleClientTest { @Nested @DisplayName("Change priority") inner class ChangePriorityTest { - @Test fun `returns prioritysuccess when completed`() { val completer = Completable.fromCallable { true } @@ -325,7 +356,6 @@ class ReactiveBleClientTest { @Nested @DisplayName("Discover services") inner class DiscoverServicesTest { - @BeforeEach fun setup() { every { bleDevice.bluetoothDevice }.returns(bluetoothDevice) diff --git a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ConnectionQueueTest.kt b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ConnectionQueueTest.kt index 291f1072..f0c8fe75 100644 --- a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ConnectionQueueTest.kt +++ b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ConnectionQueueTest.kt @@ -5,7 +5,6 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test class ConnectionQueueTest { - private lateinit var sut: com.signify.hue.flutterreactiveble.ble.ConnectionQueue @BeforeEach diff --git a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverterTest.kt b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverterTest.kt index 09a2ce40..236535b0 100644 --- a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverterTest.kt +++ b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverterTest.kt @@ -20,7 +20,6 @@ class ProtobufMessageConverterTest { @Nested @DisplayName("Convert to scaninfo") inner class ScanInfoTest { - @Test fun `converts scan result to DeviceDiscoveryMessage`() { val scanInfo = createScanInfo() @@ -107,7 +106,6 @@ class ProtobufMessageConverterTest { @Nested @DisplayName("Convert to deviceinfo") inner class DeviceInfoTest { - @Test fun `converts device id as parameter in device connection message`() { val deviceId = "2" @@ -126,7 +124,6 @@ class ProtobufMessageConverterTest { @Nested @DisplayName("Convert to charinfo") inner class ConvertCharInfoTest { - @Test fun `converts to a characteristicvalueInfo object `() { val request = createCharacteristicRequest("a", UUID.randomUUID()) @@ -148,7 +145,6 @@ class ProtobufMessageConverterTest { @Nested @DisplayName("Convert to negotiatemtuinfo") inner class NegotiateMtuInfoTest { - @Test fun `converts to negotiatemtuinfo object`() { val result = MtuNegotiateSuccesful("", 3) @@ -214,15 +210,20 @@ class ProtobufMessageConverterTest { ) } - private fun createCharacteristicRequest(deviceId: String, serviceUuid: UUID): pb.ReadCharacteristicRequest { + private fun createCharacteristicRequest( + deviceId: String, + serviceUuid: UUID, + ): pb.ReadCharacteristicRequest { val uuidConverter = UuidConverter() - val uuid = pb.Uuid.newBuilder() - .setData(ByteString.copyFrom(uuidConverter.byteArrayFromUuid(serviceUuid))) - - val characteristicAddress = pb.CharacteristicAddress.newBuilder() - .setDeviceId(deviceId) - .setServiceUuid(uuid) - .setCharacteristicUuid(uuid) + val uuid = + pb.Uuid.newBuilder() + .setData(ByteString.copyFrom(uuidConverter.byteArrayFromUuid(serviceUuid))) + + val characteristicAddress = + pb.CharacteristicAddress.newBuilder() + .setDeviceId(deviceId) + .setServiceUuid(uuid) + .setCharacteristicUuid(uuid) return pb.ReadCharacteristicRequest.newBuilder() .setCharacteristic(characteristicAddress) diff --git a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ServicesWithCharacteristicsConverterTest.kt b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ServicesWithCharacteristicsConverterTest.kt index 042ba0ee..34ee6f59 100644 --- a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ServicesWithCharacteristicsConverterTest.kt +++ b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ServicesWithCharacteristicsConverterTest.kt @@ -13,7 +13,6 @@ import java.util.UUID import com.signify.hue.flutterreactiveble.ProtobufModel as pb class ServicesWithCharacteristicsConverterTest { - private val serviceUuid = UUID.randomUUID() private val characteristicUuid = UUID.randomUUID() private val internalCharacteristicUuid = UUID.randomUUID() @@ -59,10 +58,11 @@ class ServicesWithCharacteristicsConverterTest { every { internalServiceLevel2.includedServices }.returns(listOf()) every { internalServiceLevel2.characteristics }.returns(listOf(internalCharacteristicLevel2)) - conversionResult = sut.convertDiscoverServicesInfo( - "test", - RxBleDeviceServices(listOf(service)), - ) + conversionResult = + sut.convertDiscoverServicesInfo( + "test", + RxBleDeviceServices(listOf(service)), + ) } @Test diff --git a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverterTest.kt b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverterTest.kt index 5b3a40e0..8d5c20a4 100644 --- a/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverterTest.kt +++ b/packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverterTest.kt @@ -5,7 +5,6 @@ import org.junit.jupiter.api.Test import java.util.* class UuidConverterTest { - val converter = UuidConverter() @Test