Skip to content

NetPilot 1.5.0 — 日志落盘修复 + 写入链路修复与权威存储 + 运营商识别 + Tasker 事件门控

Choose a tag to compare

@katiusu katiusu released this 05 Oct 13:13
· 8 commits to main since this release

这一版修了什么

本版把 1.5.0 起累积的几批改动合并发布(1.5.0 之前从未发布过,不另占版本号)。判定语义、默认值、用户可见行为均未改变 —— 自动降级 / 恢复 / 冷却 / 无网回退的触发条件、阈值与默认值与 1.4.0 逐位一致。

1. 日志落盘(主修复)

日志以前只在内存里,进程一被系统回收就全丢,事后无法复盘。现在按节流落盘:每 30 秒一次、最多 120 条。日志页仍是内存 400 条,导出上限不变,旧的导入/导出 JSON 仍兼容。

2. 写入链路:修掉六处「看得见的假成功」

排查「回读通过了、制式却没变」时找到的六条互相咬合的问题,典型两条:

  • 表外模式被放开成「不限制任何制式」:掩码表里查不到的模式,旧版会把 (1 shl 31) - 1 写下去,等于把 5G 门彻底打开;现在直接拒绝并写一条 WARN。
  • 权限被拒被吞成「失败」两个字:SecurityException 现在会带着「本进程 uid、需要哪个权限、为什么没有」一起进日志。

另外几条:设置的写入结果与调制解调器返回值被丢弃、settings 那条路径「自己写自己读」的闭环校验等。写入顺序本身也明确了:ITelephony → 权威存储 → settings 兜底,每一步都能看到。

3. 权威存储与跨源回读

settings put global preferred_network_mode 写的是遗留字段,回读必然一致;系统真正读的是 TelephonyProvider siminfo 表的 allowed_network_types 列。本版新增 AuthStore,通过 Root 通道直写该列并用另一个源回读,这才谈得上交叉验证。

分类修正(本版最后一批):真机日志里出现过 被拒绝:… Unable to find app for caller … when getting content provider telephony。这句与权限无关 —— ContentResolver 会先让 AMS 按调用方 pid 找一条应用进程记录,而 Shizuku 用户服务进程由守护进程用 app_process 拉起、从未 attachApplication,AMS 侧没有它的记录,补多少权限都过不去。现在这种失败单独归类为「读不到:… 补授权无效;读写权威存储只能用 Root 通道」,只有真的缺权限才会显示「被拒绝」。

4. 运营商识别 + 默认制式表重核

NetworkMode.OPERATOR_DEFAULTS 决定「解除锁 5G 时回落到哪个制式」。旧表有三处不对:漏了 46005(中国电信 CDMA)(这张卡会静默落到联通档 26)、漏了 46020(中国铁通,2008 年并入移动)、多出 46010 与 46027(四个独立来源 — musalbas/mcc-mnc-table、pbakondy/mcc-mnc-list、mcc-mnc.org、ITU-T E.212 公报 OB 1280 — 里一个都查不到)。

现在:电信 3/5/11 → 27、移动 ""(46000)/2/4/7/8/20 → 32、联通 1/6/9 → 26、广电 15 → 33。设置页「系统兼容性」新增只读行**「运营商识别」**,形如 中国移动(46000)→ 32 NR/LTE/TDSCDMA/GSM;号段不在表内时明确写「不在内置运营商表中」。这张表本质是猜,猜错不会报错、只会安静地回到错的制式 —— 摊在设置页,换一张卡就能立刻验证。

5. Tasker / Locale 接口关闭时,不再外发任何事件

以前 TaskerGate 只把三个组件设成 enabled=false(挡住「外面叫醒我们」),而五条发送路径全部汇到一个没有开关判断的 broadcast(),于是接口关着时快照与降级事件照样广播出去 —— 开关形同虚设。现在门控加在那唯一的收口点,并且开关关闭时连事件订阅都不建立。np_tasker_enabled 默认仍是关;打开后行为与之前完全一致。

6. 其他

  • 桌面只有一个图标:删掉了重复图标的隐藏代码(以前要藏一个)。
  • 设置页新增「自动更新」开关(默认开):关掉后不再请求 GitHub Releases。
  • 「写入详细诊断日志」覆盖面扩展(默认关):命令原文、结果分类、原始 exit/stdout/stderr、逐列试探、AIDL 编码串等。全部走 detail(),开关关闭时一行都不写;权限拒绝那类 WARN 仍无条件记录。

需要你留意

  • 从 1.4.0 升级上来不需要任何操作:没改默认值、没改判定、没新增权限。
  • 如果你依赖 Tasker / Locale 的广播,请确认功能页里那个开关是打开的 —— 以前它关不关都发事件,现在真的不发了。
  • 「详细诊断日志」查完记得关回去(打开后写入路径每一步都进日志页)。

已知限制

  • 运营商表是「按公开来源核对过的推测」;非国内卡与表外号段仍回落 26(语义未变)。
  • Shizuku 通道读/写权威存储做不到(AMS 找不到该进程的应用记录,与权限无关),只能用 Root 通道;日志与设置页现在会如实说明原因。
  • 设置页新增的只读行文案由 Kotlin 拼装,英文界面下仍是中文(已知外观限制)。

验证

  • assembleDebug / assembleRelease 均 EXIT=0 且 APK_CHECK ... OK(分两次单独构建,均带 --no-configuration-cache)
  • versionCode=2026100504 · versionName=1.5.0 · targetSdk=36 · compileSdk=37
  • 签名与本项目历次同一把 release key(SHA-256 34100875...4c4c)⇒ 可直接覆盖安装,SharedPreferences 不清
  • 16 KB 页对齐:zipalign -c -P 16 -v 4 → Verification successful
  • 清单里 android.intent.action.MAIN 计数 = 1(桌面只有一个入口);Tasker 三个组件仍 enabled=false
  • 交付产物里确实包含本次代码:解包 classes*.dex 后 grep -a 命中新增字符串
  • 未新增任何依赖;未引入唤醒锁、精确闹钟权限或第二个前台服务通知
  • 来源核对脚本 tools/check_provenance.py → EXIT=0

下载:NetPilot-1.5.0-2026100504-release.apk · 33,221,389 B · SHA-256 048e94ec9230df709c24b78b8a65acd42380bf2fc5459bb7a323f5e4b66f06f9

完整量化对照、逐条改动清单与回滚方式见 docs/POWER_REPORT.md §8;真机自测步骤见 docs/TESTING.md §19(19.1–19.16)。