Added support for FlashSuperLayoutTask
Test: testing flashall code with this change
Bug: 194686221
Change-Id: Ibb96980402db51b48c9a296338f29195f68c65bf
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 430ff14..0e5f3fb 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -982,7 +982,7 @@
fprintf(stderr, "--------------------------------------------\n");
}
-static std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size) {
+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);
}
@@ -1027,7 +1027,7 @@
return value;
}
-static int64_t get_sparse_limit(int64_t size) {
+int64_t get_sparse_limit(int64_t size) {
int64_t limit = sparse_limit;
if (limit == 0) {
// Unlimited, so see what the target device's limit is.
@@ -1161,7 +1161,7 @@
// Note: this only works in userspace fastboot. In the bootloader, use
// should_flash_in_userspace().
-static bool is_logical(const std::string& partition) {
+bool is_logical(const std::string& partition) {
std::string value;
return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes";
}
@@ -1243,8 +1243,7 @@
lseek(buf->fd.get(), 0, SEEK_SET);
}
-static void flash_partition_files(const std::string& partition,
- const std::vector<SparsePtr>& files) {
+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);
@@ -1303,7 +1302,7 @@
return count;
}
-static bool supports_AB() {
+bool supports_AB() {
return get_slot_count() >= 2;
}
@@ -1426,7 +1425,7 @@
}
}
-static bool is_retrofit_device() {
+bool is_retrofit_device() {
std::string value;
if (fb->GetVar("super-partition-name", &value) != fastboot::SUCCESS) {
return false;
@@ -1562,6 +1561,20 @@
}
}
+std::string GetPartitionName(const ImageEntry& entry, std::string& current_slot) {
+ auto slot = entry.second;
+ if (slot.empty()) {
+ slot = current_slot;
+ }
+ if (slot.empty()) {
+ return entry.first->part_name;
+ }
+ if (slot == "all") {
+ LOG(FATAL) << "Cannot retrieve a singular name when using all slots";
+ }
+ return entry.first->part_name + "_" + slot;
+}
+
class FlashAllTool {
public:
FlashAllTool(FlashingPlan* fp);
@@ -1575,15 +1588,12 @@
void FlashImages(const std::vector<std::pair<const Image*, std::string>>& images);
void FlashImage(const Image& image, const std::string& slot, fastboot_buffer* buf);
void UpdateSuperPartition();
- bool OptimizedFlashSuper();
// If the image uses the default slot, or the user specified "all", then
// the paired string will be empty. If the image requests a specific slot
// (for example, system_other) it is specified instead.
using ImageEntry = std::pair<const Image*, std::string>;
- std::string GetPartitionName(const ImageEntry& entry);
-
std::vector<ImageEntry> boot_images_;
std::vector<ImageEntry> os_images_;
FlashingPlan* fp_;
@@ -1612,10 +1622,13 @@
// or in bootloader fastboot.
FlashImages(boot_images_);
- if (!OptimizedFlashSuper()) {
+ auto flash_super_task = FlashSuperLayoutTask::Initialize(fp_, os_images_);
+
+ if (flash_super_task) {
+ flash_super_task->Run();
+ } else {
// Sync the super partition. This will reboot to userspace fastboot if needed.
UpdateSuperPartition();
-
// Resize any logical partition to 0, so each partition is reset to 0
// extents, and will achieve more optimal allocation.
for (const auto& [image, slot] : os_images_) {
@@ -1627,77 +1640,9 @@
do_for_partitions(image->part_name, slot, resize_partition, false);
}
}
-
- // Flash OS images, resizing logical partitions as needed.
FlashImages(os_images_);
}
-bool FlashAllTool::OptimizedFlashSuper() {
- if (!supports_AB()) {
- LOG(VERBOSE) << "Cannot optimize flashing super on non-AB device";
- return false;
- }
- 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 = fp_->source->OpenFile("super_empty.img");
- if (fd < 0) {
- LOG(VERBOSE) << "could not open super_empty.img";
- return false;
- }
-
- // Try to find whether there is a super partition.
- std::string super_name;
- if (fb->GetVar("super-partition-name", &super_name) != fastboot::SUCCESS) {
- super_name = "super";
- }
- std::string partition_size_str;
- if (fb->GetVar("partition-size:" + super_name, &partition_size_str) != fastboot::SUCCESS) {
- LOG(VERBOSE) << "Cannot optimize super flashing: could not determine super partition";
- return false;
- }
-
- SuperFlashHelper helper(*fp_->source);
- if (!helper.Open(fd)) {
- return false;
- }
-
- for (const auto& entry : os_images_) {
- auto partition = GetPartitionName(entry);
- auto image = entry.first;
-
- if (!helper.AddPartition(partition, image->img_name, image->optional_if_no_image)) {
- return false;
- }
- }
-
- auto s = helper.GetSparseLayout();
- if (!s) {
- return false;
- }
-
- std::vector<SparsePtr> files;
- if (int limit = get_sparse_limit(sparse_file_len(s.get(), false, false))) {
- files = resparse_file(s.get(), limit);
- } else {
- files.emplace_back(std::move(s));
- }
-
- // Send the data to the device.
- flash_partition_files(super_name, files);
-
- // Remove images that we already flashed, just in case we have non-dynamic OS images.
- auto remove_if_callback = [&, this](const ImageEntry& entry) -> bool {
- return helper.WillFlash(GetPartitionName(entry));
- };
- os_images_.erase(std::remove_if(os_images_.begin(), os_images_.end(), remove_if_callback),
- os_images_.end());
- return true;
-}
-
void FlashAllTool::CheckRequirements() {
std::vector<char> contents;
if (!fp_->source->ReadFile("android-info.txt", &contents)) {
@@ -1811,20 +1756,6 @@
}
}
-std::string FlashAllTool::GetPartitionName(const ImageEntry& entry) {
- auto slot = entry.second;
- if (slot.empty()) {
- slot = fp_->current_slot;
- }
- if (slot.empty()) {
- return entry.first->part_name;
- }
- if (slot == "all") {
- LOG(FATAL) << "Cannot retrieve a singular name when using all slots";
- }
- return entry.first->part_name + "_" + slot;
-}
-
class ZipImageSource final : public ImageSource {
public:
explicit ZipImageSource(ZipArchiveHandle zip) : zip_(zip) {}
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index 09666aa..2264ca3 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -29,6 +29,7 @@
#include <string>
#include "fastboot_driver.h"
+#include "super_flash_helper.h"
#include "util.h"
#include <bootimg.h>
@@ -82,7 +83,6 @@
std::string current_slot;
std::string secondary_slot;
fastboot::FastBootDriver* fb;
-
};
bool should_flash_in_userspace(const std::string& partition_name);
@@ -100,4 +100,12 @@
int port;
};
-Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial);
\ No newline at end of file
+Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial);
+bool supports_AB();
+std::string GetPartitionName(const ImageEntry& entry, std::string& current_slot_);
+void flash_partition_files(const std::string& partition, const std::vector<SparsePtr>& files);
+int64_t get_sparse_limit(int64_t size);
+std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size);
+
+bool is_retrofit_device();
+bool is_logical(const std::string& partition);
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index a4aa637..e77fa4a 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -14,11 +14,12 @@
// limitations under the License.
//
#include "task.h"
+#include <iostream>
#include "fastboot.h"
-#include "util.h"
+#include "filesystem.h"
+#include "super_flash_helper.h"
-#include "fastboot.h"
-#include "util.h"
+using namespace std::string_literals;
FlashTask::FlashTask(const std::string& _slot, const std::string& _pname)
: pname_(_pname), fname_(find_item(_pname)), slot_(_slot) {
@@ -66,3 +67,78 @@
syntax_error("unknown reboot target %s", reboot_target_.c_str());
}
}
+
+FlashSuperLayoutTask::FlashSuperLayoutTask(const std::string& super_name,
+ std::unique_ptr<SuperFlashHelper> helper,
+ SparsePtr sparse_layout)
+ : super_name_(super_name),
+ helper_(std::move(helper)),
+ sparse_layout_(std::move(sparse_layout)) {}
+
+void FlashSuperLayoutTask::Run() {
+ std::vector<SparsePtr> files;
+ if (int limit = get_sparse_limit(sparse_file_len(sparse_layout_.get(), false, false))) {
+ files = resparse_file(sparse_layout_.get(), limit);
+ } else {
+ files.emplace_back(std::move(sparse_layout_));
+ }
+
+ // Send the data to the device.
+ flash_partition_files(super_name_, files);
+}
+
+std::unique_ptr<FlashSuperLayoutTask> FlashSuperLayoutTask::Initialize(
+ FlashingPlan* fp, std::vector<ImageEntry>& os_images) {
+ if (!supports_AB()) {
+ LOG(VERBOSE) << "Cannot optimize flashing super on non-AB device";
+ return nullptr;
+ }
+ if (fp->slot == "all") {
+ LOG(VERBOSE) << "Cannot optimize flashing super for all slots";
+ return nullptr;
+ }
+
+ // Does this device use dynamic partitions at all?
+ unique_fd fd = fp->source->OpenFile("super_empty.img");
+
+ if (fd < 0) {
+ LOG(VERBOSE) << "could not open super_empty.img";
+ return nullptr;
+ }
+
+ std::string super_name;
+ // Try to find whether there is a super partition.
+ if (fp->fb->GetVar("super-partition-name", &super_name) != fastboot::SUCCESS) {
+ super_name = "super";
+ }
+ std::string partition_size_str;
+
+ if (fp->fb->GetVar("partition-size:" + super_name, &partition_size_str) != fastboot::SUCCESS) {
+ LOG(VERBOSE) << "Cannot optimize super flashing: could not determine super partition";
+ return nullptr;
+ }
+ std::unique_ptr<SuperFlashHelper> helper = std::make_unique<SuperFlashHelper>(*fp->source);
+ if (!helper->Open(fd)) {
+ return nullptr;
+ }
+
+ for (const auto& entry : os_images) {
+ auto partition = GetPartitionName(entry, fp->current_slot);
+ auto image = entry.first;
+
+ if (!helper->AddPartition(partition, image->img_name, image->optional_if_no_image)) {
+ return nullptr;
+ }
+ }
+
+ auto s = helper->GetSparseLayout();
+ if (!s) return nullptr;
+
+ // Remove images that we already flashed, just in case we have non-dynamic OS images.
+ auto remove_if_callback = [&](const ImageEntry& entry) -> bool {
+ return helper->WillFlash(GetPartitionName(entry, fp->current_slot));
+ };
+ os_images.erase(std::remove_if(os_images.begin(), os_images.end(), remove_if_callback),
+ os_images.end());
+ return std::make_unique<FlashSuperLayoutTask>(super_name, std::move(helper), std::move(s));
+}
diff --git a/fastboot/task.h b/fastboot/task.h
index d8b9e21..7acb3d5 100644
--- a/fastboot/task.h
+++ b/fastboot/task.h
@@ -20,6 +20,8 @@
#include "fastboot.h"
#include "fastboot_driver.h"
+#include "super_flash_helper.h"
+#include "util.h"
class Task {
public:
@@ -52,4 +54,19 @@
private:
const std::string reboot_target_ = "";
FlashingPlan* fp_;
-};
\ No newline at end of file
+};
+
+class FlashSuperLayoutTask : public Task {
+ public:
+ FlashSuperLayoutTask(const std::string& super_name, std::unique_ptr<SuperFlashHelper> helper,
+ SparsePtr sparse_layout);
+ static std::unique_ptr<FlashSuperLayoutTask> Initialize(FlashingPlan* fp,
+ std::vector<ImageEntry>& os_images);
+ using ImageEntry = std::pair<const Image*, std::string>;
+ void Run() override;
+
+ private:
+ const std::string super_name_;
+ std::unique_ptr<SuperFlashHelper> helper_;
+ SparsePtr sparse_layout_;
+};