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