Commit 1995d8f

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-06-14 13:35:55
minor bugfixes and code quality improvements
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 4133bf8
Changed files (5)
app/lib/components/ble_input/measurement_characteristic.dart → app/lib/bluetooth/characteristics/measurement_characteristic.dart
File renamed without changes
app/lib/bluetooth/ble_read_cubit.dart
@@ -34,11 +34,14 @@ class BleReadCubit extends Cubit<BleReadState> {
     : super(BleReadInProgress()){
     _subscription = _device.connectionState
       .listen(_onConnectionStateChanged);
+    _device.cancelWhenDisconnected(_device.mtu.listen((int mtu) => Log.trace('BleReadCubit mtu: $mtu'))); // TODO: remove
     // timeout
-    Timer(const Duration(minutes: 2), () {
-      if (super.state is BleReadInProgress) {
-        Log.trace('BleReadCubit timeout reached');
+    _timeoutTimer = Timer(const Duration(minutes: 2), () {
+      if (state is BleReadInProgress) {
+        Log.trace('BleReadCubit timeout reached and still running');
         emit(BleReadFailure());
+      } else {
+        Log.trace('BleReadCubit timeout reached with state: $state, ${state is BleReadInProgress}');
       }
     });
   }
@@ -46,8 +49,6 @@ class BleReadCubit extends Cubit<BleReadState> {
   static const String _kServiceID = '1810';
   static const String _kCharacteristicID = '2a35';
 
-  // TODO: consider using Future for this
-
   /// Bluetooth device to connect to.
   ///
   /// Must have an active established connection and support the measurement
@@ -55,11 +56,14 @@ class BleReadCubit extends Cubit<BleReadState> {
   final BluetoothDevice _device;
   
   late final StreamSubscription<BluetoothConnectionState> _subscription;
+  late final Timer _timeoutTimer;
 
   @override
   Future<void> close() async {
+    Log.trace('BleReadCubit close');
     await _subscription.cancel();
-    
+    _timeoutTimer.cancel();
+
     if (_device.isConnected) {
       try {
         Log.trace('BleReadCubit close: Attempting disconnect from ${_device.advName}');
@@ -87,27 +91,36 @@ class BleReadCubit extends Cubit<BleReadState> {
     
     if (_device.isDisconnected) {
       Log.trace('BleReadCubit _ensureConnection: Attempting to connect with ${_device.advName}');
-      await _device.connect();
+      try {
+        await _device.connect();
+      } on FlutterBluePlusException catch (e) {
+        Log.err('BleReadCubit _device.connect failed:', [_device, e]);
+      }
+
 
       if (_device.isDisconnected) {
         Log.trace('BleReadCubit _ensureConnection: Device not connected');
         emit(BleReadFailure());
+        if (kDebugMode) _debugEnsureConnectionInProgress = false;
+        return;
       } else {
         Log.trace('BleReadCubit Connection successful');
       }
     }
+    assert(_device.isConnected);
     if (kDebugMode) _debugEnsureConnectionInProgress = false;
   }
 
   Future<void> _onConnectionStateChanged(BluetoothConnectionState state) async {
     Log.trace('BleReadCubit _onConnectionStateChanged: $state');
     if (state == BluetoothConnectionState.disconnected) {
+      Log.trace('BleReadCubit _onConnectionStateChanged disconnected: '
+        '${_device.disconnectReason} Attempting reconnect');
       await _ensureConnection();
       return;
     }
     assert(state == BluetoothConnectionState.connected, 'state should be '
       'connected as connecting and disconnecting are not streamed by android');
-
     assert(_device.isConnected);
 
     // Query actual services supported by the device. While they must be
@@ -122,10 +135,10 @@ class BleReadCubit extends Cubit<BleReadState> {
       return;
     }
 
-
     // [Guid.str] trims standard parts from the uuid. 0x1810 is the blood
     // pressure uuid. https://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v4.x.x/doc/html/group___u_u_i_d___s_e_r_v_i_c_e_s.html
-    final service = allServices.firstWhereOrNull((s) => s.uuid.str == _kServiceID);
+    final BluetoothService? service = allServices
+      .firstWhereOrNull((BluetoothService s) => s.uuid.str == _kServiceID);
     if (service == null) {
       Log.err('unsupported service', [_device, allServices]);
       emit(BleReadFailure());
@@ -133,10 +146,10 @@ class BleReadCubit extends Cubit<BleReadState> {
     }
 
     // https://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v4.x.x/doc/html/group___u_u_i_d___c_h_a_r_a_c_t_e_r_i_s_t_i_c_s.html#ga95fc99c7a99cf9d991c81027e4866936
-    final allCharacteristics = service.characteristics;
+    final List<BluetoothCharacteristic> allCharacteristics = service.characteristics;
     Log.trace('BleReadCubit allCharacteristics: $allCharacteristics');
-    final characteristic = allCharacteristics.firstWhereOrNull(
-          (c) => c.uuid.str == _kCharacteristicID,);
+    final BluetoothCharacteristic? characteristic = allCharacteristics
+      .firstWhereOrNull((c) => c.uuid.str == _kCharacteristicID,);
     if (characteristic == null) {
       Log.err('no characteristic', [_device, allServices, allCharacteristics]);
       emit(BleReadFailure());
app/lib/bluetooth/bluetooth_cubit.dart
@@ -52,7 +52,6 @@ class BluetoothCubit extends Cubit<BluetoothState> {
         } else {
           emit(BluetoothUnauthorized());
         }
-
       case BluetoothAdapterState.off:
       case BluetoothAdapterState.turningOff:
       case BluetoothAdapterState.turningOn:
@@ -65,6 +64,7 @@ class BluetoothCubit extends Cubit<BluetoothState> {
 
   /// Request the permission to connect to bluetooth devices.
   Future<bool> requestPermission() async { // TODO: can this be removed entirely ?
+    Log.trace('BluetoothCubit requestPermission');
     assert(_adapterState == BluetoothAdapterState.unauthorized, 'No need to '
         'request permission when device unavailable or already authorized.');
     try {
app/lib/components/bluetooth_input/input_card.dart
@@ -42,10 +42,10 @@ class InputCard extends StatelessWidget {
 
   Widget _buildBody() => Padding( // content
     padding: EdgeInsets.only(
-      top: (title == null) ? 12 : 42,
-      bottom: 12,
-      left: 8,
-      right: 8,
+      top: (title == null) ? 12.0 : 42.0,
+      bottom: 12.0,
+      left: 8.0,
+      right: 8.0,
     ),
     child: Center(
       child: child,
app/lib/components/bluetooth_input.dart
@@ -68,10 +68,13 @@ class _BluetoothInputState extends State<BluetoothInput> {
 
   Widget _buildActive(BuildContext context) {
     _bluetoothSubscription = _bluetoothCubit.stream.listen((state) {
-      if (state is! BluetoothReady) _returnToIdle();
+      if (state is! BluetoothReady) {
+        Log.trace('_BluetoothInputState: _bluetoothSubscription state=$state, calling _returnToIdle');
+        _returnToIdle();
+      }
     });
     _deviceScanCubit = DeviceScanCubit(
-      service: Guid('1810'),
+      service: Guid('1810'), // TODO one source of truth (w read cubit)
       settings: widget.settings,
     );
     return BlocBuilder<DeviceScanCubit, DeviceScanState>(
@@ -107,8 +110,8 @@ class _BluetoothInputState extends State<BluetoothInput> {
                 BleReadSuccess() => MeasurementSuccess(
                   onTap: () {
                     widget.onMeasurement(state.data);
-                    return _returnToIdle;
-                  }(),
+                    return _returnToIdle();
+                  },
                 ),
               };
             },