fastboot: Move some helpers into util.h/.cpp.

Bug: 266982466
Test: builds
Change-Id: Ib744d763e11d8a7f7e3f417b331defff61fe4559
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 716fc4f..7a5a782 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -107,8 +107,6 @@
 
 fastboot::FastBootDriver* fb = nullptr;
 
-using SparsePtr = std::unique_ptr<sparse_file, decltype(&sparse_file_destroy)>;
-
 enum fb_buffer_type {
     FB_BUFFER_FD,
     FB_BUFFER_SPARSE,
@@ -249,14 +247,6 @@
     fprintf(stderr, "(bootloader) %s\n", info.c_str());
 }
 
-static int64_t get_file_size(borrowed_fd fd) {
-    struct stat sb;
-    if (fstat(fd.get(), &sb) == -1) {
-        die("could not get file size");
-    }
-    return sb.st_size;
-}
-
 bool ReadFileToVector(const std::string& file, std::vector<char>* out) {
     out->clear();
 
@@ -827,19 +817,16 @@
     fprintf(stderr, "--------------------------------------------\n");
 }
 
-static std::vector<SparsePtr> load_sparse_files(int fd, int64_t max_size) {
-    SparsePtr s(sparse_file_import_auto(fd, false, true), sparse_file_destroy);
-    if (!s) die("cannot sparse read file");
-
+static std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size) {
     if (max_size <= 0 || max_size > std::numeric_limits<uint32_t>::max()) {
         die("invalid max size %" PRId64, max_size);
     }
 
-    const int files = sparse_file_resparse(s.get(), max_size, nullptr, 0);
+    const int files = sparse_file_resparse(s, max_size, nullptr, 0);
     if (files < 0) die("Failed to resparse");
 
     auto temp = std::make_unique<sparse_file*[]>(files);
-    const int rv = sparse_file_resparse(s.get(), max_size, temp.get(), files);
+    const int rv = sparse_file_resparse(s, max_size, temp.get(), files);
     if (rv < 0) die("Failed to resparse");
 
     std::vector<SparsePtr> out_s;
@@ -849,6 +836,13 @@
     return out_s;
 }
 
+static std::vector<SparsePtr> load_sparse_files(int fd, int64_t max_size) {
+    SparsePtr s(sparse_file_import_auto(fd, false, true), sparse_file_destroy);
+    if (!s) die("cannot sparse read file");
+
+    return resparse_file(s.get(), max_size);
+}
+
 static uint64_t get_uint_var(const char* var_name) {
     std::string value_str;
     if (fb->GetVar(var_name, &value_str) != fastboot::SUCCESS || value_str.empty()) {
@@ -998,6 +992,8 @@
            fb->GetVar("partition-type:vbmeta_b", &partition_type) == fastboot::SUCCESS;
 }
 
+// Note: this only works in userspace fastboot. In the bootloader, use
+// should_flash_in_userspace().
 static bool is_logical(const std::string& partition) {
     std::string value;
     return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes";
@@ -1080,6 +1076,15 @@
     lseek(buf->fd.get(), 0, SEEK_SET);
 }
 
+static void flash_partition_files(const std::string& partition,
+                                  const std::vector<SparsePtr>& files) {
+    for (size_t i = 0; i < files.size(); i++) {
+        sparse_file* s = files[i].get();
+        int64_t sz = sparse_file_len(s, true, false);
+        fb->FlashPartition(partition, s, sz, i + 1, files.size());
+    }
+}
+
 static void flash_buf(const std::string& partition, struct fastboot_buffer* buf) {
     if (partition == "boot" || partition == "boot_a" || partition == "boot_b" ||
         partition == "init_boot" || partition == "init_boot_a" || partition == "init_boot_b" ||
@@ -1103,11 +1108,7 @@
 
     switch (buf->type) {
         case FB_BUFFER_SPARSE: {
-            for (size_t i = 0; i < buf->files.size(); i++) {
-                sparse_file* s = buf->files[i].get();
-                int64_t sz = sparse_file_len(s, true, false);
-                fb->FlashPartition(partition, s, sz, i + 1, buf->files.size());
-            }
+            flash_partition_files(partition, buf->files);
             break;
         }
         case FB_BUFFER_FD:
@@ -1395,13 +1396,6 @@
     }
 }
 
-class ImageSource {
-  public:
-    virtual ~ImageSource(){};
-    virtual bool ReadFile(const std::string& name, std::vector<char>* out) const = 0;
-    virtual unique_fd OpenFile(const std::string& name) const = 0;
-};
-
 class FlashAllTool {
   public:
     FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary,
@@ -1775,20 +1769,7 @@
     if (!metadata) {
         return false;
     }
-    for (const auto& partition : metadata->partitions) {
-        auto candidate = android::fs_mgr::GetPartitionName(partition);
-        if (partition.attributes & LP_PARTITION_ATTR_SLOT_SUFFIXED) {
-            // On retrofit devices, we don't know if, or whether, the A or B
-            // slot has been flashed for dynamic partitions. Instead we add
-            // both names to the list as a conservative guess.
-            if (candidate + "_a" == partition_name || candidate + "_b" == partition_name) {
-                return true;
-            }
-        } else if (candidate == partition_name) {
-            return true;
-        }
-    }
-    return false;
+    return should_flash_in_userspace(*metadata.get(), partition_name);
 }
 
 static bool wipe_super(const android::fs_mgr::LpMetadata& metadata, const std::string& slot,