Move metrics from namespace to class am: 282aa1f89d am: e5e6f9c095
am: 1e8f5d92d4

Change-Id: I52f61574115f18e3e30ee16f1739a9af809888d2
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;