Skip to content

Commit

Permalink
Characteristic:: refactor on Futures to always complete with somethin…
Browse files Browse the repository at this point in the history
…g even if withResponse is false

additional type safety on invokeMethod calls
  • Loading branch information
okocsis committed Apr 12, 2021
1 parent c9c8d60 commit 86dafd6
Show file tree
Hide file tree
Showing 13 changed files with 195 additions and 144 deletions.
2 changes: 1 addition & 1 deletion lib/characteristic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class Characteristic extends InternalCharacteristic {
/// The value can be written only if [isWritableWithResponse] or
/// [isWritableWithoutResponse] is `true` and argument [withResponse] is
/// set accordingly.
Future<void> write(
Future<Characteristic?> write(
Uint8List value,
bool withResponse, {
String? transactionId,
Expand Down
2 changes: 1 addition & 1 deletion lib/peripheral.dart
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class Peripheral {
/// [serviceUuid]. Optional [transactionId] could be used to cancel operation.
///
/// Will result in error if discovery was not done during this connection.
Future<Characteristic> writeCharacteristic(
Future<Characteristic?> writeCharacteristic(
String serviceUuid,
String characteristicUuid,
Uint8List value,
Expand Down
2 changes: 1 addition & 1 deletion lib/service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Service extends InternalService {
/// [Characteristic.isWritableWithResponse] or
/// [Characteristic.isWritableWithoutResponse] is `true` and
/// [withResponse] is specified accordingly can be written to.
Future<Characteristic> writeCharacteristic(
Future<Characteristic?> writeCharacteristic(
String characteristicUuid,
Uint8List value,
bool withResponse, {
Expand Down
6 changes: 3 additions & 3 deletions lib/src/_managers_for_classes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ abstract class ManagerForPeripheral {
String transactionId,
);

Future<Characteristic> writeCharacteristicForDevice(
Future<Characteristic?> writeCharacteristicForDevice(
Peripheral peripheral,
String serviceUuid,
String characteristicUuid,
Expand Down Expand Up @@ -101,7 +101,7 @@ abstract class ManagerForService {
String transactionId,
);

Future<Characteristic> writeCharacteristicForService(
Future<Characteristic?> writeCharacteristicForService(
Peripheral peripheral,
InternalService service,
String characteristicUuid,
Expand Down Expand Up @@ -145,7 +145,7 @@ abstract class ManagerForCharacteristic {
String transactionId,
);

Future<void> writeCharacteristicForIdentifier(
Future<Characteristic?> writeCharacteristicForIdentifier(
Peripheral peripheral,
InternalCharacteristic characteristic,
Uint8List value,
Expand Down
12 changes: 7 additions & 5 deletions lib/src/bridge/bluetooth_state_mixin.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
part of _internal;

mixin BluetoothStateMixin on FlutterBLE {
final Stream<dynamic> _adapterStateChanges =
const EventChannel(ChannelName.adapterStateChanges)
.receiveBroadcastStream();
final Stream<String> _adapterStateChanges =
const EventChannel(ChannelName.adapterStateChanges)
.receiveBroadcastStream()
.where((event) => event is String)
.cast<String>();

Future<void> enableRadio(String transactionId) async {
await _methodChannel.invokeMethod(
Expand All @@ -26,7 +28,7 @@ mixin BluetoothStateMixin on FlutterBLE {
}

Future<BluetoothState> state() => _methodChannel
.invokeMethod(MethodName.getState)
.invokeMethod<String>(MethodName.getState)
.then(_mapToBluetoothState);

Stream<BluetoothState> observeBluetoothState(bool emitCurrentValue) async* {
Expand All @@ -37,7 +39,7 @@ mixin BluetoothStateMixin on FlutterBLE {
yield* _adapterStateChanges.map(_mapToBluetoothState);
}

BluetoothState _mapToBluetoothState(dynamic rawValue) {
BluetoothState _mapToBluetoothState(String? rawValue) {
switch (rawValue) {
case "Unknown":
return BluetoothState.UNKNOWN;
Expand Down
190 changes: 113 additions & 77 deletions lib/src/bridge/characteristics_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ mixin CharacteristicsMixin on FlutterBLE {
String transactionId,
) =>
_methodChannel
.invokeMethod(
.invokeMethod<String>(
MethodName.readCharacteristicForIdentifier,
<String, dynamic>{
ArgumentName.characteristicIdentifier: characteristicIdentifier,
ArgumentName.transactionId: transactionId
},
)
.catchError((errorJson) =>
Future.error(BleError.fromJson(jsonDecode(errorJson.details))))
.catchError((errorJson) async =>
throw BleError.fromJson(jsonDecode(errorJson.details))
)
.then((rawValue) {
String rawJsonValue = "";
if (rawValue is String) {
rawJsonValue = rawValue;
if (rawValue == null) {
return Uint8List.fromList([]);
}
return _parseCharacteristicWithValueWithTransactionIdResponse(
peripheral,
rawJsonValue
rawValue
).value;
});

Expand All @@ -38,7 +38,7 @@ mixin CharacteristicsMixin on FlutterBLE {
String transactionId,
) =>
_methodChannel
.invokeMethod(
.invokeMethod<String>(
MethodName.readCharacteristicForDevice,
<String, dynamic>{
ArgumentName.deviceIdentifier: peripheral.identifier,
Expand All @@ -47,16 +47,16 @@ mixin CharacteristicsMixin on FlutterBLE {
ArgumentName.transactionId: transactionId
},
)
.catchError((errorJson) =>
Future.error(BleError.fromJson(jsonDecode(errorJson.details))))
.catchError((errorJson) async =>
throw BleError.fromJson(jsonDecode(errorJson.details))
)
.then((rawValue) {
String rawJsonValue = "";
if (rawValue is String) {
rawJsonValue = rawValue;
if (rawValue == null) {
throw Exception("rawValue cannot be null");
}
return _parseCharacteristicWithValueWithTransactionIdResponse(
peripheral,
rawJsonValue
rawValue
);
});

Expand All @@ -67,7 +67,7 @@ mixin CharacteristicsMixin on FlutterBLE {
String transactionId,
) =>
_methodChannel
.invokeMethod(
.invokeMethod<String>(
MethodName.readCharacteristicForService,
<String, dynamic>{
ArgumentName.serviceIdentifier: serviceIdentifier,
Expand All @@ -76,87 +76,123 @@ mixin CharacteristicsMixin on FlutterBLE {
},
)
.catchError((errorJson) =>
Future.error(BleError.fromJson(jsonDecode(errorJson.details))))
throw BleError.fromJson(jsonDecode(errorJson.details))
)
.then((rawValue) {
String rawJsonValue = "";
if (rawValue is String) {
rawJsonValue = rawValue;
if (rawValue == null) {
throw Exception("rawValue cannot be null");
}
return _parseCharacteristicWithValueWithTransactionIdResponse(
peripheral,
rawJsonValue
rawValue
);
});

Future<void> writeCharacteristicForIdentifier(
Future<Characteristic?> writeCharacteristicForIdentifier(
Peripheral peripheral,
int characteristicIdentifier,
Uint8List value,
bool withResponse,
String transactionId,
) =>
_methodChannel.invokeMethod(
MethodName.writeCharacteristicForIdentifier,
<String, dynamic>{
ArgumentName.characteristicIdentifier: characteristicIdentifier,
ArgumentName.value: value,
ArgumentName.withResponse: withResponse,
ArgumentName.transactionId: transactionId,
},
).catchError((errorJson) =>
Future.error(BleError.fromJson(jsonDecode(errorJson.details))));

Future<Characteristic> writeCharacteristicForDevice(
Peripheral peripheral,
String serviceUuid,
String characteristicUuid,
Uint8List value,
bool withResponse,
String transactionId) =>
_methodChannel
.invokeMethod(
MethodName.writeCharacteristicForDevice,
<String, dynamic>{
ArgumentName.deviceIdentifier: peripheral.identifier,
ArgumentName.serviceUuid: serviceUuid,
ArgumentName.characteristicUuid: characteristicUuid,
ArgumentName.value: value,
ArgumentName.withResponse: withResponse,
ArgumentName.transactionId: transactionId,
},
)
.catchError((errorJson) =>
Future.error(BleError.fromJson(jsonDecode(errorJson.details))))
.then(
(rawJsonValue) =>
_parseCharacteristicResponse(peripheral, rawJsonValue),
);
) async {
final inv = _methodChannel.invokeMethod<String>(
MethodName.writeCharacteristicForIdentifier,
<String, dynamic>{
ArgumentName.characteristicIdentifier: characteristicIdentifier,
ArgumentName.value: value,
ArgumentName.withResponse: withResponse,
ArgumentName.transactionId: transactionId,
},
).catchError((errorJson) =>
throw BleError.fromJson(jsonDecode(errorJson.details))
).then((rawJsonValue) {
if (withResponse == false) {
return null;
}
if (rawJsonValue == null) {
return null;
}
return _parseCharacteristicResponse(peripheral, rawJsonValue);
});
if (withResponse == false) {
return null;
}
return await inv;
}



Future<Characteristic?> writeCharacteristicForDevice(
Peripheral peripheral,
String serviceUuid,
String characteristicUuid,
Uint8List value,
bool withResponse,
String transactionId
) async {
final inv = _methodChannel.invokeMethod<String>(
MethodName.writeCharacteristicForDevice,
<String, dynamic>{
ArgumentName.deviceIdentifier: peripheral.identifier,
ArgumentName.serviceUuid: serviceUuid,
ArgumentName.characteristicUuid: characteristicUuid,
ArgumentName.value: value,
ArgumentName.withResponse: withResponse,
ArgumentName.transactionId: transactionId,
},
)
.catchError((errorJson) async =>
throw BleError.fromJson(jsonDecode(errorJson.details))
)
.then((rawJsonValue) {
if (withResponse == false) {
return null;
}
if (rawJsonValue == null) {
return null;
}
return _parseCharacteristicResponse(peripheral, rawJsonValue);
});
if (withResponse == false) {
return null;
}
return await inv;
}

Future<Characteristic> writeCharacteristicForService(
Future<Characteristic?> writeCharacteristicForService(
Peripheral peripheral,
int serviceIdentifier,
String characteristicUuid,
Uint8List value,
bool withResponse,
String transactionId,
) =>
_methodChannel
.invokeMethod(
MethodName.writeCharacteristicForService,
<String, dynamic>{
ArgumentName.serviceIdentifier: serviceIdentifier,
ArgumentName.characteristicUuid: characteristicUuid,
ArgumentName.value: value,
ArgumentName.withResponse: withResponse,
ArgumentName.transactionId: transactionId,
},
)
.catchError((errorJson) =>
Future.error(BleError.fromJson(jsonDecode(errorJson.details))))
.then(
(rawJsonValue) =>
_parseCharacteristicResponse(peripheral, rawJsonValue),
);
) async {
final inv = _methodChannel.invokeMethod(
MethodName.writeCharacteristicForService,
<String, dynamic>{
ArgumentName.serviceIdentifier: serviceIdentifier,
ArgumentName.characteristicUuid: characteristicUuid,
ArgumentName.value: value,
ArgumentName.withResponse: withResponse,
ArgumentName.transactionId: transactionId,
},
)
.catchError((errorJson) =>
Future.error(BleError.fromJson(jsonDecode(errorJson.details))))
.then((rawJsonValue) {
if (withResponse == false) {
return null;
}
if (rawJsonValue == null) {
return null;
}
return _parseCharacteristicResponse(peripheral, rawJsonValue);
});
if (withResponse == false) {
return null;
}
return await inv;
}

Stream<Uint8List> monitorCharacteristicForIdentifier(
Peripheral peripheral,
Expand Down
6 changes: 3 additions & 3 deletions lib/src/internal_ble_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ class InternalBleManager
);

@override
Future<void> writeCharacteristicForIdentifier(
Future<Characteristic?> writeCharacteristicForIdentifier(
Peripheral peripheral,
InternalCharacteristic characteristic,
Uint8List value,
Expand All @@ -248,7 +248,7 @@ class InternalBleManager
);

@override
Future<Characteristic> writeCharacteristicForDevice(
Future<Characteristic?> writeCharacteristicForDevice(
Peripheral peripheral,
String serviceUuid,
String characteristicUuid,
Expand All @@ -265,7 +265,7 @@ class InternalBleManager
);

@override
Future<Characteristic> writeCharacteristicForService(
Future<Characteristic?> writeCharacteristicForService(
Peripheral peripheral,
InternalService service,
String characteristicUuid,
Expand Down
11 changes: 7 additions & 4 deletions test/characteristic_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import 'test_util/characteristic_generator.dart';
import 'test_util/descriptor_generator.dart';

@GenerateMocks(
[Peripheral, ManagerForDescriptor, DescriptorWithValue],
customMocks: [
MockSpec<Service>(returnNullOnMissingStub: true),
]
[Peripheral, ManagerForDescriptor, DescriptorWithValue, Service],
// customMocks: [
// MockSpec<Service>(returnNullOnMissingStub: true),
// ]
)
void main() {
final peripheral = MockPeripheral();
Expand All @@ -44,6 +44,9 @@ void main() {
).thenAnswer(
(_) async => MockDescriptorWithValue()
);
when(
managerForCharacteristic.writeCharacteristicForIdentifier(any, any, any, any, any)
).thenAnswer((_) async => null);
final characteristicGenerator =
CharacteristicGenerator(managerForCharacteristic);
final descriptorGenerator =
Expand Down
Loading

0 comments on commit 86dafd6

Please sign in to comment.