From 71fb82a271cc793f5c21f492f5f08507ba49e376 Mon Sep 17 00:00:00 2001 From: Hridya Valsaraju Date: Thu, 2 Aug 2018 15:02:06 -0700 Subject: [PATCH] Add sideload, fastboot as reboot targets in init Rebooting to these targets requires writing bootloader messages and thus root. Moving them into init means that adb, reboot don't need root to use these targets. Test: try rebooting to these targets Bug: 78793464 Change-Id: Ia002d1e3b1cb0c0616f60435fb9af4dce162cf84 --- adb/daemon/services.cpp | 65 ++++++++++++++++++++++------------------- init/reboot.cpp | 14 +++++++++ 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp index dfcc52d95..841769043 100644 --- a/adb/daemon/services.cpp +++ b/adb/daemon/services.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include @@ -96,41 +98,44 @@ void restart_usb_service(unique_fd fd) { void reboot_service(unique_fd fd, const std::string& arg) { std::string reboot_arg = arg; - bool auto_reboot = false; - - if (reboot_arg == "sideload-auto-reboot") { - auto_reboot = true; - reboot_arg = "sideload"; - } - - // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot" - // in the command file. - if (reboot_arg == "sideload") { - if (getuid() != 0) { - WriteFdExactly(fd.get(), "'adb root' is required for 'adb reboot sideload'.\n"); - return; - } - - const std::vector options = {auto_reboot ? "--sideload_auto_reboot" - : "--sideload"}; - std::string err; - if (!write_bootloader_message(options, &err)) { - D("Failed to set bootloader message: %s", err.c_str()); - return; - } - - reboot_arg = "recovery"; - } - sync(); if (reboot_arg.empty()) reboot_arg = "adb"; std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str()); - if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) { - WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str()); - return; - } + if (reboot_arg == "fastboot" && access("/dev/socket/recovery", F_OK) == 0) { + LOG(INFO) << "Recovery specific reboot fastboot"; + /* + * The socket is created to allow switching between recovery and + * fastboot. + */ + android::base::unique_fd sock(socket(AF_UNIX, SOCK_STREAM, 0)); + if (sock < 0) { + WriteFdFmt(fd, "reboot (%s) create\n", strerror(errno)); + PLOG(ERROR) << "Creating recovery socket failed"; + return; + } + + sockaddr_un addr = {.sun_family = AF_UNIX}; + strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1); + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == -1) { + WriteFdFmt(fd, "reboot (%s) connect\n", strerror(errno)); + PLOG(ERROR) << "Couldn't connect to recovery socket"; + return; + } + const char msg_switch_to_fastboot = 'f'; + auto ret = adb_write(sock, &msg_switch_to_fastboot, sizeof(msg_switch_to_fastboot)); + if (ret != sizeof(msg_switch_to_fastboot)) { + WriteFdFmt(fd, "reboot (%s) write\n", strerror(errno)); + PLOG(ERROR) << "Couldn't write message to recovery socket to switch to fastboot"; + return; + } + } else { + if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) { + WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str()); + return; + } + } // Don't return early. Give the reboot command time to take effect // to avoid messing up scripts which do "adb reboot && adb wait-for-device" while (true) { diff --git a/init/reboot.cpp b/init/reboot.cpp index 11507f489..cd3879fc0 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -516,7 +516,21 @@ bool HandlePowerctlMessage(const std::string& command) { "bootloader_message: " << err; } + } else if (reboot_target == "sideload" || reboot_target == "sideload-auto-reboot" || + reboot_target == "fastboot") { + std::string arg = reboot_target == "sideload-auto-reboot" ? "sideload_auto_reboot" + : reboot_target; + const std::vector options = { + "--" + arg, + }; + std::string err; + if (!write_bootloader_message(options, &err)) { + LOG(ERROR) << "Failed to set bootloader message: " << err; + return false; + } + reboot_target = "recovery"; } + // If there is an additional parameter, pass it along if ((cmd_params.size() == 3) && cmd_params[2].size()) { reboot_target += "," + cmd_params[2];