feat: M1.1 完成 + M1.2 启动 — 全量更新

M1.1 收尾:
- 24项 P0/P1/P2 bug 修复 (Rust 107 tests + Flutter 15 tests)
- Flutter App v0.3: cupertino_icons 修复, 单元测试, 调试面板, APK 52.6MB
- 示例插件完善: manifest.json + 请求/响应示范 + 7个测试
- API 文档重写 (以 routes.rs 为唯一权威)
- MILESTONES.md 更新至 100%

M1.2 启动:
- P0: 插件管理 API 闭环 (handle_manager_message Custom 分支 + broadcast_plugin_states)
- ServiceManager 集成测试 8/8 (tests/m1_2_service_manager.rs)
- M1.2 测试计划 (docs/M1.2_TEST_PLAN.md, 18个E2E场景)
- 动态插件系统: auto_rollback + version_manager GC + 路径穿越防护

总计: Rust 115/115 测试, Flutter 15/15 测试, 零 warning

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
showen
2026-03-14 18:12:42 +08:00
parent 8ed9cb2d9d
commit d30c111c71
68 changed files with 8115 additions and 1201 deletions

View File

@@ -4,11 +4,15 @@ import 'package:flutter/foundation.dart';
import '../models/ble_models.dart';
import '../services/ble_service.dart';
import 'debug_provider.dart';
class BleProvider extends ChangeNotifier {
BleProvider({BleService? bleService}) : _bleService = bleService ?? BleService();
BleProvider({BleService? bleService, required DebugProvider debugProvider})
: _bleService = bleService ?? BleService(),
_debugProvider = debugProvider;
final BleService _bleService;
final DebugProvider _debugProvider;
StreamSubscription<List<BleDevice>>? _scanSubscription;
StreamSubscription<BleStatus>? _statusSubscription;
@@ -21,6 +25,7 @@ class BleProvider extends ChangeNotifier {
bool _isScanning = false;
bool _isConnecting = false;
bool _isProvisioning = false;
bool _isSendingCommand = false;
bool _isConnected = false;
bool _isDisposed = false;
@@ -32,9 +37,11 @@ class BleProvider extends ChangeNotifier {
bool get isScanning => _isScanning;
bool get isConnecting => _isConnecting;
bool get isProvisioning => _isProvisioning;
bool get isSendingCommand => _isSendingCommand;
bool get isConnected => _isConnected;
Future<void> startScan() async {
_debugProvider.addBleLog('Start BLE scan');
_errorMessage = null;
_selectedDevice = null;
_isConnected = false;
@@ -47,23 +54,31 @@ class BleProvider extends ChangeNotifier {
.scanForShowenDevices()
.listen((List<BleDevice> scannedDevices) {
_devices = scannedDevices;
_debugProvider.addBleLog(
'BLE scan update (${scannedDevices.length} devices)',
);
_notifySafely();
}, onError: (Object error, StackTrace stackTrace) {
_errorMessage = error.toString();
_isScanning = false;
_provisioningState = ProvisioningState.failed;
_debugProvider.addBleLog('BLE scan failed', details: error);
_notifySafely();
});
Future<void>.delayed(const Duration(seconds: 6), () {
if (_isScanning) {
_isScanning = false;
_debugProvider.addBleLog('BLE scan completed');
_notifySafely();
}
});
}
Future<void> connectToDevice(BleDevice device) async {
_debugProvider.addBleLog(
'Connect BLE device ${device.name.isNotEmpty ? device.name : device.id}',
);
_selectedDevice = device;
_errorMessage = null;
_isConnecting = true;
@@ -75,10 +90,12 @@ class BleProvider extends ChangeNotifier {
await _bleService.connectToDevice(device);
await _subscribeToStatus();
_isConnected = true;
_debugProvider.addBleLog('BLE device connected');
} catch (error) {
_isConnected = false;
_errorMessage = error.toString();
_provisioningState = ProvisioningState.failed;
_debugProvider.addBleLog('BLE connect failed', details: error);
rethrow;
} finally {
_isConnecting = false;
@@ -87,6 +104,10 @@ class BleProvider extends ChangeNotifier {
}
Future<void> provisionWifi(String ssid, String password) async {
_debugProvider.addBleLog(
'Provision WiFi over BLE',
details: <String, Object>{'ssid': ssid},
);
_errorMessage = null;
_latestStatus = null;
_isProvisioning = true;
@@ -115,14 +136,19 @@ class BleProvider extends ChangeNotifier {
: ProvisioningState.failed;
if (!result.ok) {
_errorMessage = result.error ?? 'WiFi provisioning failed';
_debugProvider.addBleLog('BLE provisioning returned failure', details: result.error);
} else {
_debugProvider.addBleLog('BLE provisioning succeeded');
}
} on TimeoutException {
_errorMessage = 'BLE 配网超时30 秒)';
_provisioningState = ProvisioningState.failed;
_debugProvider.addBleLog('BLE provisioning timed out');
rethrow;
} catch (error) {
_errorMessage = error.toString();
_provisioningState = ProvisioningState.failed;
_debugProvider.addBleLog('BLE provisioning failed', details: error);
rethrow;
} finally {
_isProvisioning = false;
@@ -140,10 +166,31 @@ class BleProvider extends ChangeNotifier {
_isConnecting = false;
_isProvisioning = false;
_selectedDevice = null;
_debugProvider.addBleLog('BLE disconnected');
_notifySafely();
}
Future<void> sendCommand(String command) async {
_debugProvider.addBleLog('Send BLE command', details: command);
_errorMessage = null;
_isSendingCommand = true;
_notifySafely();
try {
await _bleService.sendCommand(command);
_debugProvider.addBleLog('BLE command sent', details: command);
} catch (error) {
_errorMessage = error.toString();
_debugProvider.addBleLog('BLE command failed', details: error);
rethrow;
} finally {
_isSendingCommand = false;
_notifySafely();
}
}
Future<void> retryScan() async {
_debugProvider.addBleLog('Retry BLE scan');
await disconnect();
_devices = const <BleDevice>[];
_latestStatus = null;
@@ -158,6 +205,15 @@ class BleProvider extends ChangeNotifier {
final Stream<BleStatus> stream = await _bleService.subscribeToStatus();
_statusSubscription = stream.listen((BleStatus status) {
_latestStatus = status;
_debugProvider.addBleLog(
'BLE status update',
details: <String, Object?>{
'ok': status.ok,
'action': status.action,
'state': status.state,
'error': status.error,
},
);
if (!status.ok) {
_errorMessage = status.error ?? 'BLE status returned an error';
}
@@ -174,6 +230,7 @@ class BleProvider extends ChangeNotifier {
}, onError: (Object error, StackTrace stackTrace) {
_errorMessage = error.toString();
_provisioningState = ProvisioningState.failed;
_debugProvider.addBleLog('BLE status stream failed', details: error);
_notifySafely();
});
}