feat(bt): 批③后台管理页UI按钮化 — 每行右'杀'按钮(bgm_btn_rect精确命中,行区不误杀)+顶栏'一键清除后台'按钮(sub_page_t增row_draw/row_tap/top_action/top_action_cb全NULL守卫,wifi/bt/lock行为不变);test_bgpage 32项ALL PASS,0warning
This commit is contained in:
1 parent
c69fb92284
commit
5c174224f7
4 files changed
+324
-43
No files matched your search
@@ -1,25 +1,28 @@
|
||||
/* bg_page.c — 批③ 后台管理页(桌面顶栏居右按钮进入)。
|
||||
*
|
||||
* 容器:sub_page_t 脚手架(subpage.c,与 wifi_page/bt_page 同款)。顶栏=meow_topappbar:
|
||||
* 返回箭头 + 标题「后台管理」(+ 右上无开关)。
|
||||
* 返回箭头 + 标题「后台管理」+ **顶栏标题栏右侧「一键清除后台」按钮**(sub_page_t.top_action,
|
||||
* act=bgm_top_action → bgmgr_kill_all,**不杀框架/当前前台/非后台**,经 bgmgr_can_kill 门控)。
|
||||
* 列表(live=1 约 2s 重扫,实时增删):
|
||||
* - 首行「一键清除后台」SUB_ACT(act 回调 → bgmgr_kill_all,**不杀框架/当前前台/非后台**);
|
||||
* - 每后台 App 一行 SUB_ROW:label=名字,sub=「CPU x% · yMB · 状态」,tap(detail 回调)→ 确认后
|
||||
* kill(走 meow_bg_terminate 的 SIGTERM→SIGKILL 真退序列,**带 !framework 门控**)。
|
||||
* - 每后台 App 一行 SUB_ROW:label=名字,sub=「CPU x% · yMB · 状态」,**行最右一个「杀」按钮**
|
||||
* (sub_page_t.row_draw 行自绘 + row_tap 自定义命中:命中按钮区=kill 该 App;行体不响应)。
|
||||
* - 空态「无后台 App」。
|
||||
* 数据源=amsd FG/BG 注册表(后台常驻集=launcher meow_bg 表,EV BG/FG 上报进 amsd)+ 每进程
|
||||
* pcpu/rss(meow_svc_perf 同源 /proc 聚合,本页在 launcher 内同口径取)。
|
||||
*
|
||||
* 说明(与「每行最右 kill 按钮 + 顶栏右侧清除按钮」的像素级差异):sub_page_t 行无内嵌按钮、
|
||||
* 顶栏仅返回+开关;故 kill 用「点行→确认」,清除用「顶置动作行」。像素级自绘版见 design 备忘。
|
||||
* 按钮化(相对 agent-425 的「点行 kill + 顶置清除动作行」):
|
||||
* - kill:改「点整行」为「行最右独立杀按钮」——行自绘(bgm_row_draw)+ 自定义命中(bgm_row_tap),
|
||||
* 命中几何=bgm_btn_rect(行右 46×34 圆角按钮);行体其它区域 point 回 0(不杀)。
|
||||
* - 清:删顶置「一键清除后台」SUB_ACT 动作行,改为顶栏标题栏右侧 action 按钮(top_action)。
|
||||
*/
|
||||
#include "meow_launcher_internal.h"
|
||||
#include "meow_bgplay.h"
|
||||
#include "meow_bgmgr.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define BGMR_CLR_ACT 9999 /* 一键清除动作码 */
|
||||
#define BGMR_KILL_BASE 1000 /* kill app i:BGMR_KILL_BASE+i */
|
||||
/* 行内杀按钮尺寸(圆心/圆角定位用;命中与绘制共用同一几何,保证所见即所点) */
|
||||
#define BGM_BTN_W 46
|
||||
#define BGM_BTN_H 34
|
||||
|
||||
typedef struct {
|
||||
struct app *apps;
|
||||
@@ -135,7 +138,7 @@ static int bgm_proc_sample(void *ctx, pid_t pid, double *pcpu, long *rss_kb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---- rows(填 sub_row_t 列表)---- */
|
||||
/* ---- rows(填 sub_row_t 列表;每后台 App 一行,空态一行)---- */
|
||||
static int bgm_rows(void *ctx, sub_row_t *rbuf, int max)
|
||||
{
|
||||
bgm_ctx_t *b = ctx;
|
||||
@@ -148,13 +151,6 @@ static int bgm_rows(void *ctx, sub_row_t *rbuf, int max)
|
||||
b->n = bgmgr_collect(&ops, b->rows, MEOW_BGMR_ROW_MAX);
|
||||
|
||||
int r = 0;
|
||||
if (r < max) {
|
||||
rbuf[r].kind = SUB_ACT;
|
||||
rbuf[r].label = "一键清除后台";
|
||||
rbuf[r].sub = NULL;
|
||||
rbuf[r].act = BGMR_CLR_ACT;
|
||||
r++;
|
||||
}
|
||||
if (b->n == 0) {
|
||||
if (r < max) {
|
||||
rbuf[r].kind = SUB_ROW;
|
||||
@@ -172,7 +168,7 @@ static int bgm_rows(void *ctx, sub_row_t *rbuf, int max)
|
||||
rbuf[r].kind = SUB_ROW;
|
||||
rbuf[r].label = b->rows[i].name[0] ? b->rows[i].name : b->rows[i].app_id;
|
||||
rbuf[r].sub = sub;
|
||||
rbuf[r].act = i; /* detail 回调用 i 定位行 */
|
||||
rbuf[r].act = i; /* row_tap/row_draw 用 i 定位行 */
|
||||
r++;
|
||||
}
|
||||
return r;
|
||||
@@ -181,13 +177,59 @@ static int bgm_rows(void *ctx, sub_row_t *rbuf, int max)
|
||||
/* kill 通道(bgmgr_kill_all 的函数指针签名:void(*)(const char*)) */
|
||||
static void bgm_kill_fn(const char *app_id) { meow_bg_terminate(app_id); }
|
||||
|
||||
/* ---- detail(点 SUB_ROW 行=kill 该后台 App)---- */
|
||||
static int bgm_detail(void *ctx, int idx, int act)
|
||||
/* ---- 行内杀按钮矩形(绘制与命中共用;行视口矩形 rx,ry,rw,rh → 右侧 46×34 圆角钮)---- */
|
||||
static void bgm_btn_rect(int rx, int ry, int rw, int rh, int *bx, int *by, int *bw, int *bh)
|
||||
{
|
||||
*bw = BGM_BTN_W;
|
||||
*bh = BGM_BTN_H;
|
||||
*bx = rx + rw - 12 - BGM_BTN_W;
|
||||
*by = ry + (rh - BGM_BTN_H) / 2;
|
||||
}
|
||||
|
||||
/* ---- 行完全自绘(sub_page_t.row_draw;覆盖默认 renderer)----
|
||||
* 空态行(act=-1)居中画「无后台 App」;后台 App 行画 名字 + CPU/内存/状态 + 行右「杀」按钮。 */
|
||||
static void bgm_row_draw(void *ctx, int idx, sub_row_t *r,
|
||||
int x, int y, int w, int h, int state)
|
||||
{
|
||||
(void)idx;
|
||||
bgm_ctx_t *b = ctx;
|
||||
int i = act;
|
||||
if (i < 0 || i >= b->n) return 0;
|
||||
const meow_theme *mt = meow_theme_get();
|
||||
int i = r->act;
|
||||
if (i < 0 || i >= b->n) { /* 空态行 */
|
||||
int th = meow_ui_text_height(18);
|
||||
meow_ui_text_center(x + w / 2, y + (h - th) / 2,
|
||||
r->label ? r->label : meow_str_zh("bgmgr.empty", "无后台 App"),
|
||||
18, mt->onSurfaceVariant);
|
||||
return;
|
||||
}
|
||||
if (state & MEOW_LISTVIEW_ST_PRESSED)
|
||||
meow_ui_fill_rect_alpha(x, y, w, h, mt->primary, 26); /* 按压态(实时) */
|
||||
int th = meow_ui_text_height(20), tsub = meow_ui_text_height(16);
|
||||
int rx = x + 16; /* 左内边距 */
|
||||
int ry = y + (h - (th + tsub + 4)) / 2;
|
||||
if (r->label) meow_ui_text(rx, ry, r->label, 20, mt->onSurface);
|
||||
if (r->sub) meow_ui_text(rx, ry + th + 4, r->sub, 16, mt->onSurfaceVariant);
|
||||
/* 行内杀按钮(圆角框 + 「杀」;error=红=杀) */
|
||||
int bx, by, bw, bh; bgm_btn_rect(x, y, w, h, &bx, &by, &bw, &bh);
|
||||
meow_ui_draw_rect_round(bx, by, bw, bh, 10, mt->error);
|
||||
int bth = meow_ui_text_height(16);
|
||||
if (bth > bh) bth = bh;
|
||||
meow_ui_text_center(bx + bw / 2, by + (bh - bth) / 2, "杀", 16, mt->error);
|
||||
/* 底部分隔线 */
|
||||
if (y + h - 1 <= fb_yres)
|
||||
meow_ui_fill_rect(x, y + h - 1, w, 1, mt->outlineVariant);
|
||||
}
|
||||
|
||||
/* ---- 行内自定义命中(sub_page_t.row_tap;仅按钮区 kill,行体不响应/不误杀)---- */
|
||||
static int bgm_row_tap(void *ctx, int idx, sub_row_t *r, int x, int y,
|
||||
int rx, int ry, int rw, int rh)
|
||||
{
|
||||
(void)idx;
|
||||
bgm_ctx_t *b = ctx;
|
||||
int i = r->act;
|
||||
if (i < 0 || i >= b->n) return 0; /* 空态行无按钮 */
|
||||
int bx, by, bw, bh; bgm_btn_rect(rx, ry, rw, rh, &bx, &by, &bw, &bh);
|
||||
if (x < bx || x >= bx + bw || y < by || y >= by + bh) return 0; /* 行体/按钮外 → 不杀 */
|
||||
if (!bgmgr_can_kill(&b->rows[i])) {
|
||||
snprintf(b->toast, sizeof b->toast, "该 App 不可杀(框架/前台)");
|
||||
b->toast_ms = (long)now_ms();
|
||||
@@ -199,25 +241,28 @@ static int bgm_detail(void *ctx, int idx, int act)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ---- act(点 SUB_ACT:一键清除)---- */
|
||||
static int bgm_act(void *ctx, int idx, int act)
|
||||
/* ---- 行体点击(sub_page_t.detail):不响应(kill 只认行内按钮)---- */
|
||||
static int bgm_detail(void *ctx, int idx, int act)
|
||||
{
|
||||
(void)idx;
|
||||
bgm_ctx_t *b = ctx;
|
||||
if (act == BGMR_CLR_ACT) {
|
||||
bgmgr_ops_t ops;
|
||||
memset(&ops, 0, sizeof ops);
|
||||
ops.ctx = b;
|
||||
ops.enumerate = bgm_enumerate; /* 行已由 bgm_rows 建 */
|
||||
int k = bgmgr_kill_all(&ops, b->rows, b->n, bgm_kill_fn);
|
||||
if (k > 0) snprintf(b->toast, sizeof b->toast, "已清 %d 个后台 App", k);
|
||||
else snprintf(b->toast, sizeof b->toast, "无后台 App 可清");
|
||||
b->toast_ms = (long)now_ms();
|
||||
return 1;
|
||||
}
|
||||
(void)ctx; (void)idx; (void)act;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---- 顶栏右侧「一键清除后台」按钮(sub_page_t.top_action_cb)---- */
|
||||
static int bgm_top_action(void *ctx)
|
||||
{
|
||||
bgm_ctx_t *b = ctx;
|
||||
bgmgr_ops_t ops;
|
||||
memset(&ops, 0, sizeof ops);
|
||||
ops.ctx = b;
|
||||
ops.enumerate = bgm_enumerate; /* 行已由 bgm_rows 建 */
|
||||
int k = bgmgr_kill_all(&ops, b->rows, b->n, bgm_kill_fn);
|
||||
if (k > 0) snprintf(b->toast, sizeof b->toast, "已清 %d 个后台 App", k);
|
||||
else snprintf(b->toast, sizeof b->toast, "无后台 App 可清");
|
||||
b->toast_ms = (long)now_ms();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ---- 入口:运行后台管理页(阻塞到返回)---- */
|
||||
int run_bg_page(struct app *apps, int napps)
|
||||
{
|
||||
@@ -227,12 +272,15 @@ int run_bg_page(struct app *apps, int napps)
|
||||
b.napps = napps;
|
||||
sub_page_t p;
|
||||
memset(&p, 0, sizeof p);
|
||||
p.title = "后台管理";
|
||||
p.rows = bgm_rows;
|
||||
p.detail = bgm_detail;
|
||||
p.act = bgm_act;
|
||||
p.live = 1; /* 后台表/进程变化实时重扫 */
|
||||
p.ctx = &b;
|
||||
p.title = "后台管理";
|
||||
p.rows = bgm_rows;
|
||||
p.detail = bgm_detail;
|
||||
p.live = 1; /* 后台表/进程变化实时重扫 */
|
||||
p.ctx = &b;
|
||||
p.top_action = "一键清除后台"; /* 顶栏标题栏右侧按钮 */
|
||||
p.top_action_cb = bgm_top_action;
|
||||
p.row_draw = bgm_row_draw; /* 行自绘(名字/CPU/内存/状态 + 行右杀按钮) */
|
||||
p.row_tap = bgm_row_tap; /* 行内自定义命中(仅按钮区 kill) */
|
||||
meow_subpage_run(&p);
|
||||
|
||||
/* 清除 CPU 差分缓存(页面会话结束) */
|
||||
|
||||
Reference in new issue
Block a user