本文主要介绍Framework层Recovery相关内容,包括Recovery服务启动,升级包验证、解密、安装,恢复出厂等流程。
1.启动RecoverySystemService
1.1 SystemServer启动RecoverySystemService
作为系统启动关键服务,需要在SystemServer的startBootstrapServices中通过SystemServiceManager来启动RecoverySystemService。
1 | //frameworks/base/services/java/com/android/server/SystemServer.java |
1.2 RecoverySystemService的启动
RecoverySystemService继承自SystemService,将通过ServiceManagerService回调进入onStart方法。
1 | //frameworks/base/services/core/java/com/android/server/RecoverySystemService.java |
1 | //frameworks/base/services/core/java/com/android/server/RecoverySystemService.java |
在onStart方法中调用publishBinderService方法来发布RecoverySystemService这一Binder服务。即将该服务加入到ServiceManager列表中。
1 | //frameworks/base/services/core/java/com/android/server/SystemService.java |
2. RecoverySystem中系统升级相关API
2.1 调用VerifyPackage方法验证升级包签名
调用verifyPackage验证升级包签名。
一旦设备重启到recovery,安装程序也会单独验证程序包。仅当包成功验证后,此函数才会返回,否则会引发异常。验证包可能需要很长时间,故不应从UI线程调用此函数。在此函数正在进行时中断线程将导致抛出SecurityException。
deviceCertsZipFile:/system/etc/security/otacerts.zip
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
2.2 调用processPackage方法解密升级包
调用processPackage,使用uncrypt处理给定的升级包。如果升级包不在data分区上,则为no-op。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
调用uncrypt,通过Binder与RecoverySystemService通信以触发解密。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
1 | //frameworks/base/services/core/java/com/android/server/RecoverySystemService.java |
调用checkAndWaitForUncryptService,检查是否有init服务一直在运行。若有则不能立马启动一个uncrypt/setup-bcb/clear-bcb服务。否则它可能会造成socket通信异常,因为init正在服务启动、退出时创建、删除这些socket。
1 | //frameworks/base/services/core/java/com/android/server/RecoverySystemService.java |
2.3 调用installPackage方法安装升级包
调用installPackage,重启设备以安装给定的升级包。其中升级包必须存于recovery中可以挂载的分区中,如cache、data分区。如果升级包尚未处理(即未加密),则需要设置UNCRYPT_PACKAGE_FILE并删除BLOCK_MAP_FILE以便重启期间触发解密。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
调用setupBcb,通过Binder与RecoverySystemService通信以设置BCB。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
1 | //frameworks/base/services/core/java/com/android/server/RecoverySystemService.java |
2.4 调用cancelScheduledUpdate方法取消计划性升级
调用cancelScheduledUpdate,通过清除BCB来取消任何计划性升级。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
1 | //frameworks/base/services/core/java/com/android/server/RecoverySystemService.java |
2.5 调用scheduleUpdateOnBoot方法设定升级计划
调用scheduleUpdateOnBoot,以计划在下次启动时安装给定的升级包。调用者需确保必要时已处理(未加密)升级包。在BCB中设置命令,该命令将由bootloader和recovery image读取。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
3.RecoverySystem中恢复出厂相关API
3.1 调用rebootWipeUserData方法清除用户数据
调用rebootWipeUserData,重启设备擦除用户数据(包括data和cache分区)。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
调用wipeEuiccData,擦除Euicc数据。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
调用bootCommand,以便加入参数重启进入recovery完成相关操作。
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
1 | //frameworks/base/services/core/java/com/android/server/RecoverySystemService.java |
3.2 调用rebootPromptAndWipeUserData方法提示、擦除用户数据
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
3.3 调用rebootWipeCache方法擦除cache分区
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
3.4 调用rebootWipeAb方法擦除A/B
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |
3.5 调用handleAftermath清除recovery相关文件
1 | //frameworks/base/core/java/android/os/RecoverySystem.java |