Add a hardware_class attribute (for HWID, HWQual ID) to the Omaha request.

BUG=1600
TEST=unit tests, gmerge and looked at request logs

Review URL: http://codereview.chromium.org/3007020
diff --git a/action.h b/action.h
index 9e6eb94..7ce9f60 100644
--- a/action.h
+++ b/action.h
@@ -125,9 +125,7 @@
 template<typename SubClass>
 class Action : public AbstractAction {
  public:
-  virtual ~Action() {
-    LOG(INFO) << "Action died";
-  }
+  virtual ~Action() {}
 
   // Attaches an input pipe to this Action. This is optional; an Action
   // doesn't need to have an input pipe. The input pipe must be of the type
diff --git a/action_pipe.h b/action_pipe.h
index 7697043..4681627 100644
--- a/action_pipe.h
+++ b/action_pipe.h
@@ -41,9 +41,7 @@
 template<typename ObjectType>
 class ActionPipe {
  public:
-  virtual ~ActionPipe() {
-    LOG(INFO) << "ActionPipe died";
-  }
+  virtual ~ActionPipe() {}
 
   // This should be called by an Action on its input pipe.
   // Returns a reference to the stored object.
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 7eca9e0..cd31805 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -118,7 +118,8 @@
       XmlEncode(params.app_version) + "\" "
       "lang=\"" + XmlEncode(params.app_lang) + "\" track=\"" +
       XmlEncode(params.app_track) + "\" board=\"" +
-      XmlEncode(params.os_board) + "\" delta_okay=\"" +
+      XmlEncode(params.os_board) + "\" hardware_class=\"" +
+      XmlEncode(params.hardware_class) + "\" delta_okay=\"" +
       (params.delta_okay ? "true" : "false") + "\">\n" + body +
       "    </o:app>\n"
       "</o:gupdate>\n";
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index f4dcd1e..7a56b41 100755
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -43,6 +43,7 @@
     "0.1.0.0",
     "en-US",
     "unittest",
+    "OEM MODEL 09235 7471",
     false,  // delta okay
     "http://url");
 
@@ -412,6 +413,7 @@
                             "0.1.0.0",
                             "en-US",
                             "unittest_track&lt;",
+                            "<OEM MODEL>",
                             false,  // delta okay
                             "http://url");
   OmahaResponse response;
@@ -430,6 +432,8 @@
   EXPECT_EQ(post_str.find("x86 generic<id"), string::npos);
   EXPECT_NE(post_str.find("unittest_track&amp;lt;"), string::npos);
   EXPECT_EQ(post_str.find("unittest_track&lt;"), string::npos);
+  EXPECT_NE(post_str.find("&lt;OEM MODEL&gt;"), string::npos);
+  EXPECT_EQ(post_str.find("<OEM MODEL>"), string::npos);
 }
 
 TEST(OmahaRequestActionTest, XmlDecodeTest) {
@@ -487,6 +491,8 @@
   EXPECT_NE(post_str.find("        <o:ping a=\"-1\" r=\"-1\"></o:ping>\n"
                           "        <o:updatecheck></o:updatecheck>\n"),
             string::npos);
+  EXPECT_NE(post_str.find("hardware_class=\"OEM MODEL 09235 7471\""),
+            string::npos);
   EXPECT_EQ(post_str.find("o:event"), string::npos);
 }
 
@@ -580,6 +586,7 @@
                               "0.1.0.0",
                               "en-US",
                               "unittest_track",
+                              "OEM MODEL REV 1234",
                               delta_okay,
                               "http://url");
     ASSERT_FALSE(TestUpdateCheck(NULL,  // prefs
diff --git a/omaha_request_params.cc b/omaha_request_params.cc
index 0789fbb..9f6e82b 100644
--- a/omaha_request_params.cc
+++ b/omaha_request_params.cc
@@ -11,6 +11,7 @@
 #include <map>
 #include <string>
 
+#include "base/file_util.h"
 #include "base/string_util.h"
 #include "update_engine/simple_key_value_store.h"
 #include "update_engine/utils.h"
@@ -27,6 +28,8 @@
 const char* const OmahaRequestParams::kUpdateUrl(
     "https://tools.google.com/service/update2");
 
+static const char kHWIDPath[] = "/sys/devices/platform/chromeos_acpi/HWID";
+
 bool OmahaRequestDeviceParams::Init(const std::string& in_app_version,
                                     const std::string& in_update_url) {
   os_platform = OmahaRequestParams::kOsPlatform;
@@ -38,6 +41,7 @@
   app_id = OmahaRequestParams::kAppId;
   app_lang = "en-US";
   app_track = GetLsbValue("CHROMEOS_RELEASE_TRACK", "");
+  hardware_class = GetHardwareClass();
   struct stat stbuf;
 
   // Deltas are only okay if the /.nodelta file does not exist.
@@ -79,4 +83,14 @@
   return ret;
 }
 
+string OmahaRequestDeviceParams::GetHardwareClass() const {
+  string hwid;
+  if (!file_util::ReadFileToString(FilePath(root_ + kHWIDPath), &hwid)) {
+    LOG(ERROR) << "Unable to determine the system hardware qualification ID.";
+    return "";
+  }
+  TrimWhitespaceASCII(hwid, TRIM_ALL, &hwid);
+  return hwid;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/omaha_request_params.h b/omaha_request_params.h
index 9c37258..551a3a3 100644
--- a/omaha_request_params.h
+++ b/omaha_request_params.h
@@ -27,6 +27,7 @@
                      const std::string& in_app_version,
                      const std::string& in_app_lang,
                      const std::string& in_app_track,
+                     const std::string& in_hardware_class,
                      const bool in_delta_okay,
                      const std::string& in_update_url)
       : os_platform(in_os_platform),
@@ -37,6 +38,7 @@
         app_version(in_app_version),
         app_lang(in_app_lang),
         app_track(in_app_track),
+        hardware_class(in_hardware_class),
         delta_okay(in_delta_okay),
         update_url(in_update_url) {}
 
@@ -48,6 +50,7 @@
   std::string app_version;
   std::string app_lang;
   std::string app_track;
+  std::string hardware_class;  // Hardware Qualification ID of the client
   bool delta_okay;  // If this client can accept a delta
 
   std::string update_url;
@@ -82,6 +85,10 @@
   // Gets the machine type (e.g. "i686").
   std::string GetMachineType() const;
 
+  // Returns the hardware qualification ID of the system, or empty
+  // string if the HWID is unavailable.
+  std::string GetHardwareClass() const;
+
   // When reading files, prepend root_ to the paths. Useful for testing.
   std::string root_;
 
diff --git a/omaha_request_params_unittest.cc b/omaha_request_params_unittest.cc
index 19898f4..0150a00 100644
--- a/omaha_request_params_unittest.cc
+++ b/omaha_request_params_unittest.cc
@@ -3,8 +3,11 @@
 // found in the LICENSE file.
 
 #include <stdio.h>
+
 #include <string>
-#include <gtest/gtest.h>
+
+#include "base/file_util.h"
+#include "gtest/gtest.h"
 #include "update_engine/install_plan.h"
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/test_utils.h"
@@ -85,6 +88,7 @@
   EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id);
   EXPECT_EQ("0.2.2.3", out.app_version);
   EXPECT_EQ("en-US", out.app_lang);
+  EXPECT_EQ("", out.hardware_class);
   EXPECT_TRUE(out.delta_okay);
   EXPECT_EQ("footrack", out.app_track);
   EXPECT_EQ("http://www.google.com", out.update_url);
@@ -210,4 +214,17 @@
   EXPECT_FALSE(out.delta_okay);
 }
 
+TEST_F(OmahaRequestDeviceParamsTest, HardwareClassTest) {
+  string test_class = " \t sample hardware class \n ";
+  FilePath hwid_path(kTestDir + "/sys/devices/platform/chromeos_acpi/HWID");
+  ASSERT_TRUE(file_util::CreateDirectory(hwid_path.DirName()));
+  ASSERT_EQ(test_class.size(),
+            file_util::WriteFile(hwid_path,
+                                 test_class.data(),
+                                 test_class.size()));
+  OmahaRequestParams out;
+  EXPECT_TRUE(DoTest(&out, "", ""));
+  EXPECT_EQ("sample hardware class", out.hardware_class);
+}
+
 }  // namespace chromeos_update_engine