Add [un]mapPartitions APIs to dynamic partition control

During postinstall stage, update_engine needs all target
partitions(system_b, vendor_b) to be mounted. We add 2 APIs to dynamic
partition control, 1 for mounting all partitions, and UnmapAllPartitions for unmap all partitions.

Test: Treehugger
Bug: 168554689
Change-Id: I1047851f6cdae7f39f50bd1d50e6d3bfc0d9a7f5
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h
index 530b0af..c8a2274 100644
--- a/common/dynamic_partition_control_interface.h
+++ b/common/dynamic_partition_control_interface.h
@@ -154,6 +154,11 @@
       const std::string& unsuffixed_partition_name,
       const std::optional<std::string>&,
       bool is_append = false) = 0;
+
+  // Create virtual block devices for all partitions.
+  virtual bool MapAllPartitions() = 0;
+  // Unmap virtual block devices for all partitions.
+  virtual bool UnmapAllPartitions() = 0;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/common/dynamic_partition_control_stub.cc b/common/dynamic_partition_control_stub.cc
index 64ab201..cfc9e2e 100644
--- a/common/dynamic_partition_control_stub.cc
+++ b/common/dynamic_partition_control_stub.cc
@@ -96,4 +96,12 @@
   return nullptr;
 }
 
+bool DynamicPartitionControlStub::MapAllPartitions() {
+  return false;
+}
+
+bool DynamicPartitionControlStub::UnmapAllPartitions() {
+  return false;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/common/dynamic_partition_control_stub.h b/common/dynamic_partition_control_stub.h
index a939cfb..1fc8a35 100644
--- a/common/dynamic_partition_control_stub.h
+++ b/common/dynamic_partition_control_stub.h
@@ -62,6 +62,9 @@
       const std::string& unsuffixed_partition_name,
       const std::optional<std::string>&,
       bool is_append) override;
+
+  bool MapAllPartitions() override;
+  bool UnmapAllPartitions() override;
 };
 }  // namespace chromeos_update_engine
 
diff --git a/dynamic_partition_control_android.cc b/dynamic_partition_control_android.cc
index 06e5745..7c331f0 100644
--- a/dynamic_partition_control_android.cc
+++ b/dynamic_partition_control_android.cc
@@ -273,9 +273,9 @@
   return true;
 }
 
-void DynamicPartitionControlAndroid::UnmapAllPartitions() {
+bool DynamicPartitionControlAndroid::UnmapAllPartitions() {
   if (mapped_devices_.empty()) {
-    return;
+    return false;
   }
   // UnmapPartitionOnDeviceMapper removes objects from mapped_devices_, hence
   // a copy is needed for the loop.
@@ -284,6 +284,7 @@
   for (const auto& partition_name : mapped) {
     ignore_result(UnmapPartitionOnDeviceMapper(partition_name));
   }
+  return true;
 }
 
 void DynamicPartitionControlAndroid::Cleanup() {
@@ -1240,16 +1241,12 @@
     bool is_append) {
   auto suffix = SlotSuffixForSlotNumber(target_slot_);
 
-  std::string device_dir_str;
-  if (!GetDeviceDir(&device_dir_str)) {
-    LOG(ERROR) << "Failed to get device dir!";
+  auto super_device = GetSuperDevice();
+  if (!super_device.has_value()) {
     return nullptr;
   }
-  base::FilePath device_dir(device_dir_str);
-  auto super_device =
-      device_dir.Append(GetSuperPartitionName(target_slot_)).value();
   CreateLogicalPartitionParams params = {
-      .block_device = super_device,
+      .block_device = super_device->value(),
       .metadata_slot = target_slot_,
       .partition_name = partition_name + suffix,
       .force_writable = true,
@@ -1259,4 +1256,19 @@
   return snapshot_->OpenSnapshotWriter(params, std::move(source_path));
 }
 
+std::optional<base::FilePath> DynamicPartitionControlAndroid::GetSuperDevice() {
+  std::string device_dir_str;
+  if (!GetDeviceDir(&device_dir_str)) {
+    LOG(ERROR) << "Failed to get device dir!";
+    return {};
+  }
+  base::FilePath device_dir(device_dir_str);
+  auto super_device = device_dir.Append(GetSuperPartitionName(target_slot_));
+  return super_device;
+}
+
+bool DynamicPartitionControlAndroid::MapAllPartitions() {
+  return snapshot_->MapAllSnapshots();
+}
+
 }  // namespace chromeos_update_engine
diff --git a/dynamic_partition_control_android.h b/dynamic_partition_control_android.h
index 9bffb59..4f3964b 100644
--- a/dynamic_partition_control_android.h
+++ b/dynamic_partition_control_android.h
@@ -90,6 +90,8 @@
       const std::optional<std::string>& source_path,
       bool is_append) override;
 
+  bool UnmapAllPartitions() override;
+
  protected:
   // These functions are exposed for testing.
 
@@ -201,11 +203,14 @@
       const DeltaArchiveManifest& manifest,
       bool delete_source);
 
+  bool MapAllPartitions() override;
+
  private:
   friend class DynamicPartitionControlAndroidTest;
   friend class SnapshotPartitionTestP;
 
-  void UnmapAllPartitions();
+  std::optional<base::FilePath> GetSuperDevice();
+
   bool MapPartitionInternal(const std::string& super_device,
                             const std::string& target_partition_name,
                             uint32_t slot,
diff --git a/mock_dynamic_partition_control.h b/mock_dynamic_partition_control.h
index 5144cbb..d5853ca 100644
--- a/mock_dynamic_partition_control.h
+++ b/mock_dynamic_partition_control.h
@@ -90,6 +90,8 @@
                const std::optional<std::string>& source_path,
                bool is_append),
               (override));
+  MOCK_METHOD(bool, MapAllPartitions, (), (override));
+  MOCK_METHOD(bool, UnmapAllPartitions, (), (override));
 
   void set_fake_mapped_devices(const std::set<std::string>& fake) override {
     DynamicPartitionControlAndroid::set_fake_mapped_devices(fake);