Updating fastboot to modern c++ standards

Test: tested fastboot on raven device
Change-Id: I0c1fa4cd09378282edf5df54ae26d747e6d4f3eb
This commit is contained in:
Daniel Zheng 2022-11-30 02:25:31 +00:00
parent f9e6c5104d
commit 65452d036e
1 changed files with 94 additions and 98 deletions

View File

@ -129,23 +129,23 @@ enum class ImageType {
}; };
struct Image { struct Image {
const char* nickname; std::string nickname;
const char* img_name; std::string img_name;
const char* sig_name; std::string sig_name;
const char* part_name; std::string part_name;
bool optional_if_no_image; bool optional_if_no_image;
ImageType type; ImageType type;
bool IsSecondary() const { return nickname == nullptr; } bool IsSecondary() const { return nickname.empty(); }
}; };
static Image images[] = { static std::vector<Image> images = {
// clang-format off // clang-format off
{ "boot", "boot.img", "boot.sig", "boot", false, ImageType::BootCritical }, { "boot", "boot.img", "boot.sig", "boot", false, ImageType::BootCritical },
{ "init_boot", { "init_boot",
"init_boot.img", "init_boot.sig", "init_boot.img", "init_boot.sig",
"init_boot", "init_boot",
true, ImageType::BootCritical }, true, ImageType::BootCritical },
{ nullptr, "boot_other.img", "boot.sig", "boot", true, ImageType::Normal }, { "", "boot_other.img", "boot.sig", "boot", true, ImageType::Normal },
{ "cache", "cache.img", "cache.sig", "cache", true, ImageType::Extra }, { "cache", "cache.img", "cache.sig", "cache", true, ImageType::Extra },
{ "dtbo", "dtbo.img", "dtbo.sig", "dtbo", true, ImageType::BootCritical }, { "dtbo", "dtbo.img", "dtbo.sig", "dtbo", true, ImageType::BootCritical },
{ "dts", "dt.img", "dt.sig", "dts", true, ImageType::BootCritical }, { "dts", "dt.img", "dt.sig", "dts", true, ImageType::BootCritical },
@ -164,7 +164,7 @@ static Image images[] = {
"system_ext.img", "system_ext.sig", "system_ext.img", "system_ext.sig",
"system_ext", "system_ext",
true, ImageType::Normal }, true, ImageType::Normal },
{ nullptr, "system_other.img", "system.sig", "system", true, ImageType::Normal }, { "", "system_other.img", "system.sig", "system", true, ImageType::Normal },
{ "userdata", "userdata.img", "userdata.sig", "userdata", true, ImageType::Extra }, { "userdata", "userdata.img", "userdata.sig", "userdata", true, ImageType::Extra },
{ "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, ImageType::BootCritical }, { "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, ImageType::BootCritical },
{ "vbmeta_system", { "vbmeta_system",
@ -191,7 +191,7 @@ static Image images[] = {
"vendor_kernel_boot.sig", "vendor_kernel_boot.sig",
"vendor_kernel_boot", "vendor_kernel_boot",
true, ImageType::BootCritical }, true, ImageType::BootCritical },
{ nullptr, "vendor_other.img", "vendor.sig", "vendor", true, ImageType::Normal }, { "", "vendor_other.img", "vendor.sig", "vendor", true, ImageType::Normal },
// clang-format on // clang-format on
}; };
@ -212,8 +212,8 @@ static std::string find_item_given_name(const std::string& img_name) {
} }
static std::string find_item(const std::string& item) { static std::string find_item(const std::string& item) {
for (size_t i = 0; i < arraysize(images); ++i) { for (size_t i = 0; i < images.size(); ++i) {
if (images[i].nickname && item == images[i].nickname) { if (!images[i].nickname.empty() && item == images[i].nickname) {
return find_item_given_name(images[i].img_name); return find_item_given_name(images[i].img_name);
} }
} }
@ -274,7 +274,8 @@ static int match_fastboot_with_serial(usb_ifc_info* info, const char* local_seri
// require matching serial number or device path if requested // require matching serial number or device path if requested
// at the command line with the -s option. // at the command line with the -s option.
if (local_serial && (strcmp(local_serial, info->serial_number) != 0 && if (local_serial && (strcmp(local_serial, info->serial_number) != 0 &&
strcmp(local_serial, info->device_path) != 0)) return -1; strcmp(local_serial, info->device_path) != 0))
return -1;
return 0; return 0;
} }
@ -532,15 +533,15 @@ static std::vector<char> LoadBootableImage(const std::string& kernel, const std:
std::vector<char> dtb_data; std::vector<char> dtb_data;
if (!g_dtb_path.empty()) { if (!g_dtb_path.empty()) {
if (g_boot_img_hdr.header_version != 2) { if (g_boot_img_hdr.header_version != 2) {
die("Argument dtb not supported for boot image header version %d\n", die("Argument dtb not supported for boot image header version %d\n",
g_boot_img_hdr.header_version); g_boot_img_hdr.header_version);
} }
if (!ReadFileToVector(g_dtb_path, &dtb_data)) { if (!ReadFileToVector(g_dtb_path, &dtb_data)) {
die("cannot load '%s': %s", g_dtb_path.c_str(), strerror(errno)); die("cannot load '%s': %s", g_dtb_path.c_str(), strerror(errno));
} }
} }
fprintf(stderr,"creating boot image...\n"); fprintf(stderr, "creating boot image...\n");
std::vector<char> out; std::vector<char> out;
mkbootimg(kernel_data, ramdisk_data, second_stage_data, dtb_data, g_base_addr, g_boot_img_hdr, mkbootimg(kernel_data, ramdisk_data, second_stage_data, dtb_data, g_base_addr, g_boot_img_hdr,
@ -562,15 +563,15 @@ static bool UnzipToMemory(ZipArchiveHandle zip, const std::string& entry_name,
} }
if (zip_entry.uncompressed_length > std::numeric_limits<size_t>::max()) { if (zip_entry.uncompressed_length > std::numeric_limits<size_t>::max()) {
die("entry '%s' is too large: %" PRIu64, entry_name.c_str(), zip_entry.uncompressed_length); die("entry '%s' is too large: %" PRIu64, entry_name.c_str(), zip_entry.uncompressed_length);
} }
out->resize(zip_entry.uncompressed_length); out->resize(zip_entry.uncompressed_length);
fprintf(stderr, "extracting %s (%zu MB) to RAM...\n", entry_name.c_str(), fprintf(stderr, "extracting %s (%zu MB) to RAM...\n", entry_name.c_str(),
out->size() / 1024 / 1024); out->size() / 1024 / 1024);
int error = ExtractToMemory(zip, &zip_entry, reinterpret_cast<uint8_t*>(out->data()), int error =
out->size()); ExtractToMemory(zip, &zip_entry, reinterpret_cast<uint8_t*>(out->data()), out->size());
if (error != 0) die("failed to extract '%s': %s", entry_name.c_str(), ErrorCodeString(error)); if (error != 0) die("failed to extract '%s': %s", entry_name.c_str(), ErrorCodeString(error));
return true; return true;
@ -618,8 +619,8 @@ static int make_temporary_fd(const char* what) {
std::string path_template(make_temporary_template()); std::string path_template(make_temporary_template());
int fd = mkstemp(&path_template[0]); int fd = mkstemp(&path_template[0]);
if (fd == -1) { if (fd == -1) {
die("failed to create temporary file for %s with template %s: %s\n", die("failed to create temporary file for %s with template %s: %s\n", path_template.c_str(),
path_template.c_str(), what, strerror(errno)); what, strerror(errno));
} }
unlink(path_template.c_str()); unlink(path_template.c_str());
return fd; return fd;
@ -673,16 +674,15 @@ static bool CheckRequirement(const std::string& cur_product, const std::string&
std::string var_value; std::string var_value;
if (fb->GetVar(var, &var_value) != fastboot::SUCCESS) { if (fb->GetVar(var, &var_value) != fastboot::SUCCESS) {
fprintf(stderr, "FAILED\n\n"); fprintf(stderr, "FAILED\n\n");
fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb->Error().c_str());
fb->Error().c_str());
return false; return false;
} }
bool match = false; bool match = false;
for (const auto& option : options) { for (const auto& option : options) {
if (option == var_value || (option.back() == '*' && if (option == var_value ||
!var_value.compare(0, option.length() - 1, option, 0, (option.back() == '*' &&
option.length() - 1))) { !var_value.compare(0, option.length() - 1, option, 0, option.length() - 1))) {
match = true; match = true;
break; break;
} }
@ -757,8 +757,8 @@ static void HandlePartitionExists(const std::vector<std::string>& options) {
die("device doesn't have required partition %s!", partition_name.c_str()); die("device doesn't have required partition %s!", partition_name.c_str());
} }
bool known_partition = false; bool known_partition = false;
for (size_t i = 0; i < arraysize(images); ++i) { for (size_t i = 0; i < images.size(); ++i) {
if (images[i].nickname && images[i].nickname == partition_name) { if (!images[i].nickname.empty() && images[i].nickname == partition_name) {
images[i].optional_if_no_image = false; images[i].optional_if_no_image = false;
known_partition = true; known_partition = true;
} }
@ -796,9 +796,9 @@ static void CheckRequirements(const std::string& data, bool force_flash) {
bool met = CheckRequirement(cur_product, name, product, invert, options); bool met = CheckRequirement(cur_product, name, product, invert, options);
if (!met) { if (!met) {
if (!force_flash) { if (!force_flash) {
die("requirements not met!"); die("requirements not met!");
} else { } else {
fprintf(stderr, "requirements not met! but proceeding due to --force\n"); fprintf(stderr, "requirements not met! but proceeding due to --force\n");
} }
} }
} }
@ -822,7 +822,6 @@ static void DumpInfo() {
DisplayVarOrError("Baseband Version.....", "version-baseband"); DisplayVarOrError("Baseband Version.....", "version-baseband");
DisplayVarOrError("Serial Number........", "serialno"); DisplayVarOrError("Serial Number........", "serialno");
fprintf(stderr, "--------------------------------------------\n"); fprintf(stderr, "--------------------------------------------\n");
} }
static struct sparse_file** load_sparse_files(int fd, int64_t max_size) { static struct sparse_file** load_sparse_files(int fd, int64_t max_size) {
@ -830,13 +829,14 @@ static struct sparse_file** load_sparse_files(int fd, int64_t max_size) {
if (!s) die("cannot sparse read file"); if (!s) die("cannot sparse read file");
if (max_size <= 0 || max_size > std::numeric_limits<uint32_t>::max()) { if (max_size <= 0 || max_size > std::numeric_limits<uint32_t>::max()) {
die("invalid max size %" PRId64, max_size); die("invalid max size %" PRId64, max_size);
} }
int files = sparse_file_resparse(s, max_size, nullptr, 0); int files = sparse_file_resparse(s, max_size, nullptr, 0);
if (files < 0) die("Failed to resparse"); if (files < 0) die("Failed to resparse");
sparse_file** out_s = reinterpret_cast<sparse_file**>(calloc(sizeof(struct sparse_file *), files + 1)); sparse_file** out_s =
reinterpret_cast<sparse_file**>(calloc(sizeof(struct sparse_file*), files + 1));
if (!out_s) die("Failed to allocate sparse file array"); if (!out_s) die("Failed to allocate sparse file array");
files = sparse_file_resparse(s, max_size, out_s, files); files = sparse_file_resparse(s, max_size, out_s, files);
@ -1078,8 +1078,7 @@ static void copy_avb_footer(const std::string& partition, struct fastboot_buffer
lseek(buf->fd.get(), 0, SEEK_SET); lseek(buf->fd.get(), 0, SEEK_SET);
} }
static void flash_buf(const std::string& partition, struct fastboot_buffer *buf) static void flash_buf(const std::string& partition, struct fastboot_buffer* buf) {
{
sparse_file** s; sparse_file** s;
if (partition == "boot" || partition == "boot_a" || partition == "boot_b" || if (partition == "boot" || partition == "boot_a" || partition == "boot_b" ||
@ -1097,7 +1096,7 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf)
rewrite_vbmeta_buffer(buf, false /* vbmeta_in_boot */); rewrite_vbmeta_buffer(buf, false /* vbmeta_in_boot */);
} else if (!has_vbmeta_partition() && } else if (!has_vbmeta_partition() &&
(partition == "boot" || partition == "boot_a" || partition == "boot_b")) { (partition == "boot" || partition == "boot_a" || partition == "boot_b")) {
rewrite_vbmeta_buffer(buf, true /* vbmeta_in_boot */ ); rewrite_vbmeta_buffer(buf, true /* vbmeta_in_boot */);
} }
} }
@ -1143,14 +1142,14 @@ static int get_slot_count() {
} }
static bool supports_AB() { static bool supports_AB() {
return get_slot_count() >= 2; return get_slot_count() >= 2;
} }
// Given a current slot, this returns what the 'other' slot is. // Given a current slot, this returns what the 'other' slot is.
static std::string get_other_slot(const std::string& current_slot, int count) { static std::string get_other_slot(const std::string& current_slot, int count) {
if (count == 0) return ""; if (count == 0) return "";
char next = (current_slot[0] - 'a' + 1)%count + 'a'; char next = (current_slot[0] - 'a' + 1) % count + 'a';
return std::string(1, next); return std::string(1, next);
} }
@ -1185,17 +1184,17 @@ static std::string verify_slot(const std::string& slot_name, bool allow_all) {
if (count == 0) die("Device does not support slots"); if (count == 0) die("Device does not support slots");
if (slot == "other") { if (slot == "other") {
std::string other = get_other_slot( count); std::string other = get_other_slot(count);
if (other == "") { if (other == "") {
die("No known slots"); die("No known slots");
} }
return other; return other;
} }
if (slot.size() == 1 && (slot[0]-'a' >= 0 && slot[0]-'a' < count)) return slot; if (slot.size() == 1 && (slot[0] - 'a' >= 0 && slot[0] - 'a' < count)) return slot;
fprintf(stderr, "Slot %s does not exist. supported slots are:\n", slot.c_str()); fprintf(stderr, "Slot %s does not exist. supported slots are:\n", slot.c_str());
for (int i=0; i<count; i++) { for (int i = 0; i < count; i++) {
fprintf(stderr, "%c\n", (char)(i + 'a')); fprintf(stderr, "%c\n", (char)(i + 'a'));
} }
@ -1203,7 +1202,7 @@ static std::string verify_slot(const std::string& slot_name, bool allow_all) {
} }
static std::string verify_slot(const std::string& slot) { static std::string verify_slot(const std::string& slot) {
return verify_slot(slot, true); return verify_slot(slot, true);
} }
static void do_for_partition(const std::string& part, const std::string& slot, static void do_for_partition(const std::string& part, const std::string& slot,
@ -1243,7 +1242,8 @@ static void do_for_partition(const std::string& part, const std::string& slot,
* partition does not support slots. * partition does not support slots.
*/ */
static void do_for_partitions(const std::string& part, const std::string& slot, static void do_for_partitions(const std::string& part, const std::string& slot,
const std::function<void(const std::string&)>& func, bool force_slot) { const std::function<void(const std::string&)>& func,
bool force_slot) {
std::string has_slot; std::string has_slot;
// |part| can be vendor_boot:default. Query has-slot on the first token only. // |part| can be vendor_boot:default. Query has-slot on the first token only.
auto part_tokens = android::base::Split(part, ":"); auto part_tokens = android::base::Split(part, ":");
@ -1254,7 +1254,7 @@ static void do_for_partitions(const std::string& part, const std::string& slot,
slot.c_str()); slot.c_str());
} }
if (has_slot == "yes") { if (has_slot == "yes") {
for (int i=0; i < get_slot_count(); i++) { for (int i = 0; i < get_slot_count(); i++) {
do_for_partition(part, std::string(1, (char)(i + 'a')), func, force_slot); do_for_partition(part, std::string(1, (char)(i + 'a')), func, force_slot);
} }
} else { } else {
@ -1403,7 +1403,7 @@ static void CancelSnapshotIfNeeded() {
class ImageSource { class ImageSource {
public: public:
virtual ~ImageSource() {}; virtual ~ImageSource(){};
virtual bool ReadFile(const std::string& name, std::vector<char>* out) const = 0; virtual bool ReadFile(const std::string& name, std::vector<char>* out) const = 0;
virtual unique_fd OpenFile(const std::string& name) const = 0; virtual unique_fd OpenFile(const std::string& name) const = 0;
}; };
@ -1435,13 +1435,11 @@ class FlashAllTool {
FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_override, FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_override,
bool skip_secondary, bool wipe, bool force_flash) bool skip_secondary, bool wipe, bool force_flash)
: source_(source), : source_(source),
slot_override_(slot_override), slot_override_(slot_override),
skip_secondary_(skip_secondary), skip_secondary_(skip_secondary),
wipe_(wipe), wipe_(wipe),
force_flash_(force_flash) force_flash_(force_flash) {}
{
}
void FlashAllTool::Flash() { void FlashAllTool::Flash() {
DumpInfo(); DumpInfo();
@ -1508,7 +1506,7 @@ void FlashAllTool::DetermineSecondarySlot() {
} }
void FlashAllTool::CollectImages() { void FlashAllTool::CollectImages() {
for (size_t i = 0; i < arraysize(images); ++i) { for (size_t i = 0; i < images.size(); ++i) {
std::string slot = slot_override_; std::string slot = slot_override_;
if (images[i].IsSecondary()) { if (images[i].IsSecondary()) {
if (skip_secondary_) { if (skip_secondary_) {
@ -1532,7 +1530,7 @@ void FlashAllTool::FlashImages(const std::vector<std::pair<const Image*, std::st
if (image->optional_if_no_image) { if (image->optional_if_no_image) {
continue; continue;
} }
die("could not load '%s': %s", image->img_name, strerror(errno)); die("could not load '%s': %s", image->img_name.c_str(), strerror(errno));
} }
FlashImage(*image, slot, &buf); FlashImage(*image, slot, &buf);
} }
@ -1734,8 +1732,7 @@ static void fb_perform_format(const std::string& partition, int skip_if_not_supp
fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str()); fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str());
return; return;
} }
die("Formatting is not supported for file system with type '%s'.", die("Formatting is not supported for file system with type '%s'.", partition_type.c_str());
partition_type.c_str());
} }
int64_t size; int64_t size;
@ -1892,32 +1889,30 @@ int FastBootTool::Main(int argc, char* argv[]) {
g_boot_img_hdr.page_size = 2048; g_boot_img_hdr.page_size = 2048;
g_boot_img_hdr.dtb_addr = 0x01100000; g_boot_img_hdr.dtb_addr = 0x01100000;
const struct option longopts[] = { const struct option longopts[] = {{"base", required_argument, 0, 0},
{"base", required_argument, 0, 0}, {"cmdline", required_argument, 0, 0},
{"cmdline", required_argument, 0, 0}, {"disable-verification", no_argument, 0, 0},
{"disable-verification", no_argument, 0, 0}, {"disable-verity", no_argument, 0, 0},
{"disable-verity", no_argument, 0, 0}, {"force", no_argument, 0, 0},
{"force", no_argument, 0, 0}, {"fs-options", required_argument, 0, 0},
{"fs-options", required_argument, 0, 0}, {"header-version", required_argument, 0, 0},
{"header-version", required_argument, 0, 0}, {"help", no_argument, 0, 'h'},
{"help", no_argument, 0, 'h'}, {"kernel-offset", required_argument, 0, 0},
{"kernel-offset", required_argument, 0, 0}, {"os-patch-level", required_argument, 0, 0},
{"os-patch-level", required_argument, 0, 0}, {"os-version", required_argument, 0, 0},
{"os-version", required_argument, 0, 0}, {"page-size", required_argument, 0, 0},
{"page-size", required_argument, 0, 0}, {"ramdisk-offset", required_argument, 0, 0},
{"ramdisk-offset", required_argument, 0, 0}, {"set-active", optional_argument, 0, 'a'},
{"set-active", optional_argument, 0, 'a'}, {"skip-reboot", no_argument, 0, 0},
{"skip-reboot", no_argument, 0, 0}, {"skip-secondary", no_argument, 0, 0},
{"skip-secondary", no_argument, 0, 0}, {"slot", required_argument, 0, 0},
{"slot", required_argument, 0, 0}, {"tags-offset", required_argument, 0, 0},
{"tags-offset", required_argument, 0, 0}, {"dtb", required_argument, 0, 0},
{"dtb", required_argument, 0, 0}, {"dtb-offset", required_argument, 0, 0},
{"dtb-offset", required_argument, 0, 0}, {"unbuffered", no_argument, 0, 0},
{"unbuffered", no_argument, 0, 0}, {"verbose", no_argument, 0, 'v'},
{"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 0},
{"version", no_argument, 0, 0}, {0, 0, 0, 0}};
{0, 0, 0, 0}
};
serial = getenv("ANDROID_SERIAL"); serial = getenv("ANDROID_SERIAL");
@ -1966,7 +1961,8 @@ int FastBootTool::Main(int argc, char* argv[]) {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);
setvbuf(stderr, nullptr, _IONBF, 0); setvbuf(stderr, nullptr, _IONBF, 0);
} else if (name == "version") { } else if (name == "version") {
fprintf(stdout, "fastboot version %s-%s\n", PLATFORM_TOOLS_VERSION, android::build::GetBuildNumber().c_str()); fprintf(stdout, "fastboot version %s-%s\n", PLATFORM_TOOLS_VERSION,
android::build::GetBuildNumber().c_str());
fprintf(stdout, "Installed as %s\n", android::base::GetExecutablePath().c_str()); fprintf(stdout, "Installed as %s\n", android::base::GetExecutablePath().c_str());
return 0; return 0;
} else { } else {
@ -2024,9 +2020,9 @@ int FastBootTool::Main(int argc, char* argv[]) {
return 1; return 1;
} }
fastboot::DriverCallbacks driver_callbacks = { fastboot::DriverCallbacks driver_callbacks = {
.prolog = Status, .prolog = Status,
.epilog = Epilog, .epilog = Epilog,
.info = InfoMessage, .info = InfoMessage,
}; };
fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false);
fb = &fastboot_driver; fb = &fastboot_driver;
@ -2063,7 +2059,8 @@ int FastBootTool::Main(int argc, char* argv[]) {
std::string partition = next_arg(&args); std::string partition = next_arg(&args);
auto erase = [&](const std::string& partition) { auto erase = [&](const std::string& partition) {
std::string partition_type; std::string partition_type;
if (fb->GetVar("partition-type:" + partition, &partition_type) == fastboot::SUCCESS && if (fb->GetVar("partition-type:" + partition, &partition_type) ==
fastboot::SUCCESS &&
fs_get_generator(partition_type) != nullptr) { fs_get_generator(partition_type) != nullptr) {
fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n", fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n",
partition_type.c_str()); partition_type.c_str());
@ -2118,7 +2115,6 @@ int FastBootTool::Main(int argc, char* argv[]) {
} else { } else {
syntax_error("unknown reboot target %s", what.c_str()); syntax_error("unknown reboot target %s", what.c_str());
} }
} }
if (!args.empty()) syntax_error("junk after reboot command"); if (!args.empty()) syntax_error("junk after reboot command");
} else if (command == FB_CMD_REBOOT_BOOTLOADER) { } else if (command == FB_CMD_REBOOT_BOOTLOADER) {
@ -2149,7 +2145,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
} }
if (fname.empty()) die("cannot determine image filename for '%s'", pname.c_str()); if (fname.empty()) die("cannot determine image filename for '%s'", pname.c_str());
auto flash = [&](const std::string &partition) { auto flash = [&](const std::string& partition) {
if (should_flash_in_userspace(partition) && !is_userspace_fastboot() && if (should_flash_in_userspace(partition) && !is_userspace_fastboot() &&
!force_flash) { !force_flash) {
die("The partition you are trying to flash is dynamic, and " die("The partition you are trying to flash is dynamic, and "
@ -2178,7 +2174,8 @@ int FastBootTool::Main(int argc, char* argv[]) {
do_for_partitions(partition, slot_override, flashraw, true); do_for_partitions(partition, slot_override, flashraw, true);
} else if (command == "flashall") { } else if (command == "flashall") {
if (slot_override == "all") { if (slot_override == "all") {
fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); fprintf(stderr,
"Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
do_flashall(slot_override, true, wants_wipe, force_flash); do_flashall(slot_override, true, wants_wipe, force_flash);
} else { } else {
do_flashall(slot_override, skip_secondary, wants_wipe, force_flash); do_flashall(slot_override, skip_secondary, wants_wipe, force_flash);
@ -2187,7 +2184,8 @@ int FastBootTool::Main(int argc, char* argv[]) {
} else if (command == "update") { } else if (command == "update") {
bool slot_all = (slot_override == "all"); bool slot_all = (slot_override == "all");
if (slot_all) { if (slot_all) {
fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); fprintf(stderr,
"Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
} }
std::string filename = "update.zip"; std::string filename = "update.zip";
if (!args.empty()) { if (!args.empty()) {
@ -2214,10 +2212,9 @@ int FastBootTool::Main(int argc, char* argv[]) {
} else if (command == "flashing") { } else if (command == "flashing") {
if (args.empty()) { if (args.empty()) {
syntax_error("missing 'flashing' command"); syntax_error("missing 'flashing' command");
} else if (args.size() == 1 && (args[0] == "unlock" || args[0] == "lock" || } else if (args.size() == 1 &&
args[0] == "unlock_critical" || (args[0] == "unlock" || args[0] == "lock" || args[0] == "unlock_critical" ||
args[0] == "lock_critical" || args[0] == "lock_critical" || args[0] == "get_unlock_ability")) {
args[0] == "get_unlock_ability")) {
do_oem_command("flashing", &args); do_oem_command("flashing", &args);
} else { } else {
syntax_error("unknown 'flashing' command %s", args[0].c_str()); syntax_error("unknown 'flashing' command %s", args[0].c_str());
@ -2272,7 +2269,7 @@ int FastBootTool::Main(int argc, char* argv[]) {
if (force_flash) { if (force_flash) {
CancelSnapshotIfNeeded(); CancelSnapshotIfNeeded();
} }
std::vector<std::string> partitions = { "userdata", "cache", "metadata" }; std::vector<std::string> partitions = {"userdata", "cache", "metadata"};
for (const auto& partition : partitions) { for (const auto& partition : partitions) {
std::string partition_type; std::string partition_type;
if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) { if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) {
@ -2334,8 +2331,7 @@ unsigned FastBootTool::ParseFsOption(const char* arg) {
unsigned fsOptions = 0; unsigned fsOptions = 0;
std::vector<std::string> options = android::base::Split(arg, ","); std::vector<std::string> options = android::base::Split(arg, ",");
if (options.size() < 1) if (options.size() < 1) syntax_error("bad options: %s", arg);
syntax_error("bad options: %s", arg);
for (size_t i = 0; i < options.size(); ++i) { for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == "casefold") if (options[i] == "casefold")