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

Commit ea2b9356 authored by Tom Cherry's avatar Tom Cherry Committed by android-build-merger
Browse files

Merge "fastboot: remove engine.cpp/engine.h"

am: e6fc328d

Change-Id: I45eb11373f12d0aa36856b4d28f82b0998c107b6
parents 6e747562 e6fc328d
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -207,7 +207,6 @@ cc_library_host_static {
    cpp_std: "c++17",
    srcs: [
        "bootimg_utils.cpp",
        "engine.cpp",
        "fastboot.cpp",
        "fs.cpp",
        "socket.cpp",

fastboot/engine.cpp

deleted100644 → 0
+0 −197
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "engine.h"

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <vector>

#include <android-base/stringprintf.h>

#include "constants.h"
#include "transport.h"

using android::base::StringPrintf;

static fastboot::FastBootDriver* fb = nullptr;

void fb_init(fastboot::FastBootDriver& fbi) {
    fb = &fbi;
    auto cb = [](std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); };
    fb->SetInfoCallback(cb);
}

void fb_reinit(Transport* transport) {
    if (Transport* old_transport = fb->set_transport(transport)) {
        delete old_transport;
    }
}

const std::string fb_get_error() {
    return fb->Error();
}

bool fb_getvar(const std::string& key, std::string* value) {
    return !fb->GetVar(key, value);
}

static void HandleResult(double start, int status) {
    if (status) {
        fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
        die("Command failed");
    } else {
        double split = now();
        fprintf(stderr, "OKAY [%7.3fs]\n", (split - start));
    }
}

#define RUN_COMMAND(command)         \
    {                                \
        double start = now();        \
        auto status = (command);     \
        HandleResult(start, status); \
    }

void fb_set_active(const std::string& slot) {
    Status("Setting current slot to '" + slot + "'");
    RUN_COMMAND(fb->SetActive(slot));
}

void fb_erase(const std::string& partition) {
    Status("Erasing '" + partition + "'");
    RUN_COMMAND(fb->Erase(partition));
}

void fb_flash_fd(const std::string& partition, int fd, uint32_t sz) {
    Status(StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024));
    RUN_COMMAND(fb->Download(fd, sz));

    Status("Writing '" + partition + "'");
    RUN_COMMAND(fb->Flash(partition));
}

void fb_flash(const std::string& partition, const std::vector<char>& data) {
    Status(StringPrintf("Sending '%s' (%zu KB)", partition.c_str(), data.size() / 1024));
    RUN_COMMAND(fb->Download(data));

    Status("Writing '" + partition + "'");
    RUN_COMMAND(fb->Flash(partition));
}

void fb_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz,
                     size_t current, size_t total) {
    Status(StringPrintf("Sending sparse '%s' %zu/%zu (%u KB)", partition.c_str(), current, total,
                        sz / 1024));
    RUN_COMMAND(fb->Download(s));

    Status(StringPrintf("Writing sparse '%s' %zu/%zu", partition.c_str(), current, total));
    RUN_COMMAND(fb->Flash(partition));
}

void fb_create_partition(const std::string& partition, const std::string& size) {
    Status("Creating '" + partition + "'");
    RUN_COMMAND(fb->RawCommand(FB_CMD_CREATE_PARTITION ":" + partition + ":" + size));
}

void fb_delete_partition(const std::string& partition) {
    Status("Deleting '" + partition + "'");
    RUN_COMMAND(fb->RawCommand(FB_CMD_DELETE_PARTITION ":" + partition));
}

void fb_resize_partition(const std::string& partition, const std::string& size) {
    Status("Resizing '" + partition + "'");
    RUN_COMMAND(fb->RawCommand(FB_CMD_RESIZE_PARTITION ":" + partition + ":" + size));
}

void fb_display(const std::string& label, const std::string& var) {
    std::string value;
    auto status = fb->GetVar(var, &value);

    if (status) {
        fprintf(stderr, "getvar:%s FAILED (%s)\n", var.c_str(), fb->Error().c_str());
        return;
    }
    fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str());
}

void fb_reboot() {
    fprintf(stderr, "Rebooting");
    fb->Reboot();
    fprintf(stderr, "\n");
}

void fb_command(const std::string& cmd, const std::string& msg) {
    Status(msg);
    RUN_COMMAND(fb->RawCommand(cmd));
}

void fb_download(const std::string& name, const std::vector<char>& data) {
    Status("Downloading '" + name + "'");
    RUN_COMMAND(fb->Download(data));
}

void fb_download_fd(const std::string& name, int fd, uint32_t sz) {
    Status(StringPrintf("Sending '%s' (%u KB)", name.c_str(), sz / 1024));
    RUN_COMMAND(fb->Download(fd, sz));
}

void fb_upload(const std::string& outfile) {
    Status("Uploading '" + outfile + "'");
    RUN_COMMAND(fb->Upload(outfile));
}

void fb_notice(const std::string& notice) {
    Status(notice);
    fprintf(stderr, "\n");
}

void fb_wait_for_disconnect() {
    fb->WaitForDisconnect();
}

bool fb_reboot_to_userspace() {
    Status("Rebooting to userspace fastboot");
    verbose("\n");

    if (fb->RebootTo("fastboot") != fastboot::RetCode::SUCCESS) {
        fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
        return false;
    }
    fprintf(stderr, "OKAY\n");

    fb_reinit(nullptr);
    return true;
}
+122 −78
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
 * SUCH DAMAGE.
 */

#include "fastboot.h"

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -63,12 +65,13 @@

#include "bootimg_utils.h"
#include "diagnose_usb.h"
#include "engine.h"
#include "fastboot_driver.h"
#include "fs.h"
#include "tcp.h"
#include "transport.h"
#include "udp.h"
#include "usb.h"
#include "util.h"

using android::base::ReadFully;
using android::base::Split;
@@ -98,6 +101,8 @@ static bool g_disable_verification = false;

static const std::string convert_fbe_marker_filename("convert_fbe");

fastboot::FastBootDriver* fb = nullptr;

enum fb_buffer_type {
    FB_BUFFER_FD,
    FB_BUFFER_SPARSE,
@@ -179,6 +184,28 @@ static std::string find_item(const std::string& item) {
    return "";
}

double last_start_time;

static void Status(const std::string& message) {
    static constexpr char kStatusFormat[] = "%-50s ";
    fprintf(stderr, kStatusFormat, message.c_str());
    last_start_time = now();
}

static void Epilog(int status) {
    if (status) {
        fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
        die("Command failed");
    } else {
        double split = now();
        fprintf(stderr, "OKAY [%7.3fs]\n", (split - last_start_time));
    }
}

static void InfoMessage(const std::string& info) {
    fprintf(stderr, "(bootloader) %s\n", info.c_str());
}

static int64_t get_file_size(int fd) {
    struct stat sb;
    if (fstat(fd, &sb) == -1) {
@@ -606,9 +633,10 @@ static void CheckRequirement(const std::string& cur_product, const std::string&
    }

    std::string var_value;
    if (!fb_getvar(var, &var_value)) {
    if (fb->GetVar(var, &var_value) != fastboot::SUCCESS) {
        fprintf(stderr, "FAILED\n\n");
        fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb_get_error().c_str());
        fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(),
                fb->Error().c_str());
        die("requirements not met!");
    }

@@ -686,7 +714,7 @@ bool ParseRequirementLine(const std::string& line, std::string* name, std::strin
static void HandlePartitionExists(const std::vector<std::string>& options) {
    const std::string& partition_name = options[0];
    std::string has_slot;
    if (!fb_getvar("has-slot:" + partition_name, &has_slot) ||
    if (fb->GetVar("has-slot:" + partition_name, &has_slot) != fastboot::SUCCESS ||
        (has_slot != "yes" && has_slot != "no")) {
        die("device doesn't have required partition %s!", partition_name.c_str());
    }
@@ -705,8 +733,8 @@ static void HandlePartitionExists(const std::vector<std::string>& options) {

static void CheckRequirements(const std::string& data) {
    std::string cur_product;
    if (!fb_getvar("product", &cur_product)) {
        fprintf(stderr, "getvar:product FAILED (%s)\n", fb_get_error().c_str());
    if (fb->GetVar("product", &cur_product) != fastboot::SUCCESS) {
        fprintf(stderr, "getvar:product FAILED (%s)\n", fb->Error().c_str());
    }

    auto lines = Split(data, "\n");
@@ -732,12 +760,24 @@ static void CheckRequirements(const std::string& data) {
    }
}

static void dump_info() {
    fb_notice("--------------------------------------------");
    fb_display("Bootloader Version...", "version-bootloader");
    fb_display("Baseband Version.....", "version-baseband");
    fb_display("Serial Number........", "serialno");
    fb_notice("--------------------------------------------");
static void DisplayVarOrError(const std::string& label, const std::string& var) {
    std::string value;

    if (fb->GetVar(var, &value) != fastboot::SUCCESS) {
        Status("getvar:" + var);
        fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
        return;
    }
    fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str());
}

static void DumpInfo() {
    fprintf(stderr, "--------------------------------------------\n");
    DisplayVarOrError("Bootloader Version...", "version-bootloader");
    DisplayVarOrError("Baseband Version.....", "version-baseband");
    DisplayVarOrError("Serial Number........", "serialno");
    fprintf(stderr, "--------------------------------------------\n");

}

static struct sparse_file** load_sparse_files(int fd, int64_t max_size) {
@@ -762,7 +802,7 @@ static struct sparse_file** load_sparse_files(int fd, int64_t max_size) {

static int64_t get_target_sparse_limit() {
    std::string max_download_size;
    if (!fb_getvar("max-download-size", &max_download_size) ||
    if (fb->GetVar("max-download-size", &max_download_size) != fastboot::SUCCESS ||
        max_download_size.empty()) {
        verbose("target didn't report max-download-size");
        return 0;
@@ -910,12 +950,12 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf)

            for (size_t i = 0; i < sparse_files.size(); ++i) {
                const auto& pair = sparse_files[i];
                fb_flash_sparse(partition, pair.first, pair.second, i + 1, sparse_files.size());
                fb->FlashPartition(partition, pair.first, pair.second, i + 1, sparse_files.size());
            }
            break;
        }
        case FB_BUFFER_FD:
            fb_flash_fd(partition, buf->fd, buf->sz);
            fb->FlashPartition(partition, buf->fd, buf->sz);
            break;
        default:
            die("unknown buffer type: %d", buf->type);
@@ -924,14 +964,15 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf)

static std::string get_current_slot() {
    std::string current_slot;
    if (!fb_getvar("current-slot", &current_slot)) return "";
    if (fb->GetVar("current-slot", &current_slot) != fastboot::SUCCESS) return "";
    return current_slot;
}

static int get_slot_count() {
    std::string var;
    int count = 0;
    if (!fb_getvar("slot-count", &var) || !android::base::ParseInt(var, &count)) {
    if (fb->GetVar("slot-count", &var) != fastboot::SUCCESS ||
        !android::base::ParseInt(var, &count)) {
        return 0;
    }
    return count;
@@ -1006,7 +1047,7 @@ static void do_for_partition(const std::string& part, const std::string& slot,
    std::string has_slot;
    std::string current_slot;

    if (!fb_getvar("has-slot:" + part, &has_slot)) {
    if (fb->GetVar("has-slot:" + part, &has_slot) != fastboot::SUCCESS) {
        /* If has-slot is not supported, the answer is no. */
        has_slot = "no";
    }
@@ -1039,7 +1080,7 @@ static void do_for_partitions(const std::string& part, const std::string& slot,
    std::string has_slot;

    if (slot == "all") {
        if (!fb_getvar("has-slot:" + part, &has_slot)) {
        if (fb->GetVar("has-slot:" + part, &has_slot) != fastboot::SUCCESS) {
            die("Could not check if partition %s has slot %s", part.c_str(), slot.c_str());
        }
        if (has_slot == "yes") {
@@ -1069,25 +1110,25 @@ static void set_active(const std::string& slot_override) {
    if (!supports_AB()) return;

    if (slot_override != "") {
        fb_set_active(slot_override);
        fb->SetActive(slot_override);
    } else {
        std::string current_slot = get_current_slot();
        if (current_slot != "") {
            fb_set_active(current_slot);
            fb->SetActive(current_slot);
        }
    }
}

static bool is_userspace_fastboot() {
    std::string value;
    return fb_getvar("is-userspace", &value) && value == "yes";
    return fb->GetVar("is-userspace", &value) == fastboot::SUCCESS && value == "yes";
}

static bool if_partition_exists(const std::string& partition, const std::string& slot) {
    std::string has_slot;
    std::string partition_name = partition;

    if (fb_getvar("has-slot:" + partition, &has_slot) && has_slot == "yes") {
    if (fb->GetVar("has-slot:" + partition, &has_slot) == fastboot::SUCCESS && has_slot == "yes") {
        if (slot == "") {
            std::string current_slot = get_current_slot();
            if (current_slot == "") {
@@ -1099,23 +1140,24 @@ static bool if_partition_exists(const std::string& partition, const std::string&
        }
    }
    std::string partition_size;
    return fb_getvar("partition-size:" + partition_name, &partition_size);
    return fb->GetVar("partition-size:" + partition_name, &partition_size) == fastboot::SUCCESS;
}

static bool is_logical(const std::string& partition) {
    std::string value;
    return fb_getvar("is-logical:" + partition, &value) && value == "yes";
    return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes";
}

static void reboot_to_userspace_fastboot() {
    if (!fb_reboot_to_userspace()) {
        die("Must reboot to userspace fastboot to flash logical partitions");
    }
    fb->RebootTo("fastboot");

    auto* old_transport = fb->set_transport(nullptr);
    delete old_transport;

    // Give the current connection time to close.
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    fb_reinit(open_device());
    fb->set_transport(open_device());
}

class ImageSource {
@@ -1156,6 +1198,7 @@ FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_ov
}

void FlashAllTool::Flash() {
    DumpInfo();
    CheckRequirements();
    DetermineSecondarySlot();
    CollectImages();
@@ -1172,7 +1215,7 @@ void FlashAllTool::Flash() {
    for (const auto& [image, slot] : os_images_) {
        auto resize_partition = [](const std::string& partition) -> void {
            if (is_logical(partition)) {
                fb_resize_partition(partition, "0");
                fb->ResizePartition(partition, "0");
            }
        };
        do_for_partitions(image->part_name, slot, resize_partition, false);
@@ -1248,12 +1291,12 @@ void FlashAllTool::FlashImage(const Image& image, const std::string& slot, fastb
    auto flash = [&, this](const std::string& partition_name) {
        std::vector<char> signature_data;
        if (source_.ReadFile(image.sig_name, &signature_data)) {
            fb_download("signature", signature_data);
            fb_command("signature", "installing signature");
            fb->Download("signature", signature_data);
            fb->RawCommand("signature", "installing signature");
        }

        if (is_logical(partition_name)) {
            fb_resize_partition(partition_name, std::to_string(buf->image_size));
            fb->ResizePartition(partition_name, std::to_string(buf->image_size));
        }
        flash_buf(partition_name.c_str(), buf);
    };
@@ -1272,13 +1315,13 @@ void FlashAllTool::UpdateSuperPartition() {
    if (!is_userspace_fastboot()) {
        reboot_to_userspace_fastboot();
    }
    fb_download_fd("super", fd, get_file_size(fd));
    fb->Download("super", fd, get_file_size(fd));

    std::string command = "update-super:super";
    if (wipe_) {
        command += ":wipe";
    }
    fb_command(command, "Updating super partition");
    fb->RawCommand(command, "Updating super partition");
}

class ZipImageSource final : public ImageSource {
@@ -1300,8 +1343,6 @@ int ZipImageSource::OpenFile(const std::string& name) const {
}

static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary) {
    dump_info();

    ZipArchiveHandle zip;
    int error = OpenArchive(filename, &zip);
    if (error != 0) {
@@ -1334,9 +1375,6 @@ int LocalImageSource::OpenFile(const std::string& name) const {
}

static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe) {
    std::string fname;
    dump_info();

    FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe);
    tool.Flash();
}
@@ -1355,7 +1393,7 @@ static void do_oem_command(const std::string& cmd, std::vector<std::string>* arg
    while (!args->empty()) {
        command += " " + next_arg(args);
    }
    fb_command(command, "");
    fb->RawCommand(command, "");
}

static std::string fb_fix_numeric_var(std::string var) {
@@ -1369,7 +1407,7 @@ static std::string fb_fix_numeric_var(std::string var) {

static unsigned fb_get_flash_block_size(std::string name) {
    std::string sizeString;
    if (!fb_getvar(name, &sizeString) || sizeString.empty()) {
    if (fb->GetVar(name, &sizeString) != fastboot::SUCCESS || sizeString.empty()) {
        // This device does not report flash block sizes, so return 0.
        return 0;
    }
@@ -1407,7 +1445,7 @@ static void fb_perform_format(
        limit = sparse_limit;
    }

    if (!fb_getvar("partition-type:" + partition, &partition_type)) {
    if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) {
        errMsg = "Can't determine partition type.\n";
        goto failed;
    }
@@ -1419,7 +1457,7 @@ static void fb_perform_format(
        partition_type = type_override;
    }

    if (!fb_getvar("partition-size:" + partition, &partition_size)) {
    if (fb->GetVar("partition-size:" + partition, &partition_size) != fastboot::SUCCESS) {
        errMsg = "Unable to get partition size\n";
        goto failed;
    }
@@ -1477,7 +1515,7 @@ failed:
        fprintf(stderr, "Erase successful, but not automatically formatting.\n");
        if (errMsg) fprintf(stderr, "%s", errMsg);
    }
    fprintf(stderr, "FAILED (%s)\n", fb_get_error().c_str());
    fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
}

int FastBootTool::Main(int argc, char* argv[]) {
@@ -1627,8 +1665,13 @@ int FastBootTool::Main(int argc, char* argv[]) {
    if (transport == nullptr) {
        return 1;
    }
    fastboot::FastBootDriver fb(transport);
    fb_init(fb);
    fastboot::DriverCallbacks driver_callbacks = {
        .prolog = Status,
        .epilog = Epilog,
        .info = InfoMessage,
    };
    fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false);
    fb = &fastboot_driver;

    const double start = now();

@@ -1639,7 +1682,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
        if (next_active == "") {
            if (slot_override == "") {
                std::string current_slot;
                if (fb_getvar("current-slot", &current_slot)) {
                if (fb->GetVar("current-slot", &current_slot) == fastboot::SUCCESS) {
                    next_active = verify_slot(current_slot, false);
                } else {
                    wants_set_active = false;
@@ -1656,19 +1699,18 @@ int FastBootTool::Main(int argc, char* argv[]) {

        if (command == "getvar") {
            std::string variable = next_arg(&args);
            fb_display(variable, variable);
            DisplayVarOrError(variable, variable);
        } else if (command == "erase") {
            std::string partition = next_arg(&args);
            auto erase = [&](const std::string& partition) {
                std::string partition_type;
                if (fb_getvar(std::string("partition-type:") + partition,
                              &partition_type) &&
                if (fb->GetVar("partition-type:" + partition, &partition_type) == fastboot::SUCCESS &&
                    fs_get_generator(partition_type) != nullptr) {
                    fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n",
                            partition_type.c_str());
                }

                fb_erase(partition);
                fb->Erase(partition);
            };
            do_for_partitions(partition, slot_override, erase, true);
        } else if (android::base::StartsWith(command, "format")) {
@@ -1698,8 +1740,8 @@ int FastBootTool::Main(int argc, char* argv[]) {
                die("could not load '%s': %s", filename.c_str(), strerror(errno));
            }
            if (data.size() != 256) die("signature must be 256 bytes (got %zu)", data.size());
            fb_download("signature", data);
            fb_command("signature", "installing signature");
            fb->Download("signature", data);
            fb->RawCommand("signature", "installing signature");
        } else if (command == "reboot") {
            wants_reboot = true;

@@ -1727,7 +1769,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
        } else if (command == "reboot-fastboot") {
            wants_reboot_fastboot = true;
        } else if (command == "continue") {
            fb_command("continue", "resuming boot");
            fb->Continue();
        } else if (command == "boot") {
            std::string kernel = next_arg(&args);
            std::string ramdisk;
@@ -1736,8 +1778,8 @@ int FastBootTool::Main(int argc, char* argv[]) {
            if (!args.empty()) second_stage = next_arg(&args);

            auto data = LoadBootableImage(kernel, ramdisk, second_stage);
            fb_download("boot.img", data);
            fb_command("boot", "booting");
            fb->Download("boot.img", data);
            fb->Boot();
        } else if (command == "flash") {
            std::string pname = next_arg(&args);

@@ -1763,7 +1805,7 @@ int FastBootTool::Main(int argc, char* argv[]) {

            auto data = LoadBootableImage(kernel, ramdisk, second_stage);
            auto flashraw = [&data](const std::string& partition) {
                fb_flash(partition, data);
                fb->FlashPartition(partition, data);
            };
            do_for_partitions(partition, slot_override, flashraw, true);
        } else if (command == "flashall") {
@@ -1787,7 +1829,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
            wants_reboot = true;
        } else if (command == "set_active") {
            std::string slot = verify_slot(next_arg(&args), false);
            fb_set_active(slot);
            fb->SetActive(slot);
        } else if (command == "stage") {
            std::string filename = next_arg(&args);

@@ -1795,10 +1837,10 @@ int FastBootTool::Main(int argc, char* argv[]) {
            if (!load_buf(filename.c_str(), &buf) || buf.type != FB_BUFFER_FD) {
                die("cannot load '%s'", filename.c_str());
            }
            fb_download_fd(filename, buf.fd, buf.sz);
            fb->Download(filename, buf.fd, buf.sz);
        } else if (command == "get_staged") {
            std::string filename = next_arg(&args);
            fb_upload(filename);
            fb->Upload(filename);
        } else if (command == "oem") {
            do_oem_command("oem", &args);
        } else if (command == "flashing") {
@@ -1815,14 +1857,14 @@ int FastBootTool::Main(int argc, char* argv[]) {
        } else if (command == "create-logical-partition") {
            std::string partition = next_arg(&args);
            std::string size = next_arg(&args);
            fb_create_partition(partition, size);
            fb->CreatePartition(partition, size);
        } else if (command == "delete-logical-partition") {
            std::string partition = next_arg(&args);
            fb_delete_partition(partition);
            fb->DeletePartition(partition);
        } else if (command == "resize-logical-partition") {
            std::string partition = next_arg(&args);
            std::string size = next_arg(&args);
            fb_resize_partition(partition, size);
            fb->ResizePartition(partition, size);
        } else {
            syntax_error("unknown command %s", command.c_str());
        }
@@ -1832,9 +1874,11 @@ int FastBootTool::Main(int argc, char* argv[]) {
        std::vector<std::string> partitions = { "userdata", "cache", "metadata" };
        for (const auto& partition : partitions) {
            std::string partition_type;
            if (!fb_getvar(std::string{"partition-type:"} + partition, &partition_type)) continue;
            if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) {
                continue;
            }
            if (partition_type.empty()) continue;
            fb_erase(partition);
            fb->Erase(partition);
            if (partition == "userdata" && set_fbe_marker) {
                fprintf(stderr, "setting FBE marker on initial userdata...\n");
                std::string initial_userdata_dir = create_fbemarker_tmpdir();
@@ -1846,27 +1890,27 @@ int FastBootTool::Main(int argc, char* argv[]) {
        }
    }
    if (wants_set_active) {
        fb_set_active(next_active);
        fb->SetActive(next_active);
    }
    if (wants_reboot && !skip_reboot) {
        fb_reboot();
        fb_wait_for_disconnect();
        fb->Reboot();
        fb->WaitForDisconnect();
    } else if (wants_reboot_bootloader) {
        fb_command("reboot-bootloader", "rebooting into bootloader");
        fb_wait_for_disconnect();
        fb->RebootTo("bootloader");
        fb->WaitForDisconnect();
    } else if (wants_reboot_recovery) {
        fb_command("reboot-recovery", "rebooting into recovery");
        fb_wait_for_disconnect();
        fb->RebootTo("recovery");
        fb->WaitForDisconnect();
    } else if (wants_reboot_fastboot) {
        fb_command("reboot-fastboot", "rebooting into fastboot");
        fb_wait_for_disconnect();
        fb->RebootTo("fastboot");
        fb->WaitForDisconnect();
    }

    fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start));

    if (Transport* old_transport = fb.set_transport(nullptr)) {
    auto* old_transport = fb->set_transport(nullptr);
    delete old_transport;
    }

    return 0;
}

Loading