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:
1 parent
e87ccdf061
commit
7c7d891570
59 files changed
+5305
-590
No files matched your search
@@ -0,0 +1,142 @@
|
||||
/* key_router.c — launcher-UI 页物理键统一路由(KEY_ROUTER_UNIFY,P1:音量键)。
|
||||
*
|
||||
* 本模块持有一个进程内唯一的音量键防抖/基线:
|
||||
* kp_keys / kp_power(事件设备 poll 态,key_router_init 单开)
|
||||
* kd_vold / kd_volu(40ms 防抖态,KEY_DEBOUNCE_MS)
|
||||
* m_prev_vold / m_prev_volu(音量边沿基线)
|
||||
* 各 launcher-UI 页每圈调 key_router_pump() —— 它只产「音量边沿 + 原始 held + ramp 状态」,
|
||||
* 产出的边沿由「谁在跑循环」天然归属当前页;页据此决定 settings_volume_adj(±step) /
|
||||
* 光标导航 / ramp 推进。这样 run_menu 的 meow_mode 分支(HibyOS overlay 音量=导航)不被破坏,
|
||||
* 其余页(设置/通知中心/Now Playing/子页)用默认「音量=调音量」。
|
||||
*
|
||||
* 边界(§3 P1 / §4):
|
||||
* - App 前台 volume_page 武装时(meow_volpage_armed())音量边沿被抑制(防御闸;launcher-UI
|
||||
* 下 sink 恒空,此闸是「不改变行为」的保险)。
|
||||
* - 播放键/电源键 P1 不路由(各页现状不动;播放键严禁 cmd=6)。
|
||||
* - 锁屏(EVIOCGRAB)/App 会话层不调用本模块 —— 边界由「调用栈里当前循环是不是 launcher-UI 页」
|
||||
* 自动强加。
|
||||
*/
|
||||
#include "meow_launcher_internal.h"
|
||||
|
||||
static int g_inited = 0;
|
||||
|
||||
/* 进程唯一事件设备 poll 态(key_router_init 单开;各页另自开 kp_* 仅供播放/电源键用)。 */
|
||||
static struct keypoll kp_power, kp_keys;
|
||||
|
||||
/* 进程唯一音量键防抖态 + 边沿基线。 */
|
||||
static struct kd_state kd_vold, kd_volu;
|
||||
static int m_prev_vold = 0, m_prev_volu = 0;
|
||||
|
||||
/* 当前活动页哨兵(key_router_page_enter/exit 登记;与 sdk meow_ui_activity 交叉校验用)。 */
|
||||
static int g_page_sentinel = 0;
|
||||
|
||||
|
||||
void key_router_init(void)
|
||||
{
|
||||
if (g_inited) return;
|
||||
g_inited = 1;
|
||||
memset(&kp_power, 0, sizeof kp_power);
|
||||
memset(&kp_keys, 0, sizeof kp_keys);
|
||||
memset(&kd_vold, 0, sizeof kd_vold);
|
||||
memset(&kd_volu, 0, sizeof kd_volu);
|
||||
m_prev_vold = 0; m_prev_volu = 0;
|
||||
kp_open(&kp_power, DEV_POWER);
|
||||
kp_open(&kp_keys, DEV_KEYS);
|
||||
/* 基线对齐当前 raw:进入时已按住的音量键不产假边沿。 */
|
||||
key_router_rebase();
|
||||
}
|
||||
|
||||
|
||||
void key_router_rebase(void)
|
||||
{
|
||||
memset(&kd_vold, 0, sizeof kd_vold);
|
||||
memset(&kd_volu, 0, sizeof kd_volu);
|
||||
if (!g_inited) return;
|
||||
kp_poll(&kp_power, NULL, NULL);
|
||||
kp_poll(&kp_keys, NULL, NULL);
|
||||
m_prev_vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN);
|
||||
m_prev_volu = kp_is_down(&kp_keys, KEY_VOLUMEUP);
|
||||
}
|
||||
|
||||
|
||||
key_evt_t key_router_pump(void)
|
||||
{
|
||||
key_evt_t ev;
|
||||
memset(&ev, 0, sizeof ev);
|
||||
if (!g_inited) key_router_init();
|
||||
|
||||
/* 设备晚就绪兜底:init 时 open 失败则此处每圈重试(open 失败快速返回,无阻塞)。 */
|
||||
if (!kp_keys.ok) kp_open(&kp_keys, DEV_KEYS);
|
||||
if (!kp_power.ok) kp_open(&kp_power, DEV_POWER);
|
||||
kp_poll(&kp_power, NULL, NULL);
|
||||
kp_poll(&kp_keys, NULL, NULL);
|
||||
|
||||
int vold = 0, volu = 0;
|
||||
for (int w = 0; w < KEYBUF_WORDS; w++) {
|
||||
if (kp_keys.cur[w] & (1UL << (KEY_VOLUMEDOWN % 32))) vold = 1;
|
||||
if (kp_keys.cur[w] & (1UL << (KEY_VOLUMEUP % 32))) volu = 1;
|
||||
}
|
||||
/* 原始(未防抖)值:长按 ramp held 用(松开立即停止;同 run_menu/now_playing 现状)。 */
|
||||
ev.vol_held_dn = vold;
|
||||
ev.vol_held_up = volu;
|
||||
(void)kd_tick(&kd_vold, vold);
|
||||
(void)kd_tick(&kd_volu, volu);
|
||||
vold = kd_vold.stable; volu = kd_volu.stable;
|
||||
ev.vol_st_dn = vold; ev.vol_st_up = volu;
|
||||
|
||||
if (meow_volpage_armed()) {
|
||||
/* 防御闸:App 前台 volume_page 武装时(launcher-UI 下恒空)不放行音量边沿。
|
||||
* 音量键在那态下由 app_launcher 的 meow_volpage_key 消费(翻页),不落系统调音。 */
|
||||
ev.vol_dn_edge = 0;
|
||||
ev.vol_up_edge = 0;
|
||||
} else {
|
||||
ev.vol_dn_edge = (vold && !m_prev_vold);
|
||||
ev.vol_up_edge = (volu && !m_prev_volu);
|
||||
}
|
||||
ev.ramping = (vol_ramp_dir != 0);
|
||||
|
||||
m_prev_vold = vold;
|
||||
m_prev_volu = volu;
|
||||
return ev;
|
||||
}
|
||||
|
||||
|
||||
void key_router_default_volume(const key_evt_t *ev, unsigned long long *last_input)
|
||||
{
|
||||
if (ev->vol_dn_edge) {
|
||||
settings_volume_adj(-settings_volume_step);
|
||||
if (last_input) *last_input = now_ms();
|
||||
logmsg("key_router: volume DOWN <- step=%d", settings_volume_step);
|
||||
}
|
||||
if (ev->vol_up_edge) {
|
||||
settings_volume_adj(+settings_volume_step);
|
||||
if (last_input) *last_input = now_ms();
|
||||
logmsg("key_router: volume UP <- step=%d", settings_volume_step);
|
||||
}
|
||||
/* 在 settings_volume_adj 之后重查 vol_ramp_dir:同圈「起 ramp」即立刻迈第一步(同现状
|
||||
* 各页「settings_volume_adj 后 if(vol_ramp_dir) vol_ramp_tick」),且长按续爬随每圈推进。 */
|
||||
if (vol_ramp_dir != 0) {
|
||||
int held = (vol_ramp_dir > 0) ? ev->vol_held_up : ev->vol_held_dn;
|
||||
(void)vol_ramp_tick(held);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void key_router_page_enter(int sentinel)
|
||||
{
|
||||
g_page_sentinel = sentinel;
|
||||
/* 与 sdk 活动栈交叉校验:哨兵非 0 且栈顶不一致 → 记录(不中止,防宿主/真机栈深度差异)。 */
|
||||
if (sentinel) {
|
||||
int act = meow_ui_activity_active();
|
||||
if (act && act != sentinel)
|
||||
logmsg("key_router: page_enter sentinel=%#x but active=%#x", sentinel, act);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void key_router_page_exit(int sentinel)
|
||||
{
|
||||
if (g_page_sentinel == sentinel) g_page_sentinel = 0;
|
||||
/* 页退出即重播基线(§6 嵌套返回风险项:返回瞬间不产假边沿)。 */
|
||||
key_router_rebase();
|
||||
}
|
||||
Reference in new issue
Block a user