Added Flashing Plan
Fastboot has a lot of flags that are used by many different functions
including the Flashall Class and newly added FlashSuperTask. Passing all
of these flags as paramaters is cumbersome, so adding a Flashing Plan
that contains these flags simplifies the code.
Test: tested Flashall and update img.zip on raven
Change-Id: I9c842f25389a20b852d55f684e1b86040af1d86a
Bug: 194686221
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 5172530..e2e734e 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -128,25 +128,6 @@
int64_t image_size;
};
-enum class ImageType {
- // Must be flashed for device to boot into the kernel.
- BootCritical,
- // Normal partition to be flashed during "flashall".
- Normal,
- // Partition that is never flashed during "flashall".
- Extra
-};
-
-struct Image {
- std::string nickname;
- std::string img_name;
- std::string sig_name;
- std::string part_name;
- bool optional_if_no_image;
- ImageType type;
- bool IsSecondary() const { return nickname.empty(); }
-};
-
static std::vector<Image> images = {
// clang-format off
{ "boot", "boot.img", "boot.sig", "boot", false, ImageType::BootCritical },
@@ -1580,8 +1561,7 @@
class FlashAllTool {
public:
- FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary,
- bool wipe, bool force_flash);
+ FlashAllTool(FlashingPlan* fp);
void Flash();
@@ -1601,25 +1581,12 @@
std::string GetPartitionName(const ImageEntry& entry);
- const ImageSource& source_;
- std::string slot_override_;
- bool skip_secondary_;
- bool wipe_;
- bool force_flash_;
- std::string current_slot_;
- std::string secondary_slot_;
-
std::vector<ImageEntry> boot_images_;
std::vector<ImageEntry> os_images_;
+ FlashingPlan* fp_;
};
-FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_override,
- bool skip_secondary, bool wipe, bool force_flash)
- : source_(source),
- slot_override_(slot_override),
- skip_secondary_(skip_secondary),
- wipe_(wipe),
- force_flash_(force_flash) {}
+FlashAllTool::FlashAllTool(FlashingPlan* fp) : fp_(fp) {}
void FlashAllTool::Flash() {
DumpInfo();
@@ -1627,10 +1594,10 @@
// Change the slot first, so we boot into the correct recovery image when
// using fastbootd.
- if (slot_override_ == "all") {
+ if (fp_->slot == "all") {
set_active("a");
} else {
- set_active(slot_override_);
+ set_active(fp_->slot);
}
DetermineSlot();
@@ -1667,13 +1634,13 @@
LOG(VERBOSE) << "Cannot optimize flashing super on non-AB device";
return false;
}
- if (slot_override_ == "all") {
+ if (fp_->slot == "all") {
LOG(VERBOSE) << "Cannot optimize flashing super for all slots";
return false;
}
// Does this device use dynamic partitions at all?
- unique_fd fd = source_.OpenFile("super_empty.img");
+ unique_fd fd = fp_->source->OpenFile("super_empty.img");
if (fd < 0) {
LOG(VERBOSE) << "could not open super_empty.img";
return false;
@@ -1690,7 +1657,7 @@
return false;
}
- SuperFlashHelper helper(source_);
+ SuperFlashHelper helper(*fp_->source);
if (!helper.Open(fd)) {
return false;
}
@@ -1730,43 +1697,43 @@
void FlashAllTool::CheckRequirements() {
std::vector<char> contents;
- if (!source_.ReadFile("android-info.txt", &contents)) {
+ if (!fp_->source->ReadFile("android-info.txt", &contents)) {
die("could not read android-info.txt");
}
- ::CheckRequirements({contents.data(), contents.size()}, force_flash_);
+ ::CheckRequirements({contents.data(), contents.size()}, fp_->force_flash);
}
void FlashAllTool::DetermineSlot() {
- if (slot_override_.empty()) {
- current_slot_ = get_current_slot();
+ if (fp_->slot.empty()) {
+ fp_->current_slot = get_current_slot();
} else {
- current_slot_ = slot_override_;
+ fp_->current_slot = fp_->slot;
}
- if (skip_secondary_) {
+ if (fp_->skip_secondary) {
return;
}
- if (slot_override_ != "" && slot_override_ != "all") {
- secondary_slot_ = get_other_slot(slot_override_);
+ if (fp_->slot != "" && fp_->slot != "all") {
+ fp_->secondary_slot = get_other_slot(fp_->slot);
} else {
- secondary_slot_ = get_other_slot();
+ fp_->secondary_slot = get_other_slot();
}
- if (secondary_slot_ == "") {
+ if (fp_->secondary_slot == "") {
if (supports_AB()) {
fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
}
- skip_secondary_ = true;
+ fp_->skip_secondary = true;
}
}
void FlashAllTool::CollectImages() {
for (size_t i = 0; i < images.size(); ++i) {
- std::string slot = slot_override_;
+ std::string slot = fp_->slot;
if (images[i].IsSecondary()) {
- if (skip_secondary_) {
+ if (fp_->skip_secondary) {
continue;
}
- slot = secondary_slot_;
+ slot = fp_->secondary_slot;
}
if (images[i].type == ImageType::BootCritical) {
boot_images_.emplace_back(&images[i], slot);
@@ -1779,7 +1746,7 @@
void FlashAllTool::FlashImages(const std::vector<std::pair<const Image*, std::string>>& images) {
for (const auto& [image, slot] : images) {
fastboot_buffer buf;
- unique_fd fd = source_.OpenFile(image->img_name);
+ unique_fd fd = fp_->source->OpenFile(image->img_name);
if (fd < 0 || !load_buf_fd(std::move(fd), &buf)) {
if (image->optional_if_no_image) {
continue;
@@ -1793,7 +1760,7 @@
void FlashAllTool::FlashImage(const Image& image, const std::string& slot, fastboot_buffer* buf) {
auto flash = [&, this](const std::string& partition_name) {
std::vector<char> signature_data;
- if (source_.ReadFile(image.sig_name, &signature_data)) {
+ if (fp_->source->ReadFile(image.sig_name, &signature_data)) {
fb->Download("signature", signature_data);
fb->RawCommand("signature", "installing signature");
}
@@ -1807,7 +1774,7 @@
}
void FlashAllTool::UpdateSuperPartition() {
- unique_fd fd = source_.OpenFile("super_empty.img");
+ unique_fd fd = fp_->source->OpenFile("super_empty.img");
if (fd < 0) {
return;
}
@@ -1822,7 +1789,7 @@
fb->Download(super_name, fd, get_file_size(fd));
std::string command = "update-super:" + super_name;
- if (wipe_) {
+ if (fp_->wants_wipe) {
command += ":wipe";
}
fb->RawCommand(command, "Updating super partition");
@@ -1844,7 +1811,7 @@
std::string FlashAllTool::GetPartitionName(const ImageEntry& entry) {
auto slot = entry.second;
if (slot.empty()) {
- slot = current_slot_;
+ slot = fp_->current_slot;
}
if (slot.empty()) {
return entry.first->part_name;
@@ -1873,15 +1840,16 @@
return unzip_to_file(zip_, name.c_str());
}
-static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary,
- bool force_flash) {
+static void do_update(const char* filename, FlashingPlan* fp) {
ZipArchiveHandle zip;
int error = OpenArchive(filename, &zip);
if (error != 0) {
die("failed to open zip file '%s': %s", filename, ErrorCodeString(error));
}
-
- FlashAllTool tool(ZipImageSource(zip), slot_override, skip_secondary, false, force_flash);
+ ZipImageSource zp = ZipImageSource(zip);
+ fp->source = &zp;
+ fp->wants_wipe = false;
+ FlashAllTool tool(fp);
tool.Flash();
CloseArchive(zip);
@@ -1906,9 +1874,10 @@
return unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_BINARY)));
}
-static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe,
- bool force_flash) {
- FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe, force_flash);
+static void do_flashall(FlashingPlan* fp) {
+ LocalImageSource s = LocalImageSource();
+ fp->source = &s;
+ FlashAllTool tool(fp);
tool.Flash();
}
@@ -2143,12 +2112,8 @@
int FastBootTool::Main(int argc, char* argv[]) {
android::base::InitLogging(argv, FastbootLogger, FastbootAborter);
+ std::unique_ptr<FlashingPlan> fp = std::make_unique<FlashingPlan>();
- bool wants_wipe = false;
- bool skip_reboot = false;
- bool wants_set_active = false;
- bool skip_secondary = false;
- bool force_flash = false;
unsigned fs_options = 0;
int longindex;
std::string slot_override;
@@ -2201,7 +2166,7 @@
} else if (name == "disable-verity") {
g_disable_verity = true;
} else if (name == "force") {
- force_flash = true;
+ fp->force_flash = true;
} else if (name == "fs-options") {
fs_options = ParseFsOption(optarg);
} else if (name == "header-version") {
@@ -2220,9 +2185,9 @@
} else if (name == "ramdisk-offset") {
g_boot_img_hdr.ramdisk_addr = strtoul(optarg, 0, 16);
} else if (name == "skip-reboot") {
- skip_reboot = true;
+ fp->skip_reboot = true;
} else if (name == "skip-secondary") {
- skip_secondary = true;
+ fp->skip_secondary = true;
} else if (name == "slot") {
slot_override = optarg;
} else if (name == "dtb-offset") {
@@ -2243,7 +2208,7 @@
} else {
switch (c) {
case 'a':
- wants_set_active = true;
+ fp->wants_set_active = true;
if (optarg) next_active = optarg;
break;
case 'h':
@@ -2263,7 +2228,7 @@
set_verbose();
break;
case 'w':
- wants_wipe = true;
+ fp->wants_wipe = true;
break;
case '?':
return 1;
@@ -2276,7 +2241,7 @@
argc -= optind;
argv += optind;
- if (argc == 0 && !wants_wipe && !wants_set_active) syntax_error("no command");
+ if (argc == 0 && !fp->wants_wipe && !fp->wants_set_active) syntax_error("no command");
if (argc > 0 && !strcmp(*argv, "devices")) {
list_devices();
@@ -2318,7 +2283,7 @@
if (slot_override != "") slot_override = verify_slot(slot_override);
if (next_active != "") next_active = verify_slot(next_active, false);
- if (wants_set_active) {
+ if (fp->wants_set_active) {
if (next_active == "") {
if (slot_override == "") {
std::string current_slot;
@@ -2326,7 +2291,7 @@
if (current_slot[0] == '_') current_slot.erase(0, 1);
next_active = verify_slot(current_slot, false);
} else {
- wants_set_active = false;
+ fp->wants_set_active = false;
}
} else {
next_active = verify_slot(slot_override, false);
@@ -2418,7 +2383,7 @@
fname = find_item(pname);
}
if (fname.empty()) die("cannot determine image filename for '%s'", pname.c_str());
- FlashTask task(slot_override, force_flash, pname, fname);
+ FlashTask task(slot_override, fp->force_flash, pname, fname);
task.Run();
} else if (command == "flash:raw") {
std::string partition = next_arg(&args);
@@ -2437,9 +2402,10 @@
if (slot_override == "all") {
fprintf(stderr,
"Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
- do_flashall(slot_override, true, wants_wipe, force_flash);
+ fp->skip_secondary = true;
+ do_flashall(fp.get());
} else {
- do_flashall(slot_override, skip_secondary, wants_wipe, force_flash);
+ do_flashall(fp.get());
}
reboot_task = std::make_unique<RebootTask>(fb);
} else if (command == "update") {
@@ -2452,7 +2418,7 @@
if (!args.empty()) {
filename = next_arg(&args);
}
- do_update(filename.c_str(), slot_override, skip_secondary || slot_all, force_flash);
+ do_update(filename.c_str(), fp.get());
reboot_task = std::make_unique<RebootTask>(fb);
} else if (command == FB_CMD_SET_ACTIVE) {
std::string slot = verify_slot(next_arg(&args), false);
@@ -2525,8 +2491,8 @@
syntax_error("unknown command %s", command.c_str());
}
}
- if (wants_wipe) {
- if (force_flash) {
+ if (fp->wants_wipe) {
+ if (fp->force_flash) {
CancelSnapshotIfNeeded();
}
std::vector<std::string> partitions = {"userdata", "cache", "metadata"};
@@ -2540,10 +2506,10 @@
fb_perform_format(partition, 1, partition_type, "", fs_options);
}
}
- if (wants_set_active) {
+ if (fp->wants_set_active) {
fb->SetActive(next_active);
}
- if (reboot_task && !skip_reboot) {
+ if (reboot_task && !fp->skip_reboot) {
reboot_task->Run();
}
fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start));