feat(launcher): 通知查询/清除 IPC + App崩溃直报crash (agent-199) — MSG_NOTIFY_QUERY(0x25)/QUERY_RESULT(0x27)/DISMISS_ALL(0x26,保留媒体/进度/常驻红线), DISMISS(0x22)复用既有; 序列化在主循环单写者做; launch_app waitpid 回收处 notify_app_crash(信号杀/非0退出上报 /tmp/meow_crash.sock best-effort, 干净exit不报)
launcher 61f6b0db→3c7c2ec7; qemu IPC 往返+宿主存储单测+mock crash socket 全过; 顺带清理既有告警(util.c/app_launcher.c/meow_ipc.c)
This commit is contained in:
1 parent
29e1b35da8
commit
2d93298f8a
7 files changed
+272
-8
No files matched your search
@@ -601,6 +601,121 @@ int meow_notif_update_progress(uint32_t id, int progress)
|
||||
return NOTIF_OK;
|
||||
}
|
||||
|
||||
/* ---- 一键清除(MSG_NOTIFY_DISMISS_ALL / 通知中心 UI 同语义)----
|
||||
* 红线(用户 2026-08-30,与 notif_center.c ncp_clear_all 的 mnp_clearable 同判据):
|
||||
* ongoing 常驻 / media 媒体 / 进行中进度(progress>=0)一律保留;其余 dismiss(= 归档留档 + 释放槽)。
|
||||
* 顺序遍历固定 slot 表,dismiss 只释放当前槽,不会跳条。 */
|
||||
int meow_notif_clear_active(void)
|
||||
{
|
||||
if (!g_inited) return -NOTIF_ERR_NOTINIT;
|
||||
int n = 0;
|
||||
for (int i = 0; i < MEOW_NOTIF_MAX_SLOTS; i++) {
|
||||
meow_notif_t *s = &g_slots[i];
|
||||
if (!s->active || s->dismissed) continue;
|
||||
if (s->ongoing || s->media || s->progress >= 0) continue; /* 保留红线项 */
|
||||
if (meow_notif_dismiss(s->id) == NOTIF_OK) n++;
|
||||
}
|
||||
notif_log("clear_active: dismissed %d (retained ongoing/media/progress)", n);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* ---- 活跃通知集 JSON 序列化(MeowPanel 实时化前置;字段同 TF 归档)---- */
|
||||
|
||||
/* JSON 字符串转义:`"`/`\` 反斜杠转义,<0x20 控制字符转 \\u00XX;写到 dst,返回字符数(不含 NUL)。 */
|
||||
static int json_escape(const char *s, char *dst, int cap)
|
||||
{
|
||||
int o = 0;
|
||||
if (!s) s = "";
|
||||
for (const char *p = s; *p; p++) {
|
||||
unsigned char c = (unsigned char)*p;
|
||||
if (c == '"' || c == '\\') {
|
||||
if (o + 2 >= cap) break;
|
||||
dst[o++] = '\\';
|
||||
dst[o++] = (char)c;
|
||||
} else if (c < 0x20) {
|
||||
const char *short_esc = NULL;
|
||||
switch (c) {
|
||||
case '\n': short_esc = "\\n"; break;
|
||||
case '\r': short_esc = "\\r"; break;
|
||||
case '\t': short_esc = "\\t"; break;
|
||||
case '\b': short_esc = "\\b"; break;
|
||||
case '\f': short_esc = "\\f"; break;
|
||||
default: break;
|
||||
}
|
||||
if (short_esc) {
|
||||
if (o + 2 >= cap) break;
|
||||
dst[o++] = short_esc[0];
|
||||
dst[o++] = short_esc[1];
|
||||
} else {
|
||||
if (o + 6 >= cap) break;
|
||||
int n = snprintf(dst + o, cap - o, "\\u%04x", (unsigned)c);
|
||||
if (n < 0) break;
|
||||
o += n;
|
||||
}
|
||||
} else {
|
||||
if (o + 1 >= cap) break;
|
||||
dst[o++] = (char)c;
|
||||
}
|
||||
}
|
||||
dst[o] = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 把一条活跃通知 append 成 JSON 对象到 buf+*o。返回 0=成功;-1=缓冲放不下(中止)。 */
|
||||
static int json_append_notif(meow_notif_t *s, char *buf, int buf_len, int *o)
|
||||
{
|
||||
char a_app [2 + 2 * MEOW_NOTIF_APP_ID_MAX + 2];
|
||||
char a_cat [2 + 2 * MEOW_NOTIF_CAT_MAX + 2];
|
||||
char a_sum [2 + 2 * MEOW_NOTIF_SUMMARY_MAX + 2];
|
||||
char a_body[2 + 2 * MEOW_NOTIF_BODY_MAX + 2];
|
||||
char a_tgt [2 + 2 * MEOW_NOTIF_ACTIVITY_MAX + 2];
|
||||
char a_icon[2 + 2 * MEOW_NOTIF_ICON_MAX + 2];
|
||||
json_escape(s->app_id, a_app, sizeof a_app);
|
||||
json_escape(s->category, a_cat, sizeof a_cat);
|
||||
json_escape(s->summary, a_sum, sizeof a_sum);
|
||||
json_escape(s->body, a_body, sizeof a_body);
|
||||
json_escape(s->target_activity, a_tgt, sizeof a_tgt);
|
||||
json_escape(s->app_icon, a_icon, sizeof a_icon);
|
||||
int n = snprintf(buf + *o, buf_len - *o,
|
||||
"{\"id\":%u,\"app_id\":\"%s\",\"category\":\"%s\",\"summary\":\"%s\","
|
||||
"\"body\":\"%s\",\"urgency\":%u,\"ts\":%llu,\"progress\":%d,\"ongoing\":%u,"
|
||||
"\"media\":%u,\"target_activity\":\"%s\",\"app_icon\":\"%s\"}",
|
||||
(unsigned)s->id, a_app, a_cat, a_sum, a_body,
|
||||
(unsigned)s->urgency, (unsigned long long)s->created_ms, (int)s->progress,
|
||||
s->ongoing ? 1u : 0u, s->media ? 1u : 0u, a_tgt, a_icon);
|
||||
if (n < 0) return -1;
|
||||
if (*o + n >= buf_len) return -1; /* 放不下:中止(调用方保前缀截断) */
|
||||
*o += n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int meow_notif_serialize_json(const char *app_id, char *buf, int buf_len)
|
||||
{
|
||||
if (!g_inited) return -NOTIF_ERR_NOTINIT;
|
||||
if (!buf || buf_len <= 0) return -NOTIF_ERR_INVAL;
|
||||
int o = 0;
|
||||
buf[0] = 0;
|
||||
if (o + 1 >= buf_len) return 0; /* 放不下 '[' */
|
||||
buf[o++] = '[';
|
||||
int first = 1;
|
||||
for (int i = 0; i < MEOW_NOTIF_MAX_SLOTS; i++) {
|
||||
meow_notif_t *s = &g_slots[i];
|
||||
if (!s->active || s->dismissed) continue;
|
||||
if (app_id && app_id[0] && strcmp(s->app_id, app_id)) continue;
|
||||
if (!first) {
|
||||
if (o + 1 >= buf_len) break;
|
||||
buf[o++] = ',';
|
||||
}
|
||||
if (json_append_notif(s, buf, buf_len, &o) != 0) break; /* 满:保留已完成前缀 */
|
||||
first = 0;
|
||||
}
|
||||
if (o + 1 < buf_len) buf[o++] = ']';
|
||||
buf[o] = 0;
|
||||
notif_log("serialize_json: app=%s active=%d -> %dB",
|
||||
app_id && app_id[0] ? app_id : "*", meow_notif_count(app_id), o);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* ---- count ---- */
|
||||
int meow_notif_count(const char *app_id)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user