Measure and send update duration (and corresponding uptime) to UMA

This patch introduces two new metrics, Installer.UpdateDuration and
Installer.UpdateDurationUptime. The former is the timespan from when
the update was first discovered until it has been downloaded and
applied (including the time the device is suspended or powered
off). The latter is similar, but without taking into account time
spent in suspend or powered off.

For example, if the device is suspended (or powered off) for N seconds
while updating, the Installer.UpdateDuration metric will be N seconds
bigger than Installer.UpdateDurationUptime metric:

 Histogram: Installer.UpdateDuration recorded 1 samples, average = 313.0
 Histogram: Installer.UpdateDurationUptime recorded 1 samples, average = 251.0

Also remove the existing Installer.UpdateTime metric as this didn't
take process restarts into account and is now superseeded by the
Installer.UpdateDuration metric.

This is done by using the CLOCK_MONOTONIC_RAW clock (available in
Linux 2.6.28 and later) since this clock indeed does not advance when
the system is sleeping.

We use the PayloadState class to persist recorded data across
update_engine process restart (including device reboots).

Since clock_gettime(2) and CLOCK_MONOTONIC_RAW requires linking to the
librt library do this and also request the system header files to
expose the required symbols and defines, i.e. define _POSIX_C_SOURCE
>= 199309L.

Also remove _POSIX_C_SOURCE mangling from update_attempter.cc since
it's actually not needed there and generally it's better to make the
environment the same across all translation units (by putting whatever
is needed in e.g. CCFLAGS).

BUG=chromium:226763
TEST=unit tests, force update, examine chrome://histograms

Change-Id: I883668564b5fa78ff3e19156bd77496ff929ca58
Signed-off-by: David Zeuthen <zeuthen@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/47928
Reviewed-by: Jay Srinivasan <jaysri@chromium.org>
diff --git a/payload_state.h b/payload_state.h
index eb9d655..0557d0a 100644
--- a/payload_state.h
+++ b/payload_state.h
@@ -40,6 +40,7 @@
   virtual void SetResponse(const OmahaResponse& response);
   virtual void DownloadComplete();
   virtual void DownloadProgress(size_t count);
+  virtual void UpdateSucceeded();
   virtual void UpdateFailed(ActionExitCode error);
   virtual bool ShouldBackoffDownload();
 
@@ -63,6 +64,10 @@
     return backoff_expiry_time_;
   }
 
+  virtual base::TimeDelta GetUpdateDuration();
+
+  virtual base::TimeDelta GetUpdateDurationUptime();
+
  private:
   // Increments the payload attempt number which governs the backoff behavior
   // at the time of the next update check.
@@ -132,6 +137,36 @@
   // restart.
   void SetBackoffExpiryTime(const base::Time& new_time);
 
+  // Initializes |update_timestamp_start_| from the persisted state.
+  void LoadUpdateTimestampStart();
+
+  // Sets |update_timestamp_start_| to the given value and persists the value.
+  void SetUpdateTimestampStart(const base::Time& value);
+
+  // Sets |update_timestamp_end_| to the given value. This is not persisted
+  // as it happens at the end of the update process where state is deleted
+  // anyway.
+  void SetUpdateTimestampEnd(const base::Time& value);
+
+  // Initializes |update_duration_uptime_| from the persisted state.
+  void LoadUpdateDurationUptime();
+
+  // Helper method used in SetUpdateDurationUptime() and
+  // CalculateUpdateDurationUptime().
+  void SetUpdateDurationUptimeExtended(const base::TimeDelta& value,
+                                       const base::Time& timestamp,
+                                       bool use_logging);
+
+  // Sets |update_duration_uptime_| to the given value and persists
+  // the value and sets |update_duration_uptime_timestamp_| to the
+  // current monotonic time.
+  void SetUpdateDurationUptime(const base::TimeDelta& value);
+
+  // Adds the difference between current monotonic time and
+  // |update_duration_uptime_timestamp_| to |update_duration_uptime_| and
+  // sets |update_duration_uptime_timestamp_| to current monotonic time.
+  void CalculateUpdateDurationUptime();
+
   // Interface object with which we read/write persisted state. This must
   // be set by calling the Initialize method before calling any other method.
   PrefsInterface* prefs_;
@@ -168,6 +203,22 @@
   // payload again, so as to backoff repeated downloads.
   base::Time backoff_expiry_time_;
 
+  // The most recently calculated value of the update duration.
+  base::TimeDelta update_duration_current_;
+
+  // The point in time (wall-clock) that the update was started.
+  base::Time update_timestamp_start_;
+
+  // The point in time (wall-clock) that the update ended. If the update
+  // is still in progress, this is set to the Epoch (e.g. 0).
+  base::Time update_timestamp_end_;
+
+  // The update duration uptime
+  base::TimeDelta update_duration_uptime_;
+
+  // The monotonic time when |update_duration_uptime_| was last set
+  base::Time update_duration_uptime_timestamp_;
+
   // Returns the number of URLs in the current response.
   // Note: This value will be 0 if this method is called before we receive
   // the first valid Omaha response in this process.
@@ -175,6 +226,11 @@
     return response_.payload_urls.size();
   }
 
+  // A small timespan used when comparing wall-clock times for coping
+  // with the fact that clocks drift and consequently are adjusted
+  // (either forwards or backwards) via NTP.
+  static const base::TimeDelta kDurationSlack;
+
   DISALLOW_COPY_AND_ASSIGN(PayloadState);
 };