feat(sdk+launcher): SDK nav/media封装 + §10.5 App前台唤起通知中心 (agent-206) — meow_ui_nav.c(env栈初始化+report/request_exit) + meow_ui_media.c(懒连断线重连, meta上报+playctl接收) + MSG_NOTIF_OPEN=0x28/CLOSE=0x29(0x25/26已被占); SDK顶部下滑手势→IPC; launcher App前台会话叠加通知中心(SIGSTOP→读帧→接管输入→恢复SIGCONT, 面板内App崩溃即关); hello接线验证

meow_ui.a→9a8eb7ef; hello→fc299577; launcher→b33da20a; 宿主5套件+新test_notif_open+qemu分发 全过
出入: SDK符号用meow_ui_前缀防与launcher内同名冲突; 叠加会话真机待验; §10.5文档旧号段已过时
This commit is contained in:
MeowOS committed 2026-08-31 07:53:57 +08:00
1 parent 21519ce2e4
commit 9b4195724c
37 files changed
+1042 -21

No files matched your search

+61
View File
@@ -829,6 +829,28 @@ static pthread_t ipc_pthread;
static struct meow_ipc_conn ipc_conns[MEOW_IPC_CONNS];
/* §10.5:待处理的 App 前台「展开通知中心」请求(ipc_dispatch 单写者置位;launch_app waitpid
* 循环 meow_notif_open_take 读取并清除)。仅当 g_app_session_active(App 前台会话)期间才置位,
* 否则回 ERR(无 App 前台,不展开)。 */
static m_notif_open_t g_notif_open;
static volatile int g_notif_open_pending = 0;
int meow_notif_open_take(m_notif_open_t *out)
{
if (!out) return 0;
if (!g_notif_open_pending) return 0;
*out = g_notif_open;
g_notif_open_pending = 0;
return 1;
}
/* 会话边界:进入新 App 前台会话前清残留,防旧会话未消费的 OPEN 被新会话误展开。 */
void meow_notif_open_clear(void)
{
g_notif_open_pending = 0;
memset(&g_notif_open, 0, sizeof g_notif_open);
}
/* 写一帧(16B 头 + 负载)。返回写入字节;<=0 视为失败。 */
static size_t ipc_send(int fd, uint16_t type, uint32_t req_id,
@@ -1255,6 +1277,45 @@ static void ipc_dispatch(struct meow_ipc_msg *m)
logmsg("ipc: NOTIFY_DISMISS_ALL -> %d cleared", rc);
break;
}
/* §10.5:App 前台顶部下滑 → 请求展开通知中心叠加会话。仅在 App 前台会话(launch_app
* waitpid 循环)期间受理(置 pending 让该循环消费后展开叠加);否则回 ACK(status=BUSY)
* 让客户端知情但不展开(主循环/无 App 前台不展开)。App 不强依赖本 ACK(best-effort)。 */
case MSG_NOTIF_OPEN: {
m_notif_open_t o;
memset(&o, 0, sizeof o);
memcpy(&o, m->payload, m->plen < (uint16_t)sizeof o ? m->plen : (uint16_t)sizeof o);
o.app_id[MEOW_APP_ID_MAX - 1] = 0;
m_ack_t a;
a.code = MEOW_OK;
a.status = 0;
if (g_app_session_active && !g_notif_open_pending) {
g_notif_open = o; /* 单写者置位;waitpid 循环 take 后展开 */
g_notif_open_pending = 1;
a.status = 1; /* 已受理入队 */
logmsg("ipc: NOTIF_OPEN app=%s oy=%u hz=%u -> queued", o.app_id, o.origin_y, o.hotzone);
} else {
a.status = 0xFFFFFFFFu; /* 无 App 前台 / 已有会话在跑:不展开 */
logmsg("ipc: NOTIF_OPEN app=%s oy=%u hz=%u -> ignored (no app session or busy)",
o.app_id, o.origin_y, o.hotzone);
}
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
break;
}
/* §10.5:App 告知结束/退出 → launcher 收尾兜底(清 pending/标记;非可靠链路,launcher 主要
* 靠 waitpid/kill(pid,0) 自感知)。best-effort,回 ACK。 */
case MSG_NOTIF_CLOSE: {
m_notif_close_t o;
memset(&o, 0, sizeof o);
memcpy(&o, m->payload, m->plen < (uint16_t)sizeof o ? m->plen : (uint16_t)sizeof o);
o.app_id[MEOW_APP_ID_MAX - 1] = 0;
meow_notif_open_clear();
m_ack_t a;
a.code = MEOW_OK;
a.status = (uint32_t)o.reason;
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
logmsg("ipc: NOTIF_CLOSE app=%s reason=%u -> ACK", o.app_id, o.reason);
break;
}
case MSG_NOTIFY_LIST:
/* ↓ 守护→App 下发通知清单(重同步)。本帧不来自客户端(无请求类型),故不在此应答;
* 需用时由守护主动经 meow_notif_serialize_list() + ipc_send 下发(M5 通知中心接入)。 */