feat: M6.44+M6.45 收编 — 真机 0.8.45 现场保全(reader章节/key_router按键路由/WiFi连接修复/ncm bench+IME修复)

脏工作区现场收编:devdocs/local/m6_44_45_dirty_tracked.patch(46 个已跟踪文本文件,
+3090/-585, 已对 M6.43 基线干净适配) + m6_44_45_untracked_src.tar.gz 中 patch_v2/ 下
13 个新增源文件, 合成单个提交, 内容与容器工作树(R3ProII/patch_v2)逐字节一致。

- reader 章节: 新增 core/rdchapter.{h,c} — TXT 章节规范解析器, 扫描 512KB 码位对齐段文件
  逐段流式识别标题行(行首缩进≤4/显示宽≤40/行内标点≤1 三重约束防误判), 输出标题+全书字符
  偏移+段号/段内偏移+阿拉伯章号(中文数字归一), 首章前内容归"卷首"; book/reader/rdenc/
  rdlayout/settings 接入章节跳转与进度锚点, 附 chapter_smoke/turn_repro/build_turn_repro.sh
- key_router 按键路由: 新增 meow_launcherd/key_router.{h,c} — launcher-UI 页物理键统一路由
  (P1 仅音量键), 把读取边沿+防抖+长按 held+ramp 推进从 5 个会话收敛为进程内单开;
  各页每圈 key_router_pump() 取防抖后边沿, 动作(调音量/光标导航)仍由调用页决定,
  保留 run_menu 的 meow_mode 分支; App 前台 volume_page 武装时边沿抑制;
  main_menu/now_playing/notif_center/settings_page/subpage 接入, 附 test_key_router_vol/test_np_keys
- WiFi 连接修复: meow_netmgrd connect 有界等待 wpa_state=COMPLETED(普通 10s/隐藏网络 15s,
  env 可调)修设置页连接无响应; list_networks/scan_results 的 \xNN 转义还原始字节, 修中文 SSID
  永不命中致新建同名 open 记录顶影; launcher netmgr_ipc 配读超时; 附 test_wifi_connect(桩
  wpa_cli 驱动 static wifi_connect_ex), test_netmgrd.sh 补用例; wifi_page 同步
- ncm bench: 新增 bench/lyric_sim.c、bench/plpage_sim.c, vol_sync_sim 与 ncm core/app 同步
- SDK IME 修复: shift 大小写、K_ENTER 只提交不关、阻塞 IME 循环喂 on_tick 不被遮挡、
  IME 打开 ~200ms TAP 冷却窗吞 stray-TAP; 附 sdk/test_ime_fix.c
- 同期: meow_audiod 音量异步 ACK 线程(代际防 fd/槽复用竞态)、watchdog 音量收编(首选 audiod
  权威, settings.conf 覆盖路径)、panel 文件搜索(F1-④)与蓝牙只读详情(F1-③)、各类 build 脚本同步

范围红线: third_party/legado-E-main 原开发者未跟踪, 本次不入库(保留 devdocs/local tar 参考);
二进制不入库(后续重编); devdocs/ 不入库。59 文件全部在 patch_v2/ 下, 无 third_party/devdocs。
验证: git apply --check 干净; 59 文件 md5 与容器 patch_v2 逐一比对 59/59 一致(含
key_router.c/rdchapter.c/meow_ui_ime.c/test_wifi_connect.c 抽查); 可执行位保守
(check_lgpl_release.sh 100755, build_turn_repro.sh 100644 与容器一致)。
This commit is contained in:
AskaEth committed 2026-11-04 20:02:28 +08:00
1 parent e87ccdf061
commit 7c7d891570
59 files changed
+5305 -590

No files matched your search

+168
View File
@@ -0,0 +1,168 @@
/* test_wifi_connect.c — WiFi 设置页 bug1/bug2/bug4 宿主桩测试(2026-09-15)。
*
* 通过 #include meow_netmgrd.c 直接驱动 static 的 wifi_connect_ex(),绕过 daemon 的
* SO_PEERCRED 系统身份鉴权(宿主 CLI=CALL_OTHER 写级必拒,无法经 IPC 测连接路径)。
* 桩 wpa_cli 由本程序写入临时目录;控制文件(status_mode/list/save_fail_once)决定
* status 序列 / list_networks 原文 / save_config 是否首败,调用日志写入 <dir>/log 供断言。
*
* 编译:cc -Wall -Wextra -I../meow_launcherd test_wifi_connect.c -o test_wifi_connect
*/
#define _GNU_SOURCE
#define main meow_netmgrd_main
#include "meow_netmgrd.c"
#undef main
#include <sys/stat.h>
static char g_dir[128];
static int g_pass = 0, g_fail = 0;
static void ck(const char *name, int cond, const char *detail)
{
if (cond) { g_pass++; printf("PASS %s\n", name); }
else { g_fail++; printf("FAIL %s: %s\n", name, detail ? detail : ""); }
fflush(stdout);
}
static void putf(const char *name, const char *fmt, ...)
{
char path[192], body[512];
va_list ap;
va_start(ap, fmt);
vsnprintf(body, sizeof body, fmt, ap);
va_end(ap);
snprintf(path, sizeof path, "%s/%s", g_dir, name);
FILE *f = fopen(path, "w");
if (f) { fputs(body, f); fclose(f); }
}
static int log_has(const char *needle)
{
char path[192], buf[8192];
snprintf(path, sizeof path, "%s/log", g_dir);
FILE *f = fopen(path, "r");
if (!f) return 0;
size_t n = fread(buf, 1, sizeof buf - 1, f);
fclose(f);
buf[n] = 0;
return strstr(buf, needle) != NULL;
}
static void reset_log(void)
{
char path[192];
snprintf(path, sizeof path, "%s/log", g_dir);
FILE *f = fopen(path, "w");
if (f) fclose(f);
}
static void write_stub(void)
{
char path[192];
snprintf(path, sizeof path, "%s/wpa_cli", g_dir);
FILE *f = fopen(path, "w");
if (!f) { fprintf(stderr, "stub open fail\n"); exit(2); }
fputs(
"#!/bin/sh\n"
"D=\"${MN_WIFI_DIR:-/tmp}\"\n"
"echo \"$@\" >> \"$D/log\"\n"
"case \"$1\" in\n"
" status)\n"
" m=$(cat \"$D/status_mode\" 2>/dev/null || echo completed)\n"
" if [ \"$m\" = \"associating\" ]; then\n"
" echo \"wpa_state=ASSOCIATING\"; echo \"ssid=MyWiFi\"\n"
" else\n"
" echo \"wpa_state=COMPLETED\"; echo \"ssid=MyWiFi\"\n"
" echo \"ip_address=10.78.193.50\"; echo \"signal=-45\"\n"
" fi\n"
" ;;\n"
" list_networks)\n"
" if [ -f \"$D/list\" ]; then cat \"$D/list\"\n"
" else printf 'network id / ssid / bssid / flags\\n0\\tMyWiFi\\tany\\t[CURRENT]\\n'\n"
" fi\n"
" ;;\n"
" add_network) echo 1 ;;\n"
" set_network) echo OK ;;\n"
" enable_network) echo OK ;;\n"
" select_network) echo OK ;;\n"
" disconnect) echo OK ;;\n"
" save_config)\n"
" if [ -f \"$D/save_fail_once\" ]; then rm -f \"$D/save_fail_once\"; echo FAIL; else echo OK; fi\n"
" ;;\n"
" set) echo OK ;;\n"
" remove_network) echo OK ;;\n"
" *) echo OK ;;\n"
"esac\n"
"exit 0\n",
f);
fclose(f);
chmod(path, 0755);
}
int main(void)
{
snprintf(g_dir, sizeof g_dir, "/tmp/mnwifi.XXXXXX");
if (!mkdtemp(g_dir)) { fprintf(stderr, "mkdtemp fail\n"); return 2; }
write_stub();
setenv("MN_WIFI_DIR", g_dir, 1);
g_mode_meow = 1;
g_connect_wait_ms = 400;
g_connecth_wait_ms = 400;
{
char p[192];
snprintf(p, sizeof p, "%s/wpa_cli", g_dir);
g_wpa_cli = p;
}
ctl_result_t r;
/* ① 成功:命中既有 id=0 + 带新 psk → 更新凭据,等待 COMPLETED,成功报 ip。 */
putf("status_mode", "completed");
ctl_reset(&r, MEOW_OK);
reset_log();
wifi_connect_ex("MyWiFi,secret", &r, 0);
ck("connect-success code", r.code == MEOW_OK, r.text);
ck("connect-success text ip", strstr(r.text, "已连接") && strstr(r.text, "ip=10.78.193.50"), r.text);
ck("connect-success psk update", log_has("set_network 0 psk"), "");
ck("connect-success enable all", log_has("enable_network all"), "");
/* ② 错误密码/不在范围:status 恒 ASSOCIATING → 超时失败,新建 id 被回收。 */
putf("status_mode", "associating");
reset_log();
ctl_reset(&r, MEOW_OK);
wifi_connect_ex("OtherWiFi", &r, 0);
ck("connect-timeout code", r.code == MEOW_ERR_NODEV, r.text);
ck("connect-timeout text", strstr(r.text, "连接失败") != NULL, r.text);
ck("connect-timeout remove new", log_has("remove_network 1"), "");
/* ③ 中文 SSID \xNN 还原匹配:list_networks 原文转义,输入 UTF-8 名 → 命中 id=0 不新建。 */
putf("status_mode", "completed");
putf("list", "network id / ssid / bssid / flags\n0\t\\xe5\\xa4\\xa9\\xe5\\xa4\\xa9\tany\t[CURRENT]\n");
reset_log();
ctl_reset(&r, MEOW_OK);
wifi_connect_ex("天天", &r, 0);
ck("connect-escape match", r.code == MEOW_OK, r.text);
ck("connect-escape no add", !log_has("add_network"), "");
/* ④ connecth:隐藏网络命中既有 id → 追加 scan_ssid 1。 */
putf("status_mode", "completed");
putf("list", "network id / ssid / bssid / flags\n0\tMyWiFi\tany\t[CURRENT]\n");
reset_log();
ctl_reset(&r, MEOW_OK);
wifi_connect_ex("MyWiFi", &r, 1);
ck("connecth scan_ssid", r.code == MEOW_OK && log_has("set_network 0 scan_ssid 1"), r.text);
/* ⑤ save_config 首败 → set update_config 1 重试 → 持久化成功。 */
putf("status_mode", "completed");
putf("list", "network id / ssid / bssid / flags\n0\tMyWiFi\tany\t[CURRENT]\n");
putf("save_fail_once", "1");
reset_log();
ctl_reset(&r, MEOW_OK);
wifi_connect_ex("MyWiFi", &r, 0);
ck("save-config retry", r.code == MEOW_OK && !strstr(r.text, "记录未持久化"), r.text);
ck("save-config set update_config", log_has("set update_config 1"), "");
printf("==============================\nPASS=%d FAIL=%d\n", g_pass, g_fail);
return g_fail == 0 ? 0 : 1;
}