diff --git a/aosp/binder_service_android.cc b/aosp/binder_service_android.cc
new file mode 100644
index 0000000..ed76c4a
--- /dev/null
+++ b/aosp/binder_service_android.cc
@@ -0,0 +1,243 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/binder_service_android.h"
+
+#include <memory>
+
+#include <base/bind.h>
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <brillo/errors/error.h>
+#include <utils/String8.h>
+
+#include "update_engine/aosp/binder_service_android_common.h"
+
+using android::binder::Status;
+using android::os::IUpdateEngineCallback;
+using android::os::ParcelFileDescriptor;
+using std::string;
+using std::vector;
+using update_engine::UpdateEngineStatus;
+
+namespace chromeos_update_engine {
+
+BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
+    ServiceDelegateAndroidInterface* service_delegate)
+    : service_delegate_(service_delegate) {}
+
+void BinderUpdateEngineAndroidService::SendStatusUpdate(
+    const UpdateEngineStatus& update_engine_status) {
+  last_status_ = static_cast<int>(update_engine_status.status);
+  last_progress_ = update_engine_status.progress;
+  for (auto& callback : callbacks_) {
+    callback->onStatusUpdate(last_status_, last_progress_);
+  }
+}
+
+void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
+    ErrorCode error_code) {
+  for (auto& callback : callbacks_) {
+    callback->onPayloadApplicationComplete(static_cast<int>(error_code));
+  }
+}
+
+Status BinderUpdateEngineAndroidService::bind(
+    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
+  // Send an status update on connection (except when no update sent so far).
+  // Even though the status update is oneway, it still returns an erroneous
+  // status in case of a selinux denial. We should at least check this status
+  // and fails the binding.
+  if (last_status_ != -1) {
+    auto status = callback->onStatusUpdate(last_status_, last_progress_);
+    if (!status.isOk()) {
+      LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
+                 << status.toString8();
+      *return_value = false;
+      return Status::ok();
+    }
+  }
+
+  callbacks_.emplace_back(callback);
+
+  const android::sp<IBinder>& callback_binder =
+      IUpdateEngineCallback::asBinder(callback);
+  auto binder_wrapper = android::BinderWrapper::Get();
+  binder_wrapper->RegisterForDeathNotifications(
+      callback_binder,
+      base::Bind(
+          base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback),
+          base::Unretained(this),
+          base::Unretained(callback_binder.get())));
+
+  *return_value = true;
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::unbind(
+    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
+  const android::sp<IBinder>& callback_binder =
+      IUpdateEngineCallback::asBinder(callback);
+  auto binder_wrapper = android::BinderWrapper::Get();
+  binder_wrapper->UnregisterForDeathNotifications(callback_binder);
+
+  *return_value = UnbindCallback(callback_binder.get());
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::applyPayload(
+    const android::String16& url,
+    int64_t payload_offset,
+    int64_t payload_size,
+    const vector<android::String16>& header_kv_pairs) {
+  const string payload_url{android::String8{url}.string()};
+  vector<string> str_headers = ToVecString(header_kv_pairs);
+
+  brillo::ErrorPtr error;
+  if (!service_delegate_->ApplyPayload(
+          payload_url, payload_offset, payload_size, str_headers, &error)) {
+    return ErrorPtrToStatus(error);
+  }
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::applyPayloadFd(
+    const ParcelFileDescriptor& pfd,
+    int64_t payload_offset,
+    int64_t payload_size,
+    const vector<android::String16>& header_kv_pairs) {
+  vector<string> str_headers = ToVecString(header_kv_pairs);
+
+  brillo::ErrorPtr error;
+  if (!service_delegate_->ApplyPayload(
+          pfd.get(), payload_offset, payload_size, str_headers, &error)) {
+    return ErrorPtrToStatus(error);
+  }
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::suspend() {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->SuspendUpdate(&error))
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::resume() {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->ResumeUpdate(&error))
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::cancel() {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->CancelUpdate(&error))
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::resetStatus() {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->ResetStatus(&error))
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
+    const android::String16& metadata_filename, bool* return_value) {
+  const std::string payload_metadata{
+      android::String8{metadata_filename}.string()};
+  LOG(INFO) << "Received a request of verifying payload metadata in "
+            << payload_metadata << ".";
+  brillo::ErrorPtr error;
+  *return_value =
+      service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
+  if (error != nullptr)
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
+bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
+  auto it = std::find_if(
+      callbacks_.begin(),
+      callbacks_.end(),
+      [&callback](const android::sp<IUpdateEngineCallback>& elem) {
+        return IUpdateEngineCallback::asBinder(elem).get() == callback;
+      });
+  if (it == callbacks_.end()) {
+    LOG(ERROR) << "Unable to unbind unknown callback.";
+    return false;
+  }
+  callbacks_.erase(it);
+  return true;
+}
+
+Status BinderUpdateEngineAndroidService::allocateSpaceForPayload(
+    const android::String16& metadata_filename,
+    const vector<android::String16>& header_kv_pairs,
+    int64_t* return_value) {
+  const std::string payload_metadata{
+      android::String8{metadata_filename}.string()};
+  vector<string> str_headers = ToVecString(header_kv_pairs);
+  LOG(INFO) << "Received a request of allocating space for " << payload_metadata
+            << ".";
+  brillo::ErrorPtr error;
+  *return_value =
+      static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
+          payload_metadata, str_headers, &error));
+  if (error != nullptr)
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
+class CleanupSuccessfulUpdateCallback
+    : public CleanupSuccessfulUpdateCallbackInterface {
+ public:
+  CleanupSuccessfulUpdateCallback(
+      const android::sp<IUpdateEngineCallback>& callback)
+      : callback_(callback) {}
+  void OnCleanupComplete(int32_t error_code) {
+    ignore_result(callback_->onPayloadApplicationComplete(error_code));
+  }
+  void OnCleanupProgressUpdate(double progress) {
+    ignore_result(callback_->onStatusUpdate(
+        static_cast<int32_t>(
+            update_engine::UpdateStatus::CLEANUP_PREVIOUS_UPDATE),
+        progress));
+  }
+  void RegisterForDeathNotifications(base::Closure unbind) {
+    const android::sp<android::IBinder>& callback_binder =
+        IUpdateEngineCallback::asBinder(callback_);
+    auto binder_wrapper = android::BinderWrapper::Get();
+    binder_wrapper->RegisterForDeathNotifications(callback_binder, unbind);
+  }
+
+ private:
+  android::sp<IUpdateEngineCallback> callback_;
+};
+
+Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
+    const android::sp<IUpdateEngineCallback>& callback) {
+  brillo::ErrorPtr error;
+  service_delegate_->CleanupSuccessfulUpdate(
+      std::make_unique<CleanupSuccessfulUpdateCallback>(callback), &error);
+  if (error != nullptr)
+    return ErrorPtrToStatus(error);
+  return Status::ok();
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/binder_service_android.h b/aosp/binder_service_android.h
new file mode 100644
index 0000000..f41fbdf
--- /dev/null
+++ b/aosp/binder_service_android.h
@@ -0,0 +1,99 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+#include "android/os/BnUpdateEngine.h"
+#include "android/os/IUpdateEngineCallback.h"
+#include "update_engine/aosp/service_delegate_android_interface.h"
+#include "update_engine/common/service_observer_interface.h"
+
+namespace chromeos_update_engine {
+
+class BinderUpdateEngineAndroidService : public android::os::BnUpdateEngine,
+                                         public ServiceObserverInterface {
+ public:
+  explicit BinderUpdateEngineAndroidService(
+      ServiceDelegateAndroidInterface* service_delegate);
+  ~BinderUpdateEngineAndroidService() override = default;
+
+  const char* ServiceName() const { return "android.os.UpdateEngineService"; }
+
+  // ServiceObserverInterface overrides.
+  void SendStatusUpdate(
+      const update_engine::UpdateEngineStatus& update_engine_status) override;
+  void SendPayloadApplicationComplete(ErrorCode error_code) override;
+
+  // android::os::BnUpdateEngine overrides.
+  android::binder::Status applyPayload(
+      const android::String16& url,
+      int64_t payload_offset,
+      int64_t payload_size,
+      const std::vector<android::String16>& header_kv_pairs) override;
+  android::binder::Status applyPayloadFd(
+      const ::android::os::ParcelFileDescriptor& pfd,
+      int64_t payload_offset,
+      int64_t payload_size,
+      const std::vector<android::String16>& header_kv_pairs) override;
+  android::binder::Status bind(
+      const android::sp<android::os::IUpdateEngineCallback>& callback,
+      bool* return_value) override;
+  android::binder::Status unbind(
+      const android::sp<android::os::IUpdateEngineCallback>& callback,
+      bool* return_value) override;
+  android::binder::Status suspend() override;
+  android::binder::Status resume() override;
+  android::binder::Status cancel() override;
+  android::binder::Status resetStatus() override;
+  android::binder::Status verifyPayloadApplicable(
+      const android::String16& metadata_filename, bool* return_value) override;
+  android::binder::Status allocateSpaceForPayload(
+      const android::String16& metadata_filename,
+      const std::vector<android::String16>& header_kv_pairs,
+      int64_t* return_value) override;
+  android::binder::Status cleanupSuccessfulUpdate(
+      const android::sp<android::os::IUpdateEngineCallback>& callback) override;
+
+ private:
+  // Remove the passed |callback| from the list of registered callbacks. Called
+  // on unbind() or whenever the callback object is destroyed.
+  // Returns true on success.
+  bool UnbindCallback(const IBinder* callback);
+
+  // List of currently bound callbacks.
+  std::vector<android::sp<android::os::IUpdateEngineCallback>> callbacks_;
+
+  // Cached copy of the last status update sent. Used to send an initial
+  // notification when bind() is called from the client.
+  int last_status_{-1};
+  double last_progress_{0.0};
+
+  ServiceDelegateAndroidInterface* service_delegate_;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_H_
diff --git a/aosp/binder_service_android_common.h b/aosp/binder_service_android_common.h
new file mode 100644
index 0000000..223b32e
--- /dev/null
+++ b/aosp/binder_service_android_common.h
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_COMMON_H_
+#define UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_COMMON_H_
+
+#include <string>
+#include <vector>
+
+#include <binder/Status.h>
+
+namespace chromeos_update_engine {
+
+static inline android::binder::Status ErrorPtrToStatus(
+    const brillo::ErrorPtr& error) {
+  return android::binder::Status::fromServiceSpecificError(
+      1, android::String8{error->GetMessage().c_str()});
+}
+
+static inline std::vector<std::string> ToVecString(
+    const std::vector<android::String16>& inp) {
+  std::vector<std::string> out;
+  out.reserve(inp.size());
+  for (const auto& e : inp) {
+    out.emplace_back(android::String8{e}.string());
+  }
+  return out;
+}
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_COMMON_H_
diff --git a/aosp/binder_service_stable_android.cc b/aosp/binder_service_stable_android.cc
new file mode 100644
index 0000000..17b35ee
--- /dev/null
+++ b/aosp/binder_service_stable_android.cc
@@ -0,0 +1,132 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/binder_service_stable_android.h"
+
+#include <memory>
+
+#include <base/bind.h>
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <brillo/errors/error.h>
+#include <utils/String8.h>
+
+#include "update_engine/aosp/binder_service_android_common.h"
+
+using android::binder::Status;
+using android::os::IUpdateEngineStableCallback;
+using android::os::ParcelFileDescriptor;
+using std::string;
+using std::vector;
+using update_engine::UpdateEngineStatus;
+
+namespace chromeos_update_engine {
+
+BinderUpdateEngineAndroidStableService::BinderUpdateEngineAndroidStableService(
+    ServiceDelegateAndroidInterface* service_delegate)
+    : service_delegate_(service_delegate) {}
+
+void BinderUpdateEngineAndroidStableService::SendStatusUpdate(
+    const UpdateEngineStatus& update_engine_status) {
+  last_status_ = static_cast<int>(update_engine_status.status);
+  last_progress_ = update_engine_status.progress;
+  if (callback_) {
+    callback_->onStatusUpdate(last_status_, last_progress_);
+  }
+}
+
+void BinderUpdateEngineAndroidStableService::SendPayloadApplicationComplete(
+    ErrorCode error_code) {
+  if (callback_) {
+    callback_->onPayloadApplicationComplete(static_cast<int>(error_code));
+  }
+}
+
+Status BinderUpdateEngineAndroidStableService::bind(
+    const android::sp<IUpdateEngineStableCallback>& callback,
+    bool* return_value) {
+  // Reject binding if another callback is already bound.
+  if (callback_ != nullptr) {
+    LOG(ERROR) << "Another callback is already bound. Can't bind new callback.";
+    *return_value = false;
+    return Status::ok();
+  }
+
+  // See BinderUpdateEngineAndroidService::bind.
+  if (last_status_ != -1) {
+    auto status = callback->onStatusUpdate(last_status_, last_progress_);
+    if (!status.isOk()) {
+      LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
+                 << status.toString8();
+      *return_value = false;
+      return Status::ok();
+    }
+  }
+
+  callback_ = callback;
+
+  const android::sp<IBinder>& callback_binder =
+      IUpdateEngineStableCallback::asBinder(callback);
+  auto binder_wrapper = android::BinderWrapper::Get();
+  binder_wrapper->RegisterForDeathNotifications(
+      callback_binder,
+      base::Bind(base::IgnoreResult(
+                     &BinderUpdateEngineAndroidStableService::UnbindCallback),
+                 base::Unretained(this),
+                 base::Unretained(callback_binder.get())));
+
+  *return_value = true;
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidStableService::unbind(
+    const android::sp<IUpdateEngineStableCallback>& callback,
+    bool* return_value) {
+  const android::sp<IBinder>& callback_binder =
+      IUpdateEngineStableCallback::asBinder(callback);
+  auto binder_wrapper = android::BinderWrapper::Get();
+  binder_wrapper->UnregisterForDeathNotifications(callback_binder);
+
+  *return_value = UnbindCallback(callback_binder.get());
+  return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidStableService::applyPayloadFd(
+    const ParcelFileDescriptor& pfd,
+    int64_t payload_offset,
+    int64_t payload_size,
+    const vector<android::String16>& header_kv_pairs) {
+  vector<string> str_headers = ToVecString(header_kv_pairs);
+
+  brillo::ErrorPtr error;
+  if (!service_delegate_->ApplyPayload(
+          pfd.get(), payload_offset, payload_size, str_headers, &error)) {
+    return ErrorPtrToStatus(error);
+  }
+  return Status::ok();
+}
+
+bool BinderUpdateEngineAndroidStableService::UnbindCallback(
+    const IBinder* callback) {
+  if (IUpdateEngineStableCallback::asBinder(callback_).get() != callback) {
+    LOG(ERROR) << "Unable to unbind unknown callback.";
+    return false;
+  }
+  callback_ = nullptr;
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/binder_service_stable_android.h b/aosp/binder_service_stable_android.h
new file mode 100644
index 0000000..212afaa
--- /dev/null
+++ b/aosp/binder_service_stable_android.h
@@ -0,0 +1,85 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_BINDER_SERVICE_STABLE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_BINDER_SERVICE_STABLE_ANDROID_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+#include "android/os/BnUpdateEngineStable.h"
+#include "android/os/IUpdateEngineStableCallback.h"
+#include "update_engine/aosp/service_delegate_android_interface.h"
+#include "update_engine/common/service_observer_interface.h"
+
+namespace chromeos_update_engine {
+
+class BinderUpdateEngineAndroidStableService
+    : public android::os::BnUpdateEngineStable,
+      public ServiceObserverInterface {
+ public:
+  explicit BinderUpdateEngineAndroidStableService(
+      ServiceDelegateAndroidInterface* service_delegate);
+  ~BinderUpdateEngineAndroidStableService() override = default;
+
+  const char* ServiceName() const {
+    return "android.os.UpdateEngineStableService";
+  }
+
+  // ServiceObserverInterface overrides.
+  void SendStatusUpdate(
+      const update_engine::UpdateEngineStatus& update_engine_status) override;
+  void SendPayloadApplicationComplete(ErrorCode error_code) override;
+
+  // android::os::BnUpdateEngineStable overrides.
+  android::binder::Status applyPayloadFd(
+      const ::android::os::ParcelFileDescriptor& pfd,
+      int64_t payload_offset,
+      int64_t payload_size,
+      const std::vector<android::String16>& header_kv_pairs) override;
+  android::binder::Status bind(
+      const android::sp<android::os::IUpdateEngineStableCallback>& callback,
+      bool* return_value) override;
+  android::binder::Status unbind(
+      const android::sp<android::os::IUpdateEngineStableCallback>& callback,
+      bool* return_value) override;
+
+ private:
+  // Remove the passed |callback| from the list of registered callbacks. Called
+  // on unbind() or whenever the callback object is destroyed.
+  // Returns true on success.
+  bool UnbindCallback(const IBinder* callback);
+
+  // Bound callback. The stable interface only supports one callback at a time.
+  android::sp<android::os::IUpdateEngineStableCallback> callback_;
+
+  // Cached copy of the last status update sent. Used to send an initial
+  // notification when bind() is called from the client.
+  int last_status_{-1};
+  double last_progress_{0.0};
+
+  ServiceDelegateAndroidInterface* service_delegate_;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_BINDER_SERVICE_STABLE_ANDROID_H_
diff --git a/aosp/boot_control_android.cc b/aosp/boot_control_android.cc
new file mode 100644
index 0000000..bda65be
--- /dev/null
+++ b/aosp/boot_control_android.cc
@@ -0,0 +1,186 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/boot_control_android.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/logging.h>
+#include <bootloader_message/bootloader_message.h>
+#include <brillo/message_loops/message_loop.h>
+
+#include "update_engine/aosp/dynamic_partition_control_android.h"
+#include "update_engine/common/utils.h"
+
+using std::string;
+
+using android::dm::DmDeviceState;
+using android::hardware::hidl_string;
+using android::hardware::Return;
+using android::hardware::boot::V1_0::BoolResult;
+using android::hardware::boot::V1_0::CommandResult;
+using android::hardware::boot::V1_0::IBootControl;
+using Slot = chromeos_update_engine::BootControlInterface::Slot;
+
+namespace {
+
+auto StoreResultCallback(CommandResult* dest) {
+  return [dest](const CommandResult& result) { *dest = result; };
+}
+}  // namespace
+
+namespace chromeos_update_engine {
+
+namespace boot_control {
+
+// Factory defined in boot_control.h.
+std::unique_ptr<BootControlInterface> CreateBootControl() {
+  auto boot_control = std::make_unique<BootControlAndroid>();
+  if (!boot_control->Init()) {
+    return nullptr;
+  }
+  return std::move(boot_control);
+}
+
+}  // namespace boot_control
+
+bool BootControlAndroid::Init() {
+  module_ = IBootControl::getService();
+  if (module_ == nullptr) {
+    LOG(ERROR) << "Error getting bootctrl HIDL module.";
+    return false;
+  }
+
+  LOG(INFO) << "Loaded boot control hidl hal.";
+
+  dynamic_control_ = std::make_unique<DynamicPartitionControlAndroid>();
+
+  return true;
+}
+
+unsigned int BootControlAndroid::GetNumSlots() const {
+  return module_->getNumberSlots();
+}
+
+BootControlInterface::Slot BootControlAndroid::GetCurrentSlot() const {
+  return module_->getCurrentSlot();
+}
+
+bool BootControlAndroid::GetPartitionDevice(const std::string& partition_name,
+                                            BootControlInterface::Slot slot,
+                                            bool not_in_payload,
+                                            std::string* device,
+                                            bool* is_dynamic) const {
+  return dynamic_control_->GetPartitionDevice(partition_name,
+                                              slot,
+                                              GetCurrentSlot(),
+                                              not_in_payload,
+                                              device,
+                                              is_dynamic);
+}
+
+bool BootControlAndroid::GetPartitionDevice(const string& partition_name,
+                                            BootControlInterface::Slot slot,
+                                            string* device) const {
+  return GetPartitionDevice(
+      partition_name, slot, false /* not_in_payload */, device, nullptr);
+}
+
+bool BootControlAndroid::IsSlotBootable(Slot slot) const {
+  Return<BoolResult> ret = module_->isSlotBootable(slot);
+  if (!ret.isOk()) {
+    LOG(ERROR) << "Unable to determine if slot " << SlotName(slot)
+               << " is bootable: " << ret.description();
+    return false;
+  }
+  if (ret == BoolResult::INVALID_SLOT) {
+    LOG(ERROR) << "Invalid slot: " << SlotName(slot);
+    return false;
+  }
+  return ret == BoolResult::TRUE;
+}
+
+bool BootControlAndroid::MarkSlotUnbootable(Slot slot) {
+  CommandResult result;
+  auto ret = module_->setSlotAsUnbootable(slot, StoreResultCallback(&result));
+  if (!ret.isOk()) {
+    LOG(ERROR) << "Unable to call MarkSlotUnbootable for slot "
+               << SlotName(slot) << ": " << ret.description();
+    return false;
+  }
+  if (!result.success) {
+    LOG(ERROR) << "Unable to mark slot " << SlotName(slot)
+               << " as unbootable: " << result.errMsg.c_str();
+  }
+  return result.success;
+}
+
+bool BootControlAndroid::SetActiveBootSlot(Slot slot) {
+  CommandResult result;
+  auto ret = module_->setActiveBootSlot(slot, StoreResultCallback(&result));
+  if (!ret.isOk()) {
+    LOG(ERROR) << "Unable to call SetActiveBootSlot for slot " << SlotName(slot)
+               << ": " << ret.description();
+    return false;
+  }
+  if (!result.success) {
+    LOG(ERROR) << "Unable to set the active slot to slot " << SlotName(slot)
+               << ": " << result.errMsg.c_str();
+  }
+  return result.success;
+}
+
+bool BootControlAndroid::MarkBootSuccessfulAsync(
+    base::Callback<void(bool)> callback) {
+  CommandResult result;
+  auto ret = module_->markBootSuccessful(StoreResultCallback(&result));
+  if (!ret.isOk()) {
+    LOG(ERROR) << "Unable to call MarkBootSuccessful: " << ret.description();
+    return false;
+  }
+  if (!result.success) {
+    LOG(ERROR) << "Unable to mark boot successful: " << result.errMsg.c_str();
+  }
+  return brillo::MessageLoop::current()->PostTask(
+             FROM_HERE, base::Bind(callback, result.success)) !=
+         brillo::MessageLoop::kTaskIdNull;
+}
+
+bool BootControlAndroid::IsSlotMarkedSuccessful(
+    BootControlInterface::Slot slot) const {
+  Return<BoolResult> ret = module_->isSlotMarkedSuccessful(slot);
+  CommandResult result;
+  if (!ret.isOk()) {
+    LOG(ERROR) << "Unable to determine if slot " << SlotName(slot)
+               << " is marked successful: " << ret.description();
+    return false;
+  }
+  if (ret == BoolResult::INVALID_SLOT) {
+    LOG(ERROR) << "Invalid slot: " << SlotName(slot);
+    return false;
+  }
+  return ret == BoolResult::TRUE;
+}
+
+DynamicPartitionControlInterface*
+BootControlAndroid::GetDynamicPartitionControl() {
+  return dynamic_control_.get();
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/boot_control_android.h b/aosp/boot_control_android.h
new file mode 100644
index 0000000..e288723
--- /dev/null
+++ b/aosp/boot_control_android.h
@@ -0,0 +1,73 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_BOOT_CONTROL_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_BOOT_CONTROL_ANDROID_H_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include <android/hardware/boot/1.0/IBootControl.h>
+#include <liblp/builder.h>
+
+#include "update_engine/aosp/dynamic_partition_control_android.h"
+#include "update_engine/common/boot_control.h"
+#include "update_engine/common/dynamic_partition_control_interface.h"
+
+namespace chromeos_update_engine {
+
+// The Android implementation of the BootControlInterface. This implementation
+// uses the libhardware's boot_control HAL to access the bootloader.
+class BootControlAndroid : public BootControlInterface {
+ public:
+  BootControlAndroid() = default;
+  ~BootControlAndroid() = default;
+
+  // Load boot_control HAL implementation using libhardware and
+  // initializes it. Returns false if an error occurred.
+  bool Init();
+
+  // BootControlInterface overrides.
+  unsigned int GetNumSlots() const override;
+  BootControlInterface::Slot GetCurrentSlot() const override;
+  bool GetPartitionDevice(const std::string& partition_name,
+                          BootControlInterface::Slot slot,
+                          bool not_in_payload,
+                          std::string* device,
+                          bool* is_dynamic) const override;
+  bool GetPartitionDevice(const std::string& partition_name,
+                          BootControlInterface::Slot slot,
+                          std::string* device) const override;
+  bool IsSlotBootable(BootControlInterface::Slot slot) const override;
+  bool MarkSlotUnbootable(BootControlInterface::Slot slot) override;
+  bool SetActiveBootSlot(BootControlInterface::Slot slot) override;
+  bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override;
+  bool IsSlotMarkedSuccessful(BootControlInterface::Slot slot) const override;
+  DynamicPartitionControlInterface* GetDynamicPartitionControl() override;
+
+ private:
+  ::android::sp<::android::hardware::boot::V1_0::IBootControl> module_;
+  std::unique_ptr<DynamicPartitionControlAndroid> dynamic_control_;
+
+  friend class BootControlAndroidTest;
+
+  DISALLOW_COPY_AND_ASSIGN(BootControlAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_BOOT_CONTROL_ANDROID_H_
diff --git a/aosp/cleanup_previous_update_action.cc b/aosp/cleanup_previous_update_action.cc
new file mode 100644
index 0000000..278b101
--- /dev/null
+++ b/aosp/cleanup_previous_update_action.cc
@@ -0,0 +1,425 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#include "update_engine/aosp/cleanup_previous_update_action.h"
+
+#include <chrono>  // NOLINT(build/c++11) -- for merge times
+#include <functional>
+#include <string>
+#include <type_traits>
+
+#include <android-base/properties.h>
+#include <base/bind.h>
+
+#ifndef __ANDROID_RECOVERY__
+#include <statslog.h>
+#endif
+
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/delta_performer.h"
+
+using android::base::GetBoolProperty;
+using android::snapshot::ISnapshotManager;
+using android::snapshot::SnapshotMergeStats;
+using android::snapshot::UpdateState;
+using brillo::MessageLoop;
+
+constexpr char kBootCompletedProp[] = "sys.boot_completed";
+// Interval to check sys.boot_completed.
+constexpr auto kCheckBootCompletedInterval = base::TimeDelta::FromSeconds(2);
+// Interval to check IBootControl::isSlotMarkedSuccessful
+constexpr auto kCheckSlotMarkedSuccessfulInterval =
+    base::TimeDelta::FromSeconds(2);
+// Interval to call SnapshotManager::ProcessUpdateState
+constexpr auto kWaitForMergeInterval = base::TimeDelta::FromSeconds(2);
+
+#ifdef __ANDROID_RECOVERY__
+static constexpr bool kIsRecovery = true;
+#else
+static constexpr bool kIsRecovery = false;
+#endif
+
+namespace chromeos_update_engine {
+
+CleanupPreviousUpdateAction::CleanupPreviousUpdateAction(
+    PrefsInterface* prefs,
+    BootControlInterface* boot_control,
+    android::snapshot::ISnapshotManager* snapshot,
+    CleanupPreviousUpdateActionDelegateInterface* delegate)
+    : prefs_(prefs),
+      boot_control_(boot_control),
+      snapshot_(snapshot),
+      delegate_(delegate),
+      running_(false),
+      cancel_failed_(false),
+      last_percentage_(0),
+      merge_stats_(nullptr) {}
+
+void CleanupPreviousUpdateAction::PerformAction() {
+  ResumeAction();
+}
+
+void CleanupPreviousUpdateAction::TerminateProcessing() {
+  SuspendAction();
+}
+
+void CleanupPreviousUpdateAction::ResumeAction() {
+  CHECK(prefs_);
+  CHECK(boot_control_);
+
+  LOG(INFO) << "Starting/resuming CleanupPreviousUpdateAction";
+  running_ = true;
+  StartActionInternal();
+}
+
+void CleanupPreviousUpdateAction::SuspendAction() {
+  LOG(INFO) << "Stopping/suspending CleanupPreviousUpdateAction";
+  running_ = false;
+}
+
+void CleanupPreviousUpdateAction::ActionCompleted(ErrorCode error_code) {
+  running_ = false;
+  ReportMergeStats();
+  metadata_device_ = nullptr;
+}
+
+std::string CleanupPreviousUpdateAction::Type() const {
+  return StaticType();
+}
+
+std::string CleanupPreviousUpdateAction::StaticType() {
+  return "CleanupPreviousUpdateAction";
+}
+
+void CleanupPreviousUpdateAction::StartActionInternal() {
+  // Do nothing on non-VAB device.
+  if (!boot_control_->GetDynamicPartitionControl()
+           ->GetVirtualAbFeatureFlag()
+           .IsEnabled()) {
+    processor_->ActionComplete(this, ErrorCode::kSuccess);
+    return;
+  }
+  // SnapshotManager must be available on VAB devices.
+  CHECK(snapshot_ != nullptr);
+  merge_stats_ = snapshot_->GetSnapshotMergeStatsInstance();
+  CHECK(merge_stats_ != nullptr);
+  WaitBootCompletedOrSchedule();
+}
+
+void CleanupPreviousUpdateAction::ScheduleWaitBootCompleted() {
+  TEST_AND_RETURN(running_);
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&CleanupPreviousUpdateAction::WaitBootCompletedOrSchedule,
+                 base::Unretained(this)),
+      kCheckBootCompletedInterval);
+}
+
+void CleanupPreviousUpdateAction::WaitBootCompletedOrSchedule() {
+  TEST_AND_RETURN(running_);
+  if (!kIsRecovery &&
+      !android::base::GetBoolProperty(kBootCompletedProp, false)) {
+    // repeat
+    ScheduleWaitBootCompleted();
+    return;
+  }
+
+  LOG(INFO) << "Boot completed, waiting on markBootSuccessful()";
+  CheckSlotMarkedSuccessfulOrSchedule();
+}
+
+void CleanupPreviousUpdateAction::ScheduleWaitMarkBootSuccessful() {
+  TEST_AND_RETURN(running_);
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(
+          &CleanupPreviousUpdateAction::CheckSlotMarkedSuccessfulOrSchedule,
+          base::Unretained(this)),
+      kCheckSlotMarkedSuccessfulInterval);
+}
+
+void CleanupPreviousUpdateAction::CheckSlotMarkedSuccessfulOrSchedule() {
+  TEST_AND_RETURN(running_);
+  if (!kIsRecovery &&
+      !boot_control_->IsSlotMarkedSuccessful(boot_control_->GetCurrentSlot())) {
+    ScheduleWaitMarkBootSuccessful();
+  }
+
+  if (metadata_device_ == nullptr) {
+    metadata_device_ = snapshot_->EnsureMetadataMounted();
+  }
+
+  if (metadata_device_ == nullptr) {
+    LOG(ERROR) << "Failed to mount /metadata.";
+    // If metadata is erased but not formatted, it is possible to not mount
+    // it in recovery. It is safe to skip CleanupPreviousUpdateAction.
+    processor_->ActionComplete(
+        this, kIsRecovery ? ErrorCode::kSuccess : ErrorCode::kError);
+    return;
+  }
+
+  if (kIsRecovery) {
+    auto snapshots_created =
+        snapshot_->RecoveryCreateSnapshotDevices(metadata_device_);
+    switch (snapshots_created) {
+      case android::snapshot::CreateResult::CREATED: {
+        // If previous update has not finished merging, snapshots exists and are
+        // created here so that ProcessUpdateState can proceed.
+        LOG(INFO) << "Snapshot devices are created";
+        break;
+      }
+      case android::snapshot::CreateResult::NOT_CREATED: {
+        // If there is no previous update, no snapshot devices are created and
+        // ProcessUpdateState will return immediately. Hence, NOT_CREATED is not
+        // considered an error.
+        LOG(INFO) << "Snapshot devices are not created";
+        break;
+      }
+      case android::snapshot::CreateResult::ERROR:
+      default: {
+        LOG(ERROR)
+            << "Failed to create snapshot devices (CreateResult = "
+            << static_cast<
+                   std::underlying_type_t<android::snapshot::CreateResult>>(
+                   snapshots_created);
+        processor_->ActionComplete(this, ErrorCode::kError);
+        return;
+      }
+    }
+  }
+
+  if (!merge_stats_->Start()) {
+    // Not an error because CleanupPreviousUpdateAction may be paused and
+    // resumed while kernel continues merging snapshots in the background.
+    LOG(WARNING) << "SnapshotMergeStats::Start failed.";
+  }
+  LOG(INFO) << "Waiting for any previous merge request to complete. "
+            << "This can take up to several minutes.";
+  WaitForMergeOrSchedule();
+}
+
+void CleanupPreviousUpdateAction::ScheduleWaitForMerge() {
+  TEST_AND_RETURN(running_);
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&CleanupPreviousUpdateAction::WaitForMergeOrSchedule,
+                 base::Unretained(this)),
+      kWaitForMergeInterval);
+}
+
+void CleanupPreviousUpdateAction::WaitForMergeOrSchedule() {
+  TEST_AND_RETURN(running_);
+  auto state = snapshot_->ProcessUpdateState(
+      std::bind(&CleanupPreviousUpdateAction::OnMergePercentageUpdate, this),
+      std::bind(&CleanupPreviousUpdateAction::BeforeCancel, this));
+  merge_stats_->set_state(state);
+
+  switch (state) {
+    case UpdateState::None: {
+      LOG(INFO) << "Can't find any snapshot to merge.";
+      ErrorCode error_code = ErrorCode::kSuccess;
+      if (!snapshot_->CancelUpdate()) {
+        error_code = ErrorCode::kError;
+        LOG(INFO) << "Failed to call SnapshotManager::CancelUpdate().";
+      }
+      processor_->ActionComplete(this, error_code);
+      return;
+    }
+
+    case UpdateState::Initiated: {
+      LOG(ERROR) << "Previous update has not been completed, not cleaning up";
+      processor_->ActionComplete(this, ErrorCode::kSuccess);
+      return;
+    }
+
+    case UpdateState::Unverified: {
+      InitiateMergeAndWait();
+      return;
+    }
+
+    case UpdateState::Merging: {
+      ScheduleWaitForMerge();
+      return;
+    }
+
+    case UpdateState::MergeNeedsReboot: {
+      LOG(ERROR) << "Need reboot to finish merging.";
+      processor_->ActionComplete(this, ErrorCode::kError);
+      return;
+    }
+
+    case UpdateState::MergeCompleted: {
+      LOG(INFO) << "Merge finished with state MergeCompleted.";
+      processor_->ActionComplete(this, ErrorCode::kSuccess);
+      return;
+    }
+
+    case UpdateState::MergeFailed: {
+      LOG(ERROR) << "Merge failed. Device may be corrupted.";
+      processor_->ActionComplete(this, ErrorCode::kDeviceCorrupted);
+      return;
+    }
+
+    case UpdateState::Cancelled: {
+      // DeltaPerformer::ResetUpdateProgress failed, hence snapshots are
+      // not deleted to avoid inconsistency.
+      // Nothing can be done here; just try next time.
+      ErrorCode error_code =
+          cancel_failed_ ? ErrorCode::kError : ErrorCode::kSuccess;
+      processor_->ActionComplete(this, error_code);
+      return;
+    }
+
+    default: {
+      // Protobuf has some reserved enum values, so a default case is needed.
+      LOG(FATAL) << "SnapshotManager::ProcessUpdateState returns "
+                 << static_cast<int32_t>(state);
+    }
+  }
+}
+
+bool CleanupPreviousUpdateAction::OnMergePercentageUpdate() {
+  double percentage = 0.0;
+  snapshot_->GetUpdateState(&percentage);
+  if (delegate_) {
+    // libsnapshot uses [0, 100] percentage but update_engine uses [0, 1].
+    delegate_->OnCleanupProgressUpdate(percentage / 100);
+  }
+
+  // Log if percentage increments by at least 1.
+  if (last_percentage_ < static_cast<unsigned int>(percentage)) {
+    last_percentage_ = percentage;
+    LOG(INFO) << "Waiting for merge to complete: " << last_percentage_ << "%.";
+  }
+
+  // Do not continue to wait for merge. Instead, let ProcessUpdateState
+  // return Merging directly so that we can ScheduleWaitForMerge() in
+  // MessageLoop.
+  return false;
+}
+
+bool CleanupPreviousUpdateAction::BeforeCancel() {
+  if (DeltaPerformer::ResetUpdateProgress(
+          prefs_,
+          false /* quick */,
+          false /* skip dynamic partitions metadata*/)) {
+    return true;
+  }
+
+  // ResetUpdateProgress might not work on stub prefs. Do additional checks.
+  LOG(WARNING) << "ProcessUpdateState returns Cancelled but cleanup failed.";
+
+  std::string val;
+  ignore_result(prefs_->GetString(kPrefsDynamicPartitionMetadataUpdated, &val));
+  if (val.empty()) {
+    LOG(INFO) << kPrefsDynamicPartitionMetadataUpdated
+              << " is empty, assuming successful cleanup";
+    return true;
+  }
+  LOG(WARNING)
+      << kPrefsDynamicPartitionMetadataUpdated << " is " << val
+      << ", not deleting snapshots even though UpdateState is Cancelled.";
+  cancel_failed_ = true;
+  return false;
+}
+
+void CleanupPreviousUpdateAction::InitiateMergeAndWait() {
+  TEST_AND_RETURN(running_);
+  LOG(INFO) << "Attempting to initiate merge.";
+  // suspend the VAB merge when running a DSU
+  if (GetBoolProperty("ro.gsid.image_running", false)) {
+    LOG(WARNING) << "Suspend the VAB merge when running a DSU.";
+    processor_->ActionComplete(this, ErrorCode::kError);
+    return;
+  }
+
+  uint64_t cow_file_size;
+  if (snapshot_->InitiateMerge(&cow_file_size)) {
+    merge_stats_->set_cow_file_size(cow_file_size);
+    WaitForMergeOrSchedule();
+    return;
+  }
+
+  LOG(WARNING) << "InitiateMerge failed.";
+  auto state = snapshot_->GetUpdateState();
+  merge_stats_->set_state(state);
+  if (state == UpdateState::Unverified) {
+    // We are stuck at unverified state. This can happen if the update has
+    // been applied, but it has not even been attempted yet (in libsnapshot,
+    // rollback indicator does not exist); for example, if update_engine
+    // restarts before the device reboots, then this state may be reached.
+    // Nothing should be done here.
+    LOG(WARNING) << "InitiateMerge leaves the device at "
+                 << "UpdateState::Unverified. (Did update_engine "
+                 << "restarted?)";
+    processor_->ActionComplete(this, ErrorCode::kSuccess);
+    return;
+  }
+
+  // State does seems to be advanced.
+  // It is possibly racy. For example, on a userdebug build, the user may
+  // manually initiate a merge with snapshotctl between last time
+  // update_engine checks UpdateState. Hence, just call
+  // WaitForMergeOrSchedule one more time.
+  LOG(WARNING) << "IniitateMerge failed but GetUpdateState returned "
+               << android::snapshot::UpdateState_Name(state)
+               << ", try to wait for merge again.";
+  WaitForMergeOrSchedule();
+  return;
+}
+
+void CleanupPreviousUpdateAction::ReportMergeStats() {
+  auto result = merge_stats_->Finish();
+  if (result == nullptr) {
+    LOG(WARNING) << "Not reporting merge stats because "
+                    "SnapshotMergeStats::Finish failed.";
+    return;
+  }
+
+#ifdef __ANDROID_RECOVERY__
+  LOG(INFO) << "Skip reporting merge stats in recovery.";
+#else
+  const auto& report = result->report();
+
+  if (report.state() == UpdateState::None ||
+      report.state() == UpdateState::Initiated ||
+      report.state() == UpdateState::Unverified) {
+    LOG(INFO) << "Not reporting merge stats because state is "
+              << android::snapshot::UpdateState_Name(report.state());
+    return;
+  }
+
+  auto passed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
+      result->merge_time());
+
+  bool vab_retrofit = boot_control_->GetDynamicPartitionControl()
+                          ->GetVirtualAbFeatureFlag()
+                          .IsRetrofit();
+
+  LOG(INFO) << "Reporting merge stats: "
+            << android::snapshot::UpdateState_Name(report.state()) << " in "
+            << passed_ms.count() << "ms (resumed " << report.resume_count()
+            << " times), using " << report.cow_file_size()
+            << " bytes of COW image.";
+  android::util::stats_write(android::util::SNAPSHOT_MERGE_REPORTED,
+                             static_cast<int32_t>(report.state()),
+                             static_cast<int64_t>(passed_ms.count()),
+                             static_cast<int32_t>(report.resume_count()),
+                             vab_retrofit,
+                             static_cast<int64_t>(report.cow_file_size()));
+#endif
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/cleanup_previous_update_action.h b/aosp/cleanup_previous_update_action.h
new file mode 100644
index 0000000..73cef26
--- /dev/null
+++ b/aosp/cleanup_previous_update_action.h
@@ -0,0 +1,95 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
+#define UPDATE_ENGINE_AOSP_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
+
+#include <chrono>  // NOLINT(build/c++11) -- for merge times
+#include <memory>
+#include <string>
+
+#include <brillo/message_loops/message_loop.h>
+#include <libsnapshot/snapshot.h>
+#include <libsnapshot/snapshot_stats.h>
+
+#include "update_engine/common/action.h"
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/cleanup_previous_update_action_delegate.h"
+#include "update_engine/common/error_code.h"
+#include "update_engine/common/prefs_interface.h"
+
+namespace chromeos_update_engine {
+
+class CleanupPreviousUpdateAction;
+
+template <>
+class ActionTraits<CleanupPreviousUpdateAction> {
+ public:
+  typedef NoneType InputObjectType;
+  typedef NoneType OutputObjectType;
+};
+
+// On Android Virtual A/B devices, clean up snapshots from previous update
+// attempt. See DynamicPartitionControlAndroid::CleanupSuccessfulUpdate.
+class CleanupPreviousUpdateAction : public Action<CleanupPreviousUpdateAction> {
+ public:
+  CleanupPreviousUpdateAction(
+      PrefsInterface* prefs,
+      BootControlInterface* boot_control,
+      android::snapshot::ISnapshotManager* snapshot,
+      CleanupPreviousUpdateActionDelegateInterface* delegate);
+
+  void PerformAction() override;
+  void SuspendAction() override;
+  void ResumeAction() override;
+  void TerminateProcessing() override;
+  void ActionCompleted(ErrorCode error_code) override;
+  std::string Type() const override;
+  static std::string StaticType();
+  typedef ActionTraits<CleanupPreviousUpdateAction>::InputObjectType
+      InputObjectType;
+  typedef ActionTraits<CleanupPreviousUpdateAction>::OutputObjectType
+      OutputObjectType;
+
+ private:
+  PrefsInterface* prefs_;
+  BootControlInterface* boot_control_;
+  android::snapshot::ISnapshotManager* snapshot_;
+  CleanupPreviousUpdateActionDelegateInterface* delegate_;
+  std::unique_ptr<android::snapshot::AutoDevice> metadata_device_;
+  bool running_{false};
+  bool cancel_failed_{false};
+  unsigned int last_percentage_{0};
+  android::snapshot::ISnapshotMergeStats* merge_stats_;
+
+  void StartActionInternal();
+  void ScheduleWaitBootCompleted();
+  void WaitBootCompletedOrSchedule();
+  void ScheduleWaitMarkBootSuccessful();
+  void CheckSlotMarkedSuccessfulOrSchedule();
+  void ScheduleWaitForMerge();
+  void WaitForMergeOrSchedule();
+  void InitiateMergeAndWait();
+  void ReportMergeStats();
+
+  // Callbacks to ProcessUpdateState.
+  bool OnMergePercentageUpdate();
+  bool BeforeCancel();
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
diff --git a/aosp/daemon_android.cc b/aosp/daemon_android.cc
new file mode 100644
index 0000000..c102e3b
--- /dev/null
+++ b/aosp/daemon_android.cc
@@ -0,0 +1,74 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/daemon_android.h"
+
+#include <sysexits.h>
+
+#include <binderwrapper/binder_wrapper.h>
+
+#include "update_engine/aosp/daemon_state_android.h"
+
+using std::unique_ptr;
+
+namespace chromeos_update_engine {
+
+unique_ptr<DaemonBase> DaemonBase::CreateInstance() {
+  return std::make_unique<DaemonAndroid>();
+}
+
+int DaemonAndroid::OnInit() {
+  // Register the |subprocess_| singleton with this Daemon as the signal
+  // handler.
+  subprocess_.Init(this);
+
+  int exit_code = brillo::Daemon::OnInit();
+  if (exit_code != EX_OK)
+    return exit_code;
+
+  android::BinderWrapper::Create();
+  binder_watcher_.Init();
+
+  DaemonStateAndroid* daemon_state_android = new DaemonStateAndroid();
+  daemon_state_.reset(daemon_state_android);
+  LOG_IF(ERROR, !daemon_state_android->Initialize())
+      << "Failed to initialize system state.";
+
+  auto binder_wrapper = android::BinderWrapper::Get();
+
+  // Create the Binder Service.
+  binder_service_ = new BinderUpdateEngineAndroidService{
+      daemon_state_android->service_delegate()};
+  if (!binder_wrapper->RegisterService(binder_service_->ServiceName(),
+                                       binder_service_)) {
+    LOG(ERROR) << "Failed to register binder service.";
+  }
+  daemon_state_->AddObserver(binder_service_.get());
+
+  // Create the stable binder service.
+  stable_binder_service_ = new BinderUpdateEngineAndroidStableService{
+      daemon_state_android->service_delegate()};
+  if (!binder_wrapper->RegisterService(stable_binder_service_->ServiceName(),
+                                       stable_binder_service_)) {
+    LOG(ERROR) << "Failed to register stable binder service.";
+  }
+  daemon_state_->AddObserver(stable_binder_service_.get());
+
+  daemon_state_->StartUpdater();
+  return EX_OK;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/daemon_android.h b/aosp/daemon_android.h
new file mode 100644
index 0000000..38a8689
--- /dev/null
+++ b/aosp/daemon_android.h
@@ -0,0 +1,58 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_DAEMON_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_DAEMON_ANDROID_H_
+
+#include <memory>
+
+#include <brillo/binder_watcher.h>
+
+#include "update_engine/aosp/binder_service_android.h"
+#include "update_engine/aosp/binder_service_stable_android.h"
+#include "update_engine/common/daemon_base.h"
+#include "update_engine/common/daemon_state_interface.h"
+#include "update_engine/common/subprocess.h"
+
+namespace chromeos_update_engine {
+
+class DaemonAndroid : public DaemonBase {
+ public:
+  DaemonAndroid() = default;
+
+ protected:
+  int OnInit() override;
+
+ private:
+  // The Subprocess singleton class requires a |brillo::MessageLoop| in the
+  // current thread, so we need to initialize it from this class instead of
+  // the main() function.
+  Subprocess subprocess_;
+
+  brillo::BinderWatcher binder_watcher_;
+  android::sp<BinderUpdateEngineAndroidService> binder_service_;
+  android::sp<BinderUpdateEngineAndroidStableService> stable_binder_service_;
+
+  // The daemon state with all the required daemon classes for the configured
+  // platform.
+  std::unique_ptr<DaemonStateInterface> daemon_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(DaemonAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_DAEMON_ANDROID_H_
diff --git a/aosp/daemon_state_android.cc b/aosp/daemon_state_android.cc
new file mode 100644
index 0000000..9bdd175
--- /dev/null
+++ b/aosp/daemon_state_android.cc
@@ -0,0 +1,92 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/daemon_state_android.h"
+
+#include <base/logging.h>
+
+#include "update_engine/aosp/update_attempter_android.h"
+#include "update_engine/common/boot_control.h"
+#include "update_engine/common/boot_control_stub.h"
+#include "update_engine/common/hardware.h"
+#include "update_engine/common/prefs.h"
+
+namespace chromeos_update_engine {
+
+bool DaemonStateAndroid::Initialize() {
+  boot_control_ = boot_control::CreateBootControl();
+  if (!boot_control_) {
+    LOG(WARNING) << "Unable to create BootControl instance, using stub "
+                 << "instead. All update attempts will fail.";
+    boot_control_.reset(new BootControlStub());
+  }
+
+  hardware_ = hardware::CreateHardware();
+  if (!hardware_) {
+    LOG(ERROR) << "Error initializing the HardwareInterface.";
+    return false;
+  }
+
+  LOG_IF(INFO, !hardware_->IsNormalBootMode()) << "Booted in dev mode.";
+  LOG_IF(INFO, !hardware_->IsOfficialBuild()) << "Booted non-official build.";
+
+  // Initialize prefs.
+  base::FilePath non_volatile_path;
+  if (!hardware_->GetNonVolatileDirectory(&non_volatile_path)) {
+    prefs_.reset(new MemoryPrefs());
+    LOG(WARNING)
+        << "Could not get a non-volatile directory, fall back to memory prefs";
+  } else {
+    Prefs* prefs = new Prefs();
+    prefs_.reset(prefs);
+    if (!prefs->Init(non_volatile_path.Append(kPrefsSubDirectory))) {
+      LOG(ERROR) << "Failed to initialize preferences.";
+      return false;
+    }
+  }
+
+  // The CertificateChecker singleton is used by the update attempter.
+  certificate_checker_.reset(
+      new CertificateChecker(prefs_.get(), &openssl_wrapper_));
+  certificate_checker_->Init();
+
+  // Initialize the UpdateAttempter before the UpdateManager.
+  update_attempter_.reset(new UpdateAttempterAndroid(
+      this, prefs_.get(), boot_control_.get(), hardware_.get()));
+
+  return true;
+}
+
+bool DaemonStateAndroid::StartUpdater() {
+  // The DaemonState in Android is a passive daemon. It will only start applying
+  // an update when instructed to do so from the exposed binder API.
+  update_attempter_->Init();
+  return true;
+}
+
+void DaemonStateAndroid::AddObserver(ServiceObserverInterface* observer) {
+  service_observers_.insert(observer);
+}
+
+void DaemonStateAndroid::RemoveObserver(ServiceObserverInterface* observer) {
+  service_observers_.erase(observer);
+}
+
+ServiceDelegateAndroidInterface* DaemonStateAndroid::service_delegate() {
+  return update_attempter_.get();
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/daemon_state_android.h b/aosp/daemon_state_android.h
new file mode 100644
index 0000000..dea3a23
--- /dev/null
+++ b/aosp/daemon_state_android.h
@@ -0,0 +1,76 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_DAEMON_STATE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_DAEMON_STATE_ANDROID_H_
+
+#include <memory>
+#include <set>
+
+#include "update_engine/aosp/service_delegate_android_interface.h"
+#include "update_engine/aosp/update_attempter_android.h"
+#include "update_engine/certificate_checker.h"
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/daemon_state_interface.h"
+#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/service_observer_interface.h"
+
+namespace chromeos_update_engine {
+
+class DaemonStateAndroid : public DaemonStateInterface {
+ public:
+  DaemonStateAndroid() = default;
+  ~DaemonStateAndroid() override = default;
+
+  bool Initialize();
+
+  // DaemonStateInterface overrides.
+  bool StartUpdater() override;
+  void AddObserver(ServiceObserverInterface* observer) override;
+  void RemoveObserver(ServiceObserverInterface* observer) override;
+
+  const std::set<ServiceObserverInterface*>& service_observers() override {
+    return service_observers_;
+  }
+
+  // Return a pointer to the service delegate.
+  ServiceDelegateAndroidInterface* service_delegate();
+
+ protected:
+  std::set<ServiceObserverInterface*> service_observers_;
+
+  // Interface for the boot control functions.
+  std::unique_ptr<BootControlInterface> boot_control_;
+
+  // Interface for the hardware functions.
+  std::unique_ptr<HardwareInterface> hardware_;
+
+  // Interface for persisted store.
+  std::unique_ptr<PrefsInterface> prefs_;
+
+  // The main class handling the updates.
+  std::unique_ptr<UpdateAttempterAndroid> update_attempter_;
+
+  // OpenSSLWrapper and CertificateChecker used for checking changes in SSL
+  // certificates.
+  OpenSSLWrapper openssl_wrapper_;
+  std::unique_ptr<CertificateChecker> certificate_checker_;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_DAEMON_STATE_ANDROID_H_
diff --git a/aosp/dynamic_partition_control_android.cc b/aosp/dynamic_partition_control_android.cc
new file mode 100644
index 0000000..e045965
--- /dev/null
+++ b/aosp/dynamic_partition_control_android.cc
@@ -0,0 +1,1222 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/dynamic_partition_control_android.h"
+
+#include <chrono>  // NOLINT(build/c++11) - using libsnapshot / liblp API
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <base/files/file_util.h>
+#include <base/logging.h>
+#include <base/strings/string_util.h>
+#include <bootloader_message/bootloader_message.h>
+#include <fs_mgr.h>
+#include <fs_mgr_dm_linear.h>
+#include <fs_mgr_overlayfs.h>
+#include <libavb/libavb.h>
+#include <libdm/dm.h>
+#include <libsnapshot/snapshot.h>
+#include <libsnapshot/snapshot_stub.h>
+
+#include "update_engine/aosp/cleanup_previous_update_action.h"
+#include "update_engine/aosp/dynamic_partition_utils.h"
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/delta_performer.h"
+
+using android::base::GetBoolProperty;
+using android::base::GetProperty;
+using android::base::Join;
+using android::dm::DeviceMapper;
+using android::dm::DmDeviceState;
+using android::fs_mgr::CreateLogicalPartition;
+using android::fs_mgr::CreateLogicalPartitionParams;
+using android::fs_mgr::DestroyLogicalPartition;
+using android::fs_mgr::Fstab;
+using android::fs_mgr::MetadataBuilder;
+using android::fs_mgr::Partition;
+using android::fs_mgr::PartitionOpener;
+using android::fs_mgr::SlotSuffixForSlotNumber;
+using android::snapshot::OptimizeSourceCopyOperation;
+using android::snapshot::Return;
+using android::snapshot::SnapshotManager;
+using android::snapshot::SnapshotManagerStub;
+using android::snapshot::UpdateState;
+
+namespace chromeos_update_engine {
+
+constexpr char kUseDynamicPartitions[] = "ro.boot.dynamic_partitions";
+constexpr char kRetrfoitDynamicPartitions[] =
+    "ro.boot.dynamic_partitions_retrofit";
+constexpr char kVirtualAbEnabled[] = "ro.virtual_ab.enabled";
+constexpr char kVirtualAbRetrofit[] = "ro.virtual_ab.retrofit";
+constexpr char kPostinstallFstabPrefix[] = "ro.postinstall.fstab.prefix";
+// Map timeout for dynamic partitions.
+constexpr std::chrono::milliseconds kMapTimeout{1000};
+// Map timeout for dynamic partitions with snapshots. Since several devices
+// needs to be mapped, this timeout is longer than |kMapTimeout|.
+constexpr std::chrono::milliseconds kMapSnapshotTimeout{5000};
+
+#ifdef __ANDROID_RECOVERY__
+constexpr bool kIsRecovery = true;
+#else
+constexpr bool kIsRecovery = false;
+#endif
+
+DynamicPartitionControlAndroid::~DynamicPartitionControlAndroid() {
+  Cleanup();
+}
+
+static FeatureFlag GetFeatureFlag(const char* enable_prop,
+                                  const char* retrofit_prop) {
+  bool retrofit = GetBoolProperty(retrofit_prop, false);
+  bool enabled = GetBoolProperty(enable_prop, false);
+  if (retrofit && !enabled) {
+    LOG(ERROR) << retrofit_prop << " is true but " << enable_prop
+               << " is not. These sysprops are inconsistent. Assume that "
+               << enable_prop << " is true from now on.";
+  }
+  if (retrofit) {
+    return FeatureFlag(FeatureFlag::Value::RETROFIT);
+  }
+  if (enabled) {
+    return FeatureFlag(FeatureFlag::Value::LAUNCH);
+  }
+  return FeatureFlag(FeatureFlag::Value::NONE);
+}
+
+DynamicPartitionControlAndroid::DynamicPartitionControlAndroid()
+    : dynamic_partitions_(
+          GetFeatureFlag(kUseDynamicPartitions, kRetrfoitDynamicPartitions)),
+      virtual_ab_(GetFeatureFlag(kVirtualAbEnabled, kVirtualAbRetrofit)) {
+  if (GetVirtualAbFeatureFlag().IsEnabled()) {
+    snapshot_ = SnapshotManager::New();
+  } else {
+    snapshot_ = SnapshotManagerStub::New();
+  }
+  CHECK(snapshot_ != nullptr) << "Cannot initialize SnapshotManager.";
+}
+
+FeatureFlag DynamicPartitionControlAndroid::GetDynamicPartitionsFeatureFlag() {
+  return dynamic_partitions_;
+}
+
+FeatureFlag DynamicPartitionControlAndroid::GetVirtualAbFeatureFlag() {
+  return virtual_ab_;
+}
+
+bool DynamicPartitionControlAndroid::OptimizeOperation(
+    const std::string& partition_name,
+    const InstallOperation& operation,
+    InstallOperation* optimized) {
+  switch (operation.type()) {
+    case InstallOperation::SOURCE_COPY:
+      return target_supports_snapshot_ &&
+             GetVirtualAbFeatureFlag().IsEnabled() &&
+             mapped_devices_.count(partition_name +
+                                   SlotSuffixForSlotNumber(target_slot_)) > 0 &&
+             OptimizeSourceCopyOperation(operation, optimized);
+      break;
+    default:
+      break;
+  }
+  return false;
+}
+
+bool DynamicPartitionControlAndroid::MapPartitionInternal(
+    const std::string& super_device,
+    const std::string& target_partition_name,
+    uint32_t slot,
+    bool force_writable,
+    std::string* path) {
+  CreateLogicalPartitionParams params = {
+      .block_device = super_device,
+      .metadata_slot = slot,
+      .partition_name = target_partition_name,
+      .force_writable = force_writable,
+  };
+  bool success = false;
+  if (GetVirtualAbFeatureFlag().IsEnabled() && target_supports_snapshot_ &&
+      force_writable && ExpectMetadataMounted()) {
+    // Only target partitions are mapped with force_writable. On Virtual
+    // A/B devices, target partitions may overlap with source partitions, so
+    // they must be mapped with snapshot.
+    // One exception is when /metadata is not mounted. Fallback to
+    // CreateLogicalPartition as snapshots are not created in the first place.
+    params.timeout_ms = kMapSnapshotTimeout;
+    success = snapshot_->MapUpdateSnapshot(params, path);
+  } else {
+    params.timeout_ms = kMapTimeout;
+    success = CreateLogicalPartition(params, path);
+  }
+
+  if (!success) {
+    LOG(ERROR) << "Cannot map " << target_partition_name << " in "
+               << super_device << " on device mapper.";
+    return false;
+  }
+  LOG(INFO) << "Succesfully mapped " << target_partition_name
+            << " to device mapper (force_writable = " << force_writable
+            << "); device path at " << *path;
+  mapped_devices_.insert(target_partition_name);
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::MapPartitionOnDeviceMapper(
+    const std::string& super_device,
+    const std::string& target_partition_name,
+    uint32_t slot,
+    bool force_writable,
+    std::string* path) {
+  DmDeviceState state = GetState(target_partition_name);
+  if (state == DmDeviceState::ACTIVE) {
+    if (mapped_devices_.find(target_partition_name) != mapped_devices_.end()) {
+      if (GetDmDevicePathByName(target_partition_name, path)) {
+        LOG(INFO) << target_partition_name
+                  << " is mapped on device mapper: " << *path;
+        return true;
+      }
+      LOG(ERROR) << target_partition_name << " is mapped but path is unknown.";
+      return false;
+    }
+    // If target_partition_name is not in mapped_devices_ but state is ACTIVE,
+    // the device might be mapped incorrectly before. Attempt to unmap it.
+    // Note that for source partitions, if GetState() == ACTIVE, callers (e.g.
+    // BootControlAndroid) should not call MapPartitionOnDeviceMapper, but
+    // should directly call GetDmDevicePathByName.
+    if (!UnmapPartitionOnDeviceMapper(target_partition_name)) {
+      LOG(ERROR) << target_partition_name
+                 << " is mapped before the update, and it cannot be unmapped.";
+      return false;
+    }
+    state = GetState(target_partition_name);
+    if (state != DmDeviceState::INVALID) {
+      LOG(ERROR) << target_partition_name << " is unmapped but state is "
+                 << static_cast<std::underlying_type_t<DmDeviceState>>(state);
+      return false;
+    }
+  }
+  if (state == DmDeviceState::INVALID) {
+    return MapPartitionInternal(
+        super_device, target_partition_name, slot, force_writable, path);
+  }
+
+  LOG(ERROR) << target_partition_name
+             << " is mapped on device mapper but state is unknown: "
+             << static_cast<std::underlying_type_t<DmDeviceState>>(state);
+  return false;
+}
+
+bool DynamicPartitionControlAndroid::UnmapPartitionOnDeviceMapper(
+    const std::string& target_partition_name) {
+  if (DeviceMapper::Instance().GetState(target_partition_name) !=
+      DmDeviceState::INVALID) {
+    // Partitions at target slot on non-Virtual A/B devices are mapped as
+    // dm-linear. Also, on Virtual A/B devices, system_other may be mapped for
+    // preopt apps as dm-linear.
+    // Call DestroyLogicalPartition to handle these cases.
+    bool success = DestroyLogicalPartition(target_partition_name);
+
+    // On a Virtual A/B device, |target_partition_name| may be a leftover from
+    // a paused update. Clean up any underlying devices.
+    if (ExpectMetadataMounted()) {
+      success &= snapshot_->UnmapUpdateSnapshot(target_partition_name);
+    } else {
+      LOG(INFO) << "Skip UnmapUpdateSnapshot(" << target_partition_name
+                << ") because metadata is not mounted";
+    }
+
+    if (!success) {
+      LOG(ERROR) << "Cannot unmap " << target_partition_name
+                 << " from device mapper.";
+      return false;
+    }
+    LOG(INFO) << "Successfully unmapped " << target_partition_name
+              << " from device mapper.";
+  }
+  mapped_devices_.erase(target_partition_name);
+  return true;
+}
+
+void DynamicPartitionControlAndroid::UnmapAllPartitions() {
+  if (mapped_devices_.empty()) {
+    return;
+  }
+  // UnmapPartitionOnDeviceMapper removes objects from mapped_devices_, hence
+  // a copy is needed for the loop.
+  std::set<std::string> mapped = mapped_devices_;
+  LOG(INFO) << "Destroying [" << Join(mapped, ", ") << "] from device mapper";
+  for (const auto& partition_name : mapped) {
+    ignore_result(UnmapPartitionOnDeviceMapper(partition_name));
+  }
+}
+
+void DynamicPartitionControlAndroid::Cleanup() {
+  UnmapAllPartitions();
+  metadata_device_.reset();
+}
+
+bool DynamicPartitionControlAndroid::DeviceExists(const std::string& path) {
+  return base::PathExists(base::FilePath(path));
+}
+
+android::dm::DmDeviceState DynamicPartitionControlAndroid::GetState(
+    const std::string& name) {
+  return DeviceMapper::Instance().GetState(name);
+}
+
+bool DynamicPartitionControlAndroid::GetDmDevicePathByName(
+    const std::string& name, std::string* path) {
+  return DeviceMapper::Instance().GetDmDevicePathByName(name, path);
+}
+
+std::unique_ptr<MetadataBuilder>
+DynamicPartitionControlAndroid::LoadMetadataBuilder(
+    const std::string& super_device, uint32_t slot) {
+  auto builder = MetadataBuilder::New(PartitionOpener(), super_device, slot);
+  if (builder == nullptr) {
+    LOG(WARNING) << "No metadata slot " << BootControlInterface::SlotName(slot)
+                 << " in " << super_device;
+    return nullptr;
+  }
+  LOG(INFO) << "Loaded metadata from slot "
+            << BootControlInterface::SlotName(slot) << " in " << super_device;
+  return builder;
+}
+
+std::unique_ptr<MetadataBuilder>
+DynamicPartitionControlAndroid::LoadMetadataBuilder(
+    const std::string& super_device,
+    uint32_t source_slot,
+    uint32_t target_slot) {
+  bool always_keep_source_slot = !target_supports_snapshot_;
+  auto builder = MetadataBuilder::NewForUpdate(PartitionOpener(),
+                                               super_device,
+                                               source_slot,
+                                               target_slot,
+                                               always_keep_source_slot);
+  if (builder == nullptr) {
+    LOG(WARNING) << "No metadata slot "
+                 << BootControlInterface::SlotName(source_slot) << " in "
+                 << super_device;
+    return nullptr;
+  }
+  LOG(INFO) << "Created metadata for new update from slot "
+            << BootControlInterface::SlotName(source_slot) << " in "
+            << super_device;
+  return builder;
+}
+
+bool DynamicPartitionControlAndroid::StoreMetadata(
+    const std::string& super_device,
+    MetadataBuilder* builder,
+    uint32_t target_slot) {
+  auto metadata = builder->Export();
+  if (metadata == nullptr) {
+    LOG(ERROR) << "Cannot export metadata to slot "
+               << BootControlInterface::SlotName(target_slot) << " in "
+               << super_device;
+    return false;
+  }
+
+  if (GetDynamicPartitionsFeatureFlag().IsRetrofit()) {
+    if (!FlashPartitionTable(super_device, *metadata)) {
+      LOG(ERROR) << "Cannot write metadata to " << super_device;
+      return false;
+    }
+    LOG(INFO) << "Written metadata to " << super_device;
+  } else {
+    if (!UpdatePartitionTable(super_device, *metadata, target_slot)) {
+      LOG(ERROR) << "Cannot write metadata to slot "
+                 << BootControlInterface::SlotName(target_slot) << " in "
+                 << super_device;
+      return false;
+    }
+    LOG(INFO) << "Copied metadata to slot "
+              << BootControlInterface::SlotName(target_slot) << " in "
+              << super_device;
+  }
+
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::GetDeviceDir(std::string* out) {
+  // We can't use fs_mgr to look up |partition_name| because fstab
+  // doesn't list every slot partition (it uses the slotselect option
+  // to mask the suffix).
+  //
+  // We can however assume that there's an entry for the /misc mount
+  // point and use that to get the device file for the misc
+  // partition. This helps us locate the disk that |partition_name|
+  // resides on. From there we'll assume that a by-name scheme is used
+  // so we can just replace the trailing "misc" by the given
+  // |partition_name| and suffix corresponding to |slot|, e.g.
+  //
+  //   /dev/block/platform/soc.0/7824900.sdhci/by-name/misc ->
+  //   /dev/block/platform/soc.0/7824900.sdhci/by-name/boot_a
+  //
+  // If needed, it's possible to relax the by-name assumption in the
+  // future by trawling /sys/block looking for the appropriate sibling
+  // of misc and then finding an entry in /dev matching the sysfs
+  // entry.
+
+  std::string err, misc_device = get_bootloader_message_blk_device(&err);
+  if (misc_device.empty()) {
+    LOG(ERROR) << "Unable to get misc block device: " << err;
+    return false;
+  }
+
+  if (!utils::IsSymlink(misc_device.c_str())) {
+    LOG(ERROR) << "Device file " << misc_device << " for /misc "
+               << "is not a symlink.";
+    return false;
+  }
+  *out = base::FilePath(misc_device).DirName().value();
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::PreparePartitionsForUpdate(
+    uint32_t source_slot,
+    uint32_t target_slot,
+    const DeltaArchiveManifest& manifest,
+    bool update,
+    uint64_t* required_size) {
+  source_slot_ = source_slot;
+  target_slot_ = target_slot;
+  if (required_size != nullptr) {
+    *required_size = 0;
+  }
+
+  if (fs_mgr_overlayfs_is_setup()) {
+    // Non DAP devices can use overlayfs as well.
+    LOG(WARNING)
+        << "overlayfs overrides are active and can interfere with our "
+           "resources.\n"
+        << "run adb enable-verity to deactivate if required and try again.";
+  }
+
+  // If metadata is erased but not formatted, it is possible to not mount
+  // it in recovery. It is acceptable to skip mounting and choose fallback path
+  // (PrepareDynamicPartitionsForUpdate) when sideloading full OTAs.
+  TEST_AND_RETURN_FALSE(EnsureMetadataMounted() || IsRecovery());
+
+  if (update) {
+    TEST_AND_RETURN_FALSE(EraseSystemOtherAvbFooter(source_slot, target_slot));
+  }
+
+  if (!GetDynamicPartitionsFeatureFlag().IsEnabled()) {
+    return true;
+  }
+
+  if (target_slot == source_slot) {
+    LOG(ERROR) << "Cannot call PreparePartitionsForUpdate on current slot.";
+    return false;
+  }
+
+  if (!SetTargetBuildVars(manifest)) {
+    return false;
+  }
+
+  // Although the current build supports dynamic partitions, the given payload
+  // doesn't use it for target partitions. This could happen when applying a
+  // retrofit update. Skip updating the partition metadata for the target slot.
+  if (!is_target_dynamic_) {
+    return true;
+  }
+
+  if (!update)
+    return true;
+
+  bool delete_source = false;
+
+  if (GetVirtualAbFeatureFlag().IsEnabled()) {
+    // On Virtual A/B device, either CancelUpdate() or BeginUpdate() must be
+    // called before calling UnmapUpdateSnapshot.
+    // - If target_supports_snapshot_, PrepareSnapshotPartitionsForUpdate()
+    //   calls BeginUpdate() which resets update state
+    // - If !target_supports_snapshot_ or PrepareSnapshotPartitionsForUpdate
+    //   failed in recovery, explicitly CancelUpdate().
+    if (target_supports_snapshot_) {
+      if (PrepareSnapshotPartitionsForUpdate(
+              source_slot, target_slot, manifest, required_size)) {
+        return true;
+      }
+
+      // Virtual A/B device doing Virtual A/B update in Android mode must use
+      // snapshots.
+      if (!IsRecovery()) {
+        LOG(ERROR) << "PrepareSnapshotPartitionsForUpdate failed in Android "
+                   << "mode";
+        return false;
+      }
+
+      delete_source = true;
+      LOG(INFO) << "PrepareSnapshotPartitionsForUpdate failed in recovery. "
+                << "Attempt to overwrite existing partitions if possible";
+    } else {
+      // Downgrading to an non-Virtual A/B build or is secondary OTA.
+      LOG(INFO) << "Using regular A/B on Virtual A/B because package disabled "
+                << "snapshots.";
+    }
+
+    // In recovery, if /metadata is not mounted, it is likely that metadata
+    // partition is erased and not formatted yet. After sideloading, when
+    // rebooting into the new version, init will erase metadata partition,
+    // hence the failure of CancelUpdate() can be ignored here.
+    // However, if metadata is mounted and CancelUpdate fails, sideloading
+    // should not proceed because during next boot, snapshots will overlay on
+    // the devices incorrectly.
+    if (ExpectMetadataMounted()) {
+      TEST_AND_RETURN_FALSE(snapshot_->CancelUpdate());
+    } else {
+      LOG(INFO) << "Skip canceling previous update because metadata is not "
+                << "mounted";
+    }
+  }
+
+  // TODO(xunchang) support partial update on non VAB enabled devices.
+  TEST_AND_RETURN_FALSE(PrepareDynamicPartitionsForUpdate(
+      source_slot, target_slot, manifest, delete_source));
+
+  if (required_size != nullptr) {
+    *required_size = 0;
+  }
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::SetTargetBuildVars(
+    const DeltaArchiveManifest& manifest) {
+  // Precondition: current build supports dynamic partition.
+  CHECK(GetDynamicPartitionsFeatureFlag().IsEnabled());
+
+  bool is_target_dynamic =
+      !manifest.dynamic_partition_metadata().groups().empty();
+  bool target_supports_snapshot =
+      manifest.dynamic_partition_metadata().snapshot_enabled();
+
+  if (manifest.partial_update()) {
+    // Partial updates requires DAP. On partial updates that does not involve
+    // dynamic partitions, groups() can be empty, so also assume
+    // is_target_dynamic in this case. This assumption should be safe because we
+    // also check target_supports_snapshot below, which presumably also implies
+    // target build supports dynamic partition.
+    if (!is_target_dynamic) {
+      LOG(INFO) << "Assuming target build supports dynamic partitions for "
+                   "partial updates.";
+      is_target_dynamic = true;
+    }
+
+    // Partial updates requires Virtual A/B. Double check that both current
+    // build and target build supports Virtual A/B.
+    if (!GetVirtualAbFeatureFlag().IsEnabled()) {
+      LOG(ERROR) << "Partial update cannot be applied on a device that does "
+                    "not support snapshots.";
+      return false;
+    }
+    if (!target_supports_snapshot) {
+      LOG(ERROR) << "Cannot apply partial update to a build that does not "
+                    "support snapshots.";
+      return false;
+    }
+  }
+
+  // Store the flags.
+  is_target_dynamic_ = is_target_dynamic;
+  // If !is_target_dynamic_, leave target_supports_snapshot_ unset because
+  // snapshots would not work without dynamic partition.
+  if (is_target_dynamic_) {
+    target_supports_snapshot_ = target_supports_snapshot;
+  }
+  return true;
+}
+
+namespace {
+// Try our best to erase AVB footer.
+class AvbFooterEraser {
+ public:
+  explicit AvbFooterEraser(const std::string& path) : path_(path) {}
+  bool Erase() {
+    // Try to mark the block device read-only. Ignore any
+    // failure since this won't work when passing regular files.
+    ignore_result(utils::SetBlockDeviceReadOnly(path_, false /* readonly */));
+
+    fd_.reset(new EintrSafeFileDescriptor());
+    int flags = O_WRONLY | O_TRUNC | O_CLOEXEC | O_SYNC;
+    TEST_AND_RETURN_FALSE(fd_->Open(path_.c_str(), flags));
+
+    // Need to write end-AVB_FOOTER_SIZE to end.
+    static_assert(AVB_FOOTER_SIZE > 0);
+    off64_t offset = fd_->Seek(-AVB_FOOTER_SIZE, SEEK_END);
+    TEST_AND_RETURN_FALSE_ERRNO(offset >= 0);
+    uint64_t write_size = AVB_FOOTER_SIZE;
+    LOG(INFO) << "Zeroing " << path_ << " @ [" << offset << ", "
+              << (offset + write_size) << "] (" << write_size << " bytes)";
+    brillo::Blob zeros(write_size);
+    TEST_AND_RETURN_FALSE(utils::WriteAll(fd_, zeros.data(), zeros.size()));
+    return true;
+  }
+  ~AvbFooterEraser() {
+    TEST_AND_RETURN(fd_ != nullptr && fd_->IsOpen());
+    if (!fd_->Close()) {
+      LOG(WARNING) << "Failed to close fd for " << path_;
+    }
+  }
+
+ private:
+  std::string path_;
+  FileDescriptorPtr fd_;
+};
+
+}  // namespace
+
+std::optional<bool>
+DynamicPartitionControlAndroid::IsAvbEnabledOnSystemOther() {
+  auto prefix = GetProperty(kPostinstallFstabPrefix, "");
+  if (prefix.empty()) {
+    LOG(WARNING) << "Cannot get " << kPostinstallFstabPrefix;
+    return std::nullopt;
+  }
+  auto path = base::FilePath(prefix).Append("etc/fstab.postinstall").value();
+  return IsAvbEnabledInFstab(path);
+}
+
+std::optional<bool> DynamicPartitionControlAndroid::IsAvbEnabledInFstab(
+    const std::string& path) {
+  Fstab fstab;
+  if (!ReadFstabFromFile(path, &fstab)) {
+    PLOG(WARNING) << "Cannot read fstab from " << path;
+    if (errno == ENOENT) {
+      return false;
+    }
+    return std::nullopt;
+  }
+  for (const auto& entry : fstab) {
+    if (!entry.avb_keys.empty()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool DynamicPartitionControlAndroid::GetSystemOtherPath(
+    uint32_t source_slot,
+    uint32_t target_slot,
+    const std::string& partition_name_suffix,
+    std::string* path,
+    bool* should_unmap) {
+  path->clear();
+  *should_unmap = false;
+
+  // Check that AVB is enabled on system_other before erasing.
+  auto has_avb = IsAvbEnabledOnSystemOther();
+  TEST_AND_RETURN_FALSE(has_avb.has_value());
+  if (!has_avb.value()) {
+    LOG(INFO) << "AVB is not enabled on system_other. Skip erasing.";
+    return true;
+  }
+
+  if (!IsRecovery()) {
+    // Found unexpected avb_keys for system_other on devices retrofitting
+    // dynamic partitions. Previous crash in update_engine may leave logical
+    // partitions mapped on physical system_other partition. It is difficult to
+    // handle these cases. Just fail.
+    if (GetDynamicPartitionsFeatureFlag().IsRetrofit()) {
+      LOG(ERROR) << "Cannot erase AVB footer on system_other on devices with "
+                 << "retrofit dynamic partitions. They should not have AVB "
+                 << "enabled on system_other.";
+      return false;
+    }
+  }
+
+  std::string device_dir_str;
+  TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str));
+  base::FilePath device_dir(device_dir_str);
+
+  // On devices without dynamic partition, search for static partitions.
+  if (!GetDynamicPartitionsFeatureFlag().IsEnabled()) {
+    *path = device_dir.Append(partition_name_suffix).value();
+    TEST_AND_RETURN_FALSE(DeviceExists(*path));
+    return true;
+  }
+
+  auto source_super_device =
+      device_dir.Append(GetSuperPartitionName(source_slot)).value();
+
+  auto builder = LoadMetadataBuilder(source_super_device, source_slot);
+  if (builder == nullptr) {
+    if (IsRecovery()) {
+      // It might be corrupted for some reason. It should still be able to
+      // sideload.
+      LOG(WARNING) << "Super partition metadata cannot be read from the source "
+                   << "slot, skip erasing.";
+      return true;
+    } else {
+      // Device has booted into Android mode, indicating that the super
+      // partition metadata should be there.
+      LOG(ERROR) << "Super partition metadata cannot be read from the source "
+                 << "slot. This is unexpected on devices with dynamic "
+                 << "partitions enabled.";
+      return false;
+    }
+  }
+  auto p = builder->FindPartition(partition_name_suffix);
+  if (p == nullptr) {
+    // If the source slot is flashed without system_other, it does not exist
+    // in super partition metadata at source slot. It is safe to skip it.
+    LOG(INFO) << "Can't find " << partition_name_suffix
+              << " in metadata source slot, skip erasing.";
+    return true;
+  }
+  // System_other created by flashing tools should be erased.
+  // If partition is created by update_engine (via NewForUpdate), it is a
+  // left-over partition from the previous update and does not contain
+  // system_other, hence there is no need to erase.
+  // Note the reverse is not necessary true. If the flag is not set, we don't
+  // know if the partition is created by update_engine or by flashing tools
+  // because older versions of super partition metadata does not contain this
+  // flag. It is okay to erase the AVB footer anyways.
+  if (p->attributes() & LP_PARTITION_ATTR_UPDATED) {
+    LOG(INFO) << partition_name_suffix
+              << " does not contain system_other, skip erasing.";
+    return true;
+  }
+
+  if (p->size() < AVB_FOOTER_SIZE) {
+    LOG(INFO) << partition_name_suffix << " has length " << p->size()
+              << "( < AVB_FOOTER_SIZE " << AVB_FOOTER_SIZE
+              << "), skip erasing.";
+    return true;
+  }
+
+  // Delete any pre-existing device with name |partition_name_suffix| and
+  // also remove it from |mapped_devices_|.
+  // In recovery, metadata might not be mounted, and
+  // UnmapPartitionOnDeviceMapper might fail. However,
+  // it is unusual that system_other has already been mapped. Hence, just skip.
+  TEST_AND_RETURN_FALSE(UnmapPartitionOnDeviceMapper(partition_name_suffix));
+  // Use CreateLogicalPartition directly to avoid mapping with existing
+  // snapshots.
+  CreateLogicalPartitionParams params = {
+      .block_device = source_super_device,
+      .metadata_slot = source_slot,
+      .partition_name = partition_name_suffix,
+      .force_writable = true,
+      .timeout_ms = kMapTimeout,
+  };
+  TEST_AND_RETURN_FALSE(CreateLogicalPartition(params, path));
+  *should_unmap = true;
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::EraseSystemOtherAvbFooter(
+    uint32_t source_slot, uint32_t target_slot) {
+  LOG(INFO) << "Erasing AVB footer of system_other partition before update.";
+
+  const std::string target_suffix = SlotSuffixForSlotNumber(target_slot);
+  const std::string partition_name_suffix = "system" + target_suffix;
+
+  std::string path;
+  bool should_unmap = false;
+
+  TEST_AND_RETURN_FALSE(GetSystemOtherPath(
+      source_slot, target_slot, partition_name_suffix, &path, &should_unmap));
+
+  if (path.empty()) {
+    return true;
+  }
+
+  bool ret = AvbFooterEraser(path).Erase();
+
+  // Delete |partition_name_suffix| from device mapper and from
+  // |mapped_devices_| again so that it does not interfere with update process.
+  // In recovery, metadata might not be mounted, and
+  // UnmapPartitionOnDeviceMapper might fail. However, DestroyLogicalPartition
+  // should be called. If DestroyLogicalPartition does fail, it is still okay
+  // to skip the error here and let Prepare*() fail later.
+  if (should_unmap) {
+    TEST_AND_RETURN_FALSE(UnmapPartitionOnDeviceMapper(partition_name_suffix));
+  }
+
+  return ret;
+}
+
+bool DynamicPartitionControlAndroid::PrepareDynamicPartitionsForUpdate(
+    uint32_t source_slot,
+    uint32_t target_slot,
+    const DeltaArchiveManifest& manifest,
+    bool delete_source) {
+  const std::string target_suffix = SlotSuffixForSlotNumber(target_slot);
+
+  // Unmap all the target dynamic partitions because they would become
+  // inconsistent with the new metadata.
+  for (const auto& group : manifest.dynamic_partition_metadata().groups()) {
+    for (const auto& partition_name : group.partition_names()) {
+      if (!UnmapPartitionOnDeviceMapper(partition_name + target_suffix)) {
+        return false;
+      }
+    }
+  }
+
+  std::string device_dir_str;
+  if (!GetDeviceDir(&device_dir_str)) {
+    return false;
+  }
+  base::FilePath device_dir(device_dir_str);
+  auto source_device =
+      device_dir.Append(GetSuperPartitionName(source_slot)).value();
+
+  auto builder = LoadMetadataBuilder(source_device, source_slot, target_slot);
+  if (builder == nullptr) {
+    LOG(ERROR) << "No metadata at "
+               << BootControlInterface::SlotName(source_slot);
+    return false;
+  }
+
+  if (delete_source) {
+    TEST_AND_RETURN_FALSE(
+        DeleteSourcePartitions(builder.get(), source_slot, manifest));
+  }
+
+  if (!UpdatePartitionMetadata(builder.get(), target_slot, manifest)) {
+    return false;
+  }
+
+  auto target_device =
+      device_dir.Append(GetSuperPartitionName(target_slot)).value();
+  return StoreMetadata(target_device, builder.get(), target_slot);
+}
+
+bool DynamicPartitionControlAndroid::PrepareSnapshotPartitionsForUpdate(
+    uint32_t source_slot,
+    uint32_t target_slot,
+    const DeltaArchiveManifest& manifest,
+    uint64_t* required_size) {
+  TEST_AND_RETURN_FALSE(ExpectMetadataMounted());
+  if (!snapshot_->BeginUpdate()) {
+    LOG(ERROR) << "Cannot begin new update.";
+    return false;
+  }
+  auto ret = snapshot_->CreateUpdateSnapshots(manifest);
+  if (!ret) {
+    LOG(ERROR) << "Cannot create update snapshots: " << ret.string();
+    if (required_size != nullptr &&
+        ret.error_code() == Return::ErrorCode::NO_SPACE) {
+      *required_size = ret.required_size();
+    }
+    return false;
+  }
+  return true;
+}
+
+std::string DynamicPartitionControlAndroid::GetSuperPartitionName(
+    uint32_t slot) {
+  return fs_mgr_get_super_partition_name(slot);
+}
+
+bool DynamicPartitionControlAndroid::UpdatePartitionMetadata(
+    MetadataBuilder* builder,
+    uint32_t target_slot,
+    const DeltaArchiveManifest& manifest) {
+  // Check preconditions.
+  CHECK(!GetVirtualAbFeatureFlag().IsEnabled() || IsRecovery())
+      << "UpdatePartitionMetadata is called on a Virtual A/B device "
+         "but source partitions is not deleted. This is not allowed.";
+
+  // If applying downgrade from Virtual A/B to non-Virtual A/B, the left-over
+  // COW group needs to be deleted to ensure there are enough space to create
+  // target partitions.
+  builder->RemoveGroupAndPartitions(android::snapshot::kCowGroupName);
+
+  const std::string target_suffix = SlotSuffixForSlotNumber(target_slot);
+  DeleteGroupsWithSuffix(builder, target_suffix);
+
+  uint64_t total_size = 0;
+  for (const auto& group : manifest.dynamic_partition_metadata().groups()) {
+    total_size += group.size();
+  }
+
+  std::string expr;
+  uint64_t allocatable_space = builder->AllocatableSpace();
+  // On device retrofitting dynamic partitions, allocatable_space = super.
+  // On device launching dynamic partitions w/o VAB,
+  //   allocatable_space = super / 2.
+  // On device launching dynamic partitions with VAB, allocatable_space = super.
+  if (!GetDynamicPartitionsFeatureFlag().IsRetrofit() &&
+      !GetVirtualAbFeatureFlag().IsEnabled()) {
+    allocatable_space /= 2;
+    expr = "half of ";
+  }
+  if (total_size > allocatable_space) {
+    LOG(ERROR) << "The maximum size of all groups with suffix " << target_suffix
+               << " (" << total_size << ") has exceeded " << expr
+               << "allocatable space for dynamic partitions "
+               << allocatable_space << ".";
+    return false;
+  }
+
+  // name of partition(e.g. "system") -> size in bytes
+  std::map<std::string, uint64_t> partition_sizes;
+  for (const auto& partition : manifest.partitions()) {
+    partition_sizes.emplace(partition.partition_name(),
+                            partition.new_partition_info().size());
+  }
+
+  for (const auto& group : manifest.dynamic_partition_metadata().groups()) {
+    auto group_name_suffix = group.name() + target_suffix;
+    if (!builder->AddGroup(group_name_suffix, group.size())) {
+      LOG(ERROR) << "Cannot add group " << group_name_suffix << " with size "
+                 << group.size();
+      return false;
+    }
+    LOG(INFO) << "Added group " << group_name_suffix << " with size "
+              << group.size();
+
+    for (const auto& partition_name : group.partition_names()) {
+      auto partition_sizes_it = partition_sizes.find(partition_name);
+      if (partition_sizes_it == partition_sizes.end()) {
+        // TODO(tbao): Support auto-filling partition info for framework-only
+        // OTA.
+        LOG(ERROR) << "dynamic_partition_metadata contains partition "
+                   << partition_name << " but it is not part of the manifest. "
+                   << "This is not supported.";
+        return false;
+      }
+      uint64_t partition_size = partition_sizes_it->second;
+
+      auto partition_name_suffix = partition_name + target_suffix;
+      Partition* p = builder->AddPartition(
+          partition_name_suffix, group_name_suffix, LP_PARTITION_ATTR_READONLY);
+      if (!p) {
+        LOG(ERROR) << "Cannot add partition " << partition_name_suffix
+                   << " to group " << group_name_suffix;
+        return false;
+      }
+      if (!builder->ResizePartition(p, partition_size)) {
+        LOG(ERROR) << "Cannot resize partition " << partition_name_suffix
+                   << " to size " << partition_size << ". Not enough space?";
+        return false;
+      }
+      LOG(INFO) << "Added partition " << partition_name_suffix << " to group "
+                << group_name_suffix << " with size " << partition_size;
+    }
+  }
+
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::FinishUpdate(bool powerwash_required) {
+  if (ExpectMetadataMounted()) {
+    if (snapshot_->GetUpdateState() == UpdateState::Initiated) {
+      LOG(INFO) << "Snapshot writes are done.";
+      return snapshot_->FinishedSnapshotWrites(powerwash_required);
+    }
+  } else {
+    LOG(INFO) << "Skip FinishedSnapshotWrites() because /metadata is not "
+              << "mounted";
+  }
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::GetPartitionDevice(
+    const std::string& partition_name,
+    uint32_t slot,
+    uint32_t current_slot,
+    bool not_in_payload,
+    std::string* device,
+    bool* is_dynamic) {
+  const auto& partition_name_suffix =
+      partition_name + SlotSuffixForSlotNumber(slot);
+  std::string device_dir_str;
+  TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str));
+  base::FilePath device_dir(device_dir_str);
+
+  if (is_dynamic) {
+    *is_dynamic = false;
+  }
+
+  // When looking up target partition devices, treat them as static if the
+  // current payload doesn't encode them as dynamic partitions. This may happen
+  // when applying a retrofit update on top of a dynamic-partitions-enabled
+  // build.
+  if (GetDynamicPartitionsFeatureFlag().IsEnabled() &&
+      (slot == current_slot || is_target_dynamic_)) {
+    switch (GetDynamicPartitionDevice(device_dir,
+                                      partition_name_suffix,
+                                      slot,
+                                      current_slot,
+                                      not_in_payload,
+                                      device)) {
+      case DynamicPartitionDeviceStatus::SUCCESS:
+        if (is_dynamic) {
+          *is_dynamic = true;
+        }
+        return true;
+      case DynamicPartitionDeviceStatus::TRY_STATIC:
+        break;
+      case DynamicPartitionDeviceStatus::ERROR:  // fallthrough
+      default:
+        return false;
+    }
+  }
+  base::FilePath path = device_dir.Append(partition_name_suffix);
+  if (!DeviceExists(path.value())) {
+    LOG(ERROR) << "Device file " << path.value() << " does not exist.";
+    return false;
+  }
+
+  *device = path.value();
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::GetPartitionDevice(
+    const std::string& partition_name,
+    uint32_t slot,
+    uint32_t current_slot,
+    std::string* device) {
+  return GetPartitionDevice(
+      partition_name, slot, current_slot, false, device, nullptr);
+}
+
+bool DynamicPartitionControlAndroid::IsSuperBlockDevice(
+    const base::FilePath& device_dir,
+    uint32_t current_slot,
+    const std::string& partition_name_suffix) {
+  std::string source_device =
+      device_dir.Append(GetSuperPartitionName(current_slot)).value();
+  auto source_metadata = LoadMetadataBuilder(source_device, current_slot);
+  return source_metadata->HasBlockDevice(partition_name_suffix);
+}
+
+DynamicPartitionControlAndroid::DynamicPartitionDeviceStatus
+DynamicPartitionControlAndroid::GetDynamicPartitionDevice(
+    const base::FilePath& device_dir,
+    const std::string& partition_name_suffix,
+    uint32_t slot,
+    uint32_t current_slot,
+    bool not_in_payload,
+    std::string* device) {
+  std::string super_device =
+      device_dir.Append(GetSuperPartitionName(slot)).value();
+
+  auto builder = LoadMetadataBuilder(super_device, slot);
+  if (builder == nullptr) {
+    LOG(ERROR) << "No metadata in slot "
+               << BootControlInterface::SlotName(slot);
+    return DynamicPartitionDeviceStatus::ERROR;
+  }
+  if (builder->FindPartition(partition_name_suffix) == nullptr) {
+    LOG(INFO) << partition_name_suffix
+              << " is not in super partition metadata.";
+
+    if (IsSuperBlockDevice(device_dir, current_slot, partition_name_suffix)) {
+      LOG(ERROR) << "The static partition " << partition_name_suffix
+                 << " is a block device for current metadata."
+                 << "It cannot be used as a logical partition.";
+      return DynamicPartitionDeviceStatus::ERROR;
+    }
+
+    return DynamicPartitionDeviceStatus::TRY_STATIC;
+  }
+
+  if (slot == current_slot) {
+    if (GetState(partition_name_suffix) != DmDeviceState::ACTIVE) {
+      LOG(WARNING) << partition_name_suffix << " is at current slot but it is "
+                   << "not mapped. Now try to map it.";
+    } else {
+      if (GetDmDevicePathByName(partition_name_suffix, device)) {
+        LOG(INFO) << partition_name_suffix
+                  << " is mapped on device mapper: " << *device;
+        return DynamicPartitionDeviceStatus::SUCCESS;
+      }
+      LOG(ERROR) << partition_name_suffix << "is mapped but path is unknown.";
+      return DynamicPartitionDeviceStatus::ERROR;
+    }
+  }
+
+  bool force_writable = (slot != current_slot) && !not_in_payload;
+  if (MapPartitionOnDeviceMapper(
+          super_device, partition_name_suffix, slot, force_writable, device)) {
+    return DynamicPartitionDeviceStatus::SUCCESS;
+  }
+  return DynamicPartitionDeviceStatus::ERROR;
+}
+
+void DynamicPartitionControlAndroid::set_fake_mapped_devices(
+    const std::set<std::string>& fake) {
+  mapped_devices_ = fake;
+}
+
+bool DynamicPartitionControlAndroid::IsRecovery() {
+  return kIsRecovery;
+}
+
+static bool IsIncrementalUpdate(const DeltaArchiveManifest& manifest) {
+  const auto& partitions = manifest.partitions();
+  return std::any_of(partitions.begin(), partitions.end(), [](const auto& p) {
+    return p.has_old_partition_info();
+  });
+}
+
+bool DynamicPartitionControlAndroid::DeleteSourcePartitions(
+    MetadataBuilder* builder,
+    uint32_t source_slot,
+    const DeltaArchiveManifest& manifest) {
+  TEST_AND_RETURN_FALSE(IsRecovery());
+
+  if (IsIncrementalUpdate(manifest)) {
+    LOG(ERROR) << "Cannot sideload incremental OTA because snapshots cannot "
+               << "be created.";
+    if (GetVirtualAbFeatureFlag().IsLaunch()) {
+      LOG(ERROR) << "Sideloading incremental updates on devices launches "
+                 << " Virtual A/B is not supported.";
+    }
+    return false;
+  }
+
+  LOG(INFO) << "Will overwrite existing partitions. Slot "
+            << BootControlInterface::SlotName(source_slot)
+            << "may be unbootable until update finishes!";
+  const std::string source_suffix = SlotSuffixForSlotNumber(source_slot);
+  DeleteGroupsWithSuffix(builder, source_suffix);
+
+  return true;
+}
+
+std::unique_ptr<AbstractAction>
+DynamicPartitionControlAndroid::GetCleanupPreviousUpdateAction(
+    BootControlInterface* boot_control,
+    PrefsInterface* prefs,
+    CleanupPreviousUpdateActionDelegateInterface* delegate) {
+  if (!GetVirtualAbFeatureFlag().IsEnabled()) {
+    return std::make_unique<NoOpAction>();
+  }
+  return std::make_unique<CleanupPreviousUpdateAction>(
+      prefs, boot_control, snapshot_.get(), delegate);
+}
+
+bool DynamicPartitionControlAndroid::ResetUpdate(PrefsInterface* prefs) {
+  if (!GetVirtualAbFeatureFlag().IsEnabled()) {
+    return true;
+  }
+
+  LOG(INFO) << __func__ << " resetting update state and deleting snapshots.";
+  TEST_AND_RETURN_FALSE(prefs != nullptr);
+
+  // If the device has already booted into the target slot,
+  // ResetUpdateProgress may pass but CancelUpdate fails.
+  // This is expected. A scheduled CleanupPreviousUpdateAction should free
+  // space when it is done.
+  TEST_AND_RETURN_FALSE(DeltaPerformer::ResetUpdateProgress(
+      prefs, false /* quick */, false /* skip dynamic partitions metadata */));
+
+  if (ExpectMetadataMounted()) {
+    TEST_AND_RETURN_FALSE(snapshot_->CancelUpdate());
+  } else {
+    LOG(INFO) << "Skip cancelling update in ResetUpdate because /metadata is "
+              << "not mounted";
+  }
+
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::ListDynamicPartitionsForSlot(
+    uint32_t current_slot, std::vector<std::string>* partitions) {
+  if (!GetDynamicPartitionsFeatureFlag().IsEnabled()) {
+    LOG(ERROR) << "Dynamic partition is not enabled";
+    return false;
+  }
+
+  std::string device_dir_str;
+  TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str));
+  base::FilePath device_dir(device_dir_str);
+  auto super_device =
+      device_dir.Append(GetSuperPartitionName(current_slot)).value();
+  auto builder = LoadMetadataBuilder(super_device, current_slot);
+  TEST_AND_RETURN_FALSE(builder != nullptr);
+
+  std::vector<std::string> result;
+  auto suffix = SlotSuffixForSlotNumber(current_slot);
+  for (const auto& group : builder->ListGroups()) {
+    for (const auto& partition : builder->ListPartitionsInGroup(group)) {
+      std::string_view partition_name = partition->name();
+      if (!android::base::ConsumeSuffix(&partition_name, suffix)) {
+        continue;
+      }
+      result.emplace_back(partition_name);
+    }
+  }
+  *partitions = std::move(result);
+  return true;
+}
+
+bool DynamicPartitionControlAndroid::VerifyExtentsForUntouchedPartitions(
+    uint32_t source_slot,
+    uint32_t target_slot,
+    const std::vector<std::string>& partitions) {
+  std::string device_dir_str;
+  TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str));
+  base::FilePath device_dir(device_dir_str);
+
+  auto source_super_device =
+      device_dir.Append(GetSuperPartitionName(source_slot)).value();
+  auto source_builder = LoadMetadataBuilder(source_super_device, source_slot);
+  TEST_AND_RETURN_FALSE(source_builder != nullptr);
+
+  auto target_super_device =
+      device_dir.Append(GetSuperPartitionName(target_slot)).value();
+  auto target_builder = LoadMetadataBuilder(target_super_device, target_slot);
+  TEST_AND_RETURN_FALSE(target_builder != nullptr);
+
+  return MetadataBuilder::VerifyExtentsAgainstSourceMetadata(
+      *source_builder, source_slot, *target_builder, target_slot, partitions);
+}
+
+bool DynamicPartitionControlAndroid::ExpectMetadataMounted() {
+  // No need to mount metadata for non-Virtual A/B devices.
+  if (!GetVirtualAbFeatureFlag().IsEnabled()) {
+    return false;
+  }
+  // Intentionally not checking |metadata_device_| in Android mode.
+  // /metadata should always be mounted in Android mode. If it isn't, let caller
+  // fails when calling into SnapshotManager.
+  if (!IsRecovery()) {
+    return true;
+  }
+  // In recovery mode, explicitly check |metadata_device_|.
+  return metadata_device_ != nullptr;
+}
+
+bool DynamicPartitionControlAndroid::EnsureMetadataMounted() {
+  // No need to mount metadata for non-Virtual A/B devices.
+  if (!GetVirtualAbFeatureFlag().IsEnabled()) {
+    return true;
+  }
+
+  if (metadata_device_ == nullptr) {
+    metadata_device_ = snapshot_->EnsureMetadataMounted();
+  }
+  return metadata_device_ != nullptr;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/dynamic_partition_control_android.h b/aosp/dynamic_partition_control_android.h
new file mode 100644
index 0000000..79f87d9
--- /dev/null
+++ b/aosp/dynamic_partition_control_android.h
@@ -0,0 +1,294 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
+
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/files/file_util.h>
+#include <libsnapshot/auto_device.h>
+#include <libsnapshot/snapshot.h>
+
+#include "update_engine/common/dynamic_partition_control_interface.h"
+
+namespace chromeos_update_engine {
+
+class DynamicPartitionControlAndroid : public DynamicPartitionControlInterface {
+ public:
+  DynamicPartitionControlAndroid();
+  ~DynamicPartitionControlAndroid();
+  FeatureFlag GetDynamicPartitionsFeatureFlag() override;
+  FeatureFlag GetVirtualAbFeatureFlag() override;
+  bool OptimizeOperation(const std::string& partition_name,
+                         const InstallOperation& operation,
+                         InstallOperation* optimized) override;
+  void Cleanup() override;
+
+  bool PreparePartitionsForUpdate(uint32_t source_slot,
+                                  uint32_t target_slot,
+                                  const DeltaArchiveManifest& manifest,
+                                  bool update,
+                                  uint64_t* required_size) override;
+  bool FinishUpdate(bool powerwash_required) override;
+  std::unique_ptr<AbstractAction> GetCleanupPreviousUpdateAction(
+      BootControlInterface* boot_control,
+      PrefsInterface* prefs,
+      CleanupPreviousUpdateActionDelegateInterface* delegate) override;
+
+  bool ResetUpdate(PrefsInterface* prefs) override;
+
+  bool ListDynamicPartitionsForSlot(
+      uint32_t current_slot, std::vector<std::string>* partitions) override;
+
+  bool VerifyExtentsForUntouchedPartitions(
+      uint32_t source_slot,
+      uint32_t target_slot,
+      const std::vector<std::string>& partitions) override;
+
+  bool GetDeviceDir(std::string* path) override;
+
+  // Return the device for partition |partition_name| at slot |slot|.
+  // |current_slot| should be set to the current active slot.
+  // Note: this function is only used by BootControl*::GetPartitionDevice.
+  // Other callers should prefer BootControl*::GetPartitionDevice over
+  // BootControl*::GetDynamicPartitionControl()->GetPartitionDevice().
+  bool GetPartitionDevice(const std::string& partition_name,
+                          uint32_t slot,
+                          uint32_t current_slot,
+                          bool not_in_payload,
+                          std::string* device,
+                          bool* is_dynamic);
+
+  bool GetPartitionDevice(const std::string& partition_name,
+                          uint32_t slot,
+                          uint32_t current_slot,
+                          std::string* device);
+
+ protected:
+  // These functions are exposed for testing.
+
+  // Unmap logical partition on device mapper. This is the reverse operation
+  // of MapPartitionOnDeviceMapper.
+  // Returns true if unmapped successfully.
+  virtual bool UnmapPartitionOnDeviceMapper(
+      const std::string& target_partition_name);
+
+  // Retrieves metadata from |super_device| at slot |slot|.
+  virtual std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder(
+      const std::string& super_device, uint32_t slot);
+
+  // Retrieves metadata from |super_device| at slot |source_slot|. And modifies
+  // the metadata so that during updates, the metadata can be written to
+  // |target_slot|. In particular, on retrofit devices, the returned metadata
+  // automatically includes block devices at |target_slot|.
+  virtual std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder(
+      const std::string& super_device,
+      uint32_t source_slot,
+      uint32_t target_slot);
+
+  // Write metadata |builder| to |super_device| at slot |target_slot|.
+  virtual bool StoreMetadata(const std::string& super_device,
+                             android::fs_mgr::MetadataBuilder* builder,
+                             uint32_t target_slot);
+
+  // Map logical partition on device-mapper.
+  // |super_device| is the device path of the physical partition ("super").
+  // |target_partition_name| is the identifier used in metadata; for example,
+  // "vendor_a"
+  // |slot| is the selected slot to mount; for example, 0 for "_a".
+  // Returns true if mapped successfully; if so, |path| is set to the device
+  // path of the mapped logical partition.
+  virtual bool MapPartitionOnDeviceMapper(
+      const std::string& super_device,
+      const std::string& target_partition_name,
+      uint32_t slot,
+      bool force_writable,
+      std::string* path);
+
+  // Return true if a static partition exists at device path |path|.
+  virtual bool DeviceExists(const std::string& path);
+
+  // Returns the current state of the underlying device mapper device
+  // with given name.
+  // One of INVALID, SUSPENDED or ACTIVE.
+  virtual android::dm::DmDeviceState GetState(const std::string& name);
+
+  // Returns the path to the device mapper device node in '/dev' corresponding
+  // to 'name'. If the device does not exist, false is returned, and the path
+  // parameter is not set.
+  virtual bool GetDmDevicePathByName(const std::string& name,
+                                     std::string* path);
+
+  // Return the name of the super partition (which stores super partition
+  // metadata) for a given slot.
+  virtual std::string GetSuperPartitionName(uint32_t slot);
+
+  virtual void set_fake_mapped_devices(const std::set<std::string>& fake);
+
+  // Allow mock objects to override this to test recovery mode.
+  virtual bool IsRecovery();
+
+  // Determine path for system_other partition.
+  // |source_slot| should be current slot.
+  // |target_slot| should be "other" slot.
+  // |partition_name_suffix| should be "system" + suffix(|target_slot|).
+  // Return true and set |path| if successful.
+  // Set |path| to empty if no need to erase system_other.
+  // Set |should_unmap| to true if path needs to be unmapped later.
+  //
+  // Note: system_other cannot use GetPartitionDevice or
+  // GetDynamicPartitionDevice because:
+  // - super partition metadata may be loaded from the source slot
+  // - UPDATED flag needs to be check to skip erasing if partition is not
+  //   created by flashing tools
+  // - Snapshots from previous update attempts should not be used.
+  virtual bool GetSystemOtherPath(uint32_t source_slot,
+                                  uint32_t target_slot,
+                                  const std::string& partition_name_suffix,
+                                  std::string* path,
+                                  bool* should_unmap);
+
+  // Returns true if any entry in the fstab file in |path| has AVB enabled,
+  // false if not enabled, and nullopt for any error.
+  virtual std::optional<bool> IsAvbEnabledInFstab(const std::string& path);
+
+  // Returns true if system_other has AVB enabled, false if not enabled, and
+  // nullopt for any error.
+  virtual std::optional<bool> IsAvbEnabledOnSystemOther();
+
+  // Erase system_other partition that may contain system_other.img.
+  // After the update, the content of system_other may be corrupted but with
+  // valid AVB footer. If the update is rolled back and factory data reset is
+  // triggered, system_b fails to be mapped with verity errors (see
+  // b/152444348). Erase the system_other so that mapping system_other is
+  // skipped.
+  virtual bool EraseSystemOtherAvbFooter(uint32_t source_slot,
+                                         uint32_t target_slot);
+
+  // Helper for PreparePartitionsForUpdate. Used for devices with dynamic
+  // partitions updating without snapshots.
+  // If |delete_source| is set, source partitions are deleted before resizing
+  // target partitions (using DeleteSourcePartitions).
+  virtual bool PrepareDynamicPartitionsForUpdate(
+      uint32_t source_slot,
+      uint32_t target_slot,
+      const DeltaArchiveManifest& manifest,
+      bool delete_source);
+
+ private:
+  friend class DynamicPartitionControlAndroidTest;
+  friend class SnapshotPartitionTestP;
+
+  void UnmapAllPartitions();
+  bool MapPartitionInternal(const std::string& super_device,
+                            const std::string& target_partition_name,
+                            uint32_t slot,
+                            bool force_writable,
+                            std::string* path);
+
+  // Update |builder| according to |partition_metadata|.
+  // - In Android mode, this is only called when the device
+  //   does not have Virtual A/B.
+  // - When sideloading, this maybe called as a fallback path if CoW cannot
+  //   be created.
+  bool UpdatePartitionMetadata(android::fs_mgr::MetadataBuilder* builder,
+                               uint32_t target_slot,
+                               const DeltaArchiveManifest& manifest);
+
+  // Helper for PreparePartitionsForUpdate. Used for snapshotted partitions for
+  // Virtual A/B update.
+  bool PrepareSnapshotPartitionsForUpdate(uint32_t source_slot,
+                                          uint32_t target_slot,
+                                          const DeltaArchiveManifest& manifest,
+                                          uint64_t* required_size);
+
+  enum class DynamicPartitionDeviceStatus {
+    SUCCESS,
+    ERROR,
+    TRY_STATIC,
+  };
+
+  // Return SUCCESS and path in |device| if partition is dynamic.
+  // Return ERROR if any error.
+  // Return TRY_STATIC if caller should resolve the partition as a static
+  // partition instead.
+  DynamicPartitionDeviceStatus GetDynamicPartitionDevice(
+      const base::FilePath& device_dir,
+      const std::string& partition_name_suffix,
+      uint32_t slot,
+      uint32_t current_slot,
+      bool not_in_payload,
+      std::string* device);
+
+  // Return true if |partition_name_suffix| is a block device of
+  // super partition metadata slot |slot|.
+  bool IsSuperBlockDevice(const base::FilePath& device_dir,
+                          uint32_t current_slot,
+                          const std::string& partition_name_suffix);
+
+  // If sideloading a full OTA, delete source partitions from |builder|.
+  bool DeleteSourcePartitions(android::fs_mgr::MetadataBuilder* builder,
+                              uint32_t source_slot,
+                              const DeltaArchiveManifest& manifest);
+
+  // Returns true if metadata is expected to be mounted, false otherwise.
+  // Note that it returns false on non-Virtual A/B devices.
+  //
+  // Almost all functions of SnapshotManager depends on metadata being mounted.
+  // - In Android mode for Virtual A/B devices, assume it is mounted. If not,
+  //   let caller fails when calling into SnapshotManager.
+  // - In recovery for Virtual A/B devices, it is possible that metadata is not
+  //   formatted, hence it cannot be mounted. Caller should not call into
+  //   SnapshotManager.
+  // - On non-Virtual A/B devices, updates do not depend on metadata partition.
+  //   Caller should not call into SnapshotManager.
+  //
+  // This function does NOT mount metadata partition. Use EnsureMetadataMounted
+  // to mount metadata partition.
+  bool ExpectMetadataMounted();
+
+  // Ensure /metadata is mounted. Returns true if successful, false otherwise.
+  //
+  // Note that this function returns true on non-Virtual A/B devices without
+  // doing anything.
+  bool EnsureMetadataMounted();
+
+  // Set boolean flags related to target build. This includes flags like
+  // target_supports_snapshot_ and is_target_dynamic_.
+  bool SetTargetBuildVars(const DeltaArchiveManifest& manifest);
+
+  std::set<std::string> mapped_devices_;
+  const FeatureFlag dynamic_partitions_;
+  const FeatureFlag virtual_ab_;
+  std::unique_ptr<android::snapshot::ISnapshotManager> snapshot_;
+  std::unique_ptr<android::snapshot::AutoDevice> metadata_device_;
+  bool target_supports_snapshot_ = false;
+  // Whether the target partitions should be loaded as dynamic partitions. Set
+  // by PreparePartitionsForUpdate() per each update.
+  bool is_target_dynamic_ = false;
+  uint32_t source_slot_ = UINT32_MAX;
+  uint32_t target_slot_ = UINT32_MAX;
+
+  DISALLOW_COPY_AND_ASSIGN(DynamicPartitionControlAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
diff --git a/aosp/dynamic_partition_control_android_unittest.cc b/aosp/dynamic_partition_control_android_unittest.cc
new file mode 100644
index 0000000..5d6463b
--- /dev/null
+++ b/aosp/dynamic_partition_control_android_unittest.cc
@@ -0,0 +1,1028 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/dynamic_partition_control_android.h"
+
+#include <set>
+#include <vector>
+
+#include <base/logging.h>
+#include <base/strings/string_util.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <libavb/libavb.h>
+#include <libsnapshot/mock_snapshot.h>
+
+#include "update_engine/aosp/dynamic_partition_test_utils.h"
+#include "update_engine/aosp/mock_dynamic_partition_control.h"
+#include "update_engine/common/mock_prefs.h"
+#include "update_engine/common/test_utils.h"
+
+using android::dm::DmDeviceState;
+using android::snapshot::MockSnapshotManager;
+using chromeos_update_engine::test_utils::ScopedLoopbackDeviceBinder;
+using std::string;
+using testing::_;
+using testing::AnyNumber;
+using testing::AnyOf;
+using testing::Invoke;
+using testing::NiceMock;
+using testing::Not;
+using testing::Optional;
+using testing::Return;
+
+namespace chromeos_update_engine {
+
+class DynamicPartitionControlAndroidTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    module_ = std::make_unique<NiceMock<MockDynamicPartitionControlAndroid>>();
+
+    ON_CALL(dynamicControl(), GetDynamicPartitionsFeatureFlag())
+        .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+    ON_CALL(dynamicControl(), GetVirtualAbFeatureFlag())
+        .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::NONE)));
+
+    ON_CALL(dynamicControl(), GetDeviceDir(_))
+        .WillByDefault(Invoke([](auto path) {
+          *path = kFakeDevicePath;
+          return true;
+        }));
+
+    ON_CALL(dynamicControl(), GetSuperPartitionName(_))
+        .WillByDefault(Return(kFakeSuper));
+
+    ON_CALL(dynamicControl(), GetDmDevicePathByName(_, _))
+        .WillByDefault(Invoke([](auto partition_name_suffix, auto device) {
+          *device = GetDmDevice(partition_name_suffix);
+          return true;
+        }));
+
+    ON_CALL(dynamicControl(), EraseSystemOtherAvbFooter(_, _))
+        .WillByDefault(Return(true));
+
+    ON_CALL(dynamicControl(), IsRecovery()).WillByDefault(Return(false));
+
+    ON_CALL(dynamicControl(), PrepareDynamicPartitionsForUpdate(_, _, _, _))
+        .WillByDefault(Invoke([&](uint32_t source_slot,
+                                  uint32_t target_slot,
+                                  const DeltaArchiveManifest& manifest,
+                                  bool delete_source) {
+          return dynamicControl().RealPrepareDynamicPartitionsForUpdate(
+              source_slot, target_slot, manifest, delete_source);
+        }));
+  }
+
+  // Return the mocked DynamicPartitionControlInterface.
+  NiceMock<MockDynamicPartitionControlAndroid>& dynamicControl() {
+    return static_cast<NiceMock<MockDynamicPartitionControlAndroid>&>(*module_);
+  }
+
+  std::string GetSuperDevice(uint32_t slot) {
+    return GetDevice(dynamicControl().GetSuperPartitionName(slot));
+  }
+
+  uint32_t source() { return slots_.source; }
+  uint32_t target() { return slots_.target; }
+
+  // Return partition names with suffix of source().
+  std::string S(const std::string& name) {
+    return name + kSlotSuffixes[source()];
+  }
+
+  // Return partition names with suffix of target().
+  std::string T(const std::string& name) {
+    return name + kSlotSuffixes[target()];
+  }
+
+  // Set the fake metadata to return when LoadMetadataBuilder is called on
+  // |slot|.
+  void SetMetadata(uint32_t slot,
+                   const PartitionSuffixSizes& sizes,
+                   uint32_t partition_attr = 0,
+                   uint64_t super_size = kDefaultSuperSize) {
+    EXPECT_CALL(dynamicControl(),
+                LoadMetadataBuilder(GetSuperDevice(slot), slot))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([=](auto, auto) {
+          return NewFakeMetadata(PartitionSuffixSizesToManifest(sizes),
+                                 partition_attr,
+                                 super_size);
+        }));
+
+    EXPECT_CALL(dynamicControl(),
+                LoadMetadataBuilder(GetSuperDevice(slot), slot, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([=](auto, auto, auto) {
+          return NewFakeMetadata(PartitionSuffixSizesToManifest(sizes),
+                                 partition_attr,
+                                 super_size);
+        }));
+  }
+
+  void ExpectStoreMetadata(const PartitionSuffixSizes& partition_sizes) {
+    EXPECT_CALL(dynamicControl(),
+                StoreMetadata(GetSuperDevice(target()),
+                              MetadataMatches(partition_sizes),
+                              target()))
+        .WillOnce(Return(true));
+  }
+
+  // Expect that UnmapPartitionOnDeviceMapper is called on target() metadata
+  // slot with each partition in |partitions|.
+  void ExpectUnmap(const std::set<std::string>& partitions) {
+    // Error when UnmapPartitionOnDeviceMapper is called on unknown arguments.
+    ON_CALL(dynamicControl(), UnmapPartitionOnDeviceMapper(_))
+        .WillByDefault(Return(false));
+
+    for (const auto& partition : partitions) {
+      EXPECT_CALL(dynamicControl(), UnmapPartitionOnDeviceMapper(partition))
+          .WillOnce(Return(true));
+    }
+  }
+  bool PreparePartitionsForUpdate(const PartitionSizes& partition_sizes) {
+    return dynamicControl().PreparePartitionsForUpdate(
+        source(),
+        target(),
+        PartitionSizesToManifest(partition_sizes),
+        true,
+        nullptr);
+  }
+  void SetSlots(const TestParam& slots) { slots_ = slots; }
+
+  void SetSnapshotEnabled(bool enabled) {
+    dynamicControl().target_supports_snapshot_ = enabled;
+  }
+
+  struct Listener : public ::testing::MatchResultListener {
+    explicit Listener(std::ostream* os) : MatchResultListener(os) {}
+  };
+
+  testing::AssertionResult UpdatePartitionMetadata(
+      const PartitionSuffixSizes& source_metadata,
+      const PartitionSizes& update_metadata,
+      const PartitionSuffixSizes& expected) {
+    return UpdatePartitionMetadata(
+        PartitionSuffixSizesToManifest(source_metadata),
+        PartitionSizesToManifest(update_metadata),
+        PartitionSuffixSizesToManifest(expected));
+  }
+  testing::AssertionResult UpdatePartitionMetadata(
+      const DeltaArchiveManifest& source_manifest,
+      const DeltaArchiveManifest& update_manifest,
+      const DeltaArchiveManifest& expected) {
+    return UpdatePartitionMetadata(
+        source_manifest, update_manifest, MetadataMatches(expected));
+  }
+  testing::AssertionResult UpdatePartitionMetadata(
+      const DeltaArchiveManifest& source_manifest,
+      const DeltaArchiveManifest& update_manifest,
+      const Matcher<MetadataBuilder*>& matcher) {
+    auto super_metadata = NewFakeMetadata(source_manifest);
+    if (!module_->UpdatePartitionMetadata(
+            super_metadata.get(), target(), update_manifest)) {
+      return testing::AssertionFailure()
+             << "UpdatePartitionMetadataInternal failed";
+    }
+    std::stringstream ss;
+    Listener listener(&ss);
+    if (matcher.MatchAndExplain(super_metadata.get(), &listener)) {
+      return testing::AssertionSuccess() << ss.str();
+    } else {
+      return testing::AssertionFailure() << ss.str();
+    }
+  }
+
+  std::unique_ptr<DynamicPartitionControlAndroid> module_;
+  TestParam slots_;
+};
+
+class DynamicPartitionControlAndroidTestP
+    : public DynamicPartitionControlAndroidTest,
+      public ::testing::WithParamInterface<TestParam> {
+ public:
+  void SetUp() override {
+    DynamicPartitionControlAndroidTest::SetUp();
+    SetSlots(GetParam());
+  }
+};
+
+// Test resize case. Grow if target metadata contains a partition with a size
+// less than expected.
+TEST_P(DynamicPartitionControlAndroidTestP,
+       NeedGrowIfSizeNotMatchWhenResizing) {
+  PartitionSuffixSizes source_metadata{{S("system"), 2_GiB},
+                                       {S("vendor"), 1_GiB},
+                                       {T("system"), 2_GiB},
+                                       {T("vendor"), 1_GiB}};
+  PartitionSuffixSizes expected{{S("system"), 2_GiB},
+                                {S("vendor"), 1_GiB},
+                                {T("system"), 3_GiB},
+                                {T("vendor"), 1_GiB}};
+  PartitionSizes update_metadata{{"system", 3_GiB}, {"vendor", 1_GiB}};
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_metadata, update_metadata, expected));
+}
+
+// Test resize case. Shrink if target metadata contains a partition with a size
+// greater than expected.
+TEST_P(DynamicPartitionControlAndroidTestP,
+       NeedShrinkIfSizeNotMatchWhenResizing) {
+  PartitionSuffixSizes source_metadata{{S("system"), 2_GiB},
+                                       {S("vendor"), 1_GiB},
+                                       {T("system"), 2_GiB},
+                                       {T("vendor"), 1_GiB}};
+  PartitionSuffixSizes expected{{S("system"), 2_GiB},
+                                {S("vendor"), 1_GiB},
+                                {T("system"), 2_GiB},
+                                {T("vendor"), 150_MiB}};
+  PartitionSizes update_metadata{{"system", 2_GiB}, {"vendor", 150_MiB}};
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_metadata, update_metadata, expected));
+}
+
+// Test adding partitions on the first run.
+TEST_P(DynamicPartitionControlAndroidTestP, AddPartitionToEmptyMetadata) {
+  PartitionSuffixSizes source_metadata{};
+  PartitionSuffixSizes expected{{T("system"), 2_GiB}, {T("vendor"), 1_GiB}};
+  PartitionSizes update_metadata{{"system", 2_GiB}, {"vendor", 1_GiB}};
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_metadata, update_metadata, expected));
+}
+
+// Test subsequent add case.
+TEST_P(DynamicPartitionControlAndroidTestP, AddAdditionalPartition) {
+  PartitionSuffixSizes source_metadata{{S("system"), 2_GiB},
+                                       {T("system"), 2_GiB}};
+  PartitionSuffixSizes expected{
+      {S("system"), 2_GiB}, {T("system"), 2_GiB}, {T("vendor"), 1_GiB}};
+  PartitionSizes update_metadata{{"system", 2_GiB}, {"vendor", 1_GiB}};
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_metadata, update_metadata, expected));
+}
+
+// Test delete one partition.
+TEST_P(DynamicPartitionControlAndroidTestP, DeletePartition) {
+  PartitionSuffixSizes source_metadata{{S("system"), 2_GiB},
+                                       {S("vendor"), 1_GiB},
+                                       {T("system"), 2_GiB},
+                                       {T("vendor"), 1_GiB}};
+  // No T("vendor")
+  PartitionSuffixSizes expected{
+      {S("system"), 2_GiB}, {S("vendor"), 1_GiB}, {T("system"), 2_GiB}};
+  PartitionSizes update_metadata{{"system", 2_GiB}};
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_metadata, update_metadata, expected));
+}
+
+// Test delete all partitions.
+TEST_P(DynamicPartitionControlAndroidTestP, DeleteAll) {
+  PartitionSuffixSizes source_metadata{{S("system"), 2_GiB},
+                                       {S("vendor"), 1_GiB},
+                                       {T("system"), 2_GiB},
+                                       {T("vendor"), 1_GiB}};
+  PartitionSuffixSizes expected{{S("system"), 2_GiB}, {S("vendor"), 1_GiB}};
+  PartitionSizes update_metadata{};
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_metadata, update_metadata, expected));
+}
+
+// Test corrupt source metadata case.
+TEST_P(DynamicPartitionControlAndroidTestP, CorruptedSourceMetadata) {
+  EXPECT_CALL(dynamicControl(),
+              LoadMetadataBuilder(GetSuperDevice(source()), source(), _))
+      .WillOnce(Invoke([](auto, auto, auto) { return nullptr; }));
+  ExpectUnmap({T("system")});
+
+  EXPECT_FALSE(PreparePartitionsForUpdate({{"system", 1_GiB}}))
+      << "Should not be able to continue with corrupt source metadata";
+}
+
+// Test that UpdatePartitionMetadata fails if there is not enough space on the
+// device.
+TEST_P(DynamicPartitionControlAndroidTestP, NotEnoughSpace) {
+  PartitionSuffixSizes source_metadata{{S("system"), 3_GiB},
+                                       {S("vendor"), 2_GiB},
+                                       {T("system"), 0},
+                                       {T("vendor"), 0}};
+  PartitionSizes update_metadata{{"system", 3_GiB}, {"vendor", 3_GiB}};
+
+  EXPECT_FALSE(UpdatePartitionMetadata(source_metadata, update_metadata, {}))
+      << "Should not be able to fit 11GiB data into 10GiB space";
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP, NotEnoughSpaceForSlot) {
+  PartitionSuffixSizes source_metadata{{S("system"), 1_GiB},
+                                       {S("vendor"), 1_GiB},
+                                       {T("system"), 0},
+                                       {T("vendor"), 0}};
+  PartitionSizes update_metadata{{"system", 3_GiB}, {"vendor", 3_GiB}};
+  EXPECT_FALSE(UpdatePartitionMetadata(source_metadata, update_metadata, {}))
+      << "Should not be able to grow over size of super / 2";
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP,
+       ApplyRetrofitUpdateOnDynamicPartitionsEnabledBuild) {
+  ON_CALL(dynamicControl(), GetDynamicPartitionsFeatureFlag())
+      .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::RETROFIT)));
+  // Static partition {system,bar}_{a,b} exists.
+  EXPECT_CALL(dynamicControl(),
+              DeviceExists(AnyOf(GetDevice(S("bar")),
+                                 GetDevice(T("bar")),
+                                 GetDevice(S("system")),
+                                 GetDevice(T("system")))))
+      .WillRepeatedly(Return(true));
+
+  SetMetadata(source(),
+              {{S("system"), 2_GiB},
+               {S("vendor"), 1_GiB},
+               {T("system"), 2_GiB},
+               {T("vendor"), 1_GiB}});
+
+  // Not calling through
+  // DynamicPartitionControlAndroidTest::PreparePartitionsForUpdate(), since we
+  // don't want any default group in the PartitionMetadata.
+  EXPECT_TRUE(dynamicControl().PreparePartitionsForUpdate(
+      source(), target(), {}, true, nullptr));
+
+  // Should use dynamic source partitions.
+  EXPECT_CALL(dynamicControl(), GetState(S("system")))
+      .Times(1)
+      .WillOnce(Return(DmDeviceState::ACTIVE));
+  string system_device;
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "system", source(), source(), &system_device));
+  EXPECT_EQ(GetDmDevice(S("system")), system_device);
+
+  // Should use static target partitions without querying dynamic control.
+  EXPECT_CALL(dynamicControl(), GetState(T("system"))).Times(0);
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "system", target(), source(), &system_device));
+  EXPECT_EQ(GetDevice(T("system")), system_device);
+
+  // Static partition "bar".
+  EXPECT_CALL(dynamicControl(), GetState(S("bar"))).Times(0);
+  std::string bar_device;
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "bar", source(), source(), &bar_device));
+  EXPECT_EQ(GetDevice(S("bar")), bar_device);
+
+  EXPECT_CALL(dynamicControl(), GetState(T("bar"))).Times(0);
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "bar", target(), source(), &bar_device));
+  EXPECT_EQ(GetDevice(T("bar")), bar_device);
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP,
+       GetPartitionDeviceWhenResumingUpdate) {
+  // Static partition bar_{a,b} exists.
+  EXPECT_CALL(dynamicControl(),
+              DeviceExists(AnyOf(GetDevice(S("bar")), GetDevice(T("bar")))))
+      .WillRepeatedly(Return(true));
+
+  // Both of the two slots contain valid partition metadata, since this is
+  // resuming an update.
+  SetMetadata(source(),
+              {{S("system"), 2_GiB},
+               {S("vendor"), 1_GiB},
+               {T("system"), 2_GiB},
+               {T("vendor"), 1_GiB}});
+  SetMetadata(target(),
+              {{S("system"), 2_GiB},
+               {S("vendor"), 1_GiB},
+               {T("system"), 2_GiB},
+               {T("vendor"), 1_GiB}});
+
+  EXPECT_TRUE(dynamicControl().PreparePartitionsForUpdate(
+      source(),
+      target(),
+      PartitionSizesToManifest({{"system", 2_GiB}, {"vendor", 1_GiB}}),
+      false,
+      nullptr));
+
+  // Dynamic partition "system".
+  EXPECT_CALL(dynamicControl(), GetState(S("system")))
+      .Times(1)
+      .WillOnce(Return(DmDeviceState::ACTIVE));
+  string system_device;
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "system", source(), source(), &system_device));
+  EXPECT_EQ(GetDmDevice(S("system")), system_device);
+
+  EXPECT_CALL(dynamicControl(), GetState(T("system")))
+      .Times(AnyNumber())
+      .WillOnce(Return(DmDeviceState::ACTIVE));
+  EXPECT_CALL(dynamicControl(),
+              MapPartitionOnDeviceMapper(
+                  GetSuperDevice(target()), T("system"), target(), _, _))
+      .Times(AnyNumber())
+      .WillRepeatedly(
+          Invoke([](const auto&, const auto& name, auto, auto, auto* device) {
+            *device = "/fake/remapped/" + name;
+            return true;
+          }));
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "system", target(), source(), &system_device));
+  EXPECT_EQ("/fake/remapped/" + T("system"), system_device);
+
+  // Static partition "bar".
+  EXPECT_CALL(dynamicControl(), GetState(S("bar"))).Times(0);
+  std::string bar_device;
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "bar", source(), source(), &bar_device));
+  EXPECT_EQ(GetDevice(S("bar")), bar_device);
+
+  EXPECT_CALL(dynamicControl(), GetState(T("bar"))).Times(0);
+  EXPECT_TRUE(dynamicControl().GetPartitionDevice(
+      "bar", target(), source(), &bar_device));
+  EXPECT_EQ(GetDevice(T("bar")), bar_device);
+}
+
+INSTANTIATE_TEST_CASE_P(DynamicPartitionControlAndroidTest,
+                        DynamicPartitionControlAndroidTestP,
+                        testing::Values(TestParam{0, 1}, TestParam{1, 0}));
+
+class DynamicPartitionControlAndroidGroupTestP
+    : public DynamicPartitionControlAndroidTestP {
+ public:
+  DeltaArchiveManifest source_manifest;
+  void SetUp() override {
+    DynamicPartitionControlAndroidTestP::SetUp();
+    AddGroupAndPartition(
+        &source_manifest, S("android"), 3_GiB, S("system"), 2_GiB);
+    AddGroupAndPartition(&source_manifest, S("oem"), 2_GiB, S("vendor"), 1_GiB);
+    AddGroupAndPartition(&source_manifest, T("android"), 3_GiB, T("system"), 0);
+    AddGroupAndPartition(&source_manifest, T("oem"), 2_GiB, T("vendor"), 0);
+  }
+
+  void AddGroupAndPartition(DeltaArchiveManifest* manifest,
+                            const string& group,
+                            uint64_t group_size,
+                            const string& partition,
+                            uint64_t partition_size) {
+    auto* g = AddGroup(manifest, group, group_size);
+    AddPartition(manifest, g, partition, partition_size);
+  }
+};
+
+// Allow to resize within group.
+TEST_P(DynamicPartitionControlAndroidGroupTestP, ResizeWithinGroup) {
+  DeltaArchiveManifest expected;
+  AddGroupAndPartition(&expected, T("android"), 3_GiB, T("system"), 3_GiB);
+  AddGroupAndPartition(&expected, T("oem"), 2_GiB, T("vendor"), 2_GiB);
+
+  DeltaArchiveManifest update_manifest;
+  AddGroupAndPartition(&update_manifest, "android", 3_GiB, "system", 3_GiB);
+  AddGroupAndPartition(&update_manifest, "oem", 2_GiB, "vendor", 2_GiB);
+
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_manifest, update_manifest, expected));
+}
+
+TEST_P(DynamicPartitionControlAndroidGroupTestP, NotEnoughSpaceForGroup) {
+  DeltaArchiveManifest update_manifest;
+  AddGroupAndPartition(&update_manifest, "android", 3_GiB, "system", 1_GiB),
+      AddGroupAndPartition(&update_manifest, "oem", 2_GiB, "vendor", 3_GiB);
+  EXPECT_FALSE(UpdatePartitionMetadata(source_manifest, update_manifest, {}))
+      << "Should not be able to grow over maximum size of group";
+}
+
+TEST_P(DynamicPartitionControlAndroidGroupTestP, GroupTooBig) {
+  DeltaArchiveManifest update_manifest;
+  AddGroup(&update_manifest, "android", 3_GiB);
+  AddGroup(&update_manifest, "oem", 3_GiB);
+  EXPECT_FALSE(UpdatePartitionMetadata(source_manifest, update_manifest, {}))
+      << "Should not be able to grow over size of super / 2";
+}
+
+TEST_P(DynamicPartitionControlAndroidGroupTestP, AddPartitionToGroup) {
+  DeltaArchiveManifest expected;
+  auto* g = AddGroup(&expected, T("android"), 3_GiB);
+  AddPartition(&expected, g, T("system"), 2_GiB);
+  AddPartition(&expected, g, T("system_ext"), 1_GiB);
+
+  DeltaArchiveManifest update_manifest;
+  g = AddGroup(&update_manifest, "android", 3_GiB);
+  AddPartition(&update_manifest, g, "system", 2_GiB);
+  AddPartition(&update_manifest, g, "system_ext", 1_GiB);
+  AddGroupAndPartition(&update_manifest, "oem", 2_GiB, "vendor", 2_GiB);
+
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_manifest, update_manifest, expected));
+}
+
+TEST_P(DynamicPartitionControlAndroidGroupTestP, RemovePartitionFromGroup) {
+  DeltaArchiveManifest expected;
+  AddGroup(&expected, T("android"), 3_GiB);
+
+  DeltaArchiveManifest update_manifest;
+  AddGroup(&update_manifest, "android", 3_GiB);
+  AddGroupAndPartition(&update_manifest, "oem", 2_GiB, "vendor", 2_GiB);
+
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_manifest, update_manifest, expected));
+}
+
+TEST_P(DynamicPartitionControlAndroidGroupTestP, AddGroup) {
+  DeltaArchiveManifest expected;
+  AddGroupAndPartition(
+      &expected, T("new_group"), 2_GiB, T("new_partition"), 2_GiB);
+
+  DeltaArchiveManifest update_manifest;
+  AddGroupAndPartition(&update_manifest, "android", 2_GiB, "system", 2_GiB);
+  AddGroupAndPartition(&update_manifest, "oem", 1_GiB, "vendor", 1_GiB);
+  AddGroupAndPartition(
+      &update_manifest, "new_group", 2_GiB, "new_partition", 2_GiB);
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_manifest, update_manifest, expected));
+}
+
+TEST_P(DynamicPartitionControlAndroidGroupTestP, RemoveGroup) {
+  DeltaArchiveManifest update_manifest;
+  AddGroupAndPartition(&update_manifest, "android", 2_GiB, "system", 2_GiB);
+
+  EXPECT_TRUE(UpdatePartitionMetadata(
+      source_manifest, update_manifest, Not(HasGroup(T("oem")))));
+}
+
+TEST_P(DynamicPartitionControlAndroidGroupTestP, ResizeGroup) {
+  DeltaArchiveManifest expected;
+  AddGroupAndPartition(&expected, T("android"), 2_GiB, T("system"), 2_GiB);
+  AddGroupAndPartition(&expected, T("oem"), 3_GiB, T("vendor"), 3_GiB);
+  DeltaArchiveManifest update_manifest;
+  AddGroupAndPartition(&update_manifest, "android", 2_GiB, "system", 2_GiB),
+      AddGroupAndPartition(&update_manifest, "oem", 3_GiB, "vendor", 3_GiB);
+  EXPECT_TRUE(
+      UpdatePartitionMetadata(source_manifest, update_manifest, expected));
+}
+
+INSTANTIATE_TEST_CASE_P(DynamicPartitionControlAndroidTest,
+                        DynamicPartitionControlAndroidGroupTestP,
+                        testing::Values(TestParam{0, 1}, TestParam{1, 0}));
+
+const PartitionSuffixSizes update_sizes_0() {
+  // Initial state is 0 for "other" slot.
+  return {
+      {"grown_a", 2_GiB},
+      {"shrunk_a", 1_GiB},
+      {"same_a", 100_MiB},
+      {"deleted_a", 150_MiB},
+      // no added_a
+      {"grown_b", 200_MiB},
+      // simulate system_other
+      {"shrunk_b", 0},
+      {"same_b", 0},
+      {"deleted_b", 0},
+      // no added_b
+  };
+}
+
+const PartitionSuffixSizes update_sizes_1() {
+  return {
+      {"grown_a", 2_GiB},
+      {"shrunk_a", 1_GiB},
+      {"same_a", 100_MiB},
+      {"deleted_a", 150_MiB},
+      // no added_a
+      {"grown_b", 3_GiB},
+      {"shrunk_b", 150_MiB},
+      {"same_b", 100_MiB},
+      {"added_b", 150_MiB},
+      // no deleted_b
+  };
+}
+
+const PartitionSuffixSizes update_sizes_2() {
+  return {
+      {"grown_a", 4_GiB},
+      {"shrunk_a", 100_MiB},
+      {"same_a", 100_MiB},
+      {"deleted_a", 64_MiB},
+      // no added_a
+      {"grown_b", 3_GiB},
+      {"shrunk_b", 150_MiB},
+      {"same_b", 100_MiB},
+      {"added_b", 150_MiB},
+      // no deleted_b
+  };
+}
+
+// Test case for first update after the device is manufactured, in which
+// case the "other" slot is likely of size "0" (except system, which is
+// non-zero because of system_other partition)
+TEST_F(DynamicPartitionControlAndroidTest, SimulatedFirstUpdate) {
+  SetSlots({0, 1});
+
+  SetMetadata(source(), update_sizes_0());
+  SetMetadata(target(), update_sizes_0());
+  ExpectStoreMetadata(update_sizes_1());
+  ExpectUnmap({"grown_b", "shrunk_b", "same_b", "added_b"});
+
+  EXPECT_TRUE(PreparePartitionsForUpdate({{"grown", 3_GiB},
+                                          {"shrunk", 150_MiB},
+                                          {"same", 100_MiB},
+                                          {"added", 150_MiB}}));
+}
+
+// After first update, test for the second update. In the second update, the
+// "added" partition is deleted and "deleted" partition is re-added.
+TEST_F(DynamicPartitionControlAndroidTest, SimulatedSecondUpdate) {
+  SetSlots({1, 0});
+
+  SetMetadata(source(), update_sizes_1());
+  SetMetadata(target(), update_sizes_0());
+
+  ExpectStoreMetadata(update_sizes_2());
+  ExpectUnmap({"grown_a", "shrunk_a", "same_a", "deleted_a"});
+
+  EXPECT_TRUE(PreparePartitionsForUpdate({{"grown", 4_GiB},
+                                          {"shrunk", 100_MiB},
+                                          {"same", 100_MiB},
+                                          {"deleted", 64_MiB}}));
+}
+
+TEST_F(DynamicPartitionControlAndroidTest, ApplyingToCurrentSlot) {
+  SetSlots({1, 1});
+  EXPECT_FALSE(PreparePartitionsForUpdate({}))
+      << "Should not be able to apply to current slot.";
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP, OptimizeOperationTest) {
+  ASSERT_TRUE(dynamicControl().PreparePartitionsForUpdate(
+      source(),
+      target(),
+      PartitionSizesToManifest({{"foo", 4_MiB}}),
+      false,
+      nullptr));
+  dynamicControl().set_fake_mapped_devices({T("foo")});
+
+  InstallOperation iop;
+  InstallOperation optimized;
+  Extent *se, *de;
+
+  // Not a SOURCE_COPY operation, cannot skip.
+  iop.set_type(InstallOperation::REPLACE);
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+
+  iop.set_type(InstallOperation::SOURCE_COPY);
+
+  // By default GetVirtualAbFeatureFlag is disabled. Cannot skip operation.
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+
+  // Enable GetVirtualAbFeatureFlag in the mock interface.
+  ON_CALL(dynamicControl(), GetVirtualAbFeatureFlag())
+      .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+
+  // By default target_supports_snapshot_ is set to false. Cannot skip
+  // operation.
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+
+  SetSnapshotEnabled(true);
+
+  // Empty source and destination. Skip.
+  EXPECT_TRUE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+  EXPECT_TRUE(optimized.src_extents().empty());
+  EXPECT_TRUE(optimized.dst_extents().empty());
+
+  se = iop.add_src_extents();
+  se->set_start_block(0);
+  se->set_num_blocks(1);
+
+  // There is something in sources, but destinations are empty. Cannot skip.
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+
+  InstallOperation iop2;
+
+  de = iop2.add_dst_extents();
+  de->set_start_block(0);
+  de->set_num_blocks(1);
+
+  // There is something in destinations, but sources are empty. Cannot skip.
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("foo", iop2, &optimized));
+
+  de = iop.add_dst_extents();
+  de->set_start_block(0);
+  de->set_num_blocks(1);
+
+  // Sources and destinations are identical. Skip.
+  EXPECT_TRUE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+  EXPECT_TRUE(optimized.src_extents().empty());
+  EXPECT_TRUE(optimized.dst_extents().empty());
+
+  se = iop.add_src_extents();
+  se->set_start_block(1);
+  se->set_num_blocks(5);
+
+  // There is something in source, but not in destination. Cannot skip.
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+
+  de = iop.add_dst_extents();
+  de->set_start_block(1);
+  de->set_num_blocks(5);
+
+  // There is source and destination are equal. Skip.
+  EXPECT_TRUE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+  EXPECT_TRUE(optimized.src_extents().empty());
+  EXPECT_TRUE(optimized.dst_extents().empty());
+
+  de = iop.add_dst_extents();
+  de->set_start_block(6);
+  de->set_num_blocks(5);
+
+  // There is something extra in dest. Cannot skip.
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+
+  se = iop.add_src_extents();
+  se->set_start_block(6);
+  se->set_num_blocks(5);
+
+  // Source and dest are identical again. Skip.
+  EXPECT_TRUE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+  EXPECT_TRUE(optimized.src_extents().empty());
+  EXPECT_TRUE(optimized.dst_extents().empty());
+
+  iop.Clear();
+  iop.set_type(InstallOperation::SOURCE_COPY);
+  se = iop.add_src_extents();
+  se->set_start_block(1);
+  se->set_num_blocks(1);
+  se = iop.add_src_extents();
+  se->set_start_block(3);
+  se->set_num_blocks(2);
+  se = iop.add_src_extents();
+  se->set_start_block(7);
+  se->set_num_blocks(2);
+  de = iop.add_dst_extents();
+  de->set_start_block(2);
+  de->set_num_blocks(5);
+
+  // [1, 3, 4, 7, 8] -> [2, 3, 4, 5, 6] should return [1, 7, 8] -> [2, 5, 6]
+  EXPECT_TRUE(dynamicControl().OptimizeOperation("foo", iop, &optimized));
+  ASSERT_EQ(2, optimized.src_extents_size());
+  ASSERT_EQ(2, optimized.dst_extents_size());
+  EXPECT_EQ(1u, optimized.src_extents(0).start_block());
+  EXPECT_EQ(1u, optimized.src_extents(0).num_blocks());
+  EXPECT_EQ(2u, optimized.dst_extents(0).start_block());
+  EXPECT_EQ(1u, optimized.dst_extents(0).num_blocks());
+  EXPECT_EQ(7u, optimized.src_extents(1).start_block());
+  EXPECT_EQ(2u, optimized.src_extents(1).num_blocks());
+  EXPECT_EQ(5u, optimized.dst_extents(1).start_block());
+  EXPECT_EQ(2u, optimized.dst_extents(1).num_blocks());
+
+  // Don't skip for static partitions.
+  EXPECT_FALSE(dynamicControl().OptimizeOperation("bar", iop, &optimized));
+}
+
+TEST_F(DynamicPartitionControlAndroidTest, ResetUpdate) {
+  MockPrefs prefs;
+  ASSERT_TRUE(dynamicControl().ResetUpdate(&prefs));
+}
+
+TEST_F(DynamicPartitionControlAndroidTest, IsAvbNotEnabledInFstab) {
+  std::string fstab_content =
+      "system /postinstall ext4 ro,nosuid,nodev,noexec "
+      "slotselect_other,logical\n"
+      "/dev/block/by-name/system /postinstall ext4 "
+      "ro,nosuid,nodev,noexec slotselect_other\n";
+  ScopedTempFile fstab;
+  ASSERT_TRUE(test_utils::WriteFileString(fstab.path(), fstab_content));
+  ASSERT_THAT(dynamicControl().RealIsAvbEnabledInFstab(fstab.path()),
+              Optional(false));
+}
+
+TEST_F(DynamicPartitionControlAndroidTest, IsAvbEnabledInFstab) {
+  std::string fstab_content =
+      "system /postinstall ext4 ro,nosuid,nodev,noexec "
+      "slotselect_other,logical,avb_keys=/foo\n";
+  ScopedTempFile fstab;
+  ASSERT_TRUE(test_utils::WriteFileString(fstab.path(), fstab_content));
+  ASSERT_THAT(dynamicControl().RealIsAvbEnabledInFstab(fstab.path()),
+              Optional(true));
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP, AvbNotEnabledOnSystemOther) {
+  ON_CALL(dynamicControl(), GetSystemOtherPath(_, _, _, _, _))
+      .WillByDefault(Invoke([&](auto source_slot,
+                                auto target_slot,
+                                const auto& name,
+                                auto path,
+                                auto should_unmap) {
+        return dynamicControl().RealGetSystemOtherPath(
+            source_slot, target_slot, name, path, should_unmap);
+      }));
+  ON_CALL(dynamicControl(), IsAvbEnabledOnSystemOther())
+      .WillByDefault(Return(false));
+  EXPECT_TRUE(
+      dynamicControl().RealEraseSystemOtherAvbFooter(source(), target()));
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP, NoSystemOtherToErase) {
+  SetMetadata(source(), {{S("system"), 100_MiB}});
+  ON_CALL(dynamicControl(), IsAvbEnabledOnSystemOther())
+      .WillByDefault(Return(true));
+  std::string path;
+  bool should_unmap;
+  ASSERT_TRUE(dynamicControl().RealGetSystemOtherPath(
+      source(), target(), T("system"), &path, &should_unmap));
+  ASSERT_TRUE(path.empty()) << path;
+  ASSERT_FALSE(should_unmap);
+  ON_CALL(dynamicControl(), GetSystemOtherPath(_, _, _, _, _))
+      .WillByDefault(Invoke([&](auto source_slot,
+                                auto target_slot,
+                                const auto& name,
+                                auto path,
+                                auto should_unmap) {
+        return dynamicControl().RealGetSystemOtherPath(
+            source_slot, target_slot, name, path, should_unmap);
+      }));
+  EXPECT_TRUE(
+      dynamicControl().RealEraseSystemOtherAvbFooter(source(), target()));
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP, SkipEraseUpdatedSystemOther) {
+  PartitionSuffixSizes sizes{{S("system"), 100_MiB}, {T("system"), 100_MiB}};
+  SetMetadata(source(), sizes, LP_PARTITION_ATTR_UPDATED);
+  ON_CALL(dynamicControl(), IsAvbEnabledOnSystemOther())
+      .WillByDefault(Return(true));
+  std::string path;
+  bool should_unmap;
+  ASSERT_TRUE(dynamicControl().RealGetSystemOtherPath(
+      source(), target(), T("system"), &path, &should_unmap));
+  ASSERT_TRUE(path.empty()) << path;
+  ASSERT_FALSE(should_unmap);
+  ON_CALL(dynamicControl(), GetSystemOtherPath(_, _, _, _, _))
+      .WillByDefault(Invoke([&](auto source_slot,
+                                auto target_slot,
+                                const auto& name,
+                                auto path,
+                                auto should_unmap) {
+        return dynamicControl().RealGetSystemOtherPath(
+            source_slot, target_slot, name, path, should_unmap);
+      }));
+  EXPECT_TRUE(
+      dynamicControl().RealEraseSystemOtherAvbFooter(source(), target()));
+}
+
+TEST_P(DynamicPartitionControlAndroidTestP, EraseSystemOtherAvbFooter) {
+  constexpr uint64_t file_size = 1_MiB;
+  static_assert(file_size > AVB_FOOTER_SIZE);
+  ScopedTempFile system_other;
+  brillo::Blob original(file_size, 'X');
+  ASSERT_TRUE(test_utils::WriteFileVector(system_other.path(), original));
+  std::string mnt_path;
+  ScopedLoopbackDeviceBinder dev(system_other.path(), true, &mnt_path);
+  ASSERT_TRUE(dev.is_bound());
+
+  brillo::Blob device_content;
+  ASSERT_TRUE(utils::ReadFile(mnt_path, &device_content));
+  ASSERT_EQ(original, device_content);
+
+  PartitionSuffixSizes sizes{{S("system"), 100_MiB}, {T("system"), file_size}};
+  SetMetadata(source(), sizes);
+  ON_CALL(dynamicControl(), IsAvbEnabledOnSystemOther())
+      .WillByDefault(Return(true));
+  EXPECT_CALL(dynamicControl(),
+              GetSystemOtherPath(source(), target(), T("system"), _, _))
+      .WillRepeatedly(
+          Invoke([&](auto, auto, const auto&, auto path, auto should_unmap) {
+            *path = mnt_path;
+            *should_unmap = false;
+            return true;
+          }));
+  ASSERT_TRUE(
+      dynamicControl().RealEraseSystemOtherAvbFooter(source(), target()));
+
+  device_content.clear();
+  ASSERT_TRUE(utils::ReadFile(mnt_path, &device_content));
+  brillo::Blob new_expected(original);
+  // Clear the last AVB_FOOTER_SIZE bytes.
+  new_expected.resize(file_size - AVB_FOOTER_SIZE);
+  new_expected.resize(file_size, '\0');
+  ASSERT_EQ(new_expected, device_content);
+}
+
+class FakeAutoDevice : public android::snapshot::AutoDevice {
+ public:
+  FakeAutoDevice() : AutoDevice("") {}
+};
+
+class SnapshotPartitionTestP : public DynamicPartitionControlAndroidTestP {
+ public:
+  void SetUp() override {
+    DynamicPartitionControlAndroidTestP::SetUp();
+    ON_CALL(dynamicControl(), GetVirtualAbFeatureFlag())
+        .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+
+    snapshot_ = new NiceMock<MockSnapshotManager>();
+    dynamicControl().snapshot_.reset(snapshot_);  // takes ownership
+    EXPECT_CALL(*snapshot_, BeginUpdate()).WillOnce(Return(true));
+    EXPECT_CALL(*snapshot_, EnsureMetadataMounted())
+        .WillRepeatedly(
+            Invoke([]() { return std::make_unique<FakeAutoDevice>(); }));
+
+    manifest_ =
+        PartitionSizesToManifest({{"system", 3_GiB}, {"vendor", 1_GiB}});
+  }
+  void ExpectCreateUpdateSnapshots(android::snapshot::Return val) {
+    manifest_.mutable_dynamic_partition_metadata()->set_snapshot_enabled(true);
+    EXPECT_CALL(*snapshot_, CreateUpdateSnapshots(_))
+        .WillRepeatedly(Invoke([&, val](const auto& manifest) {
+          // Deep comparison requires full protobuf library. Comparing the
+          // pointers are sufficient.
+          EXPECT_EQ(&manifest_, &manifest);
+          LOG(WARNING) << "CreateUpdateSnapshots returning " << val.string();
+          return val;
+        }));
+  }
+  bool PreparePartitionsForUpdate(uint64_t* required_size) {
+    return dynamicControl().PreparePartitionsForUpdate(
+        source(), target(), manifest_, true /* update */, required_size);
+  }
+  MockSnapshotManager* snapshot_ = nullptr;
+  DeltaArchiveManifest manifest_;
+};
+
+// Test happy path of PreparePartitionsForUpdate on a Virtual A/B device.
+TEST_P(SnapshotPartitionTestP, PreparePartitions) {
+  ExpectCreateUpdateSnapshots(android::snapshot::Return::Ok());
+  uint64_t required_size = 0;
+  EXPECT_TRUE(PreparePartitionsForUpdate(&required_size));
+  EXPECT_EQ(0u, required_size);
+}
+
+// Test that if not enough space, required size returned by SnapshotManager is
+// passed up.
+TEST_P(SnapshotPartitionTestP, PreparePartitionsNoSpace) {
+  ExpectCreateUpdateSnapshots(android::snapshot::Return::NoSpace(1_GiB));
+  uint64_t required_size = 0;
+  EXPECT_FALSE(PreparePartitionsForUpdate(&required_size));
+  EXPECT_EQ(1_GiB, required_size);
+}
+
+// Test that in recovery, use empty space in super partition for a snapshot
+// update first.
+TEST_P(SnapshotPartitionTestP, RecoveryUseSuperEmpty) {
+  ExpectCreateUpdateSnapshots(android::snapshot::Return::Ok());
+  EXPECT_CALL(dynamicControl(), IsRecovery()).WillRepeatedly(Return(true));
+  // Must not call PrepareDynamicPartitionsForUpdate if
+  // PrepareSnapshotPartitionsForUpdate succeeds.
+  EXPECT_CALL(dynamicControl(), PrepareDynamicPartitionsForUpdate(_, _, _, _))
+      .Times(0);
+  uint64_t required_size = 0;
+  EXPECT_TRUE(PreparePartitionsForUpdate(&required_size));
+  EXPECT_EQ(0u, required_size);
+}
+
+// Test that in recovery, if CreateUpdateSnapshots throws an error, try
+// the flashing path for full updates.
+TEST_P(SnapshotPartitionTestP, RecoveryErrorShouldDeleteSource) {
+  // Expectation on PreparePartitionsForUpdate
+  ExpectCreateUpdateSnapshots(android::snapshot::Return::NoSpace(1_GiB));
+  EXPECT_CALL(dynamicControl(), IsRecovery()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*snapshot_, CancelUpdate()).WillOnce(Return(true));
+  EXPECT_CALL(dynamicControl(), PrepareDynamicPartitionsForUpdate(_, _, _, _))
+      .WillRepeatedly(Invoke([&](auto source_slot,
+                                 auto target_slot,
+                                 const auto& manifest,
+                                 auto delete_source) {
+        EXPECT_EQ(source(), source_slot);
+        EXPECT_EQ(target(), target_slot);
+        // Deep comparison requires full protobuf library. Comparing the
+        // pointers are sufficient.
+        EXPECT_EQ(&manifest_, &manifest);
+        EXPECT_TRUE(delete_source);
+        return dynamicControl().RealPrepareDynamicPartitionsForUpdate(
+            source_slot, target_slot, manifest, delete_source);
+      }));
+  // Only one slot of space in super
+  uint64_t super_size = kDefaultGroupSize + 1_MiB;
+  // Expectation on PrepareDynamicPartitionsForUpdate
+  SetMetadata(
+      source(), {{S("system"), 2_GiB}, {S("vendor"), 1_GiB}}, 0, super_size);
+  ExpectUnmap({T("system"), T("vendor")});
+  // Expect that the source partitions aren't present in target super metadata.
+  ExpectStoreMetadata({{T("system"), 3_GiB}, {T("vendor"), 1_GiB}});
+
+  uint64_t required_size = 0;
+  EXPECT_TRUE(PreparePartitionsForUpdate(&required_size));
+  EXPECT_EQ(0u, required_size);
+}
+
+INSTANTIATE_TEST_CASE_P(DynamicPartitionControlAndroidTest,
+                        SnapshotPartitionTestP,
+                        testing::Values(TestParam{0, 1}, TestParam{1, 0}));
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/dynamic_partition_test_utils.h b/aosp/dynamic_partition_test_utils.h
new file mode 100644
index 0000000..c7be1cb
--- /dev/null
+++ b/aosp/dynamic_partition_test_utils.h
@@ -0,0 +1,288 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_TEST_UTILS_H_
+#define UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_TEST_UTILS_H_
+
+#include <stdint.h>
+
+#include <iostream>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/strings/string_util.h>
+#include <fs_mgr.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <liblp/builder.h>
+#include <storage_literals/storage_literals.h>
+
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+using android::fs_mgr::MetadataBuilder;
+using testing::_;
+using testing::MakeMatcher;
+using testing::Matcher;
+using testing::MatcherInterface;
+using testing::MatchResultListener;
+using namespace android::storage_literals;  // NOLINT(build/namespaces)
+
+constexpr const uint32_t kMaxNumSlots = 2;
+constexpr const char* kSlotSuffixes[kMaxNumSlots] = {"_a", "_b"};
+constexpr const char* kFakeDevicePath = "/fake/dev/path/";
+constexpr const char* kFakeDmDevicePath = "/fake/dm/dev/path/";
+constexpr const uint32_t kFakeMetadataSize = 65536;
+constexpr const char* kDefaultGroup = "foo";
+constexpr const char* kFakeSuper = "fake_super";
+
+// A map describing the size of each partition.
+// "{name, size}"
+using PartitionSizes = std::map<std::string, uint64_t>;
+
+// "{name_a, size}"
+using PartitionSuffixSizes = std::map<std::string, uint64_t>;
+
+constexpr uint64_t kDefaultGroupSize = 5_GiB;
+// Super device size. 1 MiB for metadata.
+constexpr uint64_t kDefaultSuperSize = kDefaultGroupSize * 2 + 1_MiB;
+
+template <typename U, typename V>
+inline std::ostream& operator<<(std::ostream& os, const std::map<U, V>& param) {
+  os << "{";
+  bool first = true;
+  for (const auto& pair : param) {
+    if (!first)
+      os << ", ";
+    os << pair.first << ":" << pair.second;
+    first = false;
+  }
+  return os << "}";
+}
+
+template <typename V>
+inline void VectorToStream(std::ostream& os, const V& param) {
+  os << "[";
+  bool first = true;
+  for (const auto& e : param) {
+    if (!first)
+      os << ", ";
+    os << e;
+    first = false;
+  }
+  os << "]";
+}
+
+inline std::ostream& operator<<(std::ostream& os, const PartitionUpdate& p) {
+  return os << "{" << p.partition_name() << ", "
+            << p.new_partition_info().size() << "}";
+}
+
+inline std::ostream& operator<<(std::ostream& os,
+                                const DynamicPartitionGroup& g) {
+  os << "{" << g.name() << ", " << g.size() << ", ";
+  VectorToStream(os, g.partition_names());
+  return os << "}";
+}
+
+inline std::ostream& operator<<(std::ostream& os,
+                                const DeltaArchiveManifest& m) {
+  os << "{.groups = ";
+  VectorToStream(os, m.dynamic_partition_metadata().groups());
+  os << ", .partitions = ";
+  VectorToStream(os, m.partitions());
+  return os;
+}
+
+inline std::string GetDevice(const std::string& name) {
+  return kFakeDevicePath + name;
+}
+
+inline std::string GetDmDevice(const std::string& name) {
+  return kFakeDmDevicePath + name;
+}
+
+inline DynamicPartitionGroup* AddGroup(DeltaArchiveManifest* manifest,
+                                       const std::string& group,
+                                       uint64_t group_size) {
+  auto* g = manifest->mutable_dynamic_partition_metadata()->add_groups();
+  g->set_name(group);
+  g->set_size(group_size);
+  return g;
+}
+
+inline void AddPartition(DeltaArchiveManifest* manifest,
+                         DynamicPartitionGroup* group,
+                         const std::string& partition,
+                         uint64_t partition_size) {
+  group->add_partition_names(partition);
+  auto* p = manifest->add_partitions();
+  p->set_partition_name(partition);
+  p->mutable_new_partition_info()->set_size(partition_size);
+}
+
+// To support legacy tests, auto-convert {name_a: size} map to
+// DeltaArchiveManifest.
+inline DeltaArchiveManifest PartitionSuffixSizesToManifest(
+    const PartitionSuffixSizes& partition_sizes) {
+  DeltaArchiveManifest manifest;
+  for (const char* suffix : kSlotSuffixes) {
+    AddGroup(&manifest, std::string(kDefaultGroup) + suffix, kDefaultGroupSize);
+  }
+  for (const auto& pair : partition_sizes) {
+    for (size_t suffix_idx = 0; suffix_idx < kMaxNumSlots; ++suffix_idx) {
+      if (base::EndsWith(pair.first,
+                         kSlotSuffixes[suffix_idx],
+                         base::CompareCase::SENSITIVE)) {
+        AddPartition(
+            &manifest,
+            manifest.mutable_dynamic_partition_metadata()->mutable_groups(
+                suffix_idx),
+            pair.first,
+            pair.second);
+      }
+    }
+  }
+  return manifest;
+}
+
+// To support legacy tests, auto-convert {name: size} map to PartitionMetadata.
+inline DeltaArchiveManifest PartitionSizesToManifest(
+    const PartitionSizes& partition_sizes) {
+  DeltaArchiveManifest manifest;
+  auto* g = AddGroup(&manifest, std::string(kDefaultGroup), kDefaultGroupSize);
+  for (const auto& pair : partition_sizes) {
+    AddPartition(&manifest, g, pair.first, pair.second);
+  }
+  return manifest;
+}
+
+inline std::unique_ptr<MetadataBuilder> NewFakeMetadata(
+    const DeltaArchiveManifest& manifest,
+    uint32_t partition_attr = 0,
+    uint64_t super_size = kDefaultSuperSize) {
+  auto builder =
+      MetadataBuilder::New(super_size, kFakeMetadataSize, kMaxNumSlots);
+  for (const auto& group : manifest.dynamic_partition_metadata().groups()) {
+    EXPECT_TRUE(builder->AddGroup(group.name(), group.size()));
+    for (const auto& partition_name : group.partition_names()) {
+      EXPECT_NE(
+          nullptr,
+          builder->AddPartition(partition_name, group.name(), partition_attr));
+    }
+  }
+  for (const auto& partition : manifest.partitions()) {
+    auto p = builder->FindPartition(partition.partition_name());
+    EXPECT_TRUE(p && builder->ResizePartition(
+                         p, partition.new_partition_info().size()));
+  }
+  return builder;
+}
+
+class MetadataMatcher : public MatcherInterface<MetadataBuilder*> {
+ public:
+  explicit MetadataMatcher(const PartitionSuffixSizes& partition_sizes)
+      : manifest_(PartitionSuffixSizesToManifest(partition_sizes)) {}
+  explicit MetadataMatcher(const DeltaArchiveManifest& manifest)
+      : manifest_(manifest) {}
+
+  bool MatchAndExplain(MetadataBuilder* metadata,
+                       MatchResultListener* listener) const override {
+    bool success = true;
+    for (const auto& group : manifest_.dynamic_partition_metadata().groups()) {
+      for (const auto& partition_name : group.partition_names()) {
+        auto p = metadata->FindPartition(partition_name);
+        if (p == nullptr) {
+          if (!success)
+            *listener << "; ";
+          *listener << "No partition " << partition_name;
+          success = false;
+          continue;
+        }
+        const auto& partition_updates = manifest_.partitions();
+        auto it = std::find_if(partition_updates.begin(),
+                               partition_updates.end(),
+                               [&](const auto& p) {
+                                 return p.partition_name() == partition_name;
+                               });
+        if (it == partition_updates.end()) {
+          *listener << "Can't find partition update " << partition_name;
+          success = false;
+          continue;
+        }
+        auto partition_size = it->new_partition_info().size();
+        if (p->size() != partition_size) {
+          if (!success)
+            *listener << "; ";
+          *listener << "Partition " << partition_name << " has size "
+                    << p->size() << ", expected " << partition_size;
+          success = false;
+        }
+        if (p->group_name() != group.name()) {
+          if (!success)
+            *listener << "; ";
+          *listener << "Partition " << partition_name << " has group "
+                    << p->group_name() << ", expected " << group.name();
+          success = false;
+        }
+      }
+    }
+    return success;
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "expect: " << manifest_;
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "expect not: " << manifest_;
+  }
+
+ private:
+  DeltaArchiveManifest manifest_;
+};
+
+inline Matcher<MetadataBuilder*> MetadataMatches(
+    const PartitionSuffixSizes& partition_sizes) {
+  return MakeMatcher(new MetadataMatcher(partition_sizes));
+}
+
+inline Matcher<MetadataBuilder*> MetadataMatches(
+    const DeltaArchiveManifest& manifest) {
+  return MakeMatcher(new MetadataMatcher(manifest));
+}
+
+MATCHER_P(HasGroup, group, " has group " + group) {
+  auto groups = arg->ListGroups();
+  return std::find(groups.begin(), groups.end(), group) != groups.end();
+}
+
+struct TestParam {
+  uint32_t source;
+  uint32_t target;
+};
+inline std::ostream& operator<<(std::ostream& os, const TestParam& param) {
+  return os << "{source: " << param.source << ", target:" << param.target
+            << "}";
+}
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_TEST_UTILS_H_
diff --git a/aosp/dynamic_partition_utils.cc b/aosp/dynamic_partition_utils.cc
new file mode 100644
index 0000000..6b77a45
--- /dev/null
+++ b/aosp/dynamic_partition_utils.cc
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/dynamic_partition_utils.h"
+
+#include <vector>
+
+#include <base/logging.h>
+#include <base/strings/string_util.h>
+
+using android::fs_mgr::MetadataBuilder;
+
+namespace chromeos_update_engine {
+
+void DeleteGroupsWithSuffix(MetadataBuilder* builder,
+                            const std::string& suffix) {
+  std::vector<std::string> groups = builder->ListGroups();
+  for (const auto& group_name : groups) {
+    if (base::EndsWith(group_name, suffix, base::CompareCase::SENSITIVE)) {
+      LOG(INFO) << "Removing group " << group_name;
+      builder->RemoveGroupAndPartitions(group_name);
+    }
+  }
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/dynamic_partition_utils.h b/aosp/dynamic_partition_utils.h
new file mode 100644
index 0000000..5a51d5e
--- /dev/null
+++ b/aosp/dynamic_partition_utils.h
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_UTILS_H_
+#define UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_UTILS_H_
+
+#include <string>
+
+#include <liblp/builder.h>
+
+namespace chromeos_update_engine {
+
+// Delete all groups (and their partitions) in |builder| that have names
+// ending with |suffix|.
+void DeleteGroupsWithSuffix(android::fs_mgr::MetadataBuilder* builder,
+                            const std::string& suffix);
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_UTILS_H_
diff --git a/aosp/hardware_android.cc b/aosp/hardware_android.cc
new file mode 100644
index 0000000..3b0d9a8
--- /dev/null
+++ b/aosp/hardware_android.cc
@@ -0,0 +1,295 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/hardware_android.h"
+
+#include <sys/types.h>
+#include <sys/utsname.h>
+
+#include <memory>
+#include <string>
+#include <string_view>
+
+#include <android-base/parseint.h>
+#include <android-base/properties.h>
+#include <base/files/file_util.h>
+#include <bootloader_message/bootloader_message.h>
+#include <kver/kernel_release.h>
+#include <kver/utils.h>
+
+#include "update_engine/common/error_code_utils.h"
+#include "update_engine/common/hardware.h"
+#include "update_engine/common/platform_constants.h"
+#include "update_engine/common/utils.h"
+
+using android::base::GetBoolProperty;
+using android::base::GetIntProperty;
+using android::base::GetProperty;
+using android::kver::IsKernelUpdateValid;
+using android::kver::KernelRelease;
+using std::string;
+
+namespace chromeos_update_engine {
+
+namespace {
+
+// Android properties that identify the hardware and potentially non-updatable
+// parts of the bootloader (such as the bootloader version and the baseband
+// version).
+const char kPropProductManufacturer[] = "ro.product.manufacturer";
+const char kPropBootHardwareSKU[] = "ro.boot.hardware.sku";
+const char kPropBootRevision[] = "ro.boot.revision";
+const char kPropBuildDateUTC[] = "ro.build.date.utc";
+
+string GetPartitionBuildDate(const string& partition_name) {
+  return android::base::GetProperty("ro." + partition_name + ".build.date.utc",
+                                    "");
+}
+
+}  // namespace
+
+namespace hardware {
+
+// Factory defined in hardware.h.
+std::unique_ptr<HardwareInterface> CreateHardware() {
+  return std::make_unique<HardwareAndroid>();
+}
+
+}  // namespace hardware
+
+// In Android there are normally three kinds of builds: eng, userdebug and user.
+// These builds target respectively a developer build, a debuggable version of
+// the final product and the pristine final product the end user will run.
+// Apart from the ro.build.type property name, they differ in the following
+// properties that characterize the builds:
+// * eng builds: ro.secure=0 and ro.debuggable=1
+// * userdebug builds: ro.secure=1 and ro.debuggable=1
+// * user builds: ro.secure=1 and ro.debuggable=0
+//
+// See IsOfficialBuild() and IsNormalMode() for the meaning of these options in
+// Android.
+
+bool HardwareAndroid::IsOfficialBuild() const {
+  // We run an official build iff ro.secure == 1, because we expect the build to
+  // behave like the end user product and check for updates. Note that while
+  // developers are able to build "official builds" by just running "make user",
+  // that will only result in a more restrictive environment. The important part
+  // is that we don't produce and push "non-official" builds to the end user.
+  //
+  // In case of a non-bool value, we take the most restrictive option and
+  // assume we are in an official-build.
+  return GetBoolProperty("ro.secure", true);
+}
+
+bool HardwareAndroid::IsNormalBootMode() const {
+  // We are running in "dev-mode" iff ro.debuggable == 1. In dev-mode the
+  // update_engine will allow extra developers options, such as providing a
+  // different update URL. In case of error, we assume the build is in
+  // normal-mode.
+  return !GetBoolProperty("ro.debuggable", false);
+}
+
+bool HardwareAndroid::AreDevFeaturesEnabled() const {
+  return !IsNormalBootMode();
+}
+
+bool HardwareAndroid::IsOOBEEnabled() const {
+  // No OOBE flow blocking updates for Android-based boards.
+  return false;
+}
+
+bool HardwareAndroid::IsOOBEComplete(base::Time* out_time_of_oobe) const {
+  LOG(WARNING) << "OOBE is not enabled but IsOOBEComplete() called.";
+  if (out_time_of_oobe)
+    *out_time_of_oobe = base::Time();
+  return true;
+}
+
+string HardwareAndroid::GetHardwareClass() const {
+  auto manufacturer = GetProperty(kPropProductManufacturer, "");
+  auto sku = GetProperty(kPropBootHardwareSKU, "");
+  auto revision = GetProperty(kPropBootRevision, "");
+
+  return manufacturer + ":" + sku + ":" + revision;
+}
+
+string HardwareAndroid::GetDeviceRequisition() const {
+  LOG(WARNING) << "STUB: Getting requisition is not supported.";
+  return "";
+}
+
+int HardwareAndroid::GetMinKernelKeyVersion() const {
+  LOG(WARNING) << "STUB: No Kernel key version is available.";
+  return -1;
+}
+
+int HardwareAndroid::GetMinFirmwareKeyVersion() const {
+  LOG(WARNING) << "STUB: No Firmware key version is available.";
+  return -1;
+}
+
+int HardwareAndroid::GetMaxFirmwareKeyRollforward() const {
+  LOG(WARNING) << "STUB: Getting firmware_max_rollforward is not supported.";
+  return -1;
+}
+
+bool HardwareAndroid::SetMaxFirmwareKeyRollforward(
+    int firmware_max_rollforward) {
+  LOG(WARNING) << "STUB: Setting firmware_max_rollforward is not supported.";
+  return false;
+}
+
+bool HardwareAndroid::SetMaxKernelKeyRollforward(int kernel_max_rollforward) {
+  LOG(WARNING) << "STUB: Setting kernel_max_rollforward is not supported.";
+  return false;
+}
+
+int HardwareAndroid::GetPowerwashCount() const {
+  LOG(WARNING) << "STUB: Assuming no factory reset was performed.";
+  return 0;
+}
+
+bool HardwareAndroid::SchedulePowerwash(bool save_rollback_data) {
+  LOG(INFO) << "Scheduling a powerwash to BCB.";
+  LOG_IF(WARNING, save_rollback_data) << "save_rollback_data was true but "
+                                      << "isn't supported.";
+  string err;
+  if (!update_bootloader_message({"--wipe_data", "--reason=wipe_data_from_ota"},
+                                 &err)) {
+    LOG(ERROR) << "Failed to update bootloader message: " << err;
+    return false;
+  }
+  return true;
+}
+
+bool HardwareAndroid::CancelPowerwash() {
+  string err;
+  if (!clear_bootloader_message(&err)) {
+    LOG(ERROR) << "Failed to clear bootloader message: " << err;
+    return false;
+  }
+  return true;
+}
+
+bool HardwareAndroid::GetNonVolatileDirectory(base::FilePath* path) const {
+  base::FilePath local_path(constants::kNonVolatileDirectory);
+  if (!base::DirectoryExists(local_path)) {
+    LOG(ERROR) << "Non-volatile directory not found: " << local_path.value();
+    return false;
+  }
+  *path = local_path;
+  return true;
+}
+
+bool HardwareAndroid::GetPowerwashSafeDirectory(base::FilePath* path) const {
+  // On Android, we don't have a directory persisted across powerwash.
+  return false;
+}
+
+int64_t HardwareAndroid::GetBuildTimestamp() const {
+  return GetIntProperty<int64_t>(kPropBuildDateUTC, 0);
+}
+
+// Returns true if the device runs an userdebug build, and explicitly allows OTA
+// downgrade.
+bool HardwareAndroid::AllowDowngrade() const {
+  return GetBoolProperty("ro.ota.allow_downgrade", false) &&
+         GetBoolProperty("ro.debuggable", false);
+}
+
+bool HardwareAndroid::GetFirstActiveOmahaPingSent() const {
+  LOG(WARNING) << "STUB: Assuming first active omaha was never set.";
+  return false;
+}
+
+bool HardwareAndroid::SetFirstActiveOmahaPingSent() {
+  LOG(WARNING) << "STUB: Assuming first active omaha is set.";
+  // We will set it true, so its failure doesn't cause escalation.
+  return true;
+}
+
+void HardwareAndroid::SetWarmReset(bool warm_reset) {
+  constexpr char warm_reset_prop[] = "ota.warm_reset";
+  if (!android::base::SetProperty(warm_reset_prop, warm_reset ? "1" : "0")) {
+    LOG(WARNING) << "Failed to set prop " << warm_reset_prop;
+  }
+}
+
+string HardwareAndroid::GetVersionForLogging(
+    const string& partition_name) const {
+  if (partition_name == "boot") {
+    struct utsname buf;
+    if (uname(&buf) != 0) {
+      PLOG(ERROR) << "Unable to call uname()";
+      return "";
+    }
+    auto kernel_release =
+        KernelRelease::Parse(buf.release, true /* allow_suffix */);
+    return kernel_release.has_value() ? kernel_release->string() : "";
+  }
+  return GetPartitionBuildDate(partition_name);
+}
+
+ErrorCode HardwareAndroid::IsPartitionUpdateValid(
+    const string& partition_name, const string& new_version) const {
+  if (partition_name == "boot") {
+    struct utsname buf;
+    if (uname(&buf) != 0) {
+      PLOG(ERROR) << "Unable to call uname()";
+      return ErrorCode::kError;
+    }
+    return IsKernelUpdateValid(buf.release, new_version);
+  }
+
+  const auto old_version = GetPartitionBuildDate(partition_name);
+  // TODO(zhangkelvin)  for some partitions, missing a current timestamp should
+  // be an error, e.g. system, vendor, product etc.
+  auto error_code = utils::IsTimestampNewer(old_version, new_version);
+  if (error_code != ErrorCode::kSuccess) {
+    LOG(ERROR) << "Timestamp check failed with "
+               << utils::ErrorCodeToString(error_code)
+               << " Partition timestamp: " << old_version
+               << " Update timestamp: " << new_version;
+  }
+  return error_code;
+}
+
+ErrorCode HardwareAndroid::IsKernelUpdateValid(const string& old_release,
+                                               const string& new_release) {
+  // Check that the package either contain an empty version (indicating that the
+  // new build does not use GKI), or a valid GKI kernel release.
+  std::optional<KernelRelease> new_kernel_release;
+  if (new_release.empty()) {
+    LOG(INFO) << "New build does not contain GKI.";
+  } else {
+    new_kernel_release =
+        KernelRelease::Parse(new_release, true /* allow_suffix */);
+    if (!new_kernel_release.has_value()) {
+      LOG(ERROR) << "New kernel release is not valid GKI kernel release: "
+                 << new_release;
+      return ErrorCode::kDownloadManifestParseError;
+    }
+  }
+
+  auto old_kernel_release =
+      KernelRelease::Parse(old_release, true /* allow_suffix */);
+  return android::kver::IsKernelUpdateValid(old_kernel_release,
+                                            new_kernel_release)
+             ? ErrorCode::kSuccess
+             : ErrorCode::kPayloadTimestampError;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/hardware_android.h b/aosp/hardware_android.h
new file mode 100644
index 0000000..5e09fb3
--- /dev/null
+++ b/aosp/hardware_android.h
@@ -0,0 +1,80 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_HARDWARE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_HARDWARE_ANDROID_H_
+
+#include <string>
+#include <string_view>
+
+#include <base/macros.h>
+#include <base/time/time.h>
+#include <gtest/gtest_prod.h>
+
+#include "update_engine/common/error_code.h"
+#include "update_engine/common/hardware.h"
+#include "update_engine/common/hardware_interface.h"
+
+namespace chromeos_update_engine {
+
+// Implements the real interface with the hardware in the Android platform.
+class HardwareAndroid : public HardwareInterface {
+ public:
+  HardwareAndroid() = default;
+  ~HardwareAndroid() override = default;
+
+  // HardwareInterface methods.
+  bool IsOfficialBuild() const override;
+  bool IsNormalBootMode() const override;
+  bool AreDevFeaturesEnabled() const override;
+  bool IsOOBEEnabled() const override;
+  bool IsOOBEComplete(base::Time* out_time_of_oobe) const override;
+  std::string GetHardwareClass() const override;
+  std::string GetDeviceRequisition() const override;
+  int GetMinKernelKeyVersion() const override;
+  int GetMinFirmwareKeyVersion() const override;
+  int GetMaxFirmwareKeyRollforward() const override;
+  bool SetMaxFirmwareKeyRollforward(int firmware_max_rollforward) override;
+  bool SetMaxKernelKeyRollforward(int kernel_max_rollforward) override;
+  int GetPowerwashCount() const override;
+  bool SchedulePowerwash(bool save_rollback_data) override;
+  bool CancelPowerwash() override;
+  bool GetNonVolatileDirectory(base::FilePath* path) const override;
+  bool GetPowerwashSafeDirectory(base::FilePath* path) const override;
+  int64_t GetBuildTimestamp() const override;
+  bool AllowDowngrade() const override;
+  bool GetFirstActiveOmahaPingSent() const override;
+  bool SetFirstActiveOmahaPingSent() override;
+  void SetWarmReset(bool warm_reset) override;
+  [[nodiscard]] std::string GetVersionForLogging(
+      const std::string& partition_name) const override;
+  [[nodiscard]] ErrorCode IsPartitionUpdateValid(
+      const std::string& partition_name,
+      const std::string& new_version) const override;
+
+ private:
+  FRIEND_TEST(HardwareAndroidTest, IsKernelUpdateValid);
+
+  // Helper for IsPartitionUpdateValid.
+  static ErrorCode IsKernelUpdateValid(const std::string& old_release,
+                                       const std::string& new_release);
+
+  DISALLOW_COPY_AND_ASSIGN(HardwareAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_HARDWARE_ANDROID_H_
diff --git a/aosp/logging_android.cc b/aosp/logging_android.cc
new file mode 100644
index 0000000..0219075
--- /dev/null
+++ b/aosp/logging_android.cc
@@ -0,0 +1,276 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <functional>
+#include <iomanip>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <base/files/dir_reader_posix.h>
+#include <base/logging.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <log/log.h>
+
+#include "update_engine/common/utils.h"
+
+using std::string;
+
+#ifdef _UE_SIDELOAD
+constexpr bool kSideload = true;
+#else
+constexpr bool kSideload = false;
+#endif
+
+namespace chromeos_update_engine {
+namespace {
+
+constexpr char kSystemLogsRoot[] = "/data/misc/update_engine_log";
+constexpr size_t kLogCount = 5;
+
+// Keep the most recent |kLogCount| logs but remove the old ones in
+// "/data/misc/update_engine_log/".
+void DeleteOldLogs(const string& kLogsRoot) {
+  base::DirReaderPosix reader(kLogsRoot.c_str());
+  if (!reader.IsValid()) {
+    LOG(ERROR) << "Failed to read " << kLogsRoot;
+    return;
+  }
+
+  std::vector<string> old_logs;
+  while (reader.Next()) {
+    if (reader.name()[0] == '.')
+      continue;
+
+    // Log files are in format "update_engine.%Y%m%d-%H%M%S",
+    // e.g. update_engine.20090103-231425
+    uint64_t date;
+    uint64_t local_time;
+    if (sscanf(reader.name(),
+               "update_engine.%" PRIu64 "-%" PRIu64 "",
+               &date,
+               &local_time) == 2) {
+      old_logs.push_back(reader.name());
+    } else {
+      LOG(WARNING) << "Unrecognized log file " << reader.name();
+    }
+  }
+
+  std::sort(old_logs.begin(), old_logs.end(), std::greater<string>());
+  for (size_t i = kLogCount; i < old_logs.size(); i++) {
+    string log_path = kLogsRoot + "/" + old_logs[i];
+    if (unlink(log_path.c_str()) == -1) {
+      PLOG(WARNING) << "Failed to unlink " << log_path;
+    }
+  }
+}
+
+string SetupLogFile(const string& kLogsRoot) {
+  DeleteOldLogs(kLogsRoot);
+
+  return base::StringPrintf("%s/update_engine.%s",
+                            kLogsRoot.c_str(),
+                            utils::GetTimeAsString(::time(nullptr)).c_str());
+}
+
+const char* LogPriorityToCString(int priority) {
+  switch (priority) {
+    case ANDROID_LOG_VERBOSE:
+      return "VERBOSE";
+    case ANDROID_LOG_DEBUG:
+      return "DEBUG";
+    case ANDROID_LOG_INFO:
+      return "INFO";
+    case ANDROID_LOG_WARN:
+      return "WARN";
+    case ANDROID_LOG_ERROR:
+      return "ERROR";
+    case ANDROID_LOG_FATAL:
+      return "FATAL";
+    default:
+      return "UNKNOWN";
+  }
+}
+
+using LoggerFunction = std::function<void(const struct __android_log_message*)>;
+
+class FileLogger {
+ public:
+  explicit FileLogger(const string& path) {
+    fd_.reset(TEMP_FAILURE_RETRY(
+        open(path.c_str(),
+             O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_SYNC,
+             0644)));
+    if (fd_ == -1) {
+      // Use ALOGE that logs to logd before __android_log_set_logger.
+      ALOGE("Cannot open persistent log %s: %s", path.c_str(), strerror(errno));
+      return;
+    }
+    // The log file will have AID_LOG as group ID; this GID is inherited from
+    // the parent directory "/data/misc/update_engine_log" which sets the SGID
+    // bit.
+    if (fchmod(fd_.get(), 0640) == -1) {
+      // Use ALOGE that logs to logd before __android_log_set_logger.
+      ALOGE("Cannot chmod 0640 persistent log %s: %s",
+            path.c_str(),
+            strerror(errno));
+      return;
+    }
+  }
+  // Copy-constructor needed to be converted to std::function.
+  FileLogger(const FileLogger& other) { fd_.reset(dup(other.fd_)); }
+  void operator()(const struct __android_log_message* log_message) {
+    if (fd_ == -1) {
+      return;
+    }
+
+    std::string_view message_str =
+        log_message->message != nullptr ? log_message->message : "";
+
+    WriteToFd(GetPrefix(log_message));
+    WriteToFd(message_str);
+    WriteToFd("\n");
+  }
+
+ private:
+  android::base::unique_fd fd_;
+  void WriteToFd(std::string_view message) {
+    ignore_result(
+        android::base::WriteFully(fd_, message.data(), message.size()));
+  }
+
+  string GetPrefix(const struct __android_log_message* log_message) {
+    std::stringstream ss;
+    timeval tv;
+    gettimeofday(&tv, nullptr);
+    time_t t = tv.tv_sec;
+    struct tm local_time;
+    localtime_r(&t, &local_time);
+    struct tm* tm_time = &local_time;
+    ss << "[" << std::setfill('0') << std::setw(2) << 1 + tm_time->tm_mon
+       << std::setw(2) << tm_time->tm_mday << '/' << std::setw(2)
+       << tm_time->tm_hour << std::setw(2) << tm_time->tm_min << std::setw(2)
+       << tm_time->tm_sec << '.' << std::setw(6) << tv.tv_usec << "] ";
+    // libchrome logs prepends |message| with severity, file and line, but
+    // leave logger_data->file as nullptr.
+    // libbase / liblog logs doesn't. Hence, add them to match the style.
+    // For liblog logs that doesn't set logger_data->file, not printing the
+    // priority is acceptable.
+    if (log_message->file) {
+      ss << "[" << LogPriorityToCString(log_message->priority) << ':'
+         << log_message->file << '(' << log_message->line << ")] ";
+    }
+    return ss.str();
+  }
+};
+
+class CombinedLogger {
+ public:
+  CombinedLogger(bool log_to_system, bool log_to_file) {
+    if (log_to_system) {
+      if (kSideload) {
+        // No logd in sideload. Use stdout.
+        // recovery has already redirected stdio properly.
+        loggers_.push_back(__android_log_stderr_logger);
+      } else {
+        loggers_.push_back(__android_log_logd_logger);
+      }
+    }
+    if (log_to_file) {
+      loggers_.push_back(std::move(FileLogger(SetupLogFile(kSystemLogsRoot))));
+    }
+  }
+  void operator()(const struct __android_log_message* log_message) {
+    for (auto&& logger : loggers_) {
+      logger(log_message);
+    }
+  }
+
+ private:
+  std::vector<LoggerFunction> loggers_;
+};
+
+// Redirect all libchrome logs to liblog using our custom handler that does
+// not call __android_log_write and explicitly write to stderr at the same
+// time. The preset CombinedLogger already writes to stderr properly.
+bool RedirectToLiblog(int severity,
+                      const char* file,
+                      int line,
+                      size_t message_start,
+                      const std::string& str_newline) {
+  android_LogPriority priority =
+      (severity < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN;
+  switch (severity) {
+    case logging::LOG_INFO:
+      priority = ANDROID_LOG_INFO;
+      break;
+    case logging::LOG_WARNING:
+      priority = ANDROID_LOG_WARN;
+      break;
+    case logging::LOG_ERROR:
+      priority = ANDROID_LOG_ERROR;
+      break;
+    case logging::LOG_FATAL:
+      priority = ANDROID_LOG_FATAL;
+      break;
+  }
+  std::string_view sv = str_newline;
+  ignore_result(android::base::ConsumeSuffix(&sv, "\n"));
+  std::string str(sv.data(), sv.size());
+  // This will eventually be redirected to CombinedLogger.
+  // Use nullptr as tag so that liblog infers log tag from getprogname().
+  __android_log_write(priority, nullptr /* tag */, str.c_str());
+  return true;
+}
+
+}  // namespace
+
+void SetupLogging(bool log_to_system, bool log_to_file) {
+  // Note that libchrome logging uses liblog.
+  // By calling liblog's __android_log_set_logger function, all of libchrome
+  // (used by update_engine) / libbase / liblog (used by depended modules)
+  // logging eventually redirects to CombinedLogger.
+  static auto g_logger =
+      std::make_unique<CombinedLogger>(log_to_system, log_to_file);
+  __android_log_set_logger([](const struct __android_log_message* log_message) {
+    (*g_logger)(log_message);
+  });
+
+  // libchrome logging should not log to file.
+  logging::LoggingSettings log_settings;
+  log_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
+  log_settings.logging_dest =
+      static_cast<logging::LoggingDestination>(logging::LOG_NONE);
+  log_settings.log_file = nullptr;
+  logging::InitLogging(log_settings);
+  logging::SetLogItems(false /* enable_process_id */,
+                       false /* enable_thread_id */,
+                       false /* enable_timestamp */,
+                       false /* enable_tickcount */);
+  logging::SetLogMessageHandler(&RedirectToLiblog);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/metrics_reporter_android.cc b/aosp/metrics_reporter_android.cc
new file mode 100644
index 0000000..ea3bb6d
--- /dev/null
+++ b/aosp/metrics_reporter_android.cc
@@ -0,0 +1,170 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/metrics_reporter_android.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+#include <android-base/properties.h>
+#include <base/strings/string_util.h>
+#include <fs_mgr.h>
+#include <libdm/dm.h>
+#include <liblp/builder.h>
+#include <liblp/liblp.h>
+#include <statslog.h>
+
+#include "update_engine/common/constants.h"
+
+using android::fs_mgr::GetPartitionGroupName;
+using android::fs_mgr::LpMetadata;
+using android::fs_mgr::MetadataBuilder;
+using android::fs_mgr::ReadMetadata;
+using android::fs_mgr::SlotNumberForSlotSuffix;
+using base::EndsWith;
+
+namespace {
+// A number offset adds on top of the enum value. e.g. ErrorCode::SUCCESS will
+// be reported as 10000, and AttemptResult::UPDATE_CANCELED will be reported as
+// 10011. This keeps the ordering of update engine's enum definition when statsd
+// atoms reserve the value 0 for unknown state.
+constexpr auto kMetricsReporterEnumOffset = 10000;
+
+int32_t GetStatsdEnumValue(int32_t value) {
+  return kMetricsReporterEnumOffset + value;
+}
+}  // namespace
+
+namespace chromeos_update_engine {
+
+namespace metrics {
+
+std::unique_ptr<MetricsReporterInterface> CreateMetricsReporter() {
+  return std::make_unique<MetricsReporterAndroid>();
+}
+
+}  // namespace metrics
+
+void MetricsReporterAndroid::ReportUpdateAttemptMetrics(
+    SystemState* /* system_state */,
+    int attempt_number,
+    PayloadType payload_type,
+    base::TimeDelta duration,
+    base::TimeDelta duration_uptime,
+    int64_t payload_size,
+    metrics::AttemptResult attempt_result,
+    ErrorCode error_code) {
+  int64_t payload_size_mib = payload_size / kNumBytesInOneMiB;
+
+  int64_t super_partition_size_bytes = 0;
+  int64_t super_free_space = 0;
+  int64_t slot_size_bytes = 0;
+
+  if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
+    uint32_t slot = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
+    auto super_device = fs_mgr_get_super_partition_name();
+    std::unique_ptr<LpMetadata> metadata = ReadMetadata(super_device, slot);
+    if (metadata) {
+      super_partition_size_bytes = GetTotalSuperPartitionSize(*metadata);
+
+      for (const auto& group : metadata->groups) {
+        if (EndsWith(GetPartitionGroupName(group),
+                     fs_mgr_get_slot_suffix(),
+                     base::CompareCase::SENSITIVE)) {
+          slot_size_bytes += group.maximum_size;
+        }
+      }
+
+      auto metadata_builder = MetadataBuilder::New(*metadata);
+      if (metadata_builder) {
+        auto free_regions = metadata_builder->GetFreeRegions();
+        for (const auto& interval : free_regions) {
+          super_free_space += interval.length();
+        }
+        super_free_space *= android::dm::kSectorSize;
+      } else {
+        LOG(ERROR) << "Cannot create metadata builder.";
+      }
+    } else {
+      LOG(ERROR) << "Could not read dynamic partition metadata for device: "
+                 << super_device;
+    }
+  }
+
+  android::util::stats_write(
+      android::util::UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED,
+      attempt_number,
+      GetStatsdEnumValue(static_cast<int32_t>(payload_type)),
+      duration.InMinutes(),
+      duration_uptime.InMinutes(),
+      payload_size_mib,
+      GetStatsdEnumValue(static_cast<int32_t>(attempt_result)),
+      GetStatsdEnumValue(static_cast<int32_t>(error_code)),
+      android::base::GetProperty("ro.build.fingerprint", "").c_str(),
+      super_partition_size_bytes,
+      slot_size_bytes,
+      super_free_space);
+}
+
+void MetricsReporterAndroid::ReportUpdateAttemptDownloadMetrics(
+    int64_t payload_bytes_downloaded,
+    int64_t /* payload_download_speed_bps */,
+    DownloadSource /* download_source */,
+    metrics::DownloadErrorCode /* payload_download_error_code */,
+    metrics::ConnectionType /* connection_type */) {
+  // TODO(xunchang) add statsd reporting
+  LOG(INFO) << "Current update attempt downloads "
+            << payload_bytes_downloaded / kNumBytesInOneMiB << " bytes data";
+}
+
+void MetricsReporterAndroid::ReportSuccessfulUpdateMetrics(
+    int attempt_count,
+    int /* updates_abandoned_count */,
+    PayloadType payload_type,
+    int64_t payload_size,
+    int64_t num_bytes_downloaded[kNumDownloadSources],
+    int download_overhead_percentage,
+    base::TimeDelta total_duration,
+    base::TimeDelta /* total_duration_uptime */,
+    int reboot_count,
+    int /* url_switch_count */) {
+  int64_t payload_size_mib = payload_size / kNumBytesInOneMiB;
+  int64_t total_bytes_downloaded = 0;
+  for (size_t i = 0; i < kNumDownloadSources; i++) {
+    total_bytes_downloaded += num_bytes_downloaded[i] / kNumBytesInOneMiB;
+  }
+
+  android::util::stats_write(
+      android::util::UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED,
+      static_cast<int32_t>(attempt_count),
+      GetStatsdEnumValue(static_cast<int32_t>(payload_type)),
+      static_cast<int32_t>(payload_size_mib),
+      static_cast<int32_t>(total_bytes_downloaded),
+      static_cast<int32_t>(download_overhead_percentage),
+      static_cast<int32_t>(total_duration.InMinutes()),
+      static_cast<int32_t>(reboot_count));
+}
+
+void MetricsReporterAndroid::ReportAbnormallyTerminatedUpdateAttemptMetrics() {
+  int attempt_result =
+      static_cast<int>(metrics::AttemptResult::kAbnormalTermination);
+  // TODO(xunchang) add statsd reporting
+  LOG(INFO) << "Abnormally terminated update attempt result " << attempt_result;
+}
+
+};  // namespace chromeos_update_engine
diff --git a/aosp/metrics_reporter_android.h b/aosp/metrics_reporter_android.h
new file mode 100644
index 0000000..4a173bf
--- /dev/null
+++ b/aosp/metrics_reporter_android.h
@@ -0,0 +1,101 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_METRICS_REPORTER_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_METRICS_REPORTER_ANDROID_H_
+
+#include <string>
+
+#include "update_engine/common/error_code.h"
+#include "update_engine/common/metrics_constants.h"
+#include "update_engine/common/metrics_reporter_interface.h"
+
+namespace chromeos_update_engine {
+
+class MetricsReporterAndroid : public MetricsReporterInterface {
+ public:
+  MetricsReporterAndroid() = default;
+
+  ~MetricsReporterAndroid() override = default;
+
+  void ReportRollbackMetrics(metrics::RollbackResult result) override {}
+
+  void ReportEnterpriseRollbackMetrics(
+      bool success, const std::string& rollback_version) override {}
+
+  void ReportDailyMetrics(base::TimeDelta os_age) override {}
+
+  void ReportUpdateCheckMetrics(
+      SystemState* system_state,
+      metrics::CheckResult result,
+      metrics::CheckReaction reaction,
+      metrics::DownloadErrorCode download_error_code) override {}
+
+  void ReportUpdateAttemptMetrics(SystemState* system_state,
+                                  int attempt_number,
+                                  PayloadType payload_type,
+                                  base::TimeDelta duration,
+                                  base::TimeDelta duration_uptime,
+                                  int64_t payload_size,
+                                  metrics::AttemptResult attempt_result,
+                                  ErrorCode internal_error_code) override;
+
+  void ReportUpdateAttemptDownloadMetrics(
+      int64_t payload_bytes_downloaded,
+      int64_t payload_download_speed_bps,
+      DownloadSource download_source,
+      metrics::DownloadErrorCode payload_download_error_code,
+      metrics::ConnectionType connection_type) override;
+
+  void ReportAbnormallyTerminatedUpdateAttemptMetrics() override;
+
+  void ReportSuccessfulUpdateMetrics(
+      int attempt_count,
+      int updates_abandoned_count,
+      PayloadType payload_type,
+      int64_t payload_size,
+      int64_t num_bytes_downloaded[kNumDownloadSources],
+      int download_overhead_percentage,
+      base::TimeDelta total_duration,
+      base::TimeDelta total_duration_uptime,
+      int reboot_count,
+      int url_switch_count) override;
+
+  void ReportCertificateCheckMetrics(ServerToCheck server_to_check,
+                                     CertificateCheckResult result) override {}
+
+  void ReportFailedUpdateCount(int target_attempt) override {}
+
+  void ReportTimeToReboot(int time_to_reboot_minutes) override {}
+
+  void ReportInstallDateProvisioningSource(int source, int max) override {}
+
+  void ReportInternalErrorCode(ErrorCode error_code) override {}
+
+  void ReportKeyVersionMetrics(int kernel_min_version,
+                               int kernel_max_rollforward_version,
+                               bool kernel_max_rollforward_success) override {}
+
+  void ReportEnterpriseUpdateSeenToDownloadDays(
+      bool has_time_restriction_policy, int time_to_update_days) override {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MetricsReporterAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_METRICS_REPORTER_ANDROID_H_
diff --git a/aosp/mock_dynamic_partition_control.h b/aosp/mock_dynamic_partition_control.h
new file mode 100644
index 0000000..382106e
--- /dev/null
+++ b/aosp/mock_dynamic_partition_control.h
@@ -0,0 +1,118 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <stdint.h>
+
+#include <memory>
+#include <set>
+#include <string>
+
+#include <gmock/gmock.h>
+
+#include "update_engine/aosp/dynamic_partition_control_android.h"
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/dynamic_partition_control_interface.h"
+
+namespace chromeos_update_engine {
+
+class MockDynamicPartitionControlAndroid
+    : public DynamicPartitionControlAndroid {
+ public:
+  MOCK_METHOD(
+      bool,
+      MapPartitionOnDeviceMapper,
+      (const std::string&, const std::string&, uint32_t, bool, std::string*),
+      (override));
+  MOCK_METHOD(bool,
+              UnmapPartitionOnDeviceMapper,
+              (const std::string&),
+              (override));
+  MOCK_METHOD(void, Cleanup, (), (override));
+  MOCK_METHOD(bool, DeviceExists, (const std::string&), (override));
+  MOCK_METHOD(::android::dm::DmDeviceState,
+              GetState,
+              (const std::string&),
+              (override));
+  MOCK_METHOD(bool,
+              GetDmDevicePathByName,
+              (const std::string&, std::string*),
+              (override));
+  MOCK_METHOD(std::unique_ptr<::android::fs_mgr::MetadataBuilder>,
+              LoadMetadataBuilder,
+              (const std::string&, uint32_t),
+              (override));
+  MOCK_METHOD(std::unique_ptr<::android::fs_mgr::MetadataBuilder>,
+              LoadMetadataBuilder,
+              (const std::string&, uint32_t, uint32_t),
+              (override));
+  MOCK_METHOD(bool,
+              StoreMetadata,
+              (const std::string&, android::fs_mgr::MetadataBuilder*, uint32_t),
+              (override));
+  MOCK_METHOD(bool, GetDeviceDir, (std::string*), (override));
+  MOCK_METHOD(FeatureFlag, GetDynamicPartitionsFeatureFlag, (), (override));
+  MOCK_METHOD(std::string, GetSuperPartitionName, (uint32_t), (override));
+  MOCK_METHOD(FeatureFlag, GetVirtualAbFeatureFlag, (), (override));
+  MOCK_METHOD(bool, FinishUpdate, (bool), (override));
+  MOCK_METHOD(bool,
+              GetSystemOtherPath,
+              (uint32_t, uint32_t, const std::string&, std::string*, bool*),
+              (override));
+  MOCK_METHOD(bool,
+              EraseSystemOtherAvbFooter,
+              (uint32_t, uint32_t),
+              (override));
+  MOCK_METHOD(std::optional<bool>, IsAvbEnabledOnSystemOther, (), (override));
+  MOCK_METHOD(bool, IsRecovery, (), (override));
+  MOCK_METHOD(bool,
+              PrepareDynamicPartitionsForUpdate,
+              (uint32_t, uint32_t, const DeltaArchiveManifest&, bool),
+              (override));
+
+  void set_fake_mapped_devices(const std::set<std::string>& fake) override {
+    DynamicPartitionControlAndroid::set_fake_mapped_devices(fake);
+  }
+
+  bool RealGetSystemOtherPath(uint32_t source_slot,
+                              uint32_t target_slot,
+                              const std::string& partition_name_suffix,
+                              std::string* path,
+                              bool* should_unmap) {
+    return DynamicPartitionControlAndroid::GetSystemOtherPath(
+        source_slot, target_slot, partition_name_suffix, path, should_unmap);
+  }
+
+  bool RealEraseSystemOtherAvbFooter(uint32_t source_slot,
+                                     uint32_t target_slot) {
+    return DynamicPartitionControlAndroid::EraseSystemOtherAvbFooter(
+        source_slot, target_slot);
+  }
+
+  std::optional<bool> RealIsAvbEnabledInFstab(const std::string& path) {
+    return DynamicPartitionControlAndroid::IsAvbEnabledInFstab(path);
+  }
+
+  bool RealPrepareDynamicPartitionsForUpdate(
+      uint32_t source_slot,
+      uint32_t target_slot,
+      const DeltaArchiveManifest& manifest,
+      bool delete_source) {
+    return DynamicPartitionControlAndroid::PrepareDynamicPartitionsForUpdate(
+        source_slot, target_slot, manifest, delete_source);
+  }
+};
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/network_selector_android.cc b/aosp/network_selector_android.cc
new file mode 100644
index 0000000..a7db415
--- /dev/null
+++ b/aosp/network_selector_android.cc
@@ -0,0 +1,46 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/network_selector_android.h"
+
+#include <memory>
+
+#include <android/multinetwork.h>
+#include <base/logging.h>
+
+namespace chromeos_update_engine {
+
+namespace network {
+
+// Factory defined in common/network_selector.h.
+std::unique_ptr<NetworkSelectorInterface> CreateNetworkSelector() {
+  return std::make_unique<NetworkSelectorAndroid>();
+}
+
+}  // namespace network
+
+// Defined in common/network_selector_interface.h.
+const NetworkId kDefaultNetworkId = NETWORK_UNSPECIFIED;
+
+bool NetworkSelectorAndroid::SetProcessNetwork(NetworkId network_id) {
+  if (android_setprocnetwork(network_id) < 0) {
+    PLOG(ERROR) << "Binding the network to " << network_id;
+    return false;
+  }
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/network_selector_android.h b/aosp/network_selector_android.h
new file mode 100644
index 0000000..b79d1b3
--- /dev/null
+++ b/aosp/network_selector_android.h
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_NETWORK_SELECTOR_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_NETWORK_SELECTOR_ANDROID_H_
+
+#include <base/macros.h>
+
+#include "update_engine/common/network_selector_interface.h"
+
+namespace chromeos_update_engine {
+
+class NetworkSelectorAndroid final : public NetworkSelectorInterface {
+ public:
+  NetworkSelectorAndroid() = default;
+  ~NetworkSelectorAndroid() override = default;
+
+  // NetworkSelectorInterface overrides.
+  bool SetProcessNetwork(NetworkId network_id) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NetworkSelectorAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_NETWORK_SELECTOR_ANDROID_H_
diff --git a/aosp/platform_constants_android.cc b/aosp/platform_constants_android.cc
new file mode 100644
index 0000000..f468c3b
--- /dev/null
+++ b/aosp/platform_constants_android.cc
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/common/platform_constants.h"
+
+namespace chromeos_update_engine {
+namespace constants {
+
+const char kOmahaDefaultProductionURL[] =
+    "https://clients2.google.com/service/update2/brillo";
+const char kOmahaDefaultAUTestURL[] =
+    "https://clients2.google.com/service/update2/brillo";
+const char kOmahaUpdaterID[] = "Brillo";
+const char kOmahaPlatformName[] = "Brillo";
+const char kUpdatePayloadPublicKeyPath[] = "";
+const char kUpdateCertificatesPath[] = "/system/etc/security/otacerts.zip";
+const char kCACertificatesPath[] = "/system/etc/security/cacerts_google";
+// No deadline file API support on Android.
+const char kOmahaResponseDeadlineFile[] = "";
+const char kNonVolatileDirectory[] = "/data/misc/update_engine";
+const char kPostinstallMountOptions[] =
+    "context=u:object_r:postinstall_file:s0";
+
+}  // namespace constants
+}  // namespace chromeos_update_engine
diff --git a/aosp/service_delegate_android_interface.h b/aosp/service_delegate_android_interface.h
new file mode 100644
index 0000000..3c28794
--- /dev/null
+++ b/aosp/service_delegate_android_interface.h
@@ -0,0 +1,127 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
+#define UPDATE_ENGINE_AOSP_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
+
+#include <inttypes.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <brillo/errors/error.h>
+
+namespace chromeos_update_engine {
+
+// See ServiceDelegateAndroidInterface.CleanupSuccessfulUpdate
+// Wraps a IUpdateEngineCallback binder object used specifically for
+// CleanupSuccessfulUpdate.
+class CleanupSuccessfulUpdateCallbackInterface {
+ public:
+  virtual ~CleanupSuccessfulUpdateCallbackInterface() {}
+  virtual void OnCleanupProgressUpdate(double progress) = 0;
+  virtual void OnCleanupComplete(int32_t error_code) = 0;
+  // Call RegisterForDeathNotifications on the internal binder object.
+  virtual void RegisterForDeathNotifications(base::Closure unbind) = 0;
+};
+
+// This class defines the interface exposed by the Android version of the
+// daemon service. This interface only includes the method calls that such
+// daemon exposes. For asynchronous events initiated by a class implementing
+// this interface see the ServiceObserverInterface class.
+class ServiceDelegateAndroidInterface {
+ public:
+  virtual ~ServiceDelegateAndroidInterface() = default;
+
+  // Start an update attempt to download an apply the provided |payload_url| if
+  // no other update is running. The extra |key_value_pair_headers| will be
+  // included when fetching the payload. Returns whether the update was started
+  // successfully, which means that no other update was running and the passed
+  // parameters were correct, but not necessarily that the update finished
+  // correctly.
+  virtual bool ApplyPayload(
+      const std::string& payload_url,
+      int64_t payload_offset,
+      int64_t payload_size,
+      const std::vector<std::string>& key_value_pair_headers,
+      brillo::ErrorPtr* error) = 0;
+
+  virtual bool ApplyPayload(
+      int fd,
+      int64_t payload_offset,
+      int64_t payload_size,
+      const std::vector<std::string>& key_value_pair_headers,
+      brillo::ErrorPtr* error) = 0;
+
+  // Suspend an ongoing update. Returns true if there was an update ongoing and
+  // it was suspended. In case of failure, it returns false and sets |error|
+  // accordingly.
+  virtual bool SuspendUpdate(brillo::ErrorPtr* error) = 0;
+
+  // Resumes an update suspended with SuspendUpdate(). The update can't be
+  // suspended after it finished and this method will fail in that case.
+  // Returns whether the resume operation was successful, which only implies
+  // that there was a suspended update. In case of error, returns false and sets
+  // |error| accordingly.
+  virtual bool ResumeUpdate(brillo::ErrorPtr* error) = 0;
+
+  // Cancel the ongoing update. The update could be running or suspended, but it
+  // can't be canceled after it was done. In case of error, returns false and
+  // sets |error| accordingly.
+  virtual bool CancelUpdate(brillo::ErrorPtr* error) = 0;
+
+  // Reset the already applied update back to an idle state. This method can
+  // only be called when no update attempt is going on, and it will reset the
+  // status back to idle, deleting the currently applied update if any. In case
+  // of error, returns false and sets |error| accordingly.
+  virtual bool ResetStatus(brillo::ErrorPtr* error) = 0;
+
+  // Verifies whether a payload (delegated by the payload metadata) can be
+  // applied to the current device. Returns whether the payload is applicable.
+  // In case of error, returns false and sets |error| accordingly.
+  virtual bool VerifyPayloadApplicable(const std::string& metadata_filename,
+                                       brillo::ErrorPtr* error) = 0;
+
+  // Allocates space for a payload.
+  // Returns 0 if space is successfully preallocated.
+  // Return non-zero if not enough space is not available; returned value is
+  // the total space required (in bytes) to be free on the device for this
+  // update to be applied, and |error| is unset.
+  // In case of error, returns 0, and sets |error| accordingly.
+  //
+  // This function may block for several minutes in the worst case.
+  virtual uint64_t AllocateSpaceForPayload(
+      const std::string& metadata_filename,
+      const std::vector<std::string>& key_value_pair_headers,
+      brillo::ErrorPtr* error) = 0;
+
+  // Wait for merge to complete, then clean up merge after an update has been
+  // successful.
+  //
+  // This function returns immediately. Progress updates are provided in
+  // |callback|.
+  virtual void CleanupSuccessfulUpdate(
+      std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
+      brillo::ErrorPtr* error) = 0;
+
+ protected:
+  ServiceDelegateAndroidInterface() = default;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
diff --git a/aosp/sideload_main.cc b/aosp/sideload_main.cc
new file mode 100644
index 0000000..3cbc0c7
--- /dev/null
+++ b/aosp/sideload_main.cc
@@ -0,0 +1,203 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <xz.h>
+
+#include <string>
+#include <vector>
+
+#include <base/command_line.h>
+#include <base/strings/string_split.h>
+#include <base/strings/stringprintf.h>
+#include <brillo/asynchronous_signal_handler.h>
+#include <brillo/flag_helper.h>
+#include <brillo/message_loops/base_message_loop.h>
+#include <brillo/streams/file_stream.h>
+#include <brillo/streams/stream.h>
+
+#include "update_engine/aosp/update_attempter_android.h"
+#include "update_engine/common/boot_control.h"
+#include "update_engine/common/error_code_utils.h"
+#include "update_engine/common/hardware.h"
+#include "update_engine/common/logging.h"
+#include "update_engine/common/prefs.h"
+#include "update_engine/common/subprocess.h"
+#include "update_engine/common/terminator.h"
+#include "update_engine/common/utils.h"
+
+using std::string;
+using std::vector;
+using update_engine::UpdateEngineStatus;
+using update_engine::UpdateStatus;
+
+namespace chromeos_update_engine {
+namespace {
+
+class SideloadDaemonState : public DaemonStateInterface,
+                            public ServiceObserverInterface {
+ public:
+  explicit SideloadDaemonState(brillo::StreamPtr status_stream)
+      : status_stream_(std::move(status_stream)) {
+    // Add this class as the only observer.
+    observers_.insert(this);
+  }
+  ~SideloadDaemonState() override = default;
+
+  // DaemonStateInterface overrides.
+  bool StartUpdater() override { return true; }
+  void AddObserver(ServiceObserverInterface* observer) override {}
+  void RemoveObserver(ServiceObserverInterface* observer) override {}
+  const std::set<ServiceObserverInterface*>& service_observers() override {
+    return observers_;
+  }
+
+  // ServiceObserverInterface overrides.
+  void SendStatusUpdate(
+      const UpdateEngineStatus& update_engine_status) override {
+    UpdateStatus status = update_engine_status.status;
+    double progress = update_engine_status.progress;
+    if (status_ != status && (status == UpdateStatus::DOWNLOADING ||
+                              status == UpdateStatus::FINALIZING)) {
+      // Split the progress bar in two parts for the two stages DOWNLOADING and
+      // FINALIZING.
+      ReportStatus(base::StringPrintf(
+          "ui_print Step %d/2", status == UpdateStatus::DOWNLOADING ? 1 : 2));
+      ReportStatus(base::StringPrintf("progress 0.5 0"));
+    }
+    if (status_ != status || fabs(progress - progress_) > 0.005) {
+      ReportStatus(base::StringPrintf("set_progress %.lf", progress));
+    }
+    progress_ = progress;
+    status_ = status;
+  }
+
+  void SendPayloadApplicationComplete(ErrorCode error_code) override {
+    if (error_code != ErrorCode::kSuccess) {
+      ReportStatus(
+          base::StringPrintf("ui_print Error applying update: %d (%s)",
+                             error_code,
+                             utils::ErrorCodeToString(error_code).c_str()));
+    }
+    error_code_ = error_code;
+    brillo::MessageLoop::current()->BreakLoop();
+  }
+
+  // Getters.
+  UpdateStatus status() { return status_; }
+  ErrorCode error_code() { return error_code_; }
+
+ private:
+  // Report a status message in the status_stream_, if any. These messages
+  // should conform to the specification defined in the Android recovery.
+  void ReportStatus(const string& message) {
+    if (!status_stream_)
+      return;
+    string status_line = message + "\n";
+    status_stream_->WriteAllBlocking(
+        status_line.data(), status_line.size(), nullptr);
+  }
+
+  std::set<ServiceObserverInterface*> observers_;
+  brillo::StreamPtr status_stream_;
+
+  // The last status and error code reported.
+  UpdateStatus status_{UpdateStatus::IDLE};
+  ErrorCode error_code_{ErrorCode::kSuccess};
+  double progress_{-1.};
+};
+
+// Apply an update payload directly from the given payload URI.
+bool ApplyUpdatePayload(const string& payload,
+                        int64_t payload_offset,
+                        int64_t payload_size,
+                        const vector<string>& headers,
+                        int64_t status_fd) {
+  brillo::BaseMessageLoop loop;
+  loop.SetAsCurrent();
+
+  // Setup the subprocess handler.
+  brillo::AsynchronousSignalHandler handler;
+  handler.Init();
+  Subprocess subprocess;
+  subprocess.Init(&handler);
+
+  SideloadDaemonState sideload_daemon_state(
+      brillo::FileStream::FromFileDescriptor(status_fd, true, nullptr));
+
+  // During the sideload we don't access the prefs persisted on disk but instead
+  // use a temporary memory storage.
+  MemoryPrefs prefs;
+
+  std::unique_ptr<BootControlInterface> boot_control =
+      boot_control::CreateBootControl();
+  if (!boot_control) {
+    LOG(ERROR) << "Error initializing the BootControlInterface.";
+    return false;
+  }
+
+  std::unique_ptr<HardwareInterface> hardware = hardware::CreateHardware();
+  if (!hardware) {
+    LOG(ERROR) << "Error initializing the HardwareInterface.";
+    return false;
+  }
+
+  UpdateAttempterAndroid update_attempter(
+      &sideload_daemon_state, &prefs, boot_control.get(), hardware.get());
+  update_attempter.Init();
+
+  TEST_AND_RETURN_FALSE(update_attempter.ApplyPayload(
+      payload, payload_offset, payload_size, headers, nullptr));
+
+  loop.Run();
+  return sideload_daemon_state.status() == UpdateStatus::UPDATED_NEED_REBOOT;
+}
+
+}  // namespace
+}  // namespace chromeos_update_engine
+
+int main(int argc, char** argv) {
+  DEFINE_string(payload,
+                "file:///data/payload.bin",
+                "The URI to the update payload to use.");
+  DEFINE_int64(
+      offset, 0, "The offset in the payload where the CrAU update starts. ");
+  DEFINE_int64(size,
+               0,
+               "The size of the CrAU part of the payload. If 0 is passed, it "
+               "will be autodetected.");
+  DEFINE_string(headers,
+                "",
+                "A list of key-value pairs, one element of the list per line.");
+  DEFINE_int64(status_fd, -1, "A file descriptor to notify the update status.");
+
+  chromeos_update_engine::Terminator::Init();
+  chromeos_update_engine::SetupLogging(true /* stderr */, false /* file */);
+  brillo::FlagHelper::Init(argc, argv, "Update Engine Sideload");
+
+  LOG(INFO) << "Update Engine Sideloading starting";
+
+  // xz-embedded requires to initialize its CRC-32 table once on startup.
+  xz_crc32_init();
+
+  vector<string> headers = base::SplitString(
+      FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+  if (!chromeos_update_engine::ApplyUpdatePayload(
+          FLAGS_payload, FLAGS_offset, FLAGS_size, headers, FLAGS_status_fd))
+    return 1;
+
+  return 0;
+}
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
new file mode 100644
index 0000000..57430fe
--- /dev/null
+++ b/aosp/update_attempter_android.cc
@@ -0,0 +1,1054 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/update_attempter_android.h"
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <utility>
+
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+#include <base/bind.h>
+#include <base/logging.h>
+#include <base/strings/string_number_conversions.h>
+#include <brillo/data_encoding.h>
+#include <brillo/message_loops/message_loop.h>
+#include <brillo/strings/string_utils.h>
+#include <log/log_safetynet.h>
+
+#include "update_engine/aosp/cleanup_previous_update_action.h"
+#include "update_engine/common/constants.h"
+#include "update_engine/common/daemon_state_interface.h"
+#include "update_engine/common/download_action.h"
+#include "update_engine/common/error_code_utils.h"
+#include "update_engine/common/file_fetcher.h"
+#include "update_engine/common/metrics_reporter_interface.h"
+#include "update_engine/common/network_selector.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/metrics_utils.h"
+#include "update_engine/payload_consumer/certificate_parser_interface.h"
+#include "update_engine/payload_consumer/delta_performer.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
+#include "update_engine/payload_consumer/file_descriptor_utils.h"
+#include "update_engine/payload_consumer/filesystem_verifier_action.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+#include "update_engine/payload_consumer/payload_metadata.h"
+#include "update_engine/payload_consumer/payload_verifier.h"
+#include "update_engine/payload_consumer/postinstall_runner_action.h"
+#include "update_engine/update_boot_flags_action.h"
+#include "update_engine/update_status_utils.h"
+
+#ifndef _UE_SIDELOAD
+// Do not include support for external HTTP(s) urls when building
+// update_engine_sideload.
+#include "update_engine/libcurl_http_fetcher.h"
+#endif
+
+using android::base::unique_fd;
+using base::Bind;
+using base::Time;
+using base::TimeDelta;
+using base::TimeTicks;
+using std::shared_ptr;
+using std::string;
+using std::vector;
+using update_engine::UpdateEngineStatus;
+
+namespace chromeos_update_engine {
+
+namespace {
+
+// Minimum threshold to broadcast an status update in progress and time.
+const double kBroadcastThresholdProgress = 0.01;  // 1%
+const int kBroadcastThresholdSeconds = 10;
+
+const char* const kErrorDomain = "update_engine";
+// TODO(deymo): Convert the different errors to a numeric value to report them
+// back on the service error.
+const char* const kGenericError = "generic_error";
+
+// Log and set the error on the passed ErrorPtr.
+bool LogAndSetError(brillo::ErrorPtr* error,
+                    const base::Location& location,
+                    const string& reason) {
+  brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason);
+  LOG(ERROR) << "Replying with failure: " << location.ToString() << ": "
+             << reason;
+  return false;
+}
+
+bool GetHeaderAsBool(const string& header, bool default_value) {
+  int value = 0;
+  if (base::StringToInt(header, &value) && (value == 0 || value == 1))
+    return value == 1;
+  return default_value;
+}
+
+bool ParseKeyValuePairHeaders(const vector<string>& key_value_pair_headers,
+                              std::map<string, string>* headers,
+                              brillo::ErrorPtr* error) {
+  for (const string& key_value_pair : key_value_pair_headers) {
+    string key;
+    string value;
+    if (!brillo::string_utils::SplitAtFirst(
+            key_value_pair, "=", &key, &value, false)) {
+      return LogAndSetError(
+          error, FROM_HERE, "Passed invalid header: " + key_value_pair);
+    }
+    if (!headers->emplace(key, value).second)
+      return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key);
+  }
+  return true;
+}
+
+// Unique identifier for the payload. An empty string means that the payload
+// can't be resumed.
+string GetPayloadId(const std::map<string, string>& headers) {
+  return (headers.count(kPayloadPropertyFileHash)
+              ? headers.at(kPayloadPropertyFileHash)
+              : "") +
+         (headers.count(kPayloadPropertyMetadataHash)
+              ? headers.at(kPayloadPropertyMetadataHash)
+              : "");
+}
+
+}  // namespace
+
+UpdateAttempterAndroid::UpdateAttempterAndroid(
+    DaemonStateInterface* daemon_state,
+    PrefsInterface* prefs,
+    BootControlInterface* boot_control,
+    HardwareInterface* hardware)
+    : daemon_state_(daemon_state),
+      prefs_(prefs),
+      boot_control_(boot_control),
+      hardware_(hardware),
+      processor_(new ActionProcessor()),
+      clock_(new Clock()) {
+  metrics_reporter_ = metrics::CreateMetricsReporter();
+  network_selector_ = network::CreateNetworkSelector();
+}
+
+UpdateAttempterAndroid::~UpdateAttempterAndroid() {
+  // Release ourselves as the ActionProcessor's delegate to prevent
+  // re-scheduling the updates due to the processing stopped.
+  processor_->set_delegate(nullptr);
+}
+
+void UpdateAttempterAndroid::Init() {
+  // In case of update_engine restart without a reboot we need to restore the
+  // reboot needed state.
+  if (UpdateCompletedOnThisBoot()) {
+    SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
+  } else {
+    SetStatusAndNotify(UpdateStatus::IDLE);
+    UpdatePrefsAndReportUpdateMetricsOnReboot();
+#ifdef _UE_SIDELOAD
+    LOG(INFO) << "Skip ScheduleCleanupPreviousUpdate in sideload because "
+              << "ApplyPayload will call it later.";
+#else
+    ScheduleCleanupPreviousUpdate();
+#endif
+  }
+}
+
+bool UpdateAttempterAndroid::ApplyPayload(
+    const string& payload_url,
+    int64_t payload_offset,
+    int64_t payload_size,
+    const vector<string>& key_value_pair_headers,
+    brillo::ErrorPtr* error) {
+  if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
+    return LogAndSetError(
+        error, FROM_HERE, "An update already applied, waiting for reboot");
+  }
+  if (processor_->IsRunning()) {
+    return LogAndSetError(
+        error, FROM_HERE, "Already processing an update, cancel it first.");
+  }
+  DCHECK(status_ == UpdateStatus::IDLE);
+
+  std::map<string, string> headers;
+  if (!ParseKeyValuePairHeaders(key_value_pair_headers, &headers, error)) {
+    return false;
+  }
+
+  string payload_id = GetPayloadId(headers);
+
+  // Setup the InstallPlan based on the request.
+  install_plan_ = InstallPlan();
+
+  install_plan_.download_url = payload_url;
+  install_plan_.version = "";
+  base_offset_ = payload_offset;
+  InstallPlan::Payload payload;
+  payload.size = payload_size;
+  if (!payload.size) {
+    if (!base::StringToUint64(headers[kPayloadPropertyFileSize],
+                              &payload.size)) {
+      payload.size = 0;
+    }
+  }
+  if (!brillo::data_encoding::Base64Decode(headers[kPayloadPropertyFileHash],
+                                           &payload.hash)) {
+    LOG(WARNING) << "Unable to decode base64 file hash: "
+                 << headers[kPayloadPropertyFileHash];
+  }
+  if (!base::StringToUint64(headers[kPayloadPropertyMetadataSize],
+                            &payload.metadata_size)) {
+    payload.metadata_size = 0;
+  }
+  // The |payload.type| is not used anymore since minor_version 3.
+  payload.type = InstallPayloadType::kUnknown;
+  install_plan_.payloads.push_back(payload);
+
+  // The |public_key_rsa| key would override the public key stored on disk.
+  install_plan_.public_key_rsa = "";
+
+  install_plan_.hash_checks_mandatory = hardware_->IsOfficialBuild();
+  install_plan_.is_resume = !payload_id.empty() &&
+                            DeltaPerformer::CanResumeUpdate(prefs_, payload_id);
+  if (!install_plan_.is_resume) {
+    // No need to reset dynamic_partititon_metadata_updated. If previous calls
+    // to AllocateSpaceForPayload uses the same payload_id, reuse preallocated
+    // space. Otherwise, DeltaPerformer re-allocates space when the payload is
+    // applied.
+    if (!DeltaPerformer::ResetUpdateProgress(
+            prefs_,
+            false /* quick */,
+            true /* skip_dynamic_partititon_metadata_updated */)) {
+      LOG(WARNING) << "Unable to reset the update progress.";
+    }
+    if (!prefs_->SetString(kPrefsUpdateCheckResponseHash, payload_id)) {
+      LOG(WARNING) << "Unable to save the update check response hash.";
+    }
+  }
+  install_plan_.source_slot = GetCurrentSlot();
+  install_plan_.target_slot = GetTargetSlot();
+
+  install_plan_.powerwash_required =
+      GetHeaderAsBool(headers[kPayloadPropertyPowerwash], false);
+
+  install_plan_.switch_slot_on_reboot =
+      GetHeaderAsBool(headers[kPayloadPropertySwitchSlotOnReboot], true);
+
+  install_plan_.run_post_install =
+      GetHeaderAsBool(headers[kPayloadPropertyRunPostInstall], true);
+
+  // Skip writing verity if we're resuming and verity has already been written.
+  install_plan_.write_verity = true;
+  if (install_plan_.is_resume && prefs_->Exists(kPrefsVerityWritten)) {
+    bool verity_written = false;
+    if (prefs_->GetBoolean(kPrefsVerityWritten, &verity_written) &&
+        verity_written) {
+      install_plan_.write_verity = false;
+    }
+  }
+
+  NetworkId network_id = kDefaultNetworkId;
+  if (!headers[kPayloadPropertyNetworkId].empty()) {
+    if (!base::StringToUint64(headers[kPayloadPropertyNetworkId],
+                              &network_id)) {
+      return LogAndSetError(
+          error,
+          FROM_HERE,
+          "Invalid network_id: " + headers[kPayloadPropertyNetworkId]);
+    }
+    if (!network_selector_->SetProcessNetwork(network_id)) {
+      return LogAndSetError(
+          error,
+          FROM_HERE,
+          "Unable to set network_id: " + headers[kPayloadPropertyNetworkId]);
+    }
+  }
+
+  LOG(INFO) << "Using this install plan:";
+  install_plan_.Dump();
+
+  HttpFetcher* fetcher = nullptr;
+  if (FileFetcher::SupportedUrl(payload_url)) {
+    DLOG(INFO) << "Using FileFetcher for file URL.";
+    fetcher = new FileFetcher();
+  } else {
+#ifdef _UE_SIDELOAD
+    LOG(FATAL) << "Unsupported sideload URI: " << payload_url;
+#else
+    LibcurlHttpFetcher* libcurl_fetcher =
+        new LibcurlHttpFetcher(&proxy_resolver_, hardware_);
+    libcurl_fetcher->set_server_to_check(ServerToCheck::kDownload);
+    fetcher = libcurl_fetcher;
+#endif  // _UE_SIDELOAD
+  }
+  // Setup extra headers.
+  if (!headers[kPayloadPropertyAuthorization].empty())
+    fetcher->SetHeader("Authorization", headers[kPayloadPropertyAuthorization]);
+  if (!headers[kPayloadPropertyUserAgent].empty())
+    fetcher->SetHeader("User-Agent", headers[kPayloadPropertyUserAgent]);
+
+  BuildUpdateActions(fetcher);
+
+  SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE);
+
+  UpdatePrefsOnUpdateStart(install_plan_.is_resume);
+  // TODO(xunchang) report the metrics for unresumable updates
+
+  ScheduleProcessingStart();
+  return true;
+}
+
+bool UpdateAttempterAndroid::ApplyPayload(
+    int fd,
+    int64_t payload_offset,
+    int64_t payload_size,
+    const vector<string>& key_value_pair_headers,
+    brillo::ErrorPtr* error) {
+  payload_fd_.reset(dup(fd));
+  const string payload_url = "fd://" + std::to_string(payload_fd_.get());
+
+  return ApplyPayload(
+      payload_url, payload_offset, payload_size, key_value_pair_headers, error);
+}
+
+bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) {
+  if (!processor_->IsRunning())
+    return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend.");
+  processor_->SuspendProcessing();
+  return true;
+}
+
+bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) {
+  if (!processor_->IsRunning())
+    return LogAndSetError(error, FROM_HERE, "No ongoing update to resume.");
+  processor_->ResumeProcessing();
+  return true;
+}
+
+bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) {
+  if (!processor_->IsRunning())
+    return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel.");
+  processor_->StopProcessing();
+  return true;
+}
+
+bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) {
+  LOG(INFO) << "Attempting to reset state from "
+            << UpdateStatusToString(status_) << " to UpdateStatus::IDLE";
+
+  switch (status_) {
+    case UpdateStatus::IDLE: {
+      if (!boot_control_->GetDynamicPartitionControl()->ResetUpdate(prefs_)) {
+        LOG(WARNING) << "Failed to reset snapshots. UpdateStatus is IDLE but"
+                     << "space might not be freed.";
+      }
+      return true;
+    }
+
+    case UpdateStatus::UPDATED_NEED_REBOOT: {
+      bool ret_value = true;
+
+      // Update the boot flags so the current slot has higher priority.
+      if (!boot_control_->SetActiveBootSlot(GetCurrentSlot()))
+        ret_value = false;
+
+      // Mark the current slot as successful again, since marking it as active
+      // may reset the successful bit. We ignore the result of whether marking
+      // the current slot as successful worked.
+      if (!boot_control_->MarkBootSuccessfulAsync(Bind([](bool successful) {})))
+        ret_value = false;
+
+      // Resets the warm reset property since we won't switch the slot.
+      hardware_->SetWarmReset(false);
+
+      // Remove update progress for DeltaPerformer and remove snapshots.
+      if (!boot_control_->GetDynamicPartitionControl()->ResetUpdate(prefs_))
+        ret_value = false;
+
+      // Remove the reboot marker so that if the machine is rebooted
+      // after resetting to idle state, it doesn't go back to
+      // UpdateStatus::UPDATED_NEED_REBOOT state.
+      if (!prefs_->Delete(kPrefsUpdateCompletedOnBootId))
+        ret_value = false;
+      ClearMetricsPrefs();
+
+      if (!ret_value) {
+        return LogAndSetError(
+            error, FROM_HERE, "Failed to reset the status to ");
+      }
+
+      SetStatusAndNotify(UpdateStatus::IDLE);
+      LOG(INFO) << "Reset status successful";
+      return true;
+    }
+
+    default:
+      return LogAndSetError(
+          error,
+          FROM_HERE,
+          "Reset not allowed in this state. Cancel the ongoing update first");
+  }
+}
+
+bool UpdateAttempterAndroid::VerifyPayloadParseManifest(
+    const std::string& metadata_filename,
+    DeltaArchiveManifest* manifest,
+    brillo::ErrorPtr* error) {
+  FileDescriptorPtr fd(new EintrSafeFileDescriptor);
+  if (!fd->Open(metadata_filename.c_str(), O_RDONLY)) {
+    return LogAndSetError(
+        error, FROM_HERE, "Failed to open " + metadata_filename);
+  }
+  brillo::Blob metadata(kMaxPayloadHeaderSize);
+  if (!fd->Read(metadata.data(), metadata.size())) {
+    return LogAndSetError(
+        error,
+        FROM_HERE,
+        "Failed to read payload header from " + metadata_filename);
+  }
+  ErrorCode errorcode;
+  PayloadMetadata payload_metadata;
+  if (payload_metadata.ParsePayloadHeader(metadata, &errorcode) !=
+      MetadataParseResult::kSuccess) {
+    return LogAndSetError(error,
+                          FROM_HERE,
+                          "Failed to parse payload header: " +
+                              utils::ErrorCodeToString(errorcode));
+  }
+  uint64_t metadata_size = payload_metadata.GetMetadataSize() +
+                           payload_metadata.GetMetadataSignatureSize();
+  if (metadata_size < kMaxPayloadHeaderSize ||
+      metadata_size >
+          static_cast<uint64_t>(utils::FileSize(metadata_filename))) {
+    return LogAndSetError(
+        error,
+        FROM_HERE,
+        "Invalid metadata size: " + std::to_string(metadata_size));
+  }
+  metadata.resize(metadata_size);
+  if (!fd->Read(metadata.data() + kMaxPayloadHeaderSize,
+                metadata.size() - kMaxPayloadHeaderSize)) {
+    return LogAndSetError(
+        error,
+        FROM_HERE,
+        "Failed to read metadata and signature from " + metadata_filename);
+  }
+  fd->Close();
+
+  auto payload_verifier = PayloadVerifier::CreateInstanceFromZipPath(
+      constants::kUpdateCertificatesPath);
+  if (!payload_verifier) {
+    return LogAndSetError(error,
+                          FROM_HERE,
+                          "Failed to create the payload verifier from " +
+                              std::string(constants::kUpdateCertificatesPath));
+  }
+  errorcode = payload_metadata.ValidateMetadataSignature(
+      metadata, "", *payload_verifier);
+  if (errorcode != ErrorCode::kSuccess) {
+    return LogAndSetError(error,
+                          FROM_HERE,
+                          "Failed to validate metadata signature: " +
+                              utils::ErrorCodeToString(errorcode));
+  }
+  if (!payload_metadata.GetManifest(metadata, manifest)) {
+    return LogAndSetError(error, FROM_HERE, "Failed to parse manifest.");
+  }
+
+  return true;
+}
+
+bool UpdateAttempterAndroid::VerifyPayloadApplicable(
+    const std::string& metadata_filename, brillo::ErrorPtr* error) {
+  DeltaArchiveManifest manifest;
+  TEST_AND_RETURN_FALSE(
+      VerifyPayloadParseManifest(metadata_filename, &manifest, error));
+
+  FileDescriptorPtr fd(new EintrSafeFileDescriptor);
+  ErrorCode errorcode;
+
+  BootControlInterface::Slot current_slot = GetCurrentSlot();
+  for (const PartitionUpdate& partition : manifest.partitions()) {
+    if (!partition.has_old_partition_info())
+      continue;
+    string partition_path;
+    if (!boot_control_->GetPartitionDevice(
+            partition.partition_name(), current_slot, &partition_path)) {
+      return LogAndSetError(
+          error,
+          FROM_HERE,
+          "Failed to get partition device for " + partition.partition_name());
+    }
+    if (!fd->Open(partition_path.c_str(), O_RDONLY)) {
+      return LogAndSetError(
+          error, FROM_HERE, "Failed to open " + partition_path);
+    }
+    for (const InstallOperation& operation : partition.operations()) {
+      if (!operation.has_src_sha256_hash())
+        continue;
+      brillo::Blob source_hash;
+      if (!fd_utils::ReadAndHashExtents(fd,
+                                        operation.src_extents(),
+                                        manifest.block_size(),
+                                        &source_hash)) {
+        return LogAndSetError(
+            error, FROM_HERE, "Failed to hash " + partition_path);
+      }
+      if (!DeltaPerformer::ValidateSourceHash(
+              source_hash, operation, fd, &errorcode)) {
+        return false;
+      }
+    }
+    fd->Close();
+  }
+  return true;
+}
+
+void UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor,
+                                            ErrorCode code) {
+  LOG(INFO) << "Processing Done.";
+
+  if (status_ == UpdateStatus::CLEANUP_PREVIOUS_UPDATE) {
+    TerminateUpdateAndNotify(code);
+    return;
+  }
+
+  switch (code) {
+    case ErrorCode::kSuccess:
+      // Update succeeded.
+      WriteUpdateCompletedMarker();
+      prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0);
+
+      LOG(INFO) << "Update successfully applied, waiting to reboot.";
+      break;
+
+    case ErrorCode::kFilesystemCopierError:
+    case ErrorCode::kNewRootfsVerificationError:
+    case ErrorCode::kNewKernelVerificationError:
+    case ErrorCode::kFilesystemVerifierError:
+    case ErrorCode::kDownloadStateInitializationError:
+      // Reset the ongoing update for these errors so it starts from the
+      // beginning next time.
+      DeltaPerformer::ResetUpdateProgress(prefs_, false);
+      LOG(INFO) << "Resetting update progress.";
+      break;
+
+    case ErrorCode::kPayloadTimestampError:
+      // SafetyNet logging, b/36232423
+      android_errorWriteLog(0x534e4554, "36232423");
+      break;
+
+    default:
+      // Ignore all other error codes.
+      break;
+  }
+
+  TerminateUpdateAndNotify(code);
+}
+
+void UpdateAttempterAndroid::ProcessingStopped(
+    const ActionProcessor* processor) {
+  TerminateUpdateAndNotify(ErrorCode::kUserCanceled);
+}
+
+void UpdateAttempterAndroid::ActionCompleted(ActionProcessor* processor,
+                                             AbstractAction* action,
+                                             ErrorCode code) {
+  // Reset download progress regardless of whether or not the download
+  // action succeeded.
+  const string type = action->Type();
+  if (type == CleanupPreviousUpdateAction::StaticType() ||
+      (type == NoOpAction::StaticType() &&
+       status_ == UpdateStatus::CLEANUP_PREVIOUS_UPDATE)) {
+    cleanup_previous_update_code_ = code;
+    NotifyCleanupPreviousUpdateCallbacksAndClear();
+  }
+  // download_progress_ is actually used by other actions, such as
+  // filesystem_verify_action. Therefore we always clear it.
+  download_progress_ = 0;
+  if (type == PostinstallRunnerAction::StaticType()) {
+    bool succeeded =
+        code == ErrorCode::kSuccess || code == ErrorCode::kUpdatedButNotActive;
+    prefs_->SetBoolean(kPrefsPostInstallSucceeded, succeeded);
+  }
+  if (code != ErrorCode::kSuccess) {
+    // If an action failed, the ActionProcessor will cancel the whole thing.
+    return;
+  }
+  if (type == UpdateBootFlagsAction::StaticType()) {
+    SetStatusAndNotify(UpdateStatus::CLEANUP_PREVIOUS_UPDATE);
+  }
+  if (type == DownloadAction::StaticType()) {
+    auto download_action = static_cast<DownloadAction*>(action);
+    install_plan_ = *download_action->install_plan();
+    SetStatusAndNotify(UpdateStatus::VERIFYING);
+  } else if (type == FilesystemVerifierAction::StaticType()) {
+    SetStatusAndNotify(UpdateStatus::FINALIZING);
+    prefs_->SetBoolean(kPrefsVerityWritten, true);
+  }
+}
+
+void UpdateAttempterAndroid::BytesReceived(uint64_t bytes_progressed,
+                                           uint64_t bytes_received,
+                                           uint64_t total) {
+  double progress = 0;
+  if (total)
+    progress = static_cast<double>(bytes_received) / static_cast<double>(total);
+  if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total) {
+    download_progress_ = progress;
+    SetStatusAndNotify(UpdateStatus::DOWNLOADING);
+  } else {
+    ProgressUpdate(progress);
+  }
+
+  // Update the bytes downloaded in prefs.
+  int64_t current_bytes_downloaded =
+      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_);
+  int64_t total_bytes_downloaded =
+      metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_);
+  prefs_->SetInt64(kPrefsCurrentBytesDownloaded,
+                   current_bytes_downloaded + bytes_progressed);
+  prefs_->SetInt64(kPrefsTotalBytesDownloaded,
+                   total_bytes_downloaded + bytes_progressed);
+}
+
+bool UpdateAttempterAndroid::ShouldCancel(ErrorCode* cancel_reason) {
+  // TODO(deymo): Notify the DownloadAction that it should cancel the update
+  // download.
+  return false;
+}
+
+void UpdateAttempterAndroid::DownloadComplete() {
+  // Nothing needs to be done when the download completes.
+}
+
+void UpdateAttempterAndroid::ProgressUpdate(double progress) {
+  // Self throttle based on progress. Also send notifications if progress is
+  // too slow.
+  if (progress == 1.0 ||
+      progress - download_progress_ >= kBroadcastThresholdProgress ||
+      TimeTicks::Now() - last_notify_time_ >=
+          TimeDelta::FromSeconds(kBroadcastThresholdSeconds)) {
+    download_progress_ = progress;
+    SetStatusAndNotify(status_);
+  }
+}
+
+void UpdateAttempterAndroid::OnVerifyProgressUpdate(double progress) {
+  assert(status_ == UpdateStatus::VERIFYING);
+  ProgressUpdate(progress);
+}
+
+void UpdateAttempterAndroid::ScheduleProcessingStart() {
+  LOG(INFO) << "Scheduling an action processor start.";
+  brillo::MessageLoop::current()->PostTask(
+      FROM_HERE,
+      Bind([](ActionProcessor* processor) { processor->StartProcessing(); },
+           base::Unretained(processor_.get())));
+}
+
+void UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) {
+  if (status_ == UpdateStatus::IDLE) {
+    LOG(ERROR) << "No ongoing update, but TerminatedUpdate() called.";
+    return;
+  }
+
+  if (status_ == UpdateStatus::CLEANUP_PREVIOUS_UPDATE) {
+    LOG(INFO) << "Terminating cleanup previous update.";
+    SetStatusAndNotify(UpdateStatus::IDLE);
+    for (auto observer : daemon_state_->service_observers())
+      observer->SendPayloadApplicationComplete(error_code);
+    return;
+  }
+
+  boot_control_->GetDynamicPartitionControl()->Cleanup();
+
+  download_progress_ = 0;
+  UpdateStatus new_status =
+      (error_code == ErrorCode::kSuccess ? UpdateStatus::UPDATED_NEED_REBOOT
+                                         : UpdateStatus::IDLE);
+  SetStatusAndNotify(new_status);
+  payload_fd_.reset();
+
+  // The network id is only applicable to one download attempt and once it's
+  // done the network id should not be re-used anymore.
+  if (!network_selector_->SetProcessNetwork(kDefaultNetworkId)) {
+    LOG(WARNING) << "Unable to unbind network.";
+  }
+
+  for (auto observer : daemon_state_->service_observers())
+    observer->SendPayloadApplicationComplete(error_code);
+
+  CollectAndReportUpdateMetricsOnUpdateFinished(error_code);
+  ClearMetricsPrefs();
+  if (error_code == ErrorCode::kSuccess) {
+    // We should only reset the PayloadAttemptNumber if the update succeeds, or
+    // we switch to a different payload.
+    prefs_->Delete(kPrefsPayloadAttemptNumber);
+    metrics_utils::SetSystemUpdatedMarker(clock_.get(), prefs_);
+    // Clear the total bytes downloaded if and only if the update succeeds.
+    prefs_->SetInt64(kPrefsTotalBytesDownloaded, 0);
+  }
+}
+
+void UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) {
+  status_ = status;
+  size_t payload_size =
+      install_plan_.payloads.empty() ? 0 : install_plan_.payloads[0].size;
+  UpdateEngineStatus status_to_send = {.status = status_,
+                                       .progress = download_progress_,
+                                       .new_size_bytes = payload_size};
+
+  for (auto observer : daemon_state_->service_observers()) {
+    observer->SendStatusUpdate(status_to_send);
+  }
+  last_notify_time_ = TimeTicks::Now();
+}
+
+void UpdateAttempterAndroid::BuildUpdateActions(HttpFetcher* fetcher) {
+  CHECK(!processor_->IsRunning());
+  processor_->set_delegate(this);
+
+  // Actions:
+  auto update_boot_flags_action =
+      std::make_unique<UpdateBootFlagsAction>(boot_control_);
+  auto cleanup_previous_update_action =
+      boot_control_->GetDynamicPartitionControl()
+          ->GetCleanupPreviousUpdateAction(boot_control_, prefs_, this);
+  auto install_plan_action = std::make_unique<InstallPlanAction>(install_plan_);
+  auto download_action =
+      std::make_unique<DownloadAction>(prefs_,
+                                       boot_control_,
+                                       hardware_,
+                                       nullptr,  // system_state, not used.
+                                       fetcher,  // passes ownership
+                                       true /* interactive */);
+  download_action->set_delegate(this);
+  download_action->set_base_offset(base_offset_);
+  auto filesystem_verifier_action = std::make_unique<FilesystemVerifierAction>(
+      boot_control_->GetDynamicPartitionControl());
+  auto postinstall_runner_action =
+      std::make_unique<PostinstallRunnerAction>(boot_control_, hardware_);
+  filesystem_verifier_action->set_delegate(this);
+  postinstall_runner_action->set_delegate(this);
+
+  // Bond them together. We have to use the leaf-types when calling
+  // BondActions().
+  BondActions(install_plan_action.get(), download_action.get());
+  BondActions(download_action.get(), filesystem_verifier_action.get());
+  BondActions(filesystem_verifier_action.get(),
+              postinstall_runner_action.get());
+
+  processor_->EnqueueAction(std::move(update_boot_flags_action));
+  processor_->EnqueueAction(std::move(cleanup_previous_update_action));
+  processor_->EnqueueAction(std::move(install_plan_action));
+  processor_->EnqueueAction(std::move(download_action));
+  processor_->EnqueueAction(std::move(filesystem_verifier_action));
+  processor_->EnqueueAction(std::move(postinstall_runner_action));
+}
+
+bool UpdateAttempterAndroid::WriteUpdateCompletedMarker() {
+  string boot_id;
+  TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
+  prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id);
+  return true;
+}
+
+bool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() {
+  // In case of an update_engine restart without a reboot, we stored the boot_id
+  // when the update was completed by setting a pref, so we can check whether
+  // the last update was on this boot or a previous one.
+  string boot_id;
+  TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
+
+  string update_completed_on_boot_id;
+  return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) &&
+          prefs_->GetString(kPrefsUpdateCompletedOnBootId,
+                            &update_completed_on_boot_id) &&
+          update_completed_on_boot_id == boot_id);
+}
+
+// Collect and report the android metrics when we terminate the update.
+void UpdateAttempterAndroid::CollectAndReportUpdateMetricsOnUpdateFinished(
+    ErrorCode error_code) {
+  int64_t attempt_number =
+      metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_);
+  PayloadType payload_type = kPayloadTypeFull;
+  int64_t payload_size = 0;
+  for (const auto& p : install_plan_.payloads) {
+    if (p.type == InstallPayloadType::kDelta)
+      payload_type = kPayloadTypeDelta;
+    payload_size += p.size;
+  }
+
+  metrics::AttemptResult attempt_result =
+      metrics_utils::GetAttemptResult(error_code);
+  Time boot_time_start = Time::FromInternalValue(
+      metrics_utils::GetPersistedValue(kPrefsUpdateBootTimestampStart, prefs_));
+  Time monotonic_time_start = Time::FromInternalValue(
+      metrics_utils::GetPersistedValue(kPrefsUpdateTimestampStart, prefs_));
+  TimeDelta duration = clock_->GetBootTime() - boot_time_start;
+  TimeDelta duration_uptime = clock_->GetMonotonicTime() - monotonic_time_start;
+
+  metrics_reporter_->ReportUpdateAttemptMetrics(
+      nullptr,  // system_state
+      static_cast<int>(attempt_number),
+      payload_type,
+      duration,
+      duration_uptime,
+      payload_size,
+      attempt_result,
+      error_code);
+
+  int64_t current_bytes_downloaded =
+      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_);
+  metrics_reporter_->ReportUpdateAttemptDownloadMetrics(
+      current_bytes_downloaded,
+      0,
+      DownloadSource::kNumDownloadSources,
+      metrics::DownloadErrorCode::kUnset,
+      metrics::ConnectionType::kUnset);
+
+  if (error_code == ErrorCode::kSuccess) {
+    int64_t reboot_count =
+        metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_);
+    string build_version;
+    prefs_->GetString(kPrefsPreviousVersion, &build_version);
+
+    // For android metrics, we only care about the total bytes downloaded
+    // for all sources; for now we assume the only download source is
+    // HttpsServer.
+    int64_t total_bytes_downloaded =
+        metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_);
+    int64_t num_bytes_downloaded[kNumDownloadSources] = {};
+    num_bytes_downloaded[DownloadSource::kDownloadSourceHttpsServer] =
+        total_bytes_downloaded;
+
+    int download_overhead_percentage = 0;
+    if (total_bytes_downloaded >= payload_size) {
+      CHECK_GT(payload_size, 0);
+      download_overhead_percentage =
+          (total_bytes_downloaded - payload_size) * 100ull / payload_size;
+    } else {
+      LOG(WARNING) << "Downloaded bytes " << total_bytes_downloaded
+                   << " is smaller than the payload size " << payload_size;
+    }
+
+    metrics_reporter_->ReportSuccessfulUpdateMetrics(
+        static_cast<int>(attempt_number),
+        0,  // update abandoned count
+        payload_type,
+        payload_size,
+        num_bytes_downloaded,
+        download_overhead_percentage,
+        duration,
+        duration_uptime,
+        static_cast<int>(reboot_count),
+        0);  // url_switch_count
+  }
+}
+
+void UpdateAttempterAndroid::UpdatePrefsAndReportUpdateMetricsOnReboot() {
+  string current_boot_id;
+  TEST_AND_RETURN(utils::GetBootId(&current_boot_id));
+  // Example: [ro.build.version.incremental]: [4292972]
+  string current_version =
+      android::base::GetProperty("ro.build.version.incremental", "");
+  TEST_AND_RETURN(!current_version.empty());
+
+  // If there's no record of previous version (e.g. due to a data wipe), we
+  // save the info of current boot and skip the metrics report.
+  if (!prefs_->Exists(kPrefsPreviousVersion)) {
+    prefs_->SetString(kPrefsBootId, current_boot_id);
+    prefs_->SetString(kPrefsPreviousVersion, current_version);
+    ClearMetricsPrefs();
+    return;
+  }
+  string previous_version;
+  // update_engine restarted under the same build.
+  // TODO(xunchang) identify and report rollback by checking UpdateMarker.
+  if (prefs_->GetString(kPrefsPreviousVersion, &previous_version) &&
+      previous_version == current_version) {
+    string last_boot_id;
+    bool is_reboot = prefs_->Exists(kPrefsBootId) &&
+                     (prefs_->GetString(kPrefsBootId, &last_boot_id) &&
+                      last_boot_id != current_boot_id);
+    // Increment the reboot number if |kPrefsNumReboots| exists. That pref is
+    // set when we start a new update.
+    if (is_reboot && prefs_->Exists(kPrefsNumReboots)) {
+      prefs_->SetString(kPrefsBootId, current_boot_id);
+      int64_t reboot_count =
+          metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_);
+      metrics_utils::SetNumReboots(reboot_count + 1, prefs_);
+    }
+    return;
+  }
+
+  // Now that the build version changes, report the update metrics.
+  // TODO(xunchang) check the build version is larger than the previous one.
+  prefs_->SetString(kPrefsBootId, current_boot_id);
+  prefs_->SetString(kPrefsPreviousVersion, current_version);
+
+  bool previous_attempt_exists = prefs_->Exists(kPrefsPayloadAttemptNumber);
+  // |kPrefsPayloadAttemptNumber| should be cleared upon successful update.
+  if (previous_attempt_exists) {
+    metrics_reporter_->ReportAbnormallyTerminatedUpdateAttemptMetrics();
+  }
+
+  metrics_utils::LoadAndReportTimeToReboot(
+      metrics_reporter_.get(), prefs_, clock_.get());
+  ClearMetricsPrefs();
+
+  // Also reset the update progress if the build version has changed.
+  if (!DeltaPerformer::ResetUpdateProgress(prefs_, false)) {
+    LOG(WARNING) << "Unable to reset the update progress.";
+  }
+}
+
+// Save the update start time. Reset the reboot count and attempt number if the
+// update isn't a resume; otherwise increment the attempt number.
+void UpdateAttempterAndroid::UpdatePrefsOnUpdateStart(bool is_resume) {
+  if (!is_resume) {
+    metrics_utils::SetNumReboots(0, prefs_);
+    metrics_utils::SetPayloadAttemptNumber(1, prefs_);
+  } else {
+    int64_t attempt_number =
+        metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_);
+    metrics_utils::SetPayloadAttemptNumber(attempt_number + 1, prefs_);
+  }
+  metrics_utils::SetUpdateTimestampStart(clock_->GetMonotonicTime(), prefs_);
+  metrics_utils::SetUpdateBootTimestampStart(clock_->GetBootTime(), prefs_);
+}
+
+void UpdateAttempterAndroid::ClearMetricsPrefs() {
+  CHECK(prefs_);
+  prefs_->Delete(kPrefsCurrentBytesDownloaded);
+  prefs_->Delete(kPrefsNumReboots);
+  prefs_->Delete(kPrefsSystemUpdatedMarker);
+  prefs_->Delete(kPrefsUpdateTimestampStart);
+  prefs_->Delete(kPrefsUpdateBootTimestampStart);
+}
+
+BootControlInterface::Slot UpdateAttempterAndroid::GetCurrentSlot() const {
+  return boot_control_->GetCurrentSlot();
+}
+
+BootControlInterface::Slot UpdateAttempterAndroid::GetTargetSlot() const {
+  return GetCurrentSlot() == 0 ? 1 : 0;
+}
+
+uint64_t UpdateAttempterAndroid::AllocateSpaceForPayload(
+    const std::string& metadata_filename,
+    const vector<string>& key_value_pair_headers,
+    brillo::ErrorPtr* error) {
+  DeltaArchiveManifest manifest;
+  if (!VerifyPayloadParseManifest(metadata_filename, &manifest, error)) {
+    return 0;
+  }
+  std::map<string, string> headers;
+  if (!ParseKeyValuePairHeaders(key_value_pair_headers, &headers, error)) {
+    return 0;
+  }
+
+  string payload_id = GetPayloadId(headers);
+  uint64_t required_size = 0;
+  if (!DeltaPerformer::PreparePartitionsForUpdate(prefs_,
+                                                  boot_control_,
+                                                  GetTargetSlot(),
+                                                  manifest,
+                                                  payload_id,
+                                                  &required_size)) {
+    if (required_size == 0) {
+      LogAndSetError(error, FROM_HERE, "Failed to allocate space for payload.");
+      return 0;
+    } else {
+      LOG(ERROR) << "Insufficient space for payload: " << required_size
+                 << " bytes";
+      return required_size;
+    }
+  }
+
+  LOG(INFO) << "Successfully allocated space for payload.";
+  return 0;
+}
+
+void UpdateAttempterAndroid::CleanupSuccessfulUpdate(
+    std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
+    brillo::ErrorPtr* error) {
+  if (cleanup_previous_update_code_.has_value()) {
+    LOG(INFO) << "CleanupSuccessfulUpdate has previously completed with "
+              << utils::ErrorCodeToString(*cleanup_previous_update_code_);
+    if (callback) {
+      callback->OnCleanupComplete(
+          static_cast<int32_t>(*cleanup_previous_update_code_));
+    }
+    return;
+  }
+  if (callback) {
+    auto callback_ptr = callback.get();
+    cleanup_previous_update_callbacks_.emplace_back(std::move(callback));
+    callback_ptr->RegisterForDeathNotifications(
+        base::Bind(&UpdateAttempterAndroid::RemoveCleanupPreviousUpdateCallback,
+                   base::Unretained(this),
+                   base::Unretained(callback_ptr)));
+  }
+  ScheduleCleanupPreviousUpdate();
+}
+
+void UpdateAttempterAndroid::ScheduleCleanupPreviousUpdate() {
+  // If a previous CleanupSuccessfulUpdate call has not finished, or an update
+  // is in progress, skip enqueueing the action.
+  if (processor_->IsRunning()) {
+    LOG(INFO) << "Already processing an update. CleanupPreviousUpdate should "
+              << "be done when the current update finishes.";
+    return;
+  }
+  LOG(INFO) << "Scheduling CleanupPreviousUpdateAction.";
+  auto action =
+      boot_control_->GetDynamicPartitionControl()
+          ->GetCleanupPreviousUpdateAction(boot_control_, prefs_, this);
+  processor_->EnqueueAction(std::move(action));
+  processor_->set_delegate(this);
+  SetStatusAndNotify(UpdateStatus::CLEANUP_PREVIOUS_UPDATE);
+  processor_->StartProcessing();
+}
+
+void UpdateAttempterAndroid::OnCleanupProgressUpdate(double progress) {
+  for (auto&& callback : cleanup_previous_update_callbacks_) {
+    callback->OnCleanupProgressUpdate(progress);
+  }
+}
+
+void UpdateAttempterAndroid::NotifyCleanupPreviousUpdateCallbacksAndClear() {
+  CHECK(cleanup_previous_update_code_.has_value());
+  for (auto&& callback : cleanup_previous_update_callbacks_) {
+    callback->OnCleanupComplete(
+        static_cast<int32_t>(*cleanup_previous_update_code_));
+  }
+  cleanup_previous_update_callbacks_.clear();
+}
+
+void UpdateAttempterAndroid::RemoveCleanupPreviousUpdateCallback(
+    CleanupSuccessfulUpdateCallbackInterface* callback) {
+  auto end_it =
+      std::remove_if(cleanup_previous_update_callbacks_.begin(),
+                     cleanup_previous_update_callbacks_.end(),
+                     [&](const auto& e) { return e.get() == callback; });
+  cleanup_previous_update_callbacks_.erase(
+      end_it, cleanup_previous_update_callbacks_.end());
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/update_attempter_android.h b/aosp/update_attempter_android.h
new file mode 100644
index 0000000..499f8f6
--- /dev/null
+++ b/aosp/update_attempter_android.h
@@ -0,0 +1,249 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_AOSP_UPDATE_ATTEMPTER_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_UPDATE_ATTEMPTER_ANDROID_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/unique_fd.h>
+#include <base/time/time.h>
+
+#include "update_engine/aosp/service_delegate_android_interface.h"
+#include "update_engine/client_library/include/update_engine/update_status.h"
+#include "update_engine/common/action_processor.h"
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/clock.h"
+#include "update_engine/common/daemon_state_interface.h"
+#include "update_engine/common/download_action.h"
+#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/metrics_reporter_interface.h"
+#include "update_engine/common/network_selector_interface.h"
+#include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/service_observer_interface.h"
+#include "update_engine/metrics_utils.h"
+#include "update_engine/payload_consumer/filesystem_verifier_action.h"
+#include "update_engine/payload_consumer/postinstall_runner_action.h"
+
+namespace chromeos_update_engine {
+
+class UpdateAttempterAndroid
+    : public ServiceDelegateAndroidInterface,
+      public ActionProcessorDelegate,
+      public DownloadActionDelegate,
+      public FilesystemVerifyDelegate,
+      public PostinstallRunnerAction::DelegateInterface,
+      public CleanupPreviousUpdateActionDelegateInterface {
+ public:
+  using UpdateStatus = update_engine::UpdateStatus;
+
+  UpdateAttempterAndroid(DaemonStateInterface* daemon_state,
+                         PrefsInterface* prefs,
+                         BootControlInterface* boot_control_,
+                         HardwareInterface* hardware_);
+  ~UpdateAttempterAndroid() override;
+
+  // Further initialization to be done post construction.
+  void Init();
+
+  // ServiceDelegateAndroidInterface overrides.
+  bool ApplyPayload(const std::string& payload_url,
+                    int64_t payload_offset,
+                    int64_t payload_size,
+                    const std::vector<std::string>& key_value_pair_headers,
+                    brillo::ErrorPtr* error) override;
+  bool ApplyPayload(int fd,
+                    int64_t payload_offset,
+                    int64_t payload_size,
+                    const std::vector<std::string>& key_value_pair_headers,
+                    brillo::ErrorPtr* error) override;
+  bool SuspendUpdate(brillo::ErrorPtr* error) override;
+  bool ResumeUpdate(brillo::ErrorPtr* error) override;
+  bool CancelUpdate(brillo::ErrorPtr* error) override;
+  bool ResetStatus(brillo::ErrorPtr* error) override;
+  bool VerifyPayloadApplicable(const std::string& metadata_filename,
+                               brillo::ErrorPtr* error) override;
+  uint64_t AllocateSpaceForPayload(
+      const std::string& metadata_filename,
+      const std::vector<std::string>& key_value_pair_headers,
+      brillo::ErrorPtr* error) override;
+  void CleanupSuccessfulUpdate(
+      std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
+      brillo::ErrorPtr* error) override;
+
+  // ActionProcessorDelegate methods:
+  void ProcessingDone(const ActionProcessor* processor,
+                      ErrorCode code) override;
+  void ProcessingStopped(const ActionProcessor* processor) override;
+  void ActionCompleted(ActionProcessor* processor,
+                       AbstractAction* action,
+                       ErrorCode code) override;
+
+  // DownloadActionDelegate overrides.
+  void BytesReceived(uint64_t bytes_progressed,
+                     uint64_t bytes_received,
+                     uint64_t total) override;
+  bool ShouldCancel(ErrorCode* cancel_reason) override;
+  void DownloadComplete() override;
+
+  // FilesystemVerifyDelegate overrides
+  void OnVerifyProgressUpdate(double progress) override;
+
+  // PostinstallRunnerAction::DelegateInterface
+  void ProgressUpdate(double progress) override;
+
+  // CleanupPreviousUpdateActionDelegateInterface
+  void OnCleanupProgressUpdate(double progress) override;
+
+ private:
+  friend class UpdateAttempterAndroidTest;
+
+  // Schedules an event loop callback to start the action processor. This is
+  // scheduled asynchronously to unblock the event loop.
+  void ScheduleProcessingStart();
+
+  // Notifies an update request completed with the given error |code| to all
+  // observers.
+  void TerminateUpdateAndNotify(ErrorCode error_code);
+
+  // Sets the status to the given |status| and notifies a status update to
+  // all observers.
+  void SetStatusAndNotify(UpdateStatus status);
+
+  // Helper method to construct the sequence of actions to be performed for
+  // applying an update using a given HttpFetcher. The ownership of |fetcher| is
+  // passed to this function.
+  void BuildUpdateActions(HttpFetcher* fetcher);
+
+  // Writes to the processing completed marker. Does nothing if
+  // |update_completed_marker_| is empty.
+  bool WriteUpdateCompletedMarker();
+
+  // Returns whether an update was completed in the current boot.
+  bool UpdateCompletedOnThisBoot();
+
+  // Prefs to use for metrics report
+  // |kPrefsPayloadAttemptNumber|: number of update attempts for the current
+  // payload_id.
+  // |KprefsNumReboots|: number of reboots when applying the current update.
+  // |kPrefsSystemUpdatedMarker|: end timestamp of the last successful update.
+  // |kPrefsUpdateTimestampStart|: start timestamp in monotonic time of the
+  // current update.
+  // |kPrefsUpdateBootTimestampStart|: start timestamp in boot time of
+  // the current update.
+  // |kPrefsCurrentBytesDownloaded|: number of bytes downloaded for the current
+  // payload_id.
+  // |kPrefsTotalBytesDownloaded|: number of bytes downloaded in total since
+  // the last successful update.
+
+  // Metrics report function to call:
+  //   |ReportUpdateAttemptMetrics|
+  //   |ReportSuccessfulUpdateMetrics|
+  // Prefs to update:
+  //   |kPrefsSystemUpdatedMarker|
+  void CollectAndReportUpdateMetricsOnUpdateFinished(ErrorCode error_code);
+
+  // Metrics report function to call:
+  //   |ReportAbnormallyTerminatedUpdateAttemptMetrics|
+  //   |ReportTimeToRebootMetrics|
+  // Prefs to update:
+  //   |kPrefsBootId|, |kPrefsPreviousVersion|
+  void UpdatePrefsAndReportUpdateMetricsOnReboot();
+
+  // Prefs to update:
+  //   |kPrefsPayloadAttemptNumber|, |kPrefsUpdateTimestampStart|,
+  //   |kPrefsUpdateBootTimestampStart|
+  void UpdatePrefsOnUpdateStart(bool is_resume);
+
+  // Prefs to delete:
+  //   |kPrefsNumReboots|, |kPrefsCurrentBytesDownloaded|
+  //   |kPrefsSystemUpdatedMarker|, |kPrefsUpdateTimestampStart|,
+  //   |kPrefsUpdateBootTimestampStart|
+  void ClearMetricsPrefs();
+
+  // Return source and target slots for update.
+  BootControlInterface::Slot GetCurrentSlot() const;
+  BootControlInterface::Slot GetTargetSlot() const;
+
+  // Helper of public VerifyPayloadApplicable. Return the parsed manifest in
+  // |manifest|.
+  static bool VerifyPayloadParseManifest(const std::string& metadata_filename,
+                                         DeltaArchiveManifest* manifest,
+                                         brillo::ErrorPtr* error);
+
+  // Enqueue and run a CleanupPreviousUpdateAction.
+  void ScheduleCleanupPreviousUpdate();
+
+  // Notify and clear |cleanup_previous_update_callbacks_|.
+  void NotifyCleanupPreviousUpdateCallbacksAndClear();
+
+  // Remove |callback| from |cleanup_previous_update_callbacks_|.
+  void RemoveCleanupPreviousUpdateCallback(
+      CleanupSuccessfulUpdateCallbackInterface* callback);
+
+  DaemonStateInterface* daemon_state_;
+
+  // DaemonStateAndroid pointers.
+  PrefsInterface* prefs_;
+  BootControlInterface* boot_control_;
+  HardwareInterface* hardware_;
+
+  // Last status notification timestamp used for throttling. Use monotonic
+  // TimeTicks to ensure that notifications are sent even if the system clock is
+  // set back in the middle of an update.
+  base::TimeTicks last_notify_time_;
+
+  // Only direct proxy supported.
+  DirectProxyResolver proxy_resolver_;
+
+  // The processor for running Actions.
+  std::unique_ptr<ActionProcessor> processor_;
+
+  // The InstallPlan used during the ongoing update.
+  InstallPlan install_plan_;
+
+  // For status:
+  UpdateStatus status_{UpdateStatus::IDLE};
+  double download_progress_{0.0};
+
+  // The offset in the payload file where the CrAU part starts.
+  int64_t base_offset_{0};
+
+  // Helper class to select the network to use during the update.
+  std::unique_ptr<NetworkSelectorInterface> network_selector_;
+
+  std::unique_ptr<ClockInterface> clock_;
+
+  std::unique_ptr<MetricsReporterInterface> metrics_reporter_;
+
+  ::android::base::unique_fd payload_fd_;
+
+  std::vector<std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface>>
+      cleanup_previous_update_callbacks_;
+  // Result of previous CleanupPreviousUpdateAction. Nullopt If
+  // CleanupPreviousUpdateAction has not been executed.
+  std::optional<ErrorCode> cleanup_previous_update_code_{std::nullopt};
+
+  DISALLOW_COPY_AND_ASSIGN(UpdateAttempterAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_AOSP_UPDATE_ATTEMPTER_ANDROID_H_
diff --git a/aosp/update_attempter_android_unittest.cc b/aosp/update_attempter_android_unittest.cc
new file mode 100644
index 0000000..bb44450
--- /dev/null
+++ b/aosp/update_attempter_android_unittest.cc
@@ -0,0 +1,228 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/aosp/update_attempter_android.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <android-base/properties.h>
+#include <base/time/time.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/aosp/daemon_state_android.h"
+#include "update_engine/common/fake_boot_control.h"
+#include "update_engine/common/fake_clock.h"
+#include "update_engine/common/fake_hardware.h"
+#include "update_engine/common/fake_prefs.h"
+#include "update_engine/common/mock_action_processor.h"
+#include "update_engine/common/mock_metrics_reporter.h"
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+
+using base::Time;
+using base::TimeDelta;
+using testing::_;
+using update_engine::UpdateStatus;
+
+namespace chromeos_update_engine {
+
+class UpdateAttempterAndroidTest : public ::testing::Test {
+ protected:
+  UpdateAttempterAndroidTest() = default;
+
+  void SetUp() override {
+    clock_ = new FakeClock();
+    metrics_reporter_ = new testing::NiceMock<MockMetricsReporter>();
+    update_attempter_android_.metrics_reporter_.reset(metrics_reporter_);
+    update_attempter_android_.clock_.reset(clock_);
+    update_attempter_android_.processor_.reset(
+        new testing::NiceMock<MockActionProcessor>());
+  }
+
+  void SetUpdateStatus(update_engine::UpdateStatus status) {
+    update_attempter_android_.status_ = status;
+  }
+
+  void AddPayload(InstallPlan::Payload&& payload) {
+    update_attempter_android_.install_plan_.payloads.push_back(
+        std::move(payload));
+  }
+
+  UpdateAttempterAndroid update_attempter_android_{
+      &daemon_state_, &prefs_, &boot_control_, &hardware_};
+
+  DaemonStateAndroid daemon_state_;
+  FakePrefs prefs_;
+  FakeBootControl boot_control_;
+  FakeHardware hardware_;
+
+  FakeClock* clock_;
+  testing::NiceMock<MockMetricsReporter>* metrics_reporter_;
+};
+
+TEST_F(UpdateAttempterAndroidTest, UpdatePrefsSameBuildVersionOnInit) {
+  std::string build_version =
+      android::base::GetProperty("ro.build.version.incremental", "");
+  prefs_.SetString(kPrefsPreviousVersion, build_version);
+  prefs_.SetString(kPrefsBootId, "oldboot");
+  prefs_.SetInt64(kPrefsNumReboots, 1);
+
+  EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(_)).Times(0);
+  update_attempter_android_.Init();
+
+  // Check that the boot_id and reboot_count are updated.
+  std::string boot_id;
+  utils::GetBootId(&boot_id);
+  EXPECT_TRUE(prefs_.Exists(kPrefsBootId));
+  std::string prefs_boot_id;
+  EXPECT_TRUE(prefs_.GetString(kPrefsBootId, &prefs_boot_id));
+  EXPECT_EQ(boot_id, prefs_boot_id);
+
+  EXPECT_TRUE(prefs_.Exists(kPrefsNumReboots));
+  int64_t reboot_count;
+  EXPECT_TRUE(prefs_.GetInt64(kPrefsNumReboots, &reboot_count));
+  EXPECT_EQ(2, reboot_count);
+}
+
+TEST_F(UpdateAttempterAndroidTest, UpdatePrefsBuildVersionChangeOnInit) {
+  prefs_.SetString(kPrefsPreviousVersion, "00001");  // Set the fake version
+  prefs_.SetInt64(kPrefsPayloadAttemptNumber, 1);
+  prefs_.SetInt64(kPrefsSystemUpdatedMarker, 23456);
+
+  EXPECT_CALL(*metrics_reporter_,
+              ReportAbnormallyTerminatedUpdateAttemptMetrics())
+      .Times(1);
+
+  Time now = Time::FromInternalValue(34456);
+  clock_->SetMonotonicTime(now);
+  TimeDelta duration = now - Time::FromInternalValue(23456);
+  EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(duration.InMinutes()))
+      .Times(1);
+
+  update_attempter_android_.Init();
+  // Check that we reset the metric prefs.
+  EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
+  EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
+  EXPECT_FALSE(prefs_.Exists(kPrefsSystemUpdatedMarker));
+  // PayloadAttemptNumber should persist across reboots.
+  EXPECT_TRUE(prefs_.Exists(kPrefsPayloadAttemptNumber));
+}
+
+TEST_F(UpdateAttempterAndroidTest, ReportMetricsOnUpdateTerminated) {
+  prefs_.SetInt64(kPrefsNumReboots, 3);
+  prefs_.SetInt64(kPrefsPayloadAttemptNumber, 2);
+  prefs_.SetString(kPrefsPreviousVersion, "56789");
+  prefs_.SetInt64(kPrefsUpdateBootTimestampStart, 10000);
+  prefs_.SetInt64(kPrefsUpdateTimestampStart, 12345);
+
+  Time boot_time = Time::FromInternalValue(22345);
+  Time up_time = Time::FromInternalValue(21345);
+  clock_->SetBootTime(boot_time);
+  clock_->SetMonotonicTime(up_time);
+  TimeDelta duration = boot_time - Time::FromInternalValue(10000);
+  TimeDelta duration_uptime = up_time - Time::FromInternalValue(12345);
+  EXPECT_CALL(
+      *metrics_reporter_,
+      ReportUpdateAttemptMetrics(_,
+                                 2,
+                                 _,
+                                 duration,
+                                 duration_uptime,
+                                 _,
+                                 metrics::AttemptResult::kUpdateSucceeded,
+                                 ErrorCode::kSuccess))
+      .Times(1);
+  EXPECT_CALL(*metrics_reporter_,
+              ReportSuccessfulUpdateMetrics(
+                  2, 0, _, 50, _, _, duration, duration_uptime, 3, _))
+      .Times(1);
+
+  // Adds a payload of 50 bytes to the InstallPlan.
+  InstallPlan::Payload payload;
+  payload.size = 50;
+  AddPayload(std::move(payload));
+  SetUpdateStatus(UpdateStatus::UPDATE_AVAILABLE);
+  update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
+
+  EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
+  EXPECT_FALSE(prefs_.Exists(kPrefsPayloadAttemptNumber));
+  EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
+  EXPECT_TRUE(prefs_.Exists(kPrefsSystemUpdatedMarker));
+}
+
+TEST_F(UpdateAttempterAndroidTest, ReportMetricsForBytesDownloaded) {
+  // Check both prefs are updated correctly.
+  update_attempter_android_.BytesReceived(20, 50, 200);
+  EXPECT_EQ(
+      20,
+      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
+  EXPECT_EQ(
+      20,
+      metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
+
+  EXPECT_CALL(*metrics_reporter_,
+              ReportUpdateAttemptDownloadMetrics(50, _, _, _, _))
+      .Times(1);
+  EXPECT_CALL(*metrics_reporter_,
+              ReportUpdateAttemptDownloadMetrics(40, _, _, _, _))
+      .Times(1);
+
+  int64_t total_bytes[kNumDownloadSources] = {};
+  total_bytes[kDownloadSourceHttpsServer] = 90;
+  EXPECT_CALL(*metrics_reporter_,
+              ReportSuccessfulUpdateMetrics(
+                  _,
+                  _,
+                  _,
+                  50,
+                  test_utils::DownloadSourceMatcher(total_bytes),
+                  80,
+                  _,
+                  _,
+                  _,
+                  _))
+      .Times(1);
+
+  // Adds a payload of 50 bytes to the InstallPlan.
+  InstallPlan::Payload payload;
+  payload.size = 50;
+  AddPayload(std::move(payload));
+
+  // The first update fails after receiving 50 bytes in total.
+  update_attempter_android_.BytesReceived(30, 50, 200);
+  update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kError);
+  EXPECT_EQ(
+      0,
+      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
+  EXPECT_EQ(
+      50,
+      metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
+
+  // The second update succeeds after receiving 40 bytes, which leads to a
+  // overhead of (90 - 50) / 50 = 80%.
+  update_attempter_android_.BytesReceived(40, 40, 50);
+  update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
+  // Both prefs should be cleared.
+  EXPECT_EQ(
+      0,
+      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
+  EXPECT_EQ(
+      0, metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
+}
+
+}  // namespace chromeos_update_engine
diff --git a/aosp/update_engine_client_android.cc b/aosp/update_engine_client_android.cc
new file mode 100644
index 0000000..1a68cf4
--- /dev/null
+++ b/aosp/update_engine_client_android.cc
@@ -0,0 +1,314 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <sysexits.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/callback.h>
+#include <base/command_line.h>
+#include <base/logging.h>
+#include <base/strings/string_split.h>
+#include <binder/IServiceManager.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <brillo/binder_watcher.h>
+#include <brillo/daemons/daemon.h>
+#include <brillo/flag_helper.h>
+#include <brillo/message_loops/message_loop.h>
+#include <brillo/syslog_logging.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+#include "android/os/BnUpdateEngineCallback.h"
+#include "android/os/IUpdateEngine.h"
+#include "update_engine/client_library/include/update_engine/update_status.h"
+#include "update_engine/common/error_code.h"
+#include "update_engine/common/error_code_utils.h"
+#include "update_engine/update_status_utils.h"
+
+using android::binder::Status;
+
+namespace chromeos_update_engine {
+namespace internal {
+
+class UpdateEngineClientAndroid : public brillo::Daemon {
+ public:
+  UpdateEngineClientAndroid(int argc, char** argv) : argc_(argc), argv_(argv) {}
+
+  int ExitWhenIdle(const Status& status);
+  int ExitWhenIdle(int return_code);
+
+ private:
+  class UECallback : public android::os::BnUpdateEngineCallback {
+   public:
+    explicit UECallback(UpdateEngineClientAndroid* client) : client_(client) {}
+
+    // android::os::BnUpdateEngineCallback overrides.
+    Status onStatusUpdate(int status_code, float progress) override;
+    Status onPayloadApplicationComplete(int error_code) override;
+
+   private:
+    UpdateEngineClientAndroid* client_;
+  };
+
+  int OnInit() override;
+
+  // Called whenever the UpdateEngine daemon dies.
+  void UpdateEngineServiceDied();
+
+  static std::vector<android::String16> ParseHeaders(const std::string& arg);
+
+  // Copy of argc and argv passed to main().
+  int argc_;
+  char** argv_;
+
+  android::sp<android::os::IUpdateEngine> service_;
+  android::sp<android::os::BnUpdateEngineCallback> callback_;
+  android::sp<android::os::BnUpdateEngineCallback> cleanup_callback_;
+
+  brillo::BinderWatcher binder_watcher_;
+};
+
+Status UpdateEngineClientAndroid::UECallback::onStatusUpdate(int status_code,
+                                                             float progress) {
+  update_engine::UpdateStatus status =
+      static_cast<update_engine::UpdateStatus>(status_code);
+  LOG(INFO) << "onStatusUpdate(" << UpdateStatusToString(status) << " ("
+            << status_code << "), " << progress << ")";
+  return Status::ok();
+}
+
+Status UpdateEngineClientAndroid::UECallback::onPayloadApplicationComplete(
+    int error_code) {
+  ErrorCode code = static_cast<ErrorCode>(error_code);
+  LOG(INFO) << "onPayloadApplicationComplete(" << utils::ErrorCodeToString(code)
+            << " (" << error_code << "))";
+  client_->ExitWhenIdle(
+      (code == ErrorCode::kSuccess || code == ErrorCode::kUpdatedButNotActive)
+          ? EX_OK
+          : 1);
+  return Status::ok();
+}
+
+int UpdateEngineClientAndroid::OnInit() {
+  int ret = Daemon::OnInit();
+  if (ret != EX_OK)
+    return ret;
+
+  DEFINE_bool(update, false, "Start a new update, if no update in progress.");
+  DEFINE_string(payload,
+                "http://127.0.0.1:8080/payload",
+                "The URI to the update payload to use.");
+  DEFINE_int64(offset,
+               0,
+               "The offset in the payload where the CrAU update starts. "
+               "Used when --update is passed.");
+  DEFINE_int64(size,
+               0,
+               "The size of the CrAU part of the payload. If 0 is passed, it "
+               "will be autodetected. Used when --update is passed.");
+  DEFINE_string(headers,
+                "",
+                "A list of key-value pairs, one element of the list per line. "
+                "Used when --update or --allocate is passed.");
+
+  DEFINE_bool(verify,
+              false,
+              "Given payload metadata, verify if the payload is applicable.");
+  DEFINE_bool(allocate, false, "Given payload metadata, allocate space.");
+  DEFINE_string(metadata,
+                "/data/ota_package/metadata",
+                "The path to the update payload metadata. "
+                "Used when --verify or --allocate is passed.");
+
+  DEFINE_bool(suspend, false, "Suspend an ongoing update and exit.");
+  DEFINE_bool(resume, false, "Resume a suspended update.");
+  DEFINE_bool(cancel, false, "Cancel the ongoing update and exit.");
+  DEFINE_bool(reset_status, false, "Reset an already applied update and exit.");
+  DEFINE_bool(follow,
+              false,
+              "Follow status update changes until a final state is reached. "
+              "Exit status is 0 if the update succeeded, and 1 otherwise.");
+  DEFINE_bool(merge,
+              false,
+              "Wait for previous update to merge. "
+              "Only available after rebooting to new slot.");
+  // Boilerplate init commands.
+  base::CommandLine::Init(argc_, argv_);
+  brillo::FlagHelper::Init(argc_, argv_, "Android Update Engine Client");
+  if (argc_ == 1) {
+    LOG(ERROR) << "Nothing to do. Run with --help for help.";
+    return 1;
+  }
+
+  // Ensure there are no positional arguments.
+  const std::vector<std::string> positional_args =
+      base::CommandLine::ForCurrentProcess()->GetArgs();
+  if (!positional_args.empty()) {
+    LOG(ERROR) << "Found a positional argument '" << positional_args.front()
+               << "'. If you want to pass a value to a flag, pass it as "
+                  "--flag=value.";
+    return 1;
+  }
+
+  bool keep_running = false;
+  brillo::InitLog(brillo::kLogToStderr);
+
+  // Initialize a binder watcher early in the process before any interaction
+  // with the binder driver.
+  binder_watcher_.Init();
+
+  android::status_t status = android::getService(
+      android::String16("android.os.UpdateEngineService"), &service_);
+  if (status != android::OK) {
+    LOG(ERROR) << "Failed to get IUpdateEngine binder from service manager: "
+               << Status::fromStatusT(status).toString8();
+    return ExitWhenIdle(1);
+  }
+
+  if (FLAGS_suspend) {
+    return ExitWhenIdle(service_->suspend());
+  }
+
+  if (FLAGS_resume) {
+    return ExitWhenIdle(service_->resume());
+  }
+
+  if (FLAGS_cancel) {
+    return ExitWhenIdle(service_->cancel());
+  }
+
+  if (FLAGS_reset_status) {
+    return ExitWhenIdle(service_->resetStatus());
+  }
+
+  if (FLAGS_verify) {
+    bool applicable = false;
+    Status status = service_->verifyPayloadApplicable(
+        android::String16{FLAGS_metadata.data(), FLAGS_metadata.size()},
+        &applicable);
+    LOG(INFO) << "Payload is " << (applicable ? "" : "not ") << "applicable.";
+    return ExitWhenIdle(status);
+  }
+
+  if (FLAGS_allocate) {
+    auto headers = ParseHeaders(FLAGS_headers);
+    int64_t ret = 0;
+    Status status = service_->allocateSpaceForPayload(
+        android::String16{FLAGS_metadata.data(), FLAGS_metadata.size()},
+        headers,
+        &ret);
+    if (status.isOk()) {
+      if (ret == 0) {
+        LOG(INFO) << "Successfully allocated space for payload.";
+      } else {
+        LOG(INFO) << "Insufficient space; required " << ret << " bytes.";
+      }
+    } else {
+      LOG(INFO) << "Allocation failed.";
+    }
+    return ExitWhenIdle(status);
+  }
+
+  if (FLAGS_merge) {
+    // Register a callback object with the service.
+    cleanup_callback_ = new UECallback(this);
+    Status status = service_->cleanupSuccessfulUpdate(cleanup_callback_);
+    if (!status.isOk()) {
+      LOG(ERROR) << "Failed to call cleanupSuccessfulUpdate.";
+      return ExitWhenIdle(status);
+    }
+    keep_running = true;
+  }
+
+  if (FLAGS_follow) {
+    // Register a callback object with the service.
+    callback_ = new UECallback(this);
+    bool bound;
+    if (!service_->bind(callback_, &bound).isOk() || !bound) {
+      LOG(ERROR) << "Failed to bind() the UpdateEngine daemon.";
+      return 1;
+    }
+    keep_running = true;
+  }
+
+  if (FLAGS_update) {
+    auto and_headers = ParseHeaders(FLAGS_headers);
+    Status status = service_->applyPayload(
+        android::String16{FLAGS_payload.data(), FLAGS_payload.size()},
+        FLAGS_offset,
+        FLAGS_size,
+        and_headers);
+    if (!status.isOk())
+      return ExitWhenIdle(status);
+  }
+
+  if (!keep_running)
+    return ExitWhenIdle(EX_OK);
+
+  // When following updates status changes, exit if the update_engine daemon
+  // dies.
+  android::BinderWrapper::Create();
+  android::BinderWrapper::Get()->RegisterForDeathNotifications(
+      android::os::IUpdateEngine::asBinder(service_),
+      base::Bind(&UpdateEngineClientAndroid::UpdateEngineServiceDied,
+                 base::Unretained(this)));
+
+  return EX_OK;
+}
+
+int UpdateEngineClientAndroid::ExitWhenIdle(const Status& status) {
+  if (status.isOk())
+    return ExitWhenIdle(EX_OK);
+  LOG(ERROR) << status.toString8();
+  return ExitWhenIdle(status.exceptionCode());
+}
+
+int UpdateEngineClientAndroid::ExitWhenIdle(int return_code) {
+  auto delayed_exit = base::Bind(
+      &Daemon::QuitWithExitCode, base::Unretained(this), return_code);
+  if (!brillo::MessageLoop::current()->PostTask(delayed_exit))
+    return 1;
+  return EX_OK;
+}
+
+void UpdateEngineClientAndroid::UpdateEngineServiceDied() {
+  LOG(ERROR) << "UpdateEngineService died.";
+  QuitWithExitCode(1);
+}
+
+std::vector<android::String16> UpdateEngineClientAndroid::ParseHeaders(
+    const std::string& arg) {
+  std::vector<std::string> headers = base::SplitString(
+      arg, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+  std::vector<android::String16> and_headers;
+  for (const auto& header : headers) {
+    and_headers.push_back(android::String16{header.data(), header.size()});
+  }
+  return and_headers;
+}
+
+}  // namespace internal
+}  // namespace chromeos_update_engine
+
+int main(int argc, char** argv) {
+  chromeos_update_engine::internal::UpdateEngineClientAndroid client(argc,
+                                                                     argv);
+  return client.Run();
+}
