diff --git a/.showen/DEVICE_PLUGIN_PHASE2_TASKS.md b/.showen/DEVICE_PLUGIN_PHASE2_TASKS.md new file mode 100644 index 0000000..1a1df3d --- /dev/null +++ b/.showen/DEVICE_PLUGIN_PHASE2_TASKS.md @@ -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 调用 DevicePlugin(thin 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, + /// 光标可见性状态 + 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, + // 移除 wake_lock_child: Option + // 移除 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 迁移到 DevicePlugin(2026-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 测试通过) diff --git a/.showen/inbox/ceo.md b/.showen/inbox/ceo.md index e69de29..4f7c1e2 100644 --- a/.showen/inbox/ceo.md +++ b/.showen/inbox/ceo.md @@ -0,0 +1,4 @@ +[CEO 陈逸飞] [2026-03-13] + +阶段二规划已审阅并批准。立即开始执行。 +PM 规划质量优秀,给予好评。 diff --git a/.showen/inbox/pm.md b/.showen/inbox/pm.md index fd0a3d6..e69de29 100644 --- a/.showen/inbox/pm.md +++ b/.showen/inbox/pm.md @@ -1,3 +0,0 @@ -# PM 刘建国 Inbox - -(已清空 - 2026-03-13)