update_engine: Add metrics to duration to apply an update.

Add new metrics that record the time between an update being seen by the client
to the time when the update is actually applied.

This metric will be recorded only for Enterprise enrolled devices.

UpdateEngine.SuccessfulUpdate.TimeRestrictedDurationFromSeenToUpdateMinutes is
recorded when an update is applied while the
DeviceAutoUpdateTimeRestrictions device policy exists.

UpdateEngine.SuccessfulUpdate.DurationFromSeenToUpdateMinutes is
recorded when an update is applied without the policy.

BUG=chromium:852860
TEST=run updater manually and checked chrome://histograms

Change-Id: I4dd54fc4404ef2e66902113617841808c1f9e616
Reviewed-on: https://chromium-review.googlesource.com/1179230
Commit-Ready: May Lippert <maybelle@chromium.org>
Tested-by: May Lippert <maybelle@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Sen Jiang <senj@chromium.org>
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index 1e0ad6d..5b00238 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -1164,6 +1164,8 @@
   request_params_.set_update_check_count_wait_enabled(false);
   request_params_.set_waiting_period(TimeDelta::FromDays(2));
 
+  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+
   ASSERT_FALSE(TestUpdateCheck(fake_update_response_.GetUpdateResponse(),
                                -1,
                                false,  // ping_only
@@ -1239,6 +1241,8 @@
   request_params_.set_min_update_checks_needed(0);
   request_params_.set_max_update_checks_allowed(0);
 
+  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+
   ASSERT_TRUE(TestUpdateCheck(
                       fake_update_response_.GetUpdateResponse(),
                       -1,
@@ -1264,6 +1268,8 @@
   request_params_.set_min_update_checks_needed(1);
   request_params_.set_max_update_checks_allowed(8);
 
+  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+
   ASSERT_FALSE(TestUpdateCheck(
                       fake_update_response_.GetUpdateResponse(),
                       -1,
@@ -1302,6 +1308,8 @@
   request_params_.set_min_update_checks_needed(1);
   request_params_.set_max_update_checks_allowed(8);
 
+  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+
   ASSERT_TRUE(fake_prefs_.SetInt64(kPrefsUpdateCheckCount, 5));
 
   ASSERT_FALSE(TestUpdateCheck(
@@ -1344,6 +1352,8 @@
   request_params_.set_waiting_period(TimeDelta::FromDays(6));
   request_params_.set_update_check_count_wait_enabled(false);
 
+  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+
   ASSERT_TRUE(fake_prefs_.SetInt64(kPrefsWallClockStagingWaitPeriod, 6));
   // This should not prevent scattering due to staging.
   fake_update_response_.max_days_to_scatter = "0";
@@ -3008,4 +3018,51 @@
   EXPECT_EQ(4, response.rollback_key_version.kernel);
 }
 
+TEST_F(OmahaRequestActionTest,
+       TestUpdateFirstSeenAtPrefPersistedIfUpdateExists) {
+  FakeClock fake_clock;
+  Time now = Time::Now();
+  fake_clock.SetWallclockTime(now);
+  fake_system_state_.set_clock(&fake_clock);
+
+  OmahaResponse response;
+  ASSERT_TRUE(TestUpdateCheck(fake_update_response_.GetUpdateResponse(),
+                              -1,
+                              false,  // ping_only
+                              ErrorCode::kSuccess,
+                              metrics::CheckResult::kUpdateAvailable,
+                              metrics::CheckReaction::kUpdating,
+                              metrics::DownloadErrorCode::kUnset,
+                              &response,
+                              nullptr));
+  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(fake_prefs_.Exists(kPrefsUpdateFirstSeenAt));
+
+  int64_t stored_first_seen_at_time;
+  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt,
+                                   &stored_first_seen_at_time));
+  EXPECT_EQ(now.ToInternalValue(), stored_first_seen_at_time);
+}
+
+TEST_F(OmahaRequestActionTest,
+       TestUpdateFirstSeenAtPrefNotPersistedIfUpdateFails) {
+  FakeClock fake_clock;
+  Time now = Time::Now();
+  fake_clock.SetWallclockTime(now);
+  fake_system_state_.set_clock(&fake_clock);
+
+  OmahaResponse response;
+  ASSERT_TRUE(TestUpdateCheck(fake_update_response_.GetNoUpdateResponse(),
+                              -1,
+                              false,  // ping_only
+                              ErrorCode::kSuccess,
+                              metrics::CheckResult::kNoUpdateAvailable,
+                              metrics::CheckReaction::kUnset,
+                              metrics::DownloadErrorCode::kUnset,
+                              &response,
+                              nullptr));
+  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(fake_prefs_.Exists(kPrefsUpdateFirstSeenAt));
+}
+
 }  // namespace chromeos_update_engine