(FFOS Gecko & Gaia) OTA - 关键的apply
这篇分析已经是尾声了,在UpdatePrompt中,调用了UpdateService的applyOsUpdate函数。
1. UpdateService.applyOsUpdate
这个函数很简单,就是获取到update.zip以后,调用recovery service去完成更新。
applyOsUpdate: function AUS_applyOsUpdate(aUpdate) { if (!aUpdate.isOSUpdate || aUpdate.state != STATE_APPLIED) { aUpdate.statusText = "fota-state-error"; throw Cr.NS_ERROR_FAILURE; } aUpdate.QueryInterface(Ci.nsIWritablePropertyBag); let osApplyToDir = aUpdate.getProperty("osApplyToDir"); if (!osApplyToDir) { LOG("UpdateService:applyOsUpdate - Error: osApplyToDir is not defined" + "in the nsIUpdate!"); pingStateAndStatusCodes(aUpdate, false, STATE_FAILED + ": " + FOTA_FILE_OPERATION_ERROR); handleUpdateFailure(aUpdate, FOTA_FILE_OPERATION_ERROR); return; } // 获取最终的update.zip let updateFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); updateFile.initWithPath(osApplyToDir + "/update.zip"); if (!updateFile.exists()) { LOG("UpdateService:applyOsUpdate - Error: OS update is not found at " + updateFile.path); pingStateAndStatusCodes(aUpdate, false, STATE_FAILED + ": " + FOTA_FILE_OPERATION_ERROR); handleUpdateFailure(aUpdate, FOTA_FILE_OPERATION_ERROR); return; } writeStatusFile(getUpdatesDir(), aUpdate.state = STATE_APPLIED_OS); LOG("UpdateService:applyOsUpdate - Rebooting into recovery to apply " + "FOTA update: " + updateFile.path); try { let recoveryService = Cc["@mozilla.org/recovery-service;1"] .getService(Ci.nsIRecoveryService); recoveryService.installFotaUpdate(updateFile.path); } catch (e) { LOG("UpdateService:applyOsUpdate - Error: Couldn't reboot into recovery" + " to apply FOTA update " + updateFile.path); pingStateAndStatusCodes(aUpdate, false, STATE_FAILED + ": " + FOTA_RECOVERY_ERROR); writeStatusFile(getUpdatesDir(), aUpdate.state = STATE_APPLIED); handleUpdateFailure(aUpdate, FOTA_RECOVERY_ERROR); } },
2. "@mozilla.org/recovery-service;1"
这个service就不在这里分析了,很简单,只是对librecovery.so的简单封装,熟悉android OTA的同学一看就懂。