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

Commit 6c28203e authored by David Anderson's avatar David Anderson Committed by android-build-merger
Browse files

Merge "fastbootd: Implement getvar all."

am: 33dcdb80

Change-Id: I32c71fc81c145c5c72d1aaaf76538129424f6eff
parents 13d6d75d 33dcdb80
Loading
Loading
Loading
Loading
+60 −20
Original line number Diff line number Diff line
@@ -42,26 +42,66 @@ using ::android::hardware::boot::V1_0::CommandResult;
using ::android::hardware::boot::V1_0::Slot;
using namespace android::fs_mgr;

struct VariableHandlers {
    // Callback to retrieve the value of a single variable.
    std::function<bool(FastbootDevice*, const std::vector<std::string>&, std::string*)> get;
    // Callback to retrieve all possible argument combinations, for getvar all.
    std::function<std::vector<std::vector<std::string>>(FastbootDevice*)> get_all_args;
};

static void GetAllVars(FastbootDevice* device, const std::string& name,
                       const VariableHandlers& handlers) {
    if (!handlers.get_all_args) {
        std::string message;
        if (!handlers.get(device, std::vector<std::string>(), &message)) {
            return;
        }
        device->WriteInfo(android::base::StringPrintf("%s:%s", name.c_str(), message.c_str()));
        return;
    }

    auto all_args = handlers.get_all_args(device);
    for (const auto& args : all_args) {
        std::string message;
        if (!handlers.get(device, args, &message)) {
            continue;
        }
        std::string arg_string = android::base::Join(args, ":");
        device->WriteInfo(android::base::StringPrintf("%s:%s:%s", name.c_str(), arg_string.c_str(),
                                                      message.c_str()));
    }
}

bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) {
    using VariableHandler =
            std::function<bool(FastbootDevice*, const std::vector<std::string>&, std::string*)>;
    const std::unordered_map<std::string, VariableHandler> kVariableMap = {
            {FB_VAR_VERSION, GetVersion},
            {FB_VAR_VERSION_BOOTLOADER, GetBootloaderVersion},
            {FB_VAR_VERSION_BASEBAND, GetBasebandVersion},
            {FB_VAR_PRODUCT, GetProduct},
            {FB_VAR_SERIALNO, GetSerial},
            {FB_VAR_SECURE, GetSecure},
            {FB_VAR_UNLOCKED, GetUnlocked},
            {FB_VAR_MAX_DOWNLOAD_SIZE, GetMaxDownloadSize},
            {FB_VAR_CURRENT_SLOT, ::GetCurrentSlot},
            {FB_VAR_SLOT_COUNT, GetSlotCount},
            {FB_VAR_HAS_SLOT, GetHasSlot},
            {FB_VAR_SLOT_SUCCESSFUL, GetSlotSuccessful},
            {FB_VAR_SLOT_UNBOOTABLE, GetSlotUnbootable},
            {FB_VAR_PARTITION_SIZE, GetPartitionSize},
            {FB_VAR_IS_LOGICAL, GetPartitionIsLogical},
            {FB_VAR_IS_USERSPACE, GetIsUserspace}};
    const std::unordered_map<std::string, VariableHandlers> kVariableMap = {
            {FB_VAR_VERSION, {GetVersion, nullptr}},
            {FB_VAR_VERSION_BOOTLOADER, {GetBootloaderVersion, nullptr}},
            {FB_VAR_VERSION_BASEBAND, {GetBasebandVersion, nullptr}},
            {FB_VAR_PRODUCT, {GetProduct, nullptr}},
            {FB_VAR_SERIALNO, {GetSerial, nullptr}},
            {FB_VAR_SECURE, {GetSecure, nullptr}},
            {FB_VAR_UNLOCKED, {GetUnlocked, nullptr}},
            {FB_VAR_MAX_DOWNLOAD_SIZE, {GetMaxDownloadSize, nullptr}},
            {FB_VAR_CURRENT_SLOT, {::GetCurrentSlot, nullptr}},
            {FB_VAR_SLOT_COUNT, {GetSlotCount, nullptr}},
            {FB_VAR_HAS_SLOT, {GetHasSlot, GetAllPartitionArgsNoSlot}},
            {FB_VAR_SLOT_SUCCESSFUL, {GetSlotSuccessful, nullptr}},
            {FB_VAR_SLOT_UNBOOTABLE, {GetSlotUnbootable, nullptr}},
            {FB_VAR_PARTITION_SIZE, {GetPartitionSize, GetAllPartitionArgsWithSlot}},
            {FB_VAR_IS_LOGICAL, {GetPartitionIsLogical, GetAllPartitionArgsWithSlot}},
            {FB_VAR_IS_USERSPACE, {GetIsUserspace, nullptr}}};

    if (args.size() < 2) {
        return device->WriteFail("Missing argument");
    }

    // Special case: return all variables that we can.
    if (args[1] == "all") {
        for (const auto& [name, handlers] : kVariableMap) {
            GetAllVars(device, name, handlers);
        }
        return device->WriteOkay("");
    }

    // args[0] is command name, args[1] is variable.
    auto found_variable = kVariableMap.find(args[1]);
@@ -71,7 +111,7 @@ bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args)

    std::string message;
    std::vector<std::string> getvar_args(args.begin() + 2, args.end());
    if (!found_variable->second(device, getvar_args, &message)) {
    if (!found_variable->second.get(device, getvar_args, &message)) {
        return device->WriteFail(message);
    }
    return device->WriteOkay(message);
+4 −0
Original line number Diff line number Diff line
@@ -137,3 +137,7 @@ bool FastbootDevice::WriteOkay(const std::string& message) {
bool FastbootDevice::WriteFail(const std::string& message) {
    return WriteStatus(FastbootResult::FAIL, message);
}

bool FastbootDevice::WriteInfo(const std::string& message) {
    return WriteStatus(FastbootResult::INFO, message);
}
+2 −1
Original line number Diff line number Diff line
@@ -39,9 +39,10 @@ class FastbootDevice {
    bool HandleData(bool read, std::vector<char>* data);
    std::string GetCurrentSlot();

    // Shortcuts for writing OKAY and FAIL status results.
    // Shortcuts for writing status results.
    bool WriteOkay(const std::string& message);
    bool WriteFail(const std::string& message);
    bool WriteInfo(const std::string& message);

    std::vector<char>& download_data() { return download_data_; }
    Transport* get_transport() { return transport_.get(); }
+35 −0
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

#include "utility.h"

#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <android-base/logging.h>
#include <fs_mgr_dm_linear.h>
#include <liblp/liblp.h>
@@ -123,3 +128,33 @@ bool GetSlotNumber(const std::string& slot, Slot* number) {
    *number = slot[0] - 'a';
    return true;
}

std::vector<std::string> ListPartitions(FastbootDevice* device) {
    std::vector<std::string> partitions;

    // First get physical partitions.
    struct dirent* de;
    std::unique_ptr<DIR, decltype(&closedir)> by_name(opendir("/dev/block/by-name"), closedir);
    while ((de = readdir(by_name.get())) != nullptr) {
        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
            continue;
        }
        struct stat s;
        std::string path = "/dev/block/by-name/" + std::string(de->d_name);
        if (!stat(path.c_str(), &s) && S_ISBLK(s.st_mode)) {
            partitions.emplace_back(de->d_name);
        }
    }

    // Next get logical partitions.
    if (auto path = FindPhysicalPartition(LP_METADATA_PARTITION_NAME)) {
        uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot());
        if (auto metadata = ReadMetadata(path->c_str(), slot_number)) {
            for (const auto& partition : metadata->partitions) {
                std::string partition_name = GetPartitionName(partition);
                partitions.emplace_back(partition_name);
            }
        }
    }
    return partitions;
}
+1 −1
Original line number Diff line number Diff line
@@ -56,5 +56,5 @@ std::optional<std::string> FindPhysicalPartition(const std::string& name);
bool LogicalPartitionExists(const std::string& name, const std::string& slot_suffix,
                            bool* is_zero_length = nullptr);
bool OpenPartition(FastbootDevice* device, const std::string& name, PartitionHandle* handle);

bool GetSlotNumber(const std::string& slot, android::hardware::boot::V1_0::Slot* number);
std::vector<std::string> ListPartitions(FastbootDevice* device);
Loading