import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'ch934x_serial_platform_interface.dart'; import 'src/models/models.dart'; /// MethodChannel 实现的 [Ch934xSerialPlatform]。 /// /// 在 Android 端通过同一 MethodChannel 与原生层通信, /// 命名规则:方法名使用下划线小写,字段名使用驼峰式以便 /// 直接对应 Java 侧 Map 的 key。 class MethodChannelCh934xSerial extends Ch934xSerialPlatform { /// 测试时可被替换的 MethodChannel。 @visibleForTesting final MethodChannel methodChannel = const MethodChannel('ch934x_serial'); /// 通知 Dart 侧的异常事件流,用于支持 `setExceptionCallback`。 final StreamController _exceptionController = StreamController.broadcast(); /// 接收来自原生层主动调用的 `onException` 消息。 Future _onNativeMethodCall(MethodCall call) async { if (call.method == 'onException') { final args = call.arguments; if (args is Map) { _exceptionController.add( Ch934xException( type: (args['type'] as int?) ?? Ch934xExceptionType.unknown, message: args['message'] as String?, cause: args['cause'] as String?, ), ); } } } @override Future> getDeviceList() async { final raw = await methodChannel.invokeMethod>('getDeviceList'); if (raw == null) { return const []; } return raw .whereType() .map((e) => Ch934xDeviceInfo.fromMap(Map.from(e))) .toList(growable: false); } @override Future getSerialNumber(int deviceId) { return methodChannel.invokeMethod( 'getSerialNumber', {'deviceId': deviceId}, ); } @override Future getDeviceType(int deviceId) async { final result = await methodChannel.invokeMethod( 'getDeviceType', {'deviceId': deviceId}, ); return result ?? Ch934xDeviceType.unknown; } @override Future> getSerialPortList( int deviceId, { required int interfaceNumber, }) async { final raw = await methodChannel.invokeMethod>( 'getSerialPortList', { 'deviceId': deviceId, 'interfaceNumber': interfaceNumber, }, ); if (raw == null) { return const []; } return raw .whereType() .map((e) => Ch934xSerialPortInfo.fromMap(Map.from(e))) .toList(growable: false); } @override Future openPort(Ch934xPortTarget target) async { final result = await methodChannel.invokeMethod( 'openPort', target.toMap(), ); return result ?? false; } @override Future closePort() async { final result = await methodChannel.invokeMethod('closePort'); return result ?? false; } @override Future setActivePort(int serialPortIndex) async { if (serialPortIndex < 0) { return false; } final result = await methodChannel.invokeMethod( 'setActivePort', {'serialPortIndex': serialPortIndex}, ); return result ?? false; } @override Future requestUsbPermission(int deviceId) async { final result = await methodChannel.invokeMethod( 'requestUsbPermission', {'deviceId': deviceId}, ); return result ?? false; } @override Future read(int length) async { if (length <= 0) { return Uint8List(0); } final raw = await methodChannel.invokeMethod( 'read', {'length': length}, ); return raw ?? Uint8List(0); } @override Future write(Uint8List data) async { if (data.isEmpty) { return 0; } final result = await methodChannel.invokeMethod( 'write', {'data': data}, ); return result ?? 0; } @override Future setGpioOutput({ required int gpioNumber, required int level, }) async { final result = await methodChannel.invokeMethod( 'setGpioOutput', { 'gpioNumber': gpioNumber, 'level': level, }, ); return result ?? false; } @override Future getGpioInput(int gpioNumber) async { final result = await methodChannel.invokeMethod( 'getGpioInput', {'gpioNumber': gpioNumber}, ); return result ?? -1; } @override Future setModemControl({required int dtr, required int rts}) async { final result = await methodChannel.invokeMethod( 'setModemControl', { 'dtr': dtr, 'rts': rts, }, ); return result ?? false; } @override Future getModemStatus() async { final result = await methodChannel.invokeMethod('getModemStatus'); return result ?? 0; } @override Future setExceptionCallback( void Function(Ch934xException exception) onException, ) async { // 注册接收原生层主动推送的 `onException` 事件。 methodChannel.setMethodCallHandler(_onNativeMethodCall); _exceptionController.stream.listen(onException); await methodChannel.invokeMethod('setExceptionCallback'); } /// 由原生层主动调用的入口,对应文档 7.3.1 中的 `onException` 回调。 /// /// 必须在原生层将 `MethodChannel` 的 `setMethodCallHandler` 调通后 /// 才会被触发;此方法在测试中也可直接调用,用于模拟异常事件。 @visibleForTesting void dispatchException({ required int type, String? message, String? cause, }) { _exceptionController.add( Ch934xException(type: type, message: message, cause: cause), ); } /// 释放内部资源,通常仅在测试或热重载场景下使用。 @visibleForTesting void dispose() { _exceptionController.close(); } }