OPPO Watch X3 Mini 表盘魔改过程记录

OPPO Watch X3 Mini 表盘魔改过程记录

💡 原文中文,约6600字,阅读约需16分钟。
📝

内容提要

作者在OPPO Watch X3 Mini上修改“明晰组件”表盘:该表盘为engine表盘zip包,主屏由manifest.json和images资源渲染,抬腕/AOD由MCU二进制style0.bin渲染,需两套都改。作者将日期、星期、秒数由灰色改为白色,重绘WebP数字精灵和MCU预览图,并通过等长重打包与1ms轮询watcher在手机同步瞬间原子替换zip,成功装回手表。局限是MCU版式无编译器,只能改色。

🔎

延伸解读

双渲染路径:改表盘必须两套资源都动

文章揭示「明晰组件」表盘并非普通 APK,而是 engine 表盘 zip 包,主屏由 manifest.json 和 images 资源经主 SoC 渲染,抬腕/AOD 则由低功耗 MCU 的 style0.bin 渲染。只改 manifest.json 会出现解锁后白色、抬腕仍灰色的割裂现象。这提醒修改者:任何视觉改动都需同步处理两套资源,否则体验不一致。

安装校验绕过:在同步瞬间原子替换

手表 Launcher 的 EngineWfProvider 对写入 zip 有包名和证书校验,adb 或第三方 App 无法直接安装。作者转而利用手机 OPPO 健康同步时先写临时 zip 再读取的窗口,用 1ms 轮询 watcher 在文件创建瞬间以原子 rename 覆盖。关键细节是保持 zip 字节数一致并置于同一文件系统,否则会触发大小检查或跨设备链接错误。

MCU 版式修改的硬限制

主屏版式在 manifest.json 中改起来简单,但抬腕/AOD 的 style0.bin 是编译后的二进制显示列表,没有公开的编译器或反编译器。手工改颜色可行,改坐标、字号或文本结构成本极高。因此作者只改颜色、保持版式原样,以确保主屏与 AOD 一致。若想深度定制 AOD 版式,目前缺乏可行工具链。

❓

Q&A

OPPO Watch X3 Mini 的「明晰组件」表盘为什么不是 APK?它的真实格式是什么?

「明晰组件」表盘在 pm list packages 和 dumpsys package 中找不到,因为它不是独立 APK,而是 OPPO 的 engine 表盘 zip 包,包名为 com.heytap.wearable.enginewf.O20250310114637290,引擎为 com.heytap.wearable.uiengine。包内包含 images/、manifest.json、infos.json、project.json 和 mcu/bin/ 等资源。

修改表盘颜色时,为什么只改 manifest.json 会导致抬腕亮屏还是灰色?

因为该表盘有两条渲染路径:主屏由主 SoC 上的 uiengine 使用 manifest.json 和 images/ 渲染;抬腕亮屏/AOD 由低功耗 MCU 使用预编译的 mcu/bin/style0.bin 和 mcu/bin/aod/style0.bin 渲染。只改 manifest.json 只会影响主屏,所以抬腕/AOD 仍是灰色,必须两套资源都改。

如何从手机中提取 OPPO 表盘的原始 zip 包?

手表上的资源在 Launcher 私有目录,普通 adb 读不到。手机 OPPO 健康下发前会把 zip 写到临时目录 /data/data/com.heytap.health/files/WatchFace/Temp/Pkg/<包名>.zip,同步完成后立即删除。因此需要在手机 root 下用脚本实时轮询复制该文件(例如每 0.2 秒检查新文件并复制到 /data/local/tmp/wfcap/),然后在 OPPO 健康里删除并重新下载表盘,同步后从 wfcap 目录取出 zip。

具体如何将日期、星期和秒数从灰色改成白色?

主屏:在 manifest.json 中将颜色值 #FF7D7D7D 替换为 #FFFFFFFF(共 4 处);秒数是 WebP 数字精灵,需用 PIL 将非透明像素重绘为白色并保留 alpha。MCU/AOD:在 mcu/bin/style0.bin 和 mcu/bin/aod/style0.bin 中将字节序列 \x7d\x7d\x7d\xff 替换为 \xff\xff\xff\xff;mcu/bin/preview.bin 是 12 字节头加 PNG,重绘 PNG 灰色像素后需更新头中的长度字段;预览图 preview.png 和 preview_small.png 也需同样重绘。

为什么不能直接通过 adb 安装修改后的表盘?正确的安装方法是什么?

手表的 Launcher 有一个 EngineWfProvider,安装表盘需向其写入 zip,但写入口校验调用方必须是 OPPO 表盘商店(包名 com.heytap.wearable.themestore)且证书 SHA-256 匹配,adb shell 或第三方 App 都会被拒绝。正确方法是在手机同步给手表之前替换 zip:用 1ms 轮询的 watcher 在手机端临时文件出现时,将等长重打包的改色包原子 rename 覆盖到目标路径,这样后续按路径打开的进程就会读到改色包。

替换 zip 时需要注意哪些技术细节?

有两个关键点:1) 等长:手机/手表会 stat 文件大小,需让改色包和原包字节数完全一致,可用最高压缩级别重打包并用 zip comment 补齐到原大小(本例 341427 字节);2) 同文件系统:临时文件必须放在目标目录内再 ATOMIC_MOVE,否则会报 Cross-device link 错误。此外,watcher 需每 1ms 检查目标文件是否存在,出现时复制源包到目标目录内的 .wfrepl.tmp 再原子移动覆盖。

这次修改有哪些局限性?为什么只改了颜色而没有改版式?

主屏版式在 manifest.json 中修改很简单,但抬腕/AOD 使用的 MCU style0.bin 是编译后的二进制显示列表,没有公开的编译器/反编译器,无法从 manifest.json 重新生成。手工改颜色可行,但改坐标、字号、文本结构成本很高,且只改主屏会导致主屏和 AOD 版式不一致。因此本次只改了颜色,版式保持原样,确保两边一致。

🏷️

标签

➡️

继续阅读