Measure and send update time to UMA.

BUG=4852
TEST=unit tests, gmerged, force update, looked at about:histograms.

Review URL: http://codereview.chromium.org/2868061
diff --git a/SConstruct b/SConstruct
index c3960bd..216eb1d 100644
--- a/SConstruct
+++ b/SConstruct
@@ -162,6 +162,7 @@
                        glib-2.0
                        gthread-2.0
                        libpcrecpp
+                       metrics
                        protobuf
                        pthread
                        ssl
diff --git a/main.cc b/main.cc
index 52ace9a..268bcc0 100644
--- a/main.cc
+++ b/main.cc
@@ -5,10 +5,13 @@
 #include <string>
 #include <tr1/memory>
 #include <vector>
+
 #include <gflags/gflags.h>
 #include <glib.h>
+
 #include "base/command_line.h"
 #include "chromeos/obsolete_logging.h"
+#include "metrics/metrics_library.h"
 #include "update_engine/dbus_constants.h"
 #include "update_engine/dbus_service.h"
 #include "update_engine/update_attempter.h"
@@ -102,8 +105,11 @@
   // Create the single GMainLoop
   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
 
+  MetricsLibrary metrics_lib;
+  metrics_lib.Init();
+
   // Create the update attempter:
-  chromeos_update_engine::UpdateAttempter update_attempter;
+  chromeos_update_engine::UpdateAttempter update_attempter(&metrics_lib);
 
   // Create the dbus service object:
   dbus_g_object_type_install_info(UPDATE_ENGINE_TYPE_SERVICE,
diff --git a/update_attempter.cc b/update_attempter.cc
index f4b284f..3f20126 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -13,7 +13,10 @@
 #include <tr1/memory>
 #include <string>
 #include <vector>
+
 #include <glib.h>
+
+#include "metrics/metrics_library.h"
 #include "update_engine/dbus_service.h"
 #include "update_engine/download_action.h"
 #include "update_engine/filesystem_copier_action.h"
@@ -199,6 +202,14 @@
   if (code == kActionCodeSuccess) {
     SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT);
     utils::WriteFile(kUpdateCompletedMarker, "", 0);
+
+    // Report the time it took to update the system.
+    int64_t update_time = time(NULL) - last_checked_time_;
+    metrics_lib_->SendToUMA("Installer.UpdateTime",
+                            static_cast<int>(update_time),  // sample
+                            1,  // min = 1 second
+                            20 * 60,  // max = 20 minutes
+                            50);  // buckets
   } else {
     LOG(INFO) << "Update failed.";
     SetStatusAndNotify(UPDATE_STATUS_IDLE);
diff --git a/update_attempter.h b/update_attempter.h
index 711c8ea..5eda43f 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -15,6 +15,7 @@
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/omaha_response_handler_action.h"
 
+class MetricsLibraryInterface;
 struct UpdateEngineService;
 
 namespace chromeos_update_engine {
@@ -36,12 +37,14 @@
 class UpdateAttempter : public ActionProcessorDelegate,
                         public DownloadActionDelegate {
  public:
-  UpdateAttempter() : dbus_service_(NULL),
-                      status_(UPDATE_STATUS_IDLE),
-                      download_progress_(0.0),
-                      last_checked_time_(0),
-                      new_version_("0.0.0.0"),
-                      new_size_(0) {
+  UpdateAttempter(MetricsLibraryInterface* metrics_lib)
+      : dbus_service_(NULL),
+        metrics_lib_(metrics_lib),
+        status_(UPDATE_STATUS_IDLE),
+        download_progress_(0.0),
+        last_checked_time_(0),
+        new_version_("0.0.0.0"),
+        new_size_(0) {
     last_notify_time_.tv_sec = 0;
     last_notify_time_.tv_nsec = 0;
     if (utils::FileExists(kUpdateCompletedMarker))
@@ -96,6 +99,9 @@
   // pointer to the OmahaResponseHandlerAction in the actions_ vector;
   std::tr1::shared_ptr<OmahaResponseHandlerAction> response_handler_action_;
 
+  // Pointer to the UMA metrics collection library.
+  MetricsLibraryInterface* metrics_lib_;
+
   // For status:
   UpdateStatus status_;
   double download_progress_;