Move metrics from namespace to class

Add a new metrics reporter interface to handle the current metrics
report for omaha (with metricsd). This helps to add metrics logging
for android phone devices (using other libraries) in the future.

Also change the unit tests accordingly.

Test: unit tests pass for pico
Change-Id: I703c8b6353e4b38bc89d6a71f01623978cf7a549
diff --git a/fake_system_state.cc b/fake_system_state.cc
index d51f775..5abf71b 100644
--- a/fake_system_state.cc
+++ b/fake_system_state.cc
@@ -27,7 +27,7 @@
       clock_(&fake_clock_),
       connection_manager_(&mock_connection_manager_),
       hardware_(&fake_hardware_),
-      metrics_lib_(&mock_metrics_lib_),
+      metrics_reporter_(&mock_metrics_reporter_),
       prefs_(&mock_prefs_),
       powerwash_safe_prefs_(&mock_powerwash_safe_prefs_),
       payload_state_(&mock_payload_state_),
diff --git a/fake_system_state.h b/fake_system_state.h
index 2225933..37f2233 100644
--- a/fake_system_state.h
+++ b/fake_system_state.h
@@ -27,6 +27,7 @@
 #include "update_engine/common/fake_hardware.h"
 #include "update_engine/common/mock_prefs.h"
 #include "update_engine/mock_connection_manager.h"
+#include "update_engine/mock_metrics.h"
 #include "update_engine/mock_omaha_request_params.h"
 #include "update_engine/mock_p2p_manager.h"
 #include "update_engine/mock_payload_state.h"
@@ -66,8 +67,9 @@
 
   inline HardwareInterface* hardware() override { return hardware_; }
 
-  inline MetricsLibraryInterface* metrics_lib() override {
-    return metrics_lib_;
+  inline MetricsReporterInterface* metrics_reporter() override {
+    CHECK(metrics_reporter_ != nullptr);
+    return metrics_reporter_;
   }
 
   inline PrefsInterface* prefs() override { return prefs_; }
@@ -122,8 +124,9 @@
     hardware_ = hardware ? hardware : &fake_hardware_;
   }
 
-  inline void set_metrics_lib(MetricsLibraryInterface* metrics_lib) {
-    metrics_lib_ = metrics_lib ? metrics_lib : &mock_metrics_lib_;
+  inline void set_metrics_reporter(MetricsReporterInterface* metrics_reporter) {
+    metrics_reporter_ =
+        metrics_reporter ? metrics_reporter : &mock_metrics_reporter_;
   }
 
   inline void set_prefs(PrefsInterface* prefs) {
@@ -187,9 +190,9 @@
     return &fake_hardware_;
   }
 
-  inline testing::NiceMock<MetricsLibraryMock>* mock_metrics_lib() {
-    CHECK(metrics_lib_ == &mock_metrics_lib_);
-    return &mock_metrics_lib_;
+  inline testing::NiceMock<MockMetrics>* mock_metrics_reporter() {
+    CHECK(metrics_reporter_ == &mock_metrics_reporter_);
+    return &mock_metrics_reporter_;
   }
 
   inline testing::NiceMock<MockPrefs> *mock_prefs() {
@@ -233,7 +236,7 @@
   FakeClock fake_clock_;
   testing::NiceMock<MockConnectionManager> mock_connection_manager_;
   FakeHardware fake_hardware_;
-  testing::NiceMock<MetricsLibraryMock> mock_metrics_lib_;
+  testing::NiceMock<MockMetrics> mock_metrics_reporter_;
   testing::NiceMock<MockPrefs> mock_prefs_;
   testing::NiceMock<MockPrefs> mock_powerwash_safe_prefs_;
   testing::NiceMock<MockPayloadState> mock_payload_state_;
@@ -249,7 +252,7 @@
   ClockInterface* clock_;
   ConnectionManagerInterface* connection_manager_;
   HardwareInterface* hardware_;
-  MetricsLibraryInterface* metrics_lib_;
+  MetricsReporterInterface* metrics_reporter_;
   PrefsInterface* prefs_;
   PrefsInterface* powerwash_safe_prefs_;
   PayloadStateInterface* payload_state_;
diff --git a/metrics.cc b/metrics.cc
index 742ba7e..fcbe7e4 100644
--- a/metrics.cc
+++ b/metrics.cc
@@ -14,7 +14,7 @@
 // limitations under the License.
 //
 
-#include "update_engine/metrics.h"
+#include "update_engine/metrics_reporter_omaha.h"
 
 #include <string>
 
@@ -32,128 +32,127 @@
 
 namespace chromeos_update_engine {
 
-namespace metrics {
-
 // UpdateEngine.Daily.* metrics.
-const char kMetricDailyOSAgeDays[] = "UpdateEngine.Daily.OSAgeDays";
+constexpr char kMetricDailyOSAgeDays[] = "UpdateEngine.Daily.OSAgeDays";
 
 // UpdateEngine.Check.* metrics.
-const char kMetricCheckDownloadErrorCode[] =
+constexpr char kMetricCheckDownloadErrorCode[] =
     "UpdateEngine.Check.DownloadErrorCode";
-const char kMetricCheckReaction[] = "UpdateEngine.Check.Reaction";
-const char kMetricCheckResult[] = "UpdateEngine.Check.Result";
-const char kMetricCheckTimeSinceLastCheckMinutes[] =
+constexpr char kMetricCheckReaction[] = "UpdateEngine.Check.Reaction";
+constexpr char kMetricCheckResult[] = "UpdateEngine.Check.Result";
+constexpr char kMetricCheckTimeSinceLastCheckMinutes[] =
     "UpdateEngine.Check.TimeSinceLastCheckMinutes";
-const char kMetricCheckTimeSinceLastCheckUptimeMinutes[] =
+constexpr char kMetricCheckTimeSinceLastCheckUptimeMinutes[] =
     "UpdateEngine.Check.TimeSinceLastCheckUptimeMinutes";
 
 // UpdateEngine.Attempt.* metrics.
-const char kMetricAttemptNumber[] = "UpdateEngine.Attempt.Number";
-const char kMetricAttemptPayloadType[] =
-    "UpdateEngine.Attempt.PayloadType";
-const char kMetricAttemptPayloadSizeMiB[] =
+constexpr char kMetricAttemptNumber[] = "UpdateEngine.Attempt.Number";
+constexpr char kMetricAttemptPayloadType[] = "UpdateEngine.Attempt.PayloadType";
+constexpr char kMetricAttemptPayloadSizeMiB[] =
     "UpdateEngine.Attempt.PayloadSizeMiB";
-const char kMetricAttemptConnectionType[] =
+constexpr char kMetricAttemptConnectionType[] =
     "UpdateEngine.Attempt.ConnectionType";
-const char kMetricAttemptDurationMinutes[] =
+constexpr char kMetricAttemptDurationMinutes[] =
     "UpdateEngine.Attempt.DurationMinutes";
-const char kMetricAttemptDurationUptimeMinutes[] =
+constexpr char kMetricAttemptDurationUptimeMinutes[] =
     "UpdateEngine.Attempt.DurationUptimeMinutes";
-const char kMetricAttemptTimeSinceLastAttemptMinutes[] =
+constexpr char kMetricAttemptTimeSinceLastAttemptMinutes[] =
     "UpdateEngine.Attempt.TimeSinceLastAttemptMinutes";
-const char kMetricAttemptTimeSinceLastAttemptUptimeMinutes[] =
+constexpr char kMetricAttemptTimeSinceLastAttemptUptimeMinutes[] =
     "UpdateEngine.Attempt.TimeSinceLastAttemptUptimeMinutes";
-const char kMetricAttemptPayloadBytesDownloadedMiB[] =
+constexpr char kMetricAttemptPayloadBytesDownloadedMiB[] =
     "UpdateEngine.Attempt.PayloadBytesDownloadedMiB";
-const char kMetricAttemptPayloadDownloadSpeedKBps[] =
+constexpr char kMetricAttemptPayloadDownloadSpeedKBps[] =
     "UpdateEngine.Attempt.PayloadDownloadSpeedKBps";
-const char kMetricAttemptDownloadSource[] =
+constexpr char kMetricAttemptDownloadSource[] =
     "UpdateEngine.Attempt.DownloadSource";
-const char kMetricAttemptResult[] =
-    "UpdateEngine.Attempt.Result";
-const char kMetricAttemptInternalErrorCode[] =
+constexpr char kMetricAttemptResult[] = "UpdateEngine.Attempt.Result";
+constexpr char kMetricAttemptInternalErrorCode[] =
     "UpdateEngine.Attempt.InternalErrorCode";
-const char kMetricAttemptDownloadErrorCode[] =
+constexpr char kMetricAttemptDownloadErrorCode[] =
     "UpdateEngine.Attempt.DownloadErrorCode";
 
 // UpdateEngine.SuccessfulUpdate.* metrics.
-const char kMetricSuccessfulUpdateAttemptCount[] =
+constexpr char kMetricSuccessfulUpdateAttemptCount[] =
     "UpdateEngine.SuccessfulUpdate.AttemptCount";
-const char kMetricSuccessfulUpdateBytesDownloadedMiB[] =
+constexpr char kMetricSuccessfulUpdateBytesDownloadedMiB[] =
     "UpdateEngine.SuccessfulUpdate.BytesDownloadedMiB";
-const char kMetricSuccessfulUpdateDownloadOverheadPercentage[] =
+constexpr char kMetricSuccessfulUpdateDownloadOverheadPercentage[] =
     "UpdateEngine.SuccessfulUpdate.DownloadOverheadPercentage";
-const char kMetricSuccessfulUpdateDownloadSourcesUsed[] =
+constexpr char kMetricSuccessfulUpdateDownloadSourcesUsed[] =
     "UpdateEngine.SuccessfulUpdate.DownloadSourcesUsed";
-const char kMetricSuccessfulUpdatePayloadType[] =
+constexpr char kMetricSuccessfulUpdatePayloadType[] =
     "UpdateEngine.SuccessfulUpdate.PayloadType";
-const char kMetricSuccessfulUpdatePayloadSizeMiB[] =
+constexpr char kMetricSuccessfulUpdatePayloadSizeMiB[] =
     "UpdateEngine.SuccessfulUpdate.PayloadSizeMiB";
-const char kMetricSuccessfulUpdateRebootCount[] =
+constexpr char kMetricSuccessfulUpdateRebootCount[] =
     "UpdateEngine.SuccessfulUpdate.RebootCount";
-const char kMetricSuccessfulUpdateTotalDurationMinutes[] =
+constexpr char kMetricSuccessfulUpdateTotalDurationMinutes[] =
     "UpdateEngine.SuccessfulUpdate.TotalDurationMinutes";
-const char kMetricSuccessfulUpdateUpdatesAbandonedCount[] =
+constexpr char kMetricSuccessfulUpdateUpdatesAbandonedCount[] =
     "UpdateEngine.SuccessfulUpdate.UpdatesAbandonedCount";
-const char kMetricSuccessfulUpdateUrlSwitchCount[] =
+constexpr char kMetricSuccessfulUpdateUrlSwitchCount[] =
     "UpdateEngine.SuccessfulUpdate.UrlSwitchCount";
 
 // UpdateEngine.Rollback.* metric.
-const char kMetricRollbackResult[] = "UpdateEngine.Rollback.Result";
+constexpr char kMetricRollbackResult[] = "UpdateEngine.Rollback.Result";
 
 // UpdateEngine.CertificateCheck.* metrics.
-const char kMetricCertificateCheckUpdateCheck[] =
+constexpr char kMetricCertificateCheckUpdateCheck[] =
     "UpdateEngine.CertificateCheck.UpdateCheck";
-const char kMetricCertificateCheckDownload[] =
+constexpr char kMetricCertificateCheckDownload[] =
     "UpdateEngine.CertificateCheck.Download";
 
 // UpdateEngine.* metrics.
-const char kMetricFailedUpdateCount[] = "UpdateEngine.FailedUpdateCount";
-const char kMetricInstallDateProvisioningSource[] =
+constexpr char kMetricFailedUpdateCount[] = "UpdateEngine.FailedUpdateCount";
+constexpr char kMetricInstallDateProvisioningSource[] =
     "UpdateEngine.InstallDateProvisioningSource";
-const char kMetricTimeToRebootMinutes[] =
+constexpr char kMetricTimeToRebootMinutes[] =
     "UpdateEngine.TimeToRebootMinutes";
 
-void ReportDailyMetrics(SystemState *system_state,
-                        base::TimeDelta os_age) {
-  string metric = metrics::kMetricDailyOSAgeDays;
-  LOG(INFO) << "Uploading " << utils::FormatTimeDelta(os_age)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(
-      metric,
-      static_cast<int>(os_age.InDays()),
-      0,     // min: 0 days
-      6*30,  // max: 6 months (approx)
-      50);   // num_buckets
+void MetricsReporterOmaha::Initialize() {
+  metrics_lib_.Init();
 }
 
-void ReportUpdateCheckMetrics(SystemState *system_state,
-                              CheckResult result,
-                              CheckReaction reaction,
-                              DownloadErrorCode download_error_code) {
+void MetricsReporterOmaha::ReportDailyMetrics(base::TimeDelta os_age) {
+  string metric = kMetricDailyOSAgeDays;
+  LOG(INFO) << "Uploading " << utils::FormatTimeDelta(os_age) << " for metric "
+            << metric;
+  metrics_lib_.SendToUMA(metric,
+                         static_cast<int>(os_age.InDays()),
+                         0,       // min: 0 days
+                         6 * 30,  // max: 6 months (approx)
+                         50);     // num_buckets
+}
+
+void MetricsReporterOmaha::ReportUpdateCheckMetrics(
+    SystemState* system_state,
+    metrics::CheckResult result,
+    metrics::CheckReaction reaction,
+    metrics::DownloadErrorCode download_error_code) {
   string metric;
   int value;
   int max_value;
 
   if (result != metrics::CheckResult::kUnset) {
-    metric = metrics::kMetricCheckResult;
+    metric = kMetricCheckResult;
     value = static_cast<int>(result);
     max_value = static_cast<int>(metrics::CheckResult::kNumConstants) - 1;
     LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
-    system_state->metrics_lib()->SendEnumToUMA(metric, value, max_value);
+    metrics_lib_.SendEnumToUMA(metric, value, max_value);
   }
   if (reaction != metrics::CheckReaction::kUnset) {
-    metric = metrics::kMetricCheckReaction;
+    metric = kMetricCheckReaction;
     value = static_cast<int>(reaction);
     max_value = static_cast<int>(metrics::CheckReaction::kNumConstants) - 1;
     LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
-    system_state->metrics_lib()->SendEnumToUMA(metric, value, max_value);
+    metrics_lib_.SendEnumToUMA(metric, value, max_value);
   }
   if (download_error_code != metrics::DownloadErrorCode::kUnset) {
-    metric = metrics::kMetricCheckDownloadErrorCode;
+    metric = kMetricCheckDownloadErrorCode;
     value = static_cast<int>(download_error_code);
     LOG(INFO) << "Sending " << value << " for metric " << metric << " (sparse)";
-    system_state->metrics_lib()->SendSparseToUMA(metric, value);
+    metrics_lib_.SendSparseToUMA(metric, value);
   }
 
   base::TimeDelta time_since_last;
@@ -164,47 +163,43 @@
     metric = kMetricCheckTimeSinceLastCheckMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
               << " for metric " << metric;
-    system_state->metrics_lib()->SendToUMA(
-        metric,
-        time_since_last.InMinutes(),
-        0,         // min: 0 min
-        30*24*60,  // max: 30 days
-        50);       // num_buckets
+    metrics_lib_.SendToUMA(metric,
+                           time_since_last.InMinutes(),
+                           0,             // min: 0 min
+                           30 * 24 * 60,  // max: 30 days
+                           50);           // num_buckets
   }
 
   base::TimeDelta uptime_since_last;
   static int64_t uptime_since_last_storage = 0;
-  if (metrics_utils::MonotonicDurationHelper(system_state,
-                                             &uptime_since_last_storage,
-                                             &uptime_since_last)) {
+  if (metrics_utils::MonotonicDurationHelper(
+          system_state, &uptime_since_last_storage, &uptime_since_last)) {
     metric = kMetricCheckTimeSinceLastCheckUptimeMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
               << " for metric " << metric;
-    system_state->metrics_lib()->SendToUMA(
-        metric,
-        uptime_since_last.InMinutes(),
-        0,         // min: 0 min
-        30*24*60,  // max: 30 days
-        50);       // num_buckets
+    metrics_lib_.SendToUMA(metric,
+                           uptime_since_last.InMinutes(),
+                           0,             // min: 0 min
+                           30 * 24 * 60,  // max: 30 days
+                           50);           // num_buckets
   }
 }
 
-void ReportAbnormallyTerminatedUpdateAttemptMetrics(
-    SystemState *system_state) {
-
-  string metric = metrics::kMetricAttemptResult;
-  AttemptResult attempt_result = AttemptResult::kAbnormalTermination;
+void MetricsReporterOmaha::ReportAbnormallyTerminatedUpdateAttemptMetrics() {
+  string metric = kMetricAttemptResult;
+  metrics::AttemptResult attempt_result =
+      metrics::AttemptResult::kAbnormalTermination;
 
   LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendEnumToUMA(
+            << " for metric " << metric;
+  metrics_lib_.SendEnumToUMA(
       metric,
       static_cast<int>(attempt_result),
-      static_cast<int>(AttemptResult::kNumConstants));
+      static_cast<int>(metrics::AttemptResult::kNumConstants));
 }
 
-void ReportUpdateAttemptMetrics(
-    SystemState *system_state,
+void MetricsReporterOmaha::ReportUpdateAttemptMetrics(
+    SystemState* system_state,
     int attempt_number,
     PayloadType payload_type,
     base::TimeDelta duration,
@@ -213,107 +208,98 @@
     int64_t payload_bytes_downloaded,
     int64_t payload_download_speed_bps,
     DownloadSource download_source,
-    AttemptResult attempt_result,
+    metrics::AttemptResult attempt_result,
     ErrorCode internal_error_code,
-    DownloadErrorCode payload_download_error_code,
-    ConnectionType connection_type) {
-  string metric;
+    metrics::DownloadErrorCode payload_download_error_code,
+    metrics::ConnectionType connection_type) {
+  string metric = kMetricAttemptNumber;
+  LOG(INFO) << "Uploading " << attempt_number << " for metric " << metric;
+  metrics_lib_.SendToUMA(metric,
+                         attempt_number,
+                         0,    // min: 0 attempts
+                         49,   // max: 49 attempts
+                         50);  // num_buckets
 
-  metric = metrics::kMetricAttemptNumber;
-  LOG(INFO) << "Uploading " << attempt_number << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         attempt_number,
-                                         0,    // min: 0 attempts
-                                         49,   // max: 49 attempts
-                                         50);  // num_buckets
+  metric = kMetricAttemptPayloadType;
+  LOG(INFO) << "Uploading " << utils::ToString(payload_type) << " for metric "
+            << metric;
+  metrics_lib_.SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
 
-  metric = metrics::kMetricAttemptPayloadType;
-  LOG(INFO) << "Uploading " << utils::ToString(payload_type)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendEnumToUMA(metric,
-                                             payload_type,
-                                             kNumPayloadTypes);
-
-  metric = metrics::kMetricAttemptDurationMinutes;
+  metric = kMetricAttemptDurationMinutes;
   LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         duration.InMinutes(),
-                                         0,         // min: 0 min
-                                         10*24*60,  // max: 10 days
-                                         50);       // num_buckets
+            << " for metric " << metric;
+  metrics_lib_.SendToUMA(metric,
+                         duration.InMinutes(),
+                         0,             // min: 0 min
+                         10 * 24 * 60,  // max: 10 days
+                         50);           // num_buckets
 
-  metric = metrics::kMetricAttemptDurationUptimeMinutes;
+  metric = kMetricAttemptDurationUptimeMinutes;
   LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration_uptime)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         duration_uptime.InMinutes(),
-                                         0,         // min: 0 min
-                                         10*24*60,  // max: 10 days
-                                         50);       // num_buckets
+            << " for metric " << metric;
+  metrics_lib_.SendToUMA(metric,
+                         duration_uptime.InMinutes(),
+                         0,             // min: 0 min
+                         10 * 24 * 60,  // max: 10 days
+                         50);           // num_buckets
 
-  metric = metrics::kMetricAttemptPayloadSizeMiB;
+  metric = kMetricAttemptPayloadSizeMiB;
   int64_t payload_size_mib = payload_size / kNumBytesInOneMiB;
-  LOG(INFO) << "Uploading " << payload_size_mib << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         payload_size_mib,
-                                         0,     // min: 0 MiB
-                                         1024,  // max: 1024 MiB = 1 GiB
-                                         50);   // num_buckets
+  LOG(INFO) << "Uploading " << payload_size_mib << " for metric " << metric;
+  metrics_lib_.SendToUMA(metric,
+                         payload_size_mib,
+                         0,     // min: 0 MiB
+                         1024,  // max: 1024 MiB = 1 GiB
+                         50);   // num_buckets
 
-  metric = metrics::kMetricAttemptPayloadBytesDownloadedMiB;
+  metric = kMetricAttemptPayloadBytesDownloadedMiB;
   int64_t payload_bytes_downloaded_mib =
-       payload_bytes_downloaded / kNumBytesInOneMiB;
-  LOG(INFO) << "Uploading " << payload_bytes_downloaded_mib
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         payload_bytes_downloaded_mib,
-                                         0,     // min: 0 MiB
-                                         1024,  // max: 1024 MiB = 1 GiB
-                                         50);   // num_buckets
+      payload_bytes_downloaded / kNumBytesInOneMiB;
+  LOG(INFO) << "Uploading " << payload_bytes_downloaded_mib << " for metric "
+            << metric;
+  metrics_lib_.SendToUMA(metric,
+                         payload_bytes_downloaded_mib,
+                         0,     // min: 0 MiB
+                         1024,  // max: 1024 MiB = 1 GiB
+                         50);   // num_buckets
 
-  metric = metrics::kMetricAttemptPayloadDownloadSpeedKBps;
+  metric = kMetricAttemptPayloadDownloadSpeedKBps;
   int64_t payload_download_speed_kbps = payload_download_speed_bps / 1000;
-  LOG(INFO) << "Uploading " << payload_download_speed_kbps
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         payload_download_speed_kbps,
-                                         0,        // min: 0 kB/s
-                                         10*1000,  // max: 10000 kB/s = 10 MB/s
-                                         50);      // num_buckets
+  LOG(INFO) << "Uploading " << payload_download_speed_kbps << " for metric "
+            << metric;
+  metrics_lib_.SendToUMA(metric,
+                         payload_download_speed_kbps,
+                         0,          // min: 0 kB/s
+                         10 * 1000,  // max: 10000 kB/s = 10 MB/s
+                         50);        // num_buckets
 
-  metric = metrics::kMetricAttemptDownloadSource;
-  LOG(INFO) << "Uploading " << download_source
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendEnumToUMA(metric,
-                                             download_source,
-                                             kNumDownloadSources);
+  metric = kMetricAttemptDownloadSource;
+  LOG(INFO) << "Uploading " << download_source << " for metric " << metric;
+  metrics_lib_.SendEnumToUMA(metric, download_source, kNumDownloadSources);
 
-  metric = metrics::kMetricAttemptResult;
+  metric = kMetricAttemptResult;
   LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendEnumToUMA(
+            << " for metric " << metric;
+  metrics_lib_.SendEnumToUMA(
       metric,
       static_cast<int>(attempt_result),
-      static_cast<int>(AttemptResult::kNumConstants));
+      static_cast<int>(metrics::AttemptResult::kNumConstants));
 
   if (internal_error_code != ErrorCode::kSuccess) {
-    metric = metrics::kMetricAttemptInternalErrorCode;
-    LOG(INFO) << "Uploading " << internal_error_code
-              << " for metric " <<  metric;
-    system_state->metrics_lib()->SendEnumToUMA(
-        metric,
-        static_cast<int>(internal_error_code),
-        static_cast<int>(ErrorCode::kUmaReportedMax));
+    metric = kMetricAttemptInternalErrorCode;
+    LOG(INFO) << "Uploading " << internal_error_code << " for metric "
+              << metric;
+    metrics_lib_.SendEnumToUMA(metric,
+                               static_cast<int>(internal_error_code),
+                               static_cast<int>(ErrorCode::kUmaReportedMax));
   }
 
-  if (payload_download_error_code != DownloadErrorCode::kUnset) {
-    metric = metrics::kMetricAttemptDownloadErrorCode;
+  if (payload_download_error_code != metrics::DownloadErrorCode::kUnset) {
+    metric = kMetricAttemptDownloadErrorCode;
     LOG(INFO) << "Uploading " << static_cast<int>(payload_download_error_code)
-              << " for metric " <<  metric << " (sparse)";
-    system_state->metrics_lib()->SendSparseToUMA(
-        metric,
-        static_cast<int>(payload_download_error_code));
+              << " for metric " << metric << " (sparse)";
+    metrics_lib_.SendSparseToUMA(metric,
+                                 static_cast<int>(payload_download_error_code));
   }
 
   base::TimeDelta time_since_last;
@@ -324,62 +310,54 @@
     metric = kMetricAttemptTimeSinceLastAttemptMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
               << " for metric " << metric;
-    system_state->metrics_lib()->SendToUMA(
-        metric,
-        time_since_last.InMinutes(),
-        0,         // min: 0 min
-        30*24*60,  // max: 30 days
-        50);       // num_buckets
+    metrics_lib_.SendToUMA(metric,
+                           time_since_last.InMinutes(),
+                           0,             // min: 0 min
+                           30 * 24 * 60,  // max: 30 days
+                           50);           // num_buckets
   }
 
   static int64_t uptime_since_last_storage = 0;
   base::TimeDelta uptime_since_last;
-  if (metrics_utils::MonotonicDurationHelper(system_state,
-                                             &uptime_since_last_storage,
-                                             &uptime_since_last)) {
+  if (metrics_utils::MonotonicDurationHelper(
+          system_state, &uptime_since_last_storage, &uptime_since_last)) {
     metric = kMetricAttemptTimeSinceLastAttemptUptimeMinutes;
     LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
               << " for metric " << metric;
-    system_state->metrics_lib()->SendToUMA(
-        metric,
-        uptime_since_last.InMinutes(),
-        0,         // min: 0 min
-        30*24*60,  // max: 30 days
-        50);       // num_buckets
+    metrics_lib_.SendToUMA(metric,
+                           uptime_since_last.InMinutes(),
+                           0,             // min: 0 min
+                           30 * 24 * 60,  // max: 30 days
+                           50);           // num_buckets
   }
 
-  metric = metrics::kMetricAttemptConnectionType;
+  metric = kMetricAttemptConnectionType;
   LOG(INFO) << "Uploading " << static_cast<int>(connection_type)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendEnumToUMA(
+            << " for metric " << metric;
+  metrics_lib_.SendEnumToUMA(
       metric,
       static_cast<int>(connection_type),
-      static_cast<int>(ConnectionType::kNumConstants));
+      static_cast<int>(metrics::ConnectionType::kNumConstants));
 }
 
-
-void ReportSuccessfulUpdateMetrics(
-         SystemState *system_state,
-         int attempt_count,
-         int updates_abandoned_count,
-         PayloadType payload_type,
-         int64_t payload_size,
-         int64_t num_bytes_downloaded[kNumDownloadSources],
-         int download_overhead_percentage,
-         base::TimeDelta total_duration,
-         int reboot_count,
-         int url_switch_count) {
-  string metric;
-  int64_t mbs;
-
-  metric = kMetricSuccessfulUpdatePayloadSizeMiB;
-  mbs = payload_size / kNumBytesInOneMiB;
+void MetricsReporterOmaha::ReportSuccessfulUpdateMetrics(
+    int attempt_count,
+    int updates_abandoned_count,
+    PayloadType payload_type,
+    int64_t payload_size,
+    int64_t num_bytes_downloaded[kNumDownloadSources],
+    int download_overhead_percentage,
+    base::TimeDelta total_duration,
+    int reboot_count,
+    int url_switch_count) {
+  string metric = kMetricSuccessfulUpdatePayloadSizeMiB;
+  int64_t mbs = payload_size / kNumBytesInOneMiB;
   LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         mbs,
-                                         0,     // min: 0 MiB
-                                         1024,  // max: 1024 MiB = 1 GiB
-                                         50);   // num_buckets
+  metrics_lib_.SendToUMA(metric,
+                         mbs,
+                         0,     // min: 0 MiB
+                         1024,  // max: 1024 MiB = 1 GiB
+                         50);   // num_buckets
 
   int64_t total_bytes = 0;
   int download_sources_used = 0;
@@ -392,7 +370,7 @@
     // update. Otherwise we're going to end up with a lot of zero-byte
     // events in the histogram.
 
-    metric = metrics::kMetricSuccessfulUpdateBytesDownloadedMiB;
+    metric = kMetricSuccessfulUpdateBytesDownloadedMiB;
     if (i < kNumDownloadSources) {
       metric += utils::ToString(source);
       mbs = num_bytes_downloaded[i] / kNumBytesInOneMiB;
@@ -405,104 +383,93 @@
 
     if (mbs > 0) {
       LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
-      system_state->metrics_lib()->SendToUMA(metric,
-                                             mbs,
-                                             0,     // min: 0 MiB
-                                             1024,  // max: 1024 MiB = 1 GiB
-                                             50);   // num_buckets
+      metrics_lib_.SendToUMA(metric,
+                             mbs,
+                             0,     // min: 0 MiB
+                             1024,  // max: 1024 MiB = 1 GiB
+                             50);   // num_buckets
     }
   }
 
-  metric = metrics::kMetricSuccessfulUpdateDownloadSourcesUsed;
+  metric = kMetricSuccessfulUpdateDownloadSourcesUsed;
   LOG(INFO) << "Uploading 0x" << std::hex << download_sources_used
             << " (bit flags) for metric " << metric;
-  system_state->metrics_lib()->SendToUMA(
-      metric,
-      download_sources_used,
-      0,                               // min
-      (1 << kNumDownloadSources) - 1,  // max
-      1 << kNumDownloadSources);       // num_buckets
+  metrics_lib_.SendToUMA(metric,
+                         download_sources_used,
+                         0,                               // min
+                         (1 << kNumDownloadSources) - 1,  // max
+                         1 << kNumDownloadSources);       // num_buckets
 
-  metric = metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage;
-  LOG(INFO) << "Uploading " << download_overhead_percentage
-            << "% for metric " << metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         download_overhead_percentage,
-                                         0,     // min: 0% overhead
-                                         1000,  // max: 1000% overhead
-                                         50);   // num_buckets
+  metric = kMetricSuccessfulUpdateDownloadOverheadPercentage;
+  LOG(INFO) << "Uploading " << download_overhead_percentage << "% for metric "
+            << metric;
+  metrics_lib_.SendToUMA(metric,
+                         download_overhead_percentage,
+                         0,     // min: 0% overhead
+                         1000,  // max: 1000% overhead
+                         50);   // num_buckets
 
-  metric = metrics::kMetricSuccessfulUpdateUrlSwitchCount;
-  LOG(INFO) << "Uploading " << url_switch_count
-            << " (count) for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         url_switch_count,
-                                         0,    // min: 0 URL switches
-                                         49,   // max: 49 URL switches
-                                         50);  // num_buckets
+  metric = kMetricSuccessfulUpdateUrlSwitchCount;
+  LOG(INFO) << "Uploading " << url_switch_count << " (count) for metric "
+            << metric;
+  metrics_lib_.SendToUMA(metric,
+                         url_switch_count,
+                         0,    // min: 0 URL switches
+                         49,   // max: 49 URL switches
+                         50);  // num_buckets
 
-  metric = metrics::kMetricSuccessfulUpdateTotalDurationMinutes;
+  metric = kMetricSuccessfulUpdateTotalDurationMinutes;
   LOG(INFO) << "Uploading " << utils::FormatTimeDelta(total_duration)
-            << " for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(
-       metric,
-       static_cast<int>(total_duration.InMinutes()),
-       0,          // min: 0 min
-       365*24*60,  // max: 365 days ~= 1 year
-       50);        // num_buckets
+            << " for metric " << metric;
+  metrics_lib_.SendToUMA(metric,
+                         static_cast<int>(total_duration.InMinutes()),
+                         0,              // min: 0 min
+                         365 * 24 * 60,  // max: 365 days ~= 1 year
+                         50);            // num_buckets
 
-  metric = metrics::kMetricSuccessfulUpdateRebootCount;
+  metric = kMetricSuccessfulUpdateRebootCount;
   LOG(INFO) << "Uploading reboot count of " << reboot_count << " for metric "
-            <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         reboot_count,
-                                         0,    // min: 0 reboots
-                                         49,   // max: 49 reboots
-                                         50);  // num_buckets
+            << metric;
+  metrics_lib_.SendToUMA(metric,
+                         reboot_count,
+                         0,    // min: 0 reboots
+                         49,   // max: 49 reboots
+                         50);  // num_buckets
 
-  metric = metrics::kMetricSuccessfulUpdatePayloadType;
-  system_state->metrics_lib()->SendEnumToUMA(metric,
-                                             payload_type,
-                                             kNumPayloadTypes);
-  LOG(INFO) << "Uploading " << utils::ToString(payload_type)
-            << " for metric " <<  metric;
+  metric = kMetricSuccessfulUpdatePayloadType;
+  metrics_lib_.SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
+  LOG(INFO) << "Uploading " << utils::ToString(payload_type) << " for metric "
+            << metric;
 
-  metric = metrics::kMetricSuccessfulUpdateAttemptCount;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         attempt_count,
-                                         1,    // min: 1 attempt
-                                         50,   // max: 50 attempts
-                                         50);  // num_buckets
-  LOG(INFO) << "Uploading " << attempt_count
-            << " for metric " <<  metric;
+  metric = kMetricSuccessfulUpdateAttemptCount;
+  metrics_lib_.SendToUMA(metric,
+                         attempt_count,
+                         1,    // min: 1 attempt
+                         50,   // max: 50 attempts
+                         50);  // num_buckets
+  LOG(INFO) << "Uploading " << attempt_count << " for metric " << metric;
 
-  metric = metrics::kMetricSuccessfulUpdateUpdatesAbandonedCount;
-  LOG(INFO) << "Uploading " << updates_abandoned_count
-            << " (count) for metric " <<  metric;
-  system_state->metrics_lib()->SendToUMA(metric,
-                                         updates_abandoned_count,
-                                         0,    // min: 0 counts
-                                         49,   // max: 49 counts
-                                         50);  // num_buckets
+  metric = kMetricSuccessfulUpdateUpdatesAbandonedCount;
+  LOG(INFO) << "Uploading " << updates_abandoned_count << " (count) for metric "
+            << metric;
+  metrics_lib_.SendToUMA(metric,
+                         updates_abandoned_count,
+                         0,    // min: 0 counts
+                         49,   // max: 49 counts
+                         50);  // num_buckets
 }
 
-void ReportRollbackMetrics(SystemState *system_state,
-                           RollbackResult result) {
-  string metric;
-  int value;
-
-  metric = metrics::kMetricRollbackResult;
-  value = static_cast<int>(result);
+void MetricsReporterOmaha::ReportRollbackMetrics(
+    metrics::RollbackResult result) {
+  string metric = kMetricRollbackResult;
+  int value = static_cast<int>(result);
   LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
-  system_state->metrics_lib()->SendEnumToUMA(
-      metric,
-      value,
-      static_cast<int>(metrics::RollbackResult::kNumConstants));
+  metrics_lib_.SendEnumToUMA(
+      metric, value, static_cast<int>(metrics::RollbackResult::kNumConstants));
 }
 
-void ReportCertificateCheckMetrics(SystemState* system_state,
-                                   ServerToCheck server_to_check,
-                                   CertificateCheckResult result) {
+void MetricsReporterOmaha::ReportCertificateCheckMetrics(
+    ServerToCheck server_to_check, CertificateCheckResult result) {
   string metric;
   switch (server_to_check) {
     case ServerToCheck::kUpdate:
@@ -516,11 +483,41 @@
   }
   LOG(INFO) << "Uploading " << static_cast<int>(result) << " for metric "
             << metric;
-  system_state->metrics_lib()->SendEnumToUMA(
-      metric, static_cast<int>(result),
+  metrics_lib_.SendEnumToUMA(
+      metric,
+      static_cast<int>(result),
       static_cast<int>(CertificateCheckResult::kNumConstants));
 }
 
-}  // namespace metrics
+void MetricsReporterOmaha::ReportFailedUpdateCount(int target_attempt) {
+  string metric = kMetricFailedUpdateCount;
+  metrics_lib_.SendToUMA(metric,
+                         target_attempt,
+                         1,   // min value
+                         50,  // max value
+                         kNumDefaultUmaBuckets);
+
+  LOG(INFO) << "Uploading " << target_attempt << " (count) for metric "
+            << metric;
+}
+
+void MetricsReporterOmaha::ReportTimeToReboot(int time_to_reboot_minutes) {
+  string metric = kMetricTimeToRebootMinutes;
+  metrics_lib_.SendToUMA(metric,
+                         time_to_reboot_minutes,
+                         0,             // min: 0 minute
+                         30 * 24 * 60,  // max: 1 month (approx)
+                         kNumDefaultUmaBuckets);
+
+  LOG(INFO) << "Uploading " << time_to_reboot_minutes << " for metric "
+            << metric;
+}
+
+void MetricsReporterOmaha::ReportInstallDateProvisioningSource(int source,
+                                                               int max) {
+  metrics_lib_.SendEnumToUMA(kMetricInstallDateProvisioningSource,
+                             source,  // Sample.
+                             max);
+}
 
 }  // namespace chromeos_update_engine
diff --git a/metrics.h b/metrics.h
deleted file mode 100644
index 7c369ee..0000000
--- a/metrics.h
+++ /dev/null
@@ -1,321 +0,0 @@
-//
-// Copyright (C) 2014 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_METRICS_H_
-#define UPDATE_ENGINE_METRICS_H_
-
-#include <base/time/time.h>
-
-#include "update_engine/certificate_checker.h"
-#include "update_engine/common/constants.h"
-#include "update_engine/common/error_code.h"
-
-namespace chromeos_update_engine {
-
-class SystemState;
-
-namespace metrics {
-
-// UpdateEngine.Daily.* metrics.
-extern const char kMetricDailyOSAgeDays[];
-
-// UpdateEngine.Check.* metrics.
-extern const char kMetricCheckDownloadErrorCode[];
-extern const char kMetricCheckReaction[];
-extern const char kMetricCheckResult[];
-extern const char kMetricCheckTimeSinceLastCheckMinutes[];
-extern const char kMetricCheckTimeSinceLastCheckUptimeMinutes[];
-
-// UpdateEngine.Attempt.* metrics.
-extern const char kMetricAttemptNumber[];
-extern const char kMetricAttemptPayloadType[];
-extern const char kMetricAttemptPayloadSizeMiB[];
-extern const char kMetricAttemptConnectionType[];
-extern const char kMetricAttemptDurationMinutes[];
-extern const char kMetricAttemptDurationUptimeMinutes[];
-extern const char kMetricAttemptTimeSinceLastAttemptSeconds[];
-extern const char kMetricAttemptTimeSinceLastAttemptUptimeSeconds[];
-extern const char kMetricAttemptPayloadBytesDownloaded[];
-extern const char kMetricAttemptPayloadDownloadSpeedKBps[];
-extern const char kMetricAttemptDownloadSource[];
-extern const char kMetricAttemptResult[];
-extern const char kMetricAttemptInternalErrorCode[];
-extern const char kMetricAttemptDownloadErrorCode[];
-
-// UpdateEngine.SuccessfulUpdate.* metrics.
-extern const char kMetricSuccessfulUpdateAttemptCount[];
-extern const char kMetricSuccessfulUpdateBytesDownloadedMiB[];
-extern const char kMetricSuccessfulUpdateDownloadOverheadPercentage[];
-extern const char kMetricSuccessfulUpdateDownloadSourcesUsed[];
-extern const char kMetricSuccessfulUpdatePayloadType[];
-extern const char kMetricSuccessfulUpdatePayloadSizeMiB[];
-extern const char kMetricSuccessfulUpdateTotalDurationMinutes[];
-extern const char kMetricSuccessfulUpdateRebootCount[];
-extern const char kMetricSuccessfulUpdateUpdatesAbandonedCount[];
-extern const char kMetricSuccessfulUpdateUrlSwitchCount[];
-
-// UpdateEngine.Rollback.* metric.
-extern const char kMetricRollbackResult[];
-
-// UpdateEngine.* metrics.
-extern const char kMetricFailedUpdateCount[];
-extern const char kMetricInstallDateProvisioningSource[];
-extern const char kMetricTimeToRebootMinutes[];
-
-// The possible outcomes when checking for updates.
-//
-// This is used in the UpdateEngine.Check.Result histogram.
-enum class CheckResult {
-  kUpdateAvailable,    // Response indicates an update is available.
-  kNoUpdateAvailable,  // Response indicates no updates are available.
-  kDownloadError,      // Error downloading response from Omaha.
-  kParsingError,       // Error parsing response.
-  kRebootPending,      // No update check was performed a reboot is pending.
-
-  kNumConstants,
-  kUnset = -1
-};
-
-// Possible ways a device can react to a new update being available.
-//
-// This is used in the UpdateEngine.Check.Reaction histogram.
-enum class CheckReaction {
-  kUpdating,    // Device proceeds to download and apply update.
-  kIgnored  ,   // Device-policy dictates ignoring the update.
-  kDeferring,   // Device-policy dictates waiting.
-  kBackingOff,  // Previous errors dictates waiting.
-
-  kNumConstants,
-  kUnset = -1
-};
-
-// The possible ways that downloading from a HTTP or HTTPS server can fail.
-//
-// This is used in the UpdateEngine.Check.DownloadErrorCode and
-// UpdateEngine.Attempt.DownloadErrorCode histograms.
-enum class DownloadErrorCode {
-  // Errors that can happen in the field. See http://crbug.com/355745
-  // for how we plan to add more detail in the future.
-  kDownloadError = 0,  // Error downloading data from server.
-
-  // IMPORTANT: When adding a new error code, add at the bottom of the
-  // above block and before the kInputMalformed field. This
-  // is to ensure that error codes are not reordered.
-
-  // This error code is used to convey that malformed input was given
-  // to the utils::GetDownloadErrorCode() function. This should never
-  // happen but if it does it's because of an internal update_engine
-  // error and we're interested in knowing this.
-  kInputMalformed = 100,
-
-  // Bucket for capturing HTTP status codes not in the 200-599
-  // range. This should never happen in practice but if it does we
-  // want to know.
-  kHttpStatusOther = 101,
-
-  // Above 200 and below 600, the value is the HTTP status code.
-  kHttpStatus200 = 200,
-
-  kNumConstants = 600,
-
-  kUnset = -1
-};
-
-// Possible ways an update attempt can end.
-//
-// This is used in the UpdateEngine.Attempt.Result histogram.
-enum class AttemptResult {
-  kUpdateSucceeded,             // The update succeeded.
-  kInternalError,               // An internal error occurred.
-  kPayloadDownloadError,        // Failure while downloading payload.
-  kMetadataMalformed,           // Metadata was malformed.
-  kOperationMalformed,          // An operation was malformed.
-  kOperationExecutionError,     // An operation failed to execute.
-  kMetadataVerificationFailed,  // Metadata verification failed.
-  kPayloadVerificationFailed,   // Payload verification failed.
-  kVerificationFailed,          // Root or Kernel partition verification failed.
-  kPostInstallFailed,           // The postinstall step failed.
-  kAbnormalTermination,         // The attempt ended abnormally.
-  kUpdateCanceled,              // Update canceled by the user.
-
-  kNumConstants,
-
-  kUnset = -1
-};
-
-// Possible ways the device is connected to the Internet.
-//
-// This is used in the UpdateEngine.Attempt.ConnectionType histogram.
-enum class ConnectionType {
-  kUnknown,           // Unknown.
-  kEthernet,          // Ethernet.
-  kWifi,              // Wireless.
-  kWimax,             // WiMax.
-  kBluetooth,         // Bluetooth.
-  kCellular,          // Cellular.
-  kTetheredEthernet,  // Tethered (Ethernet).
-  kTetheredWifi,      // Tethered (Wifi).
-
-  kNumConstants,
-  kUnset = -1
-};
-
-// Possible ways a rollback can end.
-//
-// This is used in the UpdateEngine.Rollback histogram.
-enum class RollbackResult {
-  kFailed,
-  kSuccess,
-
-  kNumConstants
-};
-
-// Helper function to report metrics related to rollback. The
-// following metrics are reported:
-//
-//  |kMetricRollbackResult|
-void ReportRollbackMetrics(SystemState *system_state,
-                           RollbackResult result);
-
-// Helper function to report metrics reported once a day. The
-// following metrics are reported:
-//
-//  |kMetricDailyOSAgeDays|
-void ReportDailyMetrics(SystemState *system_state,
-                        base::TimeDelta os_age);
-
-// Helper function to report metrics after completing an update check
-// with the ChromeOS update server ("Omaha"). The following metrics
-// are reported:
-//
-//  |kMetricCheckResult|
-//  |kMetricCheckReaction|
-//  |kMetricCheckDownloadErrorCode|
-//  |kMetricCheckTimeSinceLastCheckMinutes|
-//  |kMetricCheckTimeSinceLastCheckUptimeMinutes|
-//
-// The |kMetricCheckResult| metric will only be reported if |result|
-// is not |kUnset|.
-//
-// The |kMetricCheckReaction| metric will only be reported if
-// |reaction| is not |kUnset|.
-//
-// The |kMetricCheckDownloadErrorCode| will only be reported if
-// |download_error_code| is not |kUnset|.
-//
-// The values for the |kMetricCheckTimeSinceLastCheckMinutes| and
-// |kMetricCheckTimeSinceLastCheckUptimeMinutes| metrics are
-// automatically reported and calculated by maintaining persistent
-// and process-local state variables.
-void ReportUpdateCheckMetrics(SystemState *system_state,
-                              CheckResult result,
-                              CheckReaction reaction,
-                              DownloadErrorCode download_error_code);
-
-
-// Helper function to report metrics after the completion of each
-// update attempt. The following metrics are reported:
-//
-//  |kMetricAttemptNumber|
-//  |kMetricAttemptPayloadType|
-//  |kMetricAttemptPayloadSizeMiB|
-//  |kMetricAttemptDurationSeconds|
-//  |kMetricAttemptDurationUptimeSeconds|
-//  |kMetricAttemptTimeSinceLastAttemptMinutes|
-//  |kMetricAttemptTimeSinceLastAttemptUptimeMinutes|
-//  |kMetricAttemptPayloadBytesDownloadedMiB|
-//  |kMetricAttemptPayloadDownloadSpeedKBps|
-//  |kMetricAttemptDownloadSource|
-//  |kMetricAttemptResult|
-//  |kMetricAttemptInternalErrorCode|
-//  |kMetricAttemptDownloadErrorCode|
-//
-// The |kMetricAttemptInternalErrorCode| metric will only be reported
-// if |internal_error_code| is not |kErrorSuccess|.
-//
-// The |kMetricAttemptDownloadErrorCode| metric will only be
-// reported if |payload_download_error_code| is not |kUnset|.
-//
-// The values for the |kMetricAttemptTimeSinceLastAttemptMinutes| and
-// |kMetricAttemptTimeSinceLastAttemptUptimeMinutes| metrics are
-// automatically calculated and reported by maintaining persistent and
-// process-local state variables.
-void ReportUpdateAttemptMetrics(
-    SystemState *system_state,
-    int attempt_number,
-    PayloadType payload_type,
-    base::TimeDelta duration,
-    base::TimeDelta duration_uptime,
-    int64_t payload_size,
-    int64_t payload_bytes_downloaded,
-    int64_t payload_download_speed_bps,
-    DownloadSource download_source,
-    AttemptResult attempt_result,
-    ErrorCode internal_error_code,
-    DownloadErrorCode payload_download_error_code,
-    ConnectionType connection_type);
-
-// Reports the |kAbnormalTermination| for the |kMetricAttemptResult|
-// metric. No other metrics in the UpdateEngine.Attempt.* namespace
-// will be reported.
-void ReportAbnormallyTerminatedUpdateAttemptMetrics(SystemState *system_state);
-
-// Helper function to report the after the completion of a successful
-// update attempt. The following metrics are reported:
-//
-//  |kMetricSuccessfulUpdateAttemptCount|
-//  |kMetricSuccessfulUpdateUpdatesAbandonedCount|
-//  |kMetricSuccessfulUpdatePayloadType|
-//  |kMetricSuccessfulUpdatePayloadSizeMiB|
-//  |kMetricSuccessfulUpdateBytesDownloadedMiBHttpsServer|
-//  |kMetricSuccessfulUpdateBytesDownloadedMiBHttpServer|
-//  |kMetricSuccessfulUpdateBytesDownloadedMiBHttpPeer|
-//  |kMetricSuccessfulUpdateBytesDownloadedMiB|
-//  |kMetricSuccessfulUpdateDownloadSourcesUsed|
-//  |kMetricSuccessfulUpdateDownloadOverheadPercentage|
-//  |kMetricSuccessfulUpdateTotalDurationMinutes|
-//  |kMetricSuccessfulUpdateRebootCount|
-//  |kMetricSuccessfulUpdateUrlSwitchCount|
-//
-// The values for the |kMetricSuccessfulUpdateDownloadSourcesUsed| are
-// |kMetricSuccessfulUpdateBytesDownloadedMiB| metrics automatically
-// calculated from examining the |num_bytes_downloaded| array.
-void ReportSuccessfulUpdateMetrics(
-    SystemState *system_state,
-    int attempt_count,
-    int updates_abandoned_count,
-    PayloadType payload_type,
-    int64_t payload_size,
-    int64_t num_bytes_downloaded[kNumDownloadSources],
-    int download_overhead_percentage,
-    base::TimeDelta total_duration,
-    int reboot_count,
-    int url_switch_count);
-
-// Helper function to report the after the completion of a SSL certificate
-// check. One of the following metrics is reported:
-//
-//  |kMetricCertificateCheckUpdateCheck|
-//  |kMetricCertificateCheckDownload|
-void ReportCertificateCheckMetrics(SystemState* system_state,
-                                   ServerToCheck server_to_check,
-                                   CertificateCheckResult result);
-
-}  // namespace metrics
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_METRICS_H_
diff --git a/metrics_constants.h b/metrics_constants.h
new file mode 100644
index 0000000..f6d0c74
--- /dev/null
+++ b/metrics_constants.h
@@ -0,0 +1,135 @@
+//
+// Copyright (C) 2017 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_METRICS_CONSTANTS_H_
+#define UPDATE_ENGINE_METRICS_CONSTANTS_H_
+
+namespace chromeos_update_engine {
+
+namespace metrics {
+// The possible outcomes when checking for updates.
+//
+// This is used in the UpdateEngine.Check.Result histogram.
+enum class CheckResult {
+  kUpdateAvailable,    // Response indicates an update is available.
+  kNoUpdateAvailable,  // Response indicates no updates are available.
+  kDownloadError,      // Error downloading response from Omaha.
+  kParsingError,       // Error parsing response.
+  kRebootPending,      // No update check was performed a reboot is pending.
+
+  kNumConstants,
+  kUnset = -1
+};
+
+// Possible ways a device can react to a new update being available.
+//
+// This is used in the UpdateEngine.Check.Reaction histogram.
+enum class CheckReaction {
+  kUpdating,    // Device proceeds to download and apply update.
+  kIgnored,     // Device-policy dictates ignoring the update.
+  kDeferring,   // Device-policy dictates waiting.
+  kBackingOff,  // Previous errors dictates waiting.
+
+  kNumConstants,
+  kUnset = -1
+};
+
+// The possible ways that downloading from a HTTP or HTTPS server can fail.
+//
+// This is used in the UpdateEngine.Check.DownloadErrorCode and
+// UpdateEngine.Attempt.DownloadErrorCode histograms.
+enum class DownloadErrorCode {
+  // Errors that can happen in the field. See http://crbug.com/355745
+  // for how we plan to add more detail in the future.
+  kDownloadError = 0,  // Error downloading data from server.
+
+  // IMPORTANT: When adding a new error code, add at the bottom of the
+  // above block and before the kInputMalformed field. This
+  // is to ensure that error codes are not reordered.
+
+  // This error code is used to convey that malformed input was given
+  // to the utils::GetDownloadErrorCode() function. This should never
+  // happen but if it does it's because of an internal update_engine
+  // error and we're interested in knowing this.
+  kInputMalformed = 100,
+
+  // Bucket for capturing HTTP status codes not in the 200-599
+  // range. This should never happen in practice but if it does we
+  // want to know.
+  kHttpStatusOther = 101,
+
+  // Above 200 and below 600, the value is the HTTP status code.
+  kHttpStatus200 = 200,
+
+  kNumConstants = 600,
+
+  kUnset = -1
+};
+
+// Possible ways an update attempt can end.
+//
+// This is used in the UpdateEngine.Attempt.Result histogram.
+enum class AttemptResult {
+  kUpdateSucceeded,             // The update succeeded.
+  kInternalError,               // An internal error occurred.
+  kPayloadDownloadError,        // Failure while downloading payload.
+  kMetadataMalformed,           // Metadata was malformed.
+  kOperationMalformed,          // An operation was malformed.
+  kOperationExecutionError,     // An operation failed to execute.
+  kMetadataVerificationFailed,  // Metadata verification failed.
+  kPayloadVerificationFailed,   // Payload verification failed.
+  kVerificationFailed,          // Root or Kernel partition verification failed.
+  kPostInstallFailed,           // The postinstall step failed.
+  kAbnormalTermination,         // The attempt ended abnormally.
+  kUpdateCanceled,              // Update canceled by the user.
+
+  kNumConstants,
+
+  kUnset = -1
+};
+
+// Possible ways the device is connected to the Internet.
+//
+// This is used in the UpdateEngine.Attempt.ConnectionType histogram.
+enum class ConnectionType {
+  kUnknown,           // Unknown.
+  kEthernet,          // Ethernet.
+  kWifi,              // Wireless.
+  kWimax,             // WiMax.
+  kBluetooth,         // Bluetooth.
+  kCellular,          // Cellular.
+  kTetheredEthernet,  // Tethered (Ethernet).
+  kTetheredWifi,      // Tethered (Wifi).
+
+  kNumConstants,
+  kUnset = -1
+};
+
+// Possible ways a rollback can end.
+//
+// This is used in the UpdateEngine.Rollback histogram.
+enum class RollbackResult {
+  kFailed,
+  kSuccess,
+
+  kNumConstants
+};
+
+}  // namespace metrics
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_METRICS_CONSTANTS_H_
diff --git a/metrics_reporter_interface.h b/metrics_reporter_interface.h
new file mode 100644
index 0000000..458d98e
--- /dev/null
+++ b/metrics_reporter_interface.h
@@ -0,0 +1,185 @@
+//
+// Copyright (C) 2017 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_METRICS_REPORTER_INTERFACE_H_
+#define UPDATE_ENGINE_METRICS_REPORTER_INTERFACE_H_
+
+#include <base/time/time.h>
+
+#include "update_engine/certificate_checker.h"
+#include "update_engine/common/constants.h"
+#include "update_engine/common/error_code.h"
+#include "update_engine/metrics_constants.h"
+#include "update_engine/system_state.h"
+
+namespace chromeos_update_engine {
+
+class MetricsReporterInterface {
+ public:
+  virtual ~MetricsReporterInterface() = default;
+
+  virtual void Initialize() = 0;
+
+  // Helper function to report metrics related to rollback. The
+  // following metrics are reported:
+  //
+  //  |kMetricRollbackResult|
+  virtual void ReportRollbackMetrics(metrics::RollbackResult result) = 0;
+
+  // Helper function to report metrics reported once a day. The
+  // following metrics are reported:
+  //
+  //  |kMetricDailyOSAgeDays|
+  virtual void ReportDailyMetrics(base::TimeDelta os_age) = 0;
+
+  // Helper function to report metrics after completing an update check
+  // with the ChromeOS update server ("Omaha"). The following metrics
+  // are reported:
+  //
+  //  |kMetricCheckResult|
+  //  |kMetricCheckReaction|
+  //  |kMetricCheckDownloadErrorCode|
+  //  |kMetricCheckTimeSinceLastCheckMinutes|
+  //  |kMetricCheckTimeSinceLastCheckUptimeMinutes|
+  //
+  // The |kMetricCheckResult| metric will only be reported if |result|
+  // is not |kUnset|.
+  //
+  // The |kMetricCheckReaction| metric will only be reported if
+  // |reaction| is not |kUnset|.
+  //
+  // The |kMetricCheckDownloadErrorCode| will only be reported if
+  // |download_error_code| is not |kUnset|.
+  //
+  // The values for the |kMetricCheckTimeSinceLastCheckMinutes| and
+  // |kMetricCheckTimeSinceLastCheckUptimeMinutes| metrics are
+  // automatically reported and calculated by maintaining persistent
+  // and process-local state variables.
+  virtual void ReportUpdateCheckMetrics(
+      SystemState* system_state,
+      metrics::CheckResult result,
+      metrics::CheckReaction reaction,
+      metrics::DownloadErrorCode download_error_code) = 0;
+
+  // Helper function to report metrics after the completion of each
+  // update attempt. The following metrics are reported:
+  //
+  //  |kMetricAttemptNumber|
+  //  |kMetricAttemptPayloadType|
+  //  |kMetricAttemptPayloadSizeMiB|
+  //  |kMetricAttemptDurationSeconds|
+  //  |kMetricAttemptDurationUptimeSeconds|
+  //  |kMetricAttemptTimeSinceLastAttemptMinutes|
+  //  |kMetricAttemptTimeSinceLastAttemptUptimeMinutes|
+  //  |kMetricAttemptPayloadBytesDownloadedMiB|
+  //  |kMetricAttemptPayloadDownloadSpeedKBps|
+  //  |kMetricAttemptDownloadSource|
+  //  |kMetricAttemptResult|
+  //  |kMetricAttemptInternalErrorCode|
+  //  |kMetricAttemptDownloadErrorCode|
+  //
+  // The |kMetricAttemptInternalErrorCode| metric will only be reported
+  // if |internal_error_code| is not |kErrorSuccess|.
+  //
+  // The |kMetricAttemptDownloadErrorCode| metric will only be
+  // reported if |payload_download_error_code| is not |kUnset|.
+  //
+  // The values for the |kMetricAttemptTimeSinceLastAttemptMinutes| and
+  // |kMetricAttemptTimeSinceLastAttemptUptimeMinutes| metrics are
+  // automatically calculated and reported by maintaining persistent and
+  // process-local state variables.
+  virtual void ReportUpdateAttemptMetrics(
+      SystemState* system_state,
+      int attempt_number,
+      PayloadType payload_type,
+      base::TimeDelta duration,
+      base::TimeDelta duration_uptime,
+      int64_t payload_size,
+      int64_t payload_bytes_downloaded,
+      int64_t payload_download_speed_bps,
+      DownloadSource download_source,
+      metrics::AttemptResult attempt_result,
+      ErrorCode internal_error_code,
+      metrics::DownloadErrorCode payload_download_error_code,
+      metrics::ConnectionType connection_type) = 0;
+
+  // Reports the |kAbnormalTermination| for the |kMetricAttemptResult|
+  // metric. No other metrics in the UpdateEngine.Attempt.* namespace
+  // will be reported.
+  virtual void ReportAbnormallyTerminatedUpdateAttemptMetrics() = 0;
+
+  // Helper function to report the after the completion of a successful
+  // update attempt. The following metrics are reported:
+  //
+  //  |kMetricSuccessfulUpdateAttemptCount|
+  //  |kMetricSuccessfulUpdateUpdatesAbandonedCount|
+  //  |kMetricSuccessfulUpdatePayloadType|
+  //  |kMetricSuccessfulUpdatePayloadSizeMiB|
+  //  |kMetricSuccessfulUpdateBytesDownloadedMiBHttpsServer|
+  //  |kMetricSuccessfulUpdateBytesDownloadedMiBHttpServer|
+  //  |kMetricSuccessfulUpdateBytesDownloadedMiBHttpPeer|
+  //  |kMetricSuccessfulUpdateBytesDownloadedMiB|
+  //  |kMetricSuccessfulUpdateDownloadSourcesUsed|
+  //  |kMetricSuccessfulUpdateDownloadOverheadPercentage|
+  //  |kMetricSuccessfulUpdateTotalDurationMinutes|
+  //  |kMetricSuccessfulUpdateRebootCount|
+  //  |kMetricSuccessfulUpdateUrlSwitchCount|
+  //
+  // The values for the |kMetricSuccessfulUpdateDownloadSourcesUsed| are
+  // |kMetricSuccessfulUpdateBytesDownloadedMiB| metrics automatically
+  // calculated from examining the |num_bytes_downloaded| array.
+  virtual void ReportSuccessfulUpdateMetrics(
+      int attempt_count,
+      int updates_abandoned_count,
+      PayloadType payload_type,
+      int64_t payload_size,
+      int64_t num_bytes_downloaded[kNumDownloadSources],
+      int download_overhead_percentage,
+      base::TimeDelta total_duration,
+      int reboot_count,
+      int url_switch_count) = 0;
+
+  // Helper function to report the after the completion of a SSL certificate
+  // check. One of the following metrics is reported:
+  //
+  //  |kMetricCertificateCheckUpdateCheck|
+  //  |kMetricCertificateCheckDownload|
+  virtual void ReportCertificateCheckMetrics(ServerToCheck server_to_check,
+                                             CertificateCheckResult result) = 0;
+
+  // Helper function to report the number failed update attempts. The following
+  // metrics are reported:
+  //
+  // |kMetricFailedUpdateCount|
+  virtual void ReportFailedUpdateCount(int target_attempt) = 0;
+
+  // Helper function to report the time interval in minutes between a
+  // successful update and the reboot into the updated system. The following
+  // metrics are reported:
+  //
+  // |kMetricTimeToRebootMinutes|
+  virtual void ReportTimeToReboot(int time_to_reboot_minutes) = 0;
+
+  // Helper function to report the source of installation data. The following
+  // metrics are reported:
+  //
+  // |kMetricInstallDateProvisioningSource|
+  virtual void ReportInstallDateProvisioningSource(int source, int max) = 0;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_METRICS_REPORTER_INTERFACE_H_
diff --git a/metrics_reporter_omaha.h b/metrics_reporter_omaha.h
new file mode 100644
index 0000000..e974a26
--- /dev/null
+++ b/metrics_reporter_omaha.h
@@ -0,0 +1,97 @@
+//
+// Copyright (C) 2017 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_METRICS_REPORTER_OMAHA_H_
+#define UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
+
+#include <base/time/time.h>
+#include <metrics/metrics_library.h>
+
+#include "update_engine/certificate_checker.h"
+#include "update_engine/common/constants.h"
+#include "update_engine/common/error_code.h"
+#include "update_engine/metrics_constants.h"
+#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/system_state.h"
+
+namespace chromeos_update_engine {
+
+class SystemState;
+
+class MetricsReporterOmaha : public MetricsReporterInterface {
+ public:
+  MetricsReporterOmaha() = default;
+
+  ~MetricsReporterOmaha() override = default;
+
+  void Initialize() override;
+
+  void ReportRollbackMetrics(metrics::RollbackResult result) override;
+
+  void ReportDailyMetrics(base::TimeDelta os_age) override;
+
+  void ReportUpdateCheckMetrics(
+      SystemState* system_state,
+      metrics::CheckResult result,
+      metrics::CheckReaction reaction,
+      metrics::DownloadErrorCode download_error_code) override;
+
+  void ReportUpdateAttemptMetrics(
+      SystemState* system_state,
+      int attempt_number,
+      PayloadType payload_type,
+      base::TimeDelta duration,
+      base::TimeDelta duration_uptime,
+      int64_t payload_size,
+      int64_t payload_bytes_downloaded,
+      int64_t payload_download_speed_bps,
+      DownloadSource download_source,
+      metrics::AttemptResult attempt_result,
+      ErrorCode internal_error_code,
+      metrics::DownloadErrorCode payload_download_error_code,
+      metrics::ConnectionType connection_type) override;
+
+  void ReportAbnormallyTerminatedUpdateAttemptMetrics() override;
+
+  void ReportSuccessfulUpdateMetrics(
+      int attempt_count,
+      int updates_abandoned_count,
+      PayloadType payload_type,
+      int64_t payload_size,
+      int64_t num_bytes_downloaded[kNumDownloadSources],
+      int download_overhead_percentage,
+      base::TimeDelta total_duration,
+      int reboot_count,
+      int url_switch_count) override;
+
+  void ReportCertificateCheckMetrics(ServerToCheck server_to_check,
+                                     CertificateCheckResult result) override;
+
+  void ReportFailedUpdateCount(int target_attempt) override;
+
+  void ReportTimeToReboot(int time_to_reboot_minutes) override;
+
+  void ReportInstallDateProvisioningSource(int source, int max) override;
+
+ private:
+  MetricsLibrary metrics_lib_;
+
+  DISALLOW_COPY_AND_ASSIGN(MetricsReporterOmaha);
+};  // class metrics
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
diff --git a/metrics_utils.h b/metrics_utils.h
index d9826c1..2d62dc0 100644
--- a/metrics_utils.h
+++ b/metrics_utils.h
@@ -17,8 +17,11 @@
 #ifndef UPDATE_ENGINE_METRICS_UTILS_H_
 #define UPDATE_ENGINE_METRICS_UTILS_H_
 
+#include <base/time/time.h>
+
+#include "update_engine/common/error_code.h"
 #include "update_engine/connection_utils.h"
-#include "update_engine/metrics.h"
+#include "update_engine/metrics_constants.h"
 
 namespace chromeos_update_engine {
 
diff --git a/mock_metrics.h b/mock_metrics.h
new file mode 100644
index 0000000..e456f61
--- /dev/null
+++ b/mock_metrics.h
@@ -0,0 +1,81 @@
+//
+// Copyright (C) 2017 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_MOCK_METRICS_H
+#define UPDATE_ENGINE_MOCK_METRICS_H
+
+#include <gmock/gmock.h>
+
+#include "update_engine/metrics_reporter_interface.h"
+
+namespace chromeos_update_engine {
+
+class MockMetrics : public MetricsReporterInterface {
+ public:
+  MOCK_METHOD0(Initialize, void());
+
+  MOCK_METHOD1(ReportRollbackMetrics, void(metrics::RollbackResult result));
+
+  MOCK_METHOD1(ReportDailyMetrics, void(base::TimeDelta os_age));
+
+  MOCK_METHOD4(ReportUpdateCheckMetrics,
+               void(SystemState* system_state,
+                    metrics::CheckResult result,
+                    metrics::CheckReaction reaction,
+                    metrics::DownloadErrorCode download_error_code));
+
+  void ReportUpdateAttemptMetrics(
+      SystemState* system_state,
+      int attempt_number,
+      PayloadType payload_type,
+      base::TimeDelta duration,
+      base::TimeDelta duration_uptime,
+      int64_t payload_size,
+      int64_t payload_bytes_downloaded,
+      int64_t payload_download_speed_bps,
+      DownloadSource download_source,
+      metrics::AttemptResult attempt_result,
+      ErrorCode internal_error_code,
+      metrics::DownloadErrorCode payload_download_error_code,
+      metrics::ConnectionType connection_type) override {}
+
+  MOCK_METHOD0(ReportAbnormallyTerminatedUpdateAttemptMetrics, void());
+
+  MOCK_METHOD9(ReportSuccessfulUpdateMetrics,
+               void(int attempt_count,
+                    int updates_abandoned_count,
+                    PayloadType payload_type,
+                    int64_t payload_size,
+                    int64_t num_bytes_downloaded[kNumDownloadSources],
+                    int download_overhead_percentage,
+                    base::TimeDelta total_duration,
+                    int reboot_count,
+                    int url_switch_count));
+
+  MOCK_METHOD2(ReportCertificateCheckMetrics,
+               void(ServerToCheck server_to_check,
+                    CertificateCheckResult result));
+
+  MOCK_METHOD1(ReportFailedUpdateCount, void(int target_attempt));
+
+  MOCK_METHOD1(ReportTimeToReboot, void(int time_to_reboot_minutes));
+
+  MOCK_METHOD2(ReportInstallDateProvisioningSource, void(int source, int max));
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_MOCK_METRICS_H
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 7ac7059..7e41f94 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -42,7 +42,7 @@
 #include "update_engine/common/prefs_interface.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/connection_manager_interface.h"
-#include "update_engine/metrics.h"
+#include "update_engine/metrics_reporter_interface.h"
 #include "update_engine/metrics_utils.h"
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/p2p_manager.h"
@@ -1521,12 +1521,9 @@
   if (!prefs->SetInt64(kPrefsInstallDateDays, install_date_days))
     return false;
 
-  string metric_name = metrics::kMetricInstallDateProvisioningSource;
-  system_state->metrics_lib()->SendEnumToUMA(
-      metric_name,
+  system_state->metrics_reporter()->ReportInstallDateProvisioningSource(
       static_cast<int>(source),  // Sample.
       kProvisionedMax);          // Maximum.
-
   return true;
 }
 
@@ -1612,8 +1609,8 @@
     break;
   }
 
-  metrics::ReportUpdateCheckMetrics(system_state_,
-                                    result, reaction, download_error_code);
+  system_state_->metrics_reporter()->ReportUpdateCheckMetrics(
+      system_state_, result, reaction, download_error_code);
 }
 
 bool OmahaRequestAction::ShouldIgnoreUpdate(
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index 409165c..0398281 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -44,7 +44,7 @@
 #include "update_engine/common/prefs.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/fake_system_state.h"
-#include "update_engine/metrics.h"
+#include "update_engine/metrics_reporter_interface.h"
 #include "update_engine/mock_connection_manager.h"
 #include "update_engine/mock_payload_state.h"
 #include "update_engine/omaha_request_params.h"
@@ -391,23 +391,16 @@
   BondActions(&action, &collector_action);
   processor.EnqueueAction(&collector_action);
 
-  EXPECT_CALL(*fake_system_state_.mock_metrics_lib(), SendEnumToUMA(_, _, _))
+  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+              ReportUpdateCheckMetrics(_, _, _, _))
       .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state_.mock_metrics_lib(),
-      SendEnumToUMA(metrics::kMetricCheckResult,
-          static_cast<int>(expected_check_result),
-          static_cast<int>(metrics::CheckResult::kNumConstants) - 1))
-      .Times(expected_check_result == metrics::CheckResult::kUnset ? 0 : 1);
-  EXPECT_CALL(*fake_system_state_.mock_metrics_lib(),
-      SendEnumToUMA(metrics::kMetricCheckReaction,
-          static_cast<int>(expected_check_reaction),
-          static_cast<int>(metrics::CheckReaction::kNumConstants) - 1))
-      .Times(expected_check_reaction == metrics::CheckReaction::kUnset ? 0 : 1);
-  EXPECT_CALL(*fake_system_state_.mock_metrics_lib(),
-      SendSparseToUMA(metrics::kMetricCheckDownloadErrorCode,
-          static_cast<int>(expected_download_error_code)))
-      .Times(expected_download_error_code == metrics::DownloadErrorCode::kUnset
-             ? 0 : 1);
+
+  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+              ReportUpdateCheckMetrics(_,
+                                       expected_check_result,
+                                       expected_check_reaction,
+                                       expected_download_error_code))
+      .Times(ping_only ? 0 : 1);
 
   loop.PostTask(base::Bind(
       [](ActionProcessor* processor) { processor->StartProcessing(); },
@@ -818,18 +811,19 @@
 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBE) {
   OmahaResponse response;
 
+  // TODO set better default value for metrics::checkresult in
+  // OmahaRequestAction::ActionCompleted.
   fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
-  ASSERT_FALSE(
-      TestUpdateCheck(nullptr,  // request_params
-                      fake_update_response_.GetUpdateResponse(),
-                      -1,
-                      false,  // ping_only
-                      ErrorCode::kNonCriticalUpdateInOOBE,
-                      metrics::CheckResult::kUnset,
-                      metrics::CheckReaction::kUnset,
-                      metrics::DownloadErrorCode::kUnset,
-                      &response,
-                      nullptr));
+  ASSERT_FALSE(TestUpdateCheck(nullptr,  // request_params
+                               fake_update_response_.GetUpdateResponse(),
+                               -1,
+                               false,  // ping_only
+                               ErrorCode::kNonCriticalUpdateInOOBE,
+                               metrics::CheckResult::kParsingError,
+                               metrics::CheckReaction::kUnset,
+                               metrics::DownloadErrorCode::kUnset,
+                               &response,
+                               nullptr));
   EXPECT_FALSE(response.update_exists);
 
   // The IsOOBEComplete() value is ignored when the OOBE flow is not enabled.
@@ -1752,17 +1746,16 @@
   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
       .WillOnce(DoAll(SetArgumentPointee<1>(five_days_ago), Return(true)));
   brillo::Blob post_data;
-  ASSERT_TRUE(
-      TestUpdateCheck(nullptr,  // request_params
-                      fake_update_response_.GetNoUpdateResponse(),
-                      -1,
-                      ping_only,
-                      ErrorCode::kSuccess,
-                      metrics::CheckResult::kUnset,
-                      metrics::CheckReaction::kUnset,
-                      metrics::DownloadErrorCode::kUnset,
-                      nullptr,
-                      &post_data));
+  ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
+                              fake_update_response_.GetNoUpdateResponse(),
+                              -1,
+                              ping_only,
+                              ErrorCode::kSuccess,
+                              metrics::CheckResult::kNoUpdateAvailable,
+                              metrics::CheckReaction::kUnset,
+                              metrics::DownloadErrorCode::kUnset,
+                              nullptr,
+                              &post_data));
   string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(post_str.find("<ping active=\"1\" a=\"6\" r=\"5\"></ping>"),
             string::npos);
diff --git a/payload_state.cc b/payload_state.cc
index a1a9d72..1f121b0 100644
--- a/payload_state.cc
+++ b/payload_state.cc
@@ -32,6 +32,7 @@
 #include "update_engine/common/prefs.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/connection_manager_interface.h"
+#include "update_engine/metrics_reporter_interface.h"
 #include "update_engine/metrics_utils.h"
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/payload_consumer/install_plan.h"
@@ -235,8 +236,8 @@
       break;
 
     case AttemptType::kRollback:
-      metrics::ReportRollbackMetrics(system_state_,
-                                     metrics::RollbackResult::kSuccess);
+      system_state_->metrics_reporter()->ReportRollbackMetrics(
+          metrics::RollbackResult::kSuccess);
       break;
   }
   attempt_error_code_ = ErrorCode::kSuccess;
@@ -270,8 +271,8 @@
       break;
 
     case AttemptType::kRollback:
-      metrics::ReportRollbackMetrics(system_state_,
-                                     metrics::RollbackResult::kFailed);
+      system_state_->metrics_reporter()->ReportRollbackMetrics(
+          metrics::RollbackResult::kFailed);
       break;
   }
 
@@ -635,19 +636,20 @@
       break;
   }
 
-  metrics::ReportUpdateAttemptMetrics(system_state_,
-                                      attempt_number,
-                                      payload_type,
-                                      duration,
-                                      duration_uptime,
-                                      payload_size,
-                                      payload_bytes_downloaded,
-                                      payload_download_speed_bps,
-                                      download_source,
-                                      attempt_result,
-                                      internal_error_code,
-                                      payload_download_error_code,
-                                      attempt_connection_type_);
+  system_state_->metrics_reporter()->ReportUpdateAttemptMetrics(
+      system_state_,
+      attempt_number,
+      payload_type,
+      duration,
+      duration_uptime,
+      payload_size,
+      payload_bytes_downloaded,
+      payload_download_speed_bps,
+      download_source,
+      attempt_result,
+      internal_error_code,
+      payload_download_error_code,
+      attempt_connection_type_);
 }
 
 void PayloadState::PersistAttemptMetrics() {
@@ -672,7 +674,8 @@
   if (!attempt_in_progress)
     return;
 
-  metrics::ReportAbnormallyTerminatedUpdateAttemptMetrics(system_state_);
+  system_state_->metrics_reporter()
+      ->ReportAbnormallyTerminatedUpdateAttemptMetrics();
 
   ClearPersistedAttemptMetrics();
 }
@@ -734,16 +737,16 @@
 
   int updates_abandoned_count = num_responses_seen_ - 1;
 
-  metrics::ReportSuccessfulUpdateMetrics(system_state_,
-                                         attempt_count,
-                                         updates_abandoned_count,
-                                         payload_type,
-                                         payload_size,
-                                         total_bytes_by_source,
-                                         download_overhead_percentage,
-                                         duration,
-                                         reboot_count,
-                                         url_switch_count);
+  system_state_->metrics_reporter()->ReportSuccessfulUpdateMetrics(
+      attempt_count,
+      updates_abandoned_count,
+      payload_type,
+      payload_size,
+      total_bytes_by_source,
+      download_overhead_percentage,
+      duration,
+      reboot_count,
+      url_switch_count);
 }
 
 void PayloadState::UpdateNumReboots() {
@@ -1232,14 +1235,8 @@
 
 void PayloadState::BootedIntoUpdate(TimeDelta time_to_reboot) {
   // Send |time_to_reboot| as a UMA stat.
-  string metric = metrics::kMetricTimeToRebootMinutes;
-  system_state_->metrics_lib()->SendToUMA(metric,
-                                          time_to_reboot.InMinutes(),
-                                          0,         // min: 0 minute
-                                          30*24*60,  // max: 1 month (approx)
-                                          kNumDefaultUmaBuckets);
-  LOG(INFO) << "Uploading " << utils::FormatTimeDelta(time_to_reboot)
-            << " for metric " <<  metric;
+  system_state_->metrics_reporter()->ReportTimeToReboot(
+      time_to_reboot.InMinutes());
 }
 
 void PayloadState::UpdateEngineStarted() {
@@ -1302,15 +1299,8 @@
       }
 
       // Report the UMA metric of the current boot failure.
-      string metric = metrics::kMetricFailedUpdateCount;
-      LOG(INFO) << "Uploading " << target_attempt
-                << " (count) for metric " <<  metric;
-      system_state_->metrics_lib()->SendToUMA(
-           metric,
-           target_attempt,
-           1,    // min value
-           50,   // max value
-           kNumDefaultUmaBuckets);
+      system_state_->metrics_reporter()->ReportFailedUpdateCount(
+          target_attempt);
     } else {
       prefs_->Delete(kPrefsTargetVersionAttempt);
       prefs_->Delete(kPrefsTargetVersionUniqueId);
diff --git a/payload_state.h b/payload_state.h
index 699fc74..98f21e8 100644
--- a/payload_state.h
+++ b/payload_state.h
@@ -24,7 +24,7 @@
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
 #include "update_engine/common/prefs_interface.h"
-#include "update_engine/metrics.h"
+#include "update_engine/metrics_constants.h"
 #include "update_engine/payload_state_interface.h"
 
 namespace chromeos_update_engine {
diff --git a/payload_state_unittest.cc b/payload_state_unittest.cc
index 4546180..b277d95 100644
--- a/payload_state_unittest.cc
+++ b/payload_state_unittest.cc
@@ -31,6 +31,7 @@
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/fake_system_state.h"
+#include "update_engine/metrics_reporter_interface.h"
 #include "update_engine/omaha_request_action.h"
 
 using base::Time;
@@ -102,6 +103,11 @@
   EXPECT_EQ(expected_response_sign, stored_response_sign);
 }
 
+// Compare the value of native array for download source parameter.
+MATCHER_P(DownloadSourceMatcher, source_array, "") {
+  return memcmp(source_array, arg, kNumDownloadSources) == 0;
+}
+
 class PayloadStateTest : public ::testing::Test { };
 
 TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
@@ -311,11 +317,6 @@
 
   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
-    .Times(AnyNumber());
-
   // Set the first response.
   SetupPayloadStateWith2Urls(
       "Hash5823", true, false, &payload_state, &response);
@@ -873,26 +874,9 @@
   EXPECT_EQ(p2p_total,
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricSuccessfulUpdateUrlSwitchCount,
-      3, _, _, _));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricSuccessfulUpdateTotalDurationMinutes,
-      _, _, _, _));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage,
-      314, _, _, _));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricAttemptPayloadType, kPayloadTypeFull, kNumPayloadTypes));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeFull,
-      kNumPayloadTypes));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricSuccessfulUpdateAttemptCount, 1, _, _, _));
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportSuccessfulUpdateMetrics(
+                  1, _, kPayloadTypeFull, _, _, 314, _, _, 3));
 
   payload_state.UpdateSucceeded();
 
@@ -928,12 +912,13 @@
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
 
   // Check that only HTTP is reported as a download source.
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricSuccessfulUpdateDownloadSourcesUsed,
-      (1 << kDownloadSourceHttpServer),
-      _, _, _));
+  int64_t total_bytes[kNumDownloadSources] = {};
+  total_bytes[kDownloadSourceHttpServer] = num_bytes;
+
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportSuccessfulUpdateMetrics(
+                  _, _, _, _, DownloadSourceMatcher(total_bytes), _, _, _, _))
+      .Times(1);
 
   payload_state.UpdateSucceeded();
 }
@@ -1032,15 +1017,10 @@
 
   // Check that we report only UpdateEngine.Rollback.* metrics in
   // UpdateSucceeded().
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
-    .Times(0);
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
-    .Times(0);
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
-              SendEnumToUMA(
-                  metrics::kMetricRollbackResult,
-                  static_cast<int>(metrics::RollbackResult::kSuccess),
-                  static_cast<int>(metrics::RollbackResult::kNumConstants)));
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportRollbackMetrics(metrics::RollbackResult::kSuccess))
+      .Times(1);
+
   payload_state.UpdateSucceeded();
 }
 
@@ -1140,9 +1120,8 @@
   EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
 
   // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricTimeToRebootMinutes,
-      7, _, _, _));
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportTimeToReboot(7));
   fake_system_state.set_system_rebooted(true);
 
   payload_state2.UpdateEngineStarted();
@@ -1154,6 +1133,8 @@
 TEST(PayloadStateTest, RestartAfterCrash) {
   PayloadState payload_state;
   FakeSystemState fake_system_state;
+  testing::StrictMock<MockMetrics> mock_metrics_reporter;
+  fake_system_state.set_metrics_reporter(&mock_metrics_reporter);
   NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
 
   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
@@ -1168,10 +1149,6 @@
   EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
   EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _));
 
-  // No metrics are reported after a crash.
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
-              SendToUMA(_, _, _, _, _)).Times(0);
-
   // Simulate an update_engine restart without a reboot.
   fake_system_state.set_system_rebooted(false);
 
@@ -1184,11 +1161,9 @@
 
   // If there's no marker at startup, ensure we don't report a metric.
   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
-      SendEnumToUMA(
-          metrics::kMetricAttemptResult,
-          static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
-          _)).Times(0);
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportAbnormallyTerminatedUpdateAttemptMetrics())
+      .Times(0);
   payload_state.UpdateEngineStarted();
 }
 
@@ -1204,11 +1179,9 @@
 
   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
-      SendEnumToUMA(
-          metrics::kMetricAttemptResult,
-          static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
-          _)).Times(1);
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportAbnormallyTerminatedUpdateAttemptMetrics())
+      .Times(1);
   payload_state.UpdateEngineStarted();
 
   EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
@@ -1228,15 +1201,9 @@
   response.packages.resize(1);
   payload_state.SetResponse(response);
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(),
-      SendEnumToUMA(
-          metrics::kMetricAttemptResult,
-          static_cast<int>(metrics::AttemptResult::kAbnormalTermination),
-          _)).Times(0);
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportAbnormallyTerminatedUpdateAttemptMetrics())
+      .Times(0);
 
   // Attempt not in progress, should be clear.
   EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
@@ -1335,14 +1302,9 @@
 
   // Simulate a successful download and update.
   payload_state.DownloadComplete();
-
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricAttemptPayloadType, kPayloadTypeDelta, kNumPayloadTypes));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
-      kNumPayloadTypes));
+  EXPECT_CALL(
+      *fake_system_state.mock_metrics_reporter(),
+      ReportSuccessfulUpdateMetrics(_, _, kPayloadTypeDelta, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 
   // Mock the request to a request where the delta was disabled but Omaha sends
@@ -1356,12 +1318,9 @@
 
   payload_state.DownloadComplete();
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricAttemptPayloadType, kPayloadTypeDelta,
-      kNumPayloadTypes));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeDelta,
-      kNumPayloadTypes));
+  EXPECT_CALL(
+      *fake_system_state.mock_metrics_reporter(),
+      ReportSuccessfulUpdateMetrics(_, _, kPayloadTypeDelta, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 }
 
@@ -1382,14 +1341,9 @@
   // Simulate a successful download and update.
   payload_state.DownloadComplete();
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricAttemptPayloadType, kPayloadTypeForcedFull,
-      kNumPayloadTypes));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeForcedFull,
-      kNumPayloadTypes));
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportSuccessfulUpdateMetrics(
+                  _, _, kPayloadTypeForcedFull, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 }
 
@@ -1411,14 +1365,9 @@
   // Simulate a successful download and update.
   payload_state.DownloadComplete();
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(_, _, _))
-    .Times(AnyNumber());
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricAttemptPayloadType, kPayloadTypeFull,
-      kNumPayloadTypes));
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendEnumToUMA(
-      metrics::kMetricSuccessfulUpdatePayloadType, kPayloadTypeFull,
-      kNumPayloadTypes));
+  EXPECT_CALL(
+      *fake_system_state.mock_metrics_reporter(),
+      ReportSuccessfulUpdateMetrics(_, _, kPayloadTypeFull, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 }
 
@@ -1439,27 +1388,27 @@
   payload_state.ExpectRebootInNewVersion("Version:12345678");
 
   // Reboot into the same environment to get an UMA metric with a value of 1.
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricFailedUpdateCount, 1, _, _, _));
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportFailedUpdateCount(1));
   payload_state.ReportFailedBootIfNeeded();
-  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
+  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
 
   // Simulate a second update and reboot into the same environment, this should
   // send a value of 2.
   payload_state.ExpectRebootInNewVersion("Version:12345678");
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricFailedUpdateCount, 2, _, _, _));
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportFailedUpdateCount(2));
   payload_state.ReportFailedBootIfNeeded();
-  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
+  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
 
   // Simulate a third failed reboot to new version, but this time for a
   // different payload. This should send a value of 1 this time.
   payload_state.ExpectRebootInNewVersion("Version:3141592");
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricFailedUpdateCount, 1, _, _, _));
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportFailedUpdateCount(1));
   payload_state.ReportFailedBootIfNeeded();
-  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_lib());
+  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
 }
 
 TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
@@ -1484,8 +1433,8 @@
   // Change the BootDevice to a different one, no metric should be sent.
   fake_boot_control->SetCurrentSlot(1);
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricFailedUpdateCount, _, _, _, _))
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportFailedUpdateCount(_))
       .Times(0);
   payload_state.ReportFailedBootIfNeeded();
 
@@ -1511,8 +1460,8 @@
   payload_state.UpdateSucceeded();
   payload_state.ExpectRebootInNewVersion("Version:12345678");
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricFailedUpdateCount, _, _, _, _))
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportFailedUpdateCount(_))
       .Times(0);
 
   // Cancel the applied update.
@@ -1530,8 +1479,8 @@
   fake_system_state.set_prefs(&fake_prefs);
   EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_lib(), SendToUMA(
-      metrics::kMetricFailedUpdateCount, _, _, _, _))
+  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+              ReportFailedUpdateCount(_))
       .Times(0);
 
   // Simulate a reboot in this environment.
diff --git a/real_system_state.cc b/real_system_state.cc
index d99e658..b9ffa2c 100644
--- a/real_system_state.cc
+++ b/real_system_state.cc
@@ -33,6 +33,7 @@
 #include "update_engine/common/constants.h"
 #include "update_engine/common/hardware.h"
 #include "update_engine/common/utils.h"
+#include "update_engine/metrics_reporter_omaha.h"
 #if USE_DBUS
 #include "update_engine/dbus_connection.h"
 #endif  // USE_DBUS
@@ -50,7 +51,7 @@
 }
 
 bool RealSystemState::Initialize() {
-  metrics_lib_.Init();
+  metrics_reporter_.Initialize();
 
   boot_control_ = boot_control::CreateBootControl();
   if (!boot_control_) {
diff --git a/real_system_state.h b/real_system_state.h
index 6aee0af..c95458e 100644
--- a/real_system_state.h
+++ b/real_system_state.h
@@ -22,7 +22,6 @@
 #include <memory>
 #include <set>
 
-#include <metrics/metrics_library.h>
 #include <policy/device_policy.h>
 
 #if USE_CHROME_KIOSK_APP
@@ -39,6 +38,8 @@
 #include "update_engine/common/prefs.h"
 #include "update_engine/connection_manager_interface.h"
 #include "update_engine/daemon_state_interface.h"
+#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/metrics_reporter_omaha.h"
 #include "update_engine/p2p_manager.h"
 #include "update_engine/payload_state.h"
 #include "update_engine/power_manager_interface.h"
@@ -94,8 +95,8 @@
 
   inline HardwareInterface* hardware() override { return hardware_.get(); }
 
-  inline MetricsLibraryInterface* metrics_lib() override {
-    return &metrics_lib_;
+  inline MetricsReporterInterface* metrics_reporter() override {
+    return &metrics_reporter_;
   }
 
   inline PrefsInterface* prefs() override { return prefs_.get(); }
@@ -157,8 +158,8 @@
   // Interface for the hardware functions.
   std::unique_ptr<HardwareInterface> hardware_;
 
-  // The Metrics Library interface for reporting UMA stats.
-  MetricsLibrary metrics_lib_;
+  // The Metrics reporter for reporting UMA stats.
+  MetricsReporterOmaha metrics_reporter_;
 
   // Interface for persisted store.
   std::unique_ptr<PrefsInterface> prefs_;
diff --git a/system_state.h b/system_state.h
index d538427..1b0ad08 100644
--- a/system_state.h
+++ b/system_state.h
@@ -17,8 +17,6 @@
 #ifndef UPDATE_ENGINE_SYSTEM_STATE_H_
 #define UPDATE_ENGINE_SYSTEM_STATE_H_
 
-class MetricsLibraryInterface;
-
 namespace chromeos_update_manager {
 
 class UpdateManager;
@@ -40,6 +38,7 @@
 class ClockInterface;
 class ConnectionManagerInterface;
 class HardwareInterface;
+class MetricsReporterInterface;
 class OmahaRequestParams;
 class P2PManager;
 class PayloadStateInterface;
@@ -76,7 +75,7 @@
   virtual HardwareInterface* hardware() = 0;
 
   // Gets the Metrics Library interface for reporting UMA stats.
-  virtual MetricsLibraryInterface* metrics_lib() = 0;
+  virtual MetricsReporterInterface* metrics_reporter() = 0;
 
   // Gets the interface object for persisted store.
   virtual PrefsInterface* prefs() = 0;
diff --git a/update_attempter.cc b/update_attempter.cc
index 31ebb97..9a8900d 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -50,7 +50,7 @@
 #include "update_engine/common/subprocess.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/libcurl_http_fetcher.h"
-#include "update_engine/metrics.h"
+#include "update_engine/metrics_reporter_interface.h"
 #include "update_engine/omaha_request_action.h"
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/omaha_response_handler_action.h"
@@ -179,9 +179,8 @@
 
 void UpdateAttempter::CertificateChecked(ServerToCheck server_to_check,
                                          CertificateCheckResult result) {
-  metrics::ReportCertificateCheckMetrics(system_state_,
-                                         server_to_check,
-                                         result);
+  system_state_->metrics_reporter()->ReportCertificateCheckMetrics(
+      server_to_check, result);
 }
 
 bool UpdateAttempter::CheckAndReportDailyMetrics() {
@@ -242,7 +241,7 @@
     return;
   }
 
-  metrics::ReportDailyMetrics(system_state_, age);
+  system_state_->metrics_reporter()->ReportDailyMetrics(age);
 }
 
 void UpdateAttempter::Update(const string& app_version,
@@ -270,10 +269,11 @@
     // not performing an update check because of this.
     LOG(INFO) << "Not updating b/c we already updated and we're waiting for "
               << "reboot, we'll ping Omaha instead";
-    metrics::ReportUpdateCheckMetrics(system_state_,
-                                      metrics::CheckResult::kRebootPending,
-                                      metrics::CheckReaction::kUnset,
-                                      metrics::DownloadErrorCode::kUnset);
+    system_state_->metrics_reporter()->ReportUpdateCheckMetrics(
+        system_state_,
+        metrics::CheckResult::kRebootPending,
+        metrics::CheckReaction::kUnset,
+        metrics::DownloadErrorCode::kUnset);
     PingOmaha();
     return;
   }
diff --git a/update_attempter.h b/update_attempter.h
index fb975f3..4aac60a 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -46,8 +46,6 @@
 #include "update_engine/update_manager/policy.h"
 #include "update_engine/update_manager/update_manager.h"
 
-class MetricsLibraryInterface;
-
 namespace org {
 namespace chromium {
 class NetworkProxyServiceInterfaceProxyInterface;