Files
MeowOS-For-R3P2/patch_v2/meow_launcherd/meow_media.h
T

94 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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);
/* 向当前源下发 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 */