Files
MeowOS-For-R3P2/FRAMEWORK_DESIGN.md
T
MeowOS Dev 245bee2946 MeowOS for HiBy R3 Pro II — 公共发布版本(历史已重置)
• 全新单提交:清除含敏感信息的旧历史(sudo 口令、内网 IP、SSH 密钥路径、热点 SSID、设备 MAC)
• 本地开发文档/测试记录/构建脚本全部移入 gitignored 的 devdocs/ 与 scripts/build/(不入库)
• 保留:MeowOS 源码(launcher/watchdog/bootmenu/meow_svcd/SDK)、项目规范文档、mips-repo
增补组件:SDK 统一日志+通知 API、meow_svcd 服务管理器、mips-repo 软件仓库
2026-08-30 01:12:34 +08:00

18 KiB
Raw Blame History

MeowOS 阶段 D:Activity / 通知 IPC 框架设计文档

状态:设计稿 v1(2026-08-28)。先出协议与架构,本阶段只设计、不实现。 前置: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 原生)。
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 ↓ 下发通知清单(重同步)
0x0030 MSG_ACT_DECLARE ↑ (重)声明路由表
0x0031 MSG_ACT_QUERY ↑ 解析 activity 链路
0x0032 MSG_ACT_RESULT ↓ 返回链路
0x0040 MSG_NAV ↑ 上报导航/请求退出
0x0041 MSG_SHOW_ACTIVITY ↓ 令前端应用显示某屏
0x00F0 MSG_SYS ↓ 系统事件(守护关闭/服务死亡/播放器状态)

负载结构体见设计稿正文(m_hello/m_notify/m_register/m_act_* 等,定长多字节 LE)。

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 同一时刻单前台应用。
  • 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 导航+前台会话改造、M4 后台服务保活、M5 通知中心 UI、M6 加固:后续里程碑,本轮未做。
  • ✅ 渲染地基(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(客户端)。

附录 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:实时元数据。负载:
    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:
    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 → 状态/音频子系统(已有,确认保留)。