Return correct error code when source operation hash mismatch.

Now it returns kDownloadStateInitializationError.

Test: delta update on a modified system.
Bug: 28769126

Change-Id: Iedfe938d6a0db8ae5ac137d073e61f550e3d71a9
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 09b19fb..541ee0f 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -290,7 +290,8 @@
              << next_operation_num_ - partition_first_op_num
              << " in partition \""
              << partitions_[current_partition_].partition_name() << "\"";
-  *error = ErrorCode::kDownloadOperationExecutionError;
+  if (*error == ErrorCode::kSuccess)
+    *error = ErrorCode::kDownloadOperationExecutionError;
   return false;
 }
 
@@ -725,13 +726,13 @@
         op_result = PerformBsdiffOperation(op);
         break;
       case InstallOperation::SOURCE_COPY:
-        op_result = PerformSourceCopyOperation(op);
+        op_result = PerformSourceCopyOperation(op, error);
         break;
       case InstallOperation::SOURCE_BSDIFF:
-        op_result = PerformSourceBsdiffOperation(op);
+        op_result = PerformSourceBsdiffOperation(op, error);
         break;
       case InstallOperation::IMGDIFF:
-        op_result = PerformImgdiffOperation(op);
+        op_result = PerformImgdiffOperation(op, error);
         break;
       default:
        op_result = false;
@@ -1045,9 +1046,10 @@
 }
 
 // Compare |calculated_hash| with source hash in |operation|, return false and
-// dump hash if don't match.
+// dump hash and set |error| if don't match.
 bool ValidateSourceHash(const brillo::Blob& calculated_hash,
-                        const InstallOperation& operation) {
+                        const InstallOperation& operation,
+                        ErrorCode* error) {
   brillo::Blob expected_source_hash(operation.src_sha256_hash().begin(),
                                     operation.src_sha256_hash().end());
   if (calculated_hash != expected_source_hash) {
@@ -1070,6 +1072,8 @@
     }
     LOG(ERROR) << "Operation source (offset:size) in blocks: "
                << base::JoinString(source_extents, ",");
+
+    *error = ErrorCode::kDownloadStateInitializationError;
     return false;
   }
   return true;
@@ -1078,7 +1082,7 @@
 }  // namespace
 
 bool DeltaPerformer::PerformSourceCopyOperation(
-    const InstallOperation& operation) {
+    const InstallOperation& operation, ErrorCode* error) {
   if (operation.has_src_length())
     TEST_AND_RETURN_FALSE(operation.src_length() % block_size_ == 0);
   if (operation.has_dst_length())
@@ -1131,7 +1135,7 @@
   if (operation.has_src_sha256_hash()) {
     TEST_AND_RETURN_FALSE(source_hasher.Finalize());
     TEST_AND_RETURN_FALSE(
-        ValidateSourceHash(source_hasher.raw_hash(), operation));
+        ValidateSourceHash(source_hasher.raw_hash(), operation, error));
   }
 
   DCHECK_EQ(bytes_read, static_cast<ssize_t>(blocks_to_read * block_size_));
@@ -1219,7 +1223,7 @@
 }
 
 bool DeltaPerformer::PerformSourceBsdiffOperation(
-    const InstallOperation& operation) {
+    const InstallOperation& operation, ErrorCode* error) {
   // Since we delete data off the beginning of the buffer as we use it,
   // the data we need should be exactly at the beginning of the buffer.
   TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
@@ -1249,7 +1253,7 @@
     }
     TEST_AND_RETURN_FALSE(source_hasher.Finalize());
     TEST_AND_RETURN_FALSE(
-        ValidateSourceHash(source_hasher.raw_hash(), operation));
+        ValidateSourceHash(source_hasher.raw_hash(), operation, error));
   }
 
   string input_positions;
@@ -1290,8 +1294,8 @@
   return true;
 }
 
-bool DeltaPerformer::PerformImgdiffOperation(
-    const InstallOperation& operation) {
+bool DeltaPerformer::PerformImgdiffOperation(const InstallOperation& operation,
+                                             ErrorCode* error) {
   // Since we delete data off the beginning of the buffer as we use it,
   // the data we need should be exactly at the beginning of the buffer.
   TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
@@ -1316,7 +1320,7 @@
   if (operation.has_src_sha256_hash()) {
     brillo::Blob src_hash;
     TEST_AND_RETURN_FALSE(HashCalculator::RawHashOfData(src_data, &src_hash));
-    TEST_AND_RETURN_FALSE(ValidateSourceHash(src_hash, operation));
+    TEST_AND_RETURN_FALSE(ValidateSourceHash(src_hash, operation, error));
   }
 
   vector<Extent> target_extents(operation.dst_extents().begin(),
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index 4da631f..7af59e6 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -244,13 +244,18 @@
   bool PerformInstallOperation(const InstallOperation& operation);
 
   // These perform a specific type of operation and return true on success.
+  // |error| will be set if source hash mismatch, otherwise |error| might not be
+  // set even if it fails.
   bool PerformReplaceOperation(const InstallOperation& operation);
   bool PerformZeroOrDiscardOperation(const InstallOperation& operation);
   bool PerformMoveOperation(const InstallOperation& operation);
   bool PerformBsdiffOperation(const InstallOperation& operation);
-  bool PerformSourceCopyOperation(const InstallOperation& operation);
-  bool PerformSourceBsdiffOperation(const InstallOperation& operation);
-  bool PerformImgdiffOperation(const InstallOperation& operation);
+  bool PerformSourceCopyOperation(const InstallOperation& operation,
+                                  ErrorCode* error);
+  bool PerformSourceBsdiffOperation(const InstallOperation& operation,
+                                    ErrorCode* error);
+  bool PerformImgdiffOperation(const InstallOperation& operation,
+                               ErrorCode* error);
 
   // Extracts the payload signature message from the blob on the |operation| if
   // the offset matches the one specified by the manifest. Returns whether the