18 KiB
DevicePlugin 阶段二任务分解文档 — ScreenPlugin 功能迁移
项目背景
根据 CEO 陈逸飞指示,DevicePlugin 阶段一(基础框架)已完成并通过 73/73 测试。现进入阶段二:将 ScreenPlugin 的核心功能迁移到 DevicePlugin,实现统一设备管理架构。
阶段一成果回顾
- ✅ Message enum 扩展(DeviceCommand/DeviceResponse/DeviceEvent)
- ✅ DevicePlugin 骨架与 Backend trait 定义
- ✅ LinuxArm64Backend 实现(Display + SleepInhibit + Backlight)
- ✅ 单元测试与文档完善(73/73 测试通过)
阶段二总体目标
- 将 ScreenPlugin 的 systemd-inhibit(防息屏)和 unclutter(光标隐藏)功能迁移到 DevicePlugin
- ScreenPlugin 改为通过 DeviceCommand 调用 DevicePlugin(thin wrapper)
- 确保现有功能不丢失,保持向后兼容
- 为未来完全移除 ScreenPlugin 做准备
当前状态分析
ScreenPlugin 现有功能(src/plugins/screen/mod.rs)
-
防息屏(systemd-inhibit):
start_wake_lock()— 启动 systemd-inhibit 子进程(已在 DevicePlugin 实现)stop_wake_lock()— 停止 systemd-inhibit 子进程(已在 DevicePlugin 实现)- 处理
Message::ScreenLockRequest(bool)消息
-
光标隐藏(unclutter):
set_cursor_hidden(bool)— 启动/停止 unclutter 进程(需要迁移)- 处理
Message::CursorVisibility(bool)消息
-
配置驱动:
- 从
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 光标隐藏实现(参考)
任务描述:
- 在
DeviceCommandenum 中添加新变体:/// 设置光标可见性 /// - true: 显示光标 /// - false: 隐藏光标(通过 unclutter 或平台特定方式) SetCursorVisible(bool), - 在
DeviceCapabilityenum 中添加新能力:/// 光标控制能力 Cursor, - 确保新变体派生
Debug, Clone, Serialize, Deserialize - 添加文档注释说明用途和平台差异
输出文件:
src/core/message.rs— 更新后的消息定义
验收标准:
cargo check --workspace零 warningSetCursorVisible变体正确派生 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)
任务描述:
- 在
LinuxArm64Backend结构体中添加字段:/// unclutter 子进程(用于隐藏光标) cursor_child: Option<Child>, /// 光标可见性状态 cursor_visible: bool, - 在
capabilities()方法中添加DeviceCapability::Cursor - 在
handle_command()中实现SetCursorVisible命令:SetCursorVisible(false)→ 启动 unclutter 进程:pkill -f unclutter # 先清理旧进程 unclutter -idle 0 -root # 立即隐藏光标SetCursorVisible(true)→ 停止 unclutter 进程:pkill -f unclutter- 参考 ScreenPlugin::set_cursor_hidden 的实现(src/plugins/screen/mod.rs:64-101)
- 在
shutdown()方法中清理 cursor_child 进程 - 添加错误处理:unclutter 不可用时记录警告但不阻塞
输出文件:
src/plugins/device/linux_arm64.rs— 更新后的 Backend 实现
验收标准:
cargo check --workspace零 warningSetCursorVisible(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— 消息定义
任务描述:
- 重构
ScreenPlugin结构体,移除直接硬件操作字段:pub struct ScreenPlugin { ctx: Option<PluginContext>, // 移除 wake_lock_child: Option<Child> // 移除 cursor_hidden: bool } - 重构
start_wake_lock()方法: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); } } - 重构
stop_wake_lock()方法(类似,发送SetSleepInhibit(false)) - 重构
set_cursor_hidden()方法: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); } } - 保持
handle_message()的消息接口不变:Message::ScreenLockRequest(bool)→ 调用 start/stop_wake_lockMessage::CursorVisibility(bool)→ 调用 set_cursor_hidden
- 移除所有
#[cfg(target_os = "linux")]条件编译(平台适配由 DevicePlugin 负责) - 在文件顶部添加注释说明 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— 重构后的 ScreenPluginsrc/plugins/device/— DevicePlugin 实现src/plugins/device/tests.rs— 现有测试(参考)
任务描述:
- 在
src/plugins/device/tests.rs中添加光标控制测试:#[test] fn test_set_cursor_visible() { // 测试 SetCursorVisible 命令的序列化/反序列化 } #[test] fn test_cursor_capability() { // 测试 LinuxArm64Backend 报告 Cursor 能力 } - 创建
src/plugins/screen/tests.rs:#[test] fn test_screen_lock_request_sends_device_command() { // 测试 ScreenLockRequest 消息转换为 DeviceCommand::SetSleepInhibit } #[test] fn test_cursor_visibility_sends_device_command() { // 测试 CursorVisibility 消息转换为 DeviceCommand::SetCursorVisible } - 在
src/plugins/screen/mod.rs中添加#[cfg(test)] mod tests; - 编写集成测试文档
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零 warningcargo 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— 重构后的 ScreenPluginsrc/plugins/device/README.md— DevicePlugin 文档
任务描述:
- 更新
docs/DEVICE_PLUGIN_DESIGN.md:- 在第 6 节"实施计划"中标记阶段二已完成
- 在第 8 节"验收标准"中勾选 ScreenPlugin 迁移项
- 添加"阶段二成果"章节,说明 ScreenPlugin 迁移细节
- 更新
src/plugins/device/README.md:- 在"支持的能力"中添加 Cursor 控制
- 添加"与 ScreenPlugin 的关系"章节,说明迁移历史
- 更新
src/plugins/screen/mod.rs文件头注释://! ScreenPlugin — 屏幕管理(Thin Wrapper) //! //! 本插件现在是 DevicePlugin 的 thin wrapper,通过 DeviceCommand 消息 //! 调用 DevicePlugin 实现防息屏和光标隐藏功能。 //! //! 历史:v0.1.0 直接调用 systemd-inhibit 和 unclutter //! v0.2.0 迁移到 DevicePlugin(2026-03-13) - 创建迁移总结文档
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 文档
任务描述:
- 创建
examples/device_demo.rs:- 演示如何发送
DeviceCommand::GetDisplayInfo - 演示如何发送
DeviceCommand::SetSleepInhibit - 演示如何发送
DeviceCommand::SetCursorVisible - 演示如何接收
DeviceResponse
- 演示如何发送
- 在
Cargo.toml中添加示例配置:[[example]] name = "device_demo" path = "examples/device_demo.rs" - 添加示例运行说明到
src/plugins/device/README.md
输出文件:
examples/device_demo.rs— 示例代码Cargo.toml— 更新示例配置src/plugins/device/README.md— 更新运行说明
验收标准:
cargo check --examples零 warningcargo 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零 warningcargo 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 | 迁移总结 + 集成测试文档 |
后续规划(阶段三预告)
阶段二完成后,可以考虑:
- 完全移除 ScreenPlugin(如果 thin wrapper 无存在价值)
- 扩展 DevicePlugin 能力:
- 触摸/按钮输入事件
- 传感器数据读取
- 音频播放
- 添加其他平台后端:
- Android Backend
- Embedded (bare-metal) Backend
- VideoPlugin 迁移:
- 将 framebuffer 写入迁移到 DevicePlugin.WriteFramebuffer
汇报要求
每个任务完成后,负责人需要:
- 运行
export PATH="/home/showen/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin:$PATH" && cargo check --workspace --all-targets验证编译 - 运行
export PATH="/home/showen/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin:$PATH" && cargo test --workspace验证测试 - 更新自己的 soul 文件,记录本次任务经验
- 在
.showen/TEAM_CHAT.md中汇报任务完成情况
全部任务完成后,PM 刘建国向 CEO 汇报到 .showen/inbox/ceo.md。
文档创建时间: 2026-03-13
文档创建人: PM 刘建国
文档版本: v1.0
基于: DevicePlugin 阶段一成果(73/73 测试通过)