公开 SDK 前把 SDK/App 硬编码文案外置:新增 meow_str/meow_strf/meow_str_set_locale/ meow_str_locale,按当前 locale 取串(永不 NULL),第三方开发者可做多语言。 - 新增 include/meow_ui_str.h + meow_ui_str.c:取串优先级 = TF 覆盖表 > 内嵌当前语言 (en_us→en 其余→zh) > 内嵌内置默认(zh_cn) > 原样返回 id。内嵌双语表(common.* 21 条 + ime.* 9 条);热路径零 malloc(编译期静态表 + ≤256 静态覆盖数组);纯 libc 宿主可单测。 - locale 存系统设置 settings.conf 的 ui.locale(默认 zh_cn,首次调用惰性读取); meow_str_set_locale 即时切换 + 重载覆盖表 + best-effort 持久化(流式改写保留其它行)。 - TF 覆盖表 MeowData/<pkg>/strings/<locale>.txt(id=text 行,UTF-8,'=' 两侧去空白); 无卡/无文件/无该 id → 回落内嵌。meow_strf 用调用方缓冲(snprintf 语义,重入安全)。 - SDK 控件接入:dialog 默认按钮 OK/CANCEL + INPUT 占位、IME 键面/徽标(空格/确定/拼英/ ?123/清/拼音/(无候选)/中)改走 meow_str;空态/加载态给 App 提供 common.no_data/loading。 - 测试:新增 test_meow_ui_str.c(内嵌回退/TF 覆盖优先级/未知 id 回退/切 locale 即时生效/ 查找正确性/meow_strf,tmp+env 两模式);全量宿主回归(widgets/dispatch/box/anim/scroll/ listvirt/theme/ime_fix/pinyin/overlay/notif/sdk_input_keys/p1p2p3/config/vol/sb_collapse/ notify_*) 0 回归;交叉 zig-mipsel -Wall -Wextra 0 warning。 - 文档:MEOW_APP_SDK.md 新增 §13(字符串资源/i18n,遗留顺延为 §14);docs/APP_DEV_GUIDE.md 新增 §7.11。各宿主 test_*.c 头注释补 meow_ui_str.c 编译依赖。 边界(§13.7):仅 zh_cn/en_us 整串取用;不做复数规则 / BiDi / RTL / 动态字体回退(雏形)。
98 lines
4.0 KiB
C
98 lines
4.0 KiB
C
/* test_overlay_suppress.c — §10.5 叠加让位 present 自抑宿主验证(离屏 480x720,16bpp)。
|
||
*
|
||
* 背景:媒体播放中的 App 前台唤起通知中心时 launcher 不 SIGSTOP(保 PCM 供流),改由 SDK
|
||
* present 层见 /tmp/meow_notif_active(宿主用 MEOW_NOTIF_ACTIVE_FILE 覆写)自抑上屏。
|
||
*
|
||
* 覆盖:
|
||
* T1 无标记:flush 正常上屏(frames_presented 递增,抑制计数 0);
|
||
* T2 有标记:flush 被抑制(只画进 back_buf 不 present:frames 不变、抑制计数递增);
|
||
* T2b 抑制期第二次 flush 仍被抑制(200ms 节流缓存内行为一致);
|
||
* T3 标记消失:下一次 flush 恢复上屏(抑制期累积脏区一次上屏,无需重画);
|
||
* T4 系统 UI 进程(launcher,system_mode=1)即使有标记也不抑制(面板必须照常上屏)。
|
||
*
|
||
* 编译(宿主 gcc,链真实 gfx/sys/theme/vol/log/widget/input/activity/dialog/ime + 打桩 font/global):
|
||
* gcc -Wall -Wextra -o test_overlay_suppress test_overlay_suppress.c test_host_stub.c \
|
||
* meow_ui_gfx.c meow_ui_sys.c meow_ui_theme.c meow_ui_vol.c meow_ui_log.c \
|
||
* meow_ui_widget.c meow_ui_input.c meow_ui_activity.c meow_ui_dialog.c meow_ui_ime.c meow_ui_str.c \
|
||
* meow_ui_draw.c meow_ui_view.c meow_notify_ipc.c \
|
||
* -I. -I../meow_launcherd -DMEOW_UI_HOST_TEST -pthread
|
||
*/
|
||
#include "meow_ui.h"
|
||
#include "meow_ui_internal.h"
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <assert.h>
|
||
#include <unistd.h>
|
||
#include <fcntl.h>
|
||
|
||
#define MARKER "/tmp/test_notif_active_sdk"
|
||
|
||
static void marker_write(void)
|
||
{
|
||
int fd = open(MARKER, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||
assert(fd >= 0);
|
||
if (write(fd, "1", 1) < 0) assert(0);
|
||
close(fd);
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
setenv("MEOW_UI_DUMP", "/tmp/overlay_suppress.ppm", 1);
|
||
setenv("MEOW_NOTIF_ACTIVE_FILE", MARKER, 1);
|
||
unlink(MARKER);
|
||
meow_ui_opts o = { 480, 720 };
|
||
assert(meow_ui_init(&o) == 0);
|
||
meow_ui_set_refresh_always_max(1); /* 绕过帧率门控:每次 flush 都直达 present 判定 */
|
||
|
||
/* T1:无标记正常上屏(默认 App 进程模式:render_enabled==0) */
|
||
assert(meow_ui_sys_render_enabled() == 0);
|
||
meow_ui_clear(0x112233);
|
||
meow_ui_flush();
|
||
assert(meow_ui_frames_presented() == 1);
|
||
assert(meow_gfx_overlay_suppressed_count() == 0);
|
||
printf("T1 PASS: no marker -> presented=1 suppressed=0\n");
|
||
|
||
/* T2:有标记 → 抑制(等 >200ms 越过存在性节流缓存) */
|
||
marker_write();
|
||
usleep(250000);
|
||
unsigned long long f0 = meow_ui_frames_presented();
|
||
meow_ui_clear(0x223344);
|
||
meow_ui_flush();
|
||
assert(meow_ui_frames_presented() == f0);
|
||
assert(meow_gfx_overlay_suppressed_count() == 1);
|
||
printf("T2 PASS: marker present -> suppressed (frames frozen at %llu)\n", f0);
|
||
|
||
/* T2b:抑制期再次 flush 仍抑制(节流缓存内一致) */
|
||
meow_ui_clear(0x334455);
|
||
meow_ui_flush();
|
||
assert(meow_ui_frames_presented() == f0);
|
||
assert(meow_gfx_overlay_suppressed_count() == 2);
|
||
printf("T2b PASS: still suppressed within throttle window\n");
|
||
|
||
/* T3:标记消失 → 恢复上屏(抑制期累积的整帧脏一次上屏,无需重画) */
|
||
unlink(MARKER);
|
||
usleep(250000);
|
||
meow_ui_flush();
|
||
assert(meow_ui_frames_presented() == f0 + 1);
|
||
assert(meow_gfx_overlay_suppressed_count() == 2);
|
||
printf("T3 PASS: marker gone -> present resumed (accumulated dirty flushed)\n");
|
||
|
||
/* T4:系统 UI 进程(launcher)不抑制——通知中心面板本身必须照常上屏 */
|
||
meow_ui_sys_set_system_mode(1);
|
||
assert(meow_ui_sys_render_enabled() == 1);
|
||
marker_write();
|
||
usleep(250000);
|
||
unsigned long long f1 = meow_ui_frames_presented();
|
||
meow_ui_clear(0x445566);
|
||
meow_ui_flush();
|
||
assert(meow_ui_frames_presented() == f1 + 1);
|
||
assert(meow_gfx_overlay_suppressed_count() == 2); /* 不再增长 */
|
||
unlink(MARKER);
|
||
printf("T4 PASS: system-UI process (launcher) never suppressed\n");
|
||
|
||
meow_ui_shutdown();
|
||
printf("ALL PASS\n");
|
||
return 0;
|
||
}
|