summaryrefslogtreecommitdiffstats
path: root/recovery_main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'recovery_main.cpp')
-rw-r--r--recovery_main.cpp80
1 files changed, 51 insertions, 29 deletions
diff --git a/recovery_main.cpp b/recovery_main.cpp
index de8ac1f42..28197bf40 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -41,16 +41,16 @@
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <bootloader_message/bootloader_message.h>
-#include <cutils/android_reboot.h>
#include <cutils/sockets.h>
+#include <fs_mgr/roots.h>
#include <private/android_logger.h> /* private pmsg functions */
#include <selinux/android.h>
#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"
@@ -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 */,
@@ -81,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 = {};
@@ -95,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) {
@@ -131,7 +133,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 +150,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,14 +333,15 @@ 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);
+ 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 },
};
@@ -346,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;
@@ -359,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;
@@ -370,12 +376,11 @@ int main(int argc, char** argv) {
optind = 1;
if (locale.empty()) {
- if (has_cache) {
+ if (HasCache()) {
locale = load_locale_from_cache();
}
if (locale.empty()) {
- static constexpr const char* DEFAULT_LOCALE = "en-US";
locale = DEFAULT_LOCALE;
}
}
@@ -415,9 +420,12 @@ 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 (!has_cache) {
+ if (!HasCache()) {
device->RemoveMenuItemForAction(Device::WIPE_CACHE);
}
@@ -425,7 +433,7 @@ int main(int argc, char** argv) {
device->RemoveMenuItemForAction(Device::ENTER_FASTBOOT);
}
- if (!is_ro_debuggable()) {
+ if (!IsRoDebuggable()) {
device->RemoveMenuItemForAction(Device::ENTER_RESCUE);
}
@@ -435,7 +443,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");
@@ -448,7 +456,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")) {
@@ -472,27 +480,31 @@ int main(int argc, char** argv) {
switch (ret) {
case Device::SHUTDOWN:
ui->Print("Shutting down...\n");
- // TODO: Move all the reboots to reboot(), which should conditionally set quiescent flag.
- android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown,");
+ Shutdown("userrequested,recovery");
+ break;
+
+ case Device::SHUTDOWN_FROM_FASTBOOT:
+ ui->Print("Shutting down...\n");
+ Shutdown("userrequested,fastboot");
break;
case Device::REBOOT_BOOTLOADER:
ui->Print("Rebooting to bootloader...\n");
- android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,bootloader");
+ Reboot("bootloader");
break;
case Device::REBOOT_FASTBOOT:
ui->Print("Rebooting to recovery/fastboot...\n");
- android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,fastboot");
+ Reboot("fastboot");
break;
case Device::REBOOT_RECOVERY:
ui->Print("Rebooting to recovery...\n");
- reboot("reboot,recovery");
+ Reboot("recovery");
break;
case Device::REBOOT_RESCUE: {
- // Not using `reboot("reboot,rescue")`, as it requires matching support in kernel and/or
+ // Not using `Reboot("rescue")`, as it requires matching support in kernel and/or
// bootloader.
bootloader_message boot = {};
strlcpy(boot.command, "boot-rescue", sizeof(boot.command));
@@ -503,14 +515,14 @@ int main(int argc, char** argv) {
continue;
}
ui->Print("Rebooting to recovery/rescue...\n");
- reboot("reboot,recovery");
+ Reboot("recovery");
break;
}
case Device::ENTER_FASTBOOT:
- if (logical_partitions_mapped()) {
+ if (android::fs_mgr::LogicalPartitionsMapped()) {
ui->Print("Partitions may be mounted - rebooting to enter fastboot.");
- android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,fastboot");
+ Reboot("fastboot");
} else {
LOG(INFO) << "Entering fastboot";
fastboot = true;
@@ -522,9 +534,19 @@ int main(int argc, char** argv) {
fastboot = false;
break;
+ case Device::REBOOT:
+ ui->Print("Rebooting...\n");
+ Reboot("userrequested,recovery");
+ break;
+
+ case Device::REBOOT_FROM_FASTBOOT:
+ ui->Print("Rebooting...\n");
+ Reboot("userrequested,fastboot");
+ break;
+
default:
ui->Print("Rebooting...\n");
- reboot("reboot,");
+ Reboot("unknown" + std::to_string(ret));
break;
}
}