標籤:
這篇分析已經是尾聲了,在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的同學一看就懂。
(FFOS Gecko & Gaia) OTA - 關鍵的apply