diff options
-rw-r--r-- | common.h | 13 | ||||
-rw-r--r-- | install/install.cpp | 5 | ||||
-rw-r--r-- | otautil/include/otautil/logging.h | 2 | ||||
-rw-r--r-- | otautil/include/otautil/roots.h | 3 | ||||
-rw-r--r-- | otautil/logging.cpp | 17 | ||||
-rw-r--r-- | otautil/roots.cpp | 8 | ||||
-rw-r--r-- | recovery.cpp | 53 | ||||
-rw-r--r-- | recovery_main.cpp | 24 |
8 files changed, 60 insertions, 65 deletions
@@ -18,21 +18,8 @@ #include <string> -// Not using the command-line defined macro here because this header could be included by -// device-specific recovery libraries. We static assert the value consistency in recovery.cpp. -static constexpr int kRecoveryApiVersion = 3; - -class RecoveryUI; -struct selabel_handle; - -extern struct selabel_handle* sehandle; -extern RecoveryUI* ui; -extern bool has_cache; - // The current stage, e.g. "1/2". extern std::string stage; // The reason argument provided in "--reason=". extern const char* reason; - -bool is_ro_debuggable(); diff --git a/install/install.cpp b/install/install.cpp index 09b88392a..9d67b0105 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -60,7 +60,8 @@ using namespace std::chrono_literals; static constexpr int kRecoveryApiVersion = 3; -// Assert the version defined in code and in Android.mk are consistent. +// We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed +// into target_files.zip. Assert the version defined in code and in Android.mk are consistent. static_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery API versions."); // Default allocation of progress bar segments to operations @@ -621,6 +622,8 @@ InstallResult InstallPackage(Package* package, const std::string_view package_id InstallResult result; std::vector<std::string> log_buffer; + ui->Print("Supported API: %d\n", kRecoveryApiVersion); + ui->Print("Finding update package...\n"); LOG(INFO) << "Update package id: " << package_id; if (!package) { diff --git a/otautil/include/otautil/logging.h b/otautil/include/otautil/logging.h index 608349785..4462eca6e 100644 --- a/otautil/include/otautil/logging.h +++ b/otautil/include/otautil/logging.h @@ -53,7 +53,7 @@ void rotate_logs(const char* last_log_file, const char* last_kmsg_file); void check_and_fclose(FILE* fp, const std::string& name); void copy_log_file_to_pmsg(const std::string& source, const std::string& destination); -void copy_logs(bool save_current_log, bool has_cache, const selabel_handle* sehandle); +void copy_logs(bool save_current_log); void reset_tmplog_offset(); void save_kernel_log(const char* destination); diff --git a/otautil/include/otautil/roots.h b/otautil/include/otautil/roots.h index 2ab3f4549..92ee756f0 100644 --- a/otautil/include/otautil/roots.h +++ b/otautil/include/otautil/roots.h @@ -53,3 +53,6 @@ int format_volume(const std::string& volume, const std::string& directory); // Ensure that all and only the volumes that packages expect to find // mounted (/tmp and /cache) are mounted. Returns 0 on success. int setup_install_mounts(); + +// Returns true if there is /cache in the volumes. +bool HasCache(); diff --git a/otautil/logging.cpp b/otautil/logging.cpp index 484f1150f..3db0e8ac2 100644 --- a/otautil/logging.cpp +++ b/otautil/logging.cpp @@ -178,9 +178,8 @@ void reset_tmplog_offset() { tmplog_offset = 0; } -static void copy_log_file(const std::string& source, const std::string& destination, bool append, - const selabel_handle* sehandle) { - FILE* dest_fp = fopen_path(destination, append ? "ae" : "we", sehandle); +static void copy_log_file(const std::string& source, const std::string& destination, bool append) { + FILE* dest_fp = fopen_path(destination, append ? "ae" : "we", logging_sehandle); if (dest_fp == nullptr) { PLOG(ERROR) << "Can't open " << destination; } else { @@ -203,7 +202,7 @@ static void copy_log_file(const std::string& source, const std::string& destinat } } -void copy_logs(bool save_current_log, bool has_cache, const selabel_handle* sehandle) { +void copy_logs(bool save_current_log) { // We only rotate and record the log of the current session if explicitly requested. This usually // happens after wipes, installation from BCB or menu selections. This is to avoid unnecessary // rotation (and possible deletion) of log files, if it does not do anything loggable. @@ -216,7 +215,7 @@ void copy_logs(bool save_current_log, bool has_cache, const selabel_handle* seha copy_log_file_to_pmsg(Paths::Get().temporary_install_file(), LAST_INSTALL_FILE); // We can do nothing for now if there's no /cache partition. - if (!has_cache) { + if (!HasCache()) { return; } @@ -225,9 +224,9 @@ void copy_logs(bool save_current_log, bool has_cache, const selabel_handle* seha rotate_logs(LAST_LOG_FILE, LAST_KMSG_FILE); // Copy logs to cache so the system can find out what happened. - copy_log_file(Paths::Get().temporary_log_file(), LOG_FILE, true, sehandle); - copy_log_file(Paths::Get().temporary_log_file(), LAST_LOG_FILE, false, sehandle); - copy_log_file(Paths::Get().temporary_install_file(), LAST_INSTALL_FILE, false, sehandle); + copy_log_file(Paths::Get().temporary_log_file(), LOG_FILE, true); + copy_log_file(Paths::Get().temporary_log_file(), LAST_LOG_FILE, false); + copy_log_file(Paths::Get().temporary_install_file(), LAST_INSTALL_FILE, false); save_kernel_log(LAST_KMSG_FILE); chmod(LOG_FILE, 0600); chown(LOG_FILE, AID_SYSTEM, AID_SYSTEM); @@ -319,7 +318,7 @@ bool RestoreLogFilesAfterFormat(const std::vector<saved_log_file>& log_files) { // Reset the pointer so we copy from the beginning of the temp // log. reset_tmplog_offset(); - copy_logs(true /* save_current_log */, true /* has_cache */, logging_sehandle); + copy_logs(true /* save_current_log */); return true; } diff --git a/otautil/roots.cpp b/otautil/roots.cpp index a778e05ff..431551785 100644 --- a/otautil/roots.cpp +++ b/otautil/roots.cpp @@ -51,6 +51,8 @@ using android::fs_mgr::ReadDefaultFstab; static Fstab fstab; +constexpr const char* CACHE_ROOT = "/cache"; + void load_volume_table() { if (!ReadDefaultFstab(&fstab)) { LOG(ERROR) << "Failed to read default fstab"; @@ -275,3 +277,9 @@ int setup_install_mounts() { } return 0; } + +bool HasCache() { + CHECK(!fstab.empty()); + static bool has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr; + return has_cache; +} diff --git a/recovery.cpp b/recovery.cpp index 97ca0a504..b989b2465 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -69,10 +69,6 @@ static constexpr const char* LOCALE_FILE = "/cache/recovery/last_locale"; static constexpr const char* CACHE_ROOT = "/cache"; -// We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed -// into target_files.zip. Assert the version defined in code and in Android.mk are consistent. -static_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery API versions."); - static bool save_current_log = false; std::string stage; const char* reason = nullptr; @@ -106,7 +102,7 @@ const char* reason = nullptr; * -- after this, rebooting will restart the erase -- * 5. erase_volume() reformats /data * 6. erase_volume() reformats /cache - * 7. finish_recovery() erases BCB + * 7. FinishRecovery() erases BCB * -- after this, rebooting will restart the main system -- * 8. main() calls reboot() to boot main system * @@ -118,25 +114,25 @@ const char* reason = nullptr; * -- after this, rebooting will attempt to reinstall the update -- * 5. InstallPackage() attempts to install the update * NOTE: the package install must itself be restartable from any point - * 6. finish_recovery() erases BCB + * 6. FinishRecovery() erases BCB * -- after this, rebooting will (try to) restart the main system -- * 7. ** if install failed ** * 7a. PromptAndWait() shows an error icon and waits for the user * 7b. the user reboots (pulling the battery, etc) into the main system */ -bool is_ro_debuggable() { - return android::base::GetBoolProperty("ro.debuggable", false); +static bool IsRoDebuggable() { + return android::base::GetBoolProperty("ro.debuggable", false); } // Clear the recovery command and prepare to boot a (hopefully working) system, // copy our log file to cache as well (for the system to read). This function is // idempotent: call it as many times as you like. -static void finish_recovery() { +static void FinishRecovery(RecoveryUI* ui) { std::string locale = ui->GetLocale(); // Save the locale to cache, so if recovery is next started up without a '--locale' argument // (e.g., directly from the bootloader) it will use the last-known locale. - if (!locale.empty() && has_cache) { + if (!locale.empty() && HasCache()) { LOG(INFO) << "Saving locale \"" << locale << "\""; if (ensure_path_mounted(LOCALE_FILE) != 0) { LOG(ERROR) << "Failed to mount " << LOCALE_FILE; @@ -145,7 +141,7 @@ static void finish_recovery() { } } - copy_logs(save_current_log, has_cache, sehandle); + copy_logs(save_current_log); // Reset to normal system boot so recovery won't cycle indefinitely. std::string err; @@ -154,7 +150,7 @@ static void finish_recovery() { } // Remove the command file, so recovery won't repeat indefinitely. - if (has_cache) { + if (HasCache()) { if (ensure_path_mounted(COMMAND_FILE) != 0 || (unlink(COMMAND_FILE) && errno != ENOENT)) { LOG(WARNING) << "Can't unlink " << COMMAND_FILE; } @@ -168,7 +164,7 @@ static bool yes_no(Device* device, const char* question1, const char* question2) std::vector<std::string> headers{ question1, question2 }; std::vector<std::string> items{ " No", " Yes" }; - size_t chosen_item = ui->ShowMenu( + size_t chosen_item = device->GetUI()->ShowMenu( headers, items, 0, true, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); return (chosen_item == 1); @@ -178,7 +174,7 @@ static bool ask_to_wipe_data(Device* device) { std::vector<std::string> headers{ "Wipe all user data?", " THIS CAN NOT BE UNDONE!" }; std::vector<std::string> items{ " Cancel", " Factory data reset" }; - size_t chosen_item = ui->ShowPromptWipeDataConfirmationMenu( + size_t chosen_item = device->GetUI()->ShowPromptWipeDataConfirmationMenu( headers, items, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); @@ -200,7 +196,7 @@ static InstallResult prompt_and_wipe_data(Device* device) { }; // clang-format on for (;;) { - size_t chosen_item = ui->ShowPromptWipeDataMenu( + size_t chosen_item = device->GetUI()->ShowPromptWipeDataMenu( wipe_data_menu_headers, wipe_data_menu_items, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); // If ShowMenu() returned RecoveryUI::KeyError::INTERRUPTED, WaitKey() was interrupted. @@ -224,7 +220,7 @@ static InstallResult prompt_and_wipe_data(Device* device) { static void choose_recovery_file(Device* device) { std::vector<std::string> entries; - if (has_cache) { + if (HasCache()) { for (int i = 0; i < KEEP_LOG_COUNT; i++) { auto add_to_entries = [&](const char* filename) { std::string log_file(filename); @@ -258,7 +254,7 @@ static void choose_recovery_file(Device* device) { size_t chosen_item = 0; while (true) { - chosen_item = ui->ShowMenu( + chosen_item = device->GetUI()->ShowMenu( headers, entries, chosen_item, true, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); @@ -268,11 +264,11 @@ static void choose_recovery_file(Device* device) { } if (entries[chosen_item] == "Back") break; - ui->ShowFile(entries[chosen_item]); + device->GetUI()->ShowFile(entries[chosen_item]); } } -static void run_graphics_test() { +static void run_graphics_test(RecoveryUI* ui) { // Switch to graphics screen. ui->ShowText(false); @@ -319,8 +315,9 @@ static void run_graphics_test() { // as REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER. Returning NO_ACTION means to take the default, which // is to reboot or shutdown depending on if the --shutdown_after flag was passed to recovery. static Device::BuiltinAction PromptAndWait(Device* device, InstallResult status) { + auto ui = device->GetUI(); for (;;) { - finish_recovery(); + FinishRecovery(ui); switch (status) { case INSTALL_SUCCESS: case INSTALL_NONE: @@ -421,7 +418,7 @@ static Device::BuiltinAction PromptAndWait(Device* device, InstallResult status) if (status != INSTALL_SUCCESS) { ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); - copy_logs(save_current_log, has_cache, sehandle); + copy_logs(save_current_log); } else if (!ui->IsTextVisible()) { return Device::NO_ACTION; // reboot if logs aren't visible } @@ -433,7 +430,7 @@ static Device::BuiltinAction PromptAndWait(Device* device, InstallResult status) break; case Device::RUN_GRAPHICS_TEST: - run_graphics_test(); + run_graphics_test(ui); break; case Device::RUN_LOCALE_TEST: { @@ -680,6 +677,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri printf("stage is [%s]\n", stage.c_str()); printf("reason is [%s]\n", reason); + auto ui = device->GetUI(); + // Set background string to "installing security update" for security update, // otherwise set it to "installing system update". ui->SetSystemUpdateText(security_update); @@ -706,8 +705,6 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri property_list(print_property, nullptr); printf("\n"); - ui->Print("Supported API: %d\n", kRecoveryApiVersion); - InstallResult status = INSTALL_SUCCESS; // next_action indicates the next target to reboot into upon finishing the install. It could be // overridden to a different reboot target per user request. @@ -768,7 +765,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri // RETRY_LIMIT times before we abandon this OTA update. static constexpr int RETRY_LIMIT = 4; if (status == INSTALL_RETRY && retry_count < RETRY_LIMIT) { - copy_logs(save_current_log, has_cache, sehandle); + copy_logs(save_current_log); retry_count += 1; set_retry_bootloader_message(retry_count, args); // Print retry count on screen. @@ -786,7 +783,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri // If this is an eng or userdebug build, then automatically // turn the text display on if the script fails so the error // message is visible. - if (is_ro_debuggable()) { + if (IsRoDebuggable()) { ui->ShowText(true); } } @@ -843,7 +840,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri // If this is an eng or userdebug build, automatically turn on the text display if no command // is specified. Note that this should be called before setting the background to avoid // flickering the background image. - if (is_ro_debuggable()) { + if (IsRoDebuggable()) { ui->ShowText(true); } status = INSTALL_NONE; // No command specified @@ -876,7 +873,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri } // Save logs and clean up before rebooting or shutting down. - finish_recovery(); + FinishRecovery(ui); return next_action; } diff --git a/recovery_main.cpp b/recovery_main.cpp index 7fbdf9a08..f0d75ee10 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -63,12 +63,11 @@ static constexpr const char* COMMAND_FILE = "/cache/recovery/command"; static constexpr const char* LOCALE_FILE = "/cache/recovery/last_locale"; -static constexpr const char* CACHE_ROOT = "/cache"; +static RecoveryUI* ui = nullptr; -bool has_cache = false; - -RecoveryUI* ui = nullptr; -struct selabel_handle* sehandle; +static bool IsRoDebuggable() { + return android::base::GetBoolProperty("ro.debuggable", false); +} static void UiLogger(android::base::LogId /* id */, android::base::LogSeverity severity, const char* /* tag */, const char* /* file */, unsigned int /* line */, @@ -131,7 +130,7 @@ static std::vector<std::string> get_args(const int argc, char** const argv) { } // --- if that doesn't work, try the command file (if we have /cache). - if (args.size() == 1 && has_cache) { + if (args.size() == 1 && HasCache()) { std::string content; if (ensure_path_mounted(COMMAND_FILE) == 0 && android::base::ReadFileToString(COMMAND_FILE, &content)) { @@ -148,7 +147,7 @@ static std::vector<std::string> get_args(const int argc, char** const argv) { // Write the arguments (excluding the filename in args[0]) back into the // bootloader control block. So the device will always boot into recovery to - // finish the pending work, until finish_recovery() is called. + // finish the pending work, until FinishRecovery() is called. std::vector<std::string> options(args.cbegin() + 1, args.cend()); if (!update_bootloader_message(options, &err)) { LOG(ERROR) << "Failed to set BCB message: " << err; @@ -331,7 +330,6 @@ int main(int argc, char** argv) { redirect_stdio(Paths::Get().temporary_log_file().c_str()); load_volume_table(); - has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr; std::vector<std::string> args = get_args(argc, argv); auto args_to_parse = StringVectorToNullTerminatedArray(args); @@ -370,7 +368,7 @@ int main(int argc, char** argv) { optind = 1; if (locale.empty()) { - if (has_cache) { + if (HasCache()) { locale = load_locale_from_cache(); } @@ -416,7 +414,7 @@ int main(int argc, char** argv) { } ui = device->GetUI(); - if (!has_cache) { + if (!HasCache()) { device->RemoveMenuItemForAction(Device::WIPE_CACHE); } @@ -424,7 +422,7 @@ int main(int argc, char** argv) { device->RemoveMenuItemForAction(Device::ENTER_FASTBOOT); } - if (!is_ro_debuggable()) { + if (!IsRoDebuggable()) { device->RemoveMenuItemForAction(Device::ENTER_RESCUE); } @@ -434,7 +432,7 @@ int main(int argc, char** argv) { LOG(INFO) << "Starting recovery (pid " << getpid() << ") on " << ctime(&start); LOG(INFO) << "locale is [" << locale << "]"; - sehandle = selinux_android_file_context_handle(); + auto sehandle = selinux_android_file_context_handle(); selinux_android_set_sehandle(sehandle); if (!sehandle) { ui->Print("Warning: No file_contexts\n"); @@ -447,7 +445,7 @@ int main(int argc, char** argv) { listener_thread.detach(); while (true) { - std::string usb_config = fastboot ? "fastboot" : is_ro_debuggable() ? "adb" : "none"; + std::string usb_config = fastboot ? "fastboot" : IsRoDebuggable() ? "adb" : "none"; std::string usb_state = android::base::GetProperty("sys.usb.state", "none"); if (usb_config != usb_state) { if (!SetUsbConfig("none")) { |