pread() data into memory instead of lazily mmap everything

Initially, mmap() is used to ease parsing of manifest, as manifest has
variable size, and parsing it in a streaming fashoin is complicated.
Once manifest is parsed, applying ops in streaming manner is simple,
because each op has a defined data offset/length in manifest. Use
pread() to avoid loading the entire payload in memory at once.

Test: th
Bug: 221875271

Change-Id: I261c45bb81be096910e58ba5324410eb76dae1c9
diff --git a/aosp/ota_extractor.cc b/aosp/ota_extractor.cc
index 6fab44d..f200fc8 100644
--- a/aosp/ota_extractor.cc
+++ b/aosp/ota_extractor.cc
@@ -49,14 +49,16 @@
 
 bool ExtractImagesFromOTA(const DeltaArchiveManifest& manifest,
                           const PayloadMetadata& metadata,
-                          const uint8_t* payload,
-                          size_t size,
+                          int payload_fd,
+                          size_t payload_offset,
                           std::string_view output_dir) {
   InstallOperationExecutor executor(manifest.block_size());
-  const uint8_t* data_begin = payload + metadata.GetMetadataSize() +
-                              metadata.GetMetadataSignatureSize();
+  const size_t data_begin = metadata.GetMetadataSize() +
+                            metadata.GetMetadataSignatureSize() +
+                            payload_offset;
   const base::FilePath path(
       base::StringPiece(output_dir.data(), output_dir.size()));
+  std::vector<unsigned char> blob;
   for (const auto& partition : manifest.partitions()) {
     LOG(INFO) << "Extracting partition " << partition.partition_name()
               << " size: " << partition.new_partition_info().size();
@@ -67,10 +69,14 @@
     TEST_AND_RETURN_FALSE_ERRNO(
         fd->Open(output_path.c_str(), O_RDWR | O_CREAT, 0644));
     for (const auto& op : partition.operations()) {
+      blob.resize(op.data_length());
+      const auto op_data_offset = data_begin + op.data_offset();
+      ssize_t bytes_read = 0;
+      TEST_AND_RETURN_FALSE(utils::PReadAll(
+          payload_fd, blob.data(), blob.size(), op_data_offset, &bytes_read));
       auto direct_writer = std::make_unique<DirectExtentWriter>(fd);
-      const auto op_data = data_begin + op.data_offset();
       TEST_AND_RETURN_FALSE(executor.ExecuteReplaceOperation(
-          op, std::move(direct_writer), op_data, op.data_length()));
+          op, std::move(direct_writer), blob.data(), blob.size()));
     }
     int err =
         truncate64(output_path.c_str(), partition.new_partition_info().size());
@@ -135,7 +141,7 @@
   }
   return !ExtractImagesFromOTA(manifest,
                                payload_metadata,
-                               payload + FLAGS_payload_offset,
-                               payload_size - FLAGS_payload_offset,
+                               payload_fd,
+                               FLAGS_payload_offset,
                                FLAGS_output_dir);
 }