mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-04-20 22:13:48 +00:00
Refactor USB connection handling to use scheduled closure and improve error management in USB services
This commit is contained in:
parent
4b24506310
commit
dcad5c586d
4 changed files with 81 additions and 24 deletions
|
|
@ -105,11 +105,8 @@ class MainActivity : FlutterActivity() {
|
|||
"connect" -> handleUsbConnect(call, result)
|
||||
"write" -> handleUsbWrite(call, result)
|
||||
"disconnect" -> {
|
||||
usbIoExecutor.execute {
|
||||
closeUsbConnection()
|
||||
mainHandler.post {
|
||||
result.success(null)
|
||||
}
|
||||
scheduleCloseUsbConnection {
|
||||
result.success(null)
|
||||
}
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
|
|
@ -315,7 +312,7 @@ class MainActivity : FlutterActivity() {
|
|||
null,
|
||||
)
|
||||
}
|
||||
closeUsbConnection()
|
||||
scheduleCloseUsbConnection()
|
||||
}
|
||||
},
|
||||
).also { manager ->
|
||||
|
|
@ -338,6 +335,16 @@ class MainActivity : FlutterActivity() {
|
|||
return driver.ports.firstOrNull()
|
||||
}
|
||||
|
||||
private fun scheduleCloseUsbConnection(onComplete: (() -> Unit)? = null) {
|
||||
usbIoExecutor.execute {
|
||||
closeUsbConnection()
|
||||
if (onComplete != null) {
|
||||
mainHandler.post(onComplete)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun closeUsbConnection() {
|
||||
try {
|
||||
ioManager?.stop()
|
||||
|
|
@ -381,12 +388,13 @@ class MainActivity : FlutterActivity() {
|
|||
}
|
||||
|
||||
if (connectedDeviceName == detachedName) {
|
||||
closeUsbConnection()
|
||||
eventSink?.error(
|
||||
"usb_device_detached",
|
||||
"USB device was disconnected",
|
||||
null,
|
||||
)
|
||||
scheduleCloseUsbConnection {
|
||||
eventSink?.error(
|
||||
"usb_device_detached",
|
||||
"USB device was disconnected",
|
||||
null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1266,14 +1266,23 @@ class MeshCoreConnector extends ChangeNotifier {
|
|||
_selfInfoRetryTimer?.cancel();
|
||||
if (PlatformInfo.isWeb &&
|
||||
_activeTransport == MeshCoreTransportType.bluetooth) {
|
||||
_selfInfoRetryTimer = Timer(const Duration(seconds: 10), () {
|
||||
var attempts = 0;
|
||||
const maxAttempts = 3;
|
||||
_selfInfoRetryTimer = Timer.periodic(const Duration(seconds: 10), (
|
||||
timer,
|
||||
) {
|
||||
if (!isConnected || !_awaitingSelfInfo) {
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
if (_isLoadingContacts || _isSyncingChannels || _channelSyncInFlight) {
|
||||
return;
|
||||
}
|
||||
attempts += 1;
|
||||
unawaited(sendFrame(buildAppStartFrame()));
|
||||
if (attempts >= maxAttempts) {
|
||||
timer.cancel();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,8 +186,7 @@ class UsbSerialService {
|
|||
}
|
||||
|
||||
void dispose() {
|
||||
unawaited(disconnect());
|
||||
unawaited(_frameController.close());
|
||||
unawaited(disconnect().whenComplete(_closeFrameController));
|
||||
}
|
||||
|
||||
void _handleSerialData(FlSerialEventArgs event) {
|
||||
|
|
@ -197,7 +196,7 @@ class UsbSerialService {
|
|||
_ingestRawBytes(Uint8List.fromList(bytes));
|
||||
}
|
||||
} catch (error, stack) {
|
||||
_frameController.addError(error, stack);
|
||||
_addFrameError(error, stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,13 +209,13 @@ class UsbSerialService {
|
|||
_ingestRawBytes(data.buffer.asUint8List());
|
||||
return;
|
||||
}
|
||||
_frameController.addError(
|
||||
_addFrameError(
|
||||
StateError('Unexpected Android USB event payload: ${data.runtimeType}'),
|
||||
);
|
||||
}
|
||||
|
||||
void _handleSerialError(Object error, [StackTrace? stackTrace]) {
|
||||
_frameController.addError(error, stackTrace);
|
||||
_addFrameError(error, stackTrace);
|
||||
}
|
||||
|
||||
void _handleSerialDone() {
|
||||
|
|
@ -231,10 +230,31 @@ class UsbSerialService {
|
|||
);
|
||||
continue;
|
||||
}
|
||||
_frameController.add(packet.payload);
|
||||
_addFrame(packet.payload);
|
||||
}
|
||||
}
|
||||
|
||||
void _addFrame(Uint8List payload) {
|
||||
if (_frameController.isClosed) {
|
||||
return;
|
||||
}
|
||||
_frameController.add(payload);
|
||||
}
|
||||
|
||||
void _addFrameError(Object error, [StackTrace? stackTrace]) {
|
||||
if (_frameController.isClosed) {
|
||||
return;
|
||||
}
|
||||
_frameController.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
Future<void> _closeFrameController() async {
|
||||
if (_frameController.isClosed) {
|
||||
return;
|
||||
}
|
||||
await _frameController.close();
|
||||
}
|
||||
|
||||
void _logFrameSummary(String prefix, Uint8List bytes) {
|
||||
if (bytes.isEmpty) {
|
||||
debugPrint('$prefix len=0');
|
||||
|
|
|
|||
|
|
@ -160,8 +160,7 @@ class UsbSerialService {
|
|||
}
|
||||
|
||||
void dispose() {
|
||||
unawaited(disconnect());
|
||||
unawaited(_frameController.close());
|
||||
unawaited(disconnect().whenComplete(_closeFrameController));
|
||||
}
|
||||
|
||||
Future<List<JSObject>> _getAuthorizedPorts() async {
|
||||
|
|
@ -285,12 +284,12 @@ class UsbSerialService {
|
|||
}
|
||||
} catch (error, stackTrace) {
|
||||
if (_status == UsbSerialStatus.connected) {
|
||||
_frameController.addError(error, stackTrace);
|
||||
_addFrameError(error, stackTrace);
|
||||
}
|
||||
} finally {
|
||||
_releaseLock(reader);
|
||||
if (_status == UsbSerialStatus.connected && identical(reader, _reader)) {
|
||||
_frameController.addError(StateError('USB serial connection closed'));
|
||||
_addFrameError(StateError('USB serial connection closed'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -402,10 +401,31 @@ class UsbSerialService {
|
|||
);
|
||||
continue;
|
||||
}
|
||||
_frameController.add(packet.payload);
|
||||
_addFrame(packet.payload);
|
||||
}
|
||||
}
|
||||
|
||||
void _addFrame(Uint8List payload) {
|
||||
if (_frameController.isClosed) {
|
||||
return;
|
||||
}
|
||||
_frameController.add(payload);
|
||||
}
|
||||
|
||||
void _addFrameError(Object error, [StackTrace? stackTrace]) {
|
||||
if (_frameController.isClosed) {
|
||||
return;
|
||||
}
|
||||
_frameController.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
Future<void> _closeFrameController() async {
|
||||
if (_frameController.isClosed) {
|
||||
return;
|
||||
}
|
||||
await _frameController.close();
|
||||
}
|
||||
|
||||
void _logFrameSummary(String prefix, Uint8List bytes) {
|
||||
if (bytes.isEmpty) {
|
||||
debugPrint('$prefix len=0');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue