UpdateAttempterAndroid::Init initiates merge

On update_engine starts, schedule CleanupPreviousUpdateAction that calls
CleanupSuccessfulUpdate to do necessary cleanup as soon as possible.

In the good case, update_engine initiates merge when
sys.boot_completed, and clean up snapshots.

If the update is
rolled back or partitions are flashed, the following happens (on
a Virtual A/B device):

- UpdateAttempterAndroid::CleanupSuccessfulUpdate is called
  - DynamicPartitionControlAndroid::CleanupSuccessfulUpdate is called
  - SnapshotManager::InitiateMergeAndWait is called
  - SnapshotManager::RemoveAllUpdateState(before_cancel) is called
  - before_cancel is called,
    DeltaPerformer::ResetUpdateProgress is called
    - All update states in update_engine is reset.
  - SnapshotManager proceeds to delete snapshots
    - All update states in SnapshotManager is reset.

Hence, on an VAB device, when an update is rolled back or partitions
are flashed, the whole update needs to be re-applied
(while in A/B, it skips writing and directly start verifying hashes of
the target partitions because the update markers are still there).

Bug: 147696014
Test: apply OTA then reboot, inspect logs and do `snapshotctl dump`

Change-Id: I0fc5e7768dfb53e4fd474f2d8d85d2a1b615a88b
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h
index 48cd9be..8de9d76 100644
--- a/common/dynamic_partition_control_interface.h
+++ b/common/dynamic_partition_control_interface.h
@@ -22,6 +22,8 @@
 #include <memory>
 #include <string>
 
+#include "update_engine/common/action.h"
+#include "update_engine/common/cleanup_previous_update_action_delegate.h"
 #include "update_engine/common/error_code.h"
 #include "update_engine/update_metadata.pb.h"
 
@@ -38,6 +40,9 @@
   Value value_;
 };
 
+class BootControlInterface;
+class PrefsInterface;
+
 class DynamicPartitionControlInterface {
  public:
   virtual ~DynamicPartitionControlInterface() = default;
@@ -79,6 +84,7 @@
   // this function to indicate writes to new partitions are done.
   virtual bool FinishUpdate() = 0;
 
+  // Deprecated. Use GetCleanupPreviousUpdateAction instead.
   // Before applying the next update, call this function to clean up previous
   // update files. This function blocks until delta files are merged into
   // current OS partitions and finished cleaning up.
@@ -86,6 +92,20 @@
   // - If any error, but caller should retry after reboot, return kError.
   // - If any irrecoverable failures, return kDeviceCorrupted.
   virtual ErrorCode CleanupSuccessfulUpdate() = 0;
+
+  // Get an action to clean up previous update.
+  // Return NoOpAction on non-Virtual A/B devices.
+  // Before applying the next update, run this action to clean up previous
+  // update files. This function blocks until delta files are merged into
+  // current OS partitions and finished cleaning up.
+  // - If successful, action completes with kSuccess.
+  // - If any error, but caller should retry after reboot, action completes with
+  //   kError.
+  // - If any irrecoverable failures, action completes with kDeviceCorrupted.
+  virtual std::unique_ptr<AbstractAction> GetCleanupPreviousUpdateAction(
+      BootControlInterface* boot_control,
+      PrefsInterface* prefs,
+      CleanupPreviousUpdateActionDelegateInterface* delegate) = 0;
 };
 
 }  // namespace chromeos_update_engine