Loading install/adb_install.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -90,11 +90,12 @@ static bool WriteStatusToFd(MinadbdCommandStatus status, int fd) { // Installs the package from FUSE. Returns the installation result and whether it should continue // waiting for new commands. static auto AdbInstallPackageHandler(RecoveryUI* ui, InstallResult* result) { static auto AdbInstallPackageHandler(Device* device, InstallResult* result) { // How long (in seconds) we wait for the package path to be ready. It doesn't need to be too long // because the minadbd service has already issued an install command. FUSE_SIDELOAD_HOST_PATHNAME // will start to exist once the host connects and starts serving a package. Poll for its // appearance. (Note that inotify doesn't work with FUSE.) auto ui = device->GetUI(); constexpr int ADB_INSTALL_TIMEOUT = 15; bool should_continue = true; *result = INSTALL_ERROR; Loading @@ -114,7 +115,7 @@ static auto AdbInstallPackageHandler(RecoveryUI* ui, InstallResult* result) { auto package = Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME, std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1)); *result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0, ui); *result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0, device); break; } Loading Loading @@ -348,7 +349,7 @@ InstallResult ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinActi InstallResult install_result = INSTALL_ERROR; std::map<MinadbdCommand, CommandFunction> command_map{ { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, ui, &install_result) }, { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, device, &install_result) }, { MinadbdCommand::kRebootAndroid, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootAndroid, &install_result, reboot_action) }, { MinadbdCommand::kRebootBootloader, Loading install/fuse_install.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -146,10 +146,11 @@ static bool StartInstallPackageFuse(std::string_view path) { return run_fuse_sideload(std::move(fuse_data_provider)) == 0; } InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui) { InstallResult InstallWithFuseFromPath(std::string_view path, Device* device) { // We used to use fuse in a thread as opposed to a process. Since accessing // through fuse involves going from kernel to userspace to kernel, it leads // to deadlock when a page fault occurs. (Bug: 26313124) auto ui = device->GetUI(); pid_t child; if ((child = fork()) == 0) { bool status = StartInstallPackageFuse(path); Loading Loading @@ -183,8 +184,8 @@ InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui) { auto package = Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME, std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1)); result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0 /* retry_count */, ui); result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0 /* retry_count */, device); break; } Loading Loading @@ -226,7 +227,7 @@ InstallResult ApplyFromSdcard(Device* device) { ui->Print("\n-- Install %s ...\n", path.c_str()); SetSdcardUpdateBootloaderMessage(); auto result = InstallWithFuseFromPath(path, ui); auto result = InstallWithFuseFromPath(path, device); ensure_path_unmounted(SDCARD_ROOT); return result; } install/include/install/fuse_install.h +1 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,6 @@ // Starts FUSE with the package from |path| as the data source. And installs the package from // |FUSE_SIDELOAD_HOST_PATHNAME|. The |path| can point to the location of a package zip file or a // block map file with the prefix '@'; e.g. /sdcard/package.zip, @/cache/recovery/block.map. InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui); InstallResult InstallWithFuseFromPath(std::string_view path, Device* device); InstallResult ApplyFromSdcard(Device* device); install/include/install/install.h +3 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <ziparchive/zip_archive.h> #include "otautil/package.h" #include "recovery_ui/device.h" #include "recovery_ui/ui.h" enum InstallResult { Loading @@ -49,7 +50,8 @@ enum class OtaType { // cache partition after a successful installation if |should_wipe_cache| is true or an updater // command asks to wipe the cache. InstallResult InstallPackage(Package* package, const std::string_view package_id, bool should_wipe_cache, int retry_count, RecoveryUI* ui); bool should_wipe_cache, int retry_count, Device* ui); // Verifies the package by ota keys. Returns true if the package is verified successfully, // otherwise returns false. Loading install/install.cpp +38 −13 Original line number Diff line number Diff line Loading @@ -235,30 +235,41 @@ bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, Ot return true; } bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd, std::vector<std::string>* cmd) { CHECK(cmd != nullptr); static std::string ExtractPayloadProperties(ZipArchiveHandle zip) { // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset // in the zip file. 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; return {}; } 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; return {}; } std::vector<uint8_t> payload_properties(properties_entry_length); std::string payload_properties(properties_entry_length, '\0'); int32_t err = ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length); ExtractToMemory(zip, &properties_entry, reinterpret_cast<uint8_t*>(payload_properties.data()), properties_entry_length); if (err != 0) { LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err); return {}; } return payload_properties; } bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd, std::vector<std::string>* cmd) { CHECK(cmd != nullptr); // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset // in the zip file. const auto payload_properties = ExtractPayloadProperties(zip); if (payload_properties.empty()) { return false; } Loading Loading @@ -332,10 +343,20 @@ static void log_max_temperature(int* max_temperature, const std::atomic<bool>& l } } static bool PerformPowerwashIfRequired(ZipArchiveHandle zip, Device *device) { const auto payload_properties = ExtractPayloadProperties(zip); if (payload_properties.find("POWERWASH=1") != std::string::npos) { LOG(INFO) << "Payload properties has POWERWASH=1, wiping userdata..."; return WipeData(device, true); } return true; } // If the package contains an update binary, extract it and run it. static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, std::vector<std::string>* log_buffer, int retry_count, int* max_temperature, RecoveryUI* ui) { int* max_temperature, Device* device) { auto ui = device->GetUI(); std::map<std::string, std::string> metadata; auto zip = package->GetZipArchiveHandle(); if (!ReadMetadataFromPackage(zip, &metadata)) { Loading Loading @@ -530,13 +551,15 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, } else { LOG(FATAL) << "Invalid status code " << status; } PerformPowerwashIfRequired(zip, device); return INSTALL_SUCCESS; } static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache, std::vector<std::string>* log_buffer, int retry_count, int* max_temperature, RecoveryUI* ui) { int* max_temperature, Device* device) { auto ui = device->GetUI(); ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); // Give verification half the progress bar... ui->SetProgressType(RecoveryUI::DETERMINATE); Loading @@ -554,7 +577,8 @@ static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache, ui->Print("Retry attempt: %d\n", retry_count); } ui->SetEnableReboot(false); auto result = TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, ui); auto result = TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, device); ui->SetEnableReboot(true); ui->Print("\n"); Loading @@ -562,7 +586,8 @@ static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache, } InstallResult InstallPackage(Package* package, const std::string_view package_id, bool should_wipe_cache, int retry_count, RecoveryUI* ui) { bool should_wipe_cache, int retry_count, Device* device) { auto ui = device->GetUI(); auto start = std::chrono::system_clock::now(); int start_temperature = GetMaxValueFromThermalZone(); Loading @@ -584,7 +609,7 @@ InstallResult InstallPackage(Package* package, const std::string_view package_id } else { bool updater_wipe_cache = false; result = VerifyAndInstallPackage(package, &updater_wipe_cache, &log_buffer, retry_count, &max_temperature, ui); &max_temperature, device); should_wipe_cache = should_wipe_cache || updater_wipe_cache; } Loading Loading
install/adb_install.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -90,11 +90,12 @@ static bool WriteStatusToFd(MinadbdCommandStatus status, int fd) { // Installs the package from FUSE. Returns the installation result and whether it should continue // waiting for new commands. static auto AdbInstallPackageHandler(RecoveryUI* ui, InstallResult* result) { static auto AdbInstallPackageHandler(Device* device, InstallResult* result) { // How long (in seconds) we wait for the package path to be ready. It doesn't need to be too long // because the minadbd service has already issued an install command. FUSE_SIDELOAD_HOST_PATHNAME // will start to exist once the host connects and starts serving a package. Poll for its // appearance. (Note that inotify doesn't work with FUSE.) auto ui = device->GetUI(); constexpr int ADB_INSTALL_TIMEOUT = 15; bool should_continue = true; *result = INSTALL_ERROR; Loading @@ -114,7 +115,7 @@ static auto AdbInstallPackageHandler(RecoveryUI* ui, InstallResult* result) { auto package = Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME, std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1)); *result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0, ui); *result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0, device); break; } Loading Loading @@ -348,7 +349,7 @@ InstallResult ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinActi InstallResult install_result = INSTALL_ERROR; std::map<MinadbdCommand, CommandFunction> command_map{ { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, ui, &install_result) }, { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, device, &install_result) }, { MinadbdCommand::kRebootAndroid, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootAndroid, &install_result, reboot_action) }, { MinadbdCommand::kRebootBootloader, Loading
install/fuse_install.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -146,10 +146,11 @@ static bool StartInstallPackageFuse(std::string_view path) { return run_fuse_sideload(std::move(fuse_data_provider)) == 0; } InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui) { InstallResult InstallWithFuseFromPath(std::string_view path, Device* device) { // We used to use fuse in a thread as opposed to a process. Since accessing // through fuse involves going from kernel to userspace to kernel, it leads // to deadlock when a page fault occurs. (Bug: 26313124) auto ui = device->GetUI(); pid_t child; if ((child = fork()) == 0) { bool status = StartInstallPackageFuse(path); Loading Loading @@ -183,8 +184,8 @@ InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui) { auto package = Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME, std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1)); result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0 /* retry_count */, ui); result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0 /* retry_count */, device); break; } Loading Loading @@ -226,7 +227,7 @@ InstallResult ApplyFromSdcard(Device* device) { ui->Print("\n-- Install %s ...\n", path.c_str()); SetSdcardUpdateBootloaderMessage(); auto result = InstallWithFuseFromPath(path, ui); auto result = InstallWithFuseFromPath(path, device); ensure_path_unmounted(SDCARD_ROOT); return result; }
install/include/install/fuse_install.h +1 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,6 @@ // Starts FUSE with the package from |path| as the data source. And installs the package from // |FUSE_SIDELOAD_HOST_PATHNAME|. The |path| can point to the location of a package zip file or a // block map file with the prefix '@'; e.g. /sdcard/package.zip, @/cache/recovery/block.map. InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui); InstallResult InstallWithFuseFromPath(std::string_view path, Device* device); InstallResult ApplyFromSdcard(Device* device);
install/include/install/install.h +3 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <ziparchive/zip_archive.h> #include "otautil/package.h" #include "recovery_ui/device.h" #include "recovery_ui/ui.h" enum InstallResult { Loading @@ -49,7 +50,8 @@ enum class OtaType { // cache partition after a successful installation if |should_wipe_cache| is true or an updater // command asks to wipe the cache. InstallResult InstallPackage(Package* package, const std::string_view package_id, bool should_wipe_cache, int retry_count, RecoveryUI* ui); bool should_wipe_cache, int retry_count, Device* ui); // Verifies the package by ota keys. Returns true if the package is verified successfully, // otherwise returns false. Loading
install/install.cpp +38 −13 Original line number Diff line number Diff line Loading @@ -235,30 +235,41 @@ bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, Ot return true; } bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd, std::vector<std::string>* cmd) { CHECK(cmd != nullptr); static std::string ExtractPayloadProperties(ZipArchiveHandle zip) { // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset // in the zip file. 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; return {}; } 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; return {}; } std::vector<uint8_t> payload_properties(properties_entry_length); std::string payload_properties(properties_entry_length, '\0'); int32_t err = ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length); ExtractToMemory(zip, &properties_entry, reinterpret_cast<uint8_t*>(payload_properties.data()), properties_entry_length); if (err != 0) { LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err); return {}; } return payload_properties; } bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd, std::vector<std::string>* cmd) { CHECK(cmd != nullptr); // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset // in the zip file. const auto payload_properties = ExtractPayloadProperties(zip); if (payload_properties.empty()) { return false; } Loading Loading @@ -332,10 +343,20 @@ static void log_max_temperature(int* max_temperature, const std::atomic<bool>& l } } static bool PerformPowerwashIfRequired(ZipArchiveHandle zip, Device *device) { const auto payload_properties = ExtractPayloadProperties(zip); if (payload_properties.find("POWERWASH=1") != std::string::npos) { LOG(INFO) << "Payload properties has POWERWASH=1, wiping userdata..."; return WipeData(device, true); } return true; } // If the package contains an update binary, extract it and run it. static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, std::vector<std::string>* log_buffer, int retry_count, int* max_temperature, RecoveryUI* ui) { int* max_temperature, Device* device) { auto ui = device->GetUI(); std::map<std::string, std::string> metadata; auto zip = package->GetZipArchiveHandle(); if (!ReadMetadataFromPackage(zip, &metadata)) { Loading Loading @@ -530,13 +551,15 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, } else { LOG(FATAL) << "Invalid status code " << status; } PerformPowerwashIfRequired(zip, device); return INSTALL_SUCCESS; } static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache, std::vector<std::string>* log_buffer, int retry_count, int* max_temperature, RecoveryUI* ui) { int* max_temperature, Device* device) { auto ui = device->GetUI(); ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); // Give verification half the progress bar... ui->SetProgressType(RecoveryUI::DETERMINATE); Loading @@ -554,7 +577,8 @@ static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache, ui->Print("Retry attempt: %d\n", retry_count); } ui->SetEnableReboot(false); auto result = TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, ui); auto result = TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, device); ui->SetEnableReboot(true); ui->Print("\n"); Loading @@ -562,7 +586,8 @@ static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache, } InstallResult InstallPackage(Package* package, const std::string_view package_id, bool should_wipe_cache, int retry_count, RecoveryUI* ui) { bool should_wipe_cache, int retry_count, Device* device) { auto ui = device->GetUI(); auto start = std::chrono::system_clock::now(); int start_temperature = GetMaxValueFromThermalZone(); Loading @@ -584,7 +609,7 @@ InstallResult InstallPackage(Package* package, const std::string_view package_id } else { bool updater_wipe_cache = false; result = VerifyAndInstallPackage(package, &updater_wipe_cache, &log_buffer, retry_count, &max_temperature, ui); &max_temperature, device); should_wipe_cache = should_wipe_cache || updater_wipe_cache; } Loading