上篇文章记录了通过 Rom 自带的固件升级功能,结合无障碍服务进行自动点击,来实现了 Rom 的自动升级。OTA 包下载完成后,若要更新,需要重启一次设备。无障碍自动点击,也会出现弹窗一闪而过的异象。另外放置在存储卡根目录的 update.zip 不太好管理,比如有多个版本的 Rom 升级等等。于是研究了 Rom 的相关源码,终于有所收获,记录一下优化方案。
在上文中,我抓到升级弹窗的包名为android.rockchip.update.service
,于是搜索对应包名下面的类,结果令我大跌眼镜:没有任何结果。继续搜索android.rockchip.update.service/android.rockchip.update.service.NotifyDeleteActivity
,也是没有任何结果。这就非常奇怪了,我已经下载了刷机用的 Android 系统源码了,为什么搜不到相关类呢?后面看到源码工程里,还有许多的 jar 包文件,可能就在这些 jar 包中了吧?
工程实在是太大了,50G 的空间都不够,给我电脑磁盘都干满了,申请了更换更大空间的电脑,才能继续研究。这也算是第一次完整接触一个 Android 系统源码,研究起来还是挺费劲的。还好我的目的很清晰:找到系统 OTA 升级的代码。
弹窗入口无法查找,就只能找可能的相关类了。于是搜索RecoverySystem.installPackage
,此方法虽然在上文中使用失败,但是仍然可以作为一个入口进行尝试。果然找到一个类:NonAbUpdateInstaller
。代码如下:
1 | package com.android.server.devicepolicy; |
继承自UpdateInstaller
,代码如下:
1 | package com.android.server.devicepolicy; |
可以看到代码非常简单:将 OTA 文件拷贝到 /data/ota_package 目录下,通过File.createTempFile
生成一个 updateXXXXXX.zip 的临时文件,然后调用RecoverySystem.installPackage
传入这个临时文件,就可以进行 OTA 升级了。
于是我也按照这个方案,重新改写了 RomUpdater 类,如下:
1 | object RomUpdater { |
我将代码拷贝过来,然后把 OTA 文件复制到这个 File 中,最后调用RecoverySystem.installPackage
,竟然真的升级成功了!敢情这个方法若要能成功进行升级,还必须将 OTA 文件放到 /data/ota_package 目录下。
后面为了方便管理,我尝试在此目录下,通过 new File 的形式,传入固定的文件名,比如 update20250711.zip 这样,但是调试的时候发现文件拷贝的时候,每次只有 4096 个字节就停止了,导致进行升级时,出现错误。而恢复成File.createTempFile
就一切正常,实在是摸不着头脑。
但也不影响整体,通过这样的优化方案,省去了重启设备这个多余的步骤,另外也不会出现一闪而过的弹窗,相比上文的方案要好上不少。