Conversation
ziren28
force-pushed
the
codex/android16-realme-carrier-fallback
branch
from
July 13, 2026 13:12
c379ac6 to
ae84999
Compare
hanshiyou7-pixel
approved these changes
Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
关联与提交关系
本 PR 承接并完整保留 @a5533348 在 #122 中提出的 instrumentation 回退方案:
6c05f22是 Fix carrier config saving on newer Android #122 原作者的提交,作者信息保持不变;感谢 @a5533348 对新版 Android 兼容路径的分析和初始实现。
问题与根因
Nrfr 原有写入路径通过 Shizuku 包装
ICarrierConfigLoader:carrierConfigLoader.overrideConfig(subId, bundle, true)在部分新版 Android / 厂商 ROM 上,即使 Shizuku 已正常运行并向 Nrfr 授权,TeleService 仍会根据 Binder 实际调用方拒绝 shell UID,错误为:
因此这里不是普通的 Shizuku 授权缺失,也不能通过重复授权解决。本 PR 的目标是:
调用链
还原操作沿用同一调用链,以
bundle = null表示清除 override。逐文件改动
app/src/main/AndroidManifest.xmlPrivilegedCarrierConfigInstrumentation,目标包为当前applicationIdCarrierConfigManager.ktContext;先尝试原有直接调用,只对明确的 shell 拒绝切换回退SecurityExceptionPrivilegedCarrierConfigRunner.ktMainScreen.ktREADME.md本 PR 没有增加网络请求、动态代码加载或新的 Gradle 依赖,也不需要 Root。
关键实现
1. 只对明确的 shell 限制启用回退
其他安全异常继续向上传递,不会被 instrumentation 路径掩盖。
2. 配置不进入 instrumentation 参数
subId和PersistableBundle只保存在应用进程内。instrumentation 参数中仅传 PID 与随机 token,外部启动方不能通过参数直接构造待写入的配置对象。消费请求使用
ConcurrentHashMap.remove(token):随机 UUID 是请求的主要一次性凭据;PID 校验用于拒绝跨进程或应用进程重启后的请求,不把可查询的 PID 描述为独立鉴权秘密。token 过期、未知或重复使用都会 fail closed。
3. 最小权限委派
manager.startDelegateShellPermissionIdentity( Os.getuid(), arrayOf(Manifest.permission.MODIFY_PHONE_STATE) )原始方案传入
null,权限范围过宽。本 PR 明确限制为本功能需要的MODIFY_PHONE_STATE。4. 受限的持久化降级
只有异常信息表明
persistent=true或 system app 持久覆盖限制时才降级为persistent=false;未知异常不会被当作兼容问题继续执行。5. 失败与权限清理
startInstrumentation()抛异常或返回false时立即删除 pending token;stopDelegateShellPermissionIdentity();finish();success、persistent和error。当前 UI 尚未接入
IInstrumentationWatcher,所以“instrumentation 已启动”不等于“最终写入已确认”。本 PR 将提示改为“请求已提交”,没有继续显示误导性的“设置已保存”。“权限监控”说明
在本次测试的真我 GT8 Pro / realme UI 7.0 开发者选项中,没有找到旧教程所称的“权限监控”或“禁止权限监控”。英文界面中可以看到
Disable system optimization,但没有证据证明它与旧入口是同一功能,因此本 PR:Disable system optimization;该结论只对应本次系统版本,不外推到所有 realme / ColorOS 设备。
真机验证
RMX5200)RMX5200_16.0.7.205(CN01)OVERRIDE → callback → CARRIER_CONFIG_CHANGEDpersistent=false回退这里的“写入成功”指 Android
CarrierConfig服务中的 override 已生效,不表示修改了实体 SIM 卡。用户反馈:双卡都应用配置后,TikTok 在该设备上可以正常使用。这只是本次设备上的用户观察,不是自动化验收条件,也不构成对 TikTok、其他应用或其他网络环境的兼容性承诺。
报告和附件中未包含手机号、ICCID、订阅标识、设备序列号或本次测试使用的具体 override 值。
真机测试 APK 及制作过程
为方便维护者复现,已将真机使用的 APK 放到个人 fork 的 Pre-release;二进制文件不进入上游 PR 的 Git 历史:
制作链
使用官方 Nrfr v1.0.3 APK 作为二进制基线:
回退基线固定到 Fix carrier config saving on newer Android #122 提交
6c05f224dc802d0df952db93a6d2852a91c9edb0;加固设计对应当前提交ae849997c98a26fab9af2650e2c19b32996a535f。使用 Apktool 2.10.0 解包官方 APK,将设计手工移植到 Smali。
使用 Apktool 内置 aapt2 重建资源和 8 个 DEX。
使用 Android Build Tools 33.0.2
zipalign对齐。使用仓库外本地测试证书签名,并验证 APK Signature Scheme v1、v2、v3。
安装到 RMX5200 后,核对手机内
base.apk与附件 SHA-256 完全一致。工件信息
Manifest 未新增
uses-permission,无INTERNET权限。新增的是同包 instrumentation;运行时通过 Shizuku 临时委派MODIFY_PHONE_STATE。该 APK 是按照 PR 设计手工移植的 patched-repack 测试件,不是 Gradle 从当前 Kotlin 源码直接生成的 APK,也不能替代源码编译验证。可审查实现以本 PR 的源码差异为准。
安装注意
测试证书与官方 APK 不同,不能直接覆盖官方版本。需要先卸载旧签名版本(会清除 Nrfr 应用数据),安装后重新授予 Shizuku 权限。卸载应用不等于清除系统侧已经生效的 CarrierConfig override;返回官方版时也需要先卸载测试包,再安装官方签名 APK。本附件不是官方发布,不建议普通用户作为长期版本使用。
本测试件派生自采用 Apache License 2.0 的 Ackites/Nrfr。修改源码见
ae849997c98a26fab9af2650e2c19b32996a535f,许可证见 LICENSE。该测试发布不代表上游认可或背书。已知限制
Reviewer checklist
ICarrierConfigLoader路径是否保持不变;PersistableBundle是否在入队前复制;MODIFY_PHONE_STATE;persistent=false;IInstrumentationWatcher或目标键回读;再次感谢 @a5533348 在 #122 中提供新版 Android instrumentation 回退思路与初始实现。本 PR 的加固和真机验证均建立在其工作之上。