Add D-Bus method to get the duration since an update completed.

This new API can be used by Chrome to automatically reboot the device
at N hours after updating. This is implemented as a D-Bus method that
returns the number of micro-seconds on the wall-clock since the update
completed. If the device has not updated, the D-Bus method returns an
error.

For robustness, durations are measured using the CLOCK_BOOTTIME clock
instead of the usual CLOCK_REALTIME clock. This avoids interference
with NTP adjustments, the RTC clock being wrong and other things.

BUG=chromium:218192
TEST=New unit test + unit tests pass + manual test on a device using
    the gdbus(1) command as the chronos user.

Change-Id: I51d44d69afe2d3024bb0780916c3c4e3f8ebb19e
Reviewed-on: https://chromium-review.googlesource.com/173032
Reviewed-by: David Zeuthen <zeuthen@chromium.org>
Commit-Queue: David Zeuthen <zeuthen@chromium.org>
Tested-by: David Zeuthen <zeuthen@chromium.org>
diff --git a/dbus_service.cc b/dbus_service.cc
index 42bcfa3..956b73b 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -10,6 +10,7 @@
 #include <base/logging.h>
 #include <policy/device_policy.h>
 
+#include "update_engine/clock_interface.h"
 #include "update_engine/connection_manager.h"
 #include "update_engine/dbus_constants.h"
 #include "update_engine/hardware_interface.h"
@@ -347,6 +348,20 @@
   return TRUE;
 }
 
+gboolean update_engine_service_get_duration_since_update(
+    UpdateEngineService* self,
+    gint64* out_usec_wallclock,
+    GError **/*error*/) {
+
+  base::Time time;
+  if (!self->system_state_->update_attempter()->GetBootTimeAtUpdate(&time))
+    return FALSE;
+
+  chromeos_update_engine::ClockInterface *clock = self->system_state_->clock();
+  *out_usec_wallclock = (clock->GetBootTime() - time).InMicroseconds();
+  return TRUE;
+}
+
 gboolean update_engine_service_emit_status_update(
     UpdateEngineService* self,
     gint64 last_checked_time,