/* meow_bgmgr.h — 批③ 后台管理页 逻辑层(数据汇聚 + kill 门控)。自包含、依赖注入、可独立单测。 * * 定位:把「后台常驻集 → 展示行(图标/名字/CPU/内存/状态)→ kill/一键清」的**纯逻辑**从 UI 抽出, * 便于宿主单测(test_bgmgr.c)与 launcher 页面(bg_page.c)复用。同 meow_bgplay 的 ops 注入手法: * UI 提供真实 enumerate/app_meta/proc_sample;单测用假件。**单一写者=launcher 主循环**,无锁。 * * 铁律遵循:kill/一键清 带 !framework 门控(防误杀框架/系统 App,对齐 app_launcher.c:2088 教训); * 不新建 daemon;不引 GDBus;不碰 /data/recovery_all。 */ #ifndef MEOW_BGMGR_H #define MEOW_BGMGR_H #include #include /* pid_t */ #include "meow_ipc.h" /* MEOW_APP_ID_MAX */ /* 定义于 meow_bgplay.h,此处仅注释:与 launcher 后台表同槽数(MEOW_BG_MAX=4)。 */ #define MEOW_BGMR_ROW_MAX 4 /* 后台管理页一行。enumerate 填 app_id/pid/keepalive/on_card/bg_since_ms; * bgmgr_collect 再经 app_meta/proc_sample 补元数据/CPU/RSS,并预判 killable。 */ typedef struct bgmgr_row { char app_id[MEOW_APP_ID_MAX]; char name[49]; /* display name(回退 app_id) */ char icon[129]; /* 图标 path(空=无,页面用首字/占位) */ char framework; /* '1'=framework=true(看门狗/系统 App,禁止 kill) */ pid_t pid; /* >0 后台进程 */ int keepalive; /* 1=声明常驻(background_keepalive,无限期不清) */ int is_fg; /* 1=当前前台 App(不 kill,标注「前台」) */ int on_card; /* 1=二进制在 TF 卡 */ uint64_t bg_since_ms; /* 转后台时刻(monotonic ms) */ double pcpu; /* 0-100 */ long rss_kb; /* 常驻内存 */ int killable; /* 预判:bgmgr_can_kill()==1 */ } bgmgr_row_t; /* 依赖注入(**必须全非空**;enumerate 返回行数,app_meta/proc_sample 返回 0=成功)。 */ typedef struct bgmgr_ops { /* 枚举后台常驻集:每调一次填 rows 的 app_id/pid/keepalive/on_card/bg_since_ms, * 返回行数(0..max;<0 视 0)。UI=读 launcher meow_bg 表;单测=假表。 */ int (*enumerate)(void *ctx, bgmgr_row_t *rows, int max); /* 按 app_id 补 App 元数据:name/icon/framework/is_fg。返回 0=找到;<0=未注册(name 回退 app_id)。 */ int (*app_meta)(void *ctx, const char *app_id, pid_t pid, char *name, int nl, char *icon, int il, char *framework, int *is_fg); /* 每进程 CPU/RSS 取样:返回 0=ok(写 pcpu 与 rss_kb);<0=无数据(pcpu=0/rss=0)。 */ int (*proc_sample)(void *ctx, pid_t pid, double *pcpu, long *rss_kb); void (*log)(const char *fmt, ...); /* 可空=静默 */ void *ctx; } bgmgr_ops_t; /* 枚举后台常驻并补全元数据/CPU/RSS。返回行数(>=0);app_id 空/重复加固在 enumerate 侧。 * 行序=enumerate 返回序(UI 端期望 bg_since_ms 升序=最久在前)。 */ int bgmgr_collect(const bgmgr_ops_t *ops, bgmgr_row_t *rows, int max); /* !framework 门控 + 非前台 + pid>0:返回 1=可 kill;0=禁止(框架/非后台/当前前台/无进程)。 */ int bgmgr_can_kill(const bgmgr_row_t *r); /* 一键清:遍历 rows,bgmgr_can_kill() 的条目逐一调 kill_fn(app_id)。返回发出 kill 数。 * **不杀框架 App/当前前台/非后台**;调用方负责对返回 0 弹「无后台 App 可清」之类提示。 */ int bgmgr_kill_all(const bgmgr_ops_t *ops, bgmgr_row_t *rows, int n, void (*kill_fn)(const char *app_id)); /* 状态文案(用于行内「状态」列):「常驻」keepalive=1;「后台」宽限期类;「前台」is_fg=1;空=非后台。 */ const char *bgmgr_status_str(const bgmgr_row_t *r); /* 内存文案(rss_kb → "x.xMB"/"xxKB")。返回静态缓冲区;勿复用变长调用。 */ const char *bgmgr_mem_str(long rss_kb); #endif /* MEOW_BGMGR_H */