docs: DevicePlugin阶段二规划 + PM汇报 + CEO批准

This commit is contained in:
showen
2026-03-13 07:07:05 +08:00
parent 48d1eeb7c4
commit 28566386d2
3 changed files with 475 additions and 3 deletions

View File

@@ -0,0 +1,471 @@
# DevicePlugin 阶段二任务分解文档 — ScreenPlugin 功能迁移
## 项目背景
根据 CEO 陈逸飞指示DevicePlugin 阶段一(基础框架)已完成并通过 73/73 测试。现进入阶段二:将 ScreenPlugin 的核心功能迁移到 DevicePlugin实现统一设备管理架构。
## 阶段一成果回顾
- ✅ Message enum 扩展DeviceCommand/DeviceResponse/DeviceEvent
- ✅ DevicePlugin 骨架与 Backend trait 定义
- ✅ LinuxArm64Backend 实现Display + SleepInhibit + Backlight
- ✅ 单元测试与文档完善73/73 测试通过)
## 阶段二总体目标
1. 将 ScreenPlugin 的 systemd-inhibit防息屏和 unclutter光标隐藏功能迁移到 DevicePlugin
2. ScreenPlugin 改为通过 DeviceCommand 调用 DevicePluginthin wrapper
3. 确保现有功能不丢失,保持向后兼容
4. 为未来完全移除 ScreenPlugin 做准备
## 当前状态分析
### ScreenPlugin 现有功能src/plugins/screen/mod.rs
1. **防息屏systemd-inhibit**
- `start_wake_lock()` — 启动 systemd-inhibit 子进程(已在 DevicePlugin 实现)
- `stop_wake_lock()` — 停止 systemd-inhibit 子进程(已在 DevicePlugin 实现)
- 处理 `Message::ScreenLockRequest(bool)` 消息
2. **光标隐藏unclutter**
- `set_cursor_hidden(bool)` — 启动/停止 unclutter 进程(**需要迁移**
- 处理 `Message::CursorVisibility(bool)` 消息
3. **配置驱动**
-`ctx.config.display.prevent_screen_lock` 读取配置
-`start()` 时自动启动防息屏和隐藏光标
### DevicePlugin 现有能力src/plugins/device/linux_arm64.rs
-`SetSleepInhibit(bool)` — 已实现 systemd-inhibit
-`SetBacklight(bool)` — 已实现背光控制
-`GetDisplayInfo` — 已实现显示信息查询
-**光标隐藏功能缺失** — 需要新增
## 任务列表与执行顺序
---
### Task 1: DeviceCommand 扩展 — 添加光标控制命令
**负责人建议**: 张明远(内核工程师,负责阶段一 Message enum 扩展)
**优先级**: P0阻塞后续所有任务
**输入文件**:
- `src/core/message.rs` — 现有 DeviceCommand 定义
- `src/plugins/screen/mod.rs` — ScreenPlugin 光标隐藏实现(参考)
**任务描述**:
1.`DeviceCommand` enum 中添加新变体:
```rust
/// 设置光标可见性
/// - true: 显示光标
/// - false: 隐藏光标(通过 unclutter 或平台特定方式)
SetCursorVisible(bool),
```
2. 在 `DeviceCapability` enum 中添加新能力:
```rust
/// 光标控制能力
Cursor,
```
3. 确保新变体派生 `Debug, Clone, Serialize, Deserialize`
4. 添加文档注释说明用途和平台差异
**输出文件**:
- `src/core/message.rs` — 更新后的消息定义
**验收标准**:
- [ ] `cargo check --workspace` 零 warning
- [ ] `SetCursorVisible` 变体正确派生 serde traits
- [ ] 文档注释清晰说明 Linux/Android/Embedded 平台的实现差异
- [ ] `DeviceCapability::Cursor` 已添加
**预计工时**: 0.5 小时
---
### Task 2: LinuxArm64Backend 扩展 — 实现光标控制
**负责人建议**: 赵雨薇屏幕工程师ScreenPlugin 原作者,熟悉 unclutter
**优先级**: P0依赖 Task 1
**依赖**: Task 1 必须完成DeviceCommand 已扩展)
**输入文件**:
- `src/plugins/device/linux_arm64.rs` — 现有 Backend 实现
- `src/plugins/screen/mod.rs` — ScreenPlugin 光标隐藏实现(参考 set_cursor_hidden
**任务描述**:
1. 在 `LinuxArm64Backend` 结构体中添加字段:
```rust
/// unclutter 子进程(用于隐藏光标)
cursor_child: Option<Child>,
/// 光标可见性状态
cursor_visible: bool,
```
2. 在 `capabilities()` 方法中添加 `DeviceCapability::Cursor`
3. 在 `handle_command()` 中实现 `SetCursorVisible` 命令:
- `SetCursorVisible(false)` → 启动 unclutter 进程:
```bash
pkill -f unclutter # 先清理旧进程
unclutter -idle 0 -root # 立即隐藏光标
```
- `SetCursorVisible(true)` → 停止 unclutter 进程:
```bash
pkill -f unclutter
```
- 参考 ScreenPlugin::set_cursor_hidden 的实现src/plugins/screen/mod.rs:64-101
4. 在 `shutdown()` 方法中清理 cursor_child 进程
5. 添加错误处理unclutter 不可用时记录警告但不阻塞
**输出文件**:
- `src/plugins/device/linux_arm64.rs` — 更新后的 Backend 实现
**验收标准**:
- [ ] `cargo check --workspace` 零 warning
- [ ] `SetCursorVisible(false)` 能成功启动 unclutter 进程
- [ ] `SetCursorVisible(true)` 能成功停止 unclutter 进程
- [ ] 重复调用相同命令不会产生多个 unclutter 进程
- [ ] shutdown 正确清理 cursor_child 资源
- [ ] unclutter 不可用时不阻塞插件启动
**预计工时**: 2 小时
---
### Task 3: ScreenPlugin 重构 — 改为 DevicePlugin 的 thin wrapper
**负责人建议**: 赵雨薇ScreenPlugin 原作者,熟悉现有实现和消息流)
**优先级**: P0依赖 Task 2
**依赖**: Task 2 必须完成DevicePlugin 已支持光标控制)
**输入文件**:
- `src/plugins/screen/mod.rs` — 现有 ScreenPlugin 实现
- `src/plugins/device/mod.rs` — DevicePlugin 实现
- `src/core/message.rs` — 消息定义
**任务描述**:
1. 重构 `ScreenPlugin` 结构体,移除直接硬件操作字段:
```rust
pub struct ScreenPlugin {
ctx: Option<PluginContext>,
// 移除 wake_lock_child: Option<Child>
// 移除 cursor_hidden: bool
}
```
2. 重构 `start_wake_lock()` 方法:
```rust
fn start_wake_lock(&self) {
if let Some(ctx) = &self.ctx {
let envelope = Envelope {
from: self.id().to_string(),
to: Destination::Plugin("device".to_string()),
message: Message::DeviceCommand(DeviceCommand::SetSleepInhibit(true)),
};
let _ = ctx.tx.send(envelope);
}
}
```
3. 重构 `stop_wake_lock()` 方法(类似,发送 `SetSleepInhibit(false)`
4. 重构 `set_cursor_hidden()` 方法:
```rust
fn set_cursor_hidden(&self, hidden: bool) {
if let Some(ctx) = &self.ctx {
let envelope = Envelope {
from: self.id().to_string(),
to: Destination::Plugin("device".to_string()),
message: Message::DeviceCommand(DeviceCommand::SetCursorVisible(!hidden)),
};
let _ = ctx.tx.send(envelope);
}
}
```
5. 保持 `handle_message()` 的消息接口不变:
- `Message::ScreenLockRequest(bool)` → 调用 start/stop_wake_lock
- `Message::CursorVisibility(bool)` → 调用 set_cursor_hidden
6. 移除所有 `#[cfg(target_os = "linux")]` 条件编译(平台适配由 DevicePlugin 负责)
7. 在文件顶部添加注释说明 ScreenPlugin 现在是 DevicePlugin 的 thin wrapper
**输出文件**:
- `src/plugins/screen/mod.rs` — 重构后的 ScreenPlugin 实现
**验收标准**:
- [ ] `cargo check --workspace` 零 warning
- [ ] ScreenPlugin 不再直接调用 systemd-inhibit 或 unclutter
- [ ] 所有功能通过 DeviceCommand 消息实现
- [ ] `Message::ScreenLockRequest` 和 `Message::CursorVisibility` 接口保持不变
- [ ] 移除了所有平台特定的条件编译代码
- [ ] 代码行数减少至少 50%
**预计工时**: 2 小时
---
### Task 4: 集成测试 — 验证 ScreenPlugin + DevicePlugin 协作
**负责人建议**: 李思琪(视频引擎工程师,负责阶段一测试,熟悉消息流测试)
**优先级**: P1依赖 Task 3
**依赖**: Task 3 必须完成ScreenPlugin 重构完成)
**输入文件**:
- `src/plugins/screen/mod.rs` — 重构后的 ScreenPlugin
- `src/plugins/device/` — DevicePlugin 实现
- `src/plugins/device/tests.rs` — 现有测试(参考)
**任务描述**:
1. 在 `src/plugins/device/tests.rs` 中添加光标控制测试:
```rust
#[test]
fn test_set_cursor_visible() {
// 测试 SetCursorVisible 命令的序列化/反序列化
}
#[test]
fn test_cursor_capability() {
// 测试 LinuxArm64Backend 报告 Cursor 能力
}
```
2. 创建 `src/plugins/screen/tests.rs`
```rust
#[test]
fn test_screen_lock_request_sends_device_command() {
// 测试 ScreenLockRequest 消息转换为 DeviceCommand::SetSleepInhibit
}
#[test]
fn test_cursor_visibility_sends_device_command() {
// 测试 CursorVisibility 消息转换为 DeviceCommand::SetCursorVisible
}
```
3. 在 `src/plugins/screen/mod.rs` 中添加 `#[cfg(test)] mod tests;`
4. 编写集成测试文档 `docs/DEVICE_PLUGIN_INTEGRATION_TEST.md`
- 说明 ScreenPlugin 和 DevicePlugin 的消息流
- 提供手动测试步骤(如何验证防息屏和光标隐藏)
- 列出测试覆盖的场景
**输出文件**:
- `src/plugins/device/tests.rs` — 更新后的测试
- `src/plugins/screen/tests.rs` — 新增测试
- `docs/DEVICE_PLUGIN_INTEGRATION_TEST.md` — 集成测试文档
**验收标准**:
- [ ] `cargo check --workspace --all-targets` 零 warning
- [ ] `cargo test --workspace` 全部通过
- [ ] 至少新增 4 个测试用例2 个 device + 2 个 screen
- [ ] 集成测试文档包含清晰的消息流图和手动测试步骤
- [ ] 测试覆盖 ScreenPlugin → DevicePlugin 的消息转换
**预计工时**: 2.5 小时
---
### Task 5: 文档更新与迁移总结
**负责人建议**: 李思琪(负责阶段一文档,熟悉项目文档结构)
**优先级**: P1依赖 Task 4
**依赖**: Task 4 必须完成(测试通过)
**输入文件**:
- `docs/DEVICE_PLUGIN_DESIGN.md` — 设计文档
- `.showen/DEVICE_PLUGIN_TASKS.md` — 阶段一任务文档
- `src/plugins/screen/mod.rs` — 重构后的 ScreenPlugin
- `src/plugins/device/README.md` — DevicePlugin 文档
**任务描述**:
1. 更新 `docs/DEVICE_PLUGIN_DESIGN.md`
- 在第 6 节"实施计划"中标记阶段二已完成
- 在第 8 节"验收标准"中勾选 ScreenPlugin 迁移项
- 添加"阶段二成果"章节,说明 ScreenPlugin 迁移细节
2. 更新 `src/plugins/device/README.md`
- 在"支持的能力"中添加 Cursor 控制
- 添加"与 ScreenPlugin 的关系"章节,说明迁移历史
3. 更新 `src/plugins/screen/mod.rs` 文件头注释:
```rust
//! ScreenPlugin — 屏幕管理Thin Wrapper
//!
//! 本插件现在是 DevicePlugin 的 thin wrapper通过 DeviceCommand 消息
//! 调用 DevicePlugin 实现防息屏和光标隐藏功能。
//!
//! 历史v0.1.0 直接调用 systemd-inhibit 和 unclutter
//! v0.2.0 迁移到 DevicePlugin2026-03-13
```
4. 创建迁移总结文档 `docs/SCREEN_PLUGIN_MIGRATION_SUMMARY.md`
- 迁移前后架构对比图
- 代码行数对比(迁移前 vs 迁移后)
- 性能影响分析(消息传递开销)
- 未来计划(是否完全移除 ScreenPlugin
**输出文件**:
- `docs/DEVICE_PLUGIN_DESIGN.md` — 更新设计文档
- `src/plugins/device/README.md` — 更新 DevicePlugin 文档
- `src/plugins/screen/mod.rs` — 更新文件头注释
- `docs/SCREEN_PLUGIN_MIGRATION_SUMMARY.md` — 迁移总结文档
**验收标准**:
- [ ] 所有文档更新完整,反映阶段二成果
- [ ] 迁移总结文档包含清晰的架构对比图
- [ ] ScreenPlugin 文件头注释说明其 thin wrapper 角色
- [ ] 设计文档验收标准已更新
**预计工时**: 1.5 小时
---
### Task 6: 示例插件完善 — 展示 DeviceCommand 使用(可选)
**负责人建议**: 王浩然(网络工程师,可参与示例开发)
**优先级**: P2依赖 Task 5可延后
**依赖**: Task 5 必须完成(文档更新完成)
**输入文件**:
- `examples/` — 现有示例代码
- `src/plugins/device/README.md` — DevicePlugin 文档
**任务描述**:
1. 创建 `examples/device_demo.rs`
- 演示如何发送 `DeviceCommand::GetDisplayInfo`
- 演示如何发送 `DeviceCommand::SetSleepInhibit`
- 演示如何发送 `DeviceCommand::SetCursorVisible`
- 演示如何接收 `DeviceResponse`
2. 在 `Cargo.toml` 中添加示例配置:
```toml
[[example]]
name = "device_demo"
path = "examples/device_demo.rs"
```
3. 添加示例运行说明到 `src/plugins/device/README.md`
**输出文件**:
- `examples/device_demo.rs` — 示例代码
- `Cargo.toml` — 更新示例配置
- `src/plugins/device/README.md` — 更新运行说明
**验收标准**:
- [ ] `cargo check --examples` 零 warning
- [ ] `cargo run --example device_demo` 能成功运行
- [ ] 示例代码包含清晰的注释说明每个步骤
- [ ] README 包含示例运行说明
**预计工时**: 2 小时
---
## 任务依赖关系图
```
Task 1 (DeviceCommand 扩展 — 光标控制)
Task 2 (LinuxArm64Backend 扩展 — 实现光标控制)
Task 3 (ScreenPlugin 重构 — thin wrapper)
Task 4 (集成测试 — 验证协作)
Task 5 (文档更新与迁移总结)
Task 6 (示例插件完善,可选)
```
## 团队成员分工建议
| 成员 | 角色 | 负责任务 | 理由 |
|----------|----------------|---------------|-----------------------------------------------|
| 张明远 | 内核工程师 | Task 1 | 负责阶段一 Message enum 扩展,熟悉类型系统 |
| 赵雨薇 | 屏幕工程师 | Task 2, 3 | ScreenPlugin 原作者,熟悉 unclutter 和消息流 |
| 李思琪 | 视频引擎工程师 | Task 4, 5 | 负责阶段一测试和文档,熟悉测试框架 |
| 王浩然 | 网络工程师 | Task 6可选| 可参与示例开发,学习 DevicePlugin 使用 |
**核心团队**: 张明远、赵雨薇、李思琪3 人)
**执行模式**: 串行交付Task 1 → Task 2 → Task 3 → Task 4 → Task 5
## 关键风险与应对
### 风险 1: unclutter 在某些 Linux 发行版不可用
**影响**: 中
**应对**: Task 2 中添加错误处理unclutter 失败时记录警告但不阻塞插件启动,光标控制功能降级为 no-op
### 风险 2: ScreenPlugin 重构后消息传递延迟
**影响**: 低
**应对**: Task 4 中添加性能测试,测量消息传递开销(预计 < 1ms如果延迟明显则考虑优化
### 风险 3: 现有依赖 ScreenPlugin 的代码可能受影响
**影响**: 低
**应对**: Task 3 保持 ScreenPlugin 的消息接口不变ScreenLockRequest/CursorVisibility确保向后兼容
### 风险 4: DevicePlugin 未启动时 ScreenPlugin 功能失效
**影响**: 中
**应对**: Task 3 中添加错误处理DevicePlugin 不可用时记录警告Task 4 中添加测试验证降级行为
## 时间估算
| 任务 | 预计工时 | 依赖关系 | 负责人 |
|--------|----------|----------|--------|
| Task 1 | 0.5h | 无 | 张明远 |
| Task 2 | 2h | Task 1 | 赵雨薇 |
| Task 3 | 2h | Task 2 | 赵雨薇 |
| Task 4 | 2.5h | Task 3 | 李思琪 |
| Task 5 | 1.5h | Task 4 | 李思琪 |
| Task 6 | 2h | Task 5 | 王浩然(可选)|
**总计**: 8.5 小时必需任务10.5 小时(含可选任务)
**预计完成时间**: 1-1.5 个工作日(假设单人串行)
**优化方案**:
- Task 1 完成后,赵雨薇可以立即开始 Task 2无等待
- Task 4 和 Task 5 可以部分并行(李思琪先写测试,再写文档)
- Task 6 可以与 Task 5 并行(王浩然独立开发示例)
## 验收总清单
阶段二完成的标志:
- [ ] `cargo check --workspace --all-targets` 零 warning
- [ ] `cargo test --workspace` 全部通过(包括新增的 4+ 个测试)
- [ ] DevicePlugin 支持 Cursor 控制能力
- [ ] ScreenPlugin 重构为 thin wrapper代码行数减少 50%+
- [ ] ScreenPlugin 和 DevicePlugin 协作正常,消息流测试通过
- [ ] 文档完整更新(设计文档 + README + 迁移总结)
- [ ] 手动测试验证:防息屏和光标隐藏功能正常工作
- [ ] 性能测试:消息传递延迟 < 1ms
## 与阶段一的对比
| 维度 | 阶段一(基础框架) | 阶段二ScreenPlugin 迁移) |
|----------------|-----------------------------------|-----------------------------------|
| 任务数量 | 5 个任务4 必需 + 1 可选) | 6 个任务5 必需 + 1 可选) |
| 总工时 | 12-14 小时 | 8.5-10.5 小时 |
| 核心团队 | 4 人(张明远/王思远/赵雨薇/李思琪)| 3 人(张明远/赵雨薇/李思琪) |
| 关键挑战 | 从零搭建架构 | 重构现有插件,保持兼容性 |
| 测试新增 | 5+ 个单元测试 | 4+ 个单元测试 + 集成测试 |
| 文档新增 | 设计文档 + README | 迁移总结 + 集成测试文档 |
## 后续规划(阶段三预告)
阶段二完成后,可以考虑:
1. **完全移除 ScreenPlugin**(如果 thin wrapper 无存在价值)
2. **扩展 DevicePlugin 能力**
- 触摸/按钮输入事件
- 传感器数据读取
- 音频播放
3. **添加其他平台后端**
- Android Backend
- Embedded (bare-metal) Backend
4. **VideoPlugin 迁移**
- 将 framebuffer 写入迁移到 DevicePlugin.WriteFramebuffer
## 汇报要求
每个任务完成后,负责人需要:
1. 运行 `export PATH="/home/showen/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin:$PATH" && cargo check --workspace --all-targets` 验证编译
2. 运行 `export PATH="/home/showen/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin:$PATH" && cargo test --workspace` 验证测试
3. 更新自己的 soul 文件,记录本次任务经验
4. 在 `.showen/TEAM_CHAT.md` 中汇报任务完成情况
全部任务完成后PM 刘建国向 CEO 汇报到 `.showen/inbox/ceo.md`。
---
**文档创建时间**: 2026-03-13
**文档创建人**: PM 刘建国
**文档版本**: v1.0
**基于**: DevicePlugin 阶段一成果73/73 测试通过)

View File

@@ -0,0 +1,4 @@
[CEO 陈逸飞] [2026-03-13]
阶段二规划已审阅并批准。立即开始执行。
PM 规划质量优秀,给予好评。

View File

@@ -1,3 +0,0 @@
# PM 刘建国 Inbox
(已清空 - 2026-03-13