350 lines
36 KiB
Markdown
350 lines
36 KiB
Markdown
# MeowOS 阶段 D:Activity / 通知 IPC 框架设计文档
|
||
|
||
> 状态:协议/架构参考稿(2026-08-28 起草;**以下协议已随 M2.15-M2.90 各里程碑落地**,消息号以 `patch_v2/meow_launcherd/meow_ipc.h` 为准)。本阶段的「只设计、不实现」为起草期口径;M0-M3/M5/§10.5/媒体会话/amsd/meow_audiod(独占音频守护,规范 `devdocs/plan/AUDIOD_DESIGN.md`)已实现,M4 后台服务保活与 M6 加固待排期(见 §9 进度)。
|
||
> 前置:ANALYSIS.md §18(Launcher 全架构)、§11(播放器 unix socket 先例)、APPS.md、DEVELOPMENT_PLAN.md 阶段 0/D。
|
||
> 实现语言:启动器 C(musl 静态 MIPS32r2,zig-mipsel-cc);应用同为 C 静态 MIPS。
|
||
> 补充:本文件由 plan 子代理产出设计,主会话落盘,并附「后台运行/后台播放权限」(用户追加)。
|
||
|
||
## 0. 目标与一句话概括
|
||
|
||
让 MeowOS 成为"单机迷你 Activity 框架":
|
||
- 应用经 **AF_UNIX socket** 向主守护进程(meow_launcherd,即 MeowOS 核心)推送通知、注册后台服务;
|
||
- 通知绑定 target Activity;通知中心点击后按路由表解析启动链路,逐层拉起应用、压入按应用隔离的导航栈;
|
||
- 返回语义:应用内逐屏回退到"上一层",回到栈根才退出到应用列表(回到 MeowOS 主屏 / 播放器)。
|
||
|
||
**核心架构决策**:
|
||
1. **IPC 线程只读帧+解析+入队;所有状态变更由主循环单写者应用**——主循环对时序敏感(10ms 热键轮询、SIGSTOP 让位、fb pan),绝不在 socket IO 阻塞。
|
||
2. **导航栈:应用管屏内上翻,启动器管"回到根→退出到列表"边界** + 冷启动跳转的栈初始化。
|
||
3. **后台服务永远无头(不碰 fb0/输入)、永不被 SIGSTOP**——SIGSTOP 只用于抢占用 fb/输入的前台会话。
|
||
|
||
## 1. IPC 通道(AF_UNIX socket)
|
||
|
||
- 类型 `SOCK_STREAM`,路径 `/usr/data/meow_ipc.sock`(unlink 后 bind),`chmod 0666`,backlog 4。
|
||
- 帧格式:定长头(16B) + 变长负载,**全部小端 LE**(mipsel 原生)。
|
||
|
||
```c
|
||
struct ipc_hdr { /* LE */
|
||
uint32_t magic; /* 0x4D4F5701 = 'MEOW'|1 */
|
||
uint16_t version; /* 1 */
|
||
uint16_t type; /* msg_type */
|
||
uint32_t req_id; /* 请求id,响应回显 */
|
||
uint32_t len; /* payload 字节数 */
|
||
};
|
||
```
|
||
- `len` 上限 `MEOW_IPC_MAX=4096`;读满 16B 头→校验 magic/version→读 len→分发。
|
||
- 列表编码:`[u16 count]` + count 个 NUL 结尾字符串。
|
||
|
||
### 消息类型
|
||
| type | 名称 | 方向 | 用途 |
|
||
|---|---|---|---|
|
||
| 0x0001 | MSG_HELLO | ↑ | 声明 app_id/版本/能力 |
|
||
| 0x0002 | MSG_ACK | ↓ | 握手/应答 |
|
||
| 0x0003 | MSG_ERR | ↓ | 错误码 |
|
||
| 0x0010 | MSG_REGISTER | ↑ | 注册后台服务(保持连接) |
|
||
| 0x0011 | MSG_SERVICE_OK | ↓ | 服务登记成功 |
|
||
| 0x0012 | MSG_SERVICE_STOP | ↑ | 请求停止服务 |
|
||
| 0x0020 | MSG_NOTIFY | ↑ | 推送/更新通知 |
|
||
| 0x0021 | MSG_NOTIFY_ACK | ↓ | 落库结果 |
|
||
| 0x0022 | MSG_NOTIFY_DISMISS | ↑ | 撤下通知 |
|
||
| 0x0023 | MSG_NOTIFY_LIST | ↓ | 下发通知清单(重同步) |
|
||
| 0x0024 | MSG_NOTIFY_PROGRESS | ↑ | 实时更新通知进度(仅改内存活跃槽,不落盘) |
|
||
| 0x0025 | MSG_NOTIFY_QUERY | ↑ | 查询内存活跃通知集(MeowPanel 实时化前置) |
|
||
| 0x0026 | MSG_NOTIFY_DISMISS_ALL | ↑ | 一键清除(保留 ongoing/media/progress 进行中,同通知中心 UI) |
|
||
| 0x0027 | MSG_NOTIFY_QUERY_RESULT | ↓ | 活跃通知集序列化文本(JSON,字段同 TF 归档) |
|
||
| 0x0028 | MSG_NOTIF_OPEN | ↑ | **(已实现,号以 `meow_ipc.h` 为准)** App 检测到顶部下滑→请求 launcher 展开通知中心叠加会话(App 前台,见 §10.5) |
|
||
| 0x0029 | MSG_NOTIF_CLOSE | ↑ | **(已实现,可选用途)** App 告知结束/退出→launcher 收尾兜底(见 §10.5) |
|
||
| 0x0030 | MSG_ACT_DECLARE | ↑ | (重)声明路由表 |
|
||
| 0x0031 | MSG_ACT_QUERY | ↑ | 解析 activity 链路 |
|
||
| 0x0032 | MSG_ACT_RESULT | ↓ | 返回链路 |
|
||
| 0x0040 | MSG_NAV | ↑ | 上报导航/请求退出(**M3 导航栈已落地**) |
|
||
| 0x0041 | MSG_SHOW_ACTIVITY | ↓ | 令前端应用显示某屏 |
|
||
| 0x0070 | MSG_PICKER_CALL | ↑ | 请求跨 App picker 调用(发起方 A → 持有方 B;**已实现**,amsd 二期 agent-225:`am picker`/`picker-status`,files_app 注册 `pick_file`) |
|
||
| 0x0071 | MSG_PICKER_RESULT | ↓ | picker 返回值(候选结果回 A;**已实现**,amsd 二期) |
|
||
| 0x00A0 | MSG_AMS_START | → | amsd→launcher:请求拉起某 App(pkg + 可选 activity,含 picker 上下文 `MEOW_PICKER_*`;**已实现** agent-212/225) |
|
||
| 0x00A1 | MSG_AMS_KILL | → | amsd→launcher:请求终止某 App(SIGTERM 语义;**已实现**) |
|
||
| 0x0072 | MSG_META | ↑ | 媒体会话上报元数据/进度/状态(**附录 B 已落地**,最近活跃源回收) |
|
||
| 0x0073 | MSG_PLAYCTL | ↓ | 播放控制下发 / ↑ 控制器转发到最近活跃媒体会话(**已落地**) |
|
||
| 0x00F0 | MSG_SYS | ↓ | 系统事件(守护关闭/服务死亡/播放器状态) |
|
||
|
||
负载结构体见设计稿正文(m_hello/m_notify/m_register/m_act_* 等,定长多字节 LE)。消息号**一律以 `patch_v2/meow_launcherd/meow_ipc.h` 为准**,本节为引用性摘要。
|
||
|
||
## 2. Activity 路由表
|
||
|
||
- `app_id` = `MeowAPPs/<dir>/` 目录名(app.json 可覆盖)。
|
||
- `activity_id` 全局唯一为 `app_id/activity_id`。
|
||
- **启动链路**:根屏→目标屏的 activity_id 序列(`;` 分隔),链长=逻辑深度。
|
||
- 静态路由用 **app.json 扁平行**(不引入 JSON 解析器):
|
||
`route.<id>=path`(如 `route.nowplaying=home;search;nowplaying`);`framework=true`(看门狗返回发 SIGUSR1);`service.<svc>=mode:restart:max:window_ms`。
|
||
- 运行时 `MSG_ACT_DECLARE` 并集覆盖静态。
|
||
- 校验:`route` 缺失→深度 1 兜底;activity 未注册→ERR_UNKNOWN_ACTIVITY。
|
||
|
||
## 3. 导航栈
|
||
|
||
- `struct nav_stack`(每应用一个,≤16 深度),`active` 前台标记。v1 同一时刻单前台应用。**(M3 已落地,M2.80:`nav_stack` + `MSG_NAV` report/exit + `launch_activity` 链路注入 env `MEOW_ACTIVITY`/`MEOW_CHAIN`,栈根退出回主屏;通知点击按 `route_status`:0 拉起 / 1 NO ROUTE / 2 SOURCE NOT FOUND / -1 NONE 关面板不动作;裸 App 兼容。)**
|
||
- push/pop;**回退**:应用弹自己的屏并上报 `MSG_NAV{REPORT,depth,current}`;应用在根屏再按返回→`MSG_NAV{EXIT}`→启动器终止应用、恢复播放器、回列表。
|
||
- **冷启动通知跳转**:`resolve_chain` → 设栈深 → `launch_activity(app, chain)`,环境 `MEOW_ACTIVITY=<target>` + `MEOW_CHAIN=<id0>;<id1>;...;<top>`。
|
||
- 向下兼容:应用若不发 MSG_NAV,启动器保持初始深度;应用在根屏 `exit(0)` 即退出到列表(旧版行为)。
|
||
|
||
## 4. 通知生命周期
|
||
|
||
- 内存态(配额 ≤16/应用,满丢最旧);ttl 过期(1s 粒度);ONGOING 服务常驻通知(服务死→随清)。
|
||
- 点击按 route_status:0 跳转(tap_notification 逐层 launch);1/2 友好 toast(NO ROUTE / SOURCE NOT FOUND),不崩。
|
||
- 通知仅内存,不跨守护重启持久化(服务重启后重发重建)。
|
||
|
||
## 5. 后台服务保活
|
||
|
||
- `MSG_REGISTER` 登记;`service_spawn/stop/reap`;`SIGCHLD`→eventfd 回收;退避重启 1/2/4/10s(cap);`max_restart` 熔断→清通知+广播 MSG_SYS{2}。
|
||
- **服务无头契约**:禁止 open /dev/fb0、禁读 /dev/input/*、禁碰亮度/面板;**永不被 SIGSTOP**。
|
||
- SIGTERM 时依次关服务再 SIGCONT 播放器。
|
||
|
||
## 6. 与现有启动器整合
|
||
|
||
- `main()` 起 IPC 线程 + eventfd;主循环 `poll(eventfd,0)` 排空 pending。
|
||
- `run_menu` 的 poll 集合加 eventfd(通知徽标 + 阶段 B 下拉面板预留 API:`notify_count/at/dismiss`)。
|
||
- `launch_app` → `launch_activity(a, chain)` + env;waitpid 循环 poll eventfd 收 NAV{EXIT/REPORT}。
|
||
- 看门狗:framework 应用虚拟返回键发 SIGUSR1(沉浸手势同信号),非框架保持 SIGTERM。
|
||
- **所有 IPC/通知触发的 launch 必须走统一安全出口**(fb 备份→归 0→绘制→...→fb 恢复→SIGCONT),提前返回也要确保恢复。
|
||
|
||
## 7. 边界(不崩启动器,给友好提示)
|
||
未注册/路由缺失/二进制缺失/exec 失败/秒崩/服务熔断/配额/坏帧/应用死锁(看门狗强杀兜底)等,逐一对应 toast / MSG_ERR / 日志,见设计稿正文表。
|
||
|
||
## 8. 安全
|
||
单机信任模型,AF_UNIX 0666 无认证不防恶意;只做健壮性防御(帧长/配额/服务数/熔断/越界检查)。明确不做沙箱与恶意应用防护。
|
||
|
||
## 9. 实现里程碑
|
||
M0 IPC 骨架(含 meow_ipc 测试钩子)→ M1 路由表+解析 → M2 通知存储+分发 → M3 导航+前台会话改造+看门狗返回 → M4 后台服务保活 → M5 阶段 B 通知中心 UI 整合 → M6 加固+边界+稳定性验收。建议先落 M0+M1(纯内存/socket,SSH 全验证,不动播放器),再进 M3(触碰 SIGSTOP)。
|
||
|
||
### 进度(阶段 D)
|
||
- ✅ **M0 IPC 骨架**(0.7.10,M2.15):`meow_launcherd` 加 IPC 线程 + AF_UNIX `/usr/data/meow_ipc.sock`(unlink+bind+chmod0666+listen4)+ 帧解析(16B 头 magic=0x4D4F5701/version=1/type/req_id/len,LE)+ `MSG_HELLO/ACK/ERR` + eventfd 唤醒主循环 + 无锁 SPSC 内存环(`__sync`)+ 日志埋点。遵守 §1/§6.2:IPC 线程只读帧+解析+入队,主循环 `meow_ipc_process()` 单写者改状态,跨线程 eventfd,主循环 10ms 热键轮询每圈非阻塞排空(eventfd 失败时 10ms 轮询兜底)。测试钩子:`meow_ipc`(`patch_v2/meow_launcherd/meow_ipc.c`,静态 MIPS,与 evtool 同定位)+ launcher `--ipc-only N [--ipc-sock <path>]`。验证:`meow_ipc hello`→ACK、播放器不动(MeowOS 模式下无播放器即满足)。
|
||
- ✅ **M1 路由表 + 解析**(0.7.10,M2.15):`app.json` 扁平行 `route.<id>=path` / `framework=true` / `service.<svc>=mode:restart:max:window_ms` / `icon` 解析入 `g_accts` 注册表(主循环单写者);`MSG_ACT_DECLARE`(运行时并集覆盖静态)/`MSG_ACT_QUERY`/`MSG_ACT_RESULT`(深度+链路);`resolve_chain(app,activity)` 返回 `[root..target]` 链路与深度——`route` 缺失(app 未声明路由)→ 深度 1 兜底 `chain=activity`;声明了路由但 activity 非 route 键 → `MEOW_ERR_NOENT`(activity 未注册)。验证:`meow_ipc query <app> <activity>` 返回链路(qemu + 真机 MeowOS 模式均通)。
|
||
- ✅ **M2 通知存储+分发**、**M3 导航+前台会话改造+看门狗返回**、**M5 通知中心 UI 整合**(详见下,M2.65-M2.82 已落地);⬜ **M4 后台服务保活**(`MSG_REGISTER` 后台服务登记)、**M6 加固**:待排期。
|
||
- **M3 已落地(M2.80,agent-202 · 85b4aea)**:`nav_stack`(≤16 深)+ `MSG_NAV` REPORT/EXIT + `launch_activity` 链路注入(env `MEOW_ACTIVITY`/`MEOW_CHAIN`)+ 栈根退出回主屏;通知点击按 `route_status`(0 拉起/1 NO ROUTE/2 SOURCE NOT FOUND/-1 NONE 关面板不动作);裸 App 兼容。
|
||
- **amsd(一期 agent-212 · 5fbf307 + 二期 agent-225)已落地**:活动管理器守护(svcd 托管 `trigger=boot`)+ `am` CLI(status/list/history/start/kill/`resolve`/`picker`)。二期将路由表迁 amsd(amsd 路由权威)+ **picker 契约**(`MSG_PICKER_CALL=0x70`/`MSG_PICKER_RESULT=0x71`,`am picker`/`picker-status`;files_app 注册 `picker.pick_file` 选文件返回路径)+ `MSG_AMS_START/KILL=0x00A0/0x00A1`(amsd→launcher 决策执行)。参见 `devdocs/plan/AMSD_DESIGN.md`。
|
||
- **M5 通知中心 UI 整合已落地(M2.65-M2.81)**:通知中心 + 媒体卡片 + Now Playing(媒体会话见附录 B,已落地:`meow_media.c` 最近活跃源、30s 超时回收、`MSG_META`/`MSG_PLAYCTL`)。
|
||
- **§10.5 App 前台唤起通知中心已落地(M2.82,agent-206 · 9b41957)**:`MSG_NOTIF_OPEN=0x28`/`CLOSE=0x29` + SDK `meow_ui_nav`/`meow_ui_media` 封装。
|
||
- ✅ **渲染地基(0.7.11,M2.16,前置基座)**:所有 UI 统一走 **RAM 离屏后备缓冲 `back_buf`(480×720×2=691,200B) + `meow_present`(dirty)** = `FBIO_WAITFORVSYNC` 等垂直同步 + 单次原子 memcpy(脏区或全帧)到 fb0(buffer0,yoffset=0)——无渐进/无中间态/无撕裂。脏区 `meow_dirty_add`(矩形合并集、相交吸 bbox、>12 转全屏、裁可视区);状态栏时钟/右侧格按需局部标脏。整合铺垫:框架后续 LAUNCH/NOTIFY/前台会话的绘制复用该机制(而非旧「全屏 clear→重绘到 buffer0」路径)。详情见 ANALYSIS.md §18.43。刷新率调度(display.refresh_rate 60/30/15 + refresh_always_max + 自适应降档 governor)归口 PERF_SCHEDULER.md。
|
||
- 测试钩子说明:`meow_launcherd --appinfo <app.json>`(打印单个 app.json 解析结果)、`--ipc-only N`(免 fb/输入跑 IPC)、`--ipc-sock <path>`(覆盖 socket 路径供 qemu sim);`meow_ipc hello|ping|query|declare`(客户端)。
|
||
|
||
---
|
||
|
||
## 10. 进程模型 / Supervisor 树 [源:2026-08-30 定案]
|
||
|
||
> 定位:本文档 §1-§9 聚焦「MeowAPP ↔ 启动器」的 Activity/通知 IPC;本节补齐**系统层面进程架构**——各系统进程的职责边界、监管关系与故障隔离,落实「一个崩不全部崩」。与 §5 后台服务保活**互补**:§5 管 MeowAPP 注册的**后台服务**,本节管 **MeowOS 自身系统进程**。跨文档:MEOW_APP_SDK §6.1、NOTIFICATION_SYSTEM §9、docs/MEOWOS_SPEC_REF §3.1/§5.1。
|
||
|
||
### 10.1 进程角色与 Supervisor 树
|
||
|
||
| 进程 | 职责 | 监管关系 | 崩溃隔离(核心诉求) |
|
||
|---|---|---|---|
|
||
| **meow_sysui**(新增,meow_svcd 托管) | **系统进程总监**:监管所有系统进程,监控存活 + 逐个拉起 | 监管 launcher / meow_svcd / meow_mdns / 未来媒体服务 / MeowPanel | 自身**最小依赖、不渲染、不承载重逻辑** → 最稳;**一个进程崩→只拉起它,绝不级联、绝不拖垮自身** |
|
||
| **meow_launcherd** | **系统 UI 渲染宿主**:SDK 全局状态栏、通知中心(下拉)、电源菜单、全局左缘返回/滑条;另含启动器主界面、设置页 | 被 sysui 监管;与 APP 进程独立 | 与 APP 渲染进程独立(见 §10.2) |
|
||
| **meow_svcd** | **服务管理器**:每个服务 = 独立子进程(fork+exec+setpgid) | 被 sysui 监管;其服务子进程由 svcd 托管 | 服务崩→svcd 捕获(waitpid)+只重启该子进程;**svcd 自身绝不因服务崩而崩**(信号/超时/僵死隔离) |
|
||
| **APP 进程** | 只渲染自己内容(经 SDK 语义事件) | 框架(IPC/launch)管理 | 崩→不连累 launcher / sysui / svcd |
|
||
|
||
**Supervisor 树(目标架构):**
|
||
|
||
```
|
||
meow_sysui(系统进程总监,meow_svcd 托管;最小依赖/不渲染/最稳)
|
||
├─ meow_launcherd 系统 UI 渲染宿主(主界面/设置页/电源菜单/全局状态栏/通知中心/全局手势)
|
||
├─ meow_svcd 服务管理器(服务=独立子进程;逐个子进程崩溃隔离)
|
||
│ ├─ meow_mdns mDNS 应答器(板载 /usr/data/meow/services.d/mdnsd.conf,trigger=boot)
|
||
│ ├─ meow_audiod 独占音频守护(M2.90;独占 hw:0,0+抢占+路由并入;HibyOS 模式门控 exit(0) 不启动——规范 devdocs/plan/AUDIOD_DESIGN.md)
|
||
│ └─ 未来媒体服务 / 其它 services.d 服务(TF MeowOS/services.d/…)
|
||
├─ 未来媒体服务 / MeowPanel(后置)
|
||
```
|
||
|
||
> **专项子服务(扩展,见 `devdocs/plan/SYSTEM_FRAMEWORK_SERVICES.md`)**:把**系统复用功能收敛到系统框架**,
|
||
> 新增两个 **svcd 托管、板载 `trigger=boot`** 的专项子服务挂在 svcd 之下——`meow_svc_perf`(性能/系统只读聚合)、
|
||
> `meow_svc_power`(关机/重启/升级/回HiBy 系统动作)。launcher 电源菜单与 MeowPanel 均改为**经这些服务 IPC 触发**,
|
||
> 不再直连 `sys_do_reboot`/爬 `/proc`。属 §10 supervisor 树的一种**既有托管模式的扩展**(服务仍为 svcd 子进程,
|
||
> 崩溃隔离/subreaper 语义不变,不改变本节定案;Ⅱ期补 .mpk 签名与关键 IPC 的 `os.meow.*` 鉴权)。电源 CLI 为
|
||
> `meow_svc_power <cmd>`(root 免鉴权、单一命令、不覆盖系统 shutdown/reboot),命令一览见 `docs/MEOWOS_SPEC_REF.md` §4。
|
||
|
||
> **launcher 源码拆分(M2.69 落地,纯代码组织重构,不影响本 §10 进程模型)**:`patch_v2/meow_launcherd/meow_launcherd.c`
|
||
> (曾 9778 行单文件)拆为 `patch_v2/meow_launcherd/` 多模块(14 模块
|
||
> `main_menu/statusbar/settings_page/power_menu/notif_center/app_launcher/fb_compositor/audio/backlight/net/about/font_theme/keys/util`
|
||
> + 共享头 `meow_launcher_internal.h`;`build_launcher.sh` 列模块)。二进制名 `/usr/bin/meow_launcherd`(bootmenu `LAUNCHER_BIN`)
|
||
> 不变、行为不变(见 README §2.3)。
|
||
|
||
> **托管关系澄清**:定案中的「meow_sysui(新增,meow_svcd 托管)」指 sysui 由**开机启动链**拉起(现网 S89 init.d/S90 bootmenu 归属,后续归 sysui 自身),并居于 svcd **之上**为总监——**不是** svcd 的子进程。监管方向固定:**sysui 总监 → svcd 被监管 → 服务为 svcd 子进程**。即便将来引导顺序先起 svcd 再起 sysui,此方向不变。
|
||
|
||
**监管语义(权威)**:
|
||
- **一个崩、只拉起它**:任一被监管进程崩溃(非零退出/被信号杀)→ 所属 supervisor **只重启该进程**,不级联重启、不影响相邻进程、不拖垮 supervisor 自身。
|
||
- **svcd 崩 → sysui 拉起**;launcher 崩 → sysui 拉起;mdns 崩 → svcd 拉起(或 sysui 兜底)。
|
||
- **「一个崩不全部崩」= 每进程独立 + 总监逐个拉起 + 单项故障不扩散**;「服务崩溃不导致 meow_svcd 崩溃」= **服务全部子进程化**(fork+exec+setpgid,svcd 只 waitpid 感知,绝不 dlopen/共享内存接服务)。
|
||
|
||
**现网 vs 定案(迁移说明,避免矛盾)**:
|
||
- 现网:launcher 由 bootmenu `execv` 起动(S90meow_bootmenu);svcd 由固件 `etc/init.d/S89meow_svcd` 自启(`-f` 前台)。二者**当前互不监管**。
|
||
- 定案:改为 **meow_sysui 统一监管** launcher/svcd/mdns/媒体服务/MeowPanel。属**系统基建线**(渐进迁移,非一次性推翻现网 S89/S90)。在此落地前,现网的「bootmenu+init.d 各自拉起」仍有效,但**不得**新增依赖打破「进程独立 + 崩溃隔离」约束。
|
||
- **已落地(M2.83)**:launcher 的启动权已由 bootmenu 移交 sysui(`S70meow_sysui` 预置 `sysui.d/launcher.conf` `enabled=1`;bootmenu 在 MeowOS 模式让位——sysui 在则不 exec launcher,只由 sysui 拉起/重启;sysui 不在时 bootmenu 兜底 exec)。svcd 由 sysui 监管(`svcd.conf` `enabled=1`,S89 在 sysui 存在时交给 sysui)。**仍待迁移**:mdns(svcd 负责,sysui 兜底默认关)、未来媒体服务、MeowPanel。
|
||
|
||
### 10.2 系统 UI 归属与进程隔离 [源:2026-08-30]
|
||
|
||
- **系统组件渲染归系统进程(launcher)**:状态栏 / 通知中心(下拉)/ 电源菜单 / 全局左缘返回与滑条等**全局叠加层**,一律由系统进程(meow_launcherd)负责渲染;**APP 进程不渲染系统 UI**(跨引用 MEOW_APP_SDK §6.1 ③「系统级控件仅系统内部」)。
|
||
- **SDK 提供系统组件 API 仅供系统进程链接调用**:SDK 内保留系统级控件的内部接口位(§6.1 ③);**用户 App 拿不到**、**不可自建悬浮层/全局叠加**(会引入遮挡、冲突、性能与安全风险)。App 这类需求只能走 SDK 标准能力。
|
||
- **进程隔离**:SDK 负责**系统组件渲染**的进程(launcher)与负责 **APP 渲染**的进程**相互独立**——APP 卡死/崩溃时,系统 UI(launcher)**不崩**,始终可息屏/返回/下拉通知中心(对应「物理键全局接管,APP 禁映射」APPS §3.4.1)。
|
||
- **APP 侧职责**:只画自己的内容;经 IPC 上报**全屏声明**(`fullscreen`/`route.<id>.fullscreen`)、**内容区域**(inset)与**前台 activity**;系统 UI 据此做叠画(复用 fb 双缓冲 `fb_backup/restore/pan`)与 hits 命中分流(MEOW_APP_SDK §6.1 交互分层:③ 系统全局 → ② App 全局 → ① 当前 Activity 页面控件)。
|
||
|
||
- **「同一个状态栏」正确闭环([源:2026-08-30] 收敛修正,M2.66)**:状态栏是**同一个渲染主体**,不是「样式一样的两套实现」——
|
||
- **系统进程(launcher)统一渲染**:无论主界面还是 App 前台,状态栏都由系统 UI 进程(meow_launcherd)渲染——主界面与 App 前台用**同一个**状态栏实例(真实同一主体,非各画各的)。
|
||
- **App 前台 → 状态栏为系统叠加层**:App 前台时状态栏作为**系统叠加层**盖在 App 内容之上,复用 fb 双缓冲叠加(`fb_backup/restore/pan`,见 §10.5 / `devdocs/plan/NOTIF_CENTER_APP_OVERLAY_PLAN.md`);与通知中心/电源菜单区别:状态栏**常驻**(仅顶条 28px,不进/不出会话、非模态面板)。
|
||
- **App 进程不渲染状态栏**:SDK 全局状态栏**仅系统进程链接渲染**;**App 进程不自绘、拿不到**(§6.1 ③ 系统级控件仅内部;App 这类需求只能走 SDK 标准能力,不得自建全局叠加/悬浮层)。
|
||
- **数据源唯一**:状态栏数据(时间/电量/WiFi/音量/亮度)由 launcher **统一喂/取**(单一权威源)→ 主界面与 App 两边显示**必然一致**(根治 M2.66「launcher 右侧有亮度、App 没有」的不一致)。
|
||
- **与 §10 定案闭环**:§10.1 表已定「meow_launcherd = 系统 UI 渲染宿主」;本节把状态栏明确纳入该系统 UI 渲染宿主职责,与「APP 不渲染系统 UI」(§10.2 首条)自洽,落实「一个渲染主体 + 一个数据源」。
|
||
|
||
### 10.3 通知中心归属 [源:2026-08-30]
|
||
|
||
- **通知中心 UI 渲染主体 = 系统进程(launcher),非 APP**(跨引用 NOTIFICATION_SYSTEM §9)。
|
||
- **数据**:通知列表经 IPC 从通知存储/通知服务读(`MSG_NOTIFY_LIST` 重同步等),launcher 只做 UI 呈现与手势。
|
||
- **交互**:状态栏下滑展开、上滑/点面板外关、左缘返回关(与全局左缘返回/顶部滑条按起始位置分流,见 docs/MEOWOS_SPEC_REF §5.1)。
|
||
- **协议/约束**:遵守 freedesktop 字段、配额(每 App 4 类型×每类型 4、媒体单例)、TTL、转储(10s+10MB ring)、urgency/icon/progress(见 NOTIFICATION_SYSTEM §5-§8)。
|
||
|
||
### 10.4 启动器 SDK 改造 [源:2026-08-30]
|
||
|
||
- **状态栏收敛为单一 SDK 全局**:launcher 现状私有 `draw_statusbar()` **退役移除**,统一走 SDK 全局状态栏(`meow_ui.h` §3.1;28px,默认显示,APP 声明全屏/`fullscreen` 才隐藏/收合)。
|
||
- **launcher 主界面 / 设置页 / 电源菜单全部迁到 SDK 控件**:逻辑/渲染走 SDK(MEOW_APP_SDK §6.1 ② App 跨 Activity 控件、§5.4 A① 分组设置表单、§5.7 B④ 面板等模板),MD3 化、日/夜主题(`display.theme_mode`)、全局 UI 统一。
|
||
- **不让 app 自建叠加**:app 一律经 SDK 标准能力;系统级叠加(状态栏/通知中心/电源菜单/全局手势)只在系统进程内实现。迁移后 launcher 与 APP 用同一套 SDK 渲染地基,观感/生命周期统一。
|
||
|
||
### 10.5 App 前台划出通知中心(跨进程叠加会话)[源:2026-08-30]
|
||
|
||
> 定位:补齐「全屏 App(如 hello)前台时,App 进程内顶部下滑也能唤起**由 launcher 渲染**的通知中心」。
|
||
> 详细实现方案见 `devdocs/plan/NOTIF_CENTER_APP_OVERLAY_PLAN.md`;本节为**定案决策**(归属/归属不变/协议/会话/故障隔离)。
|
||
|
||
- **交互与归属(不变)**:App 前台时顶部下滑,**App 进程只负责「检测手势 + 经 IPC 上报」**;通知中心
|
||
**仍由 launcher 渲染**(符合 §10.2「系统 UI 归 launcher」/`MEOW_APP_SDK §6.1 ③`/`NOTIFICATION_SYSTEM §9`);
|
||
**App 进程不渲染系统 UI**(不叠加状态栏/通知中心)。手势检测在 App 进程 SDK(`meow_ui_input.c` 已把
|
||
「起点在顶部热区+向下主导」识别为系统保留手势 `MEOW_EV_NOTIF_PULL` → 路由 `meow_ui_sys_notif_pull()`)。
|
||
- **跨进程握手(复用现有 IPC,不新增 socket)**:复用 `AF_UNIX /usr/data/meow_ipc.sock`(`meow_ipc.h
|
||
MEOW_IPC_PATH`,launcher `ipc_thread` bind/listen)。拟新增上行消息:
|
||
- `MSG_NOTIF_OPEN`(App→launcher):App 检测到顶部下滑→请求展开通知中心叠加会话;负载 `m_notif_open_t`
|
||
(app_id/event_seq/origin_x/origin_y/hotzone/flags)。launcher 回 `MSG_ACK` 受理(best-effort,App 不强依赖)。
|
||
- `MSG_NOTIF_CLOSE`(App→launcher,可选用途):App 告知结束/退出→launcher 收尾(清 active/SIGCONT 兜底)。
|
||
- 号段/结构以 `meow_ipc.h` 回填为准。**已实现(M2.82,agent-206 · 9b41957)**:`MSG_NOTIF_OPEN=0x0028` / `MSG_NOTIF_CLOSE=0x0029`(`0x0025/0x0026` 已被通知查询/清除 IPC 占用);SDK 侧 `meow_ui_nav`/`meow_ui_media` 封装同步落地,顶部下滑手势→IPC、launcher SIGSTOP→读帧→叠加→接管输入→SIGCONT(面板内 App 崩溃即关)。
|
||
- **launcher 叠加会话(复用电源菜单对 App 的冻结模板)**:收到 `MSG_NOTIF_OPEN`(且当前在 App 前台会话,
|
||
`launch_app` waitpid 循环内)→ **SIGSTOP App** → 读回 App 帧(`memcpy` fb0 buffer0 → back_buf,App 帧恒
|
||
buffer0 不走 `fb_backup_player`;同 `pm_capture_app_frame`)→ 写 `/tmp/meow_notif_active`(同
|
||
`/tmp/meow_power_menu_active`,让 watchdog 让位)→ 叠加渲染 `draw_notif_center` + `meow_ui_flush` →
|
||
**接管输入**(`open(DEV_TOUCH)`+`kp_open`,App 已冻不影响)→ 关闭(上滑/点空白/左缘左滑/点通知/物理键)→
|
||
恢复 App 帧 → `unlink(active)` → **SIGCONT App** → 重播输入基线。差异:背景=App 帧(非应用列表);
|
||
关闭后回 App(非回 run_menu)。
|
||
- **App 崩溃/卡死**:launcher 会话子循环周期用 `waitpid(pid,&st,WNOHANG)`/`kill(pid,0)` 探测;App 死→立即结束会话
|
||
(不 SIGCONT 死进程、不恢复死帧),走既有**统一应用退出路径**归位;launcher 不崩(`kill(pid,0)` 存活检测
|
||
与 watchdog 让位语义同 `util.c`(IPC 服务端 `ipc_thread`/`ipc_dispatch`)。
|
||
- **全屏/沉浸不冲突**:全屏/收合时 SDK 顶部热区缩小为 `MEOW_SBAR_HOTZONE_FS=4`(或提示线高),**仍保留顶部
|
||
一处下拉入口**(`meow_ui_statusbar_hotzone()`),spec-ref §3.1/A-13/§5.1 已定「全屏下顶部下滑仍开通知中心」。
|
||
- **与 M3 关系**:本方案是 M3「前台会话」的一个切面(App 前台会话+跨进程叠加)。**本方案先行**(握手+叠加会话+
|
||
故障隔离,不依赖 M3);通知点击 `target_activity` 的 activity 级跳转 / 点击通知**跨 app 启动** / nav_stack 回退
|
||
**留 M3**(首期:点通知 = dismiss + 关面板 + SIGCONT 回当前 App)。
|
||
|
||
---
|
||
|
||
## 附录 A(用户追加):后台运行 / 后台播放权限
|
||
|
||
**需求**:允许应用声明后台运行、后台播放等能力,避免播放类应用切到后台被直接终止。hiby 播放器作为系统应用单独适配。
|
||
|
||
**设计**:
|
||
- 应用经 `MSG_HELLO`/`MSG_REGISTER` 声明 **声明式权限**:`PERF_BACKGROUND`(可后台常驻)、`PERF_AUDIO_BACKGROUND`(后台音频/播放,要求系统**不因前台切换而杀掉**)。
|
||
- 权限粒度在 `MSG_HELLO.flags`/`MSG_REGISTER.flags` 扩展位:`MF_BACKGROUND`、`MF_PLAYBACK`。
|
||
- **后台播放的保活路径**:真正后台播放音源 = 注册**后台服务**(§5)+ 绑定一条 ONGOING 通知(用户可见"正在播放")+ 声明 `PERF_AUDIO_BACKGROUND`。守护进程据此**不因前台应用切换杀掉它**;退出前台会话时若该应用声明了后台能力,只结束其前台会话(SIGSTOP 播放器释放 fb/输入),**保留服务进程与音频**。
|
||
- **hiby 播放器单独适配**:作为 `app_id=hiby` 的内置系统应用(阶段 0),MeowOS 管理其启停。它天然是"后台播放"——MeowOS 主屏/通知中心使用时,hiby 播放器作为后台服务/音频源继续播放(符合其"音乐播放器"角色,不因用户切到 MeowOS 界面而停歌)。实现上:hiby 播放器注册为系统级后台音频,MeowOS 在任何前台会话下都不 SIGSTOP/终止它,仅在其自身退出时回收。
|
||
- **前台/后台切换规则**(框架统一):
|
||
- 前台应用(占用 fb/输入)切后台 → 结束其前台会话(恢复 fb/播放器),除非其声明 `MF_PLAYBACK` 且音频在播——此时仅释放视图,音频服务保留。
|
||
- 后台服务从不被 SIGSTOP;只有前台会话才 SIGSTOP。
|
||
- 缺省(未声明)应用:切后台即终止(现行为),最保守。
|
||
- **注意**:真正"切后台还在放"仍受硬件约束——音频只能走 hiby 播放器 socket 代播(44.1k/16bit)或应用直开 hw(需先确认 SIGSTOP 后播放器是否释放声卡,阶段 E 实测)。框架只保证生命周期(不被杀),不保证声卡空出;声卡占用问题是独立事项,记录为阶段 E 待测。
|
||
|
||
(完)
|
||
---
|
||
|
||
## 附录 B(用户追加):默认播放控制界面 / 正在播放(Media Session)
|
||
|
||
**需求**:MeowOS 启动器内置一个**默认播放控制界面**(Now Playing)。其他播放类应用(如网易云)在后台播放时,通过接口提供**实时播放数据**(元数据、歌词、封面等),供启动器的播放界面显示;启动器界面也能向应用下发**播放控制指令**(播放/暂停/上一首/下一首/进度)。
|
||
|
||
**设计**(在 §1 IPC 基础上新增"媒体会话"消息):
|
||
- **上报(应用→启动器)`MSG_META`**:实时元数据。负载:
|
||
```c
|
||
struct m_meta {
|
||
char title[128];
|
||
char artist[128];
|
||
char album[128];
|
||
uint32_t pos_ms; /* 当前播放位置 */
|
||
uint32_t dur_ms; /* 总时长 */
|
||
uint32_t state; /* 0=停止 1=播放 2=暂停 3=缓冲 */
|
||
uint32_t flags; /* MF_ART / MF_LYRIC / MF_COVER */
|
||
char artwork[192]; /* 封面: 本地路径或 MeowOS 存储槽位 */
|
||
char lyric[192]; /* 歌词: 路径或文本槽位 */
|
||
char app_id[32];
|
||
};
|
||
```
|
||
- 流式更新(播放位置/进度)用高频 `MSG_META`(或拆出轻量 `MSG_PROGRESS`,由应用按 ~1s 推送);元数据变化低频。
|
||
- **指令(启动器→应用)`MSG_PLAYCTL`**:
|
||
```c
|
||
struct m_playctl { uint32_t cmd; /* 1=播放 2=暂停 3=上一首 4=下一首 5=seek */ int64_t seek_ms; };
|
||
```
|
||
- 启动器播放界面上的按钮/滑条 → 通过该应用的**服务连接**下发。
|
||
- **注册**:播放应用声明 `MF_PLAYBACK` 并注册**媒体会话**(`MSG_REGISTER` 带 `svc=media_session` 或 `HELLO.flags` 含 PLAYBACK)→ 成为当前"正在播放"提供的源。
|
||
- **启动器表现**:
|
||
- 播放界面在**主屏/通知中心**有入口(默认一个 Now Playing 卡片):封面(缩略图,从 artwork 路径/槽位读)、标题/歌手/专辑、进度条、播放/暂停/上下首按钮。
|
||
- 歌词/封面若应用提供(MF_LYRIC/MF_COVER),启动器可显示(滚动歌词、封面大图)。
|
||
- 无音频源时显示"未在播放"占位。
|
||
- **hiby 播放器适配**:`app_id=hiby` 作为系统应用上报元数据(其自带曲目信息),启动器播放界面可显示官方播放器的歌名/进度,并下发放置控制。实现时从 hiby 播放器读元数据(其 SQLite 库 / 运行时状态)或后续再经其 socket 对接;阶段 0/D 落地后作为系统应用接入。
|
||
- **边界**:无应用上报 → 播放界面空态;多源 → 以最近活跃媒体会话为准(可扩展为"媒体源选择");应用退出/服务死亡 → 清 Now Playing 并回空态;进度/歌词缺省则相应区域留空。
|
||
- **与后台播放权限的关系**:MF_PLAYBACK 声明 + 媒体会话上报 → 框架视为后台播放源;启动器在主屏/通知中心时**不因用户离开该应用前台而停其音频**(附录 A),保证"切到 MeowOS 界面歌还在播、界面还能显示和控制"。
|
||
|
||
(完)
|
||
|
||
---
|
||
|
||
## 附录 C(用户追加):通知接口适配 freedesktop.org 桌面通知规范
|
||
|
||
**需求**:为最大化兼容既有通知生态,通知中心接口适配常见 X11 桌面应用使用的接口规范。
|
||
|
||
**决定**:通知后端提供**双接口**——
|
||
1. **轻量 IPC**(本框架 §1 的 AF_UNIX,MeowAPPs 用,带 Activity 路由等定制特性)。
|
||
2. **`org.freedesktop.Notifications`(freedesktop.org Desktop Notifications 规范)**——设备已跑 dbus-daemon 系统总线 + glib/gio/libdbus 可用,新增独立守护 `meow_notify_dbus` 把该 D-Bus 接口桥接到 MeowOS 通知中心后端。
|
||
|
||
**`org.freedesktop.Notifications` 方法/信号**(标准):
|
||
- `Notify(app_name, replaces_id, app_icon, summary, body, actions[], hints{}, expire_timeout)` → 存入通知后端(映射 summary/body/app_name/icon + 可选 target Activity via hints)
|
||
- `GetCapabilities()` / `GetServerInformation()` / `CloseNotification(id)` / `GetCapabilities`
|
||
- 信号:`NotificationClosed(id, reason)`、`ActionInvoked(id, action_key)`
|
||
|
||
**实现要点**:
|
||
- `meow_notify_dbus`(独立小守护,链 libdbus/GDBus)在系统总线注册 `org.freedesktop.Notifications`;收到 Notify → 经 MeowOS IPC 后端入通知存储;后端关闭/动作 → 回发信号。
|
||
- 任意遵循该规范或用 libnotify 的客户端(含未来移植的 X11/桌面应用)→ D-Bus 推送 → MeowOS 通知中心显示。
|
||
- MeowAPPs 可继续用轻量 IPC;第三方兼容走 D-Bus。
|
||
- 阶段 D 实现里把本兼容层并进(M4 附近),通知中心(阶段 B)消费统一存储。
|
||
|
||
|
||
---
|
||
|
||
## 附录 D(用户定案):与成熟标准统一(全部采纳)
|
||
|
||
> 最大化生态兼容;阶段 D(及媒体会话/设置/应用规范)实现时一并落地。
|
||
|
||
### D1. MPRIS(机制:`org.mpris.MediaPlayer2`)
|
||
- 对齐媒体会话(附录 B):MeowAPPs 播放器暴露 **`org.mpris.MediaPlayer2` / `.Player`** D-Bus 接口(设备已有 `mpris-proxy`);MeowOS Now Playing(默认播放控制界面)经 MPRIS 读取元数据/进度/封面 + 下发播放/暂停/上下首/seek。
|
||
- 方法/属性:`Play/Pause/Next/Previous/Stop/PlayPause`、`Seek/SetPosition`、`Metadata`(title/artist/album/artUrl/length)、`PlaybackStatus`、`Position`;信号 `Seeked`/`PropertiesChanged`。
|
||
- MeowOS 通知中心/媒体卡片显示 MPRIS 源;多个源时按最近活跃选择。
|
||
|
||
### D2. XDG Base Directory(数据目录兼容)
|
||
- 启动应用时,在注入 `MEOW_DATA_DIR`/`MEOW_CACHE_DIR` 基础上,**同时设置**:
|
||
- `XDG_DATA_HOME=<MeowData/<pkg>/data>`、`XDG_CACHE_HOME=<MeowData/<pkg>/cache>`、`XDG_CONFIG_HOME=<MeowData/<pkg>/config>`(config 目录首次启动若缺则建)。
|
||
- 遵循 XDG 的移植应用直接复用我们数据目录,零改码。
|
||
|
||
### D3. freedesktop Desktop Entry(应用元数据对齐)
|
||
- `app.json` 字段与 `.desktop` 对齐:`Name`/`Icon`/`Exec`/`Categories`/`Comment`/`StartupNotify`;可额外映射 `org.freedesktop` 相关。
|
||
- 图标可选遵循 freedesktop 图标主题(hicolor 等);MeowOS 应用列表读取这些元数据。
|
||
|
||
### D4. UPower / sysfs(电源标准,天然兼容)
|
||
- 已读 `/sys/class/power_supply`(电量/充电/电压),对齐 UPower 语义;MeowPanel/状态栏用同名概念。保留。
|
||
|
||
### D5. syslog 日志输出(可选)
|
||
- MeowOS 日志除 TF 卡/内存环外,**追加输出到 syslog**(设备 busybox syslog;`log.level` 控制),让 MeowOS 关键日志进标准系统日志流,便于与系统日志合并排查。
|
||
|
||
### D6. ALSA mixer 控制命名(音频兼容)
|
||
- 音量已对齐 CS43198 标准 control(`numid=1 Left Playback Volume`/`numid=2 Right Playback Volume`),MeowOS 音量键/面板用同名字节,与 ALSA 生态一致。保留。
|
||
|
||
## 实现归入
|
||
- D1/D2/D3 → 阶段 D 媒体会话/应用规范/应用启动(FRAMEWORK_DESIGN §1-§6 扩展)。
|
||
- D5 → 日志系统升级(SYSTEM_SETTINGS log.*)。
|
||
- D4/D6 → 状态/音频子系统(已有,确认保留)。
|