Files
MeowOS-SDK/test_sdk_input_keys.c
T
MeowOS c00872080a fix(media): 物理播放/暂停键(164)改发 PLAYCTL cmd=6 toggle + App 前台状态栏音量%实时刷新
Bug1: SDK meow_ui_media 按 g_last_state 本地判 play/pause,但 ncm 走自有 ipc_media
线程不经 SDK meta 上报 → g_last_state 恒 0 → 恒发 cmd=1(播放),播放中按键无效。
修:SDK 164 恒发 cmd=6 toggle(删 g_last_state 判定),ncm apply_playctl case 6
按 player_manager_state() 当前态翻转(源是状态权威);launcher meow_media/util
本就透传 cmd 不动结构,仅 meow_ipc.h/SPEC_REF 注释补 6=toggle。媒体卡片/NP 页
按钮(按 launcher 侧 s->state 判,来自 META 是准的)维持现状。

Bug2: App 前台时状态栏为 launcher 叠加层,App 内 SDK 改音量/亮度只写
settings.conf+DAC,launcher meow_settings 内存表不感知 → g_sys.vol 停旧值。
修:app_overlay_statusbar 前插 app_overlay_settings_poll——1s 节流 stat
settings.conf,mtime 变才 meow_settings_init 重读+sync 缓存+g_sys.vol/brightness
(meow_settings 新增 meow_settings_file_path() 访问器防硬编码分叉)。

验证:宿主 test_sdk_input_keys 19/19(K4 改 toggle 断言)、test_media +cmd=6
透传用例 ALL PASS、ncm bench/toggle_sim 10/10(新)、player_flow/cache_evict
sim PASS、ncm core 宿主+qemu-mipsel PASS、test_settings_brightness PASS;
mipsel 交叉 -Wall -Wextra 0 warning(改动文件单独验+整构建)。
真机(0.7.91):ncm 热更(.new+mv)后 autoplay(Docu) 起播缓存曲 → meow_ipc
playctl 6 二连发 → paused(pos=139691)/resumed 日志实证 toggle 全链路。
md5:ncm 8f10eee5 / meow_ui.a 7b359ec9(gitignore)/ launcher eba4f2b2
(/usr/bin 只读,fw_content.conf 已更新待固件)。物理键 164 实体按压留用户终验。
2026-09-01 14:44:55 +08:00

125 lines
5.7 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.
/*
* test_sdk_input_keys.c — M2.55 宿主验证:SDK 输入层接管系统按键语义(App 前台也生效)。
*
* 覆盖(直接调输入层语义函数,等效"模拟按键事件"):
* K1 音量 +/step:audio.volume 迈一步(volume_step 约束),settings.conf 落到值改变;
* K2 音量 ± clamp:volume_max 软上限、0 下限、硬上限 100;到限不再写;
* K3 保留其它键:改 audio.volume 不整文件 O_TRUNC(display.brightness/注释保留);
* K4 媒体键本地回调:注册 playctl 回调后,sys_key(上一曲/下一曲/播放暂停) → 回调 cmd 正确
* (播放/暂停恒发 toggle(6),SDK 不再本地判 state——走自有 IPC 线程的源不经 SDK meta
* 上报,本地 state 恒 0 会恒发「播放」致播放中按键无效;源侧按当前态翻转);
* K5 媒体键 IPC 兜底:未注册回调(g_cb==NULL)→ 走 IPC 发 launcher(无 socket → 静默不崩)。
*
* 编译(宿主 gcc,仅链 vol/media 两个 TU;无需 meow_ui 其它子系统):
* gcc -Wall -Wextra -pthread -o test_sdk_input_keys test_sdk_input_keys.c \
* meow_ui_vol.c meow_ui_media.c -I. -I../meow_launcherd
*/
#include "meow_ui_vol.h"
#include "meow_ui_media.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
static int failures = 0;
static void check(const char *name, int cond)
{
printf("%s %s\n", cond ? "PASS" : "FAIL", name);
if (!cond) failures++;
}
static char g_path[64];
static void wfile(const char *content)
{
FILE *f = fopen(g_path, "w");
if (!f) { perror("fopen"); exit(2); }
fputs(content, f);
fclose(f);
}
static int vol_in_file(void)
{
return meow_ui_vol_read(g_path, "audio.volume", -1);
}
/* —— 媒体回调捕获 —— */
static int cb_calls = 0, cb_cmd = 0;
static int64_t cb_seek = 0;
static void playctl_cb(int cmd, int64_t seek_ms)
{ cb_calls++; cb_cmd = cmd; cb_seek = seek_ms; }
int main(void)
{
snprintf(g_path, sizeof g_path, "/tmp/meow_kb_%d.conf", (int)getpid());
char sock[64]; /* 指向不存在路径:让 IPC 兜底路径确定性静默失败 */
snprintf(sock, sizeof sock, "/tmp/meow_kb_%d.sock", (int)getpid());
setenv("MEOW_IPC_SOCK", sock, 1);
/* ---- K1 音量迈一步(volume_step=1 默认)---- */
wfile("audio.volume = 60\naudio.volume_max = 100\naudio.volume_step = 1\n");
check("K1 vol 60 +1 -> 61", meow_ui_vol_step(g_path, +1) == 61);
check("K1 settings.conf 落到 61", vol_in_file() == 61);
check("K1 vol 61 -1 -> 60", meow_ui_vol_step(g_path, -1) == 60);
check("K1 settings.conf 回到 60", vol_in_file() == 60);
/* ---- K2 步进 volume_step=4 + clamp ---- */
wfile("audio.volume = 60\naudio.volume_max = 100\naudio.volume_step = 4\n");
check("K2 step=4: 60 +1 -> 64", meow_ui_vol_step(g_path, +1) == 64);
wfile("audio.volume = 99\naudio.volume_max = 100\naudio.volume_step = 4\n");
check("K2 step=4: 99 +1 -> 100 (硬上限)", meow_ui_vol_step(g_path, +1) == 100);
/* volume_max 软上限 */
wfile("audio.volume = 60\naudio.volume_max = 55\naudio.volume_step = 1\n");
meow_ui_vol_step(g_path, +1);
check("K2 volume_max=55: vol -> 55 (clamp 上限)", vol_in_file() == 55);
/* 到上限不再写 */
wfile("audio.volume = 100\naudio.volume_max = 100\naudio.volume_step = 1\n");
check("K2 at hard max: +1 -> 100 (no write)", meow_ui_vol_step(g_path, +1) == 100);
wfile("audio.volume = 0\naudio.volume_max = 100\naudio.volume_step = 1\n");
check("K2 at min: -1 -> 0 (no write)", meow_ui_vol_step(g_path, -1) == 0);
check("K2 at min settings 保持 0", vol_in_file() == 0);
/* ---- K3 保留其它键(不整文件 O_TRUNC)---- */
wfile("# meow-settings 1\ndisplay.brightness = 100\naudio.volume = 60\n");
meow_ui_vol_step(g_path, +1);
check("K3 vol 60 -> 61", vol_in_file() == 61);
check("K3 保留其它键 display.brightness=100",
meow_ui_vol_read(g_path, "display.brightness", -1) == 100);
/* ---- K5 媒体键 IPC 兜底:未注册回调 → 走 IPC(无 socket 静默不崩)---- */
cb_calls = 0;
meow_ui_media_sys_key(165); /* 上一曲:g_cb==NULL 走 IPC 兜底,不崩 */
check("K5 未注册回调不崩", cb_calls == 0);
/* ---- K4 媒体键本地回调:注册后按 cmd 分发 ---- */
meow_ui_media_on_playctl(playctl_cb);
meow_ui_media_sys_key(165); /* 上一曲 */
check("K4 上一曲(165) -> cb(3)", cb_calls == 1 && cb_cmd == 3 && cb_seek == 0);
meow_ui_media_sys_key(163); /* 下一曲 */
check("K4 下一曲(163) -> cb(4)", cb_calls == 2 && cb_cmd == 4);
meow_ui_media_sys_key(19); /* 旧码上一曲 */
check("K4 旧码(19) -> cb(3)", cb_calls == 3 && cb_cmd == 3);
/* 播放/暂停物理键恒发 toggle(6):与最近上报 state 无关(源侧按当前态翻转) */
meow_ui_media_meta(1, 0, 0, "t", "a", "al", NULL, NULL); /* state=PLAYING */
meow_ui_media_sys_key(164);
check("K4 播放中按播放/暂停 -> cb(6) toggle", cb_calls == 4 && cb_cmd == 6);
meow_ui_media_meta(2, 0, 0, "t", "a", "al", NULL, NULL); /* state=PAUSED */
meow_ui_media_sys_key(164);
check("K4 暂停中按播放/暂停 -> cb(6) toggle", cb_calls == 5 && cb_cmd == 6);
meow_ui_media_meta(0, 0, 0, "t", "a", "al", NULL, NULL); /* state=STOPPED */
meow_ui_media_sys_key(164);
check("K4 停止中按播放/暂停 -> cb(6) toggle", cb_calls == 6 && cb_cmd == 6);
meow_ui_media_stop();
unlink(g_path);
unlink(sock);
printf("\n%s (%d failure%s)\n", failures ? "RESULT: FAIL" : "RESULT: PASS",
failures, failures == 1 ? "" : "s");
return failures ? 1 : 0;
}