Remove SystemState references from DeltaPerformer.

DeltaPerformer is used as part of the DownloadAction and had
references to the global SystemState. The common references to
BootControlInterface (to query the partitions based on the names
from the payload) and the HardwareInterface (for dev-mode bits) are
now referenced directly from the DeltaPerformer. The calls to
UpdateAttempter and PayloadState were moved to the
DownloadActionDelegate since these calls are received by classes
outside the payload_consumer.

Bug: 25773375
TEST=FEATURES=test emerge-link update_engine

Change-Id: Id2e81d5ccf835cad22f03b069c681dcce104c456
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 21d8e54..0949f3d 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -36,19 +36,18 @@
 
 #include "update_engine/common/constants.h"
 #include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/subprocess.h"
+#include "update_engine/common/terminator.h"
 #include "update_engine/payload_consumer/bzip_extent_writer.h"
+#include "update_engine/payload_consumer/download_action.h"
 #include "update_engine/payload_consumer/extent_writer.h"
 #if USE_MTD
 #include "update_engine/payload_consumer/mtd_file_descriptor.h"
 #endif
-#include "update_engine/common/prefs_interface.h"
-#include "update_engine/common/subprocess.h"
-#include "update_engine/common/terminator.h"
 #include "update_engine/payload_consumer/payload_constants.h"
 #include "update_engine/payload_consumer/payload_verifier.h"
 #include "update_engine/payload_consumer/xz_extent_writer.h"
-#include "update_engine/payload_state_interface.h"
-#include "update_engine/update_attempter.h"
 
 using google::protobuf::RepeatedPtrField;
 using std::min;
@@ -533,7 +532,6 @@
   *error = ErrorCode::kSuccess;
 
   const char* c_bytes = reinterpret_cast<const char*>(bytes);
-  system_state_->payload_state()->DownloadProgress(count);
 
   // Update the total byte downloaded count and the progress logs.
   total_bytes_received_ += count;
@@ -601,7 +599,7 @@
     // Check if we should cancel the current attempt for any reason.
     // In this case, *error will have already been populated with the reason
     // why we're canceling.
-    if (system_state_->update_attempter()->ShouldCancel(error))
+    if (download_delegate_ && download_delegate_->ShouldCancel(error))
       return false;
 
     // We know there are more operations to perform because we didn't reach the
@@ -803,7 +801,7 @@
     install_plan_->partitions.push_back(install_part);
   }
 
-  if (!install_plan_->LoadPartitionsFromSlots(system_state_->boot_control())) {
+  if (!install_plan_->LoadPartitionsFromSlots(boot_control_)) {
     LOG(ERROR) << "Unable to determine all the partition devices.";
     *error = ErrorCode::kInstallDeviceOpenError;
     return false;
@@ -1256,7 +1254,7 @@
 }
 
 bool DeltaPerformer::GetPublicKeyFromResponse(base::FilePath *out_tmp_key) {
-  if (system_state_->hardware()->IsOfficialBuild() ||
+  if (hardware_->IsOfficialBuild() ||
       utils::FileExists(public_key_path_.c_str()) ||
       install_plan_->public_key_rsa.empty())
     return false;
@@ -1547,8 +1545,10 @@
   // the one whose size matches the size mentioned in Omaha response. If any
   // errors happen after this, it's likely a problem with the payload itself or
   // the state of the system and not a problem with the URL or network.  So,
-  // indicate that to the payload state so that AU can backoff appropriately.
-  system_state_->payload_state()->DownloadComplete();
+  // indicate that to the download delegate so that AU can backoff
+  // appropriately.
+  if (download_delegate_)
+    download_delegate_->DownloadComplete();
 
   return ErrorCode::kSuccess;
 }
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index db938c1..47ecfd8 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -32,11 +32,13 @@
 #include "update_engine/payload_consumer/file_descriptor.h"
 #include "update_engine/payload_consumer/file_writer.h"
 #include "update_engine/payload_consumer/install_plan.h"
-#include "update_engine/system_state.h"
 #include "update_engine/update_metadata.pb.h"
 
 namespace chromeos_update_engine {
 
+class DownloadActionDelegate;
+class BootControlInterface;
+class HardwareInterface;
 class PrefsInterface;
 
 // This class performs the actions in a delta update synchronously. The delta
@@ -73,10 +75,14 @@
   static const unsigned kProgressOperationsWeight;
 
   DeltaPerformer(PrefsInterface* prefs,
-                 SystemState* system_state,
+                 BootControlInterface* boot_control,
+                 HardwareInterface* hardware,
+                 DownloadActionDelegate* download_delegate,
                  InstallPlan* install_plan)
       : prefs_(prefs),
-        system_state_(system_state),
+        boot_control_(boot_control),
+        hardware_(hardware),
+        download_delegate_(download_delegate),
         install_plan_(install_plan) {}
 
   // FileWriter's Write implementation where caller doesn't care about
@@ -288,8 +294,13 @@
   // Update Engine preference store.
   PrefsInterface* prefs_;
 
-  // Global context of the system.
-  SystemState* system_state_;
+  // BootControl and Hardware interface references.
+  BootControlInterface* boot_control_;
+  HardwareInterface* hardware_;
+
+  // The DownloadActionDelegate instance monitoring the DownloadAction, or a
+  // nullptr if not used.
+  DownloadActionDelegate* download_delegate_;
 
   // Install Plan based on Omaha Response.
   InstallPlan* install_plan_;
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index 728e12e..bcf7db2 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -31,11 +31,12 @@
 #include <gtest/gtest.h>
 
 #include "update_engine/common/constants.h"
+#include "update_engine/common/fake_boot_control.h"
 #include "update_engine/common/fake_hardware.h"
 #include "update_engine/common/mock_prefs.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
-#include "update_engine/fake_system_state.h"
+#include "update_engine/payload_consumer/mock_download_action.h"
 #include "update_engine/payload_consumer/payload_constants.h"
 #include "update_engine/payload_consumer/payload_verifier.h"
 #include "update_engine/payload_generator/delta_diff_generator.h"
@@ -88,9 +89,10 @@
   // The in-memory copy of delta file.
   brillo::Blob delta;
 
-  // The mock system state object with which we initialize the
-  // delta performer.
-  FakeSystemState fake_system_state;
+  // Mock and fake instances used by the delta performer.
+  FakeBootControl fake_boot_control_;
+  FakeHardware fake_hardware_;
+  MockDownloadActionDelegate mock_delegate_;
 };
 
 enum SignatureTest {
@@ -595,8 +597,6 @@
                                            nullptr));
     LOG(INFO) << "Metadata size: " << state->metadata_size;
 
-
-
     if (signature_test == kSignatureNone) {
       EXPECT_FALSE(manifest.has_signatures_offset());
       EXPECT_FALSE(manifest.has_signatures_size());
@@ -707,6 +707,9 @@
         .WillOnce(Return(true));
   }
 
+  EXPECT_CALL(state->mock_delegate_, ShouldCancel(_))
+      .WillRepeatedly(Return(false));
+
   // Update the A image in place.
   InstallPlan* install_plan = &state->install_plan;
   install_plan->hash_checks_mandatory = hash_checks_mandatory;
@@ -731,7 +734,9 @@
   EXPECT_FALSE(install_plan->metadata_signature.empty());
 
   *performer = new DeltaPerformer(&prefs,
-                                  &state->fake_system_state,
+                                  &state->fake_boot_control_,
+                                  &state->fake_hardware_,
+                                  &state->mock_delegate_,
                                   install_plan);
   EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
   (*performer)->set_public_key_path(kUnittestPublicKeyPath);
@@ -761,13 +766,13 @@
     target_kernel = state->old_kernel;
   }
 
-  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+  state->fake_boot_control_.SetPartitionDevice(
       kLegacyPartitionNameRoot, install_plan->source_slot, state->a_img);
-  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+  state->fake_boot_control_.SetPartitionDevice(
       kLegacyPartitionNameKernel, install_plan->source_slot, state->old_kernel);
-  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+  state->fake_boot_control_.SetPartitionDevice(
       kLegacyPartitionNameRoot, install_plan->target_slot, target_root);
-  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+  state->fake_boot_control_.SetPartitionDevice(
       kLegacyPartitionNameKernel, install_plan->target_slot, target_kernel);
 
   ErrorCode expected_error, actual_error;
@@ -837,8 +842,7 @@
   }
 
   int expected_times = (expected_result == ErrorCode::kSuccess) ? 1 : 0;
-  EXPECT_CALL(*(state->fake_system_state.mock_payload_state()),
-              DownloadComplete()).Times(expected_times);
+  EXPECT_CALL(state->mock_delegate_, DownloadComplete()).Times(expected_times);
 
   LOG(INFO) << "Verifying payload for expected result "
             << expected_result;
diff --git a/payload_consumer/delta_performer_unittest.cc b/payload_consumer/delta_performer_unittest.cc
index 25e4a55..97f7892 100644
--- a/payload_consumer/delta_performer_unittest.cc
+++ b/payload_consumer/delta_performer_unittest.cc
@@ -26,15 +26,17 @@
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
+#include <gmock/gmock.h>
 #include <google/protobuf/repeated_field.h>
 #include <gtest/gtest.h>
 
 #include "update_engine/common/constants.h"
+#include "update_engine/common/fake_boot_control.h"
 #include "update_engine/common/fake_hardware.h"
 #include "update_engine/common/fake_prefs.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
-#include "update_engine/fake_system_state.h"
+#include "update_engine/payload_consumer/mock_download_action.h"
 #include "update_engine/payload_consumer/payload_constants.h"
 #include "update_engine/payload_generator/bzip.h"
 #include "update_engine/payload_generator/extent_ranges.h"
@@ -48,6 +50,7 @@
 using std::vector;
 using test_utils::System;
 using test_utils::kRandomString;
+using testing::_;
 
 extern const char* kUnittestPrivateKeyPath;
 extern const char* kUnittestPublicKeyPath;
@@ -87,6 +90,8 @@
   void SetUp() override {
     install_plan_.source_slot = 0;
     install_plan_.target_slot = 1;
+    EXPECT_CALL(mock_delegate_, ShouldCancel(_))
+        .WillRepeatedly(testing::Return(false));
   }
 
   // Test helper placed where it can easily be friended from DeltaPerformer.
@@ -175,13 +180,13 @@
 
     // We installed the operations only in the rootfs partition, but the
     // delta performer needs to access all the partitions.
-    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+    fake_boot_control_.SetPartitionDevice(
         kLegacyPartitionNameRoot, install_plan_.target_slot, new_part);
-    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+    fake_boot_control_.SetPartitionDevice(
         kLegacyPartitionNameRoot, install_plan_.source_slot, source_path);
-    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+    fake_boot_control_.SetPartitionDevice(
         kLegacyPartitionNameKernel, install_plan_.target_slot, "/dev/null");
-    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+    fake_boot_control_.SetPartitionDevice(
         kLegacyPartitionNameKernel, install_plan_.source_slot, "/dev/null");
 
     EXPECT_EQ(expect_success,
@@ -302,8 +307,11 @@
   }
   FakePrefs prefs_;
   InstallPlan install_plan_;
-  FakeSystemState fake_system_state_;
-  DeltaPerformer performer_{&prefs_, &fake_system_state_, &install_plan_};
+  FakeBootControl fake_boot_control_;
+  FakeHardware fake_hardware_;
+  MockDownloadActionDelegate mock_delegate_;
+  DeltaPerformer performer_{
+      &prefs_, &fake_boot_control_, &fake_hardware_, &mock_delegate_, &install_plan_};
 };
 
 TEST_F(DeltaPerformerTest, FullPayloadWriteTest) {
@@ -325,6 +333,31 @@
   EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
 }
 
+TEST_F(DeltaPerformerTest, ShouldCancelTest) {
+  install_plan_.is_full_update = true;
+  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
+                                            std::end(kRandomString));
+  expected_data.resize(4096);  // block size
+  vector<AnnotatedOperation> aops;
+  AnnotatedOperation aop;
+  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
+  aop.op.set_data_offset(0);
+  aop.op.set_data_length(expected_data.size());
+  aop.op.set_type(InstallOperation::REPLACE);
+  aops.push_back(aop);
+
+  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false,
+      kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);
+
+  testing::Mock::VerifyAndClearExpectations(&mock_delegate_);
+  EXPECT_CALL(mock_delegate_, ShouldCancel(_))
+      .WillOnce(
+          testing::DoAll(testing::SetArgumentPointee<0>(ErrorCode::kError),
+                         testing::Return(true)));
+
+  ApplyPayload(payload_data, "/dev/null", false);
+}
+
 TEST_F(DeltaPerformerTest, ReplaceOperationTest) {
   brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
                                             std::end(kRandomString));
@@ -620,17 +653,6 @@
   EXPECT_LT(performer_.Close(), 0);
 }
 
-TEST_F(DeltaPerformerTest, WriteUpdatesPayloadState) {
-  EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
-              DownloadProgress(4)).Times(1);
-  EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
-              DownloadProgress(8)).Times(1);
-
-  EXPECT_TRUE(performer_.Write("junk", 4));
-  EXPECT_FALSE(performer_.Write("morejunk", 8));
-  EXPECT_LT(performer_.Close(), 0);
-}
-
 TEST_F(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
   DoMetadataSizeTest(0, 75456, true);
 }
@@ -694,8 +716,6 @@
   //  a. it's not an official build; and
   //  b. there is no key in the root filesystem.
 
-  FakeHardware* fake_hardware = fake_system_state_.fake_hardware();
-
   string temp_dir;
   EXPECT_TRUE(utils::MakeTempDirectory("PublicKeyFromResponseTests.XXXXXX",
                                        &temp_dir));
@@ -704,46 +724,46 @@
   EXPECT_EQ(0, System(base::StringPrintf("touch %s", existing_file.c_str())));
 
   // Non-official build, non-existing public-key, key in response -> true
-  fake_hardware->SetIsOfficialBuild(false);
+  fake_hardware_.SetIsOfficialBuild(false);
   performer_.public_key_path_ = non_existing_file;
   install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
   EXPECT_TRUE(performer_.GetPublicKeyFromResponse(&key_path));
   EXPECT_FALSE(key_path.empty());
   EXPECT_EQ(unlink(key_path.value().c_str()), 0);
   // Same with official build -> false
-  fake_hardware->SetIsOfficialBuild(true);
+  fake_hardware_.SetIsOfficialBuild(true);
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
 
   // Non-official build, existing public-key, key in response -> false
-  fake_hardware->SetIsOfficialBuild(false);
+  fake_hardware_.SetIsOfficialBuild(false);
   performer_.public_key_path_ = existing_file;
   install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
   // Same with official build -> false
-  fake_hardware->SetIsOfficialBuild(true);
+  fake_hardware_.SetIsOfficialBuild(true);
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
 
   // Non-official build, non-existing public-key, no key in response -> false
-  fake_hardware->SetIsOfficialBuild(false);
+  fake_hardware_.SetIsOfficialBuild(false);
   performer_.public_key_path_ = non_existing_file;
   install_plan_.public_key_rsa = "";
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
   // Same with official build -> false
-  fake_hardware->SetIsOfficialBuild(true);
+  fake_hardware_.SetIsOfficialBuild(true);
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
 
   // Non-official build, existing public-key, no key in response -> false
-  fake_hardware->SetIsOfficialBuild(false);
+  fake_hardware_.SetIsOfficialBuild(false);
   performer_.public_key_path_ = existing_file;
   install_plan_.public_key_rsa = "";
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
   // Same with official build -> false
-  fake_hardware->SetIsOfficialBuild(true);
+  fake_hardware_.SetIsOfficialBuild(true);
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
 
   // Non-official build, non-existing public-key, key in response
   // but invalid base64 -> false
-  fake_hardware->SetIsOfficialBuild(false);
+  fake_hardware_.SetIsOfficialBuild(false);
   performer_.public_key_path_ = non_existing_file;
   install_plan_.public_key_rsa = "not-valid-base64";
   EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
diff --git a/payload_consumer/download_action.cc b/payload_consumer/download_action.cc
index 58e29b2..cb404b8 100644
--- a/payload_consumer/download_action.cc
+++ b/payload_consumer/download_action.cc
@@ -182,7 +182,9 @@
     LOG(INFO) << "Using writer for test.";
   } else {
     delta_performer_.reset(new DeltaPerformer(prefs_,
-                                              system_state_,
+                                              system_state_->boot_control(),
+                                              system_state_->hardware(),
+                                              delegate_,
                                               &install_plan_));
     writer_ = delta_performer_.get();
   }
@@ -254,8 +256,10 @@
   }
 
   bytes_received_ += length;
-  if (delegate_ && download_active_)
-    delegate_->BytesReceived(bytes_received_, install_plan_.payload_size);
+  if (delegate_ && download_active_) {
+    delegate_->BytesReceived(
+        length, bytes_received_, install_plan_.payload_size);
+  }
   if (writer_ && !writer_->Write(bytes, length, &code_)) {
     LOG(ERROR) << "Error " << code_ << " in DeltaPerformer's Write method when "
                << "processing the received payload -- Terminating processing";
diff --git a/payload_consumer/download_action.h b/payload_consumer/download_action.h
index e57ffb3..300d97e 100644
--- a/payload_consumer/download_action.h
+++ b/payload_consumer/download_action.h
@@ -43,9 +43,23 @@
   virtual ~DownloadActionDelegate() = default;
 
   // Called periodically after bytes are received. This method will be invoked
-  // only if the DownloadAction is running. |bytes_received| is the number of
-  // bytes downloaded thus far. |total| is the number of bytes expected.
-  virtual void BytesReceived(uint64_t bytes_received, uint64_t total) = 0;
+  // only if the DownloadAction is running. |bytes_progressed| is the number of
+  // bytes downloaded since the last call of this method, |bytes_received|
+  // the number of bytes downloaded thus far and |total| is the number of bytes
+  // expected.
+  virtual void BytesReceived(uint64_t bytes_progressed,
+                             uint64_t bytes_received,
+                             uint64_t total) = 0;
+
+  // Returns whether the download should be canceled, in which case the
+  // |cancel_reason| error should be set to the reason why the download was
+  // canceled.
+  virtual bool ShouldCancel(ErrorCode* cancel_reason) = 0;
+
+  // Called once the complete payload has been downloaded. Note that any errors
+  // while applying or downloading the partial payload will result in this
+  // method not being called.
+  virtual void DownloadComplete() = 0;
 };
 
 class PrefsInterface;
diff --git a/payload_consumer/download_action_unittest.cc b/payload_consumer/download_action_unittest.cc
index 901dbd6..08053bf 100644
--- a/payload_consumer/download_action_unittest.cc
+++ b/payload_consumer/download_action_unittest.cc
@@ -41,6 +41,7 @@
 #include "update_engine/common/utils.h"
 #include "update_engine/fake_p2p_manager_configuration.h"
 #include "update_engine/fake_system_state.h"
+#include "update_engine/payload_consumer/mock_download_action.h"
 #include "update_engine/update_manager/fake_update_manager.h"
 
 namespace chromeos_update_engine {
@@ -60,10 +61,6 @@
 class DownloadActionTest : public ::testing::Test { };
 
 namespace {
-class DownloadActionDelegateMock : public DownloadActionDelegate {
- public:
-  MOCK_METHOD2(BytesReceived, void(uint64_t bytes_received, uint64_t total));
-};
 
 class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate {
  public:
@@ -172,14 +169,14 @@
   DownloadAction download_action(&prefs, &fake_system_state, http_fetcher);
   download_action.SetTestFileWriter(&writer);
   BondActions(&feeder_action, &download_action);
-  DownloadActionDelegateMock download_delegate;
+  MockDownloadActionDelegate download_delegate;
   if (use_download_delegate) {
     InSequence s;
     download_action.set_delegate(&download_delegate);
     if (data.size() > kMockHttpFetcherChunkSize)
       EXPECT_CALL(download_delegate,
-                  BytesReceived(1 + kMockHttpFetcherChunkSize, _));
-    EXPECT_CALL(download_delegate, BytesReceived(_, _)).Times(AtLeast(1));
+                  BytesReceived(_, 1 + kMockHttpFetcherChunkSize, _));
+    EXPECT_CALL(download_delegate, BytesReceived(_, _, _)).Times(AtLeast(1));
   }
   ErrorCode expected_code = ErrorCode::kSuccess;
   if (fail_write > 0)
@@ -286,10 +283,10 @@
                                                        data.size(),
                                                        nullptr));
     download_action.SetTestFileWriter(&writer);
-    DownloadActionDelegateMock download_delegate;
+    MockDownloadActionDelegate download_delegate;
     if (use_download_delegate) {
       download_action.set_delegate(&download_delegate);
-      EXPECT_CALL(download_delegate, BytesReceived(_, _)).Times(0);
+      EXPECT_CALL(download_delegate, BytesReceived(_, _, _)).Times(0);
     }
     TerminateEarlyTestProcessorDelegate delegate;
     ActionProcessor processor;
diff --git a/payload_consumer/mock_download_action.h b/payload_consumer/mock_download_action.h
new file mode 100644
index 0000000..3abb809
--- /dev/null
+++ b/payload_consumer/mock_download_action.h
@@ -0,0 +1,41 @@
+//
+// 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_PAYLOAD_CONSUMER_MOCK_DOWNLOAD_ACTION_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_MOCK_DOWNLOAD_ACTION_H_
+
+#include <stdint.h>
+
+#include <gmock/gmock.h>
+
+#include "update_engine/common/error_code.h"
+#include "update_engine/payload_consumer/download_action.h"
+
+namespace chromeos_update_engine {
+
+class MockDownloadActionDelegate : public DownloadActionDelegate {
+ public:
+  MOCK_METHOD3(BytesReceived,
+               void(uint64_t bytes_progressed,
+                    uint64_t bytes_received,
+                    uint64_t total));
+  MOCK_METHOD1(ShouldCancel, bool(ErrorCode* cancel_reason));
+  MOCK_METHOD0(DownloadComplete, void());
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_MOCK_DOWNLOAD_ACTION_H_