Apply multiple payload in DownloadAction.

DownloadAction will now call DeltaPerformer once for each payload.

Bug: 36252799
Test: update two payload works!
Test: update_engine_unittest

Change-Id: Ibd4f3a4af9f701852f2c70b9384ca9d1fedacbeb
(cherry picked from commit 7bd9f0b95403664229b701a13dca03c31a46fb49)
diff --git a/mock_payload_state.h b/mock_payload_state.h
index 2f654c7..6dccc64 100644
--- a/mock_payload_state.h
+++ b/mock_payload_state.h
@@ -52,6 +52,7 @@
   MOCK_METHOD1(SetUsingP2PForSharing, void(bool value));
   MOCK_METHOD1(SetScatteringWaitPeriod, void(base::TimeDelta));
   MOCK_METHOD1(SetP2PUrl, void(const std::string&));
+  MOCK_METHOD0(NextPayload, bool());
 
   // Getters.
   MOCK_METHOD0(GetResponseSignature, std::string());
diff --git a/payload_consumer/download_action.cc b/payload_consumer/download_action.cc
index a8c987e..451c49e 100644
--- a/payload_consumer/download_action.cc
+++ b/payload_consumer/download_action.cc
@@ -185,15 +185,18 @@
                  << ". Proceeding with the update anyway.";
   }
 
-  if (writer_) {
+  download_active_ = true;
+  StartDownloading();
+}
+
+void DownloadAction::StartDownloading() {
+  if (writer_ && writer_ != delta_performer_.get()) {
     LOG(INFO) << "Using writer for test.";
   } else {
     delta_performer_.reset(new DeltaPerformer(
         prefs_, boot_control_, hardware_, delegate_, &install_plan_, payload_));
     writer_ = delta_performer_.get();
   }
-  download_active_ = true;
-
   if (system_state_ != nullptr) {
     const PayloadStateInterface* payload_state = system_state_->payload_state();
     string file_id = utils::CalculateP2PFileId(payload_->hash, payload_->size);
@@ -310,6 +313,15 @@
       // Delete p2p file, if applicable.
       if (!p2p_file_id_.empty())
         CloseP2PSharingFd(true);
+    } else if (payload_ < &install_plan_.payloads.back() &&
+               system_state_->payload_state()->NextPayload()) {
+      // Start downloading next payload.
+      payload_++;
+      DeltaPerformer::ResetUpdateProgress(prefs_, false);
+      install_plan_.download_url =
+          system_state_->payload_state()->GetCurrentUrl();
+      StartDownloading();
+      return;
     }
   }
 
diff --git a/payload_consumer/download_action.h b/payload_consumer/download_action.h
index 0bd0d88..48d6292 100644
--- a/payload_consumer/download_action.h
+++ b/payload_consumer/download_action.h
@@ -131,6 +131,9 @@
   // called or if CloseP2PSharingFd() has been called.
   void WriteToP2PFile(const void* data, size_t length, off_t file_offset);
 
+  // Start downloading the current payload using delta_performer.
+  void StartDownloading();
+
   // The InstallPlan passed in
   InstallPlan install_plan_;
 
diff --git a/payload_state.h b/payload_state.h
index 14f0f50..56e32fd 100644
--- a/payload_state.h
+++ b/payload_state.h
@@ -153,6 +153,14 @@
     return attempt_error_code_;
   }
 
+  bool NextPayload() override {
+    if (payload_index_ + 1 >= candidate_urls_.size())
+      return false;
+    payload_index_++;
+    url_index_ = 0;
+    return true;
+  }
+
  private:
   enum class AttemptType {
     kUpdate,
diff --git a/payload_state_interface.h b/payload_state_interface.h
index 68798ee..4aa25e3 100644
--- a/payload_state_interface.h
+++ b/payload_state_interface.h
@@ -193,6 +193,9 @@
   virtual void SetP2PUrl(const std::string& url) = 0;
   virtual std::string GetP2PUrl() const = 0;
   virtual ErrorCode GetAttemptErrorCode() const = 0;
+
+  // Switch to next payload.
+  virtual bool NextPayload() = 0;
 };
 
 }  // namespace chromeos_update_engine