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));