Enhance USB serial plugin for Android and iPadOS with DriverKit support

- Updated README.md to reflect platform support for iPadOS.
- Implemented isDriverAvailable method in FlutterUsbSerialPlugin for DriverKit readiness check.
- Added DriverKitSerialClient C source and header files for iPadOS integration.
- Created Swift Package for iPadOS support.
- Updated pubspec.yaml and flutter_usb_serial.dart to clarify platform compatibility.
- Enhanced tests to verify isDriverAvailable functionality.

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-08-01 20:40:46 +08:00
parent 2d7fc43ea2
commit 17414656a9
11 changed files with 724 additions and 31 deletions
+3 -2
View File
@@ -1,7 +1,8 @@
/// Flutter plugin for USB serial communication on Android.
/// Flutter plugin for USB serial communication on Android and iPadOS.
///
/// Uses `usb-serial-for-android` (https://github.com/mik3y/usb-serial-for-android)
/// as the underlying Android library.
/// as the underlying Android library. iPadOS uses an app-embedded DriverKit
/// extension supplied by the host application.
library;
import 'dart:async';
+28 -15
View File
@@ -2,7 +2,8 @@ part of '../flutter_usb_serial.dart';
/// Main entry point for the flutter_usb_serial plugin.
///
/// Only supported on Android.
/// Supported on Android and on iPadOS through an app-embedded DriverKit
/// extension.
class FlutterUsbSerial {
FlutterUsbSerial._();
@@ -18,6 +19,15 @@ class FlutterUsbSerial {
return _rawEventStream!;
}
/// Whether the native USB serial backend is ready.
///
/// Android always provides its USB host backend. On iPadOS this probes for
/// the DriverKit user-client service, so it is `false` until the matching
/// app-embedded driver has loaded successfully.
static Future<bool> isDriverAvailable() async {
return await _methods.invokeMethod<bool>('isDriverAvailable') ?? false;
}
/// Returns the list of currently attached USB serial devices.
static Future<List<UsbSerialDevice>> listDevices() async {
final result = await _methods.invokeMethod<List<Object?>>('listDevices');
@@ -70,21 +80,24 @@ class FlutterUsbSerial {
final dataStream = _eventStream
.where((e) => e['portId'] == portId)
.transform(StreamTransformer<Map<Object?, Object?>, Uint8List>.fromHandlers(
handleData: (e, sink) {
if (e['type'] == 'data') {
final raw = e['data'];
if (raw is Uint8List) {
sink.add(raw);
} else if (raw is List) {
sink.add(Uint8List.fromList(raw.cast<int>()));
.transform(
StreamTransformer<Map<Object?, Object?>, Uint8List>.fromHandlers(
handleData: (e, sink) {
if (e['type'] == 'data') {
final raw = e['data'];
if (raw is Uint8List) {
sink.add(raw);
} else if (raw is List) {
sink.add(Uint8List.fromList(raw.cast<int>()));
}
} else if (e['type'] == 'error') {
sink.addError(
Exception(e['message'] as String? ?? 'USB IO error'),
);
}
} else if (e['type'] == 'error') {
sink.addError(Exception(
e['message'] as String? ?? 'USB IO error'));
}
},
));
},
),
);
return UsbSerialPort._(portId, dataStream);
}