Merge changes from topic 'nyc-mr1-ue_sideload_recovery' into nyc-mr1-dev

* changes:
  Setup a temporary directory for update_engine_sideload.
  DO NOT MERGE: Make update_engine compile in the branch.
  New setting to mark postinstall as optional.
  Report the progress of the update when sideloading.
  Compile update_engine_sideload as a static recovery program.
  Remove libcurl support from update_engine_sideload.
  Build update_engine_sideload.
  Implement a memory-based Prefs class.
  Remove unused libbrillo-http dependency.
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index ae59034..a156132 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -28,6 +28,7 @@
 
 #include <base/files/file_util.h>
 #include <base/format_macros.h>
+#include <base/strings/string_number_conversions.h>
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
 #include <brillo/data_encoding.h>
@@ -277,9 +278,15 @@
   if (op_result)
     return true;
 
+  size_t partition_first_op_num =
+      current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0;
   LOG(ERROR) << "Failed to perform " << op_type_name << " operation "
-             << next_operation_num_;
-  *error = ErrorCode::kDownloadOperationExecutionError;
+             << next_operation_num_ << ", which is the operation "
+             << next_operation_num_ - partition_first_op_num
+             << " in partition \""
+             << partitions_[current_partition_].partition_name() << "\"";
+  if (*error == ErrorCode::kSuccess)
+    *error = ErrorCode::kDownloadOperationExecutionError;
   return false;
 }
 
@@ -714,10 +721,10 @@
         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;
       default:
        op_result = false;
@@ -1043,16 +1050,34 @@
 }
 
 // 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) {
-    LOG(ERROR) << "Hash verification failed. Expected hash = ";
-    utils::HexDumpVector(expected_source_hash);
-    LOG(ERROR) << "Calculated hash = ";
-    utils::HexDumpVector(calculated_hash);
+    LOG(ERROR) << "The hash of the source data on disk for this operation "
+               << "doesn't match the expected value. This could mean that the "
+               << "delta update payload was targeted for another version, or "
+               << "that the source partition was modified after it was "
+               << "installed, for example, by mounting a filesystem.";
+    LOG(ERROR) << "Expected:   sha256|hex = "
+               << base::HexEncode(expected_source_hash.data(),
+                                  expected_source_hash.size());
+    LOG(ERROR) << "Calculated: sha256|hex = "
+               << base::HexEncode(calculated_hash.data(),
+                                  calculated_hash.size());
+
+    vector<string> source_extents;
+    for (const Extent& ext : operation.src_extents()) {
+      source_extents.push_back(base::StringPrintf(
+          "%" PRIu64 ":%" PRIu64, ext.start_block(), ext.num_blocks()));
+    }
+    LOG(ERROR) << "Operation source (offset:size) in blocks: "
+               << base::JoinString(source_extents, ",");
+
+    *error = ErrorCode::kDownloadStateInitializationError;
     return false;
   }
   return true;
@@ -1061,7 +1086,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())
@@ -1114,7 +1139,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_));
@@ -1202,7 +1227,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());
@@ -1232,7 +1257,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;
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index 0a60020..fdfcb5b 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -250,12 +250,16 @@
   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 PerformSourceCopyOperation(const InstallOperation& operation,
+                                  ErrorCode* error);
+  bool PerformSourceBsdiffOperation(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