Call SnapshotManager::FinishedSnapshotWrites

... when the update has finished. This allows SnapshotManager
to conclude the update and prepare for reboot.

Test: builds
Test: apply OTA on Virtual A/B device, then check
/metadata/ota/snapshot-boot exists, then reboot
Bug: 138816109
Change-Id: I2a4699865b09358ef018313bed64e34617a78e3c
diff --git a/boot_control_android.cc b/boot_control_android.cc
index 4c998b1..4a010bd 100644
--- a/boot_control_android.cc
+++ b/boot_control_android.cc
@@ -245,6 +245,10 @@
 }
 
 bool BootControlAndroid::SetActiveBootSlot(Slot slot) {
+  if (slot != GetCurrentSlot() && !dynamic_control_->FinishUpdate()) {
+    return false;
+  }
+
   CommandResult result;
   auto ret = module_->setActiveBootSlot(slot, StoreResultCallback(&result));
   if (!ret.isOk()) {
diff --git a/dynamic_partition_control_android.cc b/dynamic_partition_control_android.cc
index f430574..8dcf343 100644
--- a/dynamic_partition_control_android.cc
+++ b/dynamic_partition_control_android.cc
@@ -490,4 +490,11 @@
   return true;
 }
 
+bool DynamicPartitionControlAndroid::FinishUpdate() {
+  if (!GetVirtualAbFeatureFlag().IsEnabled())
+    return true;
+  LOG(INFO) << "Snapshot writes are done.";
+  return snapshot_->FinishedSnapshotWrites();
+}
+
 }  // namespace chromeos_update_engine
diff --git a/dynamic_partition_control_android.h b/dynamic_partition_control_android.h
index 9509a62..f9dfd89 100644
--- a/dynamic_partition_control_android.h
+++ b/dynamic_partition_control_android.h
@@ -52,6 +52,7 @@
       const DeltaArchiveManifest& manifest) override;
   bool GetDeviceDir(std::string* path) override;
   std::string GetSuperPartitionName(uint32_t slot) override;
+  bool FinishUpdate() override;
 
  protected:
   // These functions are exposed for testing.
diff --git a/dynamic_partition_control_interface.h b/dynamic_partition_control_interface.h
index a4dc576..0ccfcd6 100644
--- a/dynamic_partition_control_interface.h
+++ b/dynamic_partition_control_interface.h
@@ -103,6 +103,8 @@
   // Return the name of the super partition (which stores super partition
   // metadata) for a given slot.
   virtual std::string GetSuperPartitionName(uint32_t slot) = 0;
+
+  virtual bool FinishUpdate() = 0;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/mock_dynamic_partition_control.h b/mock_dynamic_partition_control.h
index d96432b..1af6cfe 100644
--- a/mock_dynamic_partition_control.h
+++ b/mock_dynamic_partition_control.h
@@ -48,6 +48,7 @@
                bool(uint32_t, uint32_t, const DeltaArchiveManifest&));
   MOCK_METHOD1(GetSuperPartitionName, std::string(uint32_t));
   MOCK_METHOD0(GetVirtualAbFeatureFlag, FeatureFlag());
+  MOCK_METHOD0(FinishUpdate, bool());
 };
 
 class MockDynamicPartitionControlAndroid
@@ -75,6 +76,7 @@
   MOCK_METHOD0(GetDynamicPartitionsFeatureFlag, FeatureFlag());
   MOCK_METHOD1(GetSuperPartitionName, std::string(uint32_t));
   MOCK_METHOD0(GetVirtualAbFeatureFlag, FeatureFlag());
+  MOCK_METHOD0(FinishUpdate, bool());
 };
 
 }  // namespace chromeos_update_engine