- launcher: run_app_notif_overlay 入口 meow_media_app_playing() 判定(当前源+PLAYING+app_id 匹配) → 不 SIGSTOP/不 SIGCONT,App 续跑保 PCM;非播放中维持 SIGSTOP 模板;关闭时 unlink 标记挪到 恢复帧上屏后(防未冻结 App 抢 present 一帧回闪)。 - SDK gfx: present() 见 /tmp/meow_notif_active(env MEOW_NOTIF_ACTIVE_FILE 覆写)自抑上屏, 仅 App 进程(系统 UI/launcher 不抑制),200ms 节流 stat,脏区累积解除后一次上屏; meow_gfx_overlay_suppressed_count 供单测断言。 - SDK input: 叠加期排空丢弃本进程 evdev 副本 + EVIOCGKEY 位图静默对齐(防面板点击被 App 双重消费/解除后边沿误判),进入沿复位触摸状态机。 - 宿主:新 test_overlay_suppress T1-T4 + test_media §8(8 用例)全 PASS;test_notif_*/ test_sdk_*/test_vol_ramp_jack 等回归全过;zig-mipsel -Wall -Wextra 全 TU 0 warning。 - meow_launcherd fbb82036(/usr/bin 只读待固件,fw_content.conf 已更)/ meow_ui.a d6242fc2 / hello a073535a / files 2b799d07(已热更到卡);ncm 未重链(ncm_app 他 agent 在改)。
98 lines
4.5 KiB
C
98 lines
4.5 KiB
C
/* meow_media.h — MeowOS 媒体会话(阶段 D · 附录 B / D1)。
|
||
*
|
||
* 定位:媒体会话注册表(App 声明 MF_PLAYBACK + 上报 MSG_META → 成为媒体源;
|
||
* 最近活跃者=当前源)。通知中心媒体卡片 / Now Playing 页 / 物理媒体键 / 控制器统一消费;
|
||
* PLAYCTL 经会话的连接 fd 直接下发。语义对齐 FRAMEWORK_DESIGN 附录 B 的「启动器表现」与
|
||
* 附录 D1(MPRIS 最近活跃源选择)。
|
||
*
|
||
* 设计:
|
||
* - 会话=一个 App 一个槽(app_id 归并;单 App 恒 1 槽,防多发 META 占满)。
|
||
* - 当前源=last_active_ms 最大者(最近上报 META)。多源时此即「最近活跃」。
|
||
* - 判定源死亡:播放中(1)/缓冲(3) 超 MEOW_MEDIA_STALE_MS 无 META → 清槽回空态(App 死/
|
||
* 服务断);暂停(2)/停止(0) 不超时(暂停属合法驻留,停止由 state 判空态)。
|
||
* - 空态:无会话,或当前源 state==0(停止)。
|
||
*
|
||
* 自包含:不依赖 launcher static 符号;发送/日志经 meow_media_ops 注入(launcher 用
|
||
* ipc_send / logmsg;宿主单测用 socket write / NULL)。可独立单测(test_media.c)。
|
||
*/
|
||
#ifndef MEOW_MEDIA_H
|
||
#define MEOW_MEDIA_H
|
||
|
||
#include <stdint.h>
|
||
#include <stddef.h>
|
||
#include "meow_ipc.h"
|
||
|
||
/* 同时维护的媒体会话上限(防御;一个 App 一槽) */
|
||
#define MEOW_MEDIA_MAX 4
|
||
/* 播放中(1)/缓冲(3) 无 META 超此毫秒 → 判源死清槽(回空态);暂停/停止不超时 */
|
||
#define MEOW_MEDIA_STALE_MS 30000u
|
||
|
||
/* state 取值(与 m_meta_t.state 一致) */
|
||
#define MEOW_MEDIA_STOPPED 0u
|
||
#define MEOW_MEDIA_PLAYING 1u
|
||
#define MEOW_MEDIA_PAUSED 2u
|
||
#define MEOW_MEDIA_BUFFER 3u
|
||
|
||
/* 媒体会话(一个 App 一个槽)。fd=最近上报 META 的连接 fd(下发 PLAYCTL 用)。 */
|
||
typedef struct meow_media_session {
|
||
int used;
|
||
int fd;
|
||
char app_id[MEOW_APP_ID_MAX];
|
||
uint64_t last_active_ms; /* 最近 META 时刻(monotonic ms,进度推进用) */
|
||
uint64_t active_seq; /* 最近活跃净序(全局递增,供「最近活跃」严格排序) */
|
||
uint32_t state;
|
||
uint32_t pos_ms;
|
||
uint32_t dur_ms;
|
||
uint32_t flags;
|
||
char title[128];
|
||
char artist[128];
|
||
char album[128];
|
||
char artwork[192];
|
||
char lyric[192];
|
||
} meow_media_session_t;
|
||
|
||
/* 依赖注入:send=发一帧(launcher 用 ipc_send 包装;宿主单测用 socket 写);
|
||
* log=日志(launcher 用 logmsg;NULL=静默)。send 返回写入字节。 */
|
||
typedef struct meow_media_ops {
|
||
size_t (*send)(int fd, uint16_t type, uint32_t req_id,
|
||
const void *payload, uint32_t len);
|
||
void (*log)(const char *fmt, ...);
|
||
} meow_media_ops;
|
||
|
||
/* 注入 ops(send/log);NULL 清空。launcher 启动时(meow_ipc_init)调用一次。 */
|
||
void meow_media_init(const meow_media_ops *ops);
|
||
|
||
/* App 上报 META:按 m->app_id 归并到会话(无则建槽);记录 fd/last_active;
|
||
* 截断安全(不越界)。返回 0=成功,-1=会话满/参数非法。 */
|
||
int meow_media_meta(const m_meta_t *m, int fd);
|
||
|
||
/* 当前源 = 最近活跃会话(last_active_ms 最大)。无会话返回 NULL。 */
|
||
const meow_media_session_t *meow_media_current(void);
|
||
|
||
/* 是否有活动媒体源:当前源存在且 state != 0(停止)。通知中心卡片/播放页据此显示。 */
|
||
int meow_media_has_source(void);
|
||
|
||
/* §10.5 叠加会话保活判定:当前源(最近活跃会话)存在、state==PLAYING 且 app_id 匹配。
|
||
* launcher 据此决定通知中心叠加不 SIGSTOP 该 App(保 PCM 供流),SDK present 层自抑上屏。 */
|
||
int meow_media_app_playing(const char *app_id);
|
||
|
||
/* 向当前源下发 PLAYCTL(卡片按钮/播放页/媒体键/控制器)。返回 0=已发,-1=无源/发送失败。 */
|
||
int meow_media_playctl(uint32_t cmd, int64_t seek_ms);
|
||
|
||
/* 向指定 app 的会话下发 PLAYCTL;无匹配会话返回 -1。 */
|
||
int meow_media_playctl_to(const char *app_id, uint32_t cmd, int64_t seek_ms);
|
||
|
||
/* 清某 app 的会话(App 退出/源死亡/主动停止时调)。app_id 空/NULL=清全部。 */
|
||
void meow_media_clear(const char *app_id);
|
||
|
||
/* 主循环周期调(~1s):播放中(1)/缓冲(3) 超时无 META → 清槽。 */
|
||
void meow_media_tick(void);
|
||
|
||
/* 显示用虚拟位置:播放中按墙钟推进 pos_ms(clamp 到 dur);暂停/缓冲/停止原样。 */
|
||
uint32_t meow_media_display_pos(const meow_media_session_t *s);
|
||
|
||
/* 调试打印(经 ops->log,前缀+每会话一行)。 */
|
||
void meow_media_dump(const char *prefix);
|
||
|
||
#endif /* MEOW_MEDIA_H */
|