/* test_sb_statusbar.c — 宿主交叉验证「同一个状态栏」闭环的纯逻辑(不依赖 /dev/fb0/字库): * 1. 数据源唯一:launcher 经 meow_ui_sys_feed 喂权威快照 → meow_ui_sys_get() 反映一致 * (batt/vol/wifi_connected/wifi_level/bt/brightness)。 * 2. 系统模式门:launcher 置 system_mode=1 才渲染(meow_ui_sys_statusbar_render 画图标+值); * App 进程默认 0 → render 为 no-op(不画顶条、无双画)。 * 3. 图标簇+值:fed 数据 → render 依次调用 meow_gfx_blit_icon(电量/音量/蓝牙/WiFi/亮度) * 与 meow_ui_text_right(%n 值);WiFi 已连-50dBm → WIFI_STRONG。 * * 编译(宿主 gcc): * gcc -o test_sb_statusbar test_sb_statusbar.c meow_ui_sys.c meow_ui_theme.c meow_ui_vol.c \ * -I. -I../meow_launcherd */ #include "meow_ui.h" #include "meow_ui_internal.h" #include "meow_ui_sys.h" #include #include #include #include /* ---- gfx/text/icon/log 打桩(宿主无 fb/字库) ---- */ static int g_calls_icon[16]; /* meow_gfx_blit_icon 的 idx 调用计数 */ static int g_calls_icon_total = 0; static char g_last_text_right[128]; /* 最近一次 meow_ui_text_right 的串 */ static int g_fill_top = 0; /* 清顶条(0,0,w,28)调用计数 */ static int g_render_calls = 0; /* statusbar_render 里真正执行了的次数(用 fill 计数近似) */ static int g_collapsed = 0; int meow_ui_width(void) { return 480; } int meow_ui_text_height(int size) { (void)size; return 20; } int meow_ui_text_width(const char *s, int size) { (void)size; return (int)strlen(s) * 7; } void meow_ui_fill_rect(int x, int y, int w, int h, uint32_t c) { (void)c; if (x == 0 && y == 0 && w == 480 && h == 28) g_fill_top++; } void meow_ui_text(int x, int y, const char *s, int size, uint32_t c) { (void)x;(void)y;(void)s;(void)size;(void)c; } void meow_ui_text_right(int rx, int y, const char *s, int size, uint32_t c) { (void)rx;(void)y;(void)size;(void)c; snprintf(g_last_text_right, sizeof g_last_text_right, "%s", s); } void meow_gfx_blit_icon(int idx, int x, int y, int ink_h, uint32_t fg, int cy) { (void)x;(void)y;(void)ink_h;(void)fg;(void)cy; if (idx >= 0 && idx < 16) g_calls_icon[idx]++; g_calls_icon_total++; } int meow_ui_statusbar_collapsed(void) { return g_collapsed; } void meow_log(meow_log_level lvl, const char *fmt, ...) { (void)lvl;(void)fmt; } /* ---- feed 权威快照(模拟 launcher sb_sdk_refresh / app_overlay_statusbar) ---- */ static void feed(const meow_ui_feed *f) { meow_ui_sys_feed(f); } int main(void) { /* init + 系统模式(launcher 进程) */ meow_ui_sys_init(); assert(meow_ui_sys_render_enabled() == 0); /* 默认 App 模式 */ /* 1) 数据源唯一:喂入 → sys_get 一致 */ meow_ui_feed f; memset(&f, 0, sizeof f); f.batt = 81; f.charging = 1; f.wifi_on = 1; f.wifi_connected = 1; f.wifi_level = -50; f.bt_seen = 1; f.bt_on = 1; f.vol = 60; f.brightness = 100; feed(&f); const meow_sys_state *s = meow_ui_sys_get(); assert(s->batt == 81 && s->charging == 1); assert(s->wifi_on == 1 && s->wifi_connected == 1 && s->wifi_level == -50); assert(s->bt_seen == 1 && s->bt_on == 1); assert(s->vol == 60 && s->brightness == 100); printf("PASS data-source unique: feed -> sys_get consistent (batt=%d vol=%d wifi_lvl=%d bri=%d)\n", s->batt, s->vol, s->wifi_level, s->brightness); /* 2a) App 进程(system_mode=0):render 应 no-op(无图标 blit、无顶条 fill), * 但 inset 仍为 28px(App 内容下移让位给 launcher 叠画的状态栏)——即「有 inset、 * 无状态栏实例」,根治双画。 */ memset(g_calls_icon, 0, sizeof g_calls_icon); g_calls_icon_total = 0; g_fill_top = 0; meow_ui_set_statusbar(1); assert(meow_ui_statusbar_height() == MUI_SBAR_H); /* App 仍 inset 28 */ assert(meow_ui_statusbar_visible() == 1); meow_ui_sys_statusbar_render(); assert(g_calls_icon_total == 0 && g_fill_top == 0); printf("PASS app-mode gate: render no-op (no icon/fill) + inset=28 -> no double draw\n"); /* 2b) 系统进程(system_mode=1):render 画图标+值 */ meow_ui_sys_set_system_mode(1); assert(meow_ui_sys_render_enabled() == 1); memset(g_calls_icon, 0, sizeof g_calls_icon); g_calls_icon_total = 0; g_fill_top = 0; g_last_text_right[0] = 0; meow_ui_sys_statusbar_render(); assert(g_fill_top >= 1); /* 清整条顶栏 */ assert(g_calls_icon[MEOW_SB_ICON_BATT] >= 1); /* 电量图标 */ assert(g_calls_icon[MEOW_SB_ICON_VOL] >= 1); /* 音量图标 */ assert(g_calls_icon[MEOW_SB_ICON_BT_CONN] >= 1);/* 蓝牙连接图标 */ assert(g_calls_icon[MEOW_SB_ICON_WIFI_STRONG] >= 1); /* WiFi 已连-50dBm → 强 */ assert(g_calls_icon[MEOW_SB_ICON_BRIGHT] >= 1);/* 亮度图标 */ assert(g_calls_icon[MEOW_SB_ICON_WIFI_STRONG] >= 1); /* 已连 → 强(正确分档) */ assert(g_calls_icon[MEOW_SB_ICON_WIFI_WEAK] == 0); printf("PASS icon cluster: batt/vol/bt/wifi(strong)/bright blitted, values=%s\n", g_last_text_right); /* 3) WiFi 弱信号(-80dBm)→ WEAK;关网卡 → 不画 WiFi */ memset(g_calls_icon, 0, sizeof g_calls_icon); f.wifi_connected = 1; f.wifi_level = -80; feed(&f); meow_ui_sys_statusbar_render(); assert(g_calls_icon[MEOW_SB_ICON_WIFI_WEAK] >= 1); memset(g_calls_icon, 0, sizeof g_calls_icon); f.wifi_on = 0; f.wifi_connected = 0; f.wifi_level = -1000; feed(&f); meow_ui_sys_statusbar_render(); assert(g_calls_icon[MEOW_SB_ICON_WIFI_STRONG] == 0 && g_calls_icon[MEOW_SB_ICON_WIFI_WEAK] == 0); printf("PASS wifi tiering: weak(-80)->WEAK, off->no wifi icon\n"); printf("ALL PASS\n"); return 0; }