feat(ncm): 三期第二批 — 中文搜索接拼音IME+设置页做好(音质全档/缓存上限可设数字+清理缓存/关于)+缓存LRU淘汰接生产路径(写前写后+手动调低上限)
- 搜索页输入框 MEOW_IME_ASCII→MEOW_IME_PINYIN: 候选上屏UTF-8经 on_change 实时回写 g_st.search_query, 键盘「拼/英」「中」切换, 英文零回归; 搜索仍仅在点「搜索」时发 cloudsearch(风控) - 设置页 5 行: 音质(Hi-Res 默认,Lossless/Exhigh/Higher/Standard 全档,core 既有降级链)/缓存上限(1~100GB 预设+「自定义」NUM IME 数字输入,默认10上限100)/清理缓存(显示当前占用,ncm_cache_clear)/退出登录/关于行 - 缓存淘汰接线: ncm_cache_evict 进生产路径 — player_manager(下载写前/写后)+cover(写前/写后)+appstate_save_settings(手动调低上限立即淘汰); 封面与 mp3 同池; 上限读设置值 - core 新增 ncm_cache_clear; 设置持久化走 meow_config_* → MeowData/dev.player.ncm/data - bench/cache_evict_sim.c 离线回归(0网络) 6 组 PASS; pagination_sim/core(host+mipsel/qemu)/6页宿主渲染 全过; mipsel -Wall -Wextra 0 warning (未动 sdk/、meow_launcherd/、vendor/;0 真实 NCM 请求;真机部署留用户)
This commit is contained in:
1 parent
1a239c5eab
commit
f23720f934
13 files changed
+469
-33
No files matched your search
@@ -1050,3 +1050,123 @@ c73366373b3a372d96b2218e528c6381 build_ncm_host.sh
|
||||
| `NCM_SONG_BATCH` | 64 | 100 | song_detail 每批(≤500 安全窗内保守 100;`clist[4096]` 装 100 首 ≈2KB) |
|
||||
| `NCM_PLAYLIST_PAGE` | 50 | 删除 | track/all 服务端分页遗留(该端点 404),改由 `NCM_SONG_BATCH` 承担页粒度 |
|
||||
| `g_st.track_ids_count` | — | 新增 | detail 取回 trackIds 总数,驱动「还有下一页」判据 |
|
||||
|
||||
---
|
||||
|
||||
## 15. 三期第二批:中文搜索接入拼音 IME + 设置页做好 + 缓存淘汰接线(2026-08-31,agent-241)
|
||||
|
||||
> 范围:仅 `patch_v2/ncm_app/`(含 `core/`)。未动 `sdk/`(主会话在改 `meow_ui_theme.c`/测试,另有 agent 在改
|
||||
> `meow_launcherd/` 主题)与 `meow_launcherd/`。风控纪律:本批真实 NCM 请求 **0 次**(全部离线 stub/宿主 mock/
|
||||
> 已落盘样本)。部署/验收留用户(真机验收点见 §15.7)。上一批(歌单分页/封面/歌词锁)已 commit `ee104f1`,
|
||||
> 本批在其上做;提交见 git。
|
||||
|
||||
### 15.1 中文搜索接入拼音 IME
|
||||
|
||||
- 搜索页(`app/ui/search.c`)输入框 `meow_textfield_create(..., MEOW_IME_ASCII)` 改 **`MEOW_IME_PINYIN`**。
|
||||
SDK `MEOW_IME_PINYIN`(M2.88 agent-229 落地)打开后为 4 行字母键 + 组合条 + 候选栏(≤6 候选/页,翻页 +
|
||||
「清」+「拼/英」键),候选上屏走 `py_commit` UTF-8 写进字段并触发 `on_change`(TextField 的
|
||||
`textfield_change_cb` 实时回写 `g_st.search_query` + `invalidate`)。
|
||||
- **候选上屏/清空/退格语义**均沿用 SDK IME(`py_commit`/`py_clear`/`py_back_combo`+`py_back_field`,组合态
|
||||
UTF-8 安全退格 = 删末字;组合非空时退格删组合末字母),App 侧零改动。
|
||||
- **英文输入零回归**:拼音键盘含「拼/英」键(`K_SWITCH`→ASCII)与 ASCII 键盘顶条「中」热区(→拼音),
|
||||
ASCII/NUM 不随本批改动;搜索仍只在用户点「搜索」按钮时发 `cloudsearch`(风控:进页不自动搜,不逐键发)。
|
||||
- 保留 `search_submit`/`search_worker`(后台线程 cloudsearch,UI 不卡);`ncm_api_cloudsearch` 的 keyword
|
||||
为 UTF-8 字符串,中文关键词直接进 weapi 加密体(无需改造)。
|
||||
|
||||
### 15.2 设置页做好(用户定案:音质/缓存上限可设数字+清理缓存+关于)
|
||||
|
||||
`app/ui/settings.c` 重做为 **5 行**:音质 / 缓存上限 / 清理缓存 / 退出登录 / 关于网易云。
|
||||
|
||||
- **音质**:sheet 列出全 5 档(Hi-Res/Lossless/Exhigh/Higher/Standard,默认 Hi-Res)。单曲不可用时
|
||||
**沿用 core 既有降级链**(`ncm_api_song_url_auto`:hires→lossless→exhigh→higher→standard,`ncm_api.c:260`),
|
||||
本批未改 core 降级逻辑。
|
||||
- **缓存上限**:sheet 预设(1/2/5/10/20/30/50/100 GB)+「自定义...」→ INPUT 弹窗 + **NUM IME 数字输入**
|
||||
(`input_cache_limit_gb()`,atoi + 钳制 1~100)。默认 10GB,上限 100GB。持久化走既有
|
||||
`appstate_save_settings`(`meow_config_*` → `<env MEOW_DATA_DIR>/ncm.cache_limit_gb.cfg`,即
|
||||
`MeowData/dev.player.ncm/data/`,与 core `ncm_cache_load_setting`/`ncm_store_read_cfg_int` 同目录同键)。
|
||||
- **清理缓存(新)**:显示当前占用(`ncm_cache_total_bytes`,进页时算一次存 `g_cache_used`,清理后清零);
|
||||
tap → CONFIRM 弹窗 → `ncm_cache_clear`(新 core API)→ snack「缓存已清理」。占用用整数运算格式化
|
||||
(`fmt_bytes`,GB/MB/KB,不用浮点/软浮点)。
|
||||
- **退出登录 / 关于/版本行**:保留;关于 tap 改为 snack「网易云音乐 v0.1 · MeowOS 移植版」。
|
||||
|
||||
### 15.3 缓存淘汰接线(ncm_cache_evict 接进生产路径)
|
||||
|
||||
- **core 新增 `ncm_cache_clear`**(`core/ncm_cache.c/.h`):删除 `song_*` 全部(mp3 与封面同池,含残留
|
||||
`.tmp`),供「清理缓存」与测试用;`ncm_cache_evict`(既有)保持 LRU=按 mtime 升序删最旧直到 `<= limit`。
|
||||
- **mp3 下载路径**(`app/play/player_manager.c song_local_file`):**写前**(`ncm_cache_open` 前)与**写后**
|
||||
(`ncm_cache_commit` 后)各调一次 `ncm_cache_evict(&g_st.ctx.cache)`——写前腾空间(此时本线程 temp 尚未建,
|
||||
无在途文件被误删风险),写后清「新文件推过上限」的增量。刚写的文件 mtime 最新,LRU 淘汰时存活。
|
||||
- **封面路径**(`app/logic/cover.c` cover_worker 未命中写盘分支):写前 + 写后同样各调一次 `ncm_cache_evict`
|
||||
(封面 `song_cov<hash>..jpg` 与 mp3 同池)。
|
||||
- **手动调低上限**:`appstate_save_settings` 末尾加一次 `ncm_cache_evict`,用户从 50GB 降到 1GB 立即淘汰。
|
||||
- 上限读设置值:`ncm_cache_set_limit_gb(&g_st.ctx.cache, g_st.cache_limit_gb)`(`player_manager_set_quality`
|
||||
与 `appstate_save_settings` 均已同步,继 `appstate_load_settings`/`ncm_cache_load_setting`)。
|
||||
|
||||
### 15.4 验证记录(0 真实 NCM 请求)
|
||||
|
||||
| 项 | 方式 | 结果 |
|
||||
|---|---|---|
|
||||
| 缓存 LRU 淘汰/清空 | `bench/cache_evict_sim.c` 离线(0 网络,稀疏文件构造,直接驱动 core) | **全 PASS**:①超上限删最旧(700+300+400MB→删 700 停于 700MB)②删 2 个最旧到 ≤1GB(4×500MB→留 2)③未超上限无操作 ④`lookup` 刷新 mtime → 被访问的 A 存活、B/C 被淘汰 ⑤`set_limit_gb` 钳制(0→1、200→100)⑥`clear` 删 mp3+封面+残留 .tmp(total=0)|
|
||||
| 歌单分页回归 | `pagination_sim`(0 网络) | **全 PASS**(130/5191/空 三态无回归;`appstate.c` 加 `ncm_cache_evict` 未破坏分页——`--gc-sections` 丢弃不可达的 `save_settings`,链接不受影响) |
|
||||
| core 宿主测试 | `test_ncm_core_host`(重建 core-host) | **PASS** |
|
||||
| core mipsel 测试 | `qemu-mipsel ./out/test_ncm_core_mipsel` | **PASS** |
|
||||
| mipsel 构建 | `bash build_ncm.sh`(自有代码 `-Wall -Wextra`) | **0 warning**;`text 844640 / data 856 / bss 2052068` |
|
||||
| 宿主离屏渲染 | `build_ncm_host.sh` + `MEOW_UI_DUMP`(mock,0 网络) | settings(明/暗 5 行 + 占用 + 版本 + 品牌红脚注)/search(输入框+搜索钮+footer)/home/playlist/player 均正常渲染,无崩溃 |
|
||||
|
||||
### 15.5 md5(本批改动文件 + 产物)
|
||||
|
||||
```
|
||||
8a313d27dc7d05fa3a78ce7772436b04 ncm # mipsel 静态 App(新)
|
||||
dc66bdcfb29ba5717b42c72ecbf45049 ncm_host # 宿主离屏调试二进制(重编)
|
||||
be3d906edce4d90ebd9c09d3b7faf814 core/ncm_cache.c # 新增 ncm_cache_clear
|
||||
f5810d23709080f4fa39b2fbc242c9e0 core/ncm_cache.h
|
||||
41ae3f40014f68f7855fed3a0be1558c app/ui/settings.c # 设置页 5 行 + 自定义数字 + 清理缓存
|
||||
9811af8f7150b325225e067748ca50a3 app/ui/search.c # 输入框 MEOW_IME_PINYIN
|
||||
2350622237e9fb5d05a5497dd8b87e39 app/play/player_manager.c # mp3 写前/写后淘汰
|
||||
fb1a74a68950b26a2a4f42281725f37d app/logic/cover.c # 封面写前/写后淘汰
|
||||
a51b6d8477bde5692089caf511eafca1 app/logic/appstate.c # save_settings 末触发淘汰
|
||||
ed2f71c52563e812a04fb8a7cc05148d app/test/test_ncm_app.c # settings mock 初始化缓存目录
|
||||
2134ad23a6ee4d1b37120ee8d2e44337 bench/cache_evict_sim.c # 新增 LRU/清空离线回归
|
||||
```
|
||||
|
||||
### 15.6 出入清单(只改 `patch_v2/ncm_app/`)
|
||||
|
||||
```
|
||||
修改:
|
||||
app/ui/settings.c # 设置页 5 行:音质(全5档)/缓存上限(预设+自定义数字)/清理缓存(显示占用)/退出/关于
|
||||
app/ui/search.c # 搜索输入框 MEOW_IME_ASCII → MEOW_IME_PINYIN(中文搜索,英文零回归)
|
||||
app/play/player_manager.c # song_local_file 写前/写后 ncm_cache_evict
|
||||
app/logic/cover.c # cover_worker 未命中写盘分支 写前/写后 ncm_cache_evict
|
||||
app/logic/appstate.c # appstate_save_settings 末尾触发 ncm_cache_evict(手动调低上限立即淘汰)
|
||||
core/ncm_cache.c/.h # 新增 ncm_cache_clear(删 song_* 全部)
|
||||
app/test/test_ncm_app.c # settings mock 初始化 ctx.cache(「占用」行读真实目录)
|
||||
ncm / ncm_host / test/test_ncm_core_host # 重编产物
|
||||
新增:
|
||||
bench/cache_evict_sim.c # 缓存 LRU 淘汰/清空 离线回归(0 网络)
|
||||
REPORT.md # 本批记录(§15)
|
||||
(未动 sdk/、meow_launcherd/、vendor/;未动设备系统/恢复区;未 killall hiby_player / 未重启设备)
|
||||
```
|
||||
|
||||
### 15.7 诚实出入 / 已知限制
|
||||
|
||||
- **真机未部署/未验**(风控:0 新增真实请求)。部署链路同 §13.5(`scp ncm root@<ip>:/usr/data/mnt/sd_0/MeowAPPs/dev.player.ncm/ncm.new` → `ssh root@<ip> '. /etc/profile; mv ...ncm.new ...ncm'`)。真机验收点:
|
||||
① 搜索页输入拼音→候选上屏中文→点「搜索」出中文结果(键盘「拼/英」「中」「退格」「清」语义);
|
||||
② 设置页缓存上限「自定义」数字键盘输入 1~100、改上限后立即 LRU 淘汰;③ 清理缓存显示真实占用、(超上限
|
||||
磁盘占用下降);④ 音质默认 Hi-Res、VIP/版权曲逐档降级播放。
|
||||
- **`song_<id>..mp3` 双点命名是 core 既有约定**(`ncm_cache_path` 用 `"song_%s.%s"` + ext 带前导点 `.mp3`)
|
||||
——本批未改(改动它需动 core 缓存写入路径,风险大于收益);`cache_evict_sim.c` 已按此约定构造文件,
|
||||
验证的正是真实生产路径。
|
||||
- **跨线程淘汰的极小竞态**:cover 线程写盘时,player 线程的下载 temp(`song_<id>..mp3.tmp`)也匹配
|
||||
`song_` 前缀;但 in-progress .tmp 的 mtime 是「刚写」=最新,LRU 升序下排最末,正常淘汰只删最旧,
|
||||
不会先删它。仅在「池严重超上限、删净旧文件后仍超」的极端情形才可能触及其(上限 ≥1GB,现实中几乎不
|
||||
发生);沿用既有「双线程同池无锁」模型(本批未扩范围,未引入新锁)。
|
||||
- **`ncm_cache_evict` 上限读 `&g_st.ctx.cache`**:宿主 settings mock 未 `ncm_ctx_init`(只 init cache dir),
|
||||
`ctx.cache.dir` 为空 → 占用行显示 0(渲染验证用);真机 `appstate_init`→`ncm_ctx_init` 后为真实目录。
|
||||
|
||||
### 15.8 数值权衡(供后续微调)
|
||||
|
||||
| 常量 | 旧值 | 新值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 设置页行数 | 4 | 5 | 新增「清理缓存」行并在「缓存上限」接「自定义」数字输入 |
|
||||
| 音质 sheet 档数 | 3(Hi-Res/Higher/Standard) | 5(+Lossless/Exhigh) | 对齐 core `NCM_LEVEL_*` 全档 + 降级链起点 |
|
||||
| `ncm_cache_clear` | — | 新增 | 删除 `song_*` 全部(mp3/封面/.tmp),供「清理缓存」与测试 |
|
||||
Reference in new issue
Block a user