docs: DevicePlugin阶段二 Task5 — 文档更新与迁移总结
- 更新 DEVICE_PLUGIN_DESIGN.md: 阶段二标记完成+验收项勾选+成果章节 - 新建 src/plugins/device/README.md: 完整DevicePlugin文档 - 新建 docs/SCREEN_PLUGIN_MIGRATION_SUMMARY.md: 迁移总结 - 更新 li-siqi soul + TEAM_CHAT 汇报 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
253
src/plugins/device/README.md
Normal file
253
src/plugins/device/README.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# DevicePlugin — 统一设备管理插件
|
||||
|
||||
## 概述
|
||||
|
||||
DevicePlugin 是 ShowenV2 的统一硬件访问层,负责管理所有设备相关的操作。通过抽象的 `DeviceBackend` trait,支持多平台适配(Linux ARM64、Android、Embedded 等)。
|
||||
|
||||
## 架构
|
||||
|
||||
```
|
||||
业务插件 (Video/Screen/BLE/HTTP/...)
|
||||
↓ 发送 DeviceCommand
|
||||
DevicePlugin
|
||||
↓ 分发给 Backend
|
||||
DeviceBackend (Linux/Android/Embedded)
|
||||
↓ 硬件访问
|
||||
硬件层 (Framebuffer/DRM/GPIO/I2C/SPI/...)
|
||||
```
|
||||
|
||||
## 支持的能力
|
||||
|
||||
DevicePlugin 通过 `DeviceCapability` enum 声明支持的硬件能力:
|
||||
|
||||
- **Display**: 显示信息查询(分辨率、像素格式)
|
||||
- **Backlight**: 背光控制(开关、亮度)
|
||||
- **SleepInhibit**: 防息屏(通过 systemd-inhibit)
|
||||
- **Cursor**: 光标控制(显示/隐藏,通过 unclutter)
|
||||
- **Framebuffer**: 帧缓冲写入(待实现)
|
||||
- **Touch**: 触摸输入(待实现)
|
||||
- **Buttons**: 按钮输入(待实现)
|
||||
- **Audio**: 音频播放(待实现)
|
||||
- **Battery**: 电池状态(待实现)
|
||||
- **Sensors**: 传感器数据(待实现)
|
||||
- **GPIO**: GPIO 控制(待实现)
|
||||
|
||||
## 消息接口
|
||||
|
||||
### DeviceCommand (业务插件 → DevicePlugin)
|
||||
|
||||
```rust
|
||||
pub enum DeviceCommand {
|
||||
// 显示
|
||||
GetDisplayInfo,
|
||||
SetBrightness(u8),
|
||||
SetBacklight(bool),
|
||||
WriteFramebuffer { data: Vec<u8>, format: PixelFormat },
|
||||
|
||||
// 输入
|
||||
GetTouchEvents,
|
||||
GetButtonState,
|
||||
GetSensorData(SensorType),
|
||||
|
||||
// 音频
|
||||
PlayAudio { path: String },
|
||||
SetVolume(u8),
|
||||
|
||||
// 电源
|
||||
GetBatteryLevel,
|
||||
SetSleepInhibit(bool),
|
||||
|
||||
// 光标
|
||||
SetCursorVisible(bool),
|
||||
|
||||
// 通用
|
||||
CustomCommand { subsystem: String, payload: serde_json::Value },
|
||||
}
|
||||
```
|
||||
|
||||
### DeviceResponse (DevicePlugin → 请求者)
|
||||
|
||||
```rust
|
||||
pub enum DeviceResponse {
|
||||
DisplayInfo { width: u32, height: u32, format: PixelFormat },
|
||||
SensorData { sensor: SensorType, value: f64 },
|
||||
BatteryLevel(u8),
|
||||
Ok,
|
||||
Error(String),
|
||||
Custom(serde_json::Value),
|
||||
}
|
||||
```
|
||||
|
||||
### DeviceEvent (DevicePlugin → 广播)
|
||||
|
||||
```rust
|
||||
pub enum DeviceEvent {
|
||||
TouchEvent { x: i32, y: i32, action: TouchAction },
|
||||
ButtonEvent { button: u8, pressed: bool },
|
||||
BatteryLow(u8),
|
||||
DisplayConnected,
|
||||
DisplayDisconnected,
|
||||
SensorAlert { sensor: SensorType, value: f64 },
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 查询显示信息
|
||||
|
||||
```rust
|
||||
let envelope = Envelope {
|
||||
from: "my_plugin".to_string(),
|
||||
to: Destination::Plugin("device".to_string()),
|
||||
message: Message::DeviceCommand(DeviceCommand::GetDisplayInfo),
|
||||
};
|
||||
ctx.tx.send(envelope)?;
|
||||
|
||||
// 接收响应
|
||||
match message {
|
||||
Message::DeviceResponse(DeviceResponse::DisplayInfo { width, height, format }) => {
|
||||
println!("Display: {}x{} {:?}", width, height, format);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
|
||||
### 防息屏
|
||||
|
||||
```rust
|
||||
// 启用防息屏
|
||||
let envelope = Envelope {
|
||||
from: "my_plugin".to_string(),
|
||||
to: Destination::Plugin("device".to_string()),
|
||||
message: Message::DeviceCommand(DeviceCommand::SetSleepInhibit(true)),
|
||||
};
|
||||
ctx.tx.send(envelope)?;
|
||||
|
||||
// 禁用防息屏
|
||||
let envelope = Envelope {
|
||||
from: "my_plugin".to_string(),
|
||||
to: Destination::Plugin("device".to_string()),
|
||||
message: Message::DeviceCommand(DeviceCommand::SetSleepInhibit(false)),
|
||||
};
|
||||
ctx.tx.send(envelope)?;
|
||||
```
|
||||
|
||||
### 光标控制
|
||||
|
||||
```rust
|
||||
// 隐藏光标
|
||||
let envelope = Envelope {
|
||||
from: "my_plugin".to_string(),
|
||||
to: Destination::Plugin("device".to_string()),
|
||||
message: Message::DeviceCommand(DeviceCommand::SetCursorVisible(false)),
|
||||
};
|
||||
ctx.tx.send(envelope)?;
|
||||
|
||||
// 显示光标
|
||||
let envelope = Envelope {
|
||||
from: "my_plugin".to_string(),
|
||||
to: Destination::Plugin("device".to_string()),
|
||||
message: Message::DeviceCommand(DeviceCommand::SetCursorVisible(true)),
|
||||
};
|
||||
ctx.tx.send(envelope)?;
|
||||
```
|
||||
|
||||
## 与 ScreenPlugin 的关系
|
||||
|
||||
### 历史背景
|
||||
|
||||
在 DevicePlugin 引入之前,ScreenPlugin 直接调用 `systemd-inhibit` 和 `unclutter` 命令来实现防息屏和光标隐藏功能。这导致:
|
||||
|
||||
1. **平台耦合**: ScreenPlugin 包含大量 Linux 特定代码
|
||||
2. **重复实现**: 多个插件可能需要类似的硬件访问逻辑
|
||||
3. **难以扩展**: 添加新平台需要修改多个插件
|
||||
|
||||
### 迁移方案 (2026-03-13)
|
||||
|
||||
**阶段二**完成了 ScreenPlugin 到 DevicePlugin 的功能迁移:
|
||||
|
||||
1. **DevicePlugin 扩展**:
|
||||
- 添加 `SetCursorVisible(bool)` 命令
|
||||
- LinuxArm64Backend 实现光标控制(通过 unclutter)
|
||||
- 添加 `DeviceCapability::Cursor` 能力
|
||||
|
||||
2. **ScreenPlugin 重构**:
|
||||
- 改为 DevicePlugin 的 thin wrapper
|
||||
- 移除直接硬件操作代码
|
||||
- 通过 `DeviceCommand` 消息实现所有功能
|
||||
- 保持向后兼容的消息接口
|
||||
|
||||
3. **架构改进**:
|
||||
- 统一设备管理: 所有硬件访问通过 DevicePlugin
|
||||
- 平台解耦: ScreenPlugin 不再包含平台特定代码
|
||||
- 消息驱动: 插件间通过消息通信,松耦合
|
||||
|
||||
### 当前状态
|
||||
|
||||
- ScreenPlugin 保留作为兼容层,处理 `Message::ScreenLockRequest` 和 `Message::CursorVisibility`
|
||||
- 实际硬件操作由 DevicePlugin 的 LinuxArm64Backend 执行
|
||||
- 未来可能完全移除 ScreenPlugin,业务插件直接使用 DeviceCommand
|
||||
|
||||
## 平台支持
|
||||
|
||||
### Linux ARM64 (当前实现)
|
||||
|
||||
- **Display**: 通过 DRM/KMS 查询显示信息
|
||||
- **Backlight**: 通过 `/sys/class/backlight` 控制背光
|
||||
- **SleepInhibit**: 通过 `systemd-inhibit` 防止系统休眠
|
||||
- **Cursor**: 通过 `unclutter` 隐藏光标
|
||||
|
||||
### Android (待实现)
|
||||
|
||||
- Display: 通过 Android API 查询
|
||||
- Backlight: 通过 Settings API 控制
|
||||
- SleepInhibit: 通过 WakeLock
|
||||
- Cursor: N/A (触摸设备无光标)
|
||||
|
||||
### Embedded (待实现)
|
||||
|
||||
- Display: 直接访问 framebuffer
|
||||
- Backlight: GPIO 控制
|
||||
- SleepInhibit: 自定义电源管理
|
||||
- Cursor: N/A (无操作系统)
|
||||
|
||||
## 测试
|
||||
|
||||
DevicePlugin 包含完整的单元测试和集成测试:
|
||||
|
||||
```bash
|
||||
# 运行所有测试
|
||||
cargo test --package showen --lib plugins::device
|
||||
|
||||
# 运行特定测试
|
||||
cargo test --package showen --lib plugins::device::tests::test_set_cursor_visible
|
||||
```
|
||||
|
||||
测试覆盖:
|
||||
- 消息序列化/反序列化(DeviceCommand/DeviceResponse/DeviceEvent)
|
||||
- MockBackend 功能验证
|
||||
- LinuxArm64Backend 能力声明
|
||||
- ScreenPlugin ↔ DevicePlugin 消息流
|
||||
|
||||
## 开发指南
|
||||
|
||||
### 添加新的设备能力
|
||||
|
||||
1. 在 `DeviceCommand` 中添加新命令
|
||||
2. 在 `DeviceCapability` 中添加新能力
|
||||
3. 在 `LinuxArm64Backend::handle_command` 中实现命令处理
|
||||
4. 在 `LinuxArm64Backend::capabilities` 中声明能力
|
||||
5. 添加单元测试验证功能
|
||||
|
||||
### 添加新的平台后端
|
||||
|
||||
1. 创建 `src/plugins/device/<platform>.rs`
|
||||
2. 实现 `DeviceBackend` trait
|
||||
3. 在 `src/plugins/device/mod.rs` 中注册后端
|
||||
4. 添加平台特定的测试
|
||||
|
||||
## 参考文档
|
||||
|
||||
- [DevicePlugin 设计文档](../../docs/DEVICE_PLUGIN_DESIGN.md)
|
||||
- [ScreenPlugin 迁移总结](../../docs/SCREEN_PLUGIN_MIGRATION_SUMMARY.md)
|
||||
- [集成测试文档](../../docs/DEVICE_PLUGIN_INTEGRATION_TEST.md)
|
||||
Reference in New Issue
Block a user