Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71fb82a2 authored by Hridya Valsaraju's avatar Hridya Valsaraju
Browse files

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
parent 9c16700e
Loading
Loading
Loading
Loading
+32 −27
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include <thread>
@@ -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;
    sync();

    if (reboot_arg == "sideload-auto-reboot") {
        auto_reboot = true;
        reboot_arg = "sideload";
    }
    if (reboot_arg.empty()) reboot_arg = "adb";
    std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());

    // 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");
    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;
        }

        const std::vector<std::string> 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());
        sockaddr_un addr = {.sun_family = AF_UNIX};
        strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1);
        if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
            WriteFdFmt(fd, "reboot (%s) connect\n", strerror(errno));
            PLOG(ERROR) << "Couldn't connect to recovery socket";
            return;
        }

        reboot_arg = "recovery";
        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;
        }

    sync();

    if (reboot_arg.empty()) reboot_arg = "adb";
    std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());
    } 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) {
+14 −0
Original line number Diff line number Diff line
@@ -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<std::string> 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];