From cd986b00dd682b124dde385c1fb017eef9bba070 Mon Sep 17 00:00:00 2001 From: Dennis Moschina <45356478+DennisMoschina@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:22:08 +0100 Subject: [PATCH] identify sensor streams by wearable and sensor to avoid collisions --- open_wearable/lib/models/sensor_streams.dart | 33 ++++++++++++++++--- .../lib/view_models/sensor_data_provider.dart | 8 +++-- .../view_models/sensor_recorder_provider.dart | 5 ++- .../lib/widgets/sensors/sensor_page.dart | 5 ++- .../sensors/values/sensor_values_page.dart | 5 ++- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/open_wearable/lib/models/sensor_streams.dart b/open_wearable/lib/models/sensor_streams.dart index 68235fd7..46600f69 100644 --- a/open_wearable/lib/models/sensor_streams.dart +++ b/open_wearable/lib/models/sensor_streams.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:collection'; import 'package:open_earable_flutter/open_earable_flutter.dart'; @@ -7,16 +8,38 @@ import 'package:open_earable_flutter/open_earable_flutter.dart'; class SensorStreams { SensorStreams._(); - static final Map> _sharedStreams = {}; + static final Map>> + _sharedStreamsByDevice = {}; + static Map> _createIdentitySensorStreamMap() => + LinkedHashMap>.identity(); - static Stream shared(Sensor sensor) { - return _sharedStreams.putIfAbsent( + static Stream shared({ + required Wearable wearable, + required Sensor sensor, + }) { + final deviceStreams = _sharedStreamsByDevice.putIfAbsent( + wearable.deviceId, + // Identity map avoids collisions when Sensor overrides ==/hashCode + // non-uniquely across different devices. + _createIdentitySensorStreamMap, + ); + return deviceStreams.putIfAbsent( sensor, () => sensor.sensorStream.asBroadcastStream(), ); } - static void clearForSensor(Sensor sensor) { - _sharedStreams.remove(sensor); + static void clearForSensor({ + required Wearable wearable, + required Sensor sensor, + }) { + final deviceStreams = _sharedStreamsByDevice[wearable.deviceId]; + if (deviceStreams == null) { + return; + } + deviceStreams.remove(sensor); + if (deviceStreams.isEmpty) { + _sharedStreamsByDevice.remove(wearable.deviceId); + } } } diff --git a/open_wearable/lib/view_models/sensor_data_provider.dart b/open_wearable/lib/view_models/sensor_data_provider.dart index 8c2af178..1d896286 100644 --- a/open_wearable/lib/view_models/sensor_data_provider.dart +++ b/open_wearable/lib/view_models/sensor_data_provider.dart @@ -7,6 +7,7 @@ import 'package:open_earable_flutter/open_earable_flutter.dart'; import 'package:open_wearable/models/sensor_streams.dart'; class SensorDataProvider with ChangeNotifier { + final Wearable wearable; final Sensor sensor; final int timeWindow; // seconds @@ -26,6 +27,7 @@ class SensorDataProvider with ChangeNotifier { DateTime? _lastSensorArrivalTime; SensorDataProvider({ + required this.wearable, required this.sensor, this.timeWindow = 5, }) { @@ -52,8 +54,10 @@ class SensorDataProvider with ChangeNotifier { } void _listenToStream() { - _sensorStreamSubscription = - SensorStreams.shared(sensor).listen((sensorValue) { + _sensorStreamSubscription = SensorStreams.shared( + wearable: wearable, + sensor: sensor, + ).listen((sensorValue) { sensorValues.add(sensorValue); _lastSensorTimestamp = sensorValue.timestamp; _lastSensorArrivalTime = DateTime.now(); diff --git a/open_wearable/lib/view_models/sensor_recorder_provider.dart b/open_wearable/lib/view_models/sensor_recorder_provider.dart index 00ab29fb..b0effc3a 100644 --- a/open_wearable/lib/view_models/sensor_recorder_provider.dart +++ b/open_wearable/lib/view_models/sensor_recorder_provider.dart @@ -148,7 +148,10 @@ class SensorRecorderProvider with ChangeNotifier { File file = await recorder.start( filepath: filepath, - inputStream: SensorStreams.shared(sensor), + inputStream: SensorStreams.shared( + wearable: wearable, + sensor: sensor, + ), ); logger.i( diff --git a/open_wearable/lib/widgets/sensors/sensor_page.dart b/open_wearable/lib/widgets/sensors/sensor_page.dart index cc8e9f7b..6b5fdf86 100644 --- a/open_wearable/lib/widgets/sensors/sensor_page.dart +++ b/open_wearable/lib/widgets/sensors/sensor_page.dart @@ -189,7 +189,10 @@ class _SensorPageState extends State in wearable.requireCapability().sensors) { _sensorDataProviders.putIfAbsent( (wearable, sensor), - () => SensorDataProvider(sensor: sensor), + () => SensorDataProvider( + wearable: wearable, + sensor: sensor, + ), ); } } diff --git a/open_wearable/lib/widgets/sensors/values/sensor_values_page.dart b/open_wearable/lib/widgets/sensors/values/sensor_values_page.dart index b3483772..f847afa7 100644 --- a/open_wearable/lib/widgets/sensors/values/sensor_values_page.dart +++ b/open_wearable/lib/widgets/sensors/values/sensor_values_page.dart @@ -144,7 +144,10 @@ class _SensorValuesPageState extends State in wearable.requireCapability().sensors) { _sensorDataProvider.putIfAbsent( (wearable, sensor), - () => SensorDataProvider(sensor: sensor), + () => SensorDataProvider( + wearable: wearable, + sensor: sensor, + ), ); } }