fix(sdk+launcher): 图标不渲染真根因(agent-219) — meow_ui_img.c scale_buf cover 采样把乘写成除(÷缩放比→采到源图左上角透明区,全丢); 改乘+居中裁剪偏移修正; 宿主旧测试用纯色图掩盖了该bug。+ main_menu App退出/结构变化重绘时 fb_pan_buf0_force 无条件pan回buffer0(防App翻页留buffer1致菜单残帧)
meow_ui.a→3e0ee8f7 launcher→9d0efc2f hello→9609ea6e files→90f5cf07 ncm→be8be221(均已上卡); 真机截图证据 .tmp/meowbug/fix1.png+fix_b2_after.png
This commit is contained in:
1 parent
05a19a9ea3
commit
ab4da09e75
45 files changed
+1926
-147
No files matched your search
@@ -30,6 +30,11 @@ static pthread_t g_thr;
|
||||
static int g_thr_on = 0;
|
||||
static volatile int g_quit = 0;
|
||||
static meow_media_playctl_fn g_cb = NULL;
|
||||
/* 本进程最后一次经 meow_ui_media_meta 上报的 state(0=停 1=播放 2=暂停 3=缓冲)。
|
||||
* 供「物理播放/暂停键」做切换判据:播放中→暂停(2),否则→播放(1)。与 launcher
|
||||
* now_playing.c 的同款判定(state==PLAYING ? 2 : 1)对齐。 */
|
||||
static int g_last_state = 0;
|
||||
#define MEOW_UI_MEDIA_STATE_PLAYING 1
|
||||
|
||||
/* 后台线程主体(定义在文件后段;on_playctl 懒起时引用)。 */
|
||||
static void *media_thread_main(void *arg);
|
||||
@@ -177,6 +182,7 @@ void meow_ui_media_meta(uint32_t state, uint32_t pos_ms, uint32_t dur_ms,
|
||||
memset(&mm, 0, sizeof mm);
|
||||
pthread_mutex_lock(&g_mu);
|
||||
media_app_id();
|
||||
g_last_state = (int)state; /* 记录最近上报 state:供物理播放/暂停键切换判据(见 sys_key) */
|
||||
snprintf(mm.app_id, sizeof mm.app_id, "%s", g_app);
|
||||
mm.state = state;
|
||||
mm.pos_ms = pos_ms;
|
||||
@@ -207,6 +213,64 @@ void meow_ui_media_stop(void)
|
||||
pthread_mutex_unlock(&g_mu);
|
||||
}
|
||||
|
||||
/* ---- 物理媒体键 → 系统语义(M2.xx:SDK 输入层接管,App 前台也生效)----
|
||||
* 物理键是系统资源(APPS.md §3.4.1):播放/暂停/上一曲/下一曲 → 转发到当前媒体会话。
|
||||
* 本进程注册过 playctl 回调(= 本 App 是媒体源)→ 直接本地回调(最简,无 IPC 往返);
|
||||
* 否则经 IPC 发 MSG_PLAYCTL 给 launcher 转发到「最近活跃媒体会话」。best-effort 绝不崩。 */
|
||||
|
||||
/* 物理媒体键 keycode → MSG_PLAYCTL cmd(1=播放 2=暂停 3=上一首 4=下一首 5=seek)。
|
||||
* 播放/暂停(164)按最近上报 state 切换(播放中→暂停,否则→播放);上一曲 165/19→3,下一曲 163→4。
|
||||
* 非媒体键返回 -1。last_state 由调用方在持锁下传入(读 g_last_state 快照)。 */
|
||||
static int media_key_cmd(int code, int last_state)
|
||||
{
|
||||
switch (code) {
|
||||
case 164: /* KEY_PLAYPAUSE:切换(依最近上报 state) */
|
||||
return (last_state == MEOW_UI_MEDIA_STATE_PLAYING) ? 2 : 1;
|
||||
case 165: case 19: /* KEY_PREVIOUSSONG / 旧码 */
|
||||
return 3;
|
||||
case 163: /* KEY_NEXTSONG */
|
||||
return 4;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 控制器路径:发 MSG_PLAYCTL 给 launcher 转发到最近活跃媒体会话(launcher ipc_dispatch
|
||||
* MSG_PLAYCTL → meow_media_playctl → 下发到当前源 fd)。
|
||||
* 专门开一条临时连接(不复用媒体源持久连接 g_fd,避免与后台线程 poll/读竞争);
|
||||
* 无 launcher/断线 → 静默降级(绝不崩)。 */
|
||||
static void send_playctl_upstream(int cmd, int64_t seek_ms)
|
||||
{
|
||||
int fd = connect_path(sock_path());
|
||||
if (fd < 0) return;
|
||||
m_playctl_t c;
|
||||
memset(&c, 0, sizeof c);
|
||||
c.cmd = (uint32_t)cmd;
|
||||
c.seek_ms = seek_ms;
|
||||
if (send_frame(fd, MSG_PLAYCTL, 1, &c, sizeof c) != 0) { close(fd); return; }
|
||||
/* 读 ACK(best-effort):带 200ms poll,防 launcher 挂死导致输入线程阻塞。 */
|
||||
struct pollfd p;
|
||||
p.fd = fd; p.events = POLLIN; p.revents = 0;
|
||||
if (poll(&p, 1, 200) > 0 && (p.revents & POLLIN)) {
|
||||
uint8_t rbuf[128];
|
||||
uint16_t rt;
|
||||
(void)read_frame(fd, &rt, rbuf, sizeof rbuf);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* 物理媒体键按下边沿(val==1 时由输入线程调用;重复/抬起不重复触发)。 */
|
||||
void meow_ui_media_sys_key(int code)
|
||||
{
|
||||
pthread_mutex_lock(&g_mu);
|
||||
meow_media_playctl_fn cb = g_cb;
|
||||
int cmd = media_key_cmd(code, g_last_state);
|
||||
pthread_mutex_unlock(&g_mu);
|
||||
if (cmd <= 0) return;
|
||||
if (cb) { cb(cmd, 0); return; } /* 本 App 是媒体源(注册过回调)→ 本地回调 */
|
||||
send_playctl_upstream(cmd, 0); /* 否则经 IPC 发 launcher 转发到最近活跃会话 */
|
||||
}
|
||||
|
||||
/* 后台线程主体:懒连 + poll 读 launcher 下发 MSG_PLAYCTL → 调 cb。 */
|
||||
static void *media_thread_main(void *arg)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user