From 54a6e828b71dc96737d05d3344584b2a0bb23073 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 2 Sep 2026 02:20:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(launcher):=20app=20=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=90=8D=E7=BC=93=E5=86=B2=20name[17]=E2=86=92[49]=20+=20json?= =?UTF-8?q?=5Fstr=20=E6=88=AA=E6=96=AD=20UTF-8=20=E6=95=B4=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E4=BF=9D=E6=8A=A4=EF=BC=88=E5=90=8C=20amsd=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=8CM6.2=20=E5=A4=87=E6=96=99=20launcher?= =?UTF-8?q?=2003dfcf76=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- patch_v2/meow_launcherd/app_launcher.c | 13 +++++++++-- .../meow_launcherd/meow_launcher_internal.h | 4 ++-- patch_v2/meow_launcherd/util.c | 22 +++++++++++++++++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/patch_v2/meow_launcherd/app_launcher.c b/patch_v2/meow_launcherd/app_launcher.c index 53b1d07..3fd7db8 100644 --- a/patch_v2/meow_launcherd/app_launcher.c +++ b/patch_v2/meow_launcherd/app_launcher.c @@ -629,7 +629,7 @@ void ensure_wifi(void) void meow_parse_app_json(FILE *f, struct app *a) { char buf[256]; - char name[17] = "", exec[129] = "", icon[129] = ""; + char name[49] = "", exec[129] = "", icon[129] = ""; char package[MEOW_APP_ID_MAX] = ""; int fram = 0, immersive = 0; int fullscreen = 0; /* app.json fullscreen=(注入 MEOW_FULLSCREEN env,SDK 预先设全屏) */ @@ -1993,7 +1993,14 @@ static int launch_app_chain(struct app *a, const char *chain) } app_seq_hits++; app_seq_last = nw; - if (app_seq_hits >= 3) { + /* REPORT §30(真机四连症状④):VOL_DOWN x3 是「应用内强杀」快捷键,但和普通 + * 调音量(连按音量减几档)冲突——用户连按音量下键会误触发 SIGTERM→SIGKILL, + * 前台 App 闪退(ams 日志 `EXIT dev.player.ncm sig=9`)。框架 App(framework=1, + * 如 dev.player.ncm)有 SDK 级左缘横扫返回退出(D10 默认,app.c 根页 + * meow_ui_request_exit),无需此强杀快捷键 → 门控到裸 App(framework=0)才触发, + * 框架 App 连按音量键只调音量不再被杀。裸 App 仍保留 VOL_DOWN x3 强杀出口 + * (无框架返回手势),挂死 App 另可 `meow_ctl am kill `。 */ + if (app_seq_hits >= 3 && !a->framework) { logmsg("kill seq: VOL_DOWN x3 -> SIGTERM app"); vol_restore(app_vol0); kill(pid, SIGTERM); @@ -2002,6 +2009,8 @@ static int launch_app_chain(struct app *a, const char *chain) reap_wait(pid, &status); /* 有界,防 D-state 挂死 */ ams_status_valid = 1; break; + } else if (app_seq_hits >= 3) { + logmsg("VOL_DOWN x3 ignored: framework app (swipe-back exits, §30)"); } } app_prev_vold = vold; diff --git a/patch_v2/meow_launcherd/meow_launcher_internal.h b/patch_v2/meow_launcherd/meow_launcher_internal.h index 61db69c..37925d2 100644 --- a/patch_v2/meow_launcherd/meow_launcher_internal.h +++ b/patch_v2/meow_launcherd/meow_launcher_internal.h @@ -309,7 +309,7 @@ struct meow_dep { struct app { char id[MEOW_APP_ID_MAX]; /* M2.52:app_id=app.json 的 package(权威,缺省回退卡上目录名 de->d_name),供 MEOW_LOG_APP 注入 */ char package[MEOW_APP_ID_MAX]; /* 安卓化:app.json 的 package 字段(反域名权威标识;目录名=package),scan_apps 据此定 app_id */ - char name[17]; /* ASCII display name */ + char name[49]; /* display name(UTF-8,截断走 json_str 整序列保护) */ char exec[129]; /* absolute path */ int ok; /* exec exists and X_OK */ /* ---- 阶段 D · M1:app.json 路由/框架/服务/图标(scan_apps 解析)---- */ @@ -333,7 +333,7 @@ struct app { * 与 MSG_ACT_DECLARE/HELLO(运行时)并集填充;单一写者=主循环,无需锁。 */ struct meow_acct { char app_id[MEOW_APP_ID_MAX]; - char name[17]; + char name[49]; char exec[129]; int ok; char framework; diff --git a/patch_v2/meow_launcherd/util.c b/patch_v2/meow_launcherd/util.c index 5e75a9e..b226ba3 100644 --- a/patch_v2/meow_launcherd/util.c +++ b/patch_v2/meow_launcherd/util.c @@ -515,9 +515,26 @@ static int ident_ch(char c) } +/* 把字符串末尾不完整的 UTF-8 序列砍掉(截断到最后一个完整码点边界)。 + * 根因记录:显示名按字节截断若落在多字节序列中间,下游(面板 JSON/绘制) + * 会拿到非法 UTF-8(amsd「流媒体客户端」事故 2026-09-02)。 */ +static void utf8_trim_incomplete(char *s) +{ + size_t n = strlen(s), i = 0, last_good = 0; + while (i < n) { + unsigned char c = (unsigned char)s[i]; + int len = (c < 0x80) ? 1 : (c >= 0xF0) ? 4 : (c >= 0xE0) ? 3 : (c >= 0xC0) ? 2 : 1; + if (i + (size_t)len > n) break; + i += (size_t)len; + last_good = i; + } + s[last_good] = '\0'; +} + + /* 极简 JSON/扁平值提取:在一行里找 key,读取其值(跳过 ':'/'=' 与可选引号)。 * 支持 JSON `"name": "Hello"` 与扁平 `framework=true`。返回拷贝到 out 的字符数。 - * 返回 0=未命中/空。 */ + * 返回 0=未命中/空。截断做 UTF-8 整序列保护。 */ int json_str(const char *buf, const char *key, char *out, int olen) { out[0] = 0; @@ -535,7 +552,8 @@ int json_str(const char *buf, const char *key, char *out, int olen) out[i++] = *p++; out[i] = 0; while (i > 0 && (out[i - 1] == ' ' || out[i - 1] == '\t')) out[--i] = 0; - return i; + utf8_trim_incomplete(out); + return (int)strlen(out); }