From e9b16c4ec4f3499b279794c080965c12f480f12e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mon?= Date: Tue, 17 Aug 2021 06:47:18 +0200 Subject: [PATCH] migrate to Federated plugin structure (#338) * move current code one folder deeper in order to prepare the federated plugin structure * create platform interface package * move model and plugincontroller to platform interface * remove moved code from main library * create platform interface and integrate it in the reactive ble package * remove debuglogging * move protobuf related stuff out of the interface package * change codemagic pipeline to support federated plugin structure * make platform interface ready for publishing * add docs for platform interface * restructure project to best practice * rename package flutter_reactive_ble_platform_interface to reactive_ble_platform_interface * move mobile specific code into new reactive ble mobile package * setup CI and melos * update docs and prepare release * fix dependencies after publishing --- README.md | 11 + analysis_options.yaml | 4 +- bin/quality_checks.sh | 10 + codemagic.yaml | 38 +- example/ios/Podfile.lock | 20 +- example/ios/Runner.xcodeproj/project.pbxproj | 4 +- example/lib/main.dart | 8 +- .../lib/src/ble/ble_device_interactor.dart | 3 + .../device_detail/device_detail_screen.dart | 2 +- .../src/ui/device_detail/device_log_tab.dart | 2 + example/lib/src/ui/device_list.dart | 2 + example/lib/src/utils.dart | 1 + example/lib/src/widgets.dart | 7 +- example/pubspec.lock | 63 ++- example/pubspec.yaml | 3 +- lib/flutter_reactive_ble.dart | 17 - lib/src/plugin_controller.dart | 391 -------------- melos.yaml | 9 + .../flutter_reactive_ble/CHANGELOG.md | 9 +- packages/flutter_reactive_ble/LICENSE | 24 + packages/flutter_reactive_ble/README.md | 232 ++++++++ .../lib/flutter_reactive_ble.dart | 7 + .../lib}/src/connected_device_operation.dart | 28 +- .../lib}/src/debug_logger.dart | 2 +- .../lib}/src/device_connector.dart | 20 +- .../lib}/src/device_scanner.dart | 24 +- .../lib}/src/discovered_devices_registry.dart | 0 .../lib}/src/reactive_ble.dart | 43 +- .../lib}/src/rx_ext/repeater.dart | 3 +- .../lib}/src/rx_ext/serial_disposable.dart | 2 +- packages/flutter_reactive_ble/pubspec.lock | 504 ++++++++++++++++++ .../flutter_reactive_ble/pubspec.yaml | 32 +- .../connected_device_operation_test.dart | 58 +- ...connected_device_operation_test.mocks.dart | 159 ++++++ .../test}/device_connector_test.dart | 26 +- .../test/device_connector_test.mocks.dart | 224 ++++++++ .../test}/device_scanner_test.dart | 38 +- .../test/device_scanner_test.mocks.dart | 159 ++++++ .../test}/reactive_ble_test.dart | 22 +- .../test/reactive_ble_test.mocks.dart | 326 +++++++++++ .../test}/rx_ext/serial_disposable_test.dart | 1 - .../reactive_ble_mobile}/.metadata | 6 +- packages/reactive_ble_mobile/CHANGELOG.md | 4 + packages/reactive_ble_mobile/LICENSE | 24 + packages/reactive_ble_mobile/README.md | 3 + .../reactive_ble_mobile/android}/build.gradle | 2 +- .../android}/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../android}/proguard-rules.txt | 0 .../android}/settings.gradle | 0 .../android}/src/main/AndroidManifest.xml | 0 .../flutterreactiveble/PluginController.kt | 0 .../flutterreactiveble/ReactiveBlePlugin.kt | 0 .../hue/flutterreactiveble/ble/BleClient.kt | 0 .../hue/flutterreactiveble/ble/BleWrapper.kt | 0 .../flutterreactiveble/ble/ConnectionQueue.kt | 0 .../flutterreactiveble/ble/DeviceConnector.kt | 0 .../ble/ReactiveBleClient.kt | 0 .../extensions/RxBleConnectionExtension.kt | 0 .../channelhandlers/BleStatusHandler.kt | 0 .../CharNotificationHandler.kt | 0 .../DeviceConnectionHandler.kt | 0 .../channelhandlers/ScanDevicesHandler.kt | 0 .../converters/ManufacturerDataConverter.kt | 0 .../converters/ProtobufMessageConverter.kt | 0 .../converters/UuidConverter.kt | 0 .../debugutils/HexStringConversion.kt | 0 .../debugutils/PerformanceAnalyzer.kt | 0 .../model/ConnectionState.kt | 0 .../hue/flutterreactiveble/model/ErrorType.kt | 0 .../hue/flutterreactiveble/model/ScanMode.kt | 0 .../utils/BleWrapperExtensions.kt | 0 .../hue/flutterreactiveble/utils/Discard.kt | 0 .../hue/flutterreactiveble/utils/Duration.kt | 0 .../ble/DeviceConnectorTest.kt | 0 .../ble/ReactiveBleClientTest.kt | 0 .../channelhandlers/ConnectionQueueTest.kt | 0 .../ProtobufMessageConverterTest.kt | 0 ...ervicesWithCharacteristicsConverterTest.kt | 0 .../converters/UuidConverterTest.kt | 0 .../reactive_ble_mobile/ios}/.gitignore | 0 .../reactive_ble_mobile/ios}/Assets/.gitkeep | 0 .../Classes/BleData extras/BLEStatus.swift | 0 .../BleData extras/ConnectionState.swift | 0 .../Classes/BleData extras/FailureCodes.swift | 0 .../QualifiedCharacteristic.swift | 0 .../ios}/Classes/BleData/bledata.pb.swift | 0 .../Classes/Plugin/Common/EventSink.swift | 0 .../ios}/Classes/Plugin/Common/Failable.swift | 0 .../Classes/Plugin/Common/MethodHandler.swift | 0 .../Plugin/Common/PlatformMethod.swift | 0 .../Classes/Plugin/Common/StreamHandler.swift | 0 .../Classes/Plugin/PluginController.swift | 0 .../ios}/Classes/Plugin/PluginError.swift | 0 .../ios}/Classes/Plugin/StreamingTask.swift | 0 .../Plugin/SwiftReactiveBlePlugin.swift | 0 .../ios}/Classes/Prelude/base.swift | 0 .../ios}/Classes/Prelude/papply.swift | 0 .../ios}/Classes/ReactiveBle/Central.swift | 0 .../ReactiveBle/CentralManagerDelegate.swift | 0 .../ios}/Classes/ReactiveBle/OnOff.swift | 0 .../ReactiveBle/PeripheralDelegate.swift | 0 .../CharacteristicNotifyTaskController.swift | 0 .../CharacteristicNotifyTaskSpec.swift | 0 .../CharacteristicWriteTaskController.swift | 0 .../CharacteristicWriteTaskSpec.swift | 0 .../Tasks/Connect/ConnectTaskController.swift | 0 .../Tasks/Connect/ConnectTaskSpec.swift | 0 .../PeripheralTask.swift | 0 .../PeripheralTaskController.swift | 0 .../PeripheralTaskRegistry.swift | 0 ...aracteristicsDiscoveryTaskController.swift | 0 ...WithCharacteristicsDiscoveryTaskSpec.swift | 0 ...ervicesWithCharacteristicsToDiscover.swift | 0 .../ios}/Classes/ReactiveBlePlugin.h | 0 .../ios}/Classes/ReactiveBlePlugin.m | 2 +- .../ios/reactive_ble_mobile.podspec | 2 +- .../lib/reactive_ble_mobile.dart | 3 + .../converter/args_to_protubuf_converter.dart | 6 +- .../src/converter/protobuf_converter.dart | 20 +- .../lib}/src/generated/bledata.pb.dart | 0 .../lib/src/reactive_ble_mobile_platform.dart | 259 +++++++++ .../lib}/src/select_from.dart | 0 .../reactive_ble_mobile/protos}/README.md | 0 .../reactive_ble_mobile/protos}/bledata.proto | 2 +- packages/reactive_ble_mobile/pubspec.lock | 476 +++++++++++++++++ packages/reactive_ble_mobile/pubspec.yaml | 29 + .../args_to_protobuf_converter_test.dart | 12 +- .../converter/protobuf_converter_test.dart | 28 +- .../test/reactive_ble_platform_test.dart | 94 ++-- .../reactive_ble_platform_test.mocks.dart | 302 +++++++++++ .../CHANGELOG.md | 5 + .../reactive_ble_platform_interface/LICENSE | 24 + .../reactive_ble_platform_interface/README.md | 7 + .../lib/reactive_ble_platform_interface.dart | 4 + .../lib}/src/model/ble_status.dart | 0 .../lib}/src/model/characteristic_value.dart | 6 +- .../src/model/clear_gatt_cache_error.dart | 0 .../lib}/src/model/connection_priority.dart | 5 +- .../src/model/connection_state_update.dart | 3 +- .../src/model/connection_state_update.g.dart | 0 .../lib}/src/model/discovered_device.dart | 9 +- .../lib}/src/model/discovered_device.g.dart | 0 .../lib}/src/model/discovered_service.dart | 3 +- .../lib}/src/model/discovered_service.g.dart | 0 .../lib}/src/model/generic_failure.dart | 0 .../lib}/src/model/log_level.dart | 0 .../src/model/qualified_characteristic.dart | 3 +- .../lib}/src/model/result.dart | 0 .../lib}/src/model/scan_mode.dart | 0 .../lib}/src/model/scan_session.dart | 2 +- .../lib}/src/model/unit.dart | 0 .../lib}/src/model/uuid.dart | 0 .../src/model/write_characteristic_info.dart | 9 +- .../lib/src/models.dart | 16 + .../src/reactive_ble_platform_interface.dart | 184 +++++++ .../lib/src/select_from.dart | 7 + .../pubspec.lock | 72 ++- .../pubspec.yaml | 27 + .../test}/select_from_test.dart | 2 +- ...connected_device_operation_test.mocks.dart | 100 ---- test/debug_logger_test.dart | 47 -- test/device_connector_test.mocks.dart | 112 ---- test/device_scanner_test.mocks.dart | 46 -- test/discovered_devices_registry_test.dart | 60 --- test/plugin_controller_test.mocks.dart | 332 ------------ test/reactive_ble_test.mocks.dart | 233 -------- test/result_test.dart | 47 -- test/rx_ext/repeater_test.dart | 123 ----- test/uuid_test.dart | 66 --- 170 files changed, 3432 insertions(+), 1934 deletions(-) create mode 100755 bin/quality_checks.sh delete mode 100644 lib/flutter_reactive_ble.dart delete mode 100644 lib/src/plugin_controller.dart create mode 100644 melos.yaml rename CHANGELOG.md => packages/flutter_reactive_ble/CHANGELOG.md (97%) create mode 100644 packages/flutter_reactive_ble/LICENSE create mode 100644 packages/flutter_reactive_ble/README.md create mode 100644 packages/flutter_reactive_ble/lib/flutter_reactive_ble.dart rename {lib => packages/flutter_reactive_ble/lib}/src/connected_device_operation.dart (86%) rename {lib => packages/flutter_reactive_ble/lib}/src/debug_logger.dart (86%) rename {lib => packages/flutter_reactive_ble/lib}/src/device_connector.dart (92%) rename {lib => packages/flutter_reactive_ble/lib}/src/device_scanner.dart (85%) rename {lib => packages/flutter_reactive_ble/lib}/src/discovered_devices_registry.dart (100%) rename {lib => packages/flutter_reactive_ble/lib}/src/reactive_ble.dart (90%) rename {lib => packages/flutter_reactive_ble/lib}/src/rx_ext/repeater.dart (96%) rename {lib => packages/flutter_reactive_ble/lib}/src/rx_ext/serial_disposable.dart (93%) create mode 100644 packages/flutter_reactive_ble/pubspec.lock rename pubspec.yaml => packages/flutter_reactive_ble/pubspec.yaml (58%) rename {test => packages/flutter_reactive_ble/test}/connected_device_operation_test.dart (85%) create mode 100644 packages/flutter_reactive_ble/test/connected_device_operation_test.mocks.dart rename {test => packages/flutter_reactive_ble/test}/device_connector_test.dart (92%) create mode 100644 packages/flutter_reactive_ble/test/device_connector_test.mocks.dart rename {test => packages/flutter_reactive_ble/test}/device_scanner_test.dart (84%) create mode 100644 packages/flutter_reactive_ble/test/device_scanner_test.mocks.dart rename {test => packages/flutter_reactive_ble/test}/reactive_ble_test.dart (94%) create mode 100644 packages/flutter_reactive_ble/test/reactive_ble_test.mocks.dart rename {test => packages/flutter_reactive_ble/test}/rx_ext/serial_disposable_test.dart (96%) rename {example => packages/reactive_ble_mobile}/.metadata (70%) create mode 100644 packages/reactive_ble_mobile/CHANGELOG.md create mode 100644 packages/reactive_ble_mobile/LICENSE create mode 100644 packages/reactive_ble_mobile/README.md rename {android => packages/reactive_ble_mobile/android}/build.gradle (98%) rename {android => packages/reactive_ble_mobile/android}/gradle.properties (100%) rename {android => packages/reactive_ble_mobile/android}/gradle/wrapper/gradle-wrapper.properties (100%) rename {android => packages/reactive_ble_mobile/android}/proguard-rules.txt (100%) rename {android => packages/reactive_ble_mobile/android}/settings.gradle (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/AndroidManifest.xml (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/PluginController.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/ReactiveBlePlugin.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleClient.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleWrapper.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ConnectionQueue.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnector.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClient.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/extensions/RxBleConnectionExtension.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/BleStatusHandler.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/CharNotificationHandler.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/DeviceConnectionHandler.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ScanDevicesHandler.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ManufacturerDataConverter.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverter.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverter.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/HexStringConversion.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/PerformanceAnalyzer.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ConnectionState.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ErrorType.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ScanMode.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/BleWrapperExtensions.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Discard.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Duration.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnectorTest.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClientTest.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/test/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ConnectionQueueTest.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverterTest.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ServicesWithCharacteristicsConverterTest.kt (100%) rename {android => packages/reactive_ble_mobile/android}/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverterTest.kt (100%) rename {ios => packages/reactive_ble_mobile/ios}/.gitignore (100%) rename {ios => packages/reactive_ble_mobile/ios}/Assets/.gitkeep (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/BleData extras/BLEStatus.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/BleData extras/ConnectionState.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/BleData extras/FailureCodes.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/BleData extras/QualifiedCharacteristic.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/BleData/bledata.pb.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/Common/EventSink.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/Common/Failable.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/Common/MethodHandler.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/Common/PlatformMethod.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/Common/StreamHandler.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/PluginController.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/PluginError.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/StreamingTask.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Plugin/SwiftReactiveBlePlugin.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Prelude/base.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/Prelude/papply.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Central.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/CentralManagerDelegate.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/OnOff.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/PeripheralDelegate.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskController.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskSpec.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskController.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskSpec.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/Connect/ConnectTaskController.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/Connect/ConnectTaskSpec.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTask.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskController.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskRegistry.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskController.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskSpec.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsToDiscover.swift (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBlePlugin.h (100%) rename {ios => packages/reactive_ble_mobile/ios}/Classes/ReactiveBlePlugin.m (77%) rename ios/flutter_reactive_ble.podspec => packages/reactive_ble_mobile/ios/reactive_ble_mobile.podspec (94%) create mode 100644 packages/reactive_ble_mobile/lib/reactive_ble_mobile.dart rename {lib => packages/reactive_ble_mobile/lib}/src/converter/args_to_protubuf_converter.dart (96%) rename {lib => packages/reactive_ble_mobile/lib}/src/converter/protobuf_converter.dart (86%) rename {lib => packages/reactive_ble_mobile/lib}/src/generated/bledata.pb.dart (100%) create mode 100644 packages/reactive_ble_mobile/lib/src/reactive_ble_mobile_platform.dart rename {lib => packages/reactive_ble_mobile/lib}/src/select_from.dart (100%) rename {protos => packages/reactive_ble_mobile/protos}/README.md (100%) rename {protos => packages/reactive_ble_mobile/protos}/bledata.proto (100%) create mode 100644 packages/reactive_ble_mobile/pubspec.lock create mode 100644 packages/reactive_ble_mobile/pubspec.yaml rename {test => packages/reactive_ble_mobile/test}/converter/args_to_protobuf_converter_test.dart (95%) rename {test => packages/reactive_ble_mobile/test}/converter/protobuf_converter_test.dart (93%) rename test/plugin_controller_test.dart => packages/reactive_ble_mobile/test/reactive_ble_platform_test.dart (85%) create mode 100644 packages/reactive_ble_mobile/test/reactive_ble_platform_test.mocks.dart create mode 100644 packages/reactive_ble_platform_interface/CHANGELOG.md create mode 100644 packages/reactive_ble_platform_interface/LICENSE create mode 100644 packages/reactive_ble_platform_interface/README.md create mode 100644 packages/reactive_ble_platform_interface/lib/reactive_ble_platform_interface.dart rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/ble_status.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/characteristic_value.dart (71%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/clear_gatt_cache_error.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/connection_priority.dart (88%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/connection_state_update.dart (93%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/connection_state_update.g.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/discovered_device.dart (92%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/discovered_device.g.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/discovered_service.dart (90%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/discovered_service.g.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/generic_failure.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/log_level.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/qualified_characteristic.dart (94%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/result.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/scan_mode.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/scan_session.dart (72%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/unit.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/uuid.dart (100%) rename {lib => packages/reactive_ble_platform_interface/lib}/src/model/write_characteristic_info.dart (74%) create mode 100644 packages/reactive_ble_platform_interface/lib/src/models.dart create mode 100644 packages/reactive_ble_platform_interface/lib/src/reactive_ble_platform_interface.dart create mode 100644 packages/reactive_ble_platform_interface/lib/src/select_from.dart rename pubspec.lock => packages/reactive_ble_platform_interface/pubspec.lock (92%) create mode 100644 packages/reactive_ble_platform_interface/pubspec.yaml rename {test => packages/reactive_ble_platform_interface/test}/select_from_test.dart (89%) delete mode 100644 test/connected_device_operation_test.mocks.dart delete mode 100644 test/debug_logger_test.dart delete mode 100644 test/device_connector_test.mocks.dart delete mode 100644 test/device_scanner_test.mocks.dart delete mode 100644 test/discovered_devices_registry_test.dart delete mode 100644 test/plugin_controller_test.mocks.dart delete mode 100644 test/reactive_ble_test.mocks.dart delete mode 100644 test/result_test.dart delete mode 100644 test/rx_ext/repeater_test.dart delete mode 100644 test/uuid_test.dart diff --git a/README.md b/README.md index efe5929b..ee1a0756 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,17 @@ The Android OS maintains a table per device of the discovered service in cache. await flutterReactiveBle.clearGattCache(foundDeviceId); ``` +### Contributing +Feel free to open an new issue or a pull request to make this project better + +#### Setup + +This project uses melos to manage all the packages inside this repo. + +Install melos: `dart pub global activate melos` +Setup melos to point to the dependencies in your local folder: `melos bootstrap` + + ### FAQ #### How to handle the BLE undeliverable exception diff --git a/analysis_options.yaml b/analysis_options.yaml index 7648feef..21c6ec7d 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,9 +3,11 @@ analyzer: implicit-casts: false implicit-dynamic: false exclude: + - "bin/cache/**" + - "**/*.freezed.dart" - "**/*.g.dart" - "**/*.mocks.dart" - - "**/generated/bledata.pb.dart" + - "**/generated/**" linter: rules: diff --git a/bin/quality_checks.sh b/bin/quality_checks.sh new file mode 100755 index 00000000..68fb2419 --- /dev/null +++ b/bin/quality_checks.sh @@ -0,0 +1,10 @@ +#!/bin/bash -ex +flutter pub global activate melos +#workaround for codemagic CI since melos is not in bash +echo 'export PATH="$PATH":"$FLUTTER_ROOT/.pub-cache/bin"' >>~/.bashrc +echo 'export PATH="$PATH":"$FLUTTER_ROOT/bin"' >>~/.bashrc +source ~/.bashrc + +melos bootstrap +melos run analyze +melos run unittest \ No newline at end of file diff --git a/codemagic.yaml b/codemagic.yaml index c0631c2b..de8d6f64 100644 --- a/codemagic.yaml +++ b/codemagic.yaml @@ -34,28 +34,24 @@ workflows: -keyalg 'RSA' \ -keysize 2048 \ -validity 10000 - - | - # set up local properties - echo "flutter.sdk=$HOME/programs/flutter" > "$FCI_BUILD_DIR/android/local.properties" - - name: Pub get - script: cd . && flutter pub get - - name: Flutter analyze - script: cd . && flutter analyze - - name: Flutter test - script: cd . && flutter test - - name: Dry run publish - script: cd . && flutter pub publish --dry-run - - | - #!/bin/bash -ex - cd example/android && ls && ./gradlew detekt && ./gradlew testDebugUnitTest + - name: setup local properties + script: | + # set up local properties + echo "flutter.sdk=$HOME/programs/flutter" > "$FCI_BUILD_DIR/example/android/local.properties" + - name: Quality checks monorepo + script: | + ./bin/quality_checks.sh + - name: Android native tests + script: | + #!/bin/bash -ex + cd example/android && ls && ./gradlew detekt && ./gradlew testDebugUnitTest - name: Build android app script: cd example && flutter build apk --debug - name: Build iOS app - script: find . -name "Podfile" -execdir pod install \; - - cd example && flutter build ios --debug --no-codesign + script: | + find . -name "Podfile" -execdir pod install \; + cd example && flutter build ios --debug --no-codesign artifacts: - - build/**/outputs/**/*.apk - - build/**/outputs/**/mapping.txt - - build/ios/ipa/*.ipa - - /tmp/xcodebuild_logs/*.log - - flutter_drive.log + - example/build/**/outputs/**/*.apk + - example/build/**/outputs/**/mapping.txt + - example/build/ios/ipa/*.ipa diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 5206cdec..f481a25f 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,15 +1,15 @@ PODS: - Flutter (1.0.0) - - flutter_reactive_ble (0.0.1): + - Protobuf (3.17.0) + - reactive_ble_mobile (0.0.1): - Flutter - Protobuf (~> 3.5) - SwiftProtobuf (~> 1.0) - - Protobuf (3.13.0) - - SwiftProtobuf (1.12.0) + - SwiftProtobuf (1.17.0) DEPENDENCIES: - Flutter (from `Flutter`) - - flutter_reactive_ble (from `.symlinks/plugins/flutter_reactive_ble/ios`) + - reactive_ble_mobile (from `.symlinks/plugins/reactive_ble_mobile/ios`) SPEC REPOS: trunk: @@ -19,15 +19,15 @@ SPEC REPOS: EXTERNAL SOURCES: Flutter: :path: Flutter - flutter_reactive_ble: - :path: ".symlinks/plugins/flutter_reactive_ble/ios" + reactive_ble_mobile: + :path: ".symlinks/plugins/reactive_ble_mobile/ios" SPEC CHECKSUMS: Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c - flutter_reactive_ble: ac0ccac596f481b221549cad2abe16987e1f411b - Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748 - SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699 + Protobuf: 7327d4444215b5f18e560a97f879ff5503c4581c + reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c + SwiftProtobuf: 9c85136c6ba74b0a1b84279dbf0f6db8efb714e0 PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c -COCOAPODS: 1.10.0 +COCOAPODS: 1.10.1 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index fdc839de..9c6f2694 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -264,13 +264,13 @@ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework", "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework", - "${BUILT_PRODUCTS_DIR}/flutter_reactive_ble/flutter_reactive_ble.framework", + "${BUILT_PRODUCTS_DIR}/reactive_ble_mobile/reactive_ble_mobile.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_reactive_ble.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/reactive_ble_mobile.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/example/lib/main.dart b/example/lib/main.dart index d1a34948..94682b1e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -63,18 +63,22 @@ void main() { title: 'Flutter Reactive BLE example', color: _themeColor, theme: ThemeData(primarySwatch: _themeColor), - home: HomeScreen(), + home: const HomeScreen(), ), ), ); } class HomeScreen extends StatelessWidget { + const HomeScreen({ + Key? key, + }) : super(key: key); + @override Widget build(BuildContext context) => Consumer( builder: (_, status, __) { if (status == BleStatus.ready) { - return DeviceListScreen(); + return const DeviceListScreen(); } else { return BleStatusScreen(status: status ?? BleStatus.unknown); } diff --git a/example/lib/src/ble/ble_device_interactor.dart b/example/lib/src/ble/ble_device_interactor.dart index 9d13a1c5..3d09b509 100644 --- a/example/lib/src/ble/ble_device_interactor.dart +++ b/example/lib/src/ble/ble_device_interactor.dart @@ -64,6 +64,7 @@ class BleDeviceInteractor { _logMessage( 'Error occured when reading ${characteristic.characteristicId} : $e', ); + // ignore: avoid_print print(s); rethrow; } @@ -79,6 +80,7 @@ class BleDeviceInteractor { _logMessage( 'Error occured when writing ${characteristic.characteristicId} : $e', ); + // ignore: avoid_print print(s); rethrow; } @@ -94,6 +96,7 @@ class BleDeviceInteractor { _logMessage( 'Error occured when writing ${characteristic.characteristicId} : $e', ); + // ignore: avoid_print print(s); rethrow; } diff --git a/example/lib/src/ui/device_detail/device_detail_screen.dart b/example/lib/src/ui/device_detail/device_detail_screen.dart index 22d626b1..4a9df0b8 100644 --- a/example/lib/src/ui/device_detail/device_detail_screen.dart +++ b/example/lib/src/ui/device_detail/device_detail_screen.dart @@ -60,7 +60,7 @@ class _DeviceDetail extends StatelessWidget { DeviceInteractionTab( device: device, ), - DeviceLogTab(), + const DeviceLogTab(), ], ), ), diff --git a/example/lib/src/ui/device_detail/device_log_tab.dart b/example/lib/src/ui/device_detail/device_log_tab.dart index bb121cc9..08ab45dd 100644 --- a/example/lib/src/ui/device_detail/device_log_tab.dart +++ b/example/lib/src/ui/device_detail/device_log_tab.dart @@ -3,6 +3,8 @@ import 'package:flutter_reactive_ble_example/src/ble/ble_logger.dart'; import 'package:provider/provider.dart'; class DeviceLogTab extends StatelessWidget { + const DeviceLogTab({Key? key}) : super(key: key); + @override Widget build(BuildContext context) => Consumer( builder: (context, logger, _) => _DeviceLogTab( diff --git a/example/lib/src/ui/device_list.dart b/example/lib/src/ui/device_list.dart index bc0c1318..b42a498b 100644 --- a/example/lib/src/ui/device_list.dart +++ b/example/lib/src/ui/device_list.dart @@ -7,6 +7,8 @@ import '../widgets.dart'; import 'device_detail/device_detail_screen.dart'; class DeviceListScreen extends StatelessWidget { + const DeviceListScreen({Key? key}) : super(key: key); + @override Widget build(BuildContext context) => Consumer2( builder: (_, bleScanner, bleScannerState, __) => _DeviceList( diff --git a/example/lib/src/utils.dart b/example/lib/src/utils.dart index 17662910..a0293a03 100644 --- a/example/lib/src/utils.dart +++ b/example/lib/src/utils.dart @@ -1 +1,2 @@ +// ignore: avoid_print void log(String text) => print("[FlutterReactiveBLEApp] $text"); diff --git a/example/lib/src/widgets.dart b/example/lib/src/widgets.dart index 2f5fe8a5..a6ec0672 100644 --- a/example/lib/src/widgets.dart +++ b/example/lib/src/widgets.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class BluetoothIcon extends StatelessWidget { - const BluetoothIcon(); + const BluetoothIcon({Key? key}) : super(key: key); @override Widget build(BuildContext context) => const SizedBox( @@ -12,7 +12,10 @@ class BluetoothIcon extends StatelessWidget { } class StatusMessage extends StatelessWidget { - const StatusMessage(this.text); + const StatusMessage({ + required this.text, + Key? key, + }) : super(key: key); final String text; diff --git a/example/pubspec.lock b/example/pubspec.lock index 08901279..34034f25 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -14,7 +14,7 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.40.6" + version: "0.40.7" args: dependency: transitive description: @@ -56,7 +56,7 @@ packages: name: build_daemon url: "https://pub.dartlang.org" source: hosted - version: "2.1.8" + version: "2.1.10" build_resolvers: dependency: transitive description: @@ -70,7 +70,7 @@ packages: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "1.11.1" + version: "1.11.1+1" build_runner_core: dependency: transitive description: @@ -84,14 +84,14 @@ packages: name: built_collection url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "5.1.0" built_value: dependency: transitive description: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.0.0-nullsafety.0" + version: "8.1.2" characters: dependency: transitive description: @@ -133,7 +133,7 @@ packages: name: code_builder url: "https://pub.dartlang.org" source: hosted - version: "3.6.0" + version: "3.7.0" collection: dependency: transitive description: @@ -195,13 +195,20 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct main" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" flutter_reactive_ble: dependency: "direct main" description: - path: ".." + path: "../packages/flutter_reactive_ble" relative: true source: path - version: "3.1.1+1" + version: "4.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -262,14 +269,14 @@ packages: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "0.3.5" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.2" + version: "0.6.3" json_annotation: dependency: transitive description: @@ -277,6 +284,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.1" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" logging: dependency: transitive description: @@ -346,7 +360,14 @@ packages: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.11.0" + version: "1.11.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" pool: dependency: transitive description: @@ -381,14 +402,28 @@ packages: name: pubspec_parse url: "https://pub.dartlang.org" source: hosted - version: "0.1.7" + version: "0.1.8" + reactive_ble_mobile: + dependency: transitive + description: + name: reactive_ble_mobile + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + reactive_ble_platform_interface: + dependency: transitive + description: + name: reactive_ble_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.2.0" shelf_web_socket: dependency: transitive description: @@ -501,4 +536,4 @@ packages: version: "2.2.1" sdks: dart: ">=2.12.0 <3.0.0" - flutter: ">=1.16.0" + flutter: ">=1.20.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 4d2d9a8e..4344aac0 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -10,8 +10,9 @@ environment: dependencies: flutter: sdk: flutter + flutter_lints: ^1.0.3 flutter_reactive_ble: - path: ../ + path: ../packages/flutter_reactive_ble functional_data: ^1.0.0 intl: ^0.17.0 diff --git a/lib/flutter_reactive_ble.dart b/lib/flutter_reactive_ble.dart deleted file mode 100644 index dd3be54d..00000000 --- a/lib/flutter_reactive_ble.dart +++ /dev/null @@ -1,17 +0,0 @@ -library flutter_reactive_ble; - -export 'src/model/ble_status.dart'; -export 'src/model/characteristic_value.dart'; -export 'src/model/connection_priority.dart'; -export 'src/model/connection_state_update.dart'; -export 'src/model/discovered_device.dart'; -export 'src/model/discovered_service.dart'; -export 'src/model/generic_failure.dart'; -export 'src/model/log_level.dart'; -export 'src/model/qualified_characteristic.dart'; -export 'src/model/result.dart'; -export 'src/model/scan_mode.dart'; -export 'src/model/uuid.dart'; -export 'src/reactive_ble.dart'; -export 'src/rx_ext/repeater.dart'; -export 'src/rx_ext/serial_disposable.dart'; diff --git a/lib/src/plugin_controller.dart b/lib/src/plugin_controller.dart deleted file mode 100644 index 2db50452..00000000 --- a/lib/src/plugin_controller.dart +++ /dev/null @@ -1,391 +0,0 @@ -import 'package:flutter/services.dart'; -import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/converter/args_to_protubuf_converter.dart'; -import 'package:flutter_reactive_ble/src/debug_logger.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; -import 'package:flutter_reactive_ble/src/model/write_characteristic_info.dart'; - -import 'converter/protobuf_converter.dart'; -import 'model/characteristic_value.dart'; -import 'model/clear_gatt_cache_error.dart'; -import 'model/connection_state_update.dart'; -import 'model/discovered_service.dart'; -import 'model/qualified_characteristic.dart'; -import 'model/unit.dart'; - -abstract class DeviceOperationController { - Stream get charValueUpdateStream; - - Future> discoverServices(String deviceId); - - Stream readCharacteristic(QualifiedCharacteristic characteristic); - - Future writeCharacteristicWithResponse( - QualifiedCharacteristic characteristic, - List value, - ); - - Future writeCharacteristicWithoutResponse( - QualifiedCharacteristic characteristic, - List value, - ); - - Stream subscribeToNotifications( - QualifiedCharacteristic characteristic, - ); - - Future stopSubscribingToNotifications( - QualifiedCharacteristic characteristic, - ); - - Future requestMtuSize(String deviceId, int? mtu); - - Future requestConnectionPriority( - String deviceId, ConnectionPriority priority); -} - -abstract class ScanOperationController { - Stream get scanStream; - - Stream scanForDevices({ - required List withServices, - required ScanMode scanMode, - required bool requireLocationServicesEnabled, - }); -} - -abstract class DeviceConnectionController { - Stream get connectionUpdateStream; - - Stream connectToDevice( - String id, - Map>? servicesWithCharacteristicsToDiscover, - Duration? connectionTimeout, - ); - - Future disconnectDevice(String deviceId); -} - -abstract class BleOperationController { - Stream get bleStatusStream; - - Future initialize(); - - Future deinitialize(); - - Future?>> clearGattCache( - String deviceId); -} - -class PluginController - implements - DeviceOperationController, - ScanOperationController, - DeviceConnectionController, - BleOperationController { - PluginController({ - required ArgsToProtobufConverter argsToProtobufConverter, - required ProtobufConverter protobufConverter, - required MethodChannel bleMethodChannel, - required Stream> connectedDeviceChannel, - required Stream> charUpdateChannel, - required Stream> bleDeviceScanChannel, - required Stream> bleStatusChannel, - required Logger debugLogger, - }) : _argsToProtobufConverter = argsToProtobufConverter, - _protobufConverter = protobufConverter, - _bleMethodChannel = bleMethodChannel, - _connectedDeviceRawStream = connectedDeviceChannel, - _charUpdateRawStream = charUpdateChannel, - _bleStatusRawChannel = bleStatusChannel, - _bleDeviceScanRawStream = bleDeviceScanChannel, - _debugLogger = debugLogger; - - final ArgsToProtobufConverter _argsToProtobufConverter; - final ProtobufConverter _protobufConverter; - final MethodChannel _bleMethodChannel; - final Stream> _connectedDeviceRawStream; - final Stream> _charUpdateRawStream; - final Stream> _bleDeviceScanRawStream; - final Stream> _bleStatusRawChannel; - final Logger _debugLogger; - - Stream? _connectionUpdateStream; - Stream? _charValueStream; - Stream? _scanResultStream; - Stream? _bleStatusStream; - - @override - Stream get connectionUpdateStream => - _connectionUpdateStream ??= _connectedDeviceRawStream - .map(_protobufConverter.connectionStateUpdateFrom) - .map( - (update) { - _debugLogger.log( - 'Received $ConnectionStateUpdate(deviceId: ${update.deviceId}, connectionState: ${update.connectionState}, failure: ${update.failure})', - ); - return update; - }, - ); - - @override - Stream get charValueUpdateStream => - _charValueStream ??= _charUpdateRawStream - .map(_protobufConverter.characteristicValueFrom) - .map( - (update) { - _debugLogger.log( - 'Received $CharacteristicValue(characteristic: ${update.characteristic}, result: ${update.runtimeType})'); - return update; - }, - ); - - @override - Stream get scanStream => _scanResultStream ??= - _bleDeviceScanRawStream.map(_protobufConverter.scanResultFrom).map( - (scanResult) { - _debugLogger - .log('Received $ScanResult(result: ${scanResult.result})'); - return scanResult; - }, - ); - - @override - Stream get bleStatusStream => - _bleStatusStream ??= _bleStatusRawChannel - .map(_protobufConverter.bleStatusFrom) - .map((status) { - _debugLogger.log('Received ble status update: $status'); - return status; - }); - - @override - Future initialize() { - _debugLogger.log('Initialize ble client'); - return _bleMethodChannel.invokeMethod("initialize"); - } - - @override - Future deinitialize() { - _debugLogger.log('DeIititialize ble client'); - return _bleMethodChannel.invokeMethod("deinitialize"); - } - - @override - Stream scanForDevices({ - required List withServices, - required ScanMode scanMode, - required bool requireLocationServicesEnabled, - }) { - _debugLogger.log( - 'Start scanning for devices with arguments (withServices:$withServices, scanMode: $scanMode, locationServiceEnabled: $requireLocationServicesEnabled)', - ); - return _bleMethodChannel - .invokeMethod( - "scanForDevices", - _argsToProtobufConverter - .createScanForDevicesRequest( - withServices: withServices, - scanMode: scanMode, - requireLocationServicesEnabled: requireLocationServicesEnabled, - ) - .writeToBuffer(), - ) - .asStream(); - } - - @override - Stream connectToDevice( - String id, - Map>? servicesWithCharacteristicsToDiscover, - Duration? connectionTimeout, - ) { - _debugLogger.log( - 'Start connecting to device with arguments (deviceId: $id, servicesWithCharacteristicsToDiscover: $servicesWithCharacteristicsToDiscover, timeout: $connectionTimeout)', - ); - return _bleMethodChannel - .invokeMethod( - "connectToDevice", - _argsToProtobufConverter - .createConnectToDeviceArgs( - id, - servicesWithCharacteristicsToDiscover, - connectionTimeout, - ) - .writeToBuffer(), - ) - .asStream(); - } - - @override - Future disconnectDevice(String deviceId) { - _debugLogger.log('Disconnect from device $deviceId'); - return _bleMethodChannel.invokeMethod( - "disconnectFromDevice", - _argsToProtobufConverter - .createDisconnectDeviceArgs(deviceId) - .writeToBuffer(), - ); - } - - @override - Stream readCharacteristic(QualifiedCharacteristic characteristic) { - _debugLogger.log('Read characteristic $characteristic'); - return _bleMethodChannel - .invokeMethod( - "readCharacteristic", - _argsToProtobufConverter - .createReadCharacteristicRequest(characteristic) - .writeToBuffer(), - ) - .asStream(); - } - - @override - Future writeCharacteristicWithResponse( - QualifiedCharacteristic characteristic, - List value, - ) async { - _debugLogger.log('Write with response to $characteristic, value: $value'); - return _bleMethodChannel - .invokeMethod>( - "writeCharacteristicWithResponse", - _argsToProtobufConverter - .createWriteChacracteristicRequest(characteristic, value) - .writeToBuffer()) - .then((data) => _protobufConverter.writeCharacteristicInfoFrom(data!)); - } - - @override - Future writeCharacteristicWithoutResponse( - QualifiedCharacteristic characteristic, - List value, - ) async { - _debugLogger - .log('Write without response to $characteristic, value: $value'); - return _bleMethodChannel - .invokeMethod>( - "writeCharacteristicWithoutResponse", - _argsToProtobufConverter - .createWriteChacracteristicRequest(characteristic, value) - .writeToBuffer(), - ) - .then((data) => _protobufConverter.writeCharacteristicInfoFrom(data!)); - } - - @override - Stream subscribeToNotifications( - QualifiedCharacteristic characteristic, - ) { - _debugLogger.log('Start subscribing to notifications for $characteristic'); - return _bleMethodChannel - .invokeMethod( - "readNotifications", - _argsToProtobufConverter - .createNotifyCharacteristicRequest(characteristic) - .writeToBuffer(), - ) - .asStream(); - } - - @override - Future stopSubscribingToNotifications( - QualifiedCharacteristic characteristic, - ) { - _debugLogger.log('Stop subscribing to notifications for $characteristic'); - - return _bleMethodChannel - .invokeMethod( - "stopNotifications", - _argsToProtobufConverter - .createNotifyNoMoreCharacteristicRequest(characteristic) - .writeToBuffer(), - ) - .catchError( - (Object e) => print("Error unsubscribing from notifications: $e"), - ); - } - - @override - Future requestMtuSize(String deviceId, int? mtu) async { - _debugLogger - .log('Request mtu size for device: $deviceId with mtuSize: $mtu'); - return _bleMethodChannel - .invokeMethod>( - "negotiateMtuSize", - _argsToProtobufConverter - .createNegotiateMtuRequest(deviceId, mtu!) - .writeToBuffer(), - ) - .then((data) => _protobufConverter.mtuSizeFrom(data!)); - } - - @override - Future requestConnectionPriority( - String deviceId, ConnectionPriority priority) { - _debugLogger.log( - 'Request connection priority for device: $deviceId, priority: $priority'); - return _bleMethodChannel - .invokeMethod>( - "requestConnectionPriority", - _argsToProtobufConverter - .createChangeConnectionPrioRequest(deviceId, priority) - .writeToBuffer(), - ) - .then((data) => _protobufConverter.connectionPriorityInfoFrom(data!)); - } - - @override - Future?>> clearGattCache( - String deviceId) { - _debugLogger.log('Clear gatt cache for device: $deviceId'); - return _bleMethodChannel - .invokeMethod>( - "clearGattCache", - _argsToProtobufConverter - .createClearGattCacheRequest(deviceId) - .writeToBuffer(), - ) - .then((data) => _protobufConverter.clearGattCacheResultFrom(data!)); - } - - @override - Future> discoverServices(String deviceId) async => - _bleMethodChannel - .invokeMethod>( - 'discoverServices', - _argsToProtobufConverter - .createDiscoverServicesRequest(deviceId) - .writeToBuffer(), - ) - .then((data) => _protobufConverter.discoveredServicesFrom(data!)); -} - -class PluginControllerFactory { - const PluginControllerFactory(); - - PluginController create(Logger logger) { - const _bleMethodChannel = MethodChannel("flutter_reactive_ble_method"); - - const connectedDeviceChannel = - EventChannel("flutter_reactive_ble_connected_device"); - const charEventChannel = EventChannel("flutter_reactive_ble_char_update"); - const scanEventChannel = EventChannel("flutter_reactive_ble_scan"); - const bleStatusChannel = EventChannel("flutter_reactive_ble_status"); - - return PluginController( - protobufConverter: const ProtobufConverterImpl(), - argsToProtobufConverter: const ArgsToProtobufConverterImpl(), - bleMethodChannel: _bleMethodChannel, - connectedDeviceChannel: - connectedDeviceChannel.receiveBroadcastStream().cast>(), - charUpdateChannel: - charEventChannel.receiveBroadcastStream().cast>(), - bleDeviceScanChannel: - scanEventChannel.receiveBroadcastStream().cast>(), - bleStatusChannel: - bleStatusChannel.receiveBroadcastStream().cast>(), - debugLogger: logger, - ); - } -} diff --git a/melos.yaml b/melos.yaml new file mode 100644 index 00000000..ba9fda01 --- /dev/null +++ b/melos.yaml @@ -0,0 +1,9 @@ +name: flutter_reactive_ble +packages: + - /** +scripts: + analyze: melos exec -- flutter analyze + format: melos exec -- flutter format . + get: melos exec -- flutter pub get + unittest: + run: melos exec -- flutter test diff --git a/CHANGELOG.md b/packages/flutter_reactive_ble/CHANGELOG.md similarity index 97% rename from CHANGELOG.md rename to packages/flutter_reactive_ble/CHANGELOG.md index 3a649b4f..453ddd2a 100644 --- a/CHANGELOG.md +++ b/packages/flutter_reactive_ble/CHANGELOG.md @@ -1,14 +1,17 @@ # Main releases -# 3.1.1+1 +## 4.0.0 + +* Support federated plugin structure +## 3.1.1+1 * Fix broken read/write subscribe operations in background mode. -# 3.1.1 +## 3.1.1 * Fixes to comply to new Dart linter. * Fix #277 be able to connect when in background mode. -# 3.1.0 +## 3.1.0 * Add discoverable services to `ScanResult`. Kudos to @xvrh. diff --git a/packages/flutter_reactive_ble/LICENSE b/packages/flutter_reactive_ble/LICENSE new file mode 100644 index 00000000..1b0489a1 --- /dev/null +++ b/packages/flutter_reactive_ble/LICENSE @@ -0,0 +1,24 @@ +BSD license + +©2019 Signify Holding. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions +and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/packages/flutter_reactive_ble/README.md b/packages/flutter_reactive_ble/README.md new file mode 100644 index 00000000..efe5929b --- /dev/null +++ b/packages/flutter_reactive_ble/README.md @@ -0,0 +1,232 @@ +# Flutter reactive BLE library + +[![flutter_reactive_ble version](https://img.shields.io/pub/v/flutter_reactive_ble?label=flutter_reactive_ble)](https://pub.dev/packages/flutter_reactive_ble) + +Flutter library that handles BLE operations for multiple devices. + +## Usage + +The reactive BLE lib supports the following: + +- BLE device discovery +- Observe host device BLE status +- Establishing a BLE connection +- Maintaining connection status of multiple BLE devices +- Discover services(will be implicit) +- Read / write a characteristic +- Subscribe to a characteristic +- Clear GATT cache +- Negotiate MTU size + +### Initialization + +Initializing the library should be done the following: + +```dart +final flutterReactiveBle = FlutterReactiveBle(); +``` + +### Device discovery + +Discovering BLE devices should be done like this: + +```dart +flutterReactiveBle.scanForDevices(withServices: [serviceId], scanMode: ScanMode.lowLatency).listen((device) { + //code for handling results + }, onError: () { + //code for handling error + }); + +``` + +The `withServices` parameter specifies the advertised service IDs to look for. If an empty list is passed, all the advertising devices will be reported. The parameter `scanMode` is only used on Android and follows the conventions described on [ScanSettings](https://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_BALANCED) Android reference page. If `scanMode` is omitted the balanced scan mode will be used. + + +### Observe host device BLE status + +Use `statusStream` to retrieve updates about the BLE status of the host device (the device running the app) . This stream can be used in order to determine if the BLE is turned on, on the device or if the required permissions are granted. Example usage: + +``` dart +_ble.statusStream.listen((status) { + //code for handling status update +}); +``` + +Use ` _ble.status` to get the current status of the host device. + +See [BleStatus](https://github.com/PhilipsHue/flutter_reactive_ble/blob/master/lib/src/model/ble_status.dart) for +more info about the meaning of the different statuses. + +### Establishing connection + +To interact with a device you first need to establish a connection: + +```dart +flutterReactiveBle.connectToDevice( + id: foundDeviceId, + servicesWithCharacteristicsToDiscover: {serviceId: [char1, char2]}, + connectionTimeout: const Duration(seconds: 2), + ).listen((connectionState) { + // Handle connection state updates + }, onError: (Object error) { + // Handle a possible error + }); +``` + +For the required `id` parameter use a device ID retrieved through device discovery. On iOS the device ID is a UUID and on Android it is a MAC address (which may also be randomized, depending on the Android version). Supplying a map with service and characteristic IDs you want to discover may speed up the connection on iOS (otherwise _all_ services and characteristics will be discovered). You can specify a `connectionTimeout` when the client will provide an error in case the connection cannot be established within the specified time. + +There are numerous issues on the Android BLE stack that leave it hanging when you try to connect to a device that is not in range. To work around this +issue use the method `connectToAdvertisingDevice` to first scan for the device and only if it is found connect to it. + +```dart +flutterReactiveBle.connectToAdvertisingDevice( + id: foundDeviceId, + withServices: [serviceUuid], + prescanDuration: const Duration(seconds: 5), + servicesWithCharacteristicsToDiscover: {serviceId: [char1, char2]}, + connectionTimeout: const Duration(seconds: 2), + ).listen((connectionState) { + // Handle connection state updates + }, onError: (dynamic error) { + // Handle a possible error + }); +``` + +Besides the normal connection parameters that are described above this function also has 2 additional required parameters: `withServices` and `prescanDuration`. PreScanDuration is the amount of time the ble stack will scan for the device before it attempts to connect (if the device is found) + +### Read / write characteristics + +#### Read characteristic + +```dart +final characteristic = QualifiedCharacteristic(serviceId: serviceUuid, characteristicId: characteristicUuid, deviceId: foundDeviceId); +final response = await flutterReactiveBle.readCharacteristic(characteristic); +``` + +#### Write with response + +Write a value to characteristic and await the response. The "response" in "write characteristic with response" means "an acknowledgement of reception". The write can either be acknowledged (success) or failed (an exception is thrown), thus the return type is `void` and there is nothing to print (though you can `print("Write successful")` and in a catch-clause `print("Write failed: $e")`). + +BLE does not provide a request-response mechanism like you may know from HTTP out of the box. If you need to perform request-response calls, you will need to implement a custom mechanism on top of the basic BLE functionality. A typical approach is to implement a "control point": a characteristic that is writable and delivers [notifications or indications](https://duckduckgo.com/?q=BLE+"indications"+vs+"notifications"), so that a request is written to it and a response is delivered back as a notification or an indication. + +```dart +final characteristic = QualifiedCharacteristic(serviceId: serviceUuid, characteristicId: characteristicUuid, deviceId: foundDeviceId); +await flutterReactiveBle.writeCharacteristicWithResponse(characteristic, value: [0x00]); +``` + +#### Write without response + +Use this operation if you want to execute multiple consecutive write operations in a small timeframe (e.g uploading firmware to device) or if the device does not provide a response. This is performance wise the fastest way of writing a value but there's a chance that the BLE device cannot handle that many consecutive writes in a row, so do a `writeWithResponse` once in a while. + +```dart +final characteristic = QualifiedCharacteristic(serviceId: serviceUuid, characteristicId: characteristicUuid, deviceId: foundDeviceId); +flutterReactiveBle.writeCharacteristicWithoutResponse(characteristic, value: [0x00]); +``` + +### Subscribe to characteristic + +Instead of periodically reading the characteristic you can also listen to the notifications (in case the specific service supports it) in case the value changes. + +```dart +final characteristic = QualifiedCharacteristic(serviceId: serviceUuid, characteristicId: characteristicUuid, deviceId: foundDeviceId); + flutterReactiveBle.subscribeToCharacteristic(characteristic).listen((data) { + // code to handle incoming data + }, onError: (dynamic error) { + // code to handle errors + }); +``` + +### Negotiate MTU size + +You can increase or decrease the MTU size to reach a higher throughput. This operation will return the actual negotiated MTU size, but it is no guarantee that the requested size will be successfully negotiated. iOS has a default MTU size which cannot be negotiated, however you can still use this operation to get the current MTU. + +```dart +final mtu = await flutterReactiveBle.requestMtu(deviceId: foundDeviceId, mtu: 250); +``` + +### Android specific operations + +The following operations will only have effect for Android and are not supported by iOS. When using these operations on iOS the library will throw an UnSupportedOperationException. + +#### Request connection priority + +On Android you can send a connection priority update to the BLE device. The parameter `priority` is an enum that uses the same spec + as the [BluetoothGatt Android spec](https://developer.android.com/reference/android/bluetooth/BluetoothGatt#requestConnectionPriority(int)). + Using `highPerformance` will increase battery usage but will speed up GATT operations. Be cautious when setting the priority when communicating with multiple devices because if you set highperformance for all devices the effect of increasing the priority will be lower. + +```dart +await flutterReactiveBle.requestConnectionPriority(deviceId: foundDeviceId, priority: ConnectionPriority.highPerformance); +``` + +#### Clear GATT cache + +The Android OS maintains a table per device of the discovered service in cache. Sometimes it happens that after a firmware update a new service is introduced but the cache is not updated. To invalidate the cache you can use the cleargattCache operation. + +**This is a hidden BLE operation and should be used with extreme caution since this operation is on the [greylist](https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces).** + +```dart +await flutterReactiveBle.clearGattCache(foundDeviceId); +``` + +### FAQ + +#### How to handle the BLE undeliverable exception + +On Android side we use the [RxAndroidBle](https://github.com/Polidea/RxAndroidBle) library of Polidea. After migration towards RxJava 2 some of the errors are not routed properly to their listeners and thus this will result in a BLE Undeliverable Exception. The root cause lies in the threading of the Android OS. As workaround RxJava has a hook where you can set the global errorhandler. For more info see [RxJava docs](https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling) . + + +A default workaround implementation in the Flutter app (needs to be in the Java / Kotlin part e.g. mainactivity) is shown below. For an example (in Java) see Polidea RxAndroidBle [sample](https://github.com/Polidea/RxAndroidBle/tree/master/sample/src/main/java/com/polidea/rxandroidble2/sample). + +BleException is coming from Polidea RxAndroidBle, so make sure your application declares the following depedency: `implementation "com.polidea.rxandroidble2:rxandroidble:1.11.1"` + +```kotlin +RxJavaPlugins.setErrorHandler { throwable -> + if (throwable is UndeliverableException && throwable.cause is BleException) { + return@setErrorHandler // ignore BleExceptions since we do not have subscriber + } + else { + throw throwable + } +} +``` + +#### Which permissions are needed? +**Android** + +For android the library uses the following permissions: +* ACCESS_FINE_LOCATION : this permission is needed because old Nexus devices need location services in order to provide reliable scan results +* BLUETOOTH : allows apps to connect to a paired bluetooth device +* BLUETOOTH_ADMIN: allows apps to discover and pair bluetooth devices + +These permissions are already added in the manifest of the this library and thus should automatically merge +into the manifest of your app. It is not needed to add the permissions in your manifest. + +**iOS** + +For iOS it is required you add the following entries to the `Info.plist` file of your app. It is not allowed to access Core BLuetooth without this. See [our example app](https://github.com/PhilipsHue/flutter_reactive_ble/blob/master/example/ios/Runner/Info.plist) on how to implement this. For more indepth details: [Blog post on iOS bluetooth permissions](https://medium.com/flawless-app-stories/handling-ios-13-bluetooth-permissions-26c6a8cbb816) + +iOS13 and higher +* NSBluetoothAlwaysUsageDescription + +iOS12 and lower +* NSBluetoothPeripheralUsageDescription + +#### How to adjust ProGuard (Android) + +In case you are using ProGuard add the following snippet to your `proguard-rules.pro` file: + +``` +-keep class com.signify.hue.** { *; } +``` + +This will prevent issues like [#131](https://github.com/PhilipsHue/flutter_reactive_ble/issues/131). + +#### Why doesn't the BLE stack directly connect to my peripheral + +Before you are able to execute BLE operations the BLE-stack of the device makes sure everything is setup correctly and then reports ready for operation. For some devices this takes a bit longer than for others. When starting the app make sure that the BLE-stack is properly initialized before you execute BLE operations. The safest way to do this is by listening to the `statusStream` and wait for `BleStatus.ready`. + +This will prevent issues like [#147](https://github.com/PhilipsHue/flutter_reactive_ble/issues/147). + +#### Unofficial example apps + +Example implementation UART over BLE:[link](https://github.com/wolfc01/flutter_reactive_ble_uart_example) \ No newline at end of file diff --git a/packages/flutter_reactive_ble/lib/flutter_reactive_ble.dart b/packages/flutter_reactive_ble/lib/flutter_reactive_ble.dart new file mode 100644 index 00000000..a1214cf6 --- /dev/null +++ b/packages/flutter_reactive_ble/lib/flutter_reactive_ble.dart @@ -0,0 +1,7 @@ +library flutter_reactive_ble; + +export 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; + +export 'src/reactive_ble.dart'; +export 'src/rx_ext/repeater.dart'; +export 'src/rx_ext/serial_disposable.dart'; diff --git a/lib/src/connected_device_operation.dart b/packages/flutter_reactive_ble/lib/src/connected_device_operation.dart similarity index 86% rename from lib/src/connected_device_operation.dart rename to packages/flutter_reactive_ble/lib/src/connected_device_operation.dart index f0361de3..546c9014 100644 --- a/lib/src/connected_device_operation.dart +++ b/packages/flutter_reactive_ble/lib/src/connected_device_operation.dart @@ -1,6 +1,6 @@ import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:meta/meta.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; abstract class ConnectedDeviceOperation { Stream get characteristicValueStream; @@ -31,15 +31,14 @@ abstract class ConnectedDeviceOperation { } class ConnectedDeviceOperationImpl implements ConnectedDeviceOperation { - ConnectedDeviceOperationImpl({ - required DeviceOperationController controller, - }) : _controller = controller; + ConnectedDeviceOperationImpl({required ReactiveBlePlatform blePlatform}) + : _blePlatform = blePlatform; - final DeviceOperationController _controller; + final ReactiveBlePlatform _blePlatform; @override Stream get characteristicValueStream => - _controller.charValueUpdateStream; + _blePlatform.charValueUpdateStream; @override Future> readCharacteristic(QualifiedCharacteristic characteristic) { @@ -47,7 +46,7 @@ class ConnectedDeviceOperationImpl implements ConnectedDeviceOperation { .where((update) => update.characteristic == characteristic) .map((update) => update.result.dematerialize()); - return _controller + return _blePlatform .readCharacteristic(characteristic) .asyncExpand((_) => specificCharacteristicValueStream) .firstWhere((_) => true, @@ -59,7 +58,7 @@ class ConnectedDeviceOperationImpl implements ConnectedDeviceOperation { QualifiedCharacteristic characteristic, { required List value, }) async => - _controller + _blePlatform .writeCharacteristicWithResponse(characteristic, value) .then((info) => info.result.dematerialize()); @@ -68,7 +67,7 @@ class ConnectedDeviceOperationImpl implements ConnectedDeviceOperation { QualifiedCharacteristic characteristic, { required List value, }) async => - _controller + _blePlatform .writeCharacteristicWithoutResponse(characteristic, value) .then((info) => info.result.dematerialize()); @@ -82,12 +81,13 @@ class ConnectedDeviceOperationImpl implements ConnectedDeviceOperation { .map((update) => update.result.dematerialize()); final autosubscribingRepeater = Repeater>.broadcast( - onListenEmitFrom: () => _controller + onListenEmitFrom: () => _blePlatform .subscribeToNotifications(characteristic) .asyncExpand((_) => specificCharacteristicValueStream), - onCancel: () => _controller + onCancel: () => _blePlatform .stopSubscribingToNotifications(characteristic) .catchError((Object e) => + // ignore: avoid_print print("Error unsubscribing from notifications: $e")), ); @@ -98,16 +98,16 @@ class ConnectedDeviceOperationImpl implements ConnectedDeviceOperation { @override Future requestMtu(String deviceId, int mtu) async => - _controller.requestMtuSize(deviceId, mtu); + _blePlatform.requestMtuSize(deviceId, mtu); @override Future> discoverServices(String deviceId) => - _controller.discoverServices(deviceId); + _blePlatform.discoverServices(deviceId); @override Future requestConnectionPriority( String deviceId, ConnectionPriority priority) async => - _controller + _blePlatform .requestConnectionPriority(deviceId, priority) .then((message) => message.result.dematerialize()); } diff --git a/lib/src/debug_logger.dart b/packages/flutter_reactive_ble/lib/src/debug_logger.dart similarity index 86% rename from lib/src/debug_logger.dart rename to packages/flutter_reactive_ble/lib/src/debug_logger.dart index 49a26c57..bd8dadec 100644 --- a/lib/src/debug_logger.dart +++ b/packages/flutter_reactive_ble/lib/src/debug_logger.dart @@ -1,4 +1,4 @@ -import 'package:flutter_reactive_ble/src/model/log_level.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; abstract class Logger { set logLevel(LogLevel logLevel); diff --git a/lib/src/device_connector.dart b/packages/flutter_reactive_ble/lib/src/device_connector.dart similarity index 92% rename from lib/src/device_connector.dart rename to packages/flutter_reactive_ble/lib/src/device_connector.dart index 3e29dd8e..88e2a4fd 100644 --- a/lib/src/device_connector.dart +++ b/packages/flutter_reactive_ble/lib/src/device_connector.dart @@ -1,13 +1,7 @@ import 'package:collection/collection.dart'; import 'package:flutter_reactive_ble/src/device_scanner.dart'; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:flutter_reactive_ble/src/rx_ext/repeater.dart'; - -import 'model/discovered_device.dart'; -import 'model/generic_failure.dart'; -import 'model/scan_mode.dart'; -import 'model/uuid.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; abstract class DeviceConnector { Stream get deviceConnectionStateUpdateStream; @@ -29,7 +23,7 @@ abstract class DeviceConnector { class DeviceConnectorImpl implements DeviceConnector { const DeviceConnectorImpl({ - required DeviceConnectionController controller, + required ReactiveBlePlatform blePlatform, required bool Function( {required String deviceId, required Duration cacheValidity}) deviceIsDiscoveredRecently, @@ -37,10 +31,10 @@ class DeviceConnectorImpl implements DeviceConnector { required Duration delayAfterScanFailure, }) : _deviceIsDiscoveredRecently = deviceIsDiscoveredRecently, _deviceScanner = deviceScanner, - _controller = controller, + _blePlatform = blePlatform, _delayAfterScanFailure = delayAfterScanFailure; - final DeviceConnectionController _controller; + final ReactiveBlePlatform _blePlatform; final bool Function({ required String deviceId, required Duration cacheValidity, @@ -52,7 +46,7 @@ class DeviceConnectorImpl implements DeviceConnector { @override Stream get deviceConnectionStateUpdateStream => - _controller.connectionUpdateStream; + _blePlatform.connectionUpdateStream; @override Stream connect({ @@ -70,14 +64,14 @@ class DeviceConnectorImpl implements DeviceConnector { .cast(); final autoconnectingRepeater = Repeater.broadcast( - onListenEmitFrom: () => _controller + onListenEmitFrom: () => _blePlatform .connectToDevice( id, servicesWithCharacteristicsToDiscover, connectionTimeout, ) .asyncExpand((_) => specificConnectedDeviceStream), - onCancel: () => _controller.disconnectDevice(id), + onCancel: () => _blePlatform.disconnectDevice(id), ); return autoconnectingRepeater.stream; diff --git a/lib/src/device_scanner.dart b/packages/flutter_reactive_ble/lib/src/device_scanner.dart similarity index 85% rename from lib/src/device_scanner.dart rename to packages/flutter_reactive_ble/lib/src/device_scanner.dart index 5c4fe10e..080e71bd 100644 --- a/lib/src/device_scanner.dart +++ b/packages/flutter_reactive_ble/lib/src/device_scanner.dart @@ -1,15 +1,10 @@ import 'dart:async'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:flutter_reactive_ble/src/rx_ext/repeater.dart'; import 'package:flutter_reactive_ble/src/rx_ext/serial_disposable.dart'; import 'package:pedantic/pedantic.dart'; - -import 'model/discovered_device.dart'; -import 'model/scan_mode.dart'; -import 'model/scan_session.dart'; -import 'model/uuid.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; abstract class DeviceScanner { ScanSession? get currentScan; @@ -23,22 +18,22 @@ abstract class DeviceScanner { class DeviceScannerImpl implements DeviceScanner { DeviceScannerImpl({ - required ScanOperationController controller, + required ReactiveBlePlatform blePlatform, required bool Function() platformIsAndroid, required Future delayAfterScanCompletion, required this.addToScanRegistry, - }) : _controller = controller, + }) : _blePlatform = blePlatform, _platformIsAndroid = platformIsAndroid, _delayAfterScanCompletion = delayAfterScanCompletion; ScanSession? _currentScanSession; - final ScanOperationController _controller; + final ReactiveBlePlatform _blePlatform; final bool Function() _platformIsAndroid; final Future _delayAfterScanCompletion; final void Function(String deviceId) addToScanRegistry; - Stream get _scanStream => _controller.scanStream; + Stream get _scanStream => _blePlatform.scanStream; final SerialDisposable> _scanStreamDisposable = SerialDisposable( @@ -65,12 +60,13 @@ class DeviceScannerImpl implements DeviceScanner { (Object e, StackTrace s) { if (!completer.isCompleted) { completer.completeError(e, s); - if (e is Exception) + if (e is Exception) { throw e; - else if (e is Error) + } else if (e is Error) { throw e; - else + } else { throw Exception(e); + } } }, ), @@ -89,7 +85,7 @@ class DeviceScannerImpl implements DeviceScanner { _scanStreamDisposable.set(scanRepeater); - return _controller + return _blePlatform .scanForDevices( withServices: withServices, scanMode: scanMode, diff --git a/lib/src/discovered_devices_registry.dart b/packages/flutter_reactive_ble/lib/src/discovered_devices_registry.dart similarity index 100% rename from lib/src/discovered_devices_registry.dart rename to packages/flutter_reactive_ble/lib/src/discovered_devices_registry.dart diff --git a/lib/src/reactive_ble.dart b/packages/flutter_reactive_ble/lib/src/reactive_ble.dart similarity index 90% rename from lib/src/reactive_ble.dart rename to packages/flutter_reactive_ble/lib/src/reactive_ble.dart index d40cdd93..a7c88fe8 100644 --- a/lib/src/reactive_ble.dart +++ b/packages/flutter_reactive_ble/lib/src/reactive_ble.dart @@ -6,20 +6,10 @@ import 'package:flutter_reactive_ble/src/debug_logger.dart'; import 'package:flutter_reactive_ble/src/device_connector.dart'; import 'package:flutter_reactive_ble/src/device_scanner.dart'; import 'package:flutter_reactive_ble/src/discovered_devices_registry.dart'; -import 'package:flutter_reactive_ble/src/model/ble_status.dart'; -import 'package:flutter_reactive_ble/src/model/characteristic_value.dart'; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart'; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart'; -import 'package:flutter_reactive_ble/src/model/discovered_device.dart'; -import 'package:flutter_reactive_ble/src/model/log_level.dart'; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart'; -import 'package:flutter_reactive_ble/src/model/scan_mode.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:flutter_reactive_ble/src/rx_ext/repeater.dart'; import 'package:meta/meta.dart'; - -import 'model/discovered_service.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; +import 'package:reactive_ble_mobile/reactive_ble_mobile.dart'; /// [FlutterReactiveBle] is the facade of the library. Its interface allows to /// perform all the supported BLE operations. @@ -31,19 +21,19 @@ class FlutterReactiveBle { ///Create a new instance where injected depedencies are used. @visibleForTesting FlutterReactiveBle.witDependencies({ - required BleOperationController bleOperationController, required DeviceScanner deviceScanner, required DeviceConnector deviceConnector, required ConnectedDeviceOperation connectedDeviceOperation, required Logger debugLogger, required Future initialization, + required ReactiveBlePlatform reactiveBlePlatform, }) { - _bleOperationController = bleOperationController; _deviceScanner = deviceScanner; _deviceConnector = deviceConnector; _connectedDeviceOperator = connectedDeviceOperation; _debugLogger = debugLogger; _initialization = initialization; + _blePlatform = reactiveBlePlatform; _trackStatus(); } @@ -84,14 +74,11 @@ class FlutterReactiveBle { yield* _connectedDeviceOperator.characteristicValueStream; } - late BleOperationController _bleOperationController; - - late PluginController _pluginController; + late ReactiveBlePlatform _blePlatform; BleStatus _status = BleStatus.unknown; - Stream get _statusStream => - _bleOperationController.bleStatusStream; + Stream get _statusStream => _blePlatform.bleStatusStream; Future _trackStatus() async { await initialize(); @@ -117,16 +104,18 @@ class FlutterReactiveBle { print, ); - _pluginController = const PluginControllerFactory().create(_debugLogger); - _bleOperationController = _pluginController; + ReactiveBlePlatform.instance = + const ReactiveBleMobilePlatformFactory().create(); + + _blePlatform = ReactiveBlePlatform.instance; - _initialization ??= _bleOperationController.initialize(); + _initialization ??= _blePlatform.initialize(); _connectedDeviceOperator = ConnectedDeviceOperationImpl( - controller: _pluginController, + blePlatform: _blePlatform, ); _deviceScanner = DeviceScannerImpl( - controller: _pluginController, + blePlatform: _blePlatform, platformIsAndroid: () => Platform.isAndroid, delayAfterScanCompletion: Future.delayed( const Duration(milliseconds: 300), @@ -135,7 +124,7 @@ class FlutterReactiveBle { ); _deviceConnector = DeviceConnectorImpl( - controller: _pluginController, + blePlatform: _blePlatform, deviceIsDiscoveredRecently: scanRegistry.deviceIsDiscoveredRecently, deviceScanner: _deviceScanner, delayAfterScanFailure: const Duration(seconds: 10), @@ -152,7 +141,7 @@ class FlutterReactiveBle { Future deinitialize() async { if (_initialization != null) { _initialization = null; - await _bleOperationController.deinitialize(); + await _blePlatform.deinitialize(); } } @@ -316,7 +305,7 @@ class FlutterReactiveBle { /// Always completes with an error on iOS, as there is no way (and no need) to perform this operation on iOS. /// /// The connection may need to be reestablished after successful GATT attribute cache clearing. - Future clearGattCache(String deviceId) => _bleOperationController + Future clearGattCache(String deviceId) => _blePlatform .clearGattCache(deviceId) .then((info) => info.dematerialize()); diff --git a/lib/src/rx_ext/repeater.dart b/packages/flutter_reactive_ble/lib/src/rx_ext/repeater.dart similarity index 96% rename from lib/src/rx_ext/repeater.dart rename to packages/flutter_reactive_ble/lib/src/rx_ext/repeater.dart index 0b37e2fd..d7f1fc95 100644 --- a/lib/src/rx_ext/repeater.dart +++ b/packages/flutter_reactive_ble/lib/src/rx_ext/repeater.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import '../model/unit.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; /// [Repeater] sets an underlying stream up on the first subscription to /// the output [stream] and shuts it down when there are no more subscriptions. @@ -104,6 +104,7 @@ class Repeater { onCancel: onCancel, isSync: isSync); + // ignore: avoid_shadowing_type_parameters StreamController _makeStreamController() => _isBroadcast ? StreamController.broadcast( onListen: attach, diff --git a/lib/src/rx_ext/serial_disposable.dart b/packages/flutter_reactive_ble/lib/src/rx_ext/serial_disposable.dart similarity index 93% rename from lib/src/rx_ext/serial_disposable.dart rename to packages/flutter_reactive_ble/lib/src/rx_ext/serial_disposable.dart index 7c7dc058..18e3b862 100644 --- a/lib/src/rx_ext/serial_disposable.dart +++ b/packages/flutter_reactive_ble/lib/src/rx_ext/serial_disposable.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import '../model/unit.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; /// A disposable resource whose underlying resource can be replaced by another resource /// causing automatic disposal of the previous underlying resource. diff --git a/packages/flutter_reactive_ble/pubspec.lock b/packages/flutter_reactive_ble/pubspec.lock new file mode 100644 index 00000000..4ad753a0 --- /dev/null +++ b/packages/flutter_reactive_ble/pubspec.lock @@ -0,0 +1,504 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "22.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.1" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.1.0" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.1.2" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.3" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" + collection: + dependency: "direct main" + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + functional_data: + dependency: "direct main" + description: + name: functional_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + functional_data_generator: + dependency: "direct dev" + description: + name: functional_data_generator + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.10" + meta: + dependency: "direct main" + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + mockito: + dependency: "direct dev" + description: + name: mockito + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.14" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + pedantic: + dependency: "direct main" + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + protobuf: + dependency: transitive + description: + name: protobuf + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + reactive_ble_mobile: + dependency: "direct main" + description: + name: reactive_ble_mobile + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + reactive_ble_platform_interface: + dependency: "direct main" + description: + name: reactive_ble_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" +sdks: + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.20.0" diff --git a/pubspec.yaml b/packages/flutter_reactive_ble/pubspec.yaml similarity index 58% rename from pubspec.yaml rename to packages/flutter_reactive_ble/pubspec.yaml index ce8e826f..01464cdb 100644 --- a/pubspec.yaml +++ b/packages/flutter_reactive_ble/pubspec.yaml @@ -1,11 +1,19 @@ name: flutter_reactive_ble description: Reactive Bluetooth Low Energy (BLE) plugin that can communicate with multiple devices -version: 3.1.1+1 +version: 4.0.0 homepage: https://github.com/PhilipsHue/flutter_reactive_ble environment: sdk: '>=2.12.0 <3.0.0' - flutter: ">=1.10.0" + flutter: ">=1.17.0" + +flutter: + plugin: + platforms: + android: + default_package: reactive_ble_mobile + ios: + default_package: reactive_ble_mobile dependencies: collection: ^1.15.0 @@ -13,21 +21,15 @@ dependencies: sdk: flutter functional_data: ^1.0.0 meta: ^1.3.0 - pedantic: ^1.11.0 - protobuf: ^2.0.0 + pedantic: ^1.11.1 + reactive_ble_mobile: ^4.0.0 + reactive_ble_platform_interface: ^4.0.0 dev_dependencies: - build_runner: ^1.12.1 + build_runner: ^2.1.0 + flutter_lints: ^1.0.3 flutter_test: sdk: flutter - functional_data_generator: ^1.0.0 - mockito: ^5.0.2 + functional_data_generator: ^1.1.2 + mockito: ^5.0.14 -flutter: - plugin: - platforms: - android: - package: com.signify.hue.flutterreactiveble - pluginClass: ReactiveBlePlugin - ios: - pluginClass: ReactiveBlePlugin diff --git a/test/connected_device_operation_test.dart b/packages/flutter_reactive_ble/test/connected_device_operation_test.dart similarity index 85% rename from test/connected_device_operation_test.dart rename to packages/flutter_reactive_ble/test/connected_device_operation_test.dart index 7dbda02a..5b810756 100644 --- a/test/connected_device_operation_test.dart +++ b/packages/flutter_reactive_ble/test/connected_device_operation_test.dart @@ -1,32 +1,24 @@ import 'dart:async'; import 'package:flutter_reactive_ble/src/connected_device_operation.dart'; -import 'package:flutter_reactive_ble/src/model/characteristic_value.dart'; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart'; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart'; -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart'; -import 'package:flutter_reactive_ble/src/model/result.dart'; -import 'package:flutter_reactive_ble/src/model/unit.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; -import 'package:flutter_reactive_ble/src/model/write_characteristic_info.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; import 'connected_device_operation_test.mocks.dart'; -@GenerateMocks([DeviceOperationController]) +@GenerateMocks([ReactiveBlePlatform]) void main() { - late MockDeviceOperationController _controller; + late ReactiveBlePlatform _blePlatform; late ConnectedDeviceOperation _sut; group('$ConnectedDeviceOperation', () { setUp(() { - _controller = MockDeviceOperationController(); + _blePlatform = MockReactiveBlePlatform(); _sut = ConnectedDeviceOperationImpl( - controller: _controller, + blePlatform: _blePlatform, ); }); group('Listen to char value updates', () { @@ -42,7 +34,7 @@ void main() { result: const Result.success([1]), ); - when(_controller.charValueUpdateStream) + when(_blePlatform.charValueUpdateStream) .thenAnswer((_) => Stream.fromIterable([valueUpdate!])); }); @@ -97,14 +89,14 @@ void main() { result: const Result.success([4]), ); - when(_controller.readCharacteristic(any)).thenAnswer( + when(_blePlatform.readCharacteristic(charDevice)).thenAnswer( (_) => Stream.fromIterable([0]), ); }); group('Given multiple updates are received for specific device', () { setUp(() async { - when(_controller.charValueUpdateStream) + when(_blePlatform.charValueUpdateStream) .thenAnswer((_) => Stream.fromIterable([ valueUpdate!, valueUpdateOtherDevice!, @@ -123,7 +115,7 @@ void main() { 'Given no updates are provide for characteristic of specific device', () { setUp(() async { - when(_controller.charValueUpdateStream) + when(_blePlatform.charValueUpdateStream) .thenAnswer((_) => Stream.fromIterable([ valueUpdateOtherDevice!, valueUpdateSameDeviceOtherChar!, @@ -161,13 +153,16 @@ void main() { GenericFailure>.success(Unit()), ); - when(_controller.writeCharacteristicWithResponse(any, any)) + when(_blePlatform.writeCharacteristicWithResponse( + characteristic, value)) .thenAnswer((_) async => info); }); test('It completes without error', () async { - await _sut.writeCharacteristicWithResponse(characteristic, - value: value); + await _sut.writeCharacteristicWithResponse( + characteristic, + value: value, + ); expect(true, true); }); @@ -184,7 +179,8 @@ void main() { ), ); - when(_controller.writeCharacteristicWithResponse(any, any)) + when(_blePlatform.writeCharacteristicWithResponse( + characteristic, value)) .thenAnswer((_) async => info); }); @@ -207,7 +203,8 @@ void main() { GenericFailure>.success(Unit()), ); - when(_controller.writeCharacteristicWithoutResponse(any, any)) + when(_blePlatform.writeCharacteristicWithoutResponse( + characteristic, value)) .thenAnswer((_) async => info); }); @@ -232,7 +229,8 @@ void main() { ), ); - when(_controller.writeCharacteristicWithoutResponse(any, any)) + when(_blePlatform.writeCharacteristicWithoutResponse( + characteristic, value)) .thenAnswer((_) async => info); }); @@ -299,16 +297,16 @@ void main() { result: const Result.success([4]), ); - when(_controller.subscribeToNotifications(any)) + when(_blePlatform.subscribeToNotifications(charDevice)) .thenAnswer((_) => Stream.fromIterable([0])); - when(_controller.stopSubscribingToNotifications(any)) + when(_blePlatform.stopSubscribingToNotifications(charDevice)) .thenAnswer((_) async => 0); }); group('Given multiple updates are received for specific device', () { setUp(() async { - when(_controller.charValueUpdateStream) + when(_blePlatform.charValueUpdateStream) .thenAnswer((_) => Stream.fromIterable([ valueUpdate1, valueUpdateOtherDevice, @@ -336,7 +334,7 @@ void main() { int? result; setUp(() async { - when(_controller.requestMtuSize(any, any)) + when(_blePlatform.requestMtuSize(deviceId, mtuSize)) .thenAnswer((_) async => mtuSize); result = await _sut.requestMtu(deviceId, mtuSize); @@ -357,7 +355,7 @@ void main() { group('Given request priority succeeds', () { setUp(() { - when(_controller.requestConnectionPriority(any, any)) + when(_blePlatform.requestConnectionPriority(deviceId, priority)) .thenAnswer((_) async => const ConnectionPriorityInfo( result: Result.success(Unit()), )); @@ -372,7 +370,7 @@ void main() { group('Given request priority fails', () { setUp(() async { - when(_controller.requestConnectionPriority(any, any)) + when(_blePlatform.requestConnectionPriority(deviceId, priority)) .thenAnswer((_) async => const ConnectionPriorityInfo( result: Result.failure( GenericFailure( diff --git a/packages/flutter_reactive_ble/test/connected_device_operation_test.mocks.dart b/packages/flutter_reactive_ble/test/connected_device_operation_test.mocks.dart new file mode 100644 index 00000000..d6ad58d5 --- /dev/null +++ b/packages/flutter_reactive_ble/test/connected_device_operation_test.mocks.dart @@ -0,0 +1,159 @@ +// Mocks generated by Mockito 5.0.14 from annotations +// in flutter_reactive_ble/test/connected_device_operation_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i4; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:reactive_ble_platform_interface/src/models.dart' as _i2; +import 'package:reactive_ble_platform_interface/src/reactive_ble_platform_interface.dart' + as _i3; + +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis + +class _FakeResult_0 extends _i1.Fake + implements _i2.Result {} + +class _FakeWriteCharacteristicInfo_1 extends _i1.Fake + implements _i2.WriteCharacteristicInfo {} + +class _FakeConnectionPriorityInfo_2 extends _i1.Fake + implements _i2.ConnectionPriorityInfo {} + +/// A class which mocks [ReactiveBlePlatform]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockReactiveBlePlatform extends _i1.Mock + implements _i3.ReactiveBlePlatform { + MockReactiveBlePlatform() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.ScanResult> get scanStream => + (super.noSuchMethod(Invocation.getter(#scanStream), + returnValue: Stream<_i2.ScanResult>.empty()) + as _i4.Stream<_i2.ScanResult>); + @override + _i4.Stream<_i2.BleStatus> get bleStatusStream => (super.noSuchMethod( + Invocation.getter(#bleStatusStream), + returnValue: Stream<_i2.BleStatus>.empty()) as _i4.Stream<_i2.BleStatus>); + @override + _i4.Stream<_i2.ConnectionStateUpdate> get connectionUpdateStream => + (super.noSuchMethod(Invocation.getter(#connectionUpdateStream), + returnValue: Stream<_i2.ConnectionStateUpdate>.empty()) + as _i4.Stream<_i2.ConnectionStateUpdate>); + @override + _i4.Stream<_i2.CharacteristicValue> get charValueUpdateStream => + (super.noSuchMethod(Invocation.getter(#charValueUpdateStream), + returnValue: Stream<_i2.CharacteristicValue>.empty()) + as _i4.Stream<_i2.CharacteristicValue>); + @override + _i4.Future initialize() => + (super.noSuchMethod(Invocation.method(#initialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future deinitialize() => + (super.noSuchMethod(Invocation.method(#deinitialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Stream scanForDevices( + {List<_i2.Uuid>? withServices, + _i2.ScanMode? scanMode, + bool? requireLocationServicesEnabled}) => + (super.noSuchMethod( + Invocation.method(#scanForDevices, [], { + #withServices: withServices, + #scanMode: scanMode, + #requireLocationServicesEnabled: requireLocationServicesEnabled + }), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>> + clearGattCache(String? deviceId) => (super.noSuchMethod( + Invocation.method(#clearGattCache, [deviceId]), + returnValue: + Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>.value( + _FakeResult_0<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>())) + as _i4.Future< + _i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>); + @override + _i4.Stream connectToDevice( + String? id, + Map<_i2.Uuid, List<_i2.Uuid>>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout) => + (super.noSuchMethod( + Invocation.method(#connectToDevice, + [id, servicesWithCharacteristicsToDiscover, connectionTimeout]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future disconnectDevice(String? deviceId) => + (super.noSuchMethod(Invocation.method(#disconnectDevice, [deviceId]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future> discoverServices(String? deviceId) => + (super.noSuchMethod(Invocation.method(#discoverServices, [deviceId]), + returnValue: Future>.value( + <_i2.DiscoveredService>[])) + as _i4.Future>); + @override + _i4.Stream readCharacteristic( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#readCharacteristic, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithoutResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithoutResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Stream subscribeToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#subscribeToNotifications, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future stopSubscribingToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#stopSubscribingToNotifications, [characteristic]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future requestMtuSize(String? deviceId, int? mtu) => + (super.noSuchMethod(Invocation.method(#requestMtuSize, [deviceId, mtu]), + returnValue: Future.value(0)) as _i4.Future); + @override + _i4.Future<_i2.ConnectionPriorityInfo> requestConnectionPriority( + String? deviceId, _i2.ConnectionPriority? priority) => + (super.noSuchMethod( + Invocation.method(#requestConnectionPriority, [deviceId, priority]), + returnValue: Future<_i2.ConnectionPriorityInfo>.value( + _FakeConnectionPriorityInfo_2())) as _i4 + .Future<_i2.ConnectionPriorityInfo>); + @override + String toString() => super.toString(); +} diff --git a/test/device_connector_test.dart b/packages/flutter_reactive_ble/test/device_connector_test.dart similarity index 92% rename from test/device_connector_test.dart rename to packages/flutter_reactive_ble/test/device_connector_test.dart index b87ff107..5db00646 100644 --- a/test/device_connector_test.dart +++ b/packages/flutter_reactive_ble/test/device_connector_test.dart @@ -4,20 +4,18 @@ import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:flutter_reactive_ble/src/device_connector.dart'; import 'package:flutter_reactive_ble/src/device_scanner.dart'; import 'package:flutter_reactive_ble/src/discovered_devices_registry.dart'; -import 'package:flutter_reactive_ble/src/model/scan_session.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; import 'device_connector_test.mocks.dart'; -@GenerateMocks( - [DeviceConnectionController, DeviceScanner, DiscoveredDevicesRegistry]) +@GenerateMocks([ReactiveBlePlatform, DeviceScanner, DiscoveredDevicesRegistry]) void main() { group('$DeviceConnector', () { late DeviceConnector _sut; - late MockDeviceConnectionController _controller; + late MockReactiveBlePlatform _blePlatform; late Stream _connectionStateUpdateStream; late Stream _result; late MockDiscoveredDevicesRegistry _registry; @@ -32,16 +30,16 @@ void main() { const _delayAfterFailure = Duration(milliseconds: 10); setUp(() { - _controller = MockDeviceConnectionController(); + _blePlatform = MockReactiveBlePlatform(); _registry = MockDiscoveredDevicesRegistry(); _scanner = MockDeviceScanner(); _servicesToDiscover = { Uuid.parse('FEFE'): [Uuid.parse('FEFE')] }; - when(_controller.connectionUpdateStream) + when(_blePlatform.connectionUpdateStream) .thenAnswer((_) => _connectionStateUpdateStream); - when(_controller.disconnectDevice(any)).thenAnswer((_) async => 0); + when(_blePlatform.disconnectDevice(any)).thenAnswer((_) async => 0); updateForDevice = const ConnectionStateUpdate( deviceId: _deviceId, @@ -55,7 +53,7 @@ void main() { failure: null, ); _sut = DeviceConnectorImpl( - controller: _controller, + blePlatform: _blePlatform, deviceIsDiscoveredRecently: _registry.deviceIsDiscoveredRecently, deviceScanner: _scanner, delayAfterScanFailure: _delayAfterFailure, @@ -73,7 +71,7 @@ void main() { group('And invoking connect method succeeds', () { setUp(() async { - when(_controller.connectToDevice(any, any, any)).thenAnswer( + when(_blePlatform.connectToDevice(any, any, any)).thenAnswer( (_) => Stream.fromIterable([1]), ); _result = _sut.connect( @@ -98,10 +96,10 @@ void main() { final discoveredDevice = DiscoveredDevice( id: 'deviceId', manufacturerData: Uint8List.fromList([0]), + serviceUuids: const [], name: 'test', rssi: -39, serviceData: const {}, - serviceUuids: const [], ); setUp(() { @@ -158,7 +156,7 @@ void main() { deviceId: deviceId, cacheValidity: anyNamed('cacheValidity'))) .thenReturn(true); - when(_controller.connectToDevice(any, any, any)) + when(_blePlatform.connectToDevice(any, any, any)) .thenAnswer((_) => Stream.fromIterable([1])); _result = _sut.connectToAdvertisingDevice( @@ -219,7 +217,7 @@ void main() { deviceId: deviceId, cacheValidity: anyNamed('cacheValidity'))) .thenReturn(true); - when(_controller.connectToDevice(any, any, any)) + when(_blePlatform.connectToDevice(any, any, any)) .thenAnswer((_) => Stream.fromIterable([1])); _result = _sut.connectToAdvertisingDevice( @@ -279,7 +277,7 @@ void main() { cacheValidity: anyNamed('cacheValidity'))) .thenAnswer((_) => responses.removeAt(0)); - when(_controller.connectToDevice(any, any, any)) + when(_blePlatform.connectToDevice(any, any, any)) .thenAnswer((_) => Stream.fromIterable([1])); _result = _sut.connectToAdvertisingDevice( diff --git a/packages/flutter_reactive_ble/test/device_connector_test.mocks.dart b/packages/flutter_reactive_ble/test/device_connector_test.mocks.dart new file mode 100644 index 00000000..a4cac8b8 --- /dev/null +++ b/packages/flutter_reactive_ble/test/device_connector_test.mocks.dart @@ -0,0 +1,224 @@ +// Mocks generated by Mockito 5.0.14 from annotations +// in flutter_reactive_ble/test/device_connector_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i4; + +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart' as _i3; +import 'package:flutter_reactive_ble/src/device_scanner.dart' as _i5; +import 'package:flutter_reactive_ble/src/discovered_devices_registry.dart' + as _i6; +import 'package:mockito/mockito.dart' as _i1; +import 'package:reactive_ble_platform_interface/src/models.dart' as _i2; + +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis + +class _FakeResult_0 extends _i1.Fake + implements _i2.Result {} + +class _FakeWriteCharacteristicInfo_1 extends _i1.Fake + implements _i2.WriteCharacteristicInfo {} + +class _FakeConnectionPriorityInfo_2 extends _i1.Fake + implements _i2.ConnectionPriorityInfo {} + +class _FakeDateTime_3 extends _i1.Fake implements DateTime {} + +/// A class which mocks [ReactiveBlePlatform]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockReactiveBlePlatform extends _i1.Mock + implements _i3.ReactiveBlePlatform { + MockReactiveBlePlatform() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.ScanResult> get scanStream => + (super.noSuchMethod(Invocation.getter(#scanStream), + returnValue: Stream<_i2.ScanResult>.empty()) + as _i4.Stream<_i2.ScanResult>); + @override + _i4.Stream<_i2.BleStatus> get bleStatusStream => (super.noSuchMethod( + Invocation.getter(#bleStatusStream), + returnValue: Stream<_i2.BleStatus>.empty()) as _i4.Stream<_i2.BleStatus>); + @override + _i4.Stream<_i2.ConnectionStateUpdate> get connectionUpdateStream => + (super.noSuchMethod(Invocation.getter(#connectionUpdateStream), + returnValue: Stream<_i2.ConnectionStateUpdate>.empty()) + as _i4.Stream<_i2.ConnectionStateUpdate>); + @override + _i4.Stream<_i2.CharacteristicValue> get charValueUpdateStream => + (super.noSuchMethod(Invocation.getter(#charValueUpdateStream), + returnValue: Stream<_i2.CharacteristicValue>.empty()) + as _i4.Stream<_i2.CharacteristicValue>); + @override + _i4.Future initialize() => + (super.noSuchMethod(Invocation.method(#initialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future deinitialize() => + (super.noSuchMethod(Invocation.method(#deinitialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Stream scanForDevices( + {List<_i2.Uuid>? withServices, + _i2.ScanMode? scanMode, + bool? requireLocationServicesEnabled}) => + (super.noSuchMethod( + Invocation.method(#scanForDevices, [], { + #withServices: withServices, + #scanMode: scanMode, + #requireLocationServicesEnabled: requireLocationServicesEnabled + }), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>> + clearGattCache(String? deviceId) => (super.noSuchMethod( + Invocation.method(#clearGattCache, [deviceId]), + returnValue: + Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>.value( + _FakeResult_0<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>())) + as _i4.Future< + _i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>); + @override + _i4.Stream connectToDevice( + String? id, + Map<_i2.Uuid, List<_i2.Uuid>>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout) => + (super.noSuchMethod( + Invocation.method(#connectToDevice, + [id, servicesWithCharacteristicsToDiscover, connectionTimeout]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future disconnectDevice(String? deviceId) => + (super.noSuchMethod(Invocation.method(#disconnectDevice, [deviceId]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future> discoverServices(String? deviceId) => + (super.noSuchMethod(Invocation.method(#discoverServices, [deviceId]), + returnValue: Future>.value( + <_i2.DiscoveredService>[])) + as _i4.Future>); + @override + _i4.Stream readCharacteristic( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#readCharacteristic, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithoutResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithoutResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Stream subscribeToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#subscribeToNotifications, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future stopSubscribingToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#stopSubscribingToNotifications, [characteristic]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future requestMtuSize(String? deviceId, int? mtu) => + (super.noSuchMethod(Invocation.method(#requestMtuSize, [deviceId, mtu]), + returnValue: Future.value(0)) as _i4.Future); + @override + _i4.Future<_i2.ConnectionPriorityInfo> requestConnectionPriority( + String? deviceId, _i2.ConnectionPriority? priority) => + (super.noSuchMethod( + Invocation.method(#requestConnectionPriority, [deviceId, priority]), + returnValue: Future<_i2.ConnectionPriorityInfo>.value( + _FakeConnectionPriorityInfo_2())) as _i4 + .Future<_i2.ConnectionPriorityInfo>); + @override + String toString() => super.toString(); +} + +/// A class which mocks [DeviceScanner]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockDeviceScanner extends _i1.Mock implements _i5.DeviceScanner { + MockDeviceScanner() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.DiscoveredDevice> scanForDevices( + {List<_i2.Uuid>? withServices, + _i2.ScanMode? scanMode = _i2.ScanMode.balanced, + bool? requireLocationServicesEnabled = true}) => + (super.noSuchMethod( + Invocation.method(#scanForDevices, [], { + #withServices: withServices, + #scanMode: scanMode, + #requireLocationServicesEnabled: requireLocationServicesEnabled + }), + returnValue: Stream<_i2.DiscoveredDevice>.empty()) + as _i4.Stream<_i2.DiscoveredDevice>); + @override + String toString() => super.toString(); +} + +/// A class which mocks [DiscoveredDevicesRegistry]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockDiscoveredDevicesRegistry extends _i1.Mock + implements _i6.DiscoveredDevicesRegistry { + MockDiscoveredDevicesRegistry() { + _i1.throwOnMissingStub(this); + } + + @override + DateTime Function() get getTimestamp => + (super.noSuchMethod(Invocation.getter(#getTimestamp), + returnValue: () => _FakeDateTime_3()) as DateTime Function()); + @override + void add(String? deviceId) => + super.noSuchMethod(Invocation.method(#add, [deviceId]), + returnValueForMissingStub: null); + @override + void remove(String? deviceId) => + super.noSuchMethod(Invocation.method(#remove, [deviceId]), + returnValueForMissingStub: null); + @override + bool isEmpty() => + (super.noSuchMethod(Invocation.method(#isEmpty, []), returnValue: false) + as bool); + @override + bool deviceIsDiscoveredRecently( + {String? deviceId, Duration? cacheValidity}) => + (super.noSuchMethod( + Invocation.method(#deviceIsDiscoveredRecently, [], + {#deviceId: deviceId, #cacheValidity: cacheValidity}), + returnValue: false) as bool); + @override + String toString() => super.toString(); +} diff --git a/test/device_scanner_test.dart b/packages/flutter_reactive_ble/test/device_scanner_test.dart similarity index 84% rename from test/device_scanner_test.dart rename to packages/flutter_reactive_ble/test/device_scanner_test.dart index 1f1baeaf..8f95f86d 100644 --- a/test/device_scanner_test.dart +++ b/packages/flutter_reactive_ble/test/device_scanner_test.dart @@ -1,26 +1,21 @@ import 'dart:async'; import 'dart:typed_data'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:flutter_reactive_ble/src/device_scanner.dart'; -import 'package:flutter_reactive_ble/src/model/discovered_device.dart'; -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; -import 'package:flutter_reactive_ble/src/model/result.dart'; -import 'package:flutter_reactive_ble/src/model/scan_mode.dart'; -import 'package:flutter_reactive_ble/src/model/scan_session.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; import 'device_scanner_test.mocks.dart'; -@GenerateMocks([ScanOperationController]) +@GenerateMocks([ReactiveBlePlatform]) void main() { group('$DeviceScanner', () { DiscoveredDevice? _device1; DiscoveredDevice? _device2; - late MockScanOperationController _controller; + late ReactiveBlePlatform _blePlatform; late Completer _delayAfterScanCompletion; late DeviceScannerImpl _sut; @@ -29,22 +24,22 @@ void main() { _device1 = DiscoveredDevice( id: '123', name: 'Test1', - serviceData: const {}, serviceUuids: const [], + serviceData: const {}, manufacturerData: Uint8List.fromList([1]), rssi: -40, ); _device2 = DiscoveredDevice( id: '456', name: 'Test2', - serviceData: const {}, serviceUuids: const [], + serviceData: const {}, manufacturerData: Uint8List.fromList([0]), rssi: -80, ); _delayAfterScanCompletion = Completer(); - _controller = MockScanOperationController(); + _blePlatform = MockReactiveBlePlatform(); }); group('Scan for devices', () { @@ -59,11 +54,10 @@ void main() { locationEnabled = false; scanmode = ScanMode.lowLatency; - when(_controller.scanForDevices( - withServices: anyNamed('withServices'), - scanMode: anyNamed('scanMode'), - requireLocationServicesEnabled: - anyNamed('requireLocationServicesEnabled'), + when(_blePlatform.scanForDevices( + withServices: withServices, + scanMode: scanmode, + requireLocationServicesEnabled: locationEnabled, )).thenAnswer((_) => Stream.fromIterable([0])); }); @@ -80,14 +74,14 @@ void main() { _device2), ); - when(_controller.scanStream) + when(_blePlatform.scanStream) .thenAnswer((_) => Stream.fromIterable([result1, result2])); }); group('And platform is not Android', () { setUp(() { _sut = DeviceScannerImpl( - controller: _controller, + blePlatform: _blePlatform, platformIsAndroid: () => false, delayAfterScanCompletion: _delayAfterScanCompletion.future, addToScanRegistry: (deviceId) {}, @@ -123,7 +117,7 @@ void main() { group('And platform is android', () { setUp(() { _sut = DeviceScannerImpl( - controller: _controller, + blePlatform: _blePlatform, platformIsAndroid: () => true, delayAfterScanCompletion: _delayAfterScanCompletion.future, addToScanRegistry: (deviceId) {}, @@ -170,11 +164,11 @@ void main() { Stream? scanStream; setUp(() { - when(_controller.scanStream) + when(_blePlatform.scanStream) .thenAnswer((_) => Stream.fromIterable([resultFailure])); _sut = DeviceScannerImpl( - controller: _controller, + blePlatform: _blePlatform, platformIsAndroid: () => false, delayAfterScanCompletion: _delayAfterScanCompletion.future, addToScanRegistry: (deviceId) {}, diff --git a/packages/flutter_reactive_ble/test/device_scanner_test.mocks.dart b/packages/flutter_reactive_ble/test/device_scanner_test.mocks.dart new file mode 100644 index 00000000..93270450 --- /dev/null +++ b/packages/flutter_reactive_ble/test/device_scanner_test.mocks.dart @@ -0,0 +1,159 @@ +// Mocks generated by Mockito 5.0.14 from annotations +// in flutter_reactive_ble/test/device_scanner_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i4; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:reactive_ble_platform_interface/src/models.dart' as _i2; +import 'package:reactive_ble_platform_interface/src/reactive_ble_platform_interface.dart' + as _i3; + +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis + +class _FakeResult_0 extends _i1.Fake + implements _i2.Result {} + +class _FakeWriteCharacteristicInfo_1 extends _i1.Fake + implements _i2.WriteCharacteristicInfo {} + +class _FakeConnectionPriorityInfo_2 extends _i1.Fake + implements _i2.ConnectionPriorityInfo {} + +/// A class which mocks [ReactiveBlePlatform]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockReactiveBlePlatform extends _i1.Mock + implements _i3.ReactiveBlePlatform { + MockReactiveBlePlatform() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.ScanResult> get scanStream => + (super.noSuchMethod(Invocation.getter(#scanStream), + returnValue: Stream<_i2.ScanResult>.empty()) + as _i4.Stream<_i2.ScanResult>); + @override + _i4.Stream<_i2.BleStatus> get bleStatusStream => (super.noSuchMethod( + Invocation.getter(#bleStatusStream), + returnValue: Stream<_i2.BleStatus>.empty()) as _i4.Stream<_i2.BleStatus>); + @override + _i4.Stream<_i2.ConnectionStateUpdate> get connectionUpdateStream => + (super.noSuchMethod(Invocation.getter(#connectionUpdateStream), + returnValue: Stream<_i2.ConnectionStateUpdate>.empty()) + as _i4.Stream<_i2.ConnectionStateUpdate>); + @override + _i4.Stream<_i2.CharacteristicValue> get charValueUpdateStream => + (super.noSuchMethod(Invocation.getter(#charValueUpdateStream), + returnValue: Stream<_i2.CharacteristicValue>.empty()) + as _i4.Stream<_i2.CharacteristicValue>); + @override + _i4.Future initialize() => + (super.noSuchMethod(Invocation.method(#initialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future deinitialize() => + (super.noSuchMethod(Invocation.method(#deinitialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Stream scanForDevices( + {List<_i2.Uuid>? withServices, + _i2.ScanMode? scanMode, + bool? requireLocationServicesEnabled}) => + (super.noSuchMethod( + Invocation.method(#scanForDevices, [], { + #withServices: withServices, + #scanMode: scanMode, + #requireLocationServicesEnabled: requireLocationServicesEnabled + }), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>> + clearGattCache(String? deviceId) => (super.noSuchMethod( + Invocation.method(#clearGattCache, [deviceId]), + returnValue: + Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>.value( + _FakeResult_0<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>())) + as _i4.Future< + _i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>); + @override + _i4.Stream connectToDevice( + String? id, + Map<_i2.Uuid, List<_i2.Uuid>>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout) => + (super.noSuchMethod( + Invocation.method(#connectToDevice, + [id, servicesWithCharacteristicsToDiscover, connectionTimeout]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future disconnectDevice(String? deviceId) => + (super.noSuchMethod(Invocation.method(#disconnectDevice, [deviceId]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future> discoverServices(String? deviceId) => + (super.noSuchMethod(Invocation.method(#discoverServices, [deviceId]), + returnValue: Future>.value( + <_i2.DiscoveredService>[])) + as _i4.Future>); + @override + _i4.Stream readCharacteristic( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#readCharacteristic, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithoutResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithoutResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Stream subscribeToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#subscribeToNotifications, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future stopSubscribingToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#stopSubscribingToNotifications, [characteristic]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future requestMtuSize(String? deviceId, int? mtu) => + (super.noSuchMethod(Invocation.method(#requestMtuSize, [deviceId, mtu]), + returnValue: Future.value(0)) as _i4.Future); + @override + _i4.Future<_i2.ConnectionPriorityInfo> requestConnectionPriority( + String? deviceId, _i2.ConnectionPriority? priority) => + (super.noSuchMethod( + Invocation.method(#requestConnectionPriority, [deviceId, priority]), + returnValue: Future<_i2.ConnectionPriorityInfo>.value( + _FakeConnectionPriorityInfo_2())) as _i4 + .Future<_i2.ConnectionPriorityInfo>); + @override + String toString() => super.toString(); +} diff --git a/test/reactive_ble_test.dart b/packages/flutter_reactive_ble/test/reactive_ble_test.dart similarity index 94% rename from test/reactive_ble_test.dart rename to packages/flutter_reactive_ble/test/reactive_ble_test.dart index 6bfcf2af..67c230f2 100644 --- a/test/reactive_ble_test.dart +++ b/packages/flutter_reactive_ble/test/reactive_ble_test.dart @@ -6,18 +6,16 @@ import 'package:flutter_reactive_ble/src/connected_device_operation.dart'; import 'package:flutter_reactive_ble/src/debug_logger.dart'; import 'package:flutter_reactive_ble/src/device_connector.dart'; import 'package:flutter_reactive_ble/src/device_scanner.dart'; -import 'package:flutter_reactive_ble/src/model/clear_gatt_cache_error.dart'; -import 'package:flutter_reactive_ble/src/model/unit.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; import 'reactive_ble_test.mocks.dart'; @GenerateMocks( [ - BleOperationController, + ReactiveBlePlatform, Logger, ConnectedDeviceOperation, DeviceConnector, @@ -26,7 +24,7 @@ import 'reactive_ble_test.mocks.dart'; ) void main() { group('$FlutterReactiveBle', () { - late MockBleOperationController _bleOperationController; + late ReactiveBlePlatform _blePlatform; late MockDeviceScanner _deviceScanner; late MockDeviceConnector _deviceConnector; late MockConnectedDeviceOperation _deviceOperation; @@ -36,26 +34,26 @@ void main() { late FlutterReactiveBle _sut; setUp(() { - _bleOperationController = MockBleOperationController(); + _blePlatform = MockReactiveBlePlatform(); _deviceScanner = MockDeviceScanner(); _deviceConnector = MockDeviceConnector(); _deviceOperation = MockConnectedDeviceOperation(); _bleStatusController = StreamController(); _debugLogger = MockLogger(); - when(_bleOperationController.initialize()).thenAnswer( + when(_blePlatform.initialize()).thenAnswer( (_) => Future.value(), ); - when(_bleOperationController.deinitialize()).thenAnswer( + when(_blePlatform.deinitialize()).thenAnswer( (_) => Future.value(), ); - when(_bleOperationController.bleStatusStream).thenAnswer( + when(_blePlatform.bleStatusStream).thenAnswer( (realInvocation) => _bleStatusController.stream.asBroadcastStream()); _sut = FlutterReactiveBle.witDependencies( - bleOperationController: _bleOperationController, + reactiveBlePlatform: _blePlatform, deviceScanner: _deviceScanner, deviceConnector: _deviceConnector, connectedDeviceOperation: _deviceOperation, @@ -127,7 +125,7 @@ void main() { group('Deinitialize', () { setUp(() async { - when(_bleOperationController.deinitialize()).thenAnswer((_) async => 1); + when(_blePlatform.deinitialize()).thenAnswer((_) async => 1); await _sut.deinitialize(); }); @@ -362,7 +360,7 @@ void main() { ); setUp(() async { - when(_bleOperationController.clearGattCache(any)) + when(_blePlatform.clearGattCache('123')) .thenAnswer((_) async => result); await _sut.clearGattCache(deviceId); diff --git a/packages/flutter_reactive_ble/test/reactive_ble_test.mocks.dart b/packages/flutter_reactive_ble/test/reactive_ble_test.mocks.dart new file mode 100644 index 00000000..dd8ad483 --- /dev/null +++ b/packages/flutter_reactive_ble/test/reactive_ble_test.mocks.dart @@ -0,0 +1,326 @@ +// Mocks generated by Mockito 5.0.14 from annotations +// in flutter_reactive_ble/test/reactive_ble_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i4; + +import 'package:flutter_reactive_ble/src/connected_device_operation.dart' + as _i6; +import 'package:flutter_reactive_ble/src/debug_logger.dart' as _i5; +import 'package:flutter_reactive_ble/src/device_connector.dart' as _i7; +import 'package:flutter_reactive_ble/src/device_scanner.dart' as _i8; +import 'package:mockito/mockito.dart' as _i1; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart' + as _i3; +import 'package:reactive_ble_platform_interface/src/models.dart' as _i2; + +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis + +class _FakeResult_0 extends _i1.Fake + implements _i2.Result {} + +class _FakeWriteCharacteristicInfo_1 extends _i1.Fake + implements _i2.WriteCharacteristicInfo {} + +class _FakeConnectionPriorityInfo_2 extends _i1.Fake + implements _i2.ConnectionPriorityInfo {} + +/// A class which mocks [ReactiveBlePlatform]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockReactiveBlePlatform extends _i1.Mock + implements _i3.ReactiveBlePlatform { + MockReactiveBlePlatform() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.ScanResult> get scanStream => + (super.noSuchMethod(Invocation.getter(#scanStream), + returnValue: Stream<_i2.ScanResult>.empty()) + as _i4.Stream<_i2.ScanResult>); + @override + _i4.Stream<_i2.BleStatus> get bleStatusStream => (super.noSuchMethod( + Invocation.getter(#bleStatusStream), + returnValue: Stream<_i2.BleStatus>.empty()) as _i4.Stream<_i2.BleStatus>); + @override + _i4.Stream<_i2.ConnectionStateUpdate> get connectionUpdateStream => + (super.noSuchMethod(Invocation.getter(#connectionUpdateStream), + returnValue: Stream<_i2.ConnectionStateUpdate>.empty()) + as _i4.Stream<_i2.ConnectionStateUpdate>); + @override + _i4.Stream<_i2.CharacteristicValue> get charValueUpdateStream => + (super.noSuchMethod(Invocation.getter(#charValueUpdateStream), + returnValue: Stream<_i2.CharacteristicValue>.empty()) + as _i4.Stream<_i2.CharacteristicValue>); + @override + _i4.Future initialize() => + (super.noSuchMethod(Invocation.method(#initialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future deinitialize() => + (super.noSuchMethod(Invocation.method(#deinitialize, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Stream scanForDevices( + {List<_i2.Uuid>? withServices, + _i2.ScanMode? scanMode, + bool? requireLocationServicesEnabled}) => + (super.noSuchMethod( + Invocation.method(#scanForDevices, [], { + #withServices: withServices, + #scanMode: scanMode, + #requireLocationServicesEnabled: requireLocationServicesEnabled + }), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>> + clearGattCache(String? deviceId) => (super.noSuchMethod( + Invocation.method(#clearGattCache, [deviceId]), + returnValue: + Future<_i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>.value( + _FakeResult_0<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>())) + as _i4.Future< + _i2.Result<_i2.Unit, _i2.GenericFailure<_i2.ClearGattCacheError>?>>); + @override + _i4.Stream connectToDevice( + String? id, + Map<_i2.Uuid, List<_i2.Uuid>>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout) => + (super.noSuchMethod( + Invocation.method(#connectToDevice, + [id, servicesWithCharacteristicsToDiscover, connectionTimeout]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future disconnectDevice(String? deviceId) => + (super.noSuchMethod(Invocation.method(#disconnectDevice, [deviceId]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future> discoverServices(String? deviceId) => + (super.noSuchMethod(Invocation.method(#discoverServices, [deviceId]), + returnValue: Future>.value( + <_i2.DiscoveredService>[])) + as _i4.Future>); + @override + _i4.Stream readCharacteristic( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#readCharacteristic, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithoutResponse( + _i2.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #writeCharacteristicWithoutResponse, [characteristic, value]), + returnValue: Future<_i2.WriteCharacteristicInfo>.value( + _FakeWriteCharacteristicInfo_1())) + as _i4.Future<_i2.WriteCharacteristicInfo>); + @override + _i4.Stream subscribeToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#subscribeToNotifications, [characteristic]), + returnValue: Stream.empty()) as _i4.Stream); + @override + _i4.Future stopSubscribingToNotifications( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#stopSubscribingToNotifications, [characteristic]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future requestMtuSize(String? deviceId, int? mtu) => + (super.noSuchMethod(Invocation.method(#requestMtuSize, [deviceId, mtu]), + returnValue: Future.value(0)) as _i4.Future); + @override + _i4.Future<_i2.ConnectionPriorityInfo> requestConnectionPriority( + String? deviceId, _i2.ConnectionPriority? priority) => + (super.noSuchMethod( + Invocation.method(#requestConnectionPriority, [deviceId, priority]), + returnValue: Future<_i2.ConnectionPriorityInfo>.value( + _FakeConnectionPriorityInfo_2())) as _i4 + .Future<_i2.ConnectionPriorityInfo>); + @override + String toString() => super.toString(); +} + +/// A class which mocks [Logger]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockLogger extends _i1.Mock implements _i5.Logger { + MockLogger() { + _i1.throwOnMissingStub(this); + } + + @override + set logLevel(_i2.LogLevel? logLevel) => + super.noSuchMethod(Invocation.setter(#logLevel, logLevel), + returnValueForMissingStub: null); + @override + void log(Object? message) => + super.noSuchMethod(Invocation.method(#log, [message]), + returnValueForMissingStub: null); + @override + String toString() => super.toString(); +} + +/// A class which mocks [ConnectedDeviceOperation]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockConnectedDeviceOperation extends _i1.Mock + implements _i6.ConnectedDeviceOperation { + MockConnectedDeviceOperation() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.CharacteristicValue> get characteristicValueStream => + (super.noSuchMethod(Invocation.getter(#characteristicValueStream), + returnValue: Stream<_i2.CharacteristicValue>.empty()) + as _i4.Stream<_i2.CharacteristicValue>); + @override + _i4.Future> readCharacteristic( + _i2.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#readCharacteristic, [characteristic]), + returnValue: Future>.value([])) + as _i4.Future>); + @override + _i4.Future writeCharacteristicWithResponse( + _i2.QualifiedCharacteristic? characteristic, + {List? value}) => + (super.noSuchMethod( + Invocation.method(#writeCharacteristicWithResponse, [characteristic], + {#value: value}), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Future writeCharacteristicWithoutResponse( + _i2.QualifiedCharacteristic? characteristic, + {List? value}) => + (super.noSuchMethod( + Invocation.method(#writeCharacteristicWithoutResponse, + [characteristic], {#value: value}), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + _i4.Stream> subscribeToCharacteristic( + _i2.QualifiedCharacteristic? characteristic, + _i4.Future? isDisconnected) => + (super.noSuchMethod( + Invocation.method( + #subscribeToCharacteristic, [characteristic, isDisconnected]), + returnValue: Stream>.empty()) as _i4.Stream>); + @override + _i4.Future requestMtu(String? deviceId, int? mtu) => + (super.noSuchMethod(Invocation.method(#requestMtu, [deviceId, mtu]), + returnValue: Future.value(0)) as _i4.Future); + @override + _i4.Future> discoverServices(String? deviceId) => + (super.noSuchMethod(Invocation.method(#discoverServices, [deviceId]), + returnValue: Future>.value( + <_i2.DiscoveredService>[])) + as _i4.Future>); + @override + _i4.Future requestConnectionPriority( + String? deviceId, _i2.ConnectionPriority? priority) => + (super.noSuchMethod( + Invocation.method(#requestConnectionPriority, [deviceId, priority]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); + @override + String toString() => super.toString(); +} + +/// A class which mocks [DeviceConnector]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockDeviceConnector extends _i1.Mock implements _i7.DeviceConnector { + MockDeviceConnector() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.ConnectionStateUpdate> get deviceConnectionStateUpdateStream => + (super.noSuchMethod(Invocation.getter(#deviceConnectionStateUpdateStream), + returnValue: Stream<_i2.ConnectionStateUpdate>.empty()) + as _i4.Stream<_i2.ConnectionStateUpdate>); + @override + _i4.Stream<_i2.ConnectionStateUpdate> connect( + {String? id, + Map<_i2.Uuid, List<_i2.Uuid>>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout}) => + (super.noSuchMethod( + Invocation.method(#connect, [], { + #id: id, + #servicesWithCharacteristicsToDiscover: + servicesWithCharacteristicsToDiscover, + #connectionTimeout: connectionTimeout + }), + returnValue: Stream<_i2.ConnectionStateUpdate>.empty()) + as _i4.Stream<_i2.ConnectionStateUpdate>); + @override + _i4.Stream<_i2.ConnectionStateUpdate> connectToAdvertisingDevice( + {String? id, + List<_i2.Uuid>? withServices, + Duration? prescanDuration, + Map<_i2.Uuid, List<_i2.Uuid>>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout}) => + (super.noSuchMethod( + Invocation.method(#connectToAdvertisingDevice, [], { + #id: id, + #withServices: withServices, + #prescanDuration: prescanDuration, + #servicesWithCharacteristicsToDiscover: + servicesWithCharacteristicsToDiscover, + #connectionTimeout: connectionTimeout + }), + returnValue: Stream<_i2.ConnectionStateUpdate>.empty()) + as _i4.Stream<_i2.ConnectionStateUpdate>); + @override + String toString() => super.toString(); +} + +/// A class which mocks [DeviceScanner]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockDeviceScanner extends _i1.Mock implements _i8.DeviceScanner { + MockDeviceScanner() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Stream<_i2.DiscoveredDevice> scanForDevices( + {List<_i2.Uuid>? withServices, + _i2.ScanMode? scanMode = _i2.ScanMode.balanced, + bool? requireLocationServicesEnabled = true}) => + (super.noSuchMethod( + Invocation.method(#scanForDevices, [], { + #withServices: withServices, + #scanMode: scanMode, + #requireLocationServicesEnabled: requireLocationServicesEnabled + }), + returnValue: Stream<_i2.DiscoveredDevice>.empty()) + as _i4.Stream<_i2.DiscoveredDevice>); + @override + String toString() => super.toString(); +} diff --git a/test/rx_ext/serial_disposable_test.dart b/packages/flutter_reactive_ble/test/rx_ext/serial_disposable_test.dart similarity index 96% rename from test/rx_ext/serial_disposable_test.dart rename to packages/flutter_reactive_ble/test/rx_ext/serial_disposable_test.dart index 7af5511a..ad9b18a0 100644 --- a/test/rx_ext/serial_disposable_test.dart +++ b/packages/flutter_reactive_ble/test/rx_ext/serial_disposable_test.dart @@ -1,5 +1,4 @@ import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/model/unit.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { diff --git a/example/.metadata b/packages/reactive_ble_mobile/.metadata similarity index 70% rename from example/.metadata rename to packages/reactive_ble_mobile/.metadata index 374cb22a..a26551c5 100644 --- a/example/.metadata +++ b/packages/reactive_ble_mobile/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: d8cbb80206db06d151206f8b599b7dde5a386a2d - channel: beta + revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 + channel: stable -project_type: app +project_type: plugin diff --git a/packages/reactive_ble_mobile/CHANGELOG.md b/packages/reactive_ble_mobile/CHANGELOG.md new file mode 100644 index 00000000..fb6c0d5a --- /dev/null +++ b/packages/reactive_ble_mobile/CHANGELOG.md @@ -0,0 +1,4 @@ +## 4.0.0 + +* Initial Open Source release. + diff --git a/packages/reactive_ble_mobile/LICENSE b/packages/reactive_ble_mobile/LICENSE new file mode 100644 index 00000000..1b0489a1 --- /dev/null +++ b/packages/reactive_ble_mobile/LICENSE @@ -0,0 +1,24 @@ +BSD license + +©2019 Signify Holding. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions +and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/packages/reactive_ble_mobile/README.md b/packages/reactive_ble_mobile/README.md new file mode 100644 index 00000000..a6ddd3a0 --- /dev/null +++ b/packages/reactive_ble_mobile/README.md @@ -0,0 +1,3 @@ +# Reactive_ble_mobile + +Official Android and iOS implementation for the flutter_reactive_ble plugin. diff --git a/android/build.gradle b/packages/reactive_ble_mobile/android/build.gradle similarity index 98% rename from android/build.gradle rename to packages/reactive_ble_mobile/android/build.gradle index a53301d6..cafd47c0 100644 --- a/android/build.gradle +++ b/packages/reactive_ble_mobile/android/build.gradle @@ -44,7 +44,7 @@ android { test.java.srcDirs += 'src/test/kotlin' main { proto { - srcDir '../protos' + srcDir '../protos/' } } } diff --git a/android/gradle.properties b/packages/reactive_ble_mobile/android/gradle.properties similarity index 100% rename from android/gradle.properties rename to packages/reactive_ble_mobile/android/gradle.properties diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/packages/reactive_ble_mobile/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from android/gradle/wrapper/gradle-wrapper.properties rename to packages/reactive_ble_mobile/android/gradle/wrapper/gradle-wrapper.properties diff --git a/android/proguard-rules.txt b/packages/reactive_ble_mobile/android/proguard-rules.txt similarity index 100% rename from android/proguard-rules.txt rename to packages/reactive_ble_mobile/android/proguard-rules.txt diff --git a/android/settings.gradle b/packages/reactive_ble_mobile/android/settings.gradle similarity index 100% rename from android/settings.gradle rename to packages/reactive_ble_mobile/android/settings.gradle diff --git a/android/src/main/AndroidManifest.xml b/packages/reactive_ble_mobile/android/src/main/AndroidManifest.xml similarity index 100% rename from android/src/main/AndroidManifest.xml rename to packages/reactive_ble_mobile/android/src/main/AndroidManifest.xml diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/PluginController.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/PluginController.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/ReactiveBlePlugin.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ReactiveBlePlugin.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleClient.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleClient.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleWrapper.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/BleWrapper.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ConnectionQueue.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ConnectionQueue.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnector.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnector.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClient.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClient.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/extensions/RxBleConnectionExtension.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/ble/extensions/RxBleConnectionExtension.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/BleStatusHandler.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/BleStatusHandler.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/CharNotificationHandler.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/CharNotificationHandler.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/DeviceConnectionHandler.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/DeviceConnectionHandler.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ScanDevicesHandler.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ScanDevicesHandler.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ManufacturerDataConverter.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ManufacturerDataConverter.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ManufacturerDataConverter.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ManufacturerDataConverter.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverter.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverter.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverter.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverter.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/HexStringConversion.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/HexStringConversion.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/HexStringConversion.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/HexStringConversion.kt diff --git a/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 similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/PerformanceAnalyzer.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/debugutils/PerformanceAnalyzer.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ConnectionState.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ConnectionState.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ConnectionState.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ConnectionState.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ErrorType.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ErrorType.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ErrorType.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ErrorType.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ScanMode.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ScanMode.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ScanMode.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/model/ScanMode.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/BleWrapperExtensions.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/BleWrapperExtensions.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/BleWrapperExtensions.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/BleWrapperExtensions.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Discard.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Discard.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Discard.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Discard.kt diff --git a/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Duration.kt b/packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Duration.kt similarity index 100% rename from android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Duration.kt rename to packages/reactive_ble_mobile/android/src/main/kotlin/com/signify/hue/flutterreactiveble/utils/Duration.kt diff --git a/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 similarity index 100% rename from android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnectorTest.kt rename to packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/DeviceConnectorTest.kt diff --git a/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 similarity index 100% rename from android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClientTest.kt rename to packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/ble/ReactiveBleClientTest.kt diff --git a/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 similarity index 100% rename from android/src/test/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ConnectionQueueTest.kt rename to packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/channelhandlers/ConnectionQueueTest.kt diff --git a/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 similarity index 100% rename from android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverterTest.kt rename to packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ProtobufMessageConverterTest.kt diff --git a/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 similarity index 100% rename from android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ServicesWithCharacteristicsConverterTest.kt rename to packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/ServicesWithCharacteristicsConverterTest.kt diff --git a/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 similarity index 100% rename from android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverterTest.kt rename to packages/reactive_ble_mobile/android/src/test/kotlin/com/signify/hue/flutterreactiveble/converters/UuidConverterTest.kt diff --git a/ios/.gitignore b/packages/reactive_ble_mobile/ios/.gitignore similarity index 100% rename from ios/.gitignore rename to packages/reactive_ble_mobile/ios/.gitignore diff --git a/ios/Assets/.gitkeep b/packages/reactive_ble_mobile/ios/Assets/.gitkeep similarity index 100% rename from ios/Assets/.gitkeep rename to packages/reactive_ble_mobile/ios/Assets/.gitkeep diff --git a/ios/Classes/BleData extras/BLEStatus.swift b/packages/reactive_ble_mobile/ios/Classes/BleData extras/BLEStatus.swift similarity index 100% rename from ios/Classes/BleData extras/BLEStatus.swift rename to packages/reactive_ble_mobile/ios/Classes/BleData extras/BLEStatus.swift diff --git a/ios/Classes/BleData extras/ConnectionState.swift b/packages/reactive_ble_mobile/ios/Classes/BleData extras/ConnectionState.swift similarity index 100% rename from ios/Classes/BleData extras/ConnectionState.swift rename to packages/reactive_ble_mobile/ios/Classes/BleData extras/ConnectionState.swift diff --git a/ios/Classes/BleData extras/FailureCodes.swift b/packages/reactive_ble_mobile/ios/Classes/BleData extras/FailureCodes.swift similarity index 100% rename from ios/Classes/BleData extras/FailureCodes.swift rename to packages/reactive_ble_mobile/ios/Classes/BleData extras/FailureCodes.swift diff --git a/ios/Classes/BleData extras/QualifiedCharacteristic.swift b/packages/reactive_ble_mobile/ios/Classes/BleData extras/QualifiedCharacteristic.swift similarity index 100% rename from ios/Classes/BleData extras/QualifiedCharacteristic.swift rename to packages/reactive_ble_mobile/ios/Classes/BleData extras/QualifiedCharacteristic.swift diff --git a/ios/Classes/BleData/bledata.pb.swift b/packages/reactive_ble_mobile/ios/Classes/BleData/bledata.pb.swift similarity index 100% rename from ios/Classes/BleData/bledata.pb.swift rename to packages/reactive_ble_mobile/ios/Classes/BleData/bledata.pb.swift diff --git a/ios/Classes/Plugin/Common/EventSink.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/Common/EventSink.swift similarity index 100% rename from ios/Classes/Plugin/Common/EventSink.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/Common/EventSink.swift diff --git a/ios/Classes/Plugin/Common/Failable.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/Common/Failable.swift similarity index 100% rename from ios/Classes/Plugin/Common/Failable.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/Common/Failable.swift diff --git a/ios/Classes/Plugin/Common/MethodHandler.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/Common/MethodHandler.swift similarity index 100% rename from ios/Classes/Plugin/Common/MethodHandler.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/Common/MethodHandler.swift diff --git a/ios/Classes/Plugin/Common/PlatformMethod.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/Common/PlatformMethod.swift similarity index 100% rename from ios/Classes/Plugin/Common/PlatformMethod.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/Common/PlatformMethod.swift diff --git a/ios/Classes/Plugin/Common/StreamHandler.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/Common/StreamHandler.swift similarity index 100% rename from ios/Classes/Plugin/Common/StreamHandler.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/Common/StreamHandler.swift diff --git a/ios/Classes/Plugin/PluginController.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/PluginController.swift similarity index 100% rename from ios/Classes/Plugin/PluginController.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/PluginController.swift diff --git a/ios/Classes/Plugin/PluginError.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/PluginError.swift similarity index 100% rename from ios/Classes/Plugin/PluginError.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/PluginError.swift diff --git a/ios/Classes/Plugin/StreamingTask.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/StreamingTask.swift similarity index 100% rename from ios/Classes/Plugin/StreamingTask.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/StreamingTask.swift diff --git a/ios/Classes/Plugin/SwiftReactiveBlePlugin.swift b/packages/reactive_ble_mobile/ios/Classes/Plugin/SwiftReactiveBlePlugin.swift similarity index 100% rename from ios/Classes/Plugin/SwiftReactiveBlePlugin.swift rename to packages/reactive_ble_mobile/ios/Classes/Plugin/SwiftReactiveBlePlugin.swift diff --git a/ios/Classes/Prelude/base.swift b/packages/reactive_ble_mobile/ios/Classes/Prelude/base.swift similarity index 100% rename from ios/Classes/Prelude/base.swift rename to packages/reactive_ble_mobile/ios/Classes/Prelude/base.swift diff --git a/ios/Classes/Prelude/papply.swift b/packages/reactive_ble_mobile/ios/Classes/Prelude/papply.swift similarity index 100% rename from ios/Classes/Prelude/papply.swift rename to packages/reactive_ble_mobile/ios/Classes/Prelude/papply.swift diff --git a/ios/Classes/ReactiveBle/Central.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Central.swift similarity index 100% rename from ios/Classes/ReactiveBle/Central.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Central.swift diff --git a/ios/Classes/ReactiveBle/CentralManagerDelegate.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/CentralManagerDelegate.swift similarity index 100% rename from ios/Classes/ReactiveBle/CentralManagerDelegate.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/CentralManagerDelegate.swift diff --git a/ios/Classes/ReactiveBle/OnOff.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/OnOff.swift similarity index 100% rename from ios/Classes/ReactiveBle/OnOff.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/OnOff.swift diff --git a/ios/Classes/ReactiveBle/PeripheralDelegate.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/PeripheralDelegate.swift similarity index 100% rename from ios/Classes/ReactiveBle/PeripheralDelegate.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/PeripheralDelegate.swift diff --git a/ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskController.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskController.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskController.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskController.swift diff --git a/ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskSpec.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskSpec.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskSpec.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicNotify/CharacteristicNotifyTaskSpec.swift diff --git a/ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskController.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskController.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskController.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskController.swift diff --git a/ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskSpec.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskSpec.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskSpec.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/CharacteristicWrite/CharacteristicWriteTaskSpec.swift diff --git a/ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskController.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskController.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskController.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskController.swift diff --git a/ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskSpec.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskSpec.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskSpec.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/Connect/ConnectTaskSpec.swift diff --git a/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTask.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTask.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTask.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTask.swift diff --git a/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskController.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskController.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskController.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskController.swift diff --git a/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskRegistry.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskRegistry.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskRegistry.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/PeripheralTaskRegistry/PeripheralTaskRegistry.swift diff --git a/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskController.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskController.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskController.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskController.swift diff --git a/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskSpec.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskSpec.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskSpec.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsDiscoveryTaskSpec.swift diff --git a/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsToDiscover.swift b/packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsToDiscover.swift similarity index 100% rename from ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsToDiscover.swift rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBle/Tasks/ServicesWithCharacteristicsDiscovery/ServicesWithCharacteristicsToDiscover.swift diff --git a/ios/Classes/ReactiveBlePlugin.h b/packages/reactive_ble_mobile/ios/Classes/ReactiveBlePlugin.h similarity index 100% rename from ios/Classes/ReactiveBlePlugin.h rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBlePlugin.h diff --git a/ios/Classes/ReactiveBlePlugin.m b/packages/reactive_ble_mobile/ios/Classes/ReactiveBlePlugin.m similarity index 77% rename from ios/Classes/ReactiveBlePlugin.m rename to packages/reactive_ble_mobile/ios/Classes/ReactiveBlePlugin.m index 64cb3a0f..53c57d24 100644 --- a/ios/Classes/ReactiveBlePlugin.m +++ b/packages/reactive_ble_mobile/ios/Classes/ReactiveBlePlugin.m @@ -1,5 +1,5 @@ #import "ReactiveBlePlugin.h" -#import +#import @implementation ReactiveBlePlugin + (void)registerWithRegistrar:(NSObject*)registrar { diff --git a/ios/flutter_reactive_ble.podspec b/packages/reactive_ble_mobile/ios/reactive_ble_mobile.podspec similarity index 94% rename from ios/flutter_reactive_ble.podspec rename to packages/reactive_ble_mobile/ios/reactive_ble_mobile.podspec index abacd0eb..8d754343 100644 --- a/ios/flutter_reactive_ble.podspec +++ b/packages/reactive_ble_mobile/ios/reactive_ble_mobile.podspec @@ -1,5 +1,5 @@ Pod::Spec.new do |s| - s.name = 'flutter_reactive_ble' + s.name = 'reactive_ble_mobile' s.version = '0.0.1' s.summary = 'Bluetooth Low Energy (BLE) Flutter plug-in' s.description = <<-DESC diff --git a/packages/reactive_ble_mobile/lib/reactive_ble_mobile.dart b/packages/reactive_ble_mobile/lib/reactive_ble_mobile.dart new file mode 100644 index 00000000..2b400d91 --- /dev/null +++ b/packages/reactive_ble_mobile/lib/reactive_ble_mobile.dart @@ -0,0 +1,3 @@ +library reactive_ble_mobile; + +export 'src/reactive_ble_mobile_platform.dart'; diff --git a/lib/src/converter/args_to_protubuf_converter.dart b/packages/reactive_ble_mobile/lib/src/converter/args_to_protubuf_converter.dart similarity index 96% rename from lib/src/converter/args_to_protubuf_converter.dart rename to packages/reactive_ble_mobile/lib/src/converter/args_to_protubuf_converter.dart index 7fcaf5fc..692c8d61 100644 --- a/lib/src/converter/args_to_protubuf_converter.dart +++ b/packages/reactive_ble_mobile/lib/src/converter/args_to_protubuf_converter.dart @@ -1,6 +1,6 @@ -import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/generated/bledata.pb.dart' as pb; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; + +import '../generated/bledata.pb.dart' as pb; abstract class ArgsToProtobufConverter { pb.ConnectToDeviceRequest createConnectToDeviceArgs( diff --git a/lib/src/converter/protobuf_converter.dart b/packages/reactive_ble_mobile/lib/src/converter/protobuf_converter.dart similarity index 86% rename from lib/src/converter/protobuf_converter.dart rename to packages/reactive_ble_mobile/lib/src/converter/protobuf_converter.dart index 57574356..d7b4a9f9 100644 --- a/lib/src/converter/protobuf_converter.dart +++ b/packages/reactive_ble_mobile/lib/src/converter/protobuf_converter.dart @@ -1,21 +1,10 @@ import 'dart:typed_data'; import 'package:flutter/foundation.dart'; -import 'package:flutter_reactive_ble/src/generated/bledata.pb.dart' as pb; -import 'package:flutter_reactive_ble/src/model/ble_status.dart'; -import 'package:flutter_reactive_ble/src/model/characteristic_value.dart'; -import 'package:flutter_reactive_ble/src/model/clear_gatt_cache_error.dart'; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart'; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart'; -import 'package:flutter_reactive_ble/src/model/discovered_device.dart'; -import 'package:flutter_reactive_ble/src/model/discovered_service.dart'; -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart'; -import 'package:flutter_reactive_ble/src/model/result.dart'; -import 'package:flutter_reactive_ble/src/model/unit.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; -import 'package:flutter_reactive_ble/src/model/write_characteristic_info.dart'; -import 'package:flutter_reactive_ble/src/select_from.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; + +import '../generated/bledata.pb.dart' as pb; +import '../select_from.dart'; abstract class ProtobufConverter { BleStatus bleStatusFrom(List data); @@ -60,6 +49,7 @@ class ProtobufConverterImpl implements ProtobufConverter { message.serviceData.map((entry) => Uuid(entry.serviceUuid.data)), message.serviceData.map((entry) => Uint8List.fromList(entry.data)), ); + final serviceUuids = message.serviceUuids .map((entry) => Uuid(entry.data)) .toList(growable: false); diff --git a/lib/src/generated/bledata.pb.dart b/packages/reactive_ble_mobile/lib/src/generated/bledata.pb.dart similarity index 100% rename from lib/src/generated/bledata.pb.dart rename to packages/reactive_ble_mobile/lib/src/generated/bledata.pb.dart diff --git a/packages/reactive_ble_mobile/lib/src/reactive_ble_mobile_platform.dart b/packages/reactive_ble_mobile/lib/src/reactive_ble_mobile_platform.dart new file mode 100644 index 00000000..4e79a0ca --- /dev/null +++ b/packages/reactive_ble_mobile/lib/src/reactive_ble_mobile_platform.dart @@ -0,0 +1,259 @@ +import 'package:flutter/services.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; +import 'converter/args_to_protubuf_converter.dart'; +import 'converter/protobuf_converter.dart'; + +class ReactiveBleMobilePlatform extends ReactiveBlePlatform { + ReactiveBleMobilePlatform({ + required ArgsToProtobufConverter argsToProtobufConverter, + required ProtobufConverter protobufConverter, + required MethodChannel bleMethodChannel, + required Stream> connectedDeviceChannel, + required Stream> charUpdateChannel, + required Stream> bleDeviceScanChannel, + required Stream> bleStatusChannel, + }) : _argsToProtobufConverter = argsToProtobufConverter, + _protobufConverter = protobufConverter, + _bleMethodChannel = bleMethodChannel, + _connectedDeviceRawStream = connectedDeviceChannel, + _charUpdateRawStream = charUpdateChannel, + _bleStatusRawChannel = bleStatusChannel, + _bleDeviceScanRawStream = bleDeviceScanChannel; + + final ArgsToProtobufConverter _argsToProtobufConverter; + final ProtobufConverter _protobufConverter; + final MethodChannel _bleMethodChannel; + final Stream> _connectedDeviceRawStream; + final Stream> _charUpdateRawStream; + final Stream> _bleDeviceScanRawStream; + final Stream> _bleStatusRawChannel; + + Stream? _connectionUpdateStream; + Stream? _charValueStream; + Stream? _scanResultStream; + Stream? _bleStatusStream; + + @override + Stream get connectionUpdateStream => + _connectionUpdateStream ??= _connectedDeviceRawStream + .map(_protobufConverter.connectionStateUpdateFrom) + .map( + (update) => update, + ); + + @override + Stream get charValueUpdateStream => _charValueStream ??= + _charUpdateRawStream.map(_protobufConverter.characteristicValueFrom).map( + (update) => update, + ); + + @override + Stream get scanStream => _scanResultStream ??= + _bleDeviceScanRawStream.map(_protobufConverter.scanResultFrom).map( + (scanResult) => scanResult, + ); + + @override + Stream get bleStatusStream => + _bleStatusStream ??= _bleStatusRawChannel + .map(_protobufConverter.bleStatusFrom) + .map((status) => status); + + @override + Future initialize() => _bleMethodChannel.invokeMethod("initialize"); + + @override + Future deinitialize() => + _bleMethodChannel.invokeMethod("deinitialize"); + + @override + Stream scanForDevices({ + required List withServices, + required ScanMode scanMode, + required bool requireLocationServicesEnabled, + }) => + _bleMethodChannel + .invokeMethod( + "scanForDevices", + _argsToProtobufConverter + .createScanForDevicesRequest( + withServices: withServices, + scanMode: scanMode, + requireLocationServicesEnabled: + requireLocationServicesEnabled, + ) + .writeToBuffer(), + ) + .asStream(); + + @override + Stream connectToDevice( + String id, + Map>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout, + ) => + _bleMethodChannel + .invokeMethod( + "connectToDevice", + _argsToProtobufConverter + .createConnectToDeviceArgs( + id, + servicesWithCharacteristicsToDiscover, + connectionTimeout, + ) + .writeToBuffer(), + ) + .asStream(); + + @override + Future disconnectDevice(String deviceId) => + _bleMethodChannel.invokeMethod( + "disconnectFromDevice", + _argsToProtobufConverter + .createDisconnectDeviceArgs(deviceId) + .writeToBuffer(), + ); + + @override + Stream readCharacteristic(QualifiedCharacteristic characteristic) => + _bleMethodChannel + .invokeMethod( + "readCharacteristic", + _argsToProtobufConverter + .createReadCharacteristicRequest(characteristic) + .writeToBuffer(), + ) + .asStream(); + + @override + Future writeCharacteristicWithResponse( + QualifiedCharacteristic characteristic, + List value, + ) async => + _bleMethodChannel + .invokeMethod>( + "writeCharacteristicWithResponse", + _argsToProtobufConverter + .createWriteChacracteristicRequest(characteristic, value) + .writeToBuffer()) + .then( + (data) => _protobufConverter.writeCharacteristicInfoFrom(data!)); + + @override + Future writeCharacteristicWithoutResponse( + QualifiedCharacteristic characteristic, + List value, + ) async => + _bleMethodChannel + .invokeMethod>( + "writeCharacteristicWithoutResponse", + _argsToProtobufConverter + .createWriteChacracteristicRequest(characteristic, value) + .writeToBuffer(), + ) + .then( + (data) => _protobufConverter.writeCharacteristicInfoFrom(data!)); + + @override + Stream subscribeToNotifications( + QualifiedCharacteristic characteristic, + ) => + _bleMethodChannel + .invokeMethod( + "readNotifications", + _argsToProtobufConverter + .createNotifyCharacteristicRequest(characteristic) + .writeToBuffer(), + ) + .asStream(); + + @override + Future stopSubscribingToNotifications( + QualifiedCharacteristic characteristic, + ) => + _bleMethodChannel + .invokeMethod( + "stopNotifications", + _argsToProtobufConverter + .createNotifyNoMoreCharacteristicRequest(characteristic) + .writeToBuffer(), + ) + .catchError( + // ignore: avoid_print + (Object e) => print("Error unsubscribing from notifications: $e"), + ); + + @override + Future requestMtuSize(String deviceId, int? mtu) async => + _bleMethodChannel + .invokeMethod>( + "negotiateMtuSize", + _argsToProtobufConverter + .createNegotiateMtuRequest(deviceId, mtu!) + .writeToBuffer(), + ) + .then((data) => _protobufConverter.mtuSizeFrom(data!)); + + @override + Future requestConnectionPriority( + String deviceId, ConnectionPriority priority) => + _bleMethodChannel + .invokeMethod>( + "requestConnectionPriority", + _argsToProtobufConverter + .createChangeConnectionPrioRequest(deviceId, priority) + .writeToBuffer(), + ) + .then((data) => _protobufConverter.connectionPriorityInfoFrom(data!)); + + @override + Future?>> clearGattCache( + String deviceId) => + _bleMethodChannel + .invokeMethod>( + "clearGattCache", + _argsToProtobufConverter + .createClearGattCacheRequest(deviceId) + .writeToBuffer(), + ) + .then((data) => _protobufConverter.clearGattCacheResultFrom(data!)); + + @override + Future> discoverServices(String deviceId) async => + _bleMethodChannel + .invokeMethod>( + 'discoverServices', + _argsToProtobufConverter + .createDiscoverServicesRequest(deviceId) + .writeToBuffer(), + ) + .then((data) => _protobufConverter.discoveredServicesFrom(data!)); +} + +class ReactiveBleMobilePlatformFactory { + const ReactiveBleMobilePlatformFactory(); + + ReactiveBleMobilePlatform create() { + const _bleMethodChannel = MethodChannel("flutter_reactive_ble_method"); + + const connectedDeviceChannel = + EventChannel("flutter_reactive_ble_connected_device"); + const charEventChannel = EventChannel("flutter_reactive_ble_char_update"); + const scanEventChannel = EventChannel("flutter_reactive_ble_scan"); + const bleStatusChannel = EventChannel("flutter_reactive_ble_status"); + + return ReactiveBleMobilePlatform( + protobufConverter: const ProtobufConverterImpl(), + argsToProtobufConverter: const ArgsToProtobufConverterImpl(), + bleMethodChannel: _bleMethodChannel, + connectedDeviceChannel: + connectedDeviceChannel.receiveBroadcastStream().cast>(), + charUpdateChannel: + charEventChannel.receiveBroadcastStream().cast>(), + bleDeviceScanChannel: + scanEventChannel.receiveBroadcastStream().cast>(), + bleStatusChannel: + bleStatusChannel.receiveBroadcastStream().cast>(), + ); + } +} diff --git a/lib/src/select_from.dart b/packages/reactive_ble_mobile/lib/src/select_from.dart similarity index 100% rename from lib/src/select_from.dart rename to packages/reactive_ble_mobile/lib/src/select_from.dart diff --git a/protos/README.md b/packages/reactive_ble_mobile/protos/README.md similarity index 100% rename from protos/README.md rename to packages/reactive_ble_mobile/protos/README.md diff --git a/protos/bledata.proto b/packages/reactive_ble_mobile/protos/bledata.proto similarity index 100% rename from protos/bledata.proto rename to packages/reactive_ble_mobile/protos/bledata.proto index f7e99da7..ecf76dc7 100644 --- a/protos/bledata.proto +++ b/packages/reactive_ble_mobile/protos/bledata.proto @@ -13,8 +13,8 @@ message DeviceScanInfo { string name = 2; GenericFailure failure = 3; repeated ServiceDataEntry serviceData = 4; - repeated Uuid serviceUuids = 7; bytes manufacturerData = 6; + repeated Uuid serviceUuids = 7; int32 rssi = 5; } diff --git a/packages/reactive_ble_mobile/pubspec.lock b/packages/reactive_ble_mobile/pubspec.lock new file mode 100644 index 00000000..970251ac --- /dev/null +++ b/packages/reactive_ble_mobile/pubspec.lock @@ -0,0 +1,476 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "22.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.1" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.1.0" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.1.2" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.3" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + functional_data: + dependency: transitive + description: + name: functional_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.10" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + mockito: + dependency: "direct dev" + description: + name: mockito + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.14" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + protobuf: + dependency: "direct main" + description: + name: protobuf + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + reactive_ble_platform_interface: + dependency: "direct main" + description: + name: reactive_ble_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" +sdks: + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/reactive_ble_mobile/pubspec.yaml b/packages/reactive_ble_mobile/pubspec.yaml new file mode 100644 index 00000000..d61a8c64 --- /dev/null +++ b/packages/reactive_ble_mobile/pubspec.yaml @@ -0,0 +1,29 @@ +name: reactive_ble_mobile +description: Official Android and iOS implementation for the flutter_reactive_ble plugin. +version: 4.0.0 +homepage: https://github.com/PhilipsHue/flutter_reactive_ble + +environment: + sdk: ">=2.12.0 <3.0.0" + flutter: ">=1.20.0" + +dependencies: + flutter: + sdk: flutter + protobuf: ^2.0.0 + reactive_ble_platform_interface: ^4.0.0 + +dev_dependencies: + build_runner: ^2.1.1 + flutter_test: + sdk: flutter + mockito: ^5.0.14 + +flutter: + plugin: + platforms: + android: + package: com.signify.hue.flutterreactiveble + pluginClass: ReactiveBlePlugin + ios: + pluginClass: ReactiveBlePlugin diff --git a/test/converter/args_to_protobuf_converter_test.dart b/packages/reactive_ble_mobile/test/converter/args_to_protobuf_converter_test.dart similarity index 95% rename from test/converter/args_to_protobuf_converter_test.dart rename to packages/reactive_ble_mobile/test/converter/args_to_protobuf_converter_test.dart index 7fe1928a..0e2810eb 100644 --- a/test/converter/args_to_protobuf_converter_test.dart +++ b/packages/reactive_ble_mobile/test/converter/args_to_protobuf_converter_test.dart @@ -1,10 +1,10 @@ -import 'package:flutter_reactive_ble/src/converter/args_to_protubuf_converter.dart'; -import 'package:flutter_reactive_ble/src/generated/bledata.pb.dart' as pb; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart'; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart'; -import 'package:flutter_reactive_ble/src/model/scan_mode.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; +import 'package:reactive_ble_mobile/src/converter/args_to_protubuf_converter.dart'; +import 'package:reactive_ble_mobile/src/generated/bledata.pb.dart' as pb; import 'package:flutter_test/flutter_test.dart'; +import 'package:reactive_ble_platform_interface/src/model/connection_priority.dart'; +import 'package:reactive_ble_platform_interface/src/model/qualified_characteristic.dart'; +import 'package:reactive_ble_platform_interface/src/model/scan_mode.dart'; +import 'package:reactive_ble_platform_interface/src/model/uuid.dart'; void main() { group('$ArgsToProtobufConverter', () { diff --git a/test/converter/protobuf_converter_test.dart b/packages/reactive_ble_mobile/test/converter/protobuf_converter_test.dart similarity index 93% rename from test/converter/protobuf_converter_test.dart rename to packages/reactive_ble_mobile/test/converter/protobuf_converter_test.dart index 136e93cd..d6f271d0 100644 --- a/test/converter/protobuf_converter_test.dart +++ b/packages/reactive_ble_mobile/test/converter/protobuf_converter_test.dart @@ -1,20 +1,20 @@ import 'dart:typed_data'; -import 'package:flutter_reactive_ble/src/converter/protobuf_converter.dart'; -import 'package:flutter_reactive_ble/src/generated/bledata.pb.dart' as pb; -import 'package:flutter_reactive_ble/src/model/ble_status.dart'; -import 'package:flutter_reactive_ble/src/model/characteristic_value.dart'; -import 'package:flutter_reactive_ble/src/model/clear_gatt_cache_error.dart'; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart'; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart'; -import 'package:flutter_reactive_ble/src/model/discovered_device.dart'; -import 'package:flutter_reactive_ble/src/model/discovered_service.dart'; -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; -import 'package:flutter_reactive_ble/src/model/result.dart'; -import 'package:flutter_reactive_ble/src/model/unit.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; -import 'package:flutter_reactive_ble/src/model/write_characteristic_info.dart'; +import 'package:reactive_ble_mobile/src/converter/protobuf_converter.dart'; +import 'package:reactive_ble_mobile/src/generated/bledata.pb.dart' as pb; import 'package:flutter_test/flutter_test.dart'; +import 'package:reactive_ble_platform_interface/src/model/ble_status.dart'; +import 'package:reactive_ble_platform_interface/src/model/characteristic_value.dart'; +import 'package:reactive_ble_platform_interface/src/model/clear_gatt_cache_error.dart'; +import 'package:reactive_ble_platform_interface/src/model/connection_priority.dart'; +import 'package:reactive_ble_platform_interface/src/model/connection_state_update.dart'; +import 'package:reactive_ble_platform_interface/src/model/discovered_device.dart'; +import 'package:reactive_ble_platform_interface/src/model/discovered_service.dart'; +import 'package:reactive_ble_platform_interface/src/model/generic_failure.dart'; +import 'package:reactive_ble_platform_interface/src/model/result.dart'; +import 'package:reactive_ble_platform_interface/src/model/unit.dart'; +import 'package:reactive_ble_platform_interface/src/model/uuid.dart'; +import 'package:reactive_ble_platform_interface/src/model/write_characteristic_info.dart'; void main() { group('$ProtobufConverter', () { diff --git a/test/plugin_controller_test.dart b/packages/reactive_ble_mobile/test/reactive_ble_platform_test.dart similarity index 85% rename from test/plugin_controller_test.dart rename to packages/reactive_ble_mobile/test/reactive_ble_platform_test.dart index 2facaeb6..6f6e6ae3 100644 --- a/test/plugin_controller_test.dart +++ b/packages/reactive_ble_mobile/test/reactive_ble_platform_test.dart @@ -2,34 +2,37 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:flutter/services.dart'; -import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/converter/args_to_protubuf_converter.dart'; -import 'package:flutter_reactive_ble/src/converter/protobuf_converter.dart'; -import 'package:flutter_reactive_ble/src/debug_logger.dart'; -import 'package:flutter_reactive_ble/src/generated/bledata.pb.dart' as pb; -import 'package:flutter_reactive_ble/src/model/clear_gatt_cache_error.dart'; -import 'package:flutter_reactive_ble/src/model/unit.dart'; -import 'package:flutter_reactive_ble/src/model/write_characteristic_info.dart'; -import 'package:flutter_reactive_ble/src/plugin_controller.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; - -import 'plugin_controller_test.mocks.dart'; +import 'package:reactive_ble_mobile/src/converter/args_to_protubuf_converter.dart'; +import 'package:reactive_ble_mobile/src/converter/protobuf_converter.dart'; +import 'package:reactive_ble_mobile/src/generated/bledata.pb.dart' as pb; +import 'package:reactive_ble_mobile/src/reactive_ble_mobile_platform.dart'; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart'; +import 'package:reactive_ble_platform_interface/src/model/characteristic_value.dart'; +import 'package:reactive_ble_platform_interface/src/model/connection_state_update.dart'; +import 'package:reactive_ble_platform_interface/src/model/qualified_characteristic.dart'; +import 'package:reactive_ble_platform_interface/src/model/result.dart'; +import 'package:reactive_ble_platform_interface/src/model/unit.dart'; +import 'package:reactive_ble_platform_interface/src/model/uuid.dart'; +import 'package:reactive_ble_platform_interface/src/model/write_characteristic_info.dart'; + +import 'reactive_ble_platform_test.mocks.dart'; +// ignore_for_file: avoid_implementing_value_types @GenerateMocks([ - Logger, ArgsToProtobufConverter, ProtobufConverter, MethodChannel, ]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group('$PluginController', () { - late PluginController _sut; + group('$ReactiveBleMobilePlatform', () { + late ReactiveBleMobilePlatform _sut; late MockMethodChannel _methodChannel; - late MockArgsToProtobufConverter _argsConverter; - late MockProtobufConverter _protobufConverter; + late ArgsToProtobufConverter _argsConverter; + late ProtobufConverter _protobufConverter; late StreamController> _connectedDeviceStreamController; late StreamController> _argsStreamController; late StreamController> _scanStreamController; @@ -44,13 +47,11 @@ void main() { _scanStreamController = StreamController(); _statusStreamController = StreamController(); - final logger = MockLogger(); - when(logger.log(any)).thenAnswer((_) {}); when(_methodChannel.invokeMethod(any, any)).thenAnswer( (_) async => 0, ); - _sut = PluginController( + _sut = ReactiveBleMobilePlatform( argsToProtobufConverter: _argsConverter, bleMethodChannel: _methodChannel, protobufConverter: _protobufConverter, @@ -58,7 +59,6 @@ void main() { charUpdateChannel: _argsStreamController.stream, bleDeviceScanChannel: _scanStreamController.stream, bleStatusChannel: _statusStreamController.stream, - debugLogger: logger, ); }); @@ -74,7 +74,7 @@ void main() { StreamSubscription? subscription; setUp(() { request = pb.ConnectToDeviceRequest(); - when(_argsConverter.createConnectToDeviceArgs(any, any, any)) + when(_argsConverter.createConnectToDeviceArgs('id', any, any)) .thenReturn(request); }); @@ -101,7 +101,7 @@ void main() { late pb.DisconnectFromDeviceRequest request; setUp(() async { request = pb.DisconnectFromDeviceRequest(); - when(_argsConverter.createDisconnectDeviceArgs(any)) + when(_argsConverter.createDisconnectDeviceArgs('id')) .thenReturn(request); await _sut.disconnectDevice('id'); }); @@ -135,7 +135,7 @@ void main() { ); when( - _protobufConverter.connectionStateUpdateFrom(any), + _protobufConverter.connectionStateUpdateFrom([1, 2, 3]), ).thenReturn(update); result = _sut.connectionUpdateStream; }); @@ -165,7 +165,7 @@ void main() { ]), ); - when(_protobufConverter.characteristicValueFrom(any)) + when(_protobufConverter.characteristicValueFrom([0, 1])) .thenReturn(valueUpdate); result = _sut.charValueUpdateStream; @@ -187,7 +187,7 @@ void main() { serviceId: Uuid.parse('FEFF'), deviceId: '123', ); - when(_argsConverter.createReadCharacteristicRequest(any)) + when(_argsConverter.createReadCharacteristicRequest(characteristic)) .thenReturn(request); }); @@ -226,9 +226,9 @@ void main() { when(_methodChannel.invokeMethod?>(any, any)).thenAnswer( (_) async => [1], ); - when(_argsConverter.createWriteChacracteristicRequest(any, any)) - .thenReturn(request); - when(_protobufConverter.writeCharacteristicInfoFrom(any)) + when(_argsConverter.createWriteChacracteristicRequest( + characteristic, [0, 1])).thenReturn(request); + when(_protobufConverter.writeCharacteristicInfoFrom([1])) .thenReturn(expectedResult); result = @@ -268,11 +268,12 @@ void main() { result: const Result.success(Unit())); when(_methodChannel.invokeMethod?>(any, any)).thenAnswer( - (_) async => [1], + (_) async => value, ); - when(_argsConverter.createWriteChacracteristicRequest(any, any)) + when(_argsConverter.createWriteChacracteristicRequest( + characteristic, value)) .thenReturn(request); - when(_protobufConverter.writeCharacteristicInfoFrom(any)) + when(_protobufConverter.writeCharacteristicInfoFrom(value)) .thenReturn(expectedResult); result = await _sut.writeCharacteristicWithoutResponse( characteristic, value); @@ -301,7 +302,7 @@ void main() { deviceId: '123', ); - when(_argsConverter.createNotifyCharacteristicRequest(any)) + when(_argsConverter.createNotifyCharacteristicRequest(characteristic)) .thenReturn(request); }); @@ -334,7 +335,8 @@ void main() { deviceId: '123', ); - when(_argsConverter.createNotifyNoMoreCharacteristicRequest(any)) + when(_argsConverter + .createNotifyNoMoreCharacteristicRequest(characteristic)) .thenReturn(request); await _sut.stopSubscribingToNotifications(characteristic); }); @@ -357,13 +359,13 @@ void main() { setUp(() async { request = pb.NegotiateMtuRequest(); - when(_argsConverter.createNegotiateMtuRequest(any, any)) + when(_argsConverter.createNegotiateMtuRequest(deviceId, mtuSize)) .thenReturn(request); when(_methodChannel.invokeMethod>(any, any)).thenAnswer( (_) async => [1], ); - when(_protobufConverter.mtuSizeFrom(any)).thenReturn(mtuSize); + when(_protobufConverter.mtuSizeFrom([1])).thenReturn(mtuSize); result = await _sut.requestMtuSize(deviceId, mtuSize); }); @@ -395,10 +397,11 @@ void main() { when(_methodChannel.invokeMethod>(any, any)).thenAnswer( (_) async => [1], ); - when(_argsConverter.createChangeConnectionPrioRequest(any, any)) + when(_argsConverter.createChangeConnectionPrioRequest( + deviceId, priority)) .thenReturn(request); - when(_protobufConverter.connectionPriorityInfoFrom(any)) + when(_protobufConverter.connectionPriorityInfoFrom([1])) .thenReturn(info); result = await _sut.requestConnectionPriority(deviceId, priority); }); @@ -427,10 +430,9 @@ void main() { setUp(() { request = pb.ScanForDevicesRequest(); when(_argsConverter.createScanForDevicesRequest( - withServices: anyNamed('withServices'), - scanMode: anyNamed('scanMode'), - requireLocationServicesEnabled: - anyNamed('requireLocationServicesEnabled'), + withServices: withServices, + scanMode: scanMode, + requireLocationServicesEnabled: locationEnabled, )).thenReturn(request); }); @@ -476,7 +478,7 @@ void main() { setUp(() { scanResult = ScanResult(result: Result.success(device)); - when(_protobufConverter.scanResultFrom(any)).thenReturn(scanResult); + when(_protobufConverter.scanResultFrom([1])).thenReturn(scanResult); _scanStreamController.addStream( Stream>.fromIterable([ @@ -527,10 +529,10 @@ void main() { (_) async => [1], ); - when(_argsConverter.createClearGattCacheRequest(any)) + when(_argsConverter.createClearGattCacheRequest(deviceId)) .thenReturn(request); - when(_protobufConverter.clearGattCacheResultFrom(any)) + when(_protobufConverter.clearGattCacheResultFrom([1])) .thenReturn(convertedResult); result = await _sut.clearGattCache(deviceId); }); @@ -590,9 +592,9 @@ void main() { when(_methodChannel.invokeMethod>(any, any)).thenAnswer( (_) async => [1], ); - when(_argsConverter.createDiscoverServicesRequest(any)) + when(_argsConverter.createDiscoverServicesRequest(deviceId)) .thenReturn(request); - when(_protobufConverter.discoveredServicesFrom(any)) + when(_protobufConverter.discoveredServicesFrom([1])) .thenReturn(services); result = await _sut.discoverServices(deviceId); diff --git a/packages/reactive_ble_mobile/test/reactive_ble_platform_test.mocks.dart b/packages/reactive_ble_mobile/test/reactive_ble_platform_test.mocks.dart new file mode 100644 index 00000000..6ebc0555 --- /dev/null +++ b/packages/reactive_ble_mobile/test/reactive_ble_platform_test.mocks.dart @@ -0,0 +1,302 @@ +// Mocks generated by Mockito 5.0.14 from annotations +// in reactive_ble_mobile/test/reactive_ble_platform_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i9; + +import 'package:flutter/src/services/binary_messenger.dart' as _i5; +import 'package:flutter/src/services/message_codec.dart' as _i4; +import 'package:flutter/src/services/platform_channel.dart' as _i8; +import 'package:mockito/mockito.dart' as _i1; +import 'package:reactive_ble_mobile/src/converter/args_to_protubuf_converter.dart' + as _i6; +import 'package:reactive_ble_mobile/src/converter/protobuf_converter.dart' + as _i7; +import 'package:reactive_ble_mobile/src/generated/bledata.pb.dart' as _i2; +import 'package:reactive_ble_platform_interface/reactive_ble_platform_interface.dart' + as _i3; + +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis + +class _FakeConnectToDeviceRequest_0 extends _i1.Fake + implements _i2.ConnectToDeviceRequest {} + +class _FakeDisconnectFromDeviceRequest_1 extends _i1.Fake + implements _i2.DisconnectFromDeviceRequest {} + +class _FakeReadCharacteristicRequest_2 extends _i1.Fake + implements _i2.ReadCharacteristicRequest {} + +class _FakeWriteCharacteristicRequest_3 extends _i1.Fake + implements _i2.WriteCharacteristicRequest {} + +class _FakeNotifyCharacteristicRequest_4 extends _i1.Fake + implements _i2.NotifyCharacteristicRequest {} + +class _FakeNotifyNoMoreCharacteristicRequest_5 extends _i1.Fake + implements _i2.NotifyNoMoreCharacteristicRequest {} + +class _FakeNegotiateMtuRequest_6 extends _i1.Fake + implements _i2.NegotiateMtuRequest {} + +class _FakeChangeConnectionPriorityRequest_7 extends _i1.Fake + implements _i2.ChangeConnectionPriorityRequest {} + +class _FakeScanForDevicesRequest_8 extends _i1.Fake + implements _i2.ScanForDevicesRequest {} + +class _FakeClearGattCacheRequest_9 extends _i1.Fake + implements _i2.ClearGattCacheRequest {} + +class _FakeDiscoverServicesRequest_10 extends _i1.Fake + implements _i2.DiscoverServicesRequest {} + +class _FakeScanResult_11 extends _i1.Fake implements _i3.ScanResult {} + +class _FakeConnectionStateUpdate_12 extends _i1.Fake + implements _i3.ConnectionStateUpdate {} + +class _FakeResult_13 extends _i1.Fake + implements _i3.Result {} + +class _FakeCharacteristicValue_14 extends _i1.Fake + implements _i3.CharacteristicValue {} + +class _FakeWriteCharacteristicInfo_15 extends _i1.Fake + implements _i3.WriteCharacteristicInfo {} + +class _FakeConnectionPriorityInfo_16 extends _i1.Fake + implements _i3.ConnectionPriorityInfo {} + +class _FakeMethodCodec_17 extends _i1.Fake implements _i4.MethodCodec {} + +class _FakeBinaryMessenger_18 extends _i1.Fake implements _i5.BinaryMessenger {} + +/// A class which mocks [ArgsToProtobufConverter]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockArgsToProtobufConverter extends _i1.Mock + implements _i6.ArgsToProtobufConverter { + MockArgsToProtobufConverter() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.ConnectToDeviceRequest createConnectToDeviceArgs( + String? id, + Map<_i3.Uuid, List<_i3.Uuid>>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout) => + (super.noSuchMethod( + Invocation.method(#createConnectToDeviceArgs, [ + id, + servicesWithCharacteristicsToDiscover, + connectionTimeout + ]), + returnValue: _FakeConnectToDeviceRequest_0()) + as _i2.ConnectToDeviceRequest); + @override + _i2.DisconnectFromDeviceRequest createDisconnectDeviceArgs( + String? deviceId) => + (super.noSuchMethod( + Invocation.method(#createDisconnectDeviceArgs, [deviceId]), + returnValue: _FakeDisconnectFromDeviceRequest_1()) + as _i2.DisconnectFromDeviceRequest); + @override + _i2.ReadCharacteristicRequest createReadCharacteristicRequest( + _i3.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method(#createReadCharacteristicRequest, [characteristic]), + returnValue: + _FakeReadCharacteristicRequest_2()) as _i2 + .ReadCharacteristicRequest); + @override + _i2.WriteCharacteristicRequest createWriteChacracteristicRequest( + _i3.QualifiedCharacteristic? characteristic, List? value) => + (super.noSuchMethod( + Invocation.method( + #createWriteChacracteristicRequest, [characteristic, value]), + returnValue: _FakeWriteCharacteristicRequest_3()) + as _i2.WriteCharacteristicRequest); + @override + _i2.NotifyCharacteristicRequest createNotifyCharacteristicRequest( + _i3.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method( + #createNotifyCharacteristicRequest, [characteristic]), + returnValue: _FakeNotifyCharacteristicRequest_4()) + as _i2.NotifyCharacteristicRequest); + @override + _i2.NotifyNoMoreCharacteristicRequest createNotifyNoMoreCharacteristicRequest( + _i3.QualifiedCharacteristic? characteristic) => + (super.noSuchMethod( + Invocation.method( + #createNotifyNoMoreCharacteristicRequest, [characteristic]), + returnValue: _FakeNotifyNoMoreCharacteristicRequest_5()) + as _i2.NotifyNoMoreCharacteristicRequest); + @override + _i2.NegotiateMtuRequest createNegotiateMtuRequest( + String? deviceId, int? mtu) => + (super.noSuchMethod( + Invocation.method(#createNegotiateMtuRequest, [deviceId, mtu]), + returnValue: _FakeNegotiateMtuRequest_6()) + as _i2.NegotiateMtuRequest); + @override + _i2.ChangeConnectionPriorityRequest createChangeConnectionPrioRequest( + String? deviceId, _i3.ConnectionPriority? priority) => + (super.noSuchMethod( + Invocation.method( + #createChangeConnectionPrioRequest, [deviceId, priority]), + returnValue: _FakeChangeConnectionPriorityRequest_7()) + as _i2.ChangeConnectionPriorityRequest); + @override + _i2.ScanForDevicesRequest createScanForDevicesRequest( + {List<_i3.Uuid>? withServices, + _i3.ScanMode? scanMode, + bool? requireLocationServicesEnabled}) => + (super.noSuchMethod( + Invocation.method(#createScanForDevicesRequest, [], { + #withServices: withServices, + #scanMode: scanMode, + #requireLocationServicesEnabled: requireLocationServicesEnabled + }), + returnValue: _FakeScanForDevicesRequest_8()) + as _i2.ScanForDevicesRequest); + @override + _i2.ClearGattCacheRequest createClearGattCacheRequest(String? deviceId) => + (super.noSuchMethod( + Invocation.method(#createClearGattCacheRequest, [deviceId]), + returnValue: _FakeClearGattCacheRequest_9()) + as _i2.ClearGattCacheRequest); + @override + _i2.DiscoverServicesRequest createDiscoverServicesRequest(String? deviceId) => + (super.noSuchMethod( + Invocation.method(#createDiscoverServicesRequest, [deviceId]), + returnValue: _FakeDiscoverServicesRequest_10()) + as _i2.DiscoverServicesRequest); + @override + String toString() => super.toString(); +} + +/// A class which mocks [ProtobufConverter]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockProtobufConverter extends _i1.Mock implements _i7.ProtobufConverter { + MockProtobufConverter() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.BleStatus bleStatusFrom(List? data) => + (super.noSuchMethod(Invocation.method(#bleStatusFrom, [data]), + returnValue: _i3.BleStatus.unknown) as _i3.BleStatus); + @override + _i3.ScanResult scanResultFrom(List? data) => + (super.noSuchMethod(Invocation.method(#scanResultFrom, [data]), + returnValue: _FakeScanResult_11()) as _i3.ScanResult); + @override + _i3.ConnectionStateUpdate connectionStateUpdateFrom(List? data) => + (super.noSuchMethod(Invocation.method(#connectionStateUpdateFrom, [data]), + returnValue: _FakeConnectionStateUpdate_12()) + as _i3.ConnectionStateUpdate); + @override + _i3.Result<_i3.Unit, _i3.GenericFailure<_i3.ClearGattCacheError>?> + clearGattCacheResultFrom(List? data) => (super.noSuchMethod( + Invocation.method(#clearGattCacheResultFrom, [data]), + returnValue: _FakeResult_13<_i3.Unit, + _i3.GenericFailure<_i3.ClearGattCacheError>?>()) as _i3 + .Result<_i3.Unit, _i3.GenericFailure<_i3.ClearGattCacheError>?>); + @override + _i3.CharacteristicValue characteristicValueFrom(List? data) => + (super.noSuchMethod(Invocation.method(#characteristicValueFrom, [data]), + returnValue: _FakeCharacteristicValue_14()) + as _i3.CharacteristicValue); + @override + _i3.WriteCharacteristicInfo writeCharacteristicInfoFrom(List? data) => + (super.noSuchMethod( + Invocation.method(#writeCharacteristicInfoFrom, [data]), + returnValue: _FakeWriteCharacteristicInfo_15()) + as _i3.WriteCharacteristicInfo); + @override + _i3.ConnectionPriorityInfo connectionPriorityInfoFrom(List? data) => + (super.noSuchMethod( + Invocation.method(#connectionPriorityInfoFrom, [data]), + returnValue: _FakeConnectionPriorityInfo_16()) + as _i3.ConnectionPriorityInfo); + @override + int mtuSizeFrom(List? data) => (super + .noSuchMethod(Invocation.method(#mtuSizeFrom, [data]), returnValue: 0) + as int); + @override + List<_i3.DiscoveredService> discoveredServicesFrom(List? data) => + (super.noSuchMethod(Invocation.method(#discoveredServicesFrom, [data]), + returnValue: <_i3.DiscoveredService>[]) + as List<_i3.DiscoveredService>); + @override + String toString() => super.toString(); +} + +/// A class which mocks [MethodChannel]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockMethodChannel extends _i1.Mock implements _i8.MethodChannel { + MockMethodChannel() { + _i1.throwOnMissingStub(this); + } + + @override + String get name => + (super.noSuchMethod(Invocation.getter(#name), returnValue: '') as String); + @override + _i4.MethodCodec get codec => (super.noSuchMethod(Invocation.getter(#codec), + returnValue: _FakeMethodCodec_17()) as _i4.MethodCodec); + @override + _i5.BinaryMessenger get binaryMessenger => + (super.noSuchMethod(Invocation.getter(#binaryMessenger), + returnValue: _FakeBinaryMessenger_18()) as _i5.BinaryMessenger); + @override + _i9.Future invokeMethod(String? method, [dynamic arguments]) => + (super.noSuchMethod(Invocation.method(#invokeMethod, [method, arguments]), + returnValue: Future.value()) as _i9.Future); + @override + _i9.Future?> invokeListMethod(String? method, + [dynamic arguments]) => + (super.noSuchMethod( + Invocation.method(#invokeListMethod, [method, arguments]), + returnValue: Future?>.value()) as _i9.Future?>); + @override + _i9.Future?> invokeMapMethod(String? method, + [dynamic arguments]) => + (super.noSuchMethod( + Invocation.method(#invokeMapMethod, [method, arguments]), + returnValue: Future?>.value()) as _i9.Future?>); + @override + void setMethodCallHandler( + _i9.Future Function(_i4.MethodCall)? handler) => + super.noSuchMethod(Invocation.method(#setMethodCallHandler, [handler]), + returnValueForMissingStub: null); + @override + bool checkMethodCallHandler( + _i9.Future Function(_i4.MethodCall)? handler) => + (super.noSuchMethod(Invocation.method(#checkMethodCallHandler, [handler]), + returnValue: false) as bool); + @override + void setMockMethodCallHandler( + _i9.Future? Function(_i4.MethodCall)? handler) => + super.noSuchMethod( + Invocation.method(#setMockMethodCallHandler, [handler]), + returnValueForMissingStub: null); + @override + bool checkMockMethodCallHandler( + _i9.Future Function(_i4.MethodCall)? handler) => + (super.noSuchMethod( + Invocation.method(#checkMockMethodCallHandler, [handler]), + returnValue: false) as bool); + @override + String toString() => super.toString(); +} diff --git a/packages/reactive_ble_platform_interface/CHANGELOG.md b/packages/reactive_ble_platform_interface/CHANGELOG.md new file mode 100644 index 00000000..ce63509a --- /dev/null +++ b/packages/reactive_ble_platform_interface/CHANGELOG.md @@ -0,0 +1,5 @@ +# Main releases + +## 4.0.0 + +* Initial Open Source release. diff --git a/packages/reactive_ble_platform_interface/LICENSE b/packages/reactive_ble_platform_interface/LICENSE new file mode 100644 index 00000000..1b0489a1 --- /dev/null +++ b/packages/reactive_ble_platform_interface/LICENSE @@ -0,0 +1,24 @@ +BSD license + +©2019 Signify Holding. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions +and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/packages/reactive_ble_platform_interface/README.md b/packages/reactive_ble_platform_interface/README.md new file mode 100644 index 00000000..254cf24e --- /dev/null +++ b/packages/reactive_ble_platform_interface/README.md @@ -0,0 +1,7 @@ +# Reactive_ble_platform_interface + +A common platform interface for the [reactive ble](https://github.com/PhilipsHue/flutter_reactive_ble/) plugin. This package ensures every platform specific implementation uses the same interface. + +## Usage + +To implement a new platform specific implementation extend the `ReactiveBlePlatform` with an implementation that performs the platform specific behavior. \ No newline at end of file diff --git a/packages/reactive_ble_platform_interface/lib/reactive_ble_platform_interface.dart b/packages/reactive_ble_platform_interface/lib/reactive_ble_platform_interface.dart new file mode 100644 index 00000000..872ffb25 --- /dev/null +++ b/packages/reactive_ble_platform_interface/lib/reactive_ble_platform_interface.dart @@ -0,0 +1,4 @@ +library reactive_ble_platform_interface; + +export 'src/models.dart'; +export 'src/reactive_ble_platform_interface.dart'; diff --git a/lib/src/model/ble_status.dart b/packages/reactive_ble_platform_interface/lib/src/model/ble_status.dart similarity index 100% rename from lib/src/model/ble_status.dart rename to packages/reactive_ble_platform_interface/lib/src/model/ble_status.dart diff --git a/lib/src/model/characteristic_value.dart b/packages/reactive_ble_platform_interface/lib/src/model/characteristic_value.dart similarity index 71% rename from lib/src/model/characteristic_value.dart rename to packages/reactive_ble_platform_interface/lib/src/model/characteristic_value.dart index 6dd28b50..a7f3da52 100644 --- a/lib/src/model/characteristic_value.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/characteristic_value.dart @@ -1,6 +1,6 @@ -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart'; -import 'package:flutter_reactive_ble/src/model/result.dart'; +import 'generic_failure.dart'; +import 'qualified_characteristic.dart'; +import 'result.dart'; /// Value update for specific [QualifiedCharacteristic]. class CharacteristicValue { diff --git a/lib/src/model/clear_gatt_cache_error.dart b/packages/reactive_ble_platform_interface/lib/src/model/clear_gatt_cache_error.dart similarity index 100% rename from lib/src/model/clear_gatt_cache_error.dart rename to packages/reactive_ble_platform_interface/lib/src/model/clear_gatt_cache_error.dart diff --git a/lib/src/model/connection_priority.dart b/packages/reactive_ble_platform_interface/lib/src/model/connection_priority.dart similarity index 88% rename from lib/src/model/connection_priority.dart rename to packages/reactive_ble_platform_interface/lib/src/model/connection_priority.dart index 1f112df3..2ad3951f 100644 --- a/lib/src/model/connection_priority.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/connection_priority.dart @@ -1,7 +1,6 @@ -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; -import 'package:flutter_reactive_ble/src/model/result.dart'; - import '../model/unit.dart'; +import 'generic_failure.dart'; +import 'result.dart'; /// The priority that can be requested to update the connection parameter. enum ConnectionPriority { diff --git a/lib/src/model/connection_state_update.dart b/packages/reactive_ble_platform_interface/lib/src/model/connection_state_update.dart similarity index 93% rename from lib/src/model/connection_state_update.dart rename to packages/reactive_ble_platform_interface/lib/src/model/connection_state_update.dart index 656c29a8..6ee0ca65 100644 --- a/lib/src/model/connection_state_update.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/connection_state_update.dart @@ -1,7 +1,8 @@ -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; import 'package:functional_data/functional_data.dart'; import 'package:meta/meta.dart'; +import 'generic_failure.dart'; + part 'connection_state_update.g.dart'; //ignore_for_file: annotate_overrides diff --git a/lib/src/model/connection_state_update.g.dart b/packages/reactive_ble_platform_interface/lib/src/model/connection_state_update.g.dart similarity index 100% rename from lib/src/model/connection_state_update.g.dart rename to packages/reactive_ble_platform_interface/lib/src/model/connection_state_update.g.dart diff --git a/lib/src/model/discovered_device.dart b/packages/reactive_ble_platform_interface/lib/src/model/discovered_device.dart similarity index 92% rename from lib/src/model/discovered_device.dart rename to packages/reactive_ble_platform_interface/lib/src/model/discovered_device.dart index caaddda1..0b72403c 100644 --- a/lib/src/model/discovered_device.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/discovered_device.dart @@ -1,11 +1,13 @@ import 'dart:typed_data'; import 'package:collection/collection.dart'; -import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; import 'package:functional_data/functional_data.dart'; import 'package:meta/meta.dart'; +import '../../reactive_ble_platform_interface.dart'; +import 'generic_failure.dart'; +import 'result.dart'; + part 'discovered_device.g.dart'; // ignore_for_file: annotate_overrides, avoid_classes_with_only_static_members, non_constant_identifier_names @@ -30,6 +32,7 @@ class DiscoveredDevice extends $DiscoveredDevice { @CustomEquality(DeepCollectionEquality()) final Map serviceData; + /// Advertised services @CustomEquality(DeepCollectionEquality()) final List serviceUuids; @@ -42,9 +45,9 @@ class DiscoveredDevice extends $DiscoveredDevice { required this.id, required this.name, required this.serviceData, - required this.serviceUuids, required this.manufacturerData, required this.rssi, + required this.serviceUuids, }); } diff --git a/lib/src/model/discovered_device.g.dart b/packages/reactive_ble_platform_interface/lib/src/model/discovered_device.g.dart similarity index 100% rename from lib/src/model/discovered_device.g.dart rename to packages/reactive_ble_platform_interface/lib/src/model/discovered_device.g.dart diff --git a/lib/src/model/discovered_service.dart b/packages/reactive_ble_platform_interface/lib/src/model/discovered_service.dart similarity index 90% rename from lib/src/model/discovered_service.dart rename to packages/reactive_ble_platform_interface/lib/src/model/discovered_service.dart index 5f21385b..0fbecb32 100644 --- a/lib/src/model/discovered_service.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/discovered_service.dart @@ -1,7 +1,8 @@ import 'package:collection/collection.dart'; -import 'package:flutter_reactive_ble/src/model/uuid.dart'; import 'package:functional_data/functional_data.dart'; +import 'uuid.dart'; + part 'discovered_service.g.dart'; //ignore_for_file: annotate_overrides diff --git a/lib/src/model/discovered_service.g.dart b/packages/reactive_ble_platform_interface/lib/src/model/discovered_service.g.dart similarity index 100% rename from lib/src/model/discovered_service.g.dart rename to packages/reactive_ble_platform_interface/lib/src/model/discovered_service.g.dart diff --git a/lib/src/model/generic_failure.dart b/packages/reactive_ble_platform_interface/lib/src/model/generic_failure.dart similarity index 100% rename from lib/src/model/generic_failure.dart rename to packages/reactive_ble_platform_interface/lib/src/model/generic_failure.dart diff --git a/lib/src/model/log_level.dart b/packages/reactive_ble_platform_interface/lib/src/model/log_level.dart similarity index 100% rename from lib/src/model/log_level.dart rename to packages/reactive_ble_platform_interface/lib/src/model/log_level.dart diff --git a/lib/src/model/qualified_characteristic.dart b/packages/reactive_ble_platform_interface/lib/src/model/qualified_characteristic.dart similarity index 94% rename from lib/src/model/qualified_characteristic.dart rename to packages/reactive_ble_platform_interface/lib/src/model/qualified_characteristic.dart index 858772d6..10951f22 100644 --- a/lib/src/model/qualified_characteristic.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/qualified_characteristic.dart @@ -1,6 +1,7 @@ -import 'package:flutter_reactive_ble/src/model/uuid.dart'; import 'package:meta/meta.dart'; +import 'uuid.dart'; + /// Specific BLE characteristic for a BLE device characterised by [deviceId], [serviceId] and /// [characteristicId]. @immutable diff --git a/lib/src/model/result.dart b/packages/reactive_ble_platform_interface/lib/src/model/result.dart similarity index 100% rename from lib/src/model/result.dart rename to packages/reactive_ble_platform_interface/lib/src/model/result.dart diff --git a/lib/src/model/scan_mode.dart b/packages/reactive_ble_platform_interface/lib/src/model/scan_mode.dart similarity index 100% rename from lib/src/model/scan_mode.dart rename to packages/reactive_ble_platform_interface/lib/src/model/scan_mode.dart diff --git a/lib/src/model/scan_session.dart b/packages/reactive_ble_platform_interface/lib/src/model/scan_session.dart similarity index 72% rename from lib/src/model/scan_session.dart rename to packages/reactive_ble_platform_interface/lib/src/model/scan_session.dart index fe3d7d50..52155ae1 100644 --- a/lib/src/model/scan_session.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/scan_session.dart @@ -1,4 +1,4 @@ -import 'package:flutter_reactive_ble/src/model/uuid.dart'; +import 'uuid.dart'; class ScanSession { final List withServices; diff --git a/lib/src/model/unit.dart b/packages/reactive_ble_platform_interface/lib/src/model/unit.dart similarity index 100% rename from lib/src/model/unit.dart rename to packages/reactive_ble_platform_interface/lib/src/model/unit.dart diff --git a/lib/src/model/uuid.dart b/packages/reactive_ble_platform_interface/lib/src/model/uuid.dart similarity index 100% rename from lib/src/model/uuid.dart rename to packages/reactive_ble_platform_interface/lib/src/model/uuid.dart diff --git a/lib/src/model/write_characteristic_info.dart b/packages/reactive_ble_platform_interface/lib/src/model/write_characteristic_info.dart similarity index 74% rename from lib/src/model/write_characteristic_info.dart rename to packages/reactive_ble_platform_interface/lib/src/model/write_characteristic_info.dart index c7de40d4..5f619a93 100644 --- a/lib/src/model/write_characteristic_info.dart +++ b/packages/reactive_ble_platform_interface/lib/src/model/write_characteristic_info.dart @@ -1,9 +1,10 @@ -import 'package:flutter_reactive_ble/src/model/generic_failure.dart'; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart'; -import 'package:flutter_reactive_ble/src/model/result.dart'; -import 'package:flutter_reactive_ble/src/model/unit.dart'; import 'package:meta/meta.dart'; +import 'generic_failure.dart'; +import 'qualified_characteristic.dart'; +import 'result.dart'; +import 'unit.dart'; + @immutable class WriteCharacteristicInfo { final QualifiedCharacteristic characteristic; diff --git a/packages/reactive_ble_platform_interface/lib/src/models.dart b/packages/reactive_ble_platform_interface/lib/src/models.dart new file mode 100644 index 00000000..35c3a8a1 --- /dev/null +++ b/packages/reactive_ble_platform_interface/lib/src/models.dart @@ -0,0 +1,16 @@ +export './model/ble_status.dart'; +export './model/characteristic_value.dart'; +export './model/clear_gatt_cache_error.dart'; +export './model/connection_priority.dart'; +export './model/connection_state_update.dart'; +export './model/discovered_device.dart'; +export './model/discovered_service.dart'; +export './model/generic_failure.dart'; +export './model/log_level.dart'; +export './model/qualified_characteristic.dart'; +export './model/result.dart'; +export './model/scan_mode.dart'; +export './model/scan_session.dart'; +export './model/unit.dart'; +export './model/uuid.dart'; +export './model/write_characteristic_info.dart'; diff --git a/packages/reactive_ble_platform_interface/lib/src/reactive_ble_platform_interface.dart b/packages/reactive_ble_platform_interface/lib/src/reactive_ble_platform_interface.dart new file mode 100644 index 00000000..4baed12b --- /dev/null +++ b/packages/reactive_ble_platform_interface/lib/src/reactive_ble_platform_interface.dart @@ -0,0 +1,184 @@ +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'models.dart'; + +/// The interface that implementations of `reactive_ble` must implement. +/// +// Platform implementations should extend this class rather than implement it as +// `reactive_ble`does not consider newly added methods to be breaking changes. +// Extending this class (using `extends`) ensures that the subclass will get +// the default implementation, while platform implementations that `implements` +// this interface will be broken by newly added [ReactiveBlePlatform] methods. +abstract class ReactiveBlePlatform extends PlatformInterface { + ReactiveBlePlatform() : super(token: _token); + static final Object _token = Object(); + + static late ReactiveBlePlatform _instance; + + static ReactiveBlePlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [ReactiveBlePlatform] when they register themselves. + static set instance(ReactiveBlePlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Stream providing ble scan results. + /// + /// It is important to subscribe to this stream before scanning for devices + /// since it can happen that some results are missed. + Stream get scanStream { + throw UnimplementedError('scanStream has not been implemented.'); + } + + /// Stream that provides status updates regarding the host device BLE sub system. + /// + /// In general this stream will be listened to on app startup to determine + /// whether or not ble is switched on or authorized. + Stream get bleStatusStream { + throw UnimplementedError('bleStatusStream has not been implemented.'); + } + + /// Listen to this stream to get connection updates for all the connected BLE + /// devices. + /// + /// It is important to subscribe to this stream before connecting to a + /// device since it can happen that some results are missed. + Stream get connectionUpdateStream { + throw UnimplementedError('connectionStream has not been implemented.'); + } + + /// Stream that provides value updates about the characteristics that are read + /// or subscribed to. + Stream get charValueUpdateStream { + throw UnimplementedError('charValueUpdateStream has not been implemented.'); + } + + /// Initializes the ble plugin platform specific counter parts. + /// + /// The initialization is performed automatically the first time any BLE + /// operation is triggered. + Future initialize() { + throw UnimplementedError('initialize() has not been implemented.'); + } + + /// De-initializes the ble plugin platform specific counter parts. + Future deinitialize() { + throw UnimplementedError('deInitialize() has not been implemented.'); + } + + /// Stream that handles triggers scanning for Ble devices. + /// + /// As long as the stream has been `listened` to the scanning continues. When + /// the stream is `cancelled ` the ble scanning should stop. + Stream scanForDevices({ + required List withServices, + required ScanMode scanMode, + required bool requireLocationServicesEnabled, + }) { + throw UnimplementedError('scanForDevices has not been implemented.'); + } + + /// Clears GATT attribute cache on Android using undocumented API. This method + /// should not be implemented for other platforms. + Future?>> clearGattCache( + String deviceId) { + throw UnimplementedError('clearGattCache() has not been implemented.'); + } + + /// Connects to a specific device and the connection remains `established` until + /// the stream is `cancelled` or the connection is closed by the peripheral. + /// + /// The actual `connection updates` should be propagated to the [connectionUpdateStream]. + Stream connectToDevice( + String id, + Map>? servicesWithCharacteristicsToDiscover, + Duration? connectionTimeout, + ) { + throw UnimplementedError('connectToDevice has not been implemented.'); + } + + /// Operation that disconnects the host with the peripheral. + Future disconnectDevice(String deviceId) { + throw UnimplementedError('disconnectDevice has not been implemented.'); + } + + /// Performs service discovery on the peripheral and returns the discovered + /// services. + /// + /// This operation can only succeed when the host is `connected` with the peripheral. + Future> discoverServices(String deviceId) { + throw UnimplementedError('discoverServices has not been implemented.'); + } + + /// Performs service discovery on the peripheral and returns the discovered + /// services. + /// + /// This operation can only succeed when the host is `connected` with the + /// peripheral. Only the success or failure of this operation should be propagated + /// to this stream. The read value is distributed to [charValueUpdateStream]. + Stream readCharacteristic(QualifiedCharacteristic characteristic) { + throw UnimplementedError('readCharacteristic has not been implemented.'); + } + + /// Perform writing a value to a specific characteristic and awaiting the + /// acknowledgment from the peripheral. + /// + /// When implement this operation on the platform make sure that you return a + /// response only when the peripheral `acknowledged` the write operation + Future writeCharacteristicWithResponse( + QualifiedCharacteristic characteristic, + List value, + ) { + throw UnimplementedError( + 'writeCharacteristicWithResponse has not been implemented.'); + } + + /// Perform writing a value to a specific characteristic without awaiting the + /// acknowledgment from the peripheral. + /// + /// When implementing this operation on the platform make sure that it directly + /// returns a response to the dart layer when the command arrived. + Future writeCharacteristicWithoutResponse( + QualifiedCharacteristic characteristic, + List value, + ) { + throw UnimplementedError( + 'writeCharacteristicWithoutResponse has not been implemented.'); + } + + /// Starts subscribing to notifications for a specificied characteristic. + /// + /// This stream only returns the result of the operation. Value updates should + /// be propagated to [charValueUpdateStream]. + Stream subscribeToNotifications( + QualifiedCharacteristic characteristic, + ) { + throw UnimplementedError( + 'subscribeToNotifications has not been implemented.'); + } + + /// Stops subscribing to notifications for a specificied characteristic. + Future stopSubscribingToNotifications( + QualifiedCharacteristic characteristic, + ) { + throw UnimplementedError( + 'stopSubscribingToNotifiations has not been implemented.'); + } + + /// Requests a specific MTU for a connected device. + Future requestMtuSize(String deviceId, int? mtu) { + throw UnimplementedError('requestMtuSize has not been implemented.'); + } + + /// Requests for a connection parameter update on the connected device. + /// + /// This operation is specific to the Android ecosystem and should not be + /// implemented by other platforms. + Future requestConnectionPriority( + String deviceId, ConnectionPriority priority) { + throw UnimplementedError( + 'requesConnectionPriority has not been implemented.'); + } +} diff --git a/packages/reactive_ble_platform_interface/lib/src/select_from.dart b/packages/reactive_ble_platform_interface/lib/src/select_from.dart new file mode 100644 index 00000000..f1118021 --- /dev/null +++ b/packages/reactive_ble_platform_interface/lib/src/select_from.dart @@ -0,0 +1,7 @@ +T selectFrom(List values, + {required int? index, required T Function(int? index) fallback}) { + if (index != null && index >= 0 && index < values.length) { + return values[index]; + } + return fallback(index); +} diff --git a/pubspec.lock b/packages/reactive_ble_platform_interface/pubspec.lock similarity index 92% rename from pubspec.lock rename to packages/reactive_ble_platform_interface/pubspec.lock index 44e6281d..6734799b 100644 --- a/pubspec.lock +++ b/packages/reactive_ble_platform_interface/pubspec.lock @@ -7,21 +7,21 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "18.0.0" + version: "19.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.6.0" + version: "2.0.0" async: dependency: transitive description: @@ -70,7 +70,7 @@ packages: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "1.12.1" + version: "1.12.2" build_runner_core: dependency: transitive description: @@ -84,14 +84,14 @@ packages: name: built_collection url: "https://pub.dartlang.org" source: hosted - version: "5.0.0-nullsafety.0" + version: "5.0.0" built_value: dependency: transitive description: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.0.0-nullsafety.0" + version: "8.0.4" characters: dependency: transitive description: @@ -154,7 +154,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.0.1" dart_style: dependency: transitive description: @@ -188,6 +188,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" flutter_test: dependency: "direct dev" description: flutter @@ -213,7 +220,7 @@ packages: name: glob url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.1" graphs: dependency: transitive description: @@ -227,42 +234,49 @@ packages: name: http_multi_server url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "3.0.0" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.4" + version: "4.0.0" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "1.0.0" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.2" + version: "0.6.3" json_annotation: dependency: transitive description: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.0.1" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" matcher: dependency: transitive description: @@ -283,14 +297,14 @@ packages: name: mime url: "https://pub.dartlang.org" source: hosted - version: "0.9.7" + version: "1.0.0" mockito: dependency: "direct dev" description: name: mockito url: "https://pub.dartlang.org" source: hosted - version: "5.0.7" + version: "5.0.3" package_config: dependency: transitive description: @@ -306,12 +320,19 @@ packages: source: hosted version: "1.8.0" pedantic: - dependency: "direct main" + dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted version: "1.11.0" + plugin_platform_interface: + dependency: "direct main" + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" pool: dependency: transitive description: @@ -319,13 +340,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.0" - protobuf: - dependency: "direct main" - description: - name: protobuf - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" pub_semver: dependency: transitive description: @@ -346,14 +360,14 @@ packages: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.9" + version: "1.1.0" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "0.2.3" + version: "1.0.1" sky_engine: dependency: transitive description: flutter @@ -421,7 +435,7 @@ packages: name: timing url: "https://pub.dartlang.org" source: hosted - version: "0.1.1+3" + version: "1.0.0" typed_data: dependency: transitive description: @@ -449,7 +463,7 @@ packages: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "2.0.0" yaml: dependency: transitive description: @@ -459,4 +473,4 @@ packages: version: "3.1.0" sdks: dart: ">=2.12.0 <3.0.0" - flutter: ">=1.10.0" + flutter: ">=1.17.0" diff --git a/packages/reactive_ble_platform_interface/pubspec.yaml b/packages/reactive_ble_platform_interface/pubspec.yaml new file mode 100644 index 00000000..de873beb --- /dev/null +++ b/packages/reactive_ble_platform_interface/pubspec.yaml @@ -0,0 +1,27 @@ +name: reactive_ble_platform_interface +description: Platform interface for the flutter_reactive_ble_project +version: 4.0.0 +homepage: https://github.com/PhilipsHue/flutter_reactive_ble + +environment: + sdk: '>=2.12.0 <3.0.0' + flutter: ">=1.17.0" + +dependencies: + collection: ^1.15.0 + flutter: + sdk: flutter + functional_data: ^1.0.0 + meta: ^1.3.0 + + plugin_platform_interface: ^2.0.0 + +dev_dependencies: + build_runner: ^1.12.1 + flutter_lints: ^1.0.3 + flutter_test: + sdk: flutter + functional_data_generator: ^1.0.0 + mockito: ^5.0.2 + +flutter: diff --git a/test/select_from_test.dart b/packages/reactive_ble_platform_interface/test/select_from_test.dart similarity index 89% rename from test/select_from_test.dart rename to packages/reactive_ble_platform_interface/test/select_from_test.dart index a8b268fb..d2cfd6c6 100644 --- a/test/select_from_test.dart +++ b/packages/reactive_ble_platform_interface/test/select_from_test.dart @@ -1,5 +1,5 @@ -import 'package:flutter_reactive_ble/src/select_from.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:reactive_ble_platform_interface/src/select_from.dart'; void main() { group("selectFrom", () { diff --git a/test/connected_device_operation_test.mocks.dart b/test/connected_device_operation_test.mocks.dart deleted file mode 100644 index 230909cc..00000000 --- a/test/connected_device_operation_test.mocks.dart +++ /dev/null @@ -1,100 +0,0 @@ -// Mocks generated by Mockito 5.0.7 from annotations -// in flutter_reactive_ble/test/connected_device_operation_test.dart. -// Do not manually edit this file. - -import 'dart:async' as _i5; - -import 'package:flutter_reactive_ble/src/model/characteristic_value.dart' - as _i6; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart' as _i3; -import 'package:flutter_reactive_ble/src/model/discovered_service.dart' as _i7; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart' - as _i8; -import 'package:flutter_reactive_ble/src/model/write_characteristic_info.dart' - as _i2; -import 'package:flutter_reactive_ble/src/plugin_controller.dart' as _i4; -import 'package:mockito/mockito.dart' as _i1; - -// ignore_for_file: comment_references -// ignore_for_file: unnecessary_parenthesis - -// ignore_for_file: prefer_const_constructors - -// ignore_for_file: avoid_redundant_argument_values - -class _FakeWriteCharacteristicInfo extends _i1.Fake - implements _i2.WriteCharacteristicInfo {} - -class _FakeConnectionPriorityInfo extends _i1.Fake - implements _i3.ConnectionPriorityInfo {} - -/// A class which mocks [DeviceOperationController]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDeviceOperationController extends _i1.Mock - implements _i4.DeviceOperationController { - MockDeviceOperationController() { - _i1.throwOnMissingStub(this); - } - - @override - _i5.Stream<_i6.CharacteristicValue> get charValueUpdateStream => - (super.noSuchMethod(Invocation.getter(#charValueUpdateStream), - returnValue: Stream<_i6.CharacteristicValue>.empty()) - as _i5.Stream<_i6.CharacteristicValue>); - @override - _i5.Future> discoverServices(String? deviceId) => - (super.noSuchMethod(Invocation.method(#discoverServices, [deviceId]), - returnValue: Future>.value( - <_i7.DiscoveredService>[])) - as _i5.Future>); - @override - _i5.Stream readCharacteristic( - _i8.QualifiedCharacteristic? characteristic) => - (super.noSuchMethod( - Invocation.method(#readCharacteristic, [characteristic]), - returnValue: Stream.empty()) as _i5.Stream); - @override - _i5.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithResponse( - _i8.QualifiedCharacteristic? characteristic, List? value) => - (super.noSuchMethod( - Invocation.method( - #writeCharacteristicWithResponse, [characteristic, value]), - returnValue: Future<_i2.WriteCharacteristicInfo>.value( - _FakeWriteCharacteristicInfo())) - as _i5.Future<_i2.WriteCharacteristicInfo>); - @override - _i5.Future<_i2.WriteCharacteristicInfo> writeCharacteristicWithoutResponse( - _i8.QualifiedCharacteristic? characteristic, List? value) => - (super.noSuchMethod( - Invocation.method( - #writeCharacteristicWithoutResponse, [characteristic, value]), - returnValue: Future<_i2.WriteCharacteristicInfo>.value( - _FakeWriteCharacteristicInfo())) - as _i5.Future<_i2.WriteCharacteristicInfo>); - @override - _i5.Stream subscribeToNotifications( - _i8.QualifiedCharacteristic? characteristic) => - (super.noSuchMethod( - Invocation.method(#subscribeToNotifications, [characteristic]), - returnValue: Stream.empty()) as _i5.Stream); - @override - _i5.Future stopSubscribingToNotifications( - _i8.QualifiedCharacteristic? characteristic) => - (super.noSuchMethod( - Invocation.method(#stopSubscribingToNotifications, [characteristic]), - returnValue: Future.value(null), - returnValueForMissingStub: Future.value()) as _i5.Future); - @override - _i5.Future requestMtuSize(String? deviceId, int? mtu) => - (super.noSuchMethod(Invocation.method(#requestMtuSize, [deviceId, mtu]), - returnValue: Future.value(0)) as _i5.Future); - @override - _i5.Future<_i3.ConnectionPriorityInfo> requestConnectionPriority( - String? deviceId, _i3.ConnectionPriority? priority) => - (super.noSuchMethod( - Invocation.method(#requestConnectionPriority, [deviceId, priority]), - returnValue: Future<_i3.ConnectionPriorityInfo>.value( - _FakeConnectionPriorityInfo())) as _i5 - .Future<_i3.ConnectionPriorityInfo>); -} diff --git a/test/debug_logger_test.dart b/test/debug_logger_test.dart deleted file mode 100644 index 905a1851..00000000 --- a/test/debug_logger_test.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; -import 'package:flutter_reactive_ble/src/debug_logger.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group('$DebugLogger', () { - late DebugLogger sut; - const tag = 'TestTag'; - late _PrinterStub printer; - - setUp(() { - printer = _PrinterStub(); - sut = DebugLogger( - tag, - printer.print, - ); - }); - - group('Given debuglevel is set to verbose', () { - setUp(() { - sut.logLevel = LogLevel.verbose; - }); - - test('It logs message', () { - sut.log("Log message"); - expect(printer.lastLoggedMessage, 'TestTag: Log message'); - }); - }); - - group('Given loglevel is set to none', () { - test('It does not log message', () { - const message = "Log message"; - sut.log(message); - expect(printer.lastLoggedMessage, null); - }); - }); - }); -} - -class _PrinterStub { - String? _lastLog; - String? get lastLoggedMessage => _lastLog; - - void print(Object object) { - _lastLog = object.toString(); - } -} diff --git a/test/device_connector_test.mocks.dart b/test/device_connector_test.mocks.dart deleted file mode 100644 index 67ba692a..00000000 --- a/test/device_connector_test.mocks.dart +++ /dev/null @@ -1,112 +0,0 @@ -// Mocks generated by Mockito 5.0.7 from annotations -// in flutter_reactive_ble/test/device_connector_test.dart. -// Do not manually edit this file. - -import 'dart:async' as _i3; - -import 'package:flutter_reactive_ble/src/device_scanner.dart' as _i6; -import 'package:flutter_reactive_ble/src/discovered_devices_registry.dart' - as _i9; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart' - as _i4; -import 'package:flutter_reactive_ble/src/model/discovered_device.dart' as _i7; -import 'package:flutter_reactive_ble/src/model/scan_mode.dart' as _i8; -import 'package:flutter_reactive_ble/src/model/uuid.dart' as _i5; -import 'package:flutter_reactive_ble/src/plugin_controller.dart' as _i2; -import 'package:mockito/mockito.dart' as _i1; - -// ignore_for_file: comment_references -// ignore_for_file: unnecessary_parenthesis - -// ignore_for_file: prefer_const_constructors - -// ignore_for_file: avoid_redundant_argument_values - -class _FakeDateTime extends _i1.Fake implements DateTime {} - -/// A class which mocks [DeviceConnectionController]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDeviceConnectionController extends _i1.Mock - implements _i2.DeviceConnectionController { - MockDeviceConnectionController() { - _i1.throwOnMissingStub(this); - } - - @override - _i3.Stream<_i4.ConnectionStateUpdate> get connectionUpdateStream => - (super.noSuchMethod(Invocation.getter(#connectionUpdateStream), - returnValue: Stream<_i4.ConnectionStateUpdate>.empty()) - as _i3.Stream<_i4.ConnectionStateUpdate>); - @override - _i3.Stream connectToDevice( - String? id, - Map<_i5.Uuid, List<_i5.Uuid>>? servicesWithCharacteristicsToDiscover, - Duration? connectionTimeout) => - (super.noSuchMethod( - Invocation.method(#connectToDevice, - [id, servicesWithCharacteristicsToDiscover, connectionTimeout]), - returnValue: Stream.empty()) as _i3.Stream); - @override - _i3.Future disconnectDevice(String? deviceId) => - (super.noSuchMethod(Invocation.method(#disconnectDevice, [deviceId]), - returnValue: Future.value(null), - returnValueForMissingStub: Future.value()) as _i3.Future); -} - -/// A class which mocks [DeviceScanner]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDeviceScanner extends _i1.Mock implements _i6.DeviceScanner { - MockDeviceScanner() { - _i1.throwOnMissingStub(this); - } - - @override - _i3.Stream<_i7.DiscoveredDevice> scanForDevices( - {List<_i5.Uuid>? withServices, - _i8.ScanMode? scanMode = _i8.ScanMode.balanced, - bool? requireLocationServicesEnabled = true}) => - (super.noSuchMethod( - Invocation.method(#scanForDevices, [], { - #withServices: withServices, - #scanMode: scanMode, - #requireLocationServicesEnabled: requireLocationServicesEnabled - }), - returnValue: Stream<_i7.DiscoveredDevice>.empty()) - as _i3.Stream<_i7.DiscoveredDevice>); -} - -/// A class which mocks [DiscoveredDevicesRegistry]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDiscoveredDevicesRegistry extends _i1.Mock - implements _i9.DiscoveredDevicesRegistry { - MockDiscoveredDevicesRegistry() { - _i1.throwOnMissingStub(this); - } - - @override - DateTime Function() get getTimestamp => - (super.noSuchMethod(Invocation.getter(#getTimestamp), - returnValue: () => _FakeDateTime()) as DateTime Function()); - @override - void add(String? deviceId) => - super.noSuchMethod(Invocation.method(#add, [deviceId]), - returnValueForMissingStub: null); - @override - void remove(String? deviceId) => - super.noSuchMethod(Invocation.method(#remove, [deviceId]), - returnValueForMissingStub: null); - @override - bool isEmpty() => - (super.noSuchMethod(Invocation.method(#isEmpty, []), returnValue: false) - as bool); - @override - bool deviceIsDiscoveredRecently( - {String? deviceId, Duration? cacheValidity}) => - (super.noSuchMethod( - Invocation.method(#deviceIsDiscoveredRecently, [], - {#deviceId: deviceId, #cacheValidity: cacheValidity}), - returnValue: false) as bool); -} diff --git a/test/device_scanner_test.mocks.dart b/test/device_scanner_test.mocks.dart deleted file mode 100644 index a4cff683..00000000 --- a/test/device_scanner_test.mocks.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Mocks generated by Mockito 5.0.7 from annotations -// in flutter_reactive_ble/test/device_scanner_test.dart. -// Do not manually edit this file. - -import 'dart:async' as _i3; - -import 'package:flutter_reactive_ble/src/model/discovered_device.dart' as _i4; -import 'package:flutter_reactive_ble/src/model/scan_mode.dart' as _i6; -import 'package:flutter_reactive_ble/src/model/uuid.dart' as _i5; -import 'package:flutter_reactive_ble/src/plugin_controller.dart' as _i2; -import 'package:mockito/mockito.dart' as _i1; - -// ignore_for_file: comment_references -// ignore_for_file: unnecessary_parenthesis - -// ignore_for_file: prefer_const_constructors - -// ignore_for_file: avoid_redundant_argument_values - -/// A class which mocks [ScanOperationController]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockScanOperationController extends _i1.Mock - implements _i2.ScanOperationController { - MockScanOperationController() { - _i1.throwOnMissingStub(this); - } - - @override - _i3.Stream<_i4.ScanResult> get scanStream => - (super.noSuchMethod(Invocation.getter(#scanStream), - returnValue: Stream<_i4.ScanResult>.empty()) - as _i3.Stream<_i4.ScanResult>); - @override - _i3.Stream scanForDevices( - {List<_i5.Uuid>? withServices, - _i6.ScanMode? scanMode, - bool? requireLocationServicesEnabled}) => - (super.noSuchMethod( - Invocation.method(#scanForDevices, [], { - #withServices: withServices, - #scanMode: scanMode, - #requireLocationServicesEnabled: requireLocationServicesEnabled - }), - returnValue: Stream.empty()) as _i3.Stream); -} diff --git a/test/discovered_devices_registry_test.dart b/test/discovered_devices_registry_test.dart deleted file mode 100644 index 4d90e461..00000000 --- a/test/discovered_devices_registry_test.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:flutter_reactive_ble/src/discovered_devices_registry.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group("$DiscoveredDevicesRegistry", () { - late DiscoveredDevicesRegistryImpl sut; - const device = "Testdevice"; - final timestamp = DateTime(2019); - - setUp(() { - sut = DiscoveredDevicesRegistryImpl(getTimestamp: () => timestamp); - }); - group('Given device is added', () { - setUp(() { - sut.add(device); - }); - - test("Device is in cache", () { - expect( - sut.deviceIsDiscoveredRecently( - deviceId: device, cacheValidity: const Duration(minutes: 10)), - true); - }); - - test("Device is not in cache", () { - expect( - sut.deviceIsDiscoveredRecently( - deviceId: "NotInCacheDevice", - cacheValidity: const Duration(seconds: 10)), - false); - }); - - test("Does not have duplicate entries", () { - sut.add(device); - - expect(sut.discoveredDevices.length, 1); - }); - - test("Returns false when entry exceeds cache limit", () { - final dateTime = DateTime(2018, 1, 1); - - final responses = [dateTime, timestamp]; - - sut = DiscoveredDevicesRegistryImpl( - getTimestamp: () => responses.removeAt(0), - )..add(device); - - expect( - sut.deviceIsDiscoveredRecently( - deviceId: device, cacheValidity: const Duration(days: 1)), - false); - }); - - test("Registry is empty in case last device is removed", () { - sut.remove(device); - expect(sut.isEmpty(), true); - }); - }); - }); -} diff --git a/test/plugin_controller_test.mocks.dart b/test/plugin_controller_test.mocks.dart deleted file mode 100644 index d1a3831f..00000000 --- a/test/plugin_controller_test.mocks.dart +++ /dev/null @@ -1,332 +0,0 @@ -// Mocks generated by Mockito 5.0.7 from annotations -// in flutter_reactive_ble/test/plugin_controller_test.dart. -// Do not manually edit this file. - -import 'dart:async' as _i24; - -import 'package:flutter/src/services/binary_messenger.dart' as _i10; -import 'package:flutter/src/services/message_codec.dart' as _i9; -import 'package:flutter/src/services/platform_channel.dart' as _i23; -import 'package:flutter_reactive_ble/src/converter/args_to_protubuf_converter.dart' - as _i13; -import 'package:flutter_reactive_ble/src/converter/protobuf_converter.dart' - as _i17; -import 'package:flutter_reactive_ble/src/debug_logger.dart' as _i11; -import 'package:flutter_reactive_ble/src/generated/bledata.pb.dart' as _i2; -import 'package:flutter_reactive_ble/src/model/ble_status.dart' as _i18; -import 'package:flutter_reactive_ble/src/model/characteristic_value.dart' - as _i6; -import 'package:flutter_reactive_ble/src/model/clear_gatt_cache_error.dart' - as _i21; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart' as _i8; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart' - as _i4; -import 'package:flutter_reactive_ble/src/model/discovered_device.dart' as _i3; -import 'package:flutter_reactive_ble/src/model/discovered_service.dart' as _i22; -import 'package:flutter_reactive_ble/src/model/generic_failure.dart' as _i20; -import 'package:flutter_reactive_ble/src/model/log_level.dart' as _i12; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart' - as _i15; -import 'package:flutter_reactive_ble/src/model/result.dart' as _i5; -import 'package:flutter_reactive_ble/src/model/scan_mode.dart' as _i16; -import 'package:flutter_reactive_ble/src/model/unit.dart' as _i19; -import 'package:flutter_reactive_ble/src/model/uuid.dart' as _i14; -import 'package:flutter_reactive_ble/src/model/write_characteristic_info.dart' - as _i7; -import 'package:mockito/mockito.dart' as _i1; - -// ignore_for_file: comment_references -// ignore_for_file: unnecessary_parenthesis - -// ignore_for_file: prefer_const_constructors - -// ignore_for_file: avoid_redundant_argument_values - -class _FakeConnectToDeviceRequest extends _i1.Fake - implements _i2.ConnectToDeviceRequest {} - -class _FakeDisconnectFromDeviceRequest extends _i1.Fake - implements _i2.DisconnectFromDeviceRequest {} - -class _FakeReadCharacteristicRequest extends _i1.Fake - implements _i2.ReadCharacteristicRequest {} - -class _FakeWriteCharacteristicRequest extends _i1.Fake - implements _i2.WriteCharacteristicRequest {} - -class _FakeNotifyCharacteristicRequest extends _i1.Fake - implements _i2.NotifyCharacteristicRequest {} - -class _FakeNotifyNoMoreCharacteristicRequest extends _i1.Fake - implements _i2.NotifyNoMoreCharacteristicRequest {} - -class _FakeNegotiateMtuRequest extends _i1.Fake - implements _i2.NegotiateMtuRequest {} - -class _FakeChangeConnectionPriorityRequest extends _i1.Fake - implements _i2.ChangeConnectionPriorityRequest {} - -class _FakeScanForDevicesRequest extends _i1.Fake - implements _i2.ScanForDevicesRequest {} - -class _FakeClearGattCacheRequest extends _i1.Fake - implements _i2.ClearGattCacheRequest {} - -class _FakeDiscoverServicesRequest extends _i1.Fake - implements _i2.DiscoverServicesRequest {} - -class _FakeScanResult extends _i1.Fake implements _i3.ScanResult {} - -class _FakeConnectionStateUpdate extends _i1.Fake - implements _i4.ConnectionStateUpdate {} - -class _FakeResult extends _i1.Fake - implements _i5.Result {} - -class _FakeCharacteristicValue extends _i1.Fake - implements _i6.CharacteristicValue {} - -class _FakeWriteCharacteristicInfo extends _i1.Fake - implements _i7.WriteCharacteristicInfo {} - -class _FakeConnectionPriorityInfo extends _i1.Fake - implements _i8.ConnectionPriorityInfo {} - -class _FakeMethodCodec extends _i1.Fake implements _i9.MethodCodec {} - -class _FakeBinaryMessenger extends _i1.Fake implements _i10.BinaryMessenger {} - -/// A class which mocks [Logger]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockLogger extends _i1.Mock implements _i11.Logger { - MockLogger() { - _i1.throwOnMissingStub(this); - } - - @override - set logLevel(_i12.LogLevel? logLevel) => - super.noSuchMethod(Invocation.setter(#logLevel, logLevel), - returnValueForMissingStub: null); - @override - void log(Object? message) => - super.noSuchMethod(Invocation.method(#log, [message]), - returnValueForMissingStub: null); -} - -/// A class which mocks [ArgsToProtobufConverter]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockArgsToProtobufConverter extends _i1.Mock - implements _i13.ArgsToProtobufConverter { - MockArgsToProtobufConverter() { - _i1.throwOnMissingStub(this); - } - - @override - _i2.ConnectToDeviceRequest createConnectToDeviceArgs( - String? id, - Map<_i14.Uuid, List<_i14.Uuid>>? - servicesWithCharacteristicsToDiscover, - Duration? connectionTimeout) => - (super.noSuchMethod( - Invocation.method(#createConnectToDeviceArgs, [ - id, - servicesWithCharacteristicsToDiscover, - connectionTimeout - ]), - returnValue: _FakeConnectToDeviceRequest()) - as _i2.ConnectToDeviceRequest); - @override - _i2.DisconnectFromDeviceRequest createDisconnectDeviceArgs( - String? deviceId) => - (super.noSuchMethod( - Invocation.method(#createDisconnectDeviceArgs, [deviceId]), - returnValue: _FakeDisconnectFromDeviceRequest()) - as _i2.DisconnectFromDeviceRequest); - @override - _i2.ReadCharacteristicRequest createReadCharacteristicRequest( - _i15.QualifiedCharacteristic? characteristic) => - (super.noSuchMethod( - Invocation.method(#createReadCharacteristicRequest, [characteristic]), - returnValue: - _FakeReadCharacteristicRequest()) as _i2 - .ReadCharacteristicRequest); - @override - _i2.WriteCharacteristicRequest createWriteChacracteristicRequest( - _i15.QualifiedCharacteristic? characteristic, List? value) => - (super.noSuchMethod( - Invocation.method( - #createWriteChacracteristicRequest, [characteristic, value]), - returnValue: _FakeWriteCharacteristicRequest()) - as _i2.WriteCharacteristicRequest); - @override - _i2.NotifyCharacteristicRequest createNotifyCharacteristicRequest( - _i15.QualifiedCharacteristic? characteristic) => - (super.noSuchMethod( - Invocation.method( - #createNotifyCharacteristicRequest, [characteristic]), - returnValue: _FakeNotifyCharacteristicRequest()) - as _i2.NotifyCharacteristicRequest); - @override - _i2.NotifyNoMoreCharacteristicRequest createNotifyNoMoreCharacteristicRequest( - _i15.QualifiedCharacteristic? characteristic) => - (super.noSuchMethod( - Invocation.method( - #createNotifyNoMoreCharacteristicRequest, [characteristic]), - returnValue: _FakeNotifyNoMoreCharacteristicRequest()) - as _i2.NotifyNoMoreCharacteristicRequest); - @override - _i2.NegotiateMtuRequest createNegotiateMtuRequest( - String? deviceId, int? mtu) => - (super.noSuchMethod( - Invocation.method(#createNegotiateMtuRequest, [deviceId, mtu]), - returnValue: _FakeNegotiateMtuRequest()) as _i2.NegotiateMtuRequest); - @override - _i2.ChangeConnectionPriorityRequest createChangeConnectionPrioRequest( - String? deviceId, _i8.ConnectionPriority? priority) => - (super.noSuchMethod( - Invocation.method( - #createChangeConnectionPrioRequest, [deviceId, priority]), - returnValue: _FakeChangeConnectionPriorityRequest()) - as _i2.ChangeConnectionPriorityRequest); - @override - _i2.ScanForDevicesRequest createScanForDevicesRequest( - {List<_i14.Uuid>? withServices, - _i16.ScanMode? scanMode, - bool? requireLocationServicesEnabled}) => - (super.noSuchMethod( - Invocation.method(#createScanForDevicesRequest, [], { - #withServices: withServices, - #scanMode: scanMode, - #requireLocationServicesEnabled: requireLocationServicesEnabled - }), - returnValue: _FakeScanForDevicesRequest()) - as _i2.ScanForDevicesRequest); - @override - _i2.ClearGattCacheRequest createClearGattCacheRequest(String? deviceId) => - (super.noSuchMethod( - Invocation.method(#createClearGattCacheRequest, [deviceId]), - returnValue: _FakeClearGattCacheRequest()) - as _i2.ClearGattCacheRequest); - @override - _i2.DiscoverServicesRequest createDiscoverServicesRequest(String? deviceId) => - (super.noSuchMethod( - Invocation.method(#createDiscoverServicesRequest, [deviceId]), - returnValue: _FakeDiscoverServicesRequest()) - as _i2.DiscoverServicesRequest); -} - -/// A class which mocks [ProtobufConverter]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockProtobufConverter extends _i1.Mock implements _i17.ProtobufConverter { - MockProtobufConverter() { - _i1.throwOnMissingStub(this); - } - - @override - _i18.BleStatus bleStatusFrom(List? data) => - (super.noSuchMethod(Invocation.method(#bleStatusFrom, [data]), - returnValue: _i18.BleStatus.unknown) as _i18.BleStatus); - @override - _i3.ScanResult scanResultFrom(List? data) => - (super.noSuchMethod(Invocation.method(#scanResultFrom, [data]), - returnValue: _FakeScanResult()) as _i3.ScanResult); - @override - _i4.ConnectionStateUpdate connectionStateUpdateFrom(List? data) => - (super.noSuchMethod(Invocation.method(#connectionStateUpdateFrom, [data]), - returnValue: _FakeConnectionStateUpdate()) - as _i4.ConnectionStateUpdate); - @override - _i5.Result<_i19.Unit, _i20.GenericFailure<_i21.ClearGattCacheError>?> - clearGattCacheResultFrom(List? data) => (super.noSuchMethod( - Invocation.method(#clearGattCacheResultFrom, [data]), - returnValue: _FakeResult<_i19.Unit, - _i20.GenericFailure<_i21.ClearGattCacheError>?>()) as _i5 - .Result<_i19.Unit, _i20.GenericFailure<_i21.ClearGattCacheError>?>); - @override - _i6.CharacteristicValue characteristicValueFrom(List? data) => - (super.noSuchMethod(Invocation.method(#characteristicValueFrom, [data]), - returnValue: _FakeCharacteristicValue()) as _i6.CharacteristicValue); - @override - _i7.WriteCharacteristicInfo writeCharacteristicInfoFrom(List? data) => - (super.noSuchMethod( - Invocation.method(#writeCharacteristicInfoFrom, [data]), - returnValue: _FakeWriteCharacteristicInfo()) - as _i7.WriteCharacteristicInfo); - @override - _i8.ConnectionPriorityInfo connectionPriorityInfoFrom(List? data) => - (super.noSuchMethod( - Invocation.method(#connectionPriorityInfoFrom, [data]), - returnValue: _FakeConnectionPriorityInfo()) - as _i8.ConnectionPriorityInfo); - @override - int mtuSizeFrom(List? data) => (super - .noSuchMethod(Invocation.method(#mtuSizeFrom, [data]), returnValue: 0) - as int); - @override - List<_i22.DiscoveredService> discoveredServicesFrom(List? data) => - (super.noSuchMethod(Invocation.method(#discoveredServicesFrom, [data]), - returnValue: <_i22.DiscoveredService>[]) - as List<_i22.DiscoveredService>); -} - -/// A class which mocks [MethodChannel]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockMethodChannel extends _i1.Mock implements _i23.MethodChannel { - MockMethodChannel() { - _i1.throwOnMissingStub(this); - } - - @override - String get name => - (super.noSuchMethod(Invocation.getter(#name), returnValue: '') as String); - @override - _i9.MethodCodec get codec => (super.noSuchMethod(Invocation.getter(#codec), - returnValue: _FakeMethodCodec()) as _i9.MethodCodec); - @override - _i10.BinaryMessenger get binaryMessenger => - (super.noSuchMethod(Invocation.getter(#binaryMessenger), - returnValue: _FakeBinaryMessenger()) as _i10.BinaryMessenger); - @override - _i24.Future invokeMethod(String? method, [dynamic arguments]) => - (super.noSuchMethod(Invocation.method(#invokeMethod, [method, arguments]), - returnValue: Future.value(null)) as _i24.Future); - @override - _i24.Future?> invokeListMethod(String? method, - [dynamic arguments]) => - (super.noSuchMethod( - Invocation.method(#invokeListMethod, [method, arguments]), - returnValue: Future?>.value([])) as _i24.Future?>); - @override - _i24.Future?> invokeMapMethod(String? method, - [dynamic arguments]) => - (super.noSuchMethod( - Invocation.method(#invokeMapMethod, [method, arguments]), - returnValue: Future?>.value({})) - as _i24.Future?>); - @override - void setMethodCallHandler( - _i24.Future Function(_i9.MethodCall)? handler) => - super.noSuchMethod(Invocation.method(#setMethodCallHandler, [handler]), - returnValueForMissingStub: null); - @override - bool checkMethodCallHandler( - _i24.Future Function(_i9.MethodCall)? handler) => - (super.noSuchMethod(Invocation.method(#checkMethodCallHandler, [handler]), - returnValue: false) as bool); - @override - void setMockMethodCallHandler( - _i24.Future? Function(_i9.MethodCall)? handler) => - super.noSuchMethod( - Invocation.method(#setMockMethodCallHandler, [handler]), - returnValueForMissingStub: null); - @override - bool checkMockMethodCallHandler( - _i24.Future Function(_i9.MethodCall)? handler) => - (super.noSuchMethod( - Invocation.method(#checkMockMethodCallHandler, [handler]), - returnValue: false) as bool); -} diff --git a/test/reactive_ble_test.mocks.dart b/test/reactive_ble_test.mocks.dart deleted file mode 100644 index eb38fa0f..00000000 --- a/test/reactive_ble_test.mocks.dart +++ /dev/null @@ -1,233 +0,0 @@ -// Mocks generated by Mockito 5.0.7 from annotations -// in flutter_reactive_ble/test/reactive_ble_test.dart. -// Do not manually edit this file. - -import 'dart:async' as _i4; - -import 'package:flutter_reactive_ble/src/connected_device_operation.dart' - as _i11; -import 'package:flutter_reactive_ble/src/debug_logger.dart' as _i9; -import 'package:flutter_reactive_ble/src/device_connector.dart' as _i16; -import 'package:flutter_reactive_ble/src/device_scanner.dart' as _i19; -import 'package:flutter_reactive_ble/src/model/ble_status.dart' as _i5; -import 'package:flutter_reactive_ble/src/model/characteristic_value.dart' - as _i12; -import 'package:flutter_reactive_ble/src/model/clear_gatt_cache_error.dart' - as _i8; -import 'package:flutter_reactive_ble/src/model/connection_priority.dart' - as _i15; -import 'package:flutter_reactive_ble/src/model/connection_state_update.dart' - as _i17; -import 'package:flutter_reactive_ble/src/model/discovered_device.dart' as _i20; -import 'package:flutter_reactive_ble/src/model/discovered_service.dart' as _i14; -import 'package:flutter_reactive_ble/src/model/generic_failure.dart' as _i7; -import 'package:flutter_reactive_ble/src/model/log_level.dart' as _i10; -import 'package:flutter_reactive_ble/src/model/qualified_characteristic.dart' - as _i13; -import 'package:flutter_reactive_ble/src/model/result.dart' as _i2; -import 'package:flutter_reactive_ble/src/model/scan_mode.dart' as _i21; -import 'package:flutter_reactive_ble/src/model/unit.dart' as _i6; -import 'package:flutter_reactive_ble/src/model/uuid.dart' as _i18; -import 'package:flutter_reactive_ble/src/plugin_controller.dart' as _i3; -import 'package:mockito/mockito.dart' as _i1; - -// ignore_for_file: comment_references -// ignore_for_file: unnecessary_parenthesis - -// ignore_for_file: prefer_const_constructors - -// ignore_for_file: avoid_redundant_argument_values - -class _FakeResult extends _i1.Fake - implements _i2.Result {} - -/// A class which mocks [BleOperationController]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockBleOperationController extends _i1.Mock - implements _i3.BleOperationController { - MockBleOperationController() { - _i1.throwOnMissingStub(this); - } - - @override - _i4.Stream<_i5.BleStatus> get bleStatusStream => (super.noSuchMethod( - Invocation.getter(#bleStatusStream), - returnValue: Stream<_i5.BleStatus>.empty()) as _i4.Stream<_i5.BleStatus>); - @override - _i4.Future initialize() => - (super.noSuchMethod(Invocation.method(#initialize, []), - returnValue: Future.value(null), - returnValueForMissingStub: Future.value()) as _i4.Future); - @override - _i4.Future deinitialize() => - (super.noSuchMethod(Invocation.method(#deinitialize, []), - returnValue: Future.value(null), - returnValueForMissingStub: Future.value()) as _i4.Future); - @override - _i4.Future<_i2.Result<_i6.Unit, _i7.GenericFailure<_i8.ClearGattCacheError>?>> - clearGattCache(String? deviceId) => (super.noSuchMethod( - Invocation.method(#clearGattCache, [deviceId]), - returnValue: - Future<_i2.Result<_i6.Unit, _i7.GenericFailure<_i8.ClearGattCacheError>?>>.value( - _FakeResult<_i6.Unit, _i7.GenericFailure<_i8.ClearGattCacheError>?>())) - as _i4.Future< - _i2.Result<_i6.Unit, _i7.GenericFailure<_i8.ClearGattCacheError>?>>); -} - -/// A class which mocks [Logger]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockLogger extends _i1.Mock implements _i9.Logger { - MockLogger() { - _i1.throwOnMissingStub(this); - } - - @override - set logLevel(_i10.LogLevel? logLevel) => - super.noSuchMethod(Invocation.setter(#logLevel, logLevel), - returnValueForMissingStub: null); - @override - void log(Object? message) => - super.noSuchMethod(Invocation.method(#log, [message]), - returnValueForMissingStub: null); -} - -/// A class which mocks [ConnectedDeviceOperation]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockConnectedDeviceOperation extends _i1.Mock - implements _i11.ConnectedDeviceOperation { - MockConnectedDeviceOperation() { - _i1.throwOnMissingStub(this); - } - - @override - _i4.Stream<_i12.CharacteristicValue> get characteristicValueStream => - (super.noSuchMethod(Invocation.getter(#characteristicValueStream), - returnValue: Stream<_i12.CharacteristicValue>.empty()) - as _i4.Stream<_i12.CharacteristicValue>); - @override - _i4.Future> readCharacteristic( - _i13.QualifiedCharacteristic? characteristic) => - (super.noSuchMethod( - Invocation.method(#readCharacteristic, [characteristic]), - returnValue: Future>.value([])) - as _i4.Future>); - @override - _i4.Future writeCharacteristicWithResponse( - _i13.QualifiedCharacteristic? characteristic, - {List? value}) => - (super.noSuchMethod( - Invocation.method(#writeCharacteristicWithResponse, [characteristic], - {#value: value}), - returnValue: Future.value(null), - returnValueForMissingStub: Future.value()) as _i4.Future); - @override - _i4.Future writeCharacteristicWithoutResponse( - _i13.QualifiedCharacteristic? characteristic, - {List? value}) => - (super.noSuchMethod( - Invocation.method(#writeCharacteristicWithoutResponse, - [characteristic], {#value: value}), - returnValue: Future.value(null), - returnValueForMissingStub: Future.value()) as _i4.Future); - @override - _i4.Stream> subscribeToCharacteristic( - _i13.QualifiedCharacteristic? characteristic, - _i4.Future? isDisconnected) => - (super.noSuchMethod( - Invocation.method( - #subscribeToCharacteristic, [characteristic, isDisconnected]), - returnValue: Stream>.empty()) as _i4.Stream>); - @override - _i4.Future requestMtu(String? deviceId, int? mtu) => - (super.noSuchMethod(Invocation.method(#requestMtu, [deviceId, mtu]), - returnValue: Future.value(0)) as _i4.Future); - @override - _i4.Future> discoverServices(String? deviceId) => - (super.noSuchMethod(Invocation.method(#discoverServices, [deviceId]), - returnValue: Future>.value( - <_i14.DiscoveredService>[])) - as _i4.Future>); - @override - _i4.Future requestConnectionPriority( - String? deviceId, _i15.ConnectionPriority? priority) => - (super.noSuchMethod( - Invocation.method(#requestConnectionPriority, [deviceId, priority]), - returnValue: Future.value(null), - returnValueForMissingStub: Future.value()) as _i4.Future); -} - -/// A class which mocks [DeviceConnector]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDeviceConnector extends _i1.Mock implements _i16.DeviceConnector { - MockDeviceConnector() { - _i1.throwOnMissingStub(this); - } - - @override - _i4.Stream<_i17.ConnectionStateUpdate> - get deviceConnectionStateUpdateStream => (super.noSuchMethod( - Invocation.getter(#deviceConnectionStateUpdateStream), - returnValue: Stream<_i17.ConnectionStateUpdate>.empty()) - as _i4.Stream<_i17.ConnectionStateUpdate>); - @override - _i4.Stream<_i17.ConnectionStateUpdate> connect( - {String? id, - Map<_i18.Uuid, List<_i18.Uuid>>? - servicesWithCharacteristicsToDiscover, - Duration? connectionTimeout}) => - (super.noSuchMethod( - Invocation.method(#connect, [], { - #id: id, - #servicesWithCharacteristicsToDiscover: - servicesWithCharacteristicsToDiscover, - #connectionTimeout: connectionTimeout - }), - returnValue: Stream<_i17.ConnectionStateUpdate>.empty()) - as _i4.Stream<_i17.ConnectionStateUpdate>); - @override - _i4.Stream<_i17.ConnectionStateUpdate> connectToAdvertisingDevice( - {String? id, - List<_i18.Uuid>? withServices, - Duration? prescanDuration, - Map<_i18.Uuid, List<_i18.Uuid>>? - servicesWithCharacteristicsToDiscover, - Duration? connectionTimeout}) => - (super.noSuchMethod( - Invocation.method(#connectToAdvertisingDevice, [], { - #id: id, - #withServices: withServices, - #prescanDuration: prescanDuration, - #servicesWithCharacteristicsToDiscover: - servicesWithCharacteristicsToDiscover, - #connectionTimeout: connectionTimeout - }), - returnValue: Stream<_i17.ConnectionStateUpdate>.empty()) - as _i4.Stream<_i17.ConnectionStateUpdate>); -} - -/// A class which mocks [DeviceScanner]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDeviceScanner extends _i1.Mock implements _i19.DeviceScanner { - MockDeviceScanner() { - _i1.throwOnMissingStub(this); - } - - @override - _i4.Stream<_i20.DiscoveredDevice> scanForDevices( - {List<_i18.Uuid>? withServices, - _i21.ScanMode? scanMode = _i21.ScanMode.balanced, - bool? requireLocationServicesEnabled = true}) => - (super.noSuchMethod( - Invocation.method(#scanForDevices, [], { - #withServices: withServices, - #scanMode: scanMode, - #requireLocationServicesEnabled: requireLocationServicesEnabled - }), - returnValue: Stream<_i20.DiscoveredDevice>.empty()) - as _i4.Stream<_i20.DiscoveredDevice>); -} diff --git a/test/result_test.dart b/test/result_test.dart deleted file mode 100644 index 1715f636..00000000 --- a/test/result_test.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter_reactive_ble/src/model/result.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group("Result", () { - test("executes the failure branch for a non-null failure object", () { - const failureObject = 1; - const sut = Result.failure(failureObject); - final handler = _ResultHandler(); - - final result = - sut.iif(success: handler.success, failure: handler.failure); - - expect(result, failureObject); - }); - - test("executes the success branch for a non-null success value", () { - const value = 1; - const sut = Result.success(value); - final handler = _ResultHandler(); - - final result = - sut.iif(success: handler.success, failure: handler.failure); - - expect(result, value); - }); - - test("throws failure as is", () { - final failureObject = Exception(); - final sut = Result.failure(failureObject); - - expect(sut.dematerialize, throwsA(failureObject)); - }); - - test("throws failure wrapping in an exception", () { - const failureObject = 1; - const sut = Result.failure(failureObject); - - expect(sut.dematerialize, throwsException); - }); - }); -} - -class _ResultHandler { - T success(Value value) => value as T; - T failure(Failure failure) => failure as T; -} diff --git a/test/rx_ext/repeater_test.dart b/test/rx_ext/repeater_test.dart deleted file mode 100644 index ad1f37ec..00000000 --- a/test/rx_ext/repeater_test.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'dart:async'; - -import 'package:flutter_reactive_ble/src/rx_ext/repeater.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group("Repeater", () { - late StreamController underlyingStreamController; - late _RepeaterHandler handler; - - setUp(() { - underlyingStreamController = StreamController(sync: true); - handler = _RepeaterHandler(underlyingStreamController.stream); - }); - - tearDown(() { - underlyingStreamController.close(); - }); - - group('Repeater internals', () { - late Repeater sut; - - setUp(() { - sut = Repeater( - onListenEmitFrom: handler.onListenEmitFrom, - onCancel: handler.onCancel, - isSync: true, - ); - }); - group('Has subscription', () { - late StreamSubscription subscription; - - setUp(() { - subscription = sut.stream.listen((_) {}); - }); - - test("subscribes to the underlying stream when a listener connects", - () { - expect(underlyingStreamController.hasListener, true); - }); - test( - "unsubscribes from the underlying stream when there are no listeners left", - () async { - await subscription.cancel(); - - expect(underlyingStreamController.hasListener, false); - }); - - test("unsubscribes from the underlying stream when detached", () async { - await sut.detach(); - - expect(underlyingStreamController.hasListener, false); - }); - - test("unsubscribes from the underlying stream when disposed", () async { - await sut.dispose(); - - expect(underlyingStreamController.hasListener, false); - }); - - test("safely disposes when has not been listened to", () { - expect(() async => sut.dispose(), returnsNormally); - }); - }); - }); - - group('Broadcast repeater', () { - late Repeater sut; - - setUp(() { - sut = Repeater.broadcast( - onListenEmitFrom: handler.onListenEmitFrom, - onCancel: handler.onCancel, - isSync: true, - ); - }); - - test('It converts non broadcast stream to abroadcast stream', () { - expect(sut.stream.isBroadcast, true); - }); - }); - - group('Repeater from stream', () { - Repeater sut; - late StreamSubscription subscription; - - setUp(() { - sut = Repeater.fromStream(underlyingStreamController.stream); - subscription = sut.stream.listen((_) {}); - }); - - tearDown(() async { - await subscription.cancel(); - }); - - test('It subscribes to stream supplied in constructor', () { - expect(underlyingStreamController.hasListener, true); - }); - - test('It pauses the stream when pause is called', () async { - subscription.pause(); - expect(underlyingStreamController.isPaused, true); - }); - - test( - 'Repeater returns broadcast stream in case source is a broadcast stream', - () { - sut = Repeater.fromStream( - underlyingStreamController.stream.asBroadcastStream()); - - expect(sut.stream.isBroadcast, true); - }); - }); - }); -} - -class _RepeaterHandler { - const _RepeaterHandler(Stream stream) : _stream = stream; - final Stream _stream; - Stream onListenEmitFrom() => _stream; - - Future onCancel() async {} -} diff --git a/test/uuid_test.dart b/test/uuid_test.dart deleted file mode 100644 index c05a1a61..00000000 --- a/test/uuid_test.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter_reactive_ble/src/model/uuid.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group("Uuid", () { - group("128-bit", () { - const sampleText = "00112233-4455-6677-8899-aabbccddeeff"; - const sampleData = [ - 0x00, - 0x11, - 0x22, - 0x33, - 0x44, - 0x55, - 0x66, - 0x77, - 0x88, - 0x99, - 0xaa, - 0xbb, - 0xcc, - 0xdd, - 0xee, - 0xff - ]; - - test("parses text", () { - final uuid = Uuid.parse(sampleText); - expect(uuid.data, sampleData); - }); - - test("serializes to text", () { - final uuid = Uuid(sampleData); - expect(uuid.toString().toLowerCase(), sampleText.toLowerCase()); - }); - }); - group("32-bit", () { - const sampleText = "00112233"; - const sampleData = [0x00, 0x11, 0x22, 0x33]; - - test("parses text", () { - final uuid = Uuid.parse(sampleText); - expect(uuid.data, sampleData); - }); - - test("serializes to text", () { - final uuid = Uuid(sampleData); - expect(uuid.toString().toLowerCase(), sampleText.toLowerCase()); - }); - }); - group("16-bit", () { - const sampleText = "0011"; - const sampleData = [0x00, 0x11]; - - test("parses text", () { - final uuid = Uuid.parse(sampleText); - expect(uuid.data, sampleData); - }); - - test("serializes to text", () { - final uuid = Uuid(sampleData); - expect(uuid.toString().toLowerCase(), sampleText.toLowerCase()); - }); - }); - }); -}