1、Fota升级方式:
整包\差分包,网络\SD卡
差分包:原理是根据算法把新旧两个版本之间的差别做成一个软件包
2、Fota应用升级的调用接口及reboot update的流程:
1、FotaAPK:
(1)、fotaApk定时检查FOTA服务器是否有更新;如有更新,服务器发送消息(包括更新包URL,以及关于该更新包的描述)通知设备。
(2)更新程序下载升级包到 cache 或者 data 分区,并验证升级包的签名证书(证书位于/system/etc/security/otacerts.zip),验证通过后,通知用户准备安装。(验证:verifyPackage(FilepackageFile, ProgressListener listener, File deviceCertsZipFile))
(3)FotaAPK调用:/frameworks/base/core/java/android/os/recoverySystem.java
RecoverySystem.installPackage(mContext,mFile)方法重启手机进入Recovery模式。在recovery模式下,Installer会先获取升级包,如果该包没有被处理则设置UNCRYPT_PACKAGE_FILE(文件路径:/cache/recovery/uncrypt_file)并且删除BLOCK_MAP_FILE。
注:删除BLOCK_MAP_FILE的原因是需要在reboot时触发uncrypt.
(4)调用setupBcb :将command写入BCB (bootloader control block).
command ="--update_package="+filename + "\n""--locale="+ Locale.getDefault().toString()+ "\n";
如果是securityUpdate :
Command="--update_package=" +filename + "\n""--locale="+ Locale.getDefault().toString()+ "\n"+"--security\n"
rs.setupBcb(command)
注意:如果安装包在/data目录下,以/cache/recovery/block.map代替升级包名字。
(5)调用PowerManager触发REBOOT_RCOVERY。
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
pm.reboot(PowerManager.REBOOT_RECOVERY_UPDATE);
(6)reboot流程:
(6.1)/frameworks/base/core/java/android/os/PowerManager.java
mService是PowerManagerService的实例。
public void reboot(String reason) {
try {
mService.reboot(false, reason, true);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public voidreboot(boolean confirm, String reason, boolean wait) {
……
shutdownOrRebootInternal(HALT_MODE_REBOOT,confirm, reason, wait);
……
}
最终会调用ShutdownThread.reboot(mContext,reason, confirm);
(6.2)/frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
public staticvoid reboot(final Context context, String reason, boolean confirm) {
mReboot = true;
mRebootSafeMode = false;
mRebootHasProgressBar = false;
mReason = reason;
……
shutdownInner(context, confirm);
…….
}
然后shutdownInner(,)会调用beginShutdownSequence(context);
{//根据不同关机原因进行progressdialog设置和关机动画设置
//实例化一个ShutdownThread()调用run()方法。
……sInstance.start();}
检查block.map是否存在,如果存在会调用
Private void running(){
…..
rebootOrShutdown(mContext,mReboot, mReason);
…..}
不存在则进入uncrypt()。
rebootOrShutdown会调回PowerManagerService中的lowLevelReboot()
//设置系统属性就传给Kernel进入reboot了
public static void lowLevelReboot(Stringreason){
…..
if(reason.equals(PowerManager.REBOOT_RECOVERY)
||reason.equals(PowerManager.REBOOT_RECOVERY_UPDATE)) {
SystemProperties.set("sys.powerctl","reboot,recovery");
} else {
SystemProperties.set("sys.powerctl", "reboot," +reason);
}
…..
}