diff options
-rw-r--r-- | otautil/include/otautil/boot_state.h (renamed from common.h) | 21 | ||||
-rw-r--r-- | recovery.cpp | 21 | ||||
-rw-r--r-- | recovery_main.cpp | 19 | ||||
-rw-r--r-- | recovery_ui/device.cpp | 13 | ||||
-rw-r--r-- | recovery_ui/include/recovery_ui/device.h | 10 |
5 files changed, 64 insertions, 20 deletions
diff --git a/common.h b/otautil/include/otautil/boot_state.h index 128a69d9b..6c877baef 100644 --- a/common.h +++ b/otautil/include/otautil/boot_state.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,20 @@ #pragma once #include <string> +#include <string_view> -// The current stage, e.g. "1/2". -extern std::string stage; +class BootState { + public: + BootState(std::string_view reason, std::string_view stage) : reason_(reason), stage_(stage) {} -// The reason argument provided in "--reason=". -extern const char* reason; + std::string reason() const { + return reason_; + } + std::string stage() const { + return stage_; + } + + private: + std::string reason_; // The reason argument provided in "--reason=". + std::string stage_; // The current stage, e.g. "1/2". +}; diff --git a/recovery.cpp b/recovery.cpp index b989b2465..4862dfccb 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -46,7 +46,6 @@ #include <ziparchive/zip_archive.h> #include "bootloader_message/bootloader_message.h" -#include "common.h" #include "fsck_unshare_blocks.h" #include "install/adb_install.h" #include "install/fuse_install.h" @@ -54,6 +53,7 @@ #include "install/package.h" #include "install/wipe_data.h" #include "install/wipe_device.h" +#include "otautil/boot_state.h" #include "otautil/error_code.h" #include "otautil/logging.h" #include "otautil/paths.h" @@ -70,8 +70,6 @@ static constexpr const char* LOCALE_FILE = "/cache/recovery/last_locale"; static constexpr const char* CACHE_ROOT = "/cache"; static bool save_current_log = false; -std::string stage; -const char* reason = nullptr; /* * The recovery tool communicates with the main system through /cache files. @@ -208,7 +206,8 @@ static InstallResult prompt_and_wipe_data(Device* device) { } if (ask_to_wipe_data(device)) { - bool convert_fbe = reason && strcmp(reason, "convert_fbe") == 0; + CHECK(device->GetReason().has_value()); + bool convert_fbe = device->GetReason().value() == "convert_fbe"; if (WipeData(device, convert_fbe)) { return INSTALL_SUCCESS; } else { @@ -635,12 +634,10 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri fsck_unshare_blocks = true; } else if (option == "install_with_fuse") { install_with_fuse = true; - } else if (option == "locale" || option == "fastboot") { + } else if (option == "locale" || option == "fastboot" || option == "reason") { // Handled in recovery_main.cpp } else if (option == "prompt_and_wipe_data") { should_prompt_and_wipe_data = true; - } else if (option == "reason") { - reason = optarg; } else if (option == "rescue") { rescue = true; } else if (option == "retry_count") { @@ -674,8 +671,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri } optind = 1; - printf("stage is [%s]\n", stage.c_str()); - printf("reason is [%s]\n", reason); + printf("stage is [%s]\n", device->GetStage().value_or("").c_str()); + printf("reason is [%s]\n", device->GetReason().value_or("").c_str()); auto ui = device->GetUI(); @@ -684,7 +681,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri ui->SetSystemUpdateText(security_update); int st_cur, st_max; - if (!stage.empty() && sscanf(stage.c_str(), "%d/%d", &st_cur, &st_max) == 2) { + if (!device->GetStage().has_value() && + sscanf(device->GetStage().value().c_str(), "%d/%d", &st_cur, &st_max) == 2) { ui->SetStage(st_cur, st_max); } @@ -790,7 +788,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri } } else if (should_wipe_data) { save_current_log = true; - bool convert_fbe = reason && strcmp(reason, "convert_fbe") == 0; + CHECK(device->GetReason().has_value()); + bool convert_fbe = device->GetReason().value() == "convert_fbe"; if (!WipeData(device, convert_fbe)) { status = INSTALL_ERROR; } diff --git a/recovery_main.cpp b/recovery_main.cpp index f0d75ee10..28197bf40 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -48,9 +48,9 @@ #include <selinux/label.h> #include <selinux/selinux.h> -#include "common.h" #include "fastboot/fastboot.h" #include "install/wipe_data.h" +#include "otautil/boot_state.h" #include "otautil/logging.h" #include "otautil/paths.h" #include "otautil/roots.h" @@ -80,11 +80,12 @@ static void UiLogger(android::base::LogId /* id */, android::base::LogSeverity s } } +// Parses the command line argument from various sources; and reads the stage field from BCB. // command line args come from, in decreasing precedence: // - the actual command line // - the bootloader control block (one per line, after "recovery") // - the contents of COMMAND_FILE (one per line) -static std::vector<std::string> get_args(const int argc, char** const argv) { +static std::vector<std::string> get_args(const int argc, char** const argv, std::string* stage) { CHECK_GT(argc, 0); bootloader_message boot = {}; @@ -94,7 +95,9 @@ static std::vector<std::string> get_args(const int argc, char** const argv) { // If fails, leave a zeroed bootloader_message. boot = {}; } - stage = std::string(boot.stage); + if (stage) { + *stage = std::string(boot.stage); + } std::string boot_command; if (boot.command[0] != 0) { @@ -331,12 +334,14 @@ int main(int argc, char** argv) { load_volume_table(); - std::vector<std::string> args = get_args(argc, argv); + std::string stage; + std::vector<std::string> args = get_args(argc, argv, &stage); auto args_to_parse = StringVectorToNullTerminatedArray(args); static constexpr struct option OPTIONS[] = { { "fastboot", no_argument, nullptr, 0 }, { "locale", required_argument, nullptr, 0 }, + { "reason", required_argument, nullptr, 0 }, { "show_text", no_argument, nullptr, 't' }, { nullptr, 0, nullptr, 0 }, }; @@ -344,6 +349,7 @@ int main(int argc, char** argv) { bool show_text = false; bool fastboot = false; std::string locale; + std::string reason; int arg; int option_index; @@ -357,6 +363,8 @@ int main(int argc, char** argv) { std::string option = OPTIONS[option_index].name; if (option == "locale") { locale = optarg; + } else if (option == "reason") { + reason = optarg; } else if (option == "fastboot" && android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) { fastboot = true; @@ -412,6 +420,9 @@ int main(int argc, char** argv) { device->ResetUI(new StubRecoveryUI()); } } + + BootState boot_state(reason, stage); // recovery_main owns the state of boot. + device->SetBootState(&boot_state); ui = device->GetUI(); if (!HasCache()) { diff --git a/recovery_ui/device.cpp b/recovery_ui/device.cpp index e7ae1a3e1..d46df92d3 100644 --- a/recovery_ui/device.cpp +++ b/recovery_ui/device.cpp @@ -23,6 +23,7 @@ #include <android-base/logging.h> +#include "otautil/boot_state.h" #include "recovery_ui/ui.h" static std::vector<std::pair<std::string, Device::BuiltinAction>> g_menu_actions{ @@ -95,3 +96,15 @@ int Device::HandleMenuKey(int key, bool visible) { return ui_->HasThreeButtons() ? kNoAction : kHighlightDown; } } + +void Device::SetBootState(const BootState* state) { + boot_state_ = state; +} + +std::optional<std::string> Device::GetReason() const { + return boot_state_ ? std::make_optional(boot_state_->reason()) : std::nullopt; +} + +std::optional<std::string> Device::GetStage() const { + return boot_state_ ? std::make_optional(boot_state_->stage()) : std::nullopt; +} diff --git a/recovery_ui/include/recovery_ui/device.h b/recovery_ui/include/recovery_ui/device.h index 9a4edf261..f4f993638 100644 --- a/recovery_ui/include/recovery_ui/device.h +++ b/recovery_ui/include/recovery_ui/device.h @@ -20,12 +20,15 @@ #include <stddef.h> #include <memory> +#include <optional> #include <string> #include <vector> // Forward declaration to avoid including "ui.h". class RecoveryUI; +class BootState; + class Device { public: static constexpr const int kNoAction = -1; @@ -126,9 +129,16 @@ class Device { return true; } + void SetBootState(const BootState* state); + // The getters for reason and stage may return std::nullopt until StartRecovery() is called. It's + // the caller's responsibility to perform the check and handle the exception. + std::optional<std::string> GetReason() const; + std::optional<std::string> GetStage() const; + private: // The RecoveryUI object that should be used to display the user interface for this device. std::unique_ptr<RecoveryUI> ui_; + const BootState* boot_state_{ nullptr }; }; // Disable name mangling, as this function will be loaded via dlsym(3). |