Send the system image build fingerprint and bootloader versions.

In Android, we had STUBS for the bootloader (firmware) version, board,
and EC version. This patch populates those versions and strings based on
the system props using Android standard properties and includes the full
build.fingerprint in the request, which could be used to double-check
the request.

Bug: 35364971
Test: `update_engine_client --check_for_update` sends all this
information now.

(cherry picked from commit 094ce0bec1de7952e2ddc6c0f3c94dc3615b99c0)

Change-Id: I8265c5b8f4415f825160ea259c5b84b4b77372d7
diff --git a/hardware_android.cc b/hardware_android.cc
index 653ccf9..91c3fbe 100644
--- a/hardware_android.cc
+++ b/hardware_android.cc
@@ -25,6 +25,7 @@
 #include <bootloader.h>
 
 #include <base/files/file_util.h>
+#include <base/strings/stringprintf.h>
 #include <brillo/make_unique_ptr.h>
 #include <cutils/properties.h>
 
@@ -45,6 +46,15 @@
     "--wipe_data\n"
     "--reason=wipe_data_from_ota\n";
 
+// Android properties that identify the hardware and potentially non-updatable
+// parts of the bootloader (such as the bootloader version and the baseband
+// version).
+const char kPropBootBootloader[] = "ro.boot.bootloader";
+const char kPropBootBaseband[] = "ro.boot.baseband";
+const char kPropProductManufacturer[] = "ro.product.manufacturer";
+const char kPropBootHardwareSKU[] = "ro.boot.hardware.sku";
+const char kPropBootRevision[] = "ro.boot.revision";
+
 // Write a recovery command line |message| to the BCB. The arguments to recovery
 // must be separated by '\n'. An empty string will erase the BCB.
 bool WriteBootloaderRecoveryMessage(const string& message) {
@@ -139,18 +149,26 @@
 }
 
 string HardwareAndroid::GetHardwareClass() const {
-  LOG(WARNING) << "STUB: GetHardwareClass().";
-  return "ANDROID";
+  char manufacturer[PROPERTY_VALUE_MAX];
+  char sku[PROPERTY_VALUE_MAX];
+  char revision[PROPERTY_VALUE_MAX];
+  property_get(kPropBootHardwareSKU, sku, "");
+  property_get(kPropProductManufacturer, manufacturer, "");
+  property_get(kPropBootRevision, revision, "");
+
+  return base::StringPrintf("%s:%s:%s", manufacturer, sku, revision);
 }
 
 string HardwareAndroid::GetFirmwareVersion() const {
-  LOG(WARNING) << "STUB: GetFirmwareVersion().";
-  return "0";
+  char bootloader[PROPERTY_VALUE_MAX];
+  property_get(kPropBootBootloader, bootloader, "");
+  return bootloader;
 }
 
 string HardwareAndroid::GetECVersion() const {
-  LOG(WARNING) << "STUB: GetECVersion().";
-  return "0";
+  char baseband[PROPERTY_VALUE_MAX];
+  property_get(kPropBootBaseband, baseband, "");
+  return baseband;
 }
 
 int HardwareAndroid::GetPowerwashCount() const {
diff --git a/image_properties.h b/image_properties.h
index 6026c2e..ba6ce44 100644
--- a/image_properties.h
+++ b/image_properties.h
@@ -37,6 +37,10 @@
   // The product version of this image.
   std::string version;
 
+  // A unique string that identifies this build. Normally a combination of the
+  // the version, signing keys and build target.
+  std::string build_fingerprint;
+
   // The board name this image was built for.
   std::string board;
 
diff --git a/image_properties_android.cc b/image_properties_android.cc
index 5ec63a5..e3b7616 100644
--- a/image_properties_android.cc
+++ b/image_properties_android.cc
@@ -20,6 +20,7 @@
 
 #include <base/logging.h>
 #include <brillo/osrelease_reader.h>
+#include <cutils/properties.h>
 
 #include "update_engine/common/boot_control_interface.h"
 #include "update_engine/common/constants.h"
@@ -40,6 +41,10 @@
 const char kPrefsImgPropChannelName[] = "img-prop-channel-name";
 const char kPrefsImgPropPowerwashAllowed[] = "img-prop-powerwash-allowed";
 
+// System properties that identifies the "board".
+const char kPropProductName[] = "ro.product.name";
+const char kPropBuildFingerprint[] = "ro.build.fingerprint";
+
 std::string GetStringWithDefault(const brillo::OsReleaseReader& osrelease,
                                  const std::string& key,
                                  const std::string& default_value) {
@@ -71,7 +76,12 @@
       GetStringWithDefault(osrelease, kProductVersion, "0");
   result.version = system_version + "." + product_version;
 
-  result.board = "brillo";
+  char prop[PROPERTY_VALUE_MAX];
+  property_get(kPropProductName, prop, "brillo");
+  result.board = prop;
+
+  property_get(kPropBuildFingerprint, prop, "none");
+  result.build_fingerprint = prop;
 
   // Brillo images don't have a channel assigned. We stored the name of the
   // channel where we got the image from in prefs at the time of the update, so
diff --git a/image_properties_chromeos.cc b/image_properties_chromeos.cc
index 501e662..024eebf 100644
--- a/image_properties_chromeos.cc
+++ b/image_properties_chromeos.cc
@@ -115,6 +115,8 @@
   result.omaha_url =
       GetStringWithDefault(lsb_release, kLsbReleaseAutoUpdateServerKey,
                            constants::kOmahaDefaultProductionURL);
+  // Build fingerprint not used in Chrome OS.
+  result.buiild_fingerprint = "";
 
   return result;
 }
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 3d2dac1..b06de09 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -258,11 +258,18 @@
   app_cohort_args += GetCohortArgXml(system_state->prefs(),
                                      "cohortname", kPrefsOmahaCohortName);
 
+  string fingerprint_arg;
+  if (!params->os_build_fingerprint().empty()) {
+    fingerprint_arg =
+        "fingerprint=\"" + XmlEncodeWithDefault(params->os_build_fingerprint(), "") + "\" ";
+  }
+
   string app_xml = "    <app "
       "appid=\"" + XmlEncodeWithDefault(params->GetAppId(), "") + "\" " +
       app_cohort_args +
       app_versions +
       app_channels +
+      fingerprint_arg +
       "lang=\"" + XmlEncodeWithDefault(params->app_lang(), "en-US") + "\" " +
       "board=\"" + XmlEncodeWithDefault(params->os_board(), "") + "\" " +
       "hardware_class=\"" + XmlEncodeWithDefault(params->hwid(), "") + "\" " +
diff --git a/omaha_request_params.h b/omaha_request_params.h
index 379563a..3a28ed1 100644
--- a/omaha_request_params.h
+++ b/omaha_request_params.h
@@ -102,6 +102,9 @@
   inline std::string os_version() const { return os_version_; }
   inline std::string os_sp() const { return os_sp_; }
   inline std::string os_board() const { return image_props_.board; }
+  inline std::string os_build_fingerprint() const {
+    return image_props_.build_fingerprint;
+  }
   inline std::string board_app_id() const { return image_props_.product_id; }
   inline std::string canary_app_id() const {
     return image_props_.canary_product_id;