Commit Graph
361 Commits
Author SHA1 Message Date
AskaEth 4e60f440f6 Merge branch 'feat/sdk-clock-abi-fix' 2026-11-05 13:42:04 +08:00
AskaEth 38be5e78bc fix(sdk): 时钟 ABI 根因修复 — meow_ui_time 按 o32 time32 取时并链接期接管
真机 meow_ui_time_ms() 返回「低 32=秒×1000、高 32 随机」的根因不是 SDK 写法,
而是 zig 0.17 自带 musl 在 mipsel 上的 time64 ABI 自相矛盾:
- zig 头(mips-linux-musl/bits/alltypes.h)无条件 64 位 time_t、struct timespec 16 字节;
- zig 的 clang 给 32 位 mips 预定义 __ILP32__,musl 的 time64 回退分支
  `#if defined(SYS_x_time64) && !defined(__ILP32__)`(本意只排除 x32)被编译掉;
- 于是 libc 的 __clock_gettime64 实为 o32 time32 实现(SYS_clock_gettime 4263),
  只写 8 字节 {int32 sec; int32 nsec},与头的 16 字节布局错配。

修复(patch_v2/sdk/meow_ui_time.c):
- meow_ui_time_ms() 直接按内核 o32 ABI 取 8 字节 time32,再升 64 位毫秒;
- 同 TU 强定义 __clock_gettime/__clock_gettime64(归档先于 -lc,链接期接管,
  time()/gettimeofday()/pthread 定时等待的内部取时随之修正);
- 同源缺陷一并修:__nanosleep_time64/__clock_nanosleep(_time64) 转换 time32 后重发
  (修复前 usleep(16000) 等亚秒睡眠立即返回、变忙等空转);
- gfx/sys/input/cachegov 四处重复 now_ms 收敛到 meow_ui_time_ms;
- build_sdk.sh OBJS 增加 meow_ui_time;新增 test_meow_time 宿主单测、
  tools/clock_abi_probe.c 探针、CLOCK_ABI.md 根因/验证/影响面文档;
- 26 个宿主测试的编译注释补 meow_ui_time.c(cachegov 测试补时钟源)。

验证:宿主单测 PASS;anim(32)/view_event 宿主用例全过;build_sdk_host.sh --verify
76 成员全 MIPS32r2、0 warning;探针链接后无 libc cgt_init/__vdsosym,
__time64/__timedwait_cp 的取时指向本 TU,睡眠走 4166/4265 且用本地 8 字节结构。
2026-11-05 13:41:52 +08:00
AskaEth 8a115f6583 Merge branch 'feat/ncm-offline-retry-storm' 2026-11-05 13:16:54 +08:00
AskaEth 294ed6ffc7 test(ncm): M10 宿主回归三套(44 断言)+ 构建脚本 + REPORT §42
- bench/retry_storm_sim.c(25 断言):真实 retry_ctl.c/meta_gate.c,100ms tick 断网
  120s→4 次/间隔 ≥30s;状态每 tick 抖动→2 次;时钟回退→不立即重试且间隔仍 ≥30s;
  worker 45s>间隔→不并发;META 空闲 3 帧/60s(旧 600)、播放 13 帧(≤1/5s)、
  状态抖动 ≤4 帧/秒、元数据变化/seek 立即报、超长标题截断不重报、回退不连发。
- bench/home_retry_sim.c(13 断言):真实 app/ui/home.c 的 home_tick 编进宿主
  (--gc-sections + 桩),断网 120s→4 次重试、单飞、全帧重绘 0 次;
  把真机形态的垃圾 64 位 now 喂给 home_tick 仍为 4 次/≥30s;回在线再断网不清基准。
- bench/meta_ipc_sim.c(6 断言):真实 ipc_media 线程 + 假 launcher AF_UNIX socket,
  空闲 2s 只收到 1 帧 META(旧 ~10 帧),状态翻转恰好多 1 帧,帧头合法。
- build_ncm.sh / build_ncm_host.sh:源列表加 retry_ctl.c、meta_gate.c(host 补
  mem_watch.c,否则 player_manager 链接失败);build_ncm_sims.sh 加三个 sim。
- REPORT §42:真机日志证据(时间戳低/高 32 位拆解、21016 帧 META)、根因三链、
  实现、验证(session_gate 88 / http_truncate 13 / core 139 全过)、真机验证建议。
2026-11-05 13:00:32 +08:00
AskaEth 7f4e18b0ed fix(ncm): META 改「变化+低频心跳」,不再每 100ms 刷 launcher(M10)
根因:ipc_media 主循环 `if (now - last_meta >= 1000)` 同样依赖 meow_ui_time_ms()
的坏 64 位值(REPORT §42)→ 条件恒真 → 每个 IPC 轮次都发 MSG_META。
launcher 日志 meow_20261105_122541.log:单次启动 21016 条
`ipc: META app=dev.player.ncm state=0 pos=0/0 -> ACK`,间隔 ~100ms,且全是
无变化的静止帧;launcher 每帧写 2 行日志+归并会话,SD 写放大到整机卡死。

修复:
- 新增 app/play/meta_gate.{h,c}(纯逻辑):状态/时长/标题/歌手/专辑/封面/歌词
  标志变化 → 立即报;播放中位置偏移 ≥5s 重锚(launcher 自己按 last_active 外推);
  心跳播放中 5s / 非播放 30s;硬下限 250ms(任何路径 ≤4 帧/秒);时钟回退不下溢;
  字符串按发送侧截断长度比较(超长标题不得恒判「变了」)。
- ipc_media.send_meta 改为「组快照 → 闸判定 → 才发」,删除 1s 定时器;
  时间改 ncm_monotonic_ms();首帧仍必发(注册媒体源);发送走 DEBUG 日志。
2026-11-05 13:00:28 +08:00
AskaEth 35a636ef42 fix(ncm): 离线重试改单调钟节奏闸,断网不再每个 tick 重试(M10)
根因(真机日志 19000100_000000_7534.log):meow_ui_time_ms() 在设备上返回坏值——
低 32 位是「开机秒数×1000」(无毫秒),高 32 位每次调用随机(REPORT §42)。
旧守卫 `!g_home_thr_on && (!g_offline_retry_ms || now - g_offline_retry_ms >= 30000)`
因此恒真:worker 一收工,下一个 tick 立刻再重试;真机 74s 内 10 次
(间隔 5-7s 只是失败请求本身的连接超时)。第二条链是 else 分支清零重试时刻,
online/offline 一抖动就再试。

修复:
- 新增 app/logic/retry_ctl.{h,c}:节奏闸只做差值,时钟由调用方给可信单调钟
  (home.c 改传 core 的 ncm_monotonic_ms());回退不下溢(重定基准、不重试);
  busy 单飞;在线/离线抖动不重置基准;首次进离线立即探测一次,之后严格 ≥30s。
- home_tick 不再使用入参 now(真机坏值无效化);新增 home_retry_reset()。
- 静默重试不再走完整 home_reload:新增 home_reload_ex(silent) 不预读盘
  (旧实现每轮在 UI 线程同步读 playlists.bin)、home_apply_ex(keep_scroll)
  保留滚动位置、worker 记 g_home_changed 决定是否需要重绘——旧实现每轮
  home_apply() 复位滚动+整帧重绘,是「歌单列表滑动特别卡」的直接来源。
- worker 线程 pthread_detach(旧代码每轮泄漏线程栈)。
2026-11-05 13:00:24 +08:00
AskaEth aa225a1973 tower: snapshot of uncommitted base checkout changes (worktree wt-10) 2026-11-05 12:47:10 +08:00
AskaEth 61ef0f6de9 Merge branch 'feat/ncm-offline-session-keep' 2026-11-05 12:01:33 +08:00
AskaEth 31879f3302 fix(ncm): 缓存命中改单请求出参,移除全局命中计数(评审 P2-2/P2-1)
问题(P2-2):离线判定用 `ncm_apicache_hits()` 前后差值判「本次是否缓存命中」——
①其它 worker 的命中会污染差值 → 误判「已回在线」;②盘缓存分支的 g_hits++ 在 g_mu 锁外,
跨线程自增/64 位读存在竞争与撕裂可能。

修法(出参方案):
- `api_post_cached(..., int *from_cache)`:命中置 1(未走网络),miss/失败为 0;
  四个调用点显式传参。
- 新增 `ncm_api_user_playlist_ex(..., int *out_from_cache)`;out_n 与原接口一致**必填**
  (NULL→NCM_ERR_ARG,修入口容忍 NULL、成功路径却无条件解引用的契约不一致,评审 P2-1);
  out_from_cache 可 NULL。旧 `ncm_api_user_playlist` 为薄包装(调用方零改动)。
- `appstate_load_playlists_ex` 透传该标志;home_worker 用本次请求的 from_cache 判定是否
  回在线;歌单页只在失败时同步离线态(成功可能是缓存命中,不据此清离线)。
- 删除 `ncm_apicache_hits()`/g_hits(无使用者,同时消除数据竞争);盘缓存命中分支两行
  合并为一行(行为不变,重构)。
- 测试:session_gate_sim 新增 D2 五例(miss→0 且真网络 +1 次 / 命中→1 且 0 请求 /
  失败→0 / 兼容入口不崩 / out_n 必填契约);playlist_race_sim、plpage_sim 补 `_ex` 桩。

验证:session_gate_sim 88 PASS/0 FAIL;test_ncm_core_host 139 PASS/0 FAIL;
http_truncate_sim 13 PASS/0 FAIL;核心 13 TU(-Wall -Wextra)0 warning。
2026-11-05 11:59:33 +08:00
AskaEth b1d607d43f fix(ncm): http_ret_norm 保留 NCM_ERR_JSON(评审 P2-1:畸形分块不再误报断网)
问题:http_run 在 body_feed 失败时返回 NCM_ERR_JSON(畸形 chunk 尺寸/帧体),
但 http_ret_norm 的白名单漏了它,落到 default 被改判 NCM_ERR_NET → 上层按网络类
进离线模式,明明是数据/协议错误却误报「网络不可用」,也会误导离线恢复重试。

修法:白名单补 NCM_ERR_JSON(已属 NCM 错误码的一律原样返回),并把「不得改判」
写进函数注释。测试:http_truncate_sim 新增畸形分块用例(chunk 尺寸行 "ZZ"),
期望 NCM_ERR_JSON;修前该用例会得到 -4。

验证:http_truncate_sim 13 PASS(原 8 截断 + 4 传输归一 + 1 本用例)。
2026-11-05 11:54:23 +08:00
AskaEth 2ca386973b test(ncm): M9 分类/登录门宿主单测(83 断言)+ 传输层归一 4 例 + REPORT §41
- bench/session_gate_sim.c(新):真实 core + ncm_http_request 桩,覆盖
  A 错误分类矩阵(-4/-5/-6/-17/裸 mbedtls vs -13/其它)、B HTTP 状态矩阵
  (401/403 vs 5xx/429 vs 3xx/4xx)、C 登录门 + 启动决策(无网→离线、无会话→扫码)、
  D 真实 ncm_api 状态/业务码映射(含 -460→SVC、301/302→AUTH)、
  E 真实 ncm_login_status_check/refresh 映射、F 会话密钥稳定性(换 MAC 仍可解、
  旧 MAC 密文可解且自动迁移)。83 PASS / 0 FAIL,0 真实请求。
- bench/http_truncate_sim.c:追加 4 例传输层归一(握手 fatal alert→NET、握手超时→TIMEOUT、
  读 fatal alert→NET、CA 失败→TLS),原 8 例截断守卫零回归(12 PASS)。
- build_ncm_sims.sh:window/search/plpage/apicache/cookie_refresh 链入 ncm_session.o
  (appstate/api/login 新依赖),新增 session_gate_sim 构建与运行。
- test_ncm_core.c:采用 M8 分支的 $TMPDIR 适配(Termux /tmp 不可写;合并时以 M8 为准)。
- 相关 sim 头注释同步链接命令(ncm_apicache.o/ncm_session.o)。
- REPORT §41:判定点调用链与行号、根因证据、实现、验证矩阵与诚实出入
  (mipsel/真机未跑;app.c 宿主不可编译的既有原因;403/-460 取舍)。

验证:test_ncm_core_host 139 PASS/0 FAIL;session_gate_sim 83 PASS;
http_truncate_sim 12 PASS;window/search/apicache/cookie_refresh sim 通过;
核心 12 TU + 应用 13 TU(-Wall -Wextra)0 warning。
2026-11-05 11:45:44 +08:00
AskaEth e0bd503261 fix(ncm): 会话密钥改用设备私有 .mkey,网卡/MAC 变化不再丢登录态(M9 启动无网根因)
根因(代码级):会话 cookie 加密密钥 = sha256(首选网卡 MAC + 盐),MAC 取自
/sys/class/net 首个非 lo 网卡。设备断网时 Wi-Fi 网卡可能从 /sys/class/net 消失,
或 readdir 顺序变化选到另一块网卡 → 派生密钥改变 → session.enc 解不开 →
ncm_ctx_load_cookie 失败 → cookie 为空 → g_st.logged_in=0 → 启动直接进扫码页。
这与「把网络不可达当登录过期」是同一症状的另一条路径,且发生在登录门之前。

改动:
- 新密钥优先 <data_dir>/.mkey(32B 随机,首次生成后稳定,与网络状态无关);
  .mkey 不可写(只读 FS/无权限)才回退旧 MAC 派生,保持极端环境可启动。
- 旧版 MAC 派生密文仍可解(cookie_decrypt_sel 二次尝试);load_session 命中旧密钥时
  自动重写为 .mkey 密钥(透明迁移,不改调用方)。
- ncm_store.h 同步说明:machine_key 仅作旧密文兼容,新写入不再使用。
2026-11-05 11:45:20 +08:00
AskaEth 707bbd8a02 feat(ncm): 断网保持登录态 + 离线模式(可见提示/缓存可播/联网自动回在线)(M9)
用户报告:「一断网就退出到扫码登录界面,不会保持账号态切离线,缓存列表形同虚设」。
上一条已把失败分成 NETWORK/AUTH;本条把结论落到 App 状态与 UI。

- 会话状态机(appstate.c):只有 NCM_ERR_AUTH(401/403/301/302)清 cookie;网络类失败
  (不可达/超时/TLS/5xx/-460)只置 g_st.offline,账号态与 session.enc 一律保留;
  appstate_ensure_uid 同语义(原先任何 AUTH 都清 cookie,网络故障不得进入该分支)。
- 启动(app.c):根页改由 ncm_session_boot_decide 决定——有本地会话就进 home(无网也是),
  只有无本地会话才进扫码;打印 boot 决策日志。
- 离线 UX:首页个人卡「离线模式」红标 + 页脚提示 + 空态「离线模式/可播放已缓存」;
  歌单页/搜索页/播放页/缓存页分别给出离线文案(缓存页点播照旧走 NCM_QUEUE_CACHE,本地可播)。
- 恢复:home 可见时每 30s 静默重试一次(强制绕过接口缓存,成功即回在线并重绘);
  任何真实网络成功(home/playlist worker)也会清离线态。
- 防误判:接口缓存命中(120s 旧响应)不算「回在线」——home_worker 用
  ncm_apicache_hits() 差分识别,避免离线提示被缓存命中闪掉。
2026-11-05 11:45:20 +08:00
AskaEth 8557da6fca feat(ncm): 失败分类 + 登录门决策核心(M9:断网不再被当会话过期)
根因:传输层/服务端暂不可用与鉴权失败共用「负错误码」一个通道,登录门只能按
NCM_ERR_AUTH 判断,任何上游映射偏差都会变成「退出登录」:
- ncm_login.c 把任何业务码 !=200(含 -460 风控)都当 AUTH;ncm_api.c 把 -460 也映射 AUTH;
- api/login 层完全不看 HTTP 状态:401/403 与 5xx/网关 HTML 都落进 JSON/缺字段分支,
  反过来 5xx 与网络故障无法区分;
- http 层握手/写入失败把 mbedtls 裸负码(如 -0x7280)直接返回,上层按 NCM_ERR_* 比不中。

改动:
- core/ncm_session.{h,c}(新):ncm_err_classify / ncm_err_is_network /
  ncm_http_status_class|err / ncm_gate_decide / ncm_session_boot_decide。
  语义:NETWORK={NET,TLS,TIMEOUT,SVC,历史裸码};AUTH 仅 NCM_ERR_AUTH;
  401/403→AUTH,408/425/429/5xx→SVC,其它非 2xx→HTTP;启动时有本地会话就先信它
  (无网→离线进 home,绝不进扫码)。
- NCM_ERR_SVC=-17(服务端 5xx/429、业务码 -460:暂不可用、可重试,不是登录失效)。
- ncm_http.c:http_ret_norm 在 done: 统一归一(超时/证书/其它→NET),裸 mbedtls 码不再穿透。
- ncm_api.c:api_status_gate 先按 HTTP 状态定性再解析 body;业务码加 302→AUTH、-460→SVC。
- ncm_login.c:status_check/refresh 先过状态门;301/302→AUTH、-460→SVC、其它非 200→HTTP
  (不再因一次未知响应把用户踢回扫码)。
- ncm_apicache:新增命中计数,供 App 区分「真网络成功」与「离线读到旧缓存」。
- build_core.sh / build_ncm.sh:核心源列表加 ncm_session.c。
2026-11-05 11:45:20 +08:00
AskaEth 03868d048a Merge branch 'feat/ncm-crossbuild-hotupdate' 2026-11-05 11:36:56 +08:00
AskaEth 7d4906828d build(ncm): 宿主交叉适配层 + 全量测试补跑(M8)
- 新增 build_ncm_cross_host.sh:同构 HOME 复用容器脚本,串起 sdk/vendor/host-mbedtls/core/tests/ncm
- libs_common.sh 工具链路径改为 MEOW_R3PROII_ROOT/$HOME 可覆盖,容器默认不变
- build_mbedtls.sh 递归清理 library/ 与 3rdparty/ 旧对象,修宿主/mipsel 混架构归档
- test_ncm_core.c 改用 $TMPDIR,Termux /tmp 不可写不再导致 store/cache/tag 用例失败
- REPORT §40:构建/测试/热更结果(ncm md5 1bbd2a55…,Music du 前后恒定)
2026-11-05 11:34:45 +08:00
AskaEth 2c69070cc4 Merge branch 'feat/ncm-cache-filename-actual-level' 2026-11-04 21:11:04 +08:00
AskaEth e60642217a test(ncm): M6 缓存命名宿主单测(63 PASS)+ core 全量用例 + REPORT §39
- 新增 test/test_ncm_cache.c + build_ncm_cache_host.sh(纯 libc:真实 ncm_cache.c +
  ncm_tag.c,仅桩 strlcpy/mkdir_p/档位映射,不依赖 vendor/mbedtls)
- 覆盖:实际档映射、降级后写入名、hires 命中已存 exhigh/lossless、低档不命中高档、
  旧命名命中/扫描/删除/双点名迁移、列表去重、LRU/清空/删除兼容、level_from_path 边界
- test_ncm_core.c 新增 test_cache_actual_naming(接入 core 全量测试集,同语义断言)
- REPORT §39:命名/命中/兼容方案、质量取舍与未执行项(vendor/交叉/真机)
2026-11-04 21:11:00 +08:00
AskaEth 68833cf642 feat(ncm): 下载落盘名用响应实际档 + 命中按文件名标实际档(M6 播放链路)
- song_download_attempt:URL/类型确定后算实际档,.part/open/commit 统一用实际档键
  (hires 请求被降级为 320k mp3 → song_<id>_exhigh.mp3),eff_level=实际档
- song_local_file:命中路径由 ncm_cache_level_from_path 取文件名档位并按容器钳顶
  (mp3 永不高于极高),旧 hires.mp3 正确显示「极高」
- 移除旧「stale-degraded 改名+强制重下」与「无档位键迁移」:老卡文件读可用、不迁移
- player_flow_sim 适配:补实际档/路径档位桩与 M5 链接桩;P7/P12 期望键改实际档,
  P13 改为旧命名命中即播、不重下不迁移
2026-11-04 21:11:00 +08:00
AskaEth 30ffe469c8 feat(ncm): 缓存实际档判定/文件名解析 + 查找档位下探(M6 core)
- ncm_cache_actual_level:请求档 + 容器/码率/位深 + 响应生效档 → 实际档(只降不升),
  作为写盘名/播放显示/已缓存列表的唯一事实源
- ncm_cache_level_from_path:文件名档位段解析(song_<id>_<档位>,含 sky_c51)
- ncm_cache_lookup:请求档精确 miss 后按实际档逐档下探(hires 命中已存 exhigh/lossless),
  只降不升,低档请求不命中高档实体
- ncm_cache_scan:actual_level 改用统一判定;同曲同实际档的旧名+新名去重展示
2026-11-04 21:11:00 +08:00
AskaEth 132622cbc1 Merge branch 'feat/launcher-bg-kill-button-dead' 2026-11-04 21:00:45 +08:00
AskaEth 6b52740ff1 fix: 后台页杀按钮点不动 — app.json framework=1 被误当「不可杀」门控 + am kill 无前台会话不可执行
根因(2026-11-04 真机 dev.player.ncm pid=7520):
- bg_page.c bgm_app_meta 把 app.json 的 framework 字段映射进 bgmgr_row.framework,而
  bgmgr_can_kill 把它当「系统/框架 App 禁止 kill」。但 framework=1 在 MeowOS 里意为「用
  meow_ui.a 的 SDK 框架 App」(docs/APP_DEV_GUIDE.md §9,推荐值,真机 4 个 App 全写 1)
  → 后台页每行「杀」按钮被置灰,bgm_row_tap 命中后直接 return 1、不调 meow_bg_terminate;
  「一键清除后台」同理 0 行可杀。整条链路无日志,故只能靠翻 app.json 才定位(全部设备日志里
  "后台管理页终止后台App" 出现 0 次 = 4 次进页从未真正杀过)。
- 面板 killfg 正常是因为走 am kill → amsd → MSG_AMS_KILL,无 framework 门控;但它其实靠
  amsd 1200ms×2 超时兜底 kill(pid,SIGTERM) 才杀成:util.c 原本在无前台 App 会话时只回
  ACK -2((uint32_t)MEOW_ERR_NOENT),ACK 及时到达时 amsd 判「launcher refused」完全不杀
  (ams_20260915_031339.log 实证),ACK 迟到才侥幸成功(2026-11-04 真机)。

修复:
- meow_bgmgr: 门控位 framework → protected_app(系统级受保护标记;当前无 App 置位,launcher
  自身组件本就不在 App 表/后台表内)。bg_page 不再把 a->framework 送进门控。
- bg_page: 行副文本改存 ctx 持久缓冲(原 rbuf[].sub 指向 bgm_rows 栈帧 → 悬垂,副标题乱码);
  门控拒绝/未命中后台表各留一行 logmsg,「点了没反应」从此可查。
- util.c MSG_AMS_KILL: 先查后台保活表 → meow_bg_terminate 就地走真退序列(与页面「杀」按钮
  同一通道,故 am kill 与页面按钮行为对称),无前台会话也能杀;否则仍走 pending / ACK -2。
- amsd cmd_kill/cmd_start: ipc 失败原因细分(connect failed / timeout, no reply / ...),日志
  不再笼统写 "launcher offline"(响应串保留该字样,MeowPanel api_ams_ctl 依此映射 503)。
- meow_bgplay: meow_bg_terminate 注释/日志写明「后台管理页 / am kill」双入口同通道。

测试(宿主 gcc,产物在 $TMPDIR):
- test_bgpage 40 checks:新增 framework=1 仍判可杀且按钮真 terminate(本 bug 回归)、
  受保护行按钮不杀但留诊断日志、sub 持久化 + 栈抖动不变(悬垂回归)。
- test_bgmgr 30 checks:protected_app 门控矩阵 + framework=1 可杀回归。
- test_bgplay 92 PASS:新增 4b meow_bg_terminate 全链路(受理→term_at_ms→tick SIGTERM→
  on_bg_dead→清槽;空/不在表分别 INVAL/NOENT);TEST_SVC_PATH 改取 $TMPDIR
  (Termux 无 /tmp,原 fputs(NULL) 直接 abort)。
- amsd 宿主集成(fake launcher 桩,4 例):ACK 0→terminate 且不盲杀;ACK -2→refused 不盲杀;
  无 launcher→direct SIGTERM (connect failed);挂起不回→direct SIGTERM (timeout, no reply)。
0warning:util.c 与 main 同告警逐行一致(仅 SDK 头既有 typedef 重定义),其余文件干净。
2026-11-04 21:00:40 +08:00
AskaEth a73bcb9841 Merge branch 'feat/ncm-cached-list-and-tag-embed' 2026-11-04 20:49:36 +08:00
AskaEth a9c94c7221 fix(ncm): tag 嵌入按实际容器拒绝 MP4/M4A(ID3v2 前缀会破坏 MP4 容器)
download 扩展名在 type 非 flac 时一律落 mp3;若服务端降级返回 MP4/M4A("....ftyp"),
给文件加 ID3v2 头会破坏容器。ncm_tag_embed_file 现读 12 字节 magic:fLaC → VORBIS_COMMENT,
"ftyp" → NCM_ERR_ARG 拒绝(调用方 commit 裸流),其余按 MP3 处理。
test_ncm_tag 增 2 条断言(拒绝 + 原文件不变)→ 53 PASS / 0 FAIL,0 warning。
2026-11-04 20:49:25 +08:00
AskaEth 39465ea1ef feat(ncm): 新写入的缓存文件嵌入歌曲元数据(FLAC/MP3,commit 前流式重写,失败降级裸流)
用户需求:保留元数据分离的同时把歌曲元数据嵌进缓存文件(否则外部播放器读不到任何信息)。
- 接入点 player_manager:下载完整(dl_rc==OK)→ stream_src_finish(读端先自然收尾)→
  ncm_tag_embed_file(.tmp, 实际扩展名, {name/art_name/album_name}) → dispose join 之后才
  commit。tag 重写是同目录 .tag.tmp + rename 换 inode,解码端全程持旧 fd,播放/seek/
  .part 续传字节语义零改动。
- 容器按实际 magic 分支(ncm_tag.c);峰值内存 64KB;失败只记 WARN、commit 裸流,
  播放主链路不受影响(用户红线)。
- 元数据分离体系不动:<cache_dir>/meta/<id>.bin 旁路照旧写读;LRU 只 stat 文件,
  无 size/etag 索引需回填(重写后 stat 自然一致)。
- test_ncm_core 新增 test_cache_tag:writer 写裸流 → 嵌入 ID3v2.3 / VORBIS_COMMENT →
  读回 → ncm_cache_scan(hires 名 + 320k mp3 体 → 实际档 EXHIGH,名称来自文件内 tag)
  → ncm_cache_remove → ncm_cache_clear。
- REPORT §38:设计/内存估算/验证/诚实遗留(本机缺 vendor 与交叉工具链,未跑整链与真机)。
2026-11-04 20:49:25 +08:00
AskaEth f392ee5c48 feat(ncm): 首页顶栏「已缓存」入口 + 已缓存列表页(歌名/歌手/实际档位/大小,点播/单曲删除/清空)
入口:首页 topbar 新增动作 3(MEOW_ICON_DOWNLOAD 位图,原「回播放页」顺延动作 4)→
push ACT_CACHE;左缘返回弹回首页(app.c 路由补齐 tap/swipe/touch/tick)。

列表页 app/ui/cache.c(对齐 queue.c 惯例:圆角卡/红 mini-vinyl/按压红条/当前播放行高亮):
- 行 = 歌名 / 歌手 · 实际档位 · 大小;空态/页脚(N 首 · 合计 X MB)。
- 点行 = 点播(NCM_QUEUE_CACHE 队列,上/下一首在缓存列表内循环);行右「删除」=单曲删除;
  顶栏「清空」=确认框 + ncm_cache_clear(与设置页「清理缓存」同语义)。
- 数据全在 worker:cache_reload → appstate_cache_list_load → ncm_cache_scan(读目录 +
  文件内 tag + 音频头探测)→ 快照;UI 线程零磁盘 IO。快照上限 512 条(最近访问优先,
  ≈116KB bss),更多条目按 mtime 保留最近的。

core:
- ncm_cache_scan / ncm_cache_remove(songs/ 池,song_<id>_<请求档>.<实际格式> 解析,
  跳过 .tmp/.part 与非数字 id;按 mtime 降序;历史双点名删除兜底)。
- ncm_api_level_from_key(缓存键后缀 ↔ 档位枚举,与 ncm_api_level_key 互逆)。
- **档位显示实际档而非请求档**:真机存在 song_171650_hires.mp3(无损请求被降级链落到
  exhigh mp3),故 scan 用 ncm_audio_probe_file 读实际容器参数后只降不升地推断
  (FLAC 16bit→无损 / 24bit→Hi-Res+,MP3 ≤128k→标准 / >128k→极高)。

播放:player_manager 对 NCM_QUEUE_CACHE 用条目真实键(id+请求档+实际扩展名)直读缓存
文件,不按用户当前档键重下;song_local_file/play_is_same_song/queue 页均支持第三种队列。
宿主 mock(NCM_PAGE=cache)造 3 条缓存 + 嵌入 tag + 同步扫描。
2026-11-04 20:49:25 +08:00
AskaEth 184ebd0ac9 feat(ncm): 缓存文件内嵌元数据模块 ncm_tag(FLAC VORBIS_COMMENT / MP3 ID3v2.3 写读 + 音频头探测)
core/ncm_tag.c/.h(纯 libc,宿主可单测,不依赖 mbedtls/jsmn):
- FLAC:在元数据末块之后插入 VORBIS_COMMENT(TITLE/ARTIST/ALBUM),旧 VORBIS_COMMENT
  替换、PADDING/PICTURE 原样保留;MP3:ID3v2.3 TIT2/TPE1/TALB(UTF-16LE+BOM,中英文
  与 emoji 均可),源已带 ID3v2 时先剥旧标签(不留双标签)。
- **按实际容器分支**(读 fLaC 魔数):缓存名档位段是请求档,真机存在
  song_<id>_hires.mp3(无损请求被降级链落到 exhigh mp3),不能按名字判容器。
- 写入 = 同目录 <path>.tag.tmp + 64KB 分块搬运 + fsync + rename 原子替换;任一步失败
  即 unlink 临时件、原文件保持不变(调用方 commit 裸流降级),峰值内存 64KB。
- ncm_audio_probe_file:只读文件头探测实际容器/位深/码率(FLAC STREAMINFO / MP3 首帧),
  「已缓存列表」据此显示实际档位而非请求档。
- test/test_ncm_tag.c + build_ncm_tag_host.sh:FLAC/MP3 构建+读回、中文 roundtrip、
  旧标签替换、容器判定、3MB 分块、失败降级、探测 —— 51 断言全过,0 warning。
2026-11-04 20:49:25 +08:00
AskaEth e56c837f4f Merge branch 'feat/sdk-cross-build-bring-up' 2026-11-04 20:26:22 +08:00
AskaEth 8be4634a61 feat(sdk): 本机 zig 交叉链跑通 build_sdk.sh — 新增 build_sdk_host.sh 环境适配+成员/架构自检
主仓 patch_v2/sdk/build_sdk.sh 此前只在 SDK 仓验证过:硬编码 ROOT="$HOME/Project/R3ProII"
取 .tools/zig-mipsel-cc 与 patch_v2/meow_launcherd/meow_font.a,默认 AR=/usr/bin/ar、
mktemp 落 /tmp。Termux 上三者都不成立(工具链在 ~/.tools、meow_font.a 在仓库内且 *.a 被
gitignore、ar 在 $PREFIX/bin、/tmp 不可写),脚本无法直接跑通。

- build_sdk_host.sh: 不改 build_sdk.sh,临时布局同构 $HOME(.tools 与 patch_v2/
  meow_launcherd 符号链接到真实位置),导出 AR/TMPDIR 后原样执行脚本;--verify 追加
  「成员清单 = 本次 *.o(OBJS + meow_font.o)+ libfreetype.a 对象」比对与全量架构校验
  (不复制 OBJS 列表,避免与 build_sdk.sh 漂移)
- FreeType 2.14.3 源: SDK_FREETYPE_SRC 指向本地源优先;未设且无 vendor 时仍走 savannah 下载
- 验证: 冷构建(zig cache 空) 55s,重编 11-14s;meow_ui.a 5,701,866B / 75 成员
  (OBJS 31 + meow_font.o + freetype 43),全 ELF32 MIPS32 rel2 o32;hello_app 按文档链路
  meow_ui.a + libz.a + -lpthread 链接成功(474,612B 静态 MIPS32r2),不调 meow_ft_* 时
  freetype 成员未被拉入(零增量成立)
- 产物不入库: vendor/、*.a、*.o 均被 .gitignore 覆盖,git status 仅本脚本
2026-11-04 20:25:54 +08:00
AskaEth 47c638d65b Merge branch 'feat/m6445-web-license-residual-sync' 2026-11-04 20:14:16 +08:00
AskaEth 20f4727714 feat: M6.44+M6.45 现场补全 — 补齐按扩展名过滤遗漏的 web 前端与 license 合规件
真机 0.8.45 现场组成补全(初次提现场按扩展名过滤漏掉 7 个文本文件),
内容逐字节取自容器现场 /mnt/mb/home/Aska/Project/R3ProII 并 md5 对拍一致:

- patch_v2/meowpanel/web/meowpanel.css          (+17)  趋势/App 详情卡样式
- patch_v2/meowpanel/web/mp_pages.js            (+289) 性能趋势/功耗曲线/App 详情/蓝牙详情
- patch_v2/meowpanel/web/mp_shared.js           (+49)  趋势 sparkline 通用逻辑
- patch_v2/reader_app/.gitignore                (+2)   seg/chapter smoke host
- patch_v2/reader_app/NOTICE                    (+23)  FreeType 2.14.3 + zlib 条目
- patch_v2/reader_app/resources/licenses/NOTICE (+23)  同 reader_app/NOTICE(md5 一致)
- patch_v2/reader_app/resources/licenses/FTL.txt (新增 6743B) FreeType 许可证全文

面板前端对应已收编的后端 mp_files.c/mp_net.c(文件搜索+蓝牙详情),
NOTICE/FTL.txt 为 LGPL/FreeType 合规产物。仅投运现场内容,未改内容。
2026-11-04 20:10:42 +08:00
AskaEth 2ffb92c038 Merge branch 'feat/m6445-dirty-snapshot-consolidation' 2026-11-04 20:09:20 +08:00
AskaEth 7c7d891570 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 与容器一致)。
2026-11-04 20:02:28 +08:00
AskaEth e87ccdf061 Merge branch 'feat/m643-reader-streaming-panel-sync' 2026-11-04 20:00:59 +08:00
AskaEth f40abbd494 feat: M6.43 — reader分段流式读取(Phase1,只txt) + 面板前台管理/返回回桌面按钮
- reader分段(只txt): core/seg.{h,c} 512KB码位对齐切段(尾字完整)+manifest+按需读单段; book.c rd_book_open只布局每页所在段(治CPU100%/返回无效) load_seg只读当前段(非txt原路径); reader.c 进度实时保存(翻页/刮擦/字号/编码dirty+on_tick节流落盘+退出即时写,锚点存段号,崩溃不丢进度); rdtxt.c fread替代fgetc(去开书扫描卡顿); Phase2(双段拼接+4%释放)留待
- 面板: /api/ams/bg加fg/fg_count(后台保持向后兼容)+POST /api/ams/:pkg/killfg(前台救命:优先am kill,launcher拒则pid直信号SIGTERM->SIGKILL绕过门控)+前端/#/bg前台组'终止'绿徽标+确认弹窗(一键清仍只后台不误杀前台); POST /api/input/gesture(返回=左缘右滑/回桌面=底部上滑,注入滑动轨迹复用SDK手势)+前端屏幕控制页加返回/回桌面MD3按钮

0warning;宿主test_reader_core 72-0/seg_smoke 19-0/loaders_smoke/book_smoke/formats_smoke PASS;面板selftest/node check PASS
2026-11-04 19:47:10 +08:00
AskaEth a64ae06eb6 fix(reader): txt编码误判(UTF-8前窗截断判GB18030致乱码) + build_index无持久化(整本重排慢/UI阻塞卡) — ①rd_utf8_sample_ok结尾不完整序列按合法(中间非法仍拒,GBK不误判,新增t13回归) ②索引落盘MeowData/os.meow.reader/index/*.idx(失效键size/mtime/font/fs/ls/wh/enc,命中秒开,原子写+强自检弃坏缓存,编码/字号/行距重排重写) 重开<0.3s/首开建cache; test_reader_core 72-0, 0warning 2026-11-04 19:47:10 +08:00
AskaEth 68710d7ed8 fix(reader): 书索引build_index全量逐字FreeType排版优化 — rdft_advance加(px,cp)->advance缓存(开放寻址4096槽,与glyph缓存分离,load_font/set_px同清), 测量从O(全书字符)降到O(唯一码点~2600); 大书(10MB)打开 rd_book_open 23.9s->140ms(~170x), npages一致布局确定保留; 点条目不再用户态busy循环冻死(非驱动/锁屏, 是UI线程同步全量建索引); 0warning, 宿主test_reader_core 68-0/loaders_smoke/book_smoke/formats_smoke PASS 2026-09-04 21:01:56 +08:00
AskaEth 5e67100231 fix(reader): 书架scan_books改为递归扫子目录(Books/<subdir>/,深度≤2), 用户按目录组织书也能扫到 — 修复'书架为空'(书在Books/kh/子目录); reader热更 eacd0e6c 已基于此; 0warning 2026-09-04 20:48:55 +08:00
AskaEth 06f872faf2 fix(fw): M6.42 收编audiod开机路由武装瘦身(防楔死) — 推卡
- audiod 重编 d833abce(0warning, glibc-dynamic≤2.17): 去无条件apply_route(5)→target双写,当前端口正确则跳过强烧,仅未武装/端口不对/读失败才写目标;保留M2.91防挂死武装(numid=9语义/popen有界超时/D态抛弃/io_thread未动)
- SDK未变(meow_ui.a 207630cb沿用); launcher 9013f843未变; netmgrd 9c345b2e/meow_audio 6864ec38/amsd 57e19cde 未变
- 固件 r3proii_m6_42.upt 6d7c1168(0.8.42, rootfs 38719488<=45088768, unpack 0 diff); 已上卡+备份r3proii_prev_m6_42=2a966f2b+rm recovery_all+升级重启; 设备已回网0.8.42
- reader eacd0e6c/files 01ad3f01 卡上已热更未动(不在固件)
- 注: audiod瘦身是驱动楔死缓解,需用户后续多boot复测(不在本收编范围)
2026-09-04 20:48:02 +08:00
AskaEth 68f91f7de2 fix(audio): M6.42 — audiod开机路由武装瘦身(去无条件apply_route(5)→target双写, 当前端口正确则跳过强烧, 仅未武装/端口不对/读失败才写目标; 保留M2.91核心防挂死武装, numid=9语义/popen有界超时/D态抛弃/io_thread未动) — 降低stock hbc3000驱动楔死整机硬冻结触发面(reader后台+Files切换撞楔死驱动口); 0warning, 宿主test_audiod_host 100-0; 需真机多boot复测 2026-09-04 20:43:22 +08:00
AskaEth 4ce7a268a8 fix(fw): M6.41 收编启动失败原因透传+后台管理按钮点不动修复+主菜单微调 — 推卡(固件已上卡,设备待回网补reader热更+校准)
- launcher 9013f843(启动失败原因透传+后台管理按钮点不动修复+主菜单字体/样式微调) / reader 5a0c8776(左缘返回+view栈+字体瘦身+页位图释放)
- SDK未变(meow_ui.a 207630cb沿用),不重编meow_ui.a/不重链ncm/hello/files(files已热更01ad3f01不动)
- 固件 r3proii_m6_41.upt 2a966f2b(0.8.41, rootfs 38719488<=45088768, unpack 0 diff); 已上卡+备份r3proii_prev_m6_41=28191ae7+rm recovery_all+触发升级重启
- netmgrd 9c345b2e/audiod 9f47c8fd/meow_audio 6864ec38 未变; amsd 57e19cde 保持
- 注: 设备升级后未回网(WiFi已知问题,超~5分钟),reader热更+升级后验收+红线校准待设备回网后补
2026-09-04 19:50:55 +08:00
AskaEth ddc8d35eb9 fix: M6.41批 — 启动失败原因透传 + 阅读器左缘返回/阅读页接入view栈 + 后台管理按钮点不动 + 阅读器瘦身(fonts common+页位图释放) + files txt换行
- launcher(453): app_launcher.c g_launch_fail_reason+launch_fail()统一出口(5失败点 fork OOM/exec/no such file/missing dep/execpipe)+main_menu.c launch_fail_toast(缺依赖/CANNOT START: name(reason))+toast256
- launcher(457): bg_page.c bgm_enumerate跳过term_at_ms(杀后当下消失)+不可杀行按钮置灰+row_tap/top_action返回1; subpage.c 消warning
- reader(454): reader_on_swipe LEFT/RIGHT→返回(先关overlay否则page_pop回书架)+app.c书架根LEFT→exit
- reader(458瘦身A+B): app.json fonts full→common(省13MB atlas)+reader.c RD_PAGE_CACHE 3→2+g_anim_old懒分配/anim_done释放+on_enter/on_leave页位图离开释放重建
- reader(459导航): reader_open返回int+shelf点书push ACT_READER(阅读页接入view栈,on_enter/on_leave驱动) — 使454左缘返回+458瘦身B真正生效
- files(455): viewer.c viewer_cp_len+按码位折行(txt中文不冲出右缘)

0warning;宿主测试全过;files二进制已热更
2026-09-04 19:43:28 +08:00
AskaEth 626a87a30d fix(fw): M6.40 收编系统级音量翻页映射(MSG_KEY_PAGEUP/PAGEDOWN)+P1 MD3(select面板28/对话框按钮胶囊)+阅读器UI改版 — 推卡(固件已上卡,设备待回网验收)
- meow_ui.a 重编 207630cb(0warning): select面板28/对话框按钮胶囊h/2
- launcher f1980f4f(音量翻页系统映射) / hello 92c7ba17 / files 66bdb60d / reader 9c2a25e0(阅读器UI改版) / ncm e796282e
- 固件 r3proii_m6_40.upt 28191ae7(0.8.40, rootfs 38719488<=45088768, unpack 0 diff); 已上卡+备份r3proii_prev_m6_40=a671b8ba+rm recovery_all+触发升级重启
- netmgrd 9c345b2e/audiod 9f47c8fd/meow_audio 6864ec38 未变; amsd 57e19cde 保持
- 注: 设备升级后未回网(超8分钟),四App+面板热更与升级后验收待设备回网后补
2026-09-04 18:24:16 +08:00
AskaEth 2826c1e905 feat: M6.40批 — 阅读器UI改版(书架list·grid+空态骨架+界面设置+App设置页+header·footer+背景黑默认) + 系统级音量翻页映射 + P1 MD3(select面板28/对话框按钮胶囊) + MeowPanel写端点护栏 + SDK公开仓·文档同步
- reader: app.c/shelf.c/reader.c 全套UI; 新增 reader_conf(reader.conf)/settings(App设置页)/reader_ipc(音量翻页IPC响应); app.json加volume_page
- launcher: keys.c meow_volpage_*门 + util.c app_id→fd映射(HELLO记fd/断开清) + app_launcher.c 前台三处接线(进入sink/按键路径volpage_key/离开clear) → 前台声明volume_page的App音量键→MSG_KEY_PAGEUP/PAGEDOWN翻页(非阅读器前台音量照旧)
- sdk: meow_select.c 底部面板28 + meow_ui_dialog.c 对话框按钮胶囊(h/2) + test_meow_ui_select.c修采样
- meowpanel: /api/net/policy·/api/power/policy 加防自锁+policy默认关两条护栏(panel.policy_enabled默认0)
- 文档: MEOW_APP_SDK.md §12.6 + meowpanel README端点表

0warning;宿主测试全过;二进制留批量批次未入库
2026-09-04 18:13:18 +08:00
AskaEth b364b6371a fix(fw): M6.39 收编SDK LazyGrid/LazyColumn/LazyRow MD3容器化+SDK全局App内底部上滑回桌面(系统手势优先) — 推卡
- meow_ui.a 重编 0fb87579(0warning): meow_list/lazygrid 默认container=1 + meow_ui_input_is_home_swipe/MEOW_EV_HOME
- launcher a21243b6 / hello 96d14310 / files a9de683f / reader 3e8be7cb / ncm 47954e2c (重链新meow_ui.a)
- 固件 r3proii_m6_39.upt a671b8ba(0.8.39, rootfs 38715392<=45088768, unpack 0 diff)
- netmgrd 9c345b2e/audiod 9f47c8fd/meow_audio 6864ec38 未变; amsd 57e19cde 保持
2026-09-04 14:01:26 +08:00
AskaEth 501867b362 feat(sdk): M6.39批 — LazyGrid/LazyColumn/LazyRow MD3容器化 + SDK全局App内底部上滑回桌面(系统手势优先)
- meow_ui_widget.c: W_LIST/meow_list/LazyColumn/LazyRow默认container=1(MD3圆角卡surfaceContainer+tonal选中+卡内按压+去分隔线) + 新增meow_list_set_container; 平坦回退set_container(0)
- meow_lazygrid.c: lg_draw_cell容器化(卡内缩8,surfaceContainer圆角+tonal选中+按压)
- meow_ui_input.c: 新增meow_ui_input_is_home_swipe(镜像np_home_gesture:屏底28px热区+上移65px+竖向主导,与左缘返回/列表中滑互斥) + MEOW_EV_HOME分发→meow_ui_nav_request_exit(系统保留手势**优先于App on_swipe**,任意App内生效→MSG_NAV EXIT→批①保活回桌面; 不调request_exit避免进程退出断送保活)
- 声明: meow_ui_input.h / meow_ui_widgets.h 各追加
- 宿主测试: test_meow_ui_home_gesture 19-0 / test_meow_ui_lazygrid 32-0, 0warning
2026-09-04 13:56:11 +08:00
AskaEth d0a5901ffb fix(fw): M6.38 收编SDK对话框MD3细化+批②底部上滑回桌面+批6 ncm顶栏回播放页+批④面板后台列表+launcher UI微调+封面空artwork保留 — 推卡+面板热更
- meow_ui.a 重编 4c006844(0warning): meow_ui_dialog MEOW_SHAPE_EXTRA_LARGE 28
- launcher c9218411 / hello 63824093 / files c9309774 / reader 0d462111(未变,不拉对话框对象) / ncm 2b33b1dc
- 固件 r3proii_m6_38.upt 7b6ce4a5(0.8.38, rootfs 38715392<=45088768, unpack 0 diff)
- meowpanel 后端 fcb2f658 + web(index/css/js/mp_pages) 热更 MeowOS/opt/MeowPanel, /api/ams/bg 新增, 运行中新二进制
- netmgrd 9c345b2e/audiod 9f47c8fd/meow_audio 6864ec38 未变; amsd 57e19cde 保持
2026-09-04 13:23:56 +08:00
AskaEth a2aec783a7 feat(ui): M6.38批 — P1 MD3细化(SDK对话框28)+批②底部上滑回桌面+批6 ncm顶栏回播放页+批④面板后台列表+launcher UI微调(歌词页黑半透明底/播放页布局下移)+封面空artwork保留修复
- P1: meow_ui_dialog.c 对话框底框 radius_card→MEOW_SHAPE_EXTRA_LARGE(28) 三处(:103填充/:104描边/:361 BottomSheet); meow_ui_widgets.h 新增 MEOW_SHAPE_EXTRA_LARGE 28 宏; TextField/FAB/Slider/Progress 按设计文档保留
- 批②: np_gesture.h 新增 NP_GEST_HOME+np_home_gesture(底部热区上滑,与左缘返回对称互斥); now_playing.c 新增 np_draw_home_bar(屏底左缘pill指示条)+手势衔接; test_now_playing_widgets G5b
- 批6: ncm home.c 顶栏加回播放页按钮(MEOW_ICON_QUEUE_MUSIC)→push(ACT_PLAYER), 无音频也生效
- 批④: meowpanel /api/ams/bg 只读端点+前端后台列表页+杀/清复用kill通道
- UI微调: now_playing.c 播放页布局宏下移(NP_COVER_Y 84/NP_BTN_Y 612消底部留白)+歌词页背景统一黑色半透明叠层(弃封面取色底,删 np_draw_lyric_coverbg)
- 封面保留: now_playing.c/notif_center.c 空artwork保留上一张已解码封面(防暂停/开歌单致META报空artwork后封面闪没); test_np_cover C2断言更新+mirror同步

0warning;宿主测试 test_np_cover ALL PASS;launcher/ncm/panel 宿主测试无回归。二进制留批量批次未入库
2026-09-04 13:09:03 +08:00
AskaEth b3ce719742 fix(fw): M6.37 收编SDK默认列表MD3容器化(meow_listview_create默认container=1)重编meow_ui.a重链四App — 推卡
- meow_ui.a 重编 14f218d7(0warning): meow_listview_create默认container=1,行=surfaceContainer圆角卡+空隙+去分隔线+卡内tonal选中
- launcher e7fd28dd / hello c10a3ea5 / files 90a6e817 / reader 0d462111 / ncm 6f3967f8 (重链新meow_ui.a)
- 固件 r3proii_m6_37.upt a8dd8f54(0.8.37, rootfs 38715392<=45088768, unpack 0 diff)
- netmgrd 9c345b2e/audiod 9f47c8fd/meow_audio 6864ec38 未变; amsd 57e19cde 保持
2026-09-04 12:29:23 +08:00
AskaEth 8e68254ce4 style(sdk): SDK默认列表MD3容器化 — meow_listview_create默认container=1(行=surfaceContainer圆角卡+空隙+去分隔线+卡内tonal选中),hello/files/ncm/reader等用默认renderer的App开箱即MD3(用户2026-09-04反馈默认仍扁平);需平坦宿主可set_container(0)回退(宿主测试test_meow_ui_widgets/listvirt补set_container(0)锁扁平基线)。0warning,宿主测试全过(widgets ALL PASS/md3 PASS/swipe 35-0/listvirt 44-0)。meow_ui.a变需重编+重链四App 2026-09-04 12:24:16 +08:00