Make Hardware class platform specific.

The Hardware class abstracts the interaction with the actual hardware
which is inherently platform-specific. This patch implementes a stub
version for Android and moves the Chromium OS implementation, handling
both with the same public factory method.

Bug: 23084776
TEST=emerge-link update_engine; `mma -i` builds the stubs.

Change-Id: I19c791a2e3fa22f0ac38bbe68a9c47838bcf019a
diff --git a/fake_hardware.h b/fake_hardware.h
index 5d3da1a..686c1cc 100644
--- a/fake_hardware.h
+++ b/fake_hardware.h
@@ -19,7 +19,6 @@
 
 #include <map>
 #include <string>
-#include <vector>
 
 #include <base/time/time.h>
 
diff --git a/hardware.h b/hardware.h
index 4f03cf1..4d52bb9 100644
--- a/hardware.h
+++ b/hardware.h
@@ -17,34 +17,18 @@
 #ifndef UPDATE_ENGINE_HARDWARE_H_
 #define UPDATE_ENGINE_HARDWARE_H_
 
-#include <string>
-#include <vector>
-
-#include <base/macros.h>
+#include <memory>
 
 #include "update_engine/hardware_interface.h"
 
 namespace chromeos_update_engine {
+namespace hardware {
 
-// Implements the real interface with the hardware.
-class Hardware : public HardwareInterface {
- public:
-  Hardware() = default;
-  ~Hardware() override = default;
+// The real HardwareInterface is platform-specific. This factory function
+// creates a new HardwareInterface instance for the current platform.
+std::unique_ptr<HardwareInterface> CreateHardware();
 
-  // HardwareInterface methods.
-  bool IsOfficialBuild() const override;
-  bool IsNormalBootMode() const override;
-  bool IsOOBEComplete(base::Time* out_time_of_oobe) const override;
-  std::string GetHardwareClass() const override;
-  std::string GetFirmwareVersion() const override;
-  std::string GetECVersion() const override;
-  int GetPowerwashCount() const override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Hardware);
-};
-
+}  // namespace hardware
 }  // namespace chromeos_update_engine
 
 #endif  // UPDATE_ENGINE_HARDWARE_H_
diff --git a/hardware_android.cc b/hardware_android.cc
new file mode 100644
index 0000000..5c76989
--- /dev/null
+++ b/hardware_android.cc
@@ -0,0 +1,76 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/hardware_android.h"
+
+#include <chromeos/make_unique_ptr.h>
+
+#include "update_engine/hardware.h"
+
+using std::string;
+
+namespace chromeos_update_engine {
+
+namespace hardware {
+
+// Factory defined in hardware.h.
+std::unique_ptr<HardwareInterface> CreateHardware() {
+  return chromeos::make_unique_ptr(new HardwareAndroid());
+}
+
+}  // namespace hardware
+
+bool HardwareAndroid::IsOfficialBuild() const {
+  // TODO(deymo): Read the kind of build we are running from the metadata
+  // partition.
+  LOG(WARNING) << "STUB: Assuming we are not an official build.";
+  return false;
+}
+
+bool HardwareAndroid::IsNormalBootMode() const {
+  // TODO(deymo): Read the kind of build we are running from the metadata
+  // partition.
+  LOG(WARNING) << "STUB: Assuming we are in dev-mode.";
+  return false;
+}
+
+bool HardwareAndroid::IsOOBEComplete(base::Time* out_time_of_oobe) const {
+  LOG(WARNING) << "STUB: Assuming OOBE is complete.";
+  *out_time_of_oobe = base::Time();
+  return true;
+}
+
+string HardwareAndroid::GetHardwareClass() const {
+  LOG(WARNING) << "STUB: GetHardwareClass().";
+  return "ANDROID";
+}
+
+string HardwareAndroid::GetFirmwareVersion() const {
+  LOG(WARNING) << "STUB: GetFirmwareVersion().";
+  return "0";
+}
+
+string HardwareAndroid::GetECVersion() const {
+  LOG(WARNING) << "STUB: GetECVersion().";
+  return "0";
+}
+
+int HardwareAndroid::GetPowerwashCount() const {
+  LOG(WARNING) << "STUB: Assuming no factory reset was performed.";
+  return 0;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/hardware_android.h b/hardware_android.h
new file mode 100644
index 0000000..0a341c0
--- /dev/null
+++ b/hardware_android.h
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_HARDWARE_ANDROID_H_
+#define UPDATE_ENGINE_HARDWARE_ANDROID_H_
+
+#include <string>
+
+#include <base/macros.h>
+#include <base/time/time.h>
+
+#include "update_engine/hardware.h"
+#include "update_engine/hardware_interface.h"
+
+namespace chromeos_update_engine {
+
+// Implements the real interface with the hardware in the Android platform.
+class HardwareAndroid final : public HardwareInterface {
+ public:
+  HardwareAndroid() = default;
+  ~HardwareAndroid() override = default;
+
+  // HardwareInterface methods.
+  bool IsOfficialBuild() const override;
+  bool IsNormalBootMode() const override;
+  bool IsOOBEComplete(base::Time* out_time_of_oobe) const override;
+  std::string GetHardwareClass() const override;
+  std::string GetFirmwareVersion() const override;
+  std::string GetECVersion() const override;
+  int GetPowerwashCount() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HardwareAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_HARDWARE_ANDROID_H_
diff --git a/hardware.cc b/hardware_chromeos.cc
similarity index 81%
rename from hardware.cc
rename to hardware_chromeos.cc
index 96edaa5..888772d 100644
--- a/hardware.cc
+++ b/hardware_chromeos.cc
@@ -14,18 +14,20 @@
 // limitations under the License.
 //
 
-#include "update_engine/hardware.h"
+#include "update_engine/hardware_chromeos.h"
 
 #include <base/files/file_util.h>
 #include <base/logging.h>
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/string_util.h>
+#include <chromeos/make_unique_ptr.h>
 #include <vboot/crossystem.h>
 
 extern "C" {
 #include "vboot/vboot_host.h"
 }
 
+#include "update_engine/hardware.h"
 #include "update_engine/hwid_override.h"
 #include "update_engine/subprocess.h"
 #include "update_engine/utils.h"
@@ -47,17 +49,26 @@
 
 namespace chromeos_update_engine {
 
-bool Hardware::IsOfficialBuild() const {
+namespace hardware {
+
+// Factory defined in hardware.h.
+std::unique_ptr<HardwareInterface> CreateHardware() {
+  return chromeos::make_unique_ptr(new HardwareChromeOS());
+}
+
+}  // namespace hardware
+
+bool HardwareChromeOS::IsOfficialBuild() const {
   return VbGetSystemPropertyInt("debug_build") == 0;
 }
 
-bool Hardware::IsNormalBootMode() const {
+bool HardwareChromeOS::IsNormalBootMode() const {
   bool dev_mode = VbGetSystemPropertyInt("devsw_boot") != 0;
   LOG_IF(INFO, dev_mode) << "Booted in dev mode.";
   return !dev_mode;
 }
 
-bool Hardware::IsOOBEComplete(base::Time* out_time_of_oobe) const {
+bool HardwareChromeOS::IsOOBEComplete(base::Time* out_time_of_oobe) const {
   struct stat statbuf;
   if (stat(kOOBECompletedMarker, &statbuf) != 0) {
     if (errno != ENOENT) {
@@ -75,7 +86,7 @@
 static string ReadValueFromCrosSystem(const string& key) {
   char value_buffer[VB_MAX_STRING_PROPERTY];
 
-  const char *rv = VbGetSystemPropertyString(key.c_str(), value_buffer,
+  const char* rv = VbGetSystemPropertyString(key.c_str(), value_buffer,
                                              sizeof(value_buffer));
   if (rv != nullptr) {
     string return_value(value_buffer);
@@ -87,18 +98,18 @@
   return "";
 }
 
-string Hardware::GetHardwareClass() const {
+string HardwareChromeOS::GetHardwareClass() const {
   if (USE_HWID_OVERRIDE) {
     return HwidOverride::Read(base::FilePath("/"));
   }
   return ReadValueFromCrosSystem("hwid");
 }
 
-string Hardware::GetFirmwareVersion() const {
+string HardwareChromeOS::GetFirmwareVersion() const {
   return ReadValueFromCrosSystem("fwid");
 }
 
-string Hardware::GetECVersion() const {
+string HardwareChromeOS::GetECVersion() const {
   string input_line;
   int exit_code = 0;
   vector<string> cmd = {"/usr/sbin/mosys", "-k", "ec", "info"};
@@ -112,7 +123,7 @@
   return utils::ParseECVersion(input_line);
 }
 
-int Hardware::GetPowerwashCount() const {
+int HardwareChromeOS::GetPowerwashCount() const {
   int powerwash_count;
   string contents;
   if (!utils::ReadFile(kPowerwashCountMarker, &contents))
diff --git a/hardware_chromeos.h b/hardware_chromeos.h
new file mode 100644
index 0000000..56f5ba8
--- /dev/null
+++ b/hardware_chromeos.h
@@ -0,0 +1,52 @@
+//
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
+#define UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <base/time/time.h>
+
+#include "update_engine/hardware_interface.h"
+
+namespace chromeos_update_engine {
+
+// Implements the real interface with Chrome OS verified boot and recovery
+// process.
+class HardwareChromeOS final : public HardwareInterface {
+ public:
+  HardwareChromeOS() = default;
+  ~HardwareChromeOS() override = default;
+
+  // HardwareInterface methods.
+  bool IsOfficialBuild() const override;
+  bool IsNormalBootMode() const override;
+  bool IsOOBEComplete(base::Time* out_time_of_oobe) const override;
+  std::string GetHardwareClass() const override;
+  std::string GetFirmwareVersion() const override;
+  std::string GetECVersion() const override;
+  int GetPowerwashCount() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HardwareChromeOS);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
diff --git a/mock_hardware.h b/mock_hardware.h
index 5cdccb9..e082a4f 100644
--- a/mock_hardware.h
+++ b/mock_hardware.h
@@ -18,7 +18,6 @@
 #define UPDATE_ENGINE_MOCK_HARDWARE_H_
 
 #include <string>
-#include <vector>
 
 #include "update_engine/fake_hardware.h"
 
diff --git a/real_system_state.cc b/real_system_state.cc
index c89f297..7dfa012 100644
--- a/real_system_state.cc
+++ b/real_system_state.cc
@@ -21,6 +21,7 @@
 
 #include "update_engine/boot_control_chromeos.h"
 #include "update_engine/constants.h"
+#include "update_engine/hardware.h"
 #include "update_engine/update_manager/state_factory.h"
 #include "update_engine/utils.h"
 
@@ -44,6 +45,12 @@
     LOG(ERROR) << "Ignoring BootControlChromeOS failure. We won't run updates.";
   }
 
+  hardware_ = hardware::CreateHardware();
+  if (!hardware_) {
+    LOG(ERROR) << "Error intializing the HardwareInterface.";
+    return false;
+  }
+
   if (!shill_proxy_.Init()) {
     LOG(ERROR) << "Failed to initialize shill proxy.";
     return false;
diff --git a/real_system_state.h b/real_system_state.h
index 31cf4da..5797d18 100644
--- a/real_system_state.h
+++ b/real_system_state.h
@@ -30,7 +30,7 @@
 #include "update_engine/boot_control_interface.h"
 #include "update_engine/clock.h"
 #include "update_engine/connection_manager.h"
-#include "update_engine/hardware.h"
+#include "update_engine/hardware_interface.h"
 #include "update_engine/p2p_manager.h"
 #include "update_engine/payload_state.h"
 #include "update_engine/prefs.h"
@@ -71,7 +71,7 @@
     return &connection_manager_;
   }
 
-  inline HardwareInterface* hardware() override { return &hardware_; }
+  inline HardwareInterface* hardware() override { return hardware_.get(); }
 
   inline MetricsLibraryInterface* metrics_lib() override {
     return &metrics_lib_;
@@ -130,7 +130,7 @@
   ConnectionManager connection_manager_{&shill_proxy_, this};
 
   // Interface for the hardware functions.
-  Hardware hardware_;
+  std::unique_ptr<HardwareInterface> hardware_;
 
   // The Metrics Library interface for reporting UMA stats.
   MetricsLibrary metrics_lib_;
diff --git a/update_engine.gyp b/update_engine.gyp
index 0f0a770..5d1ce97 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -173,7 +173,7 @@
         'file_descriptor.cc',
         'file_writer.cc',
         'filesystem_verifier_action.cc',
-        'hardware.cc',
+        'hardware_chromeos.cc',
         'http_common.cc',
         'http_fetcher.cc',
         'hwid_override.cc',
diff --git a/update_manager/real_system_provider.cc b/update_manager/real_system_provider.cc
index d0d788d..90173a0 100644
--- a/update_manager/real_system_provider.cc
+++ b/update_manager/real_system_provider.cc
@@ -27,7 +27,6 @@
 #include <base/logging.h>
 #include <base/strings/stringprintf.h>
 #include <base/time/time.h>
-#include <vboot/crossystem.h>
 
 #include "update_engine/update_manager/generic_variables.h"
 #include "update_engine/utils.h"
@@ -39,11 +38,11 @@
 bool RealSystemProvider::Init() {
   var_is_normal_boot_mode_.reset(
       new ConstCopyVariable<bool>("is_normal_boot_mode",
-                                  VbGetSystemPropertyInt("devsw_boot") != 0));
+                                  hardware_->IsNormalBootMode()));
 
   var_is_official_build_.reset(
       new ConstCopyVariable<bool>("is_official_build",
-                                  VbGetSystemPropertyInt("debug_build") == 0));
+                                  hardware_->IsOfficialBuild()));
 
   var_is_oobe_complete_.reset(
       new CallCopyVariable<bool>(