/* * 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 #include #include #include #include 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; }