update_engine: add logs and metrics for libcurl errors

curl_multi_perform may return code that is neither CURLM_OK or
CURLM_CALL_MULTI_PERFORM. When error returns we log them in
update_engine.log and send UMA metrics.

When update_engine does not get http response code from libcurl, we log
internal error code of the libcurl transfer for diagnosis.

Chrome CL to add the metrics enum is here: https://chromium-review.googlesource.com/c/chromium/src/+/1566150

BUG=chromium:927039
TEST=unittest

Change-Id: Ie8ce9dc0a6ce5ff6ffc2ff9425b652d125518558
Reviewed-on: https://chromium-review.googlesource.com/1562172
Commit-Ready: Sean Abraham <seanabraham@chromium.org>
Tested-by: Xiaochu Liu <xiaochu@chromium.org>
Reviewed-by: Xiaochu Liu <xiaochu@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/common/http_fetcher.h b/common/http_fetcher.h
index 2b4fc83..93b0e24 100644
--- a/common/http_fetcher.h
+++ b/common/http_fetcher.h
@@ -29,6 +29,7 @@
 
 #include "update_engine/common/http_common.h"
 #include "update_engine/common/proxy_resolver.h"
+#include "update_engine/metrics_constants.h"
 
 // This class is a simple wrapper around an HTTP library (libcurl). We can
 // easily mock out this interface for testing.
@@ -200,6 +201,13 @@
   // situations. It's OK to destroy the |fetcher| object in this callback.
   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) = 0;
   virtual void TransferTerminated(HttpFetcher* fetcher) {}
+
+  // This allows |HttpFetcher| to send UMA metrics for its internal states
+  // (unrecoverable libcurl internal error, etc.).
+  virtual void ReportUpdateCheckMetrics(
+      metrics::CheckResult result,
+      metrics::CheckReaction reaction,
+      metrics::DownloadErrorCode download_error_code) {}
 };
 
 }  // namespace chromeos_update_engine