由於一開始是在trace原生的AOSP在recovery mode下是如何透過USB更新,因此這裡還是會紀錄一下native下是如何進行的,然後再說如何使用UpdateEngine這個Java layer的API來實作。
首先,recovery的主程式位在bootable/recovery,在recovery_main.cpp決定要進入fastboot還是recovery模式
auto ret = fastboot ? StartFastboot(device, args) : start_recovery(device, args);進到recovery.cpp
Device::BuiltinAction start_recovery(Device* device, const std::vector〈std::string〉& args) { ...略... status = InstallPackage(memory_package.get(), update_package, should_wipe_cache, retry_count, ui); ...略... }install.cpp進行驗證和安裝package
InstallResult InstallPackage(Package* package, const std::string_view package_id, bool should_wipe_cache, int retry_count, RecoveryUI* ui) { ...略... result = VerifyAndInstallPackage(package, &updater_wipe_cache, &log_buffer, retry_count, &max_temperature, ui); ...略... }static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache, std::vector<std::string>* log_buffer, int retry_count, int* max_temperature, RecoveryUI* ui) { ...略... auto result = TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, ui); ...略... }static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, std::vector〈std::string〉* log_buffer, int retry_count, int* max_temperature, RecoveryUI* ui) { ...略... //確認device是否支援ab update bool package_is_ab = get_value(metadata, "ota-type") == OtaTypeToString(OtaType::AB); bool device_supports_ab = android::base::GetBoolProperty("ro.build.ab_update", false); bool ab_device_supports_nonab = android::base::GetBoolProperty("ro.virtual_ab.allow_non_ab", false); bool device_only_supports_ab = device_supports_ab && !ab_device_supports_nonab; //查看目前security_patch版本,不允許做downgrade const auto current_spl = android::base::GetProperty("ro.build.version.security_patch", ""); if (ViolatesSPLDowngrade(zip, current_spl)) { LOG(ERROR) 〈〈 "Denying OTA because it's SPL downgrade"; return INSTALL_ERROR; } ...略... //如果是AB update就走SetUpAbUpdateCommands if (auto setup_result = package_is_ab ? SetUpAbUpdateCommands(package_path, zip, pipe_write.get(), &args) : SetUpNonAbUpdateCommands(package_path, zip, retry_count, pipe_write.get(), &args); !setup_result) { log_buffer-〉push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure)); return INSTALL_CORRUPT; } ...略... }bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd, std::vector〈std::string〉* cmd) { //取出payload properties static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt"; ZipEntry64 properties_entry; if (FindEntry(zip, AB_OTA_PAYLOAD_PROPERTIES, &properties_entry) != 0) { LOG(ERROR) 〈〈 "Failed to find " 〈〈 AB_OTA_PAYLOAD_PROPERTIES; return false; } auto properties_entry_length = properties_entry.uncompressed_length; if (properties_entry_length 〉 std::numeric_limits〈size_t〉::max()) { LOG(ERROR) 〈〈 "Failed to extract " 〈〈 AB_OTA_PAYLOAD_PROPERTIES 〈〈 " because's uncompressed size exceeds size of address space. " 〈〈 properties_entry_length; return false; } std::vector〈uint8_t〉 payload_properties(properties_entry_length); int32_t err = ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length); if (err != 0) { LOG(ERROR) 〈〈 "Failed to extract " 〈〈 AB_OTA_PAYLOAD_PROPERTIES 〈〈 ": " 〈〈 ErrorCodeString(err); return false; } //取出payload.bin在zip檔裡的offset位址 static constexpr const char* AB_OTA_PAYLOAD = "payload.bin"; ZipEntry64 payload_entry; if (FindEntry(zip, AB_OTA_PAYLOAD, &payload_entry) != 0) { LOG(ERROR) 〈〈 "Failed to find " 〈〈 AB_OTA_PAYLOAD; return false; } long payload_offset = payload_entry.offset; //執行update_engine_sideload指令進行AB update *cmd = { "/system/bin/update_engine_sideload", "--payload=file://" + package, android::base::StringPrintf("--offset=%ld", payload_offset), "--headers=" + std::string(payload_properties.begin(), payload_properties.end()), android::base::StringPrintf("--status_fd=%d", status_fd), }; }而主要在進行更新的主程式位在system/update_engine
Place your comment