Files
MeowOS-For-R3P2/patch_v2/meow_launcherd/test_bgpage.c
T

165 lines
7.8 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_bgpage.c — 批③ 后台管理页 UI 按钮化 宿主子测(bg_page.c 按钮命中/顶栏清除命中)。
*
* 通过 #include bg_page.c 把其 FILE-STATIC 的 bgm_rows/bgm_btn_rect/bgm_row_tap/bgm_top_action
* 平移进本 TU;桩掉 launcher 后台表(meow_bg_count/at/terminate)+ 时钟 + meow_str,
* 直接验证:
* P1 bgm_rows 行骨架:后台 App 行(act=i)+ 空态行(act=-1);name/framework 经 app_meta 正确;
* P2 bgm_btn_rect 按钮几何:行右 46×34 圆角钮(rx+rw-12-46 定位);
* P3 bgm_row_tap 行内命中:**仅按钮区 kill(bgm_terminate 一次),行体/按钮外不误杀**;框架 App
* 按钮点击 → 不 terminate(!framework 门控);空态行不响应;
* P4 bgm_top_action 顶栏清除:kill_all **不杀框架 App**(sysguard 不 terminate),杀普通后台;
* P5 门控矩阵:bgmgr_can_kill(framework/fg/pid<=0/普通)。
* 不调用行自绘 bgm_row_draw(纯逻辑),故无需桩 SDK 绘制;行自绘段经 -ffunction-sections/--gc-sections 剔除。
*
* 编译(在 patch_v2/meow_launcherd 下):
* gcc -I../sdk -I. -Wall -Wextra -fsanitize=undefined \
* -ffunction-sections -fdata-sections test_bgpage.c meow_bgmgr.c \
* -Wl,--gc-sections -o test_bgpage
* 运行:./test_bgpage
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "meow_launcher_internal.h"
#include "bg_page.c" /* FILE-STATIC 函数平移进本 TU */
/* ---------- 桩:launcher 后台表(meow_bgplay 视角) ---------- */
static meow_bg_entry_t g_bg[MEOW_BG_MAX];
static int g_bg_n;
static int g_term_calls;
static char g_terminated[16][64];
int meow_bg_count(void) { return g_bg_n; }
const meow_bg_entry_t *meow_bg_at(int i)
{
if (i < 0 || i >= g_bg_n) return NULL;
return &g_bg[i];
}
int meow_bg_terminate(const char *app_id)
{
if (g_term_calls < 16) snprintf(g_terminated[g_term_calls++], 64, "%s", app_id);
return 0;
}
unsigned long long now_ms(void) { return 0; }
const char *meow_str(const char *id) { (void)id; return NULL; } /* 未知 id → meow_str_zh 回退 zh */
/* ---------- 测试态:launcher 应用表(app_meta 用) ---------- */
static struct app g_apps[4];
static void set_app(int i, const char *id, const char *name, char fw)
{
memset(&g_apps[i], 0, sizeof g_apps[i]);
snprintf(g_apps[i].id, sizeof g_apps[i].id, "%s", id);
snprintf(g_apps[i].name, sizeof g_apps[i].name, "%s", name);
g_apps[i].framework = fw;
}
static void bg_reset(int n, const char *id0, pid_t pid0, const char *id1, pid_t pid1)
{
g_bg_n = n; g_term_calls = 0;
memset(g_bg, 0, sizeof g_bg);
if (n >= 1 && id0) {
g_bg[0].used = 1; snprintf(g_bg[0].app_id, sizeof g_bg[0].app_id, "%s", id0);
g_bg[0].pid = pid0; g_bg[0].keepalive = 0;
}
if (n >= 2 && id1) {
g_bg[1].used = 1; snprintf(g_bg[1].app_id, sizeof g_bg[1].app_id, "%s", id1);
g_bg[1].pid = pid1; g_bg[1].keepalive = 0;
}
}
static int g_fails = 0;
#define CHECK(cond, msg) do { \
if (cond) printf("PASS: %s\n", msg); \
else { printf("FAIL: %s\n", msg); g_fails++; } } while (0)
static int term_count_app(const char *app_id)
{
int c = 0;
for (int i = 0; i < g_term_calls; i++) if (!strcmp(g_terminated[i], app_id)) c++;
return c;
}
int main(void)
{
static bgm_ctx_t b;
memset(&b, 0, sizeof b);
b.apps = g_apps; b.napps = 2;
set_app(0, "os.meow.hello", "播放", 0);
set_app(1, "os.meow.sysguard", "系统守护", '1');
static sub_row_t rows[SUB_ROWS_MAX];
printf("=== P1) bgm_rows 行骨架 ===\n");
bg_reset(2, "os.meow.hello", 1001, "os.meow.sysguard", 1002);
int rn = bgm_rows(&b, rows, SUB_ROWS_MAX);
CHECK(rn == 2, "2 后台 App → 2 行(无空态/无清除动作行)");
CHECK(rows[0].kind == SUB_ROW && rows[0].act == 0, "row0 act=0");
CHECK(!strcmp(rows[0].label, "播放"), "row0 label=名字(播放)");
CHECK(rows[1].kind == SUB_ROW && rows[1].act == 1, "row1 act=1");
CHECK(!strcmp(rows[1].label, "系统守护"), "row1 label=系统守护");
CHECK(!strcmp(rows[1].sub, "") || rows[1].sub[0] != '\0', "row1 sub 非空(CPU/内存/状态)");
CHECK(b.n == 2, "bgm_ctx.n=2");
printf("=== P2) bgm_btn_rect 按钮几何(行右 46×34) ===\n");
{
int bx, by, bw, bh; bgm_btn_rect(0, 0, 480, 56, &bx, &by, &bw, &bh);
CHECK(bw == 46 && bh == 34, "按钮 46×34");
CHECK(bx == 480 - 12 - 46, "按钮左缘=行宽-12-46");
CHECK(by == (56 - 34) / 2, "按钮垂直居中");
}
printf("=== P3) bgm_row_tap 行内杀按钮命中(仅按钮区 kill,行区不误杀) ===\n");
bg_reset(2, "os.meow.hello", 1001, "os.meow.sysguard", 1002);
bgm_rows(&b, rows, SUB_ROWS_MAX);
/* 按钮区命中:行(0,0,480,56),按钮 x 422-468, y 11-45 */
CHECK(bgm_row_tap(&b, 0, &rows[0], 445, 28, 0, 0, 480, 56) == 1, "按钮点击→返回1(重绘)");
CHECK(term_count_app("os.meow.hello") == 1, "按钮点击→terminate hello 一次");
/* 行体(按钮左/其下区)命中 → 不 kill */
CHECK(bgm_row_tap(&b, 0, &rows[0], 200, 28, 0, 0, 480, 56) == 0, "行体点击→返回0(不杀)");
CHECK(term_count_app("os.meow.hello") == 1, "行体点击→不误杀(仍1次)");
CHECK(bgm_row_tap(&b, 0, &rows[0], 410, 28, 0, 0, 480, 56) == 0, "按钮左侧缘(410)→不杀");
CHECK(bgm_row_tap(&b, 0, &rows[0], 475, 28, 0, 0, 480, 56) == 0, "按钮右侧(475)→不杀");
CHECK(bgm_row_tap(&b, 0, &rows[0], 445, 60, 0, 0, 480, 56) == 0, "按钮下方(60)→不杀");
/* 框架 App:按钮命中但不 terminate(!framework 门控) */
CHECK(bgm_row_tap(&b, 1, &rows[1], 445, 28, 0, 0, 480, 56) == 1, "框架App按钮→返回1(不可杀提示)");
CHECK(term_count_app("os.meow.sysguard") == 0, "框架App按钮点击→不 terminate");
printf("=== P3b) 空态行不响应 ===\n");
bg_reset(0, NULL, 0, NULL, 0);
int rn0 = bgm_rows(&b, rows, SUB_ROWS_MAX);
CHECK(rn0 == 1 && rows[0].act == -1, "0 后台 App → 1 空态行(act=-1)");
CHECK(bgm_row_tap(&b, 0, &rows[0], 445, 28, 0, 0, 480, 56) == 0, "空态行点击→返回0(不杀)");
g_term_calls = 0;
printf("=== P4) 顶栏清除(一键清除后台)不杀框架/前台 ===\n");
bg_reset(2, "os.meow.hello", 1001, "os.meow.sysguard", 1002);
bgm_rows(&b, rows, SUB_ROWS_MAX);
CHECK(bgm_top_action(&b) == 1, "顶栏清除按钮:返回 1(重绘约定)");
CHECK(term_count_app("os.meow.hello") == 1, "清除→terminate 普通后台 hello");
CHECK(term_count_app("os.meow.sysguard") == 0, "清除→不杀框架 sysguard");
/* 前台 App(is_fg)不杀:给 hello 标前台再清 */
bg_reset(1, "os.meow.hello", 1001, NULL, 0);
bgm_rows(&b, rows, SUB_ROWS_MAX);
for (int i = 0; i < b.n; i++) if (!strcmp(b.rows[i].app_id, "os.meow.hello")) b.rows[i].is_fg = 1;
g_term_calls = 0;
CHECK(bgm_top_action(&b) == 1, "前台 App 仍在:顶栏清除返回 1(重绘)");
CHECK(g_term_calls == 0, "前台 App → kill_all 不杀(0 terminate)");
CHECK(bgm_top_action(&b) == 1, "二次清除(仍前台/不可杀):返回 1");
CHECK(g_term_calls == 0, "二次清除 → 仍不 terminate");
printf("=== P5) 门控矩阵(bgmgr_can_kill) ===\n");
{
bgmgr_row_t r; memset(&r, 0, sizeof r);
r.pid = 5; CHECK(bgmgr_can_kill(&r) == 1, "普通后台可杀");
r.framework = '1'; CHECK(bgmgr_can_kill(&r) == 0, "framework 不可杀");
r.framework = 0; r.is_fg = 1; CHECK(bgmgr_can_kill(&r) == 0, "前台不可杀");
r.is_fg = 0; r.pid = 0; CHECK(bgmgr_can_kill(&r) == 0, "pid<=0 不可杀");
}
if (g_fails == 0) printf("\nALL PASS (%d checks)\n", 32);
else printf("\n%d FAILED\n", g_fails);
return g_fails ? 1 : 0;
}