Move IsOOBEComplete to HardwareInterface.

This patch moves the mockable IsOOBEComplete to the HardwareInterface
which already has a fake implemented. This is required as a first
step to make it available on the PolicyManager.

This patch also passes a null pointer when the timestamp isn't
required.

BUG=chromium:358269
TEST=Unittests adjusted and passing.

Change-Id: I620e0f4521832b3f2c0170811116251cdfe58f26
Reviewed-on: https://chromium-review.googlesource.com/193101
Reviewed-by: David Zeuthen <zeuthen@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/fake_hardware.h b/fake_hardware.h
index 5aa6a3d..06f1c30 100644
--- a/fake_hardware.h
+++ b/fake_hardware.h
@@ -7,6 +7,8 @@
 
 #include <map>
 
+#include <base/time/time.h>
+
 #include "update_engine/hardware_interface.h"
 
 namespace chromeos_update_engine {
@@ -20,6 +22,7 @@
       kernel_devices_({"/dev/sdz2", "/dev/sdz4"}),
       is_official_build_(true),
       is_normal_boot_mode_(true),
+      is_oobe_complete_(false),
       hardware_class_("Fake HWID BLAH-1234"),
       firmware_version_("Fake Firmware v1.0.1"),
       ec_version_("Fake EC v1.0a") {}
@@ -53,6 +56,12 @@
     return is_normal_boot_mode_;
   }
 
+  virtual bool IsOOBEComplete(base::Time* out_time_of_oobe) const override {
+    if (out_time_of_oobe != nullptr)
+      *out_time_of_oobe = oobe_timestamp_;
+    return is_oobe_complete_;
+  }
+
   virtual std::string GetHardwareClass() const override {
     return hardware_class_;
   }
@@ -76,6 +85,17 @@
     is_normal_boot_mode_ = is_normal_boot_mode;
   }
 
+  // Sets the IsOOBEComplete to True with the given timestamp.
+  void SetIsOOBEComplete(base::Time oobe_timestamp) {
+    is_oobe_complete_ = true;
+    oobe_timestamp_ = oobe_timestamp;
+  }
+
+  // Sets the IsOOBEComplete to False.
+  void UnsetIsOOBEComplete() {
+    is_oobe_complete_ = false;
+  }
+
   void SetHardwareClass(std::string hardware_class) {
     hardware_class_ = hardware_class;
   }
@@ -95,6 +115,8 @@
   std::map<std::string, bool> is_bootable_;
   bool is_official_build_;
   bool is_normal_boot_mode_;
+  bool is_oobe_complete_;
+  base::Time oobe_timestamp_;
   std::string hardware_class_;
   std::string firmware_version_;
   std::string ec_version_;
diff --git a/hardware.cc b/hardware.cc
index f094d97..5d5492f 100644
--- a/hardware.cc
+++ b/hardware.cc
@@ -27,6 +27,12 @@
 using std::string;
 using std::vector;
 
+namespace {
+
+static const char kOOBECompletedMarker[] = "/home/chronos/.oobe_completed";
+
+}  // namespace
+
 namespace chromeos_update_engine {
 
 Hardware::Hardware() {}
@@ -145,6 +151,21 @@
   return !dev_mode;
 }
 
+bool Hardware::IsOOBEComplete(base::Time* out_time_of_oobe) const {
+  struct stat statbuf;
+  if (stat(kOOBECompletedMarker, &statbuf) != 0) {
+    if (errno != ENOENT) {
+      PLOG(ERROR) << "Error getting information about "
+                  << kOOBECompletedMarker;
+    }
+    return false;
+  }
+
+  if (out_time_of_oobe != nullptr)
+    *out_time_of_oobe = base::Time::FromTimeT(statbuf.st_mtime);
+  return true;
+}
+
 static string ReadValueFromCrosSystem(const string& key) {
   char value_buffer[VB_MAX_STRING_PROPERTY];
 
diff --git a/hardware.h b/hardware.h
index cad5699..fdcdf13 100644
--- a/hardware.h
+++ b/hardware.h
@@ -26,6 +26,7 @@
   virtual bool MarkKernelUnbootable(const std::string& kernel_device) override;
   virtual bool IsOfficialBuild() const override;
   virtual bool IsNormalBootMode() const override;
+  virtual bool IsOOBEComplete(base::Time* out_time_of_oobe) const override;
   virtual std::string GetHardwareClass() const override;
   virtual std::string GetFirmwareVersion() const override;
   virtual std::string GetECVersion() const override;
diff --git a/hardware_interface.h b/hardware_interface.h
index c22aef5..bc7fee3 100644
--- a/hardware_interface.h
+++ b/hardware_interface.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include <base/time/time.h>
+
 namespace chromeos_update_engine {
 
 // The hardware interface allows access to the following parts of the system,
@@ -45,6 +47,11 @@
   // developer.
   virtual bool IsNormalBootMode() const = 0;
 
+  // Returns true if the OOBE process has been completed and EULA accepted,
+  // False otherwise. If True is returned, and |out_time_of_oobe| isn't null,
+  // the time-stamp of when OOBE happened is stored at |out_time_of_oobe|.
+  virtual bool IsOOBEComplete(base::Time* out_time_of_oobe) const = 0;
+
   // Returns the HWID or an empty string on error.
   virtual std::string GetHardwareClass() const = 0;
 
diff --git a/libcurl_http_fetcher.h b/libcurl_http_fetcher.h
index cc8b7a6..a59a56e 100644
--- a/libcurl_http_fetcher.h
+++ b/libcurl_http_fetcher.h
@@ -58,8 +58,7 @@
     // be waiting on the dev server to build an image.
     if (!system_state->hardware()->IsOfficialBuild())
       low_speed_time_seconds_ = kDownloadDevModeLowSpeedTimeSeconds;
-    base::Time time_oobe_complete;
-    if (!system_state_->IsOOBEComplete(&time_oobe_complete))
+    if (!system_state_->hardware()->IsOOBEComplete(nullptr))
       max_retry_count_ = kDownloadMaxRetryCountOobeNotComplete;
   }
 
diff --git a/mock_hardware.h b/mock_hardware.h
index 6b1da8e..a996896 100644
--- a/mock_hardware.h
+++ b/mock_hardware.h
@@ -37,6 +37,9 @@
     ON_CALL(*this, IsNormalBootMode())
       .WillByDefault(testing::Invoke(&fake_,
             &FakeHardware::IsNormalBootMode));
+    ON_CALL(*this, IsOOBEComplete(testing::_))
+      .WillByDefault(testing::Invoke(&fake_,
+            &FakeHardware::IsOOBEComplete));
     ON_CALL(*this, GetHardwareClass())
       .WillByDefault(testing::Invoke(&fake_,
             &FakeHardware::GetHardwareClass));
@@ -60,6 +63,7 @@
                bool(const std::string& kernel_device));
   MOCK_CONST_METHOD0(IsOfficialBuild, bool());
   MOCK_CONST_METHOD0(IsNormalBootMode, bool());
+  MOCK_CONST_METHOD1(IsOOBEComplete, bool(base::Time* out_time_of_oobe));
   MOCK_CONST_METHOD0(GetHardwareClass, std::string());
   MOCK_CONST_METHOD0(GetFirmwareVersion, std::string());
   MOCK_CONST_METHOD0(GetECVersion, std::string());
diff --git a/mock_system_state.h b/mock_system_state.h
index 33d1b1e..19efaf1 100644
--- a/mock_system_state.h
+++ b/mock_system_state.h
@@ -33,8 +33,6 @@
 
   virtual ~MockSystemState();
 
-  MOCK_METHOD1(IsOOBEComplete, bool(base::Time*));
-
   MOCK_METHOD1(set_device_policy, void(const policy::DevicePolicy*));
   MOCK_CONST_METHOD0(device_policy, const policy::DevicePolicy*());
   MOCK_METHOD0(system_rebooted, bool());
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 8e372b5..bd5993d 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -380,7 +380,7 @@
   // inspecting the timestamp of when OOBE happened.
 
   Time time_of_oobe;
-  if (!system_state->IsOOBEComplete(&time_of_oobe)) {
+  if (!system_state->hardware()->IsOOBEComplete(&time_of_oobe)) {
     LOG(INFO) << "Not generating Omaha InstallData as we have "
               << "no prefs file and OOBE is not complete.";
     return -1;
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index fdfb590..0bc5538 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -2255,30 +2255,24 @@
   // prefs. However, first try with an invalid date and check we do
   // nothing.
   {
-    NiceMock<MockSystemState> system_state;
-    system_state.set_prefs(&prefs);
+    NiceMock<MockSystemState> mock_system_state;
+    mock_system_state.set_prefs(&prefs);
 
     Time oobe_date = Time::FromTimeT(42); // Dec 31, 1969 16:00:42 PST.
-    EXPECT_CALL(system_state,
-                IsOOBEComplete(_))
-                .WillRepeatedly(DoAll(SetArgumentPointee<0>(oobe_date),
-                                      Return(true)));
-    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&system_state), -1);
+    mock_system_state.get_fake_hardware()->SetIsOOBEComplete(oobe_date);
+    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&mock_system_state), -1);
     EXPECT_FALSE(prefs.Exists(kPrefsInstallDateDays));
   }
 
   // Then check with a valid date. The date Jan 20, 2007 0:00 PST
   // should yield an InstallDate of 14.
   {
-    NiceMock<MockSystemState> system_state;
-    system_state.set_prefs(&prefs);
+    NiceMock<MockSystemState> mock_system_state;
+    mock_system_state.set_prefs(&prefs);
 
     Time oobe_date = Time::FromTimeT(1169280000); // Jan 20, 2007 0:00 PST.
-    EXPECT_CALL(system_state,
-                IsOOBEComplete(_))
-                .WillRepeatedly(DoAll(SetArgumentPointee<0>(oobe_date),
-                                      Return(true)));
-    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&system_state), 14);
+    mock_system_state.get_fake_hardware()->SetIsOOBEComplete(oobe_date);
+    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&mock_system_state), 14);
     EXPECT_TRUE(prefs.Exists(kPrefsInstallDateDays));
 
     int64_t prefs_days;
@@ -2291,15 +2285,12 @@
   // 2007 0:00 PST should yield an InstallDate of 28... but since
   // there's a prefs file, we should still get 14.
   {
-    NiceMock<MockSystemState> system_state;
-    system_state.set_prefs(&prefs);
+    NiceMock<MockSystemState> mock_system_state;
+    mock_system_state.set_prefs(&prefs);
 
     Time oobe_date = Time::FromTimeT(1170144000); // Jan 30, 2007 0:00 PST.
-    EXPECT_CALL(system_state,
-                IsOOBEComplete(_))
-                .WillRepeatedly(DoAll(SetArgumentPointee<0>(oobe_date),
-                                      Return(true)));
-    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&system_state), 14);
+    mock_system_state.get_fake_hardware()->SetIsOOBEComplete(oobe_date);
+    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&mock_system_state), 14);
 
     int64_t prefs_days;
     EXPECT_TRUE(prefs.GetInt64(kPrefsInstallDateDays, &prefs_days));
@@ -2307,7 +2298,7 @@
 
     // If we delete the prefs file, we should get 28 days.
     EXPECT_TRUE(prefs.Delete(kPrefsInstallDateDays));
-    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&system_state), 28);
+    EXPECT_EQ(OmahaRequestAction::GetInstallDate(&mock_system_state), 28);
     EXPECT_TRUE(prefs.GetInt64(kPrefsInstallDateDays, &prefs_days));
     EXPECT_EQ(prefs_days, 28);
   }
diff --git a/real_system_state.cc b/real_system_state.cc
index 936e819..ac1ea25 100644
--- a/real_system_state.cc
+++ b/real_system_state.cc
@@ -13,8 +13,6 @@
 
 namespace chromeos_update_engine {
 
-static const char kOOBECompletedMarker[] = "/home/chronos/.oobe_completed";
-
 RealSystemState::RealSystemState()
     : device_policy_(nullptr),
       connection_manager_(this),
@@ -76,19 +74,4 @@
   return true;
 }
 
-bool RealSystemState::IsOOBEComplete(base::Time* out_time_of_oobe) {
-  struct stat statbuf;
-  if (stat(kOOBECompletedMarker, &statbuf) != 0) {
-    if (errno != ENOENT) {
-      PLOG(ERROR) << "Error getting information about "
-                  << kOOBECompletedMarker;
-    }
-    return false;
-  }
-
-  if (out_time_of_oobe != NULL)
-    *out_time_of_oobe = base::Time::FromTimeT(statbuf.st_mtime);
-  return true;
-}
-
 }  // namespace chromeos_update_engine
diff --git a/real_system_state.h b/real_system_state.h
index baa9c60..ed24ed8 100644
--- a/real_system_state.h
+++ b/real_system_state.h
@@ -28,8 +28,6 @@
   RealSystemState();
   virtual ~RealSystemState() {}
 
-  virtual bool IsOOBEComplete(base::Time* out_time_of_oobe);
-
   virtual inline void set_device_policy(
       const policy::DevicePolicy* device_policy) {
     device_policy_ = device_policy;
diff --git a/system_state.h b/system_state.h
index 2148b51..ce561e1 100644
--- a/system_state.h
+++ b/system_state.h
@@ -5,7 +5,6 @@
 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_SYSTEM_STATE_H_
 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_SYSTEM_STATE_H_
 
-#include <base/time/time.h>
 #include "metrics/metrics_library.h"
 #include <policy/device_policy.h>
 #include <policy/libpolicy.h>
@@ -45,11 +44,6 @@
   // Destructs this object.
   virtual ~SystemState() {}
 
-  // Returns true if the OOBE process has been completed and EULA
-  // accepted, False otherwise. If True is returned, the time-stamp
-  // of when OOBE happened is returned in |out_time_of_oobe|.
-  virtual bool IsOOBEComplete(base::Time* out_time_of_oobe) = 0;
-
   // Sets or gets the latest device policy.
   virtual void set_device_policy(const policy::DevicePolicy* device_policy) = 0;
   virtual const policy::DevicePolicy* device_policy() const = 0;
diff --git a/update_attempter.cc b/update_attempter.cc
index f3f6d4e..be76a8e 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -489,12 +489,11 @@
   }
 
   bool is_scatter_enabled = false;
-  base::Time time_oobe_complete;
   if (scatter_factor_.InSeconds() == 0) {
     LOG(INFO) << "Scattering disabled since scatter factor is set to 0";
   } else if (interactive) {
     LOG(INFO) << "Scattering disabled as this is an interactive update check";
-  } else if (!system_state_->IsOOBEComplete(&time_oobe_complete)) {
+  } else if (!system_state_->hardware()->IsOOBEComplete(nullptr)) {
     LOG(INFO) << "Scattering disabled since OOBE is not complete yet";
   } else {
     is_scatter_enabled = true;
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index b623aec..2148c06 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -920,10 +920,7 @@
   Prefs prefs;
   attempter_.prefs_ = &prefs;
 
-  EXPECT_CALL(mock_system_state_,
-              IsOOBEComplete(_))
-              .WillRepeatedly(DoAll(SetArgumentPointee<0>(Time::UnixEpoch()),
-                                    Return(true)));
+  mock_system_state_.get_fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
 
   string prefs_dir;
   EXPECT_TRUE(utils::MakeTempDirectory("ue_ut_prefs.XXXXXX",
@@ -987,10 +984,7 @@
   Prefs prefs;
   attempter_.prefs_ = &prefs;
 
-  EXPECT_CALL(mock_system_state_,
-              IsOOBEComplete(_))
-              .WillRepeatedly(DoAll(SetArgumentPointee<0>(Time::UnixEpoch()),
-                                    Return(true)));
+  mock_system_state_.get_fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
 
   string prefs_dir;
   EXPECT_TRUE(utils::MakeTempDirectory("ue_ut_prefs.XXXXXX",
diff --git a/update_check_scheduler.cc b/update_check_scheduler.cc
index 096387b..45a28ae 100644
--- a/update_check_scheduler.cc
+++ b/update_check_scheduler.cc
@@ -89,8 +89,7 @@
 
   bool is_test_mode = false;
   GpioHandler* gpio_handler = me->system_state_->gpio_handler();
-  base::Time time_oobe_complete;
-  if (me->system_state_->IsOOBEComplete(&time_oobe_complete) ||
+  if (me->system_state_->hardware()->IsOOBEComplete(nullptr) ||
       (is_test_mode = (!me->is_test_update_attempted_ &&
                        gpio_handler->IsTestModeSignaled()))) {
     if (is_test_mode) {
diff --git a/update_check_scheduler_unittest.cc b/update_check_scheduler_unittest.cc
index 62eb876..0eed080 100644
--- a/update_check_scheduler_unittest.cc
+++ b/update_check_scheduler_unittest.cc
@@ -281,10 +281,8 @@
 TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
   scheduler_.scheduled_ = true;
   EXPECT_TRUE(scheduler_.mock_system_state_ != NULL);
-  EXPECT_CALL(*scheduler_.mock_system_state_,
-              IsOOBEComplete(_)).Times(1)
-              .WillOnce(DoAll(SetArgumentPointee<0>(Time::UnixEpoch()),
-                              Return(true)));
+  scheduler_.mock_system_state_->get_fake_hardware()->SetIsOOBEComplete(
+      Time::UnixEpoch());
   EXPECT_CALL(attempter_, Update("", "", false, false, false))
       .Times(1)
       .WillOnce(Assign(&scheduler_.scheduled_, true));
@@ -295,10 +293,7 @@
 
 TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
   scheduler_.scheduled_ = true;
-  EXPECT_CALL(*scheduler_.mock_system_state_,
-              IsOOBEComplete(_)).Times(1)
-              .WillOnce(DoAll(SetArgumentPointee<0>(Time::UnixEpoch()),
-                              Return(false)));
+  scheduler_.mock_system_state_->get_fake_hardware()->UnsetIsOOBEComplete();
   EXPECT_CALL(attempter_, Update("", "", _, _, _)).Times(0);
   int interval_min, interval_max;
   FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,