Merge "Simulator: add the argument to keep the updated images"
am: c34e4e7fb5

Change-Id: Idb86f6ee1b5a99c626150acaa86d8152b2a8ba99
diff --git a/tests/unit/host/update_simulator_test.cpp b/tests/unit/host/update_simulator_test.cpp
index bf89b78..fb12178 100644
--- a/tests/unit/host/update_simulator_test.cpp
+++ b/tests/unit/host/update_simulator_test.cpp
@@ -93,7 +93,7 @@
 
   // Run the update simulation and check the result.
   TemporaryDir work_dir;
-  BuildInfo build_info(work_dir.path);
+  BuildInfo build_info(work_dir.path, false);
   ASSERT_TRUE(build_info.ParseTargetFile(src_tf, false));
   Updater updater(std::make_unique<SimulatorRuntime>(&build_info));
   ASSERT_TRUE(updater.Init(cmd_pipe.release(), ota_package, false));
@@ -211,7 +211,7 @@
   AddZipEntries(zip_file.release(), entries);
 
   TemporaryDir temp_dir;
-  BuildInfo build_info(temp_dir.path);
+  BuildInfo build_info(temp_dir.path, false);
   ASSERT_TRUE(build_info.ParseTargetFile(zip_file.path, false));
 
   std::map<string, string> expected_result = {
diff --git a/updater/build_info.cpp b/updater/build_info.cpp
index 3072aab..f168008 100644
--- a/updater/build_info.cpp
+++ b/updater/build_info.cpp
@@ -16,6 +16,8 @@
 
 #include "updater/build_info.h"
 
+#include <stdio.h>
+
 #include <set>
 #include <vector>
 
@@ -55,12 +57,23 @@
         return false;
       }
 
+      std::string mapped_path = image_file.path;
+      // Rename the images to more readable ones if we want to keep the image.
+      if (keep_images_) {
+        mapped_path = work_dir_ + fstab_info.mount_point + ".img";
+        image_file.release();
+        if (rename(image_file.path, mapped_path.c_str()) != 0) {
+          PLOG(ERROR) << "Failed to rename " << image_file.path << " to " << mapped_path;
+          return false;
+        }
+      }
+
       LOG(INFO) << "Mounted " << fstab_info.mount_point << "\nMapping: " << fstab_info.blockdev_name
-                << " to " << image_file.path;
+                << " to " << mapped_path;
 
       blockdev_map_.emplace(
           fstab_info.blockdev_name,
-          FakeBlockDevice(fstab_info.blockdev_name, fstab_info.mount_point, image_file.path));
+          FakeBlockDevice(fstab_info.blockdev_name, fstab_info.mount_point, mapped_path));
       break;
     }
   }
diff --git a/updater/include/updater/build_info.h b/updater/include/updater/build_info.h
index 2229957..0073bfa 100644
--- a/updater/include/updater/build_info.h
+++ b/updater/include/updater/build_info.h
@@ -43,7 +43,8 @@
 // query the information and run the update on host.
 class BuildInfo {
  public:
-  explicit BuildInfo(const std::string_view work_dir) : work_dir_(work_dir) {}
+  BuildInfo(const std::string_view work_dir, bool keep_images)
+      : work_dir_(work_dir), keep_images_(keep_images) {}
   // Returns the value of the build properties.
   std::string GetProperty(const std::string_view key, const std::string_view default_value) const;
   // Returns the path to the mock block device.
@@ -69,4 +70,5 @@
 
   std::list<TemporaryFile> temp_files_;
   std::string work_dir_;  // A temporary directory to store the extracted image files
+  bool keep_images_;
 };
diff --git a/updater/install.cpp b/updater/install.cpp
index c82351e..be0ceb0 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -113,7 +113,7 @@
                         argv.size());
     }
     const std::string& zip_path = args[0];
-    const std::string& dest_path = args[1];
+    std::string dest_path = args[1];
 
     ZipArchiveHandle za = state->updater->GetPackageHandle();
     ZipEntry entry;
@@ -122,6 +122,13 @@
       return StringValue("");
     }
 
+    // Update the destination of package_extract_file if it's a block device. During simulation the
+    // destination will map to a fake file.
+    if (std::string block_device_name = state->updater->FindBlockDeviceName(dest_path);
+        !block_device_name.empty()) {
+      dest_path = block_device_name;
+    }
+
     android::base::unique_fd fd(TEMP_FAILURE_RETRY(
         open(dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)));
     if (fd == -1) {
diff --git a/updater/update_simulator_main.cpp b/updater/update_simulator_main.cpp
index 278a440..6c6989b 100644
--- a/updater/update_simulator_main.cpp
+++ b/updater/update_simulator_main.cpp
@@ -58,12 +58,16 @@
   std::string skip_function_file;
   std::string source_target_file;
   std::string package_name;
+  std::string work_dir;
+  bool keep_images = false;
 
   constexpr struct option OPTIONS[] = {
+    { "keep_images", no_argument, nullptr, 0 },
     { "oem_settings", required_argument, nullptr, 0 },
     { "ota_package", required_argument, nullptr, 0 },
     { "skip_functions", required_argument, nullptr, 0 },
     { "source", required_argument, nullptr, 0 },
+    { "work_dir", required_argument, nullptr, 0 },
     { nullptr, 0, nullptr, 0 },
   };
 
@@ -86,6 +90,10 @@
       source_target_file = optarg;
     } else if (option_name == "ota_package"s) {
       package_name = optarg;
+    } else if (option_name == "keep_images"s) {
+      keep_images = true;
+    } else if (option_name == "work_dir"s) {
+      work_dir = optarg;
     } else {
       Usage(argv[0]);
       return EXIT_FAILURE;
@@ -129,8 +137,11 @@
 
   TemporaryFile cmd_pipe;
   TemporaryDir source_temp_dir;
+  if (work_dir.empty()) {
+    work_dir = source_temp_dir.path;
+  }
 
-  BuildInfo source_build_info(source_temp_dir.path);
+  BuildInfo source_build_info(work_dir, keep_images);
   if (!source_build_info.ParseTargetFile(source_target_file, false)) {
     LOG(ERROR) << "Failed to parse the target file " << source_target_file;
     return EXIT_FAILURE;