diff --git a/fastboot/engine.cpp b/fastboot/engine.cpp index d80e98601e14e205fb8ee5be0c86c0499a1f7b66..0ac57afc58dfaa78b0d5a8b0632e5e460fa55475 100644 --- a/fastboot/engine.cpp +++ b/fastboot/engine.cpp @@ -44,43 +44,10 @@ #include "constants.h" #include "transport.h" -enum Op { - OP_DOWNLOAD, - OP_COMMAND, - OP_QUERY, - OP_NOTICE, - OP_DOWNLOAD_SPARSE, - OP_WAIT_FOR_DISCONNECT, - OP_DOWNLOAD_FD, - OP_UPLOAD, -}; +using android::base::StringPrintf; -struct Action { - Action(Op op, const std::string& cmd) : op(op), cmd(cmd) {} - - Op op; - std::string cmd; - std::string msg; - - std::string product; - - void* data = nullptr; - // The protocol only supports 32-bit sizes, so you'll have to break - // anything larger into multiple chunks. - uint32_t size = 0; - - int fd = -1; - - int (*func)(Action& a, int status, const char* resp) = nullptr; - - double start = -1; -}; - -static std::vector<std::unique_ptr<Action>> action_list; static fastboot::FastBootDriver* fb = nullptr; -static constexpr char kStatusFormat[] = "%-50s "; - void fb_init(fastboot::FastBootDriver& fbi) { fb = &fbi; auto cb = [](std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); }; @@ -101,81 +68,72 @@ bool fb_getvar(const std::string& key, std::string* value) { return !fb->GetVar(key, value); } -static int cb_default(Action& a, int status, const char* resp) { +static void HandleResult(double start, int status) { if (status) { - fprintf(stderr,"FAILED (%s)\n", resp); + fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str()); + die("Command failed"); } else { double split = now(); - fprintf(stderr, "OKAY [%7.3fs]\n", (split - a.start)); - a.start = split; + fprintf(stderr, "OKAY [%7.3fs]\n", (split - start)); } - return status; } -static Action& queue_action(Op op, const std::string& cmd) { - std::unique_ptr<Action> a{new Action(op, cmd)}; - a->func = cb_default; - - action_list.push_back(std::move(a)); - return *action_list.back(); -} +#define RUN_COMMAND(command) \ + { \ + double start = now(); \ + auto status = (command); \ + HandleResult(start, status); \ + } void fb_set_active(const std::string& slot) { - Action& a = queue_action(OP_COMMAND, FB_CMD_SET_ACTIVE ":" + slot); - a.msg = "Setting current slot to '" + slot + "'"; + Status("Setting current slot to '" + slot + "'"); + RUN_COMMAND(fb->SetActive(slot)); } -void fb_queue_erase(const std::string& partition) { - Action& a = queue_action(OP_COMMAND, FB_CMD_ERASE ":" + partition); - a.msg = "Erasing '" + partition + "'"; +void fb_erase(const std::string& partition) { + Status("Erasing '" + partition + "'"); + RUN_COMMAND(fb->Erase(partition)); } -void fb_queue_flash_fd(const std::string& partition, int fd, uint32_t sz) { - Action& a = queue_action(OP_DOWNLOAD_FD, ""); - a.fd = fd; - a.size = sz; - a.msg = android::base::StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024); +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)); - Action& b = queue_action(OP_COMMAND, FB_CMD_FLASH ":" + partition); - b.msg = "Writing '" + partition + "'"; + Status("Writing '" + partition + "'"); + RUN_COMMAND(fb->Flash(partition)); } -void fb_queue_flash(const std::string& partition, void* data, uint32_t sz) { - Action& a = queue_action(OP_DOWNLOAD, ""); - a.data = data; - a.size = sz; - a.msg = android::base::StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024); +void fb_flash(const std::string& partition, void* data, uint32_t sz) { + Status(StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024)); + RUN_COMMAND(fb->Download(static_cast<char*>(data), sz)); - Action& b = queue_action(OP_COMMAND, FB_CMD_FLASH ":" + partition); - b.msg = "Writing '" + partition + "'"; + Status("Writing '" + partition + "'"); + RUN_COMMAND(fb->Flash(partition)); } -void fb_queue_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz, - size_t current, size_t total) { - Action& a = queue_action(OP_DOWNLOAD_SPARSE, ""); - a.data = s; - a.size = 0; - a.msg = android::base::StringPrintf("Sending sparse '%s' %zu/%zu (%u KB)", partition.c_str(), - current, total, sz / 1024); - - Action& b = queue_action(OP_COMMAND, FB_CMD_FLASH ":" + partition); - b.msg = android::base::StringPrintf("Writing sparse '%s' %zu/%zu", partition.c_str(), current, - total); +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_queue_create_partition(const std::string& partition, const std::string& size) { - Action& a = queue_action(OP_COMMAND, FB_CMD_CREATE_PARTITION ":" + partition + ":" + size); - a.msg = "Creating '" + 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_queue_delete_partition(const std::string& partition) { - Action& a = queue_action(OP_COMMAND, FB_CMD_DELETE_PARTITION ":" + partition); - a.msg = "Deleting '" + partition + "'"; +void fb_delete_partition(const std::string& partition) { + Status("Deleting '" + partition + "'"); + RUN_COMMAND(fb->RawCommand(FB_CMD_DELETE_PARTITION ":" + partition)); } -void fb_queue_resize_partition(const std::string& partition, const std::string& size) { - Action& a = queue_action(OP_COMMAND, FB_CMD_RESIZE_PARTITION ":" + partition + ":" + size); - a.msg = "Resizing '" + 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)); } static int match(const char* str, const char** value, unsigned count) { @@ -199,193 +157,108 @@ static int match(const char* str, const char** value, unsigned count) { return 0; } -static int cb_check(Action& a, int status, const char* resp, int invert) { - const char** value = reinterpret_cast<const char**>(a.data); - unsigned count = a.size; - unsigned n; +void fb_require(const std::string& product, const std::string& var, bool invert, size_t count, + const char** values) { + Status("Checking '" + var + "'"); + + double start = now(); + + std::string var_value; + auto status = fb->GetVar(var, &var_value); if (status) { - fprintf(stderr,"FAILED (%s)\n", resp); - return status; + fprintf(stderr, "getvar:%s FAILED (%s)\n", var.c_str(), fb->Error().c_str()); + die("requirements not met!"); } - if (!a.product.empty()) { - if (a.product != cur_product) { + if (!product.empty()) { + if (product != cur_product) { double split = now(); fprintf(stderr, "IGNORE, product is %s required only for %s [%7.3fs]\n", cur_product, - a.product.c_str(), (split - a.start)); - a.start = split; - return 0; + product.c_str(), (split - start)); + return; } } - int yes = match(resp, value, count); + int yes = match(var_value.c_str(), values, count); if (invert) yes = !yes; if (yes) { double split = now(); - fprintf(stderr, "OKAY [%7.3fs]\n", (split - a.start)); - a.start = split; - return 0; + fprintf(stderr, "OKAY [%7.3fs]\n", (split - start)); + return; } fprintf(stderr, "FAILED\n\n"); - fprintf(stderr, "Device %s is '%s'.\n", a.cmd.c_str() + 7, resp); - fprintf(stderr, "Update %s '%s'", invert ? "rejects" : "requires", value[0]); - for (n = 1; n < count; n++) { - fprintf(stderr, " or '%s'", value[n]); + fprintf(stderr, "Device %s is '%s'.\n", var.c_str(), var_value.c_str()); + fprintf(stderr, "Update %s '%s'", invert ? "rejects" : "requires", values[0]); + for (size_t n = 1; n < count; n++) { + fprintf(stderr, " or '%s'", values[n]); } fprintf(stderr, ".\n\n"); - return -1; -} - -static int cb_require(Action& a, int status, const char* resp) { - return cb_check(a, status, resp, 0); + die("requirements not met!"); } -static int cb_reject(Action& a, int status, const char* resp) { - return cb_check(a, status, resp, 1); -} - -void fb_queue_require(const std::string& product, const std::string& var, bool invert, - size_t nvalues, const char** values) { - Action& a = queue_action(OP_QUERY, FB_CMD_GETVAR ":" + var); - a.product = product; - a.data = values; - a.size = nvalues; - a.msg = "Checking " + var; - a.func = invert ? cb_reject : cb_require; - if (a.data == nullptr) die("out of memory"); -} +void fb_display(const std::string& label, const std::string& var) { + std::string value; + auto status = fb->GetVar(var, &value); -static int cb_display(Action& a, int status, const char* resp) { if (status) { - fprintf(stderr, "%s FAILED (%s)\n", a.cmd.c_str(), resp); - return status; + fprintf(stderr, "getvar:%s FAILED (%s)\n", var.c_str(), fb->Error().c_str()); + return; } - fprintf(stderr, "%s: %s\n", static_cast<const char*>(a.data), resp); - free(static_cast<char*>(a.data)); - return 0; + fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str()); } -void fb_queue_display(const std::string& label, const std::string& var) { - Action& a = queue_action(OP_QUERY, FB_CMD_GETVAR ":" + var); - a.data = xstrdup(label.c_str()); - a.func = cb_display; -} +void fb_query_save(const std::string& var, char* dest, uint32_t dest_size) { + std::string value; + auto status = fb->GetVar(var, &value); -static int cb_save(Action& a, int status, const char* resp) { if (status) { - fprintf(stderr, "%s FAILED (%s)\n", a.cmd.c_str(), resp); - return status; + fprintf(stderr, "getvar:%s FAILED (%s)\n", var.c_str(), fb->Error().c_str()); + return; } - strncpy(reinterpret_cast<char*>(a.data), resp, a.size); - return 0; -} -void fb_queue_query_save(const std::string& var, char* dest, uint32_t dest_size) { - Action& a = queue_action(OP_QUERY, FB_CMD_GETVAR ":" + var); - a.data = dest; - a.size = dest_size; - a.func = cb_save; + strncpy(dest, value.c_str(), dest_size); } -static int cb_do_nothing(Action&, int, const char*) { +void fb_reboot() { + fprintf(stderr, "Rebooting"); + fb->Reboot(); fprintf(stderr, "\n"); - return 0; -} - -void fb_queue_reboot() { - Action& a = queue_action(OP_COMMAND, FB_CMD_REBOOT); - a.func = cb_do_nothing; - a.msg = "Rebooting"; } -void fb_queue_command(const std::string& cmd, const std::string& msg) { - Action& a = queue_action(OP_COMMAND, cmd); - a.msg = msg; +void fb_command(const std::string& cmd, const std::string& msg) { + Status(msg); + RUN_COMMAND(fb->RawCommand(cmd)); } -void fb_queue_download(const std::string& name, void* data, uint32_t size) { - Action& a = queue_action(OP_DOWNLOAD, ""); - a.data = data; - a.size = size; - a.msg = "Downloading '" + name + "'"; +void fb_download(const std::string& name, void* data, uint32_t size) { + Status("Downloading '" + name + "'"); + RUN_COMMAND(fb->Download(static_cast<char*>(data), size)); } -void fb_queue_download_fd(const std::string& name, int fd, uint32_t sz) { - Action& a = queue_action(OP_DOWNLOAD_FD, ""); - a.fd = fd; - a.size = sz; - a.msg = android::base::StringPrintf("Sending '%s' (%u KB)", name.c_str(), sz / 1024); +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_queue_upload(const std::string& outfile) { - Action& a = queue_action(OP_UPLOAD, ""); - a.data = xstrdup(outfile.c_str()); - a.msg = "Uploading '" + outfile + "'"; +void fb_upload(const std::string& outfile) { + Status("Uploading '" + outfile + "'"); + RUN_COMMAND(fb->Upload(outfile)); } -void fb_queue_notice(const std::string& notice) { - Action& a = queue_action(OP_NOTICE, ""); - a.msg = notice; +void fb_notice(const std::string& notice) { + Status(notice); + fprintf(stderr, "\n"); } -void fb_queue_wait_for_disconnect() { - queue_action(OP_WAIT_FOR_DISCONNECT, ""); -} - -int64_t fb_execute_queue() { - int64_t status = 0; - for (auto& a : action_list) { - a->start = now(); - if (!a->msg.empty()) { - fprintf(stderr, kStatusFormat, a->msg.c_str()); - verbose("\n"); - } - if (a->op == OP_DOWNLOAD) { - char* cbuf = static_cast<char*>(a->data); - status = fb->Download(cbuf, a->size); - status = a->func(*a, status, status ? fb_get_error().c_str() : ""); - if (status) break; - } else if (a->op == OP_DOWNLOAD_FD) { - status = fb->Download(a->fd, a->size); - status = a->func(*a, status, status ? fb_get_error().c_str() : ""); - if (status) break; - } else if (a->op == OP_COMMAND) { - status = fb->RawCommand(a->cmd); - status = a->func(*a, status, status ? fb_get_error().c_str() : ""); - if (status) break; - } else if (a->op == OP_QUERY) { - std::string resp; - status = fb->RawCommand(a->cmd, &resp); - status = a->func(*a, status, status ? fb_get_error().c_str() : resp.c_str()); - if (status) break; - } else if (a->op == OP_NOTICE) { - // We already showed the notice because it's in `Action::msg`. - fprintf(stderr, "\n"); - } else if (a->op == OP_DOWNLOAD_SPARSE) { - status = fb->Download(reinterpret_cast<sparse_file*>(a->data)); - status = a->func(*a, status, status ? fb_get_error().c_str() : ""); - if (status) break; - } else if (a->op == OP_WAIT_FOR_DISCONNECT) { - fb->WaitForDisconnect(); - } else if (a->op == OP_UPLOAD) { - status = fb->Upload(reinterpret_cast<const char*>(a->data)); - status = a->func(*a, status, status ? fb_get_error().c_str() : ""); - } else { - die("unknown action: %d", a->op); - } - } - action_list.clear(); - return status; +void fb_wait_for_disconnect() { + fb->WaitForDisconnect(); } bool fb_reboot_to_userspace() { - // First ensure that the queue is flushed. - fb_execute_queue(); - - fprintf(stderr, kStatusFormat, "Rebooting to userspace fastboot"); + Status("Rebooting to userspace fastboot"); verbose("\n"); if (fb->RebootTo("fastboot") != fastboot::RetCode::SUCCESS) { diff --git a/fastboot/engine.h b/fastboot/engine.h index f098ca7a645e4191200dc0e5a94b81b542f5f22f..d78cb1380e4e067daae21910cd1681fed5838fea 100644 --- a/fastboot/engine.h +++ b/fastboot/engine.h @@ -44,36 +44,29 @@ struct sparse_file; const std::string fb_get_error(); -//#define FB_COMMAND_SZ (fastboot::FB_COMMAND_SZ) -//#define FB_RESPONSE_SZ (fastboot::FB_RESPONSE_SZ) - -/* engine.c - high level command queue engine */ - void fb_init(fastboot::FastBootDriver& fbi); void fb_reinit(Transport* transport); bool fb_getvar(const std::string& key, std::string* value); -void fb_queue_flash(const std::string& partition, void* data, uint32_t sz); -void fb_queue_flash_fd(const std::string& partition, int fd, uint32_t sz); -void fb_queue_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz, - size_t current, size_t total); -void fb_queue_erase(const std::string& partition); -void fb_queue_format(const std::string& partition, int skip_if_not_supported, int32_t max_chunk_sz); -void fb_queue_require(const std::string& prod, const std::string& var, bool invert, size_t nvalues, - const char** values); -void fb_queue_display(const std::string& label, const std::string& var); -void fb_queue_query_save(const std::string& var, char* dest, uint32_t dest_size); -void fb_queue_reboot(void); -void fb_queue_command(const std::string& cmd, const std::string& msg); -void fb_queue_download(const std::string& name, void* data, uint32_t size); -void fb_queue_download_fd(const std::string& name, int fd, uint32_t sz); -void fb_queue_upload(const std::string& outfile); -void fb_queue_notice(const std::string& notice); -void fb_queue_wait_for_disconnect(void); -void fb_queue_create_partition(const std::string& partition, const std::string& size); -void fb_queue_delete_partition(const std::string& partition); -void fb_queue_resize_partition(const std::string& partition, const std::string& size); -int64_t fb_execute_queue(); +void fb_flash(const std::string& partition, void* data, uint32_t sz); +void fb_flash_fd(const std::string& partition, int fd, uint32_t sz); +void fb_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz, + size_t current, size_t total); +void fb_erase(const std::string& partition); +void fb_require(const std::string& prod, const std::string& var, bool invert, size_t nvalues, + const char** values); +void fb_display(const std::string& label, const std::string& var); +void fb_query_save(const std::string& var, char* dest, uint32_t dest_size); +void fb_reboot(); +void fb_command(const std::string& cmd, const std::string& msg); +void fb_download(const std::string& name, void* data, uint32_t size); +void fb_download_fd(const std::string& name, int fd, uint32_t sz); +void fb_upload(const std::string& outfile); +void fb_notice(const std::string& notice); +void fb_wait_for_disconnect(void); +void fb_create_partition(const std::string& partition, const std::string& size); +void fb_delete_partition(const std::string& partition); +void fb_resize_partition(const std::string& partition, const std::string& size); void fb_set_active(const std::string& slot); bool fb_reboot_to_userspace(); diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 1aef567f20567cdb44675049b96faeabf8be7ab5..817afd0266cbf66501ccc76f54d1e1dd1fdf5f4b 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -688,7 +688,7 @@ static void check_requirement(char* line) { out[i] = xstrdup(strip(val[i])); } - fb_queue_require(product, var, invert, count, out); + fb_require(product, var, invert, count, out); } static void check_requirements(char* data, int64_t sz) { @@ -702,15 +702,14 @@ static void check_requirements(char* data, int64_t sz) { s++; } } - if (fb_execute_queue()) die("requirements not met!"); } -static void queue_info_dump() { - fb_queue_notice("--------------------------------------------"); - fb_queue_display("Bootloader Version...", "version-bootloader"); - fb_queue_display("Baseband Version.....", "version-baseband"); - fb_queue_display("Serial Number........", "serialno"); - fb_queue_notice("--------------------------------------------"); +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 struct sparse_file** load_sparse_files(int fd, int64_t max_size) { @@ -883,12 +882,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_queue_flash_sparse(partition, pair.first, pair.second, i + 1, sparse_files.size()); + fb_flash_sparse(partition, pair.first, pair.second, i + 1, sparse_files.size()); } break; } case FB_BUFFER_FD: - fb_queue_flash_fd(partition, buf->fd, buf->sz); + fb_flash_fd(partition, buf->fd, buf->sz); break; default: die("unknown buffer type: %d", buf->type); @@ -1145,7 +1144,7 @@ void FlashAllTool::Flash() { for (const auto& [image, slot] : os_images_) { auto resize_partition = [](const std::string& partition) -> void { if (is_logical(partition)) { - fb_queue_resize_partition(partition, "0"); + fb_resize_partition(partition, "0"); } }; do_for_partitions(image->part_name, slot, resize_partition, false); @@ -1223,12 +1222,12 @@ void FlashAllTool::FlashImage(const Image& image, const std::string& slot, fastb int64_t sz; void* data = source_.ReadFile(image.sig_name, &sz); if (data) { - fb_queue_download("signature", data, sz); - fb_queue_command("signature", "installing signature"); + fb_download("signature", data, sz); + fb_command("signature", "installing signature"); } if (is_logical(partition_name)) { - fb_queue_resize_partition(partition_name, std::to_string(buf->image_size)); + fb_resize_partition(partition_name, std::to_string(buf->image_size)); } flash_buf(partition_name.c_str(), buf); }; @@ -1247,17 +1246,13 @@ void FlashAllTool::UpdateSuperPartition() { if (!is_userspace_fastboot()) { reboot_to_userspace_fastboot(); } - fb_queue_download_fd("super", fd, get_file_size(fd)); + fb_download_fd("super", fd, get_file_size(fd)); std::string command = "update-super:super"; if (wipe_) { command += ":wipe"; } - fb_queue_command(command, "Updating super partition"); - - // We need these commands to have finished before proceeding, since - // otherwise "getvar is-logical" may not return a correct answer below. - fb_execute_queue(); + fb_command(command, "Updating super partition"); } class ZipImageSource final : public ImageSource { @@ -1279,9 +1274,9 @@ int ZipImageSource::OpenFile(const std::string& name) const { } static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary) { - queue_info_dump(); + dump_info(); - fb_queue_query_save("product", cur_product, sizeof(cur_product)); + fb_query_save("product", cur_product, sizeof(cur_product)); ZipArchiveHandle zip; int error = OpenArchive(filename, &zip); @@ -1316,9 +1311,9 @@ 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; - queue_info_dump(); + dump_info(); - fb_queue_query_save("product", cur_product, sizeof(cur_product)); + fb_query_save("product", cur_product, sizeof(cur_product)); FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe); tool.Flash(); @@ -1338,7 +1333,7 @@ static void do_oem_command(const std::string& cmd, std::vector<std::string>* arg while (!args->empty()) { command += " " + next_arg(args); } - fb_queue_command(command, ""); + fb_command(command, ""); } static std::string fb_fix_numeric_var(std::string var) { @@ -1641,7 +1636,7 @@ int FastBootTool::Main(int argc, char* argv[]) { if (command == "getvar") { std::string variable = next_arg(&args); - fb_queue_display(variable, variable); + fb_display(variable, variable); } else if (command == "erase") { std::string partition = next_arg(&args); auto erase = [&](const std::string& partition) { @@ -1653,7 +1648,7 @@ int FastBootTool::Main(int argc, char* argv[]) { partition_type.c_str()); } - fb_queue_erase(partition); + fb_erase(partition); }; do_for_partitions(partition, slot_override, erase, true); } else if (android::base::StartsWith(command, "format")) { @@ -1681,8 +1676,8 @@ int FastBootTool::Main(int argc, char* argv[]) { data = load_file(filename.c_str(), &sz); if (data == nullptr) die("could not load '%s': %s", filename.c_str(), strerror(errno)); if (sz != 256) die("signature must be 256 bytes (got %" PRId64 ")", sz); - fb_queue_download("signature", data, sz); - fb_queue_command("signature", "installing signature"); + fb_download("signature", data, sz); + fb_command("signature", "installing signature"); } else if (command == "reboot") { wants_reboot = true; @@ -1710,7 +1705,7 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "reboot-fastboot") { wants_reboot_fastboot = true; } else if (command == "continue") { - fb_queue_command("continue", "resuming boot"); + fb_command("continue", "resuming boot"); } else if (command == "boot") { std::string kernel = next_arg(&args); std::string ramdisk; @@ -1719,8 +1714,8 @@ int FastBootTool::Main(int argc, char* argv[]) { if (!args.empty()) second_stage = next_arg(&args); data = load_bootable_image(kernel, ramdisk, second_stage, &sz); - fb_queue_download("boot.img", data, sz); - fb_queue_command("boot", "booting"); + fb_download("boot.img", data, sz); + fb_command("boot", "booting"); } else if (command == "flash") { std::string pname = next_arg(&args); @@ -1746,7 +1741,7 @@ int FastBootTool::Main(int argc, char* argv[]) { data = load_bootable_image(kernel, ramdisk, second_stage, &sz); auto flashraw = [&](const std::string& partition) { - fb_queue_flash(partition, data, sz); + fb_flash(partition, data, sz); }; do_for_partitions(partition, slot_override, flashraw, true); } else if (command == "flashall") { @@ -1778,10 +1773,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_queue_download_fd(filename, buf.fd, buf.sz); + fb_download_fd(filename, buf.fd, buf.sz); } else if (command == "get_staged") { std::string filename = next_arg(&args); - fb_queue_upload(filename); + fb_upload(filename); } else if (command == "oem") { do_oem_command("oem", &args); } else if (command == "flashing") { @@ -1798,14 +1793,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_queue_create_partition(partition, size); + fb_create_partition(partition, size); } else if (command == "delete-logical-partition") { std::string partition = next_arg(&args); - fb_queue_delete_partition(partition); + fb_delete_partition(partition); } else if (command == "resize-logical-partition") { std::string partition = next_arg(&args); std::string size = next_arg(&args); - fb_queue_resize_partition(partition, size); + fb_resize_partition(partition, size); } else { syntax_error("unknown command %s", command.c_str()); } @@ -1817,7 +1812,7 @@ int FastBootTool::Main(int argc, char* argv[]) { std::string partition_type; if (!fb_getvar(std::string{"partition-type:"} + partition, &partition_type)) continue; if (partition_type.empty()) continue; - fb_queue_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(); @@ -1832,26 +1827,25 @@ int FastBootTool::Main(int argc, char* argv[]) { fb_set_active(next_active); } if (wants_reboot && !skip_reboot) { - fb_queue_reboot(); - fb_queue_wait_for_disconnect(); + fb_reboot(); + fb_wait_for_disconnect(); } else if (wants_reboot_bootloader) { - fb_queue_command("reboot-bootloader", "rebooting into bootloader"); - fb_queue_wait_for_disconnect(); + fb_command("reboot-bootloader", "rebooting into bootloader"); + fb_wait_for_disconnect(); } else if (wants_reboot_recovery) { - fb_queue_command("reboot-recovery", "rebooting into recovery"); - fb_queue_wait_for_disconnect(); + fb_command("reboot-recovery", "rebooting into recovery"); + fb_wait_for_disconnect(); } else if (wants_reboot_fastboot) { - fb_queue_command("reboot-fastboot", "rebooting into fastboot"); - fb_queue_wait_for_disconnect(); + fb_command("reboot-fastboot", "rebooting into fastboot"); + fb_wait_for_disconnect(); } - int status = fb_execute_queue() ? EXIT_FAILURE : EXIT_SUCCESS; fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start)); if (Transport* old_transport = fb.set_transport(nullptr)) { delete old_transport; } - return status; + return 0; } void FastBootTool::ParseOsPatchLevel(boot_img_hdr_v1* hdr, const char* arg) { diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp index f9e640ab33a1f184955d7a9f2176f72bae4de9d4..4a14131a75b5bb76080411e512ead10cbc0091c0 100644 --- a/fastboot/fastboot_driver.cpp +++ b/fastboot/fastboot_driver.cpp @@ -97,9 +97,9 @@ RetCode FastBootDriver::RebootTo(std::string target, std::string* response, return RawCommand("reboot-" + target, response, info); } -RetCode FastBootDriver::SetActive(const std::string& part, std::string* response, +RetCode FastBootDriver::SetActive(const std::string& slot, std::string* response, std::vector<std::string>* info) { - return RawCommand(Commands::SET_ACTIVE + part, response, info); + return RawCommand(Commands::SET_ACTIVE + slot, response, info); } RetCode FastBootDriver::FlashPartition(const std::string& part, const std::vector<char>& data) { diff --git a/fastboot/fastboot_driver.h b/fastboot/fastboot_driver.h index ca9003a0bd02a55c80dca14878120689bcb04af0..4d85ba05e9f0f24cb0ecf6c6bd3d7282eedbb2a0 100644 --- a/fastboot/fastboot_driver.h +++ b/fastboot/fastboot_driver.h @@ -89,7 +89,7 @@ class FastBootDriver { RetCode Reboot(std::string* response = nullptr, std::vector<std::string>* info = nullptr); RetCode RebootTo(std::string target, std::string* response = nullptr, std::vector<std::string>* info = nullptr); - RetCode SetActive(const std::string& part, std::string* response = nullptr, + RetCode SetActive(const std::string& slot, std::string* response = nullptr, std::vector<std::string>* info = nullptr); RetCode Upload(const std::string& outfile, std::string* response = nullptr, std::vector<std::string>* info = nullptr); diff --git a/fastboot/util.cpp b/fastboot/util.cpp index 8f6e52afb1f1edef919293b8db34ecdaad25f7e8..125182d73aa786b79242996a43250f6dd603460c 100644 --- a/fastboot/util.cpp +++ b/fastboot/util.cpp @@ -70,6 +70,11 @@ void verbose(const char* fmt, ...) { fprintf(stderr, "\n"); } +void Status(const std::string& message) { + static constexpr char kStatusFormat[] = "%-50s "; + fprintf(stderr, kStatusFormat, message.c_str()); +} + char* xstrdup(const char* s) { char* result = strdup(s); if (!result) die("out of memory"); diff --git a/fastboot/util.h b/fastboot/util.h index 9033f933a7784476e35792d58096c486dece07c2..20be46167bcc6bfcd2d8228fb5405ff57e17ff9a 100644 --- a/fastboot/util.h +++ b/fastboot/util.h @@ -12,6 +12,8 @@ double now(); char* xstrdup(const char*); void set_verbose(); +void Status(const std::string& message); + // These printf-like functions are implemented in terms of vsnprintf, so they // use the same attribute for compile-time format string checking. void die(const char* fmt, ...) __attribute__((__noreturn__))