Added support for FlashSuperLayoutTask
Test: testing flashall code with this change
Bug: 194686221
Change-Id: Ibb96980402db51b48c9a296338f29195f68c65bf
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));
+}