feat(launcher): 媒体会话+Now Playing (agent-204) — MSG_META(0x72)/MSG_PLAYCTL(0x73)+meow_media.c(最近活跃源=active_seq净序,30s超时回收); 通知中心顶部媒体卡片(封面缓存+进度seek+控制键); 主界面中部/右缘左滑进 Now Playing 大页(封面+元数据+进度+控制+歌词占位), 左缘返回; 空态完备
launcher a42171a1→ddfe616e; 宿主 test_media ALL PASS + qemu 端到端(META注册→PLAYCTL下发闭环) 出入: 卡片以媒体会话为权威非通知; PLAYCTL 走会话fd(断连防御留后续)
This commit is contained in:
1 parent
8012948b26
commit
32543ac616
15 files changed
+1429
-34
No files matched your search
@@ -862,6 +862,14 @@ static size_t ipc_send(int fd, uint16_t type, uint32_t req_id,
|
||||
}
|
||||
|
||||
|
||||
/* 公开的 ipc_send 包装(media 模块经 ops 注入用;签名与 meow_media_ops.send 一致)。 */
|
||||
size_t meow_ipc_send_pub(int fd, uint16_t type, uint32_t req_id,
|
||||
const void *payload, uint32_t len)
|
||||
{
|
||||
return ipc_send(fd, type, req_id, payload, len);
|
||||
}
|
||||
|
||||
|
||||
/* 组装完的帧入队(SPSC 无锁,先写槽再推进 tail,__sync 发布)。 */
|
||||
static void ipc_enqueue_frame(struct meow_ipc_conn *c)
|
||||
{
|
||||
@@ -1014,6 +1022,12 @@ static void *ipc_thread(void *arg)
|
||||
* (bind/listen 失败记 ipc_thread_ok=0,随后 meow_ipc_process 仍安全轮询空队列。) */
|
||||
int meow_ipc_init(void)
|
||||
{
|
||||
/* 注入媒体会话 ops:send=ipc_send 包装、log=logmsg(阶段D附录B)。 */
|
||||
static meow_media_ops g_media_ops;
|
||||
g_media_ops.send = meow_ipc_send_pub;
|
||||
g_media_ops.log = logmsg;
|
||||
meow_media_init(&g_media_ops);
|
||||
|
||||
ipc_event_fd = eventfd(0, EFD_NONBLOCK);
|
||||
if (ipc_event_fd < 0)
|
||||
logmsg("ipc: eventfd fail %s (10ms poll drains anyway)", strerror(errno));
|
||||
@@ -1246,6 +1260,39 @@ static void ipc_dispatch(struct meow_ipc_msg *m)
|
||||
* 需用时由守护主动经 meow_notif_serialize_list() + ipc_send 下发(M5 通知中心接入)。 */
|
||||
logmsg("ipc: NOTIFY_LIST (downlink) not dispatched here");
|
||||
break;
|
||||
/* 阶段D附录B:媒体会话(FRAMEWORK_DESIGN 附录 B)。META 声明 MF_PLAYBACK 的 App 上报
|
||||
* 元数据/进度/状态 → 归并到 meow_media 会话(最近活跃=当前源);回 ACK。 */
|
||||
case MSG_META: {
|
||||
m_meta_t mm;
|
||||
memset(&mm, 0, sizeof mm);
|
||||
memcpy(&mm, m->payload, m->plen < (uint16_t)sizeof mm ? m->plen : (uint16_t)sizeof mm);
|
||||
mm.app_id[MEOW_APP_ID_MAX - 1] = 0;
|
||||
mm.title[127] = 0; mm.artist[127] = 0; mm.album[127] = 0;
|
||||
mm.artwork[191] = 0; mm.lyric[191] = 0;
|
||||
int rc = meow_media_meta(&mm, m->fd);
|
||||
m_ack_t a;
|
||||
a.code = MEOW_OK; /* 会话策略:槽满降级最旧,不视为错误 */
|
||||
a.status = (uint32_t)rc;
|
||||
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
|
||||
logmsg("ipc: META app=%s state=%u pos=%u/%u rc=%d -> ACK",
|
||||
mm.app_id, mm.state, mm.pos_ms, mm.dur_ms, rc);
|
||||
break;
|
||||
}
|
||||
/* MSG_PLAYCTL(↑ 控制器→launcher 转发):把 cmd/seek 下发到「最近活跃媒体会话」fd。
|
||||
* 物理媒体键 / 宿主验证经此外发;通知中心卡片/播放页按钮走 meow_media_playctl 直发。 */
|
||||
case MSG_PLAYCTL: {
|
||||
m_playctl_t c;
|
||||
memset(&c, 0, sizeof c);
|
||||
memcpy(&c, m->payload, m->plen < (uint16_t)sizeof c ? m->plen : (uint16_t)sizeof c);
|
||||
int rc = meow_media_playctl(c.cmd, c.seek_ms);
|
||||
m_ack_t a;
|
||||
a.code = MEOW_OK;
|
||||
a.status = (uint32_t)rc; /* 0=已下发;-1=无源/发送失败(status=0xFFFFFFFF) */
|
||||
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
|
||||
logmsg("ipc: PLAYCTL cmd=%u seek=%lld rc=%d -> ACK", c.cmd,
|
||||
(long long)c.seek_ms, rc);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logmsg("ipc: unsupported frame type 0x%04x (req %u)", m->type, m->req_id);
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user