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

Commit 3fdcf8c3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I939b1e01,I8b723dda,I4acab4b5,Ibc16e93c into nyc-mr1-dev

* changes:
  Handle invalid suffix lists
  Call set_active after flashall and update
  Revert "Make fastboot flash 'B' partitions automatically."
  Revert "Fix issue where non-AB-ota devices will cause flashall to fail."
parents 2ef8922c 190d9684
Loading
Loading
Loading
Loading
+72 −72
Original line number Diff line number Diff line
@@ -99,20 +99,15 @@ struct fastboot_buffer {
};

static struct {
    char img_name[17];
    char sig_name[17];
    char item_name[17];
    char img_name[13];
    char sig_name[13];
    char part_name[9];
    bool active_slot;
    bool is_optional;
} images[] = {
    {"boot.img",         "boot.sig",         "boot",         "boot",     true,  false},
    {"boot_other.img",   "boot_other.sig",   "boot_other",   "boot",     false, true},
    {"recovery.img",     "recovery.sig",     "recovery",     "recovery", true,  true},
    {"system.img",       "system.sig",       "system",       "system",   true,  false},
    {"system_other.img", "system_other.sig", "system_other", "system",   false, true},
    {"vendor.img",       "vendor.sig",       "vendor",       "vendor",   true,  true},
    {"vendor_other.img", "vendor_other.sig", "vendor_other", "vendor",   false, true},
    {"boot.img", "boot.sig", "boot", false},
    {"recovery.img", "recovery.sig", "recovery", true},
    {"system.img", "system.sig", "system", false},
    {"vendor.img", "vendor.sig", "vendor", true},
};

static char* find_item(const char* item, const char* product) {
@@ -134,12 +129,6 @@ static char* find_item(const char* item, const char* product) {
        fn = "cache.img";
    } else if(!strcmp(item,"info")) {
        fn = "android-info.txt";
    } else if(!strcmp(item,"system_other")) {
        fn = "system_other.img";
    } else if(!strcmp(item,"boot_other")) {
        fn = "boot_other.img";
    } else if(!strcmp(item,"vendor_other")) {
        fn = "vendor_other.img";
    } else {
        fprintf(stderr,"unknown partition '%s'\n", item);
        return 0;
@@ -325,8 +314,11 @@ static void usage() {
            "\n"
            "commands:\n"
            "  update <filename>                        Reflash device from update.zip.\n"
            "                                           Sets the flashed slot as active.\n"
            "  flashall                                 Flash boot, system, vendor, and --\n"
            "                                           if found -- recovery.\n"
            "                                           if found -- recovery. If the device\n"
            "                                           supports slots, the slot that has\n"
            "                                           been flashed to is set as active.\n"
            "  flash <partition> [ <filename> ]         Write a file to a flash partition.\n"
            "  flashing lock                            Locks the device. Prevents flashing.\n"
            "  flashing unlock                          Unlocks the device. Allows flashing\n"
@@ -391,10 +383,9 @@ static void usage() {
            "                                           added to all partition names that use\n"
            "                                           slots. 'all' can be given to refer\n"
            "                                           to all slots. 'other' can be given to\n"
            "                                           refer to a non-current slot. 'active' can\n"
            "                                           be given to refer to a current slot only.\n"
            "                                           If this flag is not given slots will be\n"
            "                                           written to based on the filename.\n"
            "                                           refer to a non-current slot. If this\n"
            "                                           flag is not used, slotted partitions\n"
            "                                           will default to the current active slot.\n"
            "  -a, --set-active[=<suffix>]              Sets the active slot. If no suffix is\n"
            "                                           provided, this will default to the value\n"
            "                                           given by --slot. If slots are not\n"
@@ -860,39 +851,33 @@ static void flash_buf(const char *pname, struct fastboot_buffer *buf)
    }
}

static bool has_slots(Transport* transport) {
  std::string suffix_list_unused;
  return fb_getvar(transport, "slot-suffixes", &suffix_list_unused);
}

static std::vector<std::string> get_suffixes(Transport* transport) {
    std::vector<std::string> suffixes;
    std::string suffix_list;
    if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) {
        die("Could not get suffixes.\n");
        return suffixes;
    }
    suffixes = android::base::Split(suffix_list, ",");
    // Unfortunately some devices will return an error message in the
    // guise of a valid value. If we only see only one suffix, it's probably
    // not real.
    if (suffixes.size() == 1) {
        suffixes.clear();
    }
    return android::base::Split(suffix_list, ",");
    return suffixes;
}

// Returns a std::string of the slot name 'active_offset' after the active slot
static std::string get_slot_name(Transport* transport, size_t active_offset) {
// Given a current slot, this returns what the 'other' slot is.
static std::string get_other_slot(Transport* transport, std::string& current_slot) {
    std::vector<std::string> suffixes = get_suffixes(transport);
    std::string current_slot;
    if (!fb_getvar(transport, "current-slot", &current_slot)) {
        die("Failed to identify current slot.");
    }
    if (active_offset >= suffixes.size()) {
        die("active slot offset larger than total number of slots!");
    }

    if (!suffixes.empty()) {
        for (size_t i = 0; i < suffixes.size(); i++) {
            if (current_slot == suffixes[i])
                return suffixes[(i + active_offset) % suffixes.size()];
            if (current_slot == suffixes[i]) {
                return suffixes[(i+1)%suffixes.size()];
            }
        }
    } else {
        die("No known slots.");
    }
    die("Unable to find current slot");
    return "";
}

@@ -913,19 +898,29 @@ static std::string verify_slot(Transport* transport, const char *slot, bool allo
    std::vector<std::string> suffixes = get_suffixes(transport);

    if (strcmp(slot, "other") == 0) {
        return get_slot_name(transport, 1);
    } else if (strcmp(slot, "active") == 0) {
        return get_slot_name(transport, 0);
        std::string current_slot;
        if (!fb_getvar(transport, "current-slot", &current_slot)) {
            die("Failed to identify current slot.");
        }
        std::string other = get_other_slot(transport, current_slot);
        if (other == "") {
           die("No known slots.");
        }
        return other;
    }

    for (const std::string &suffix : suffixes) {
        if (suffix == slot)
            return slot;
    }
    if (suffixes.empty()) {
        fprintf(stderr, "Device does not support slots.\n");
    } else {
        fprintf(stderr, "Slot %s does not exist. supported slots are:\n", slot);
        for (const std::string &suffix : suffixes) {
            fprintf(stderr, "%s\n", suffix.c_str());
        }
    }
    exit(1);
}

@@ -975,6 +970,9 @@ static void do_for_partitions(Transport* transport, const char *part, const char
        }
        if (has_slot == "yes") {
            std::vector<std::string> suffixes = get_suffixes(transport);
            if (suffixes.empty()) {
                die("Error reading suffixes.\n");
            }
            for (std::string &suffix : suffixes) {
                do_for_partition(transport, part, suffix.c_str(), func, force_slot);
            }
@@ -1003,6 +1001,20 @@ static void do_update_signature(ZipArchiveHandle zip, char* fn) {
    fb_queue_command("signature", "installing signature");
}

// Sets slot_override as the active slot. If slot_override is blank,
// set current slot as active instead. This clears slot-unbootable.
static void set_active(Transport* transport, const char* slot_override) {
    if (slot_override && slot_override[0]) {
        fb_set_active(slot_override);
    } else {
        std::string current_slot;
        if (fb_getvar(transport, "current-slot", &current_slot)) {
            current_slot = verify_slot(transport, current_slot.c_str(), false);
            fb_set_active(current_slot.c_str());
        }
    }
}

static void do_update(Transport* transport, const char* filename, const char* slot_override, bool erase_first) {
    queue_info_dump();

@@ -1052,6 +1064,7 @@ static void do_update(Transport* transport, const char* filename, const char* sl
    }

    CloseArchive(zip);
    set_active(transport, slot_override);
}

static void do_send_signature(char* fn) {
@@ -1072,9 +1085,6 @@ static void do_send_signature(char* fn) {

static void do_flashall(Transport* transport, const char* slot_override, int erase_first) {
    queue_info_dump();
    const bool device_has_slots = has_slots(transport);
    const bool has_slot_override = slot_override != nullptr && strcmp(slot_override, "") != 0;
    const bool should_ignore_slots = !device_has_slots || has_slot_override;

    fb_queue_query_save("product", cur_product, sizeof(cur_product));

@@ -1088,26 +1098,13 @@ static void do_flashall(Transport* transport, const char* slot_override, int era
    setup_requirements(reinterpret_cast<char*>(data), sz);

    for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
        if (should_ignore_slots && !images[i].active_slot) {
            // We will not do anything with _other files if we are given an explicit slot to use.
            continue;
        }
        fname = find_item(images[i].item_name, product);
        fname = find_item(images[i].part_name, product);
        fastboot_buffer buf;
        if (load_buf(transport, fname, &buf)) {
            if (images[i].is_optional)
                continue;
            die("could not load %s\n", images[i].img_name);
        }
        // Get the actual slot we are writing to based on the filename. This is because we need to
        // sometimes write the 'active + 1'th slot for first boot optimization reasons. This is
        // defined by the images array unless one is explicitly provided.
        std::string real_slot_override;
        if (should_ignore_slots) {
            real_slot_override = slot_override;
        } else {
            real_slot_override = get_slot_name(transport, images[i].active_slot ? 0 : 1);
        }

        auto flashall = [&](const std::string &partition) {
            do_send_signature(fname);
@@ -1116,12 +1113,10 @@ static void do_flashall(Transport* transport, const char* slot_override, int era
            }
            flash_buf(partition.c_str(), &buf);
        };
        do_for_partitions(transport,
                          images[i].part_name,
                          real_slot_override.c_str(),
                          flashall,
                          false);
        do_for_partitions(transport, images[i].part_name, slot_override, flashall, false);
    }

    set_active(transport, slot_override);
}

#define skip(n) do { argc -= (n); argv += (n); } while (0)
@@ -1456,7 +1451,12 @@ int main(int argc, char **argv)
    if (wants_set_active) {
        if (next_active == "") {
            if (slot_override == "") {
                std::string current_slot;
                if (fb_getvar(transport, "current-slot", &current_slot)) {
                    next_active = verify_slot(transport, current_slot.c_str(), false);
                } else {
                    wants_set_active = false;
                }
            } else {
                next_active = verify_slot(transport, slot_override.c_str(), false);
            }