update_engine: GPU Drivers in HW details

.. allows filtering based off GPU drivers.

Details: space delimited.

```
gpu_drivers="fake-driver-2 fake-driver-3 ..."
```

BUG=b:272369984
TEST=emerge + gtest

Change-Id: I5a813734f8d49d403cda5c200d0ba3f8bd7c83b7
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/4321212
Reviewed-by: Yuanpeng Ni‎ <yuanpengni@chromium.org>
Commit-Queue: Jae Hoon Kim <kimjae@chromium.org>
Tested-by: Jae Hoon Kim <kimjae@chromium.org>
diff --git a/common/telemetry_info.cc b/common/telemetry_info.cc
index 1acdb5a..bedeb22 100644
--- a/common/telemetry_info.cc
+++ b/common/telemetry_info.cc
@@ -23,29 +23,37 @@
 namespace chromeos_update_engine {
 
 std::string TelemetryInfo::GetWirelessDrivers() const {
-  std::vector<std::string> wireless_drivers;
-  for (const auto& bus_device : bus_devices) {
-    if (bus_device.device_class !=
-        BusDevice::BusDeviceClass::kWirelessController)
-      continue;
-    if (const auto* pci_bus_info =
-            std::get_if<BusDevice::PciBusInfo>(&bus_device.bus_type_info)) {
-      const auto& driver = pci_bus_info->driver;
-      if (!driver.empty())
-        wireless_drivers.push_back(driver);
-    }
-  }
-  return base::JoinString(wireless_drivers, " ");
+  return GetBusDeviceDrivers(BusDevice::BusDeviceClass::kWirelessController);
 }
 
 std::string TelemetryInfo::GetWirelessIds() const {
   return GetBusDeviceIds(BusDevice::BusDeviceClass::kWirelessController);
 }
 
+std::string TelemetryInfo::GetGpuDrivers() const {
+  return GetBusDeviceDrivers(BusDevice::BusDeviceClass::kDisplayController);
+}
+
 std::string TelemetryInfo::GetGpuIds() const {
   return GetBusDeviceIds(BusDevice::BusDeviceClass::kDisplayController);
 }
 
+std::string TelemetryInfo::GetBusDeviceDrivers(
+    BusDevice::BusDeviceClass bus_device_class) const {
+  std::vector<std::string> drivers;
+  for (const auto& bus_device : bus_devices) {
+    if (bus_device.device_class != bus_device_class)
+      continue;
+    if (const auto* pci_bus_info =
+            std::get_if<BusDevice::PciBusInfo>(&bus_device.bus_type_info)) {
+      const auto& driver = pci_bus_info->driver;
+      if (!driver.empty())
+        drivers.push_back(driver);
+    }
+  }
+  return base::JoinString(drivers, " ");
+}
+
 std::string TelemetryInfo::GetBusDeviceIds(
     BusDevice::BusDeviceClass bus_device_class) const {
   std::vector<std::string> ids;
diff --git a/common/telemetry_info.h b/common/telemetry_info.h
index fa5b121..8d78a0d 100644
--- a/common/telemetry_info.h
+++ b/common/telemetry_info.h
@@ -107,9 +107,12 @@
 
   std::string GetWirelessDrivers() const;
   std::string GetWirelessIds() const;
+  std::string GetGpuDrivers() const;
   std::string GetGpuIds() const;
 
  private:
+  std::string GetBusDeviceDrivers(
+      BusDevice::BusDeviceClass bus_device_class) const;
   std::string GetBusDeviceIds(BusDevice::BusDeviceClass bus_device_class) const;
 } TelemetryInfo;
 
diff --git a/cros/omaha_request_builder_xml.cc b/cros/omaha_request_builder_xml.cc
index 612761d..9eeb830 100644
--- a/cros/omaha_request_builder_xml.cc
+++ b/cros/omaha_request_builder_xml.cc
@@ -543,6 +543,7 @@
       " cpu_name=\"%s\""
       " wireless_drivers=\"%s\""
       " wireless_ids=\"%s\""
+      " gpu_drivers=\"%s\""
       " gpu_ids=\"%s\""
       " />\n",
       XmlEncodeWithDefault(telemetry_info->system_info.dmi_info.sys_vendor)
@@ -571,6 +572,7 @@
           .c_str(),
       XmlEncodeWithDefault(telemetry_info->GetWirelessDrivers()).c_str(),
       XmlEncodeWithDefault(telemetry_info->GetWirelessIds()).c_str(),
+      XmlEncodeWithDefault(telemetry_info->GetGpuDrivers()).c_str(),
       XmlEncodeWithDefault(telemetry_info->GetGpuIds()).c_str());
   return hw_xml;
 }
diff --git a/cros/omaha_request_builder_xml_unittest.cc b/cros/omaha_request_builder_xml_unittest.cc
index 1892748..de0f70e 100644
--- a/cros/omaha_request_builder_xml_unittest.cc
+++ b/cros/omaha_request_builder_xml_unittest.cc
@@ -602,6 +602,7 @@
                                    " cpu_name=\"%s\""
                                    " wireless_drivers=\"%s\""
                                    " wireless_ids=\"%s\""
+                                   " gpu_drivers=\"%s\""
                                    " gpu_ids=\"%s\""
                                    " />\n",
                                    sys_vendor.c_str(),
@@ -614,10 +615,154 @@
                                    model_name.c_str(),
                                    "fake-driver-1",
                                    "0001:0002 0003:0004",
+                                   "fake-driver-2",
                                    "0005:0006 00AA:1111")))
       << request_xml;
 }
 
+TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlHwCheckMultipleGpuDrivers) {
+  params_.set_hw_details(true);
+
+  const string sys_vendor = "fake-sys-vendor",
+               product_name = "fake-product-name",
+               product_version = "fake-product-version",
+               bios_version = "fake-bios-version",
+               model_name = "fake-model-name";
+  auto boot_mode = TelemetryInfo::SystemInfo::OsInfo::BootMode::kCrosEfi;
+  uint32_t total_memory_kib = 123;
+  uint64_t size = 456;
+
+  FakeSystemState::Get()
+      ->fake_cros_healthd()
+      ->telemetry_info() = std::make_unique<TelemetryInfo>(TelemetryInfo{
+      .system_info =
+          // NOLINTNEXTLINE(whitespace/braces)
+      {
+          .dmi_info =
+              // NOLINTNEXTLINE(whitespace/braces)
+          {
+              .sys_vendor = sys_vendor,
+              .product_name = product_name,
+              .product_version = product_version,
+              .bios_version = bios_version,
+          },
+          .os_info =
+              // NOLINTNEXTLINE(whitespace/braces)
+          {
+              .boot_mode = boot_mode,
+          },
+      },
+      .memory_info =
+          // NOLINTNEXTLINE(whitespace/braces)
+      {
+          .total_memory_kib = total_memory_kib,
+      },
+      .block_device_info =
+          // NOLINTNEXTLINE(whitespace/braces)
+      {
+          {
+              .size = size,
+          },
+      },
+      .cpu_info =
+          // NOLINTNEXTLINE(whitespace/braces)
+      {
+          .physical_cpus =
+              // NOLINTNEXTLINE(whitespace/braces)
+          {
+              {
+                  .model_name = model_name,
+              },
+          },
+      },
+      .bus_devices =
+          // NOLINTNEXTLINE(whitespace/braces)
+      {
+          {
+              .device_class =
+                  TelemetryInfo::BusDevice::BusDeviceClass::kWirelessController,
+              .bus_type_info =
+                  TelemetryInfo::BusDevice::PciBusInfo{
+                      .vendor_id = 0x0001,
+                      .device_id = 0x0002,
+                      .driver = "fake-driver-1",
+                  },
+          },
+          {
+              .device_class =
+                  TelemetryInfo::BusDevice::BusDeviceClass::kWirelessController,
+              .bus_type_info =
+                  TelemetryInfo::BusDevice::UsbBusInfo{
+                      .vendor_id = 0x0003,
+                      .product_id = 0x0004,
+                  },
+          },
+          {
+              .device_class =
+                  TelemetryInfo::BusDevice::BusDeviceClass::kDisplayController,
+              .bus_type_info =
+                  TelemetryInfo::BusDevice::PciBusInfo{
+                      .vendor_id = 0x0005,
+                      .device_id = 0x0006,
+                      .driver = "fake-driver-2",
+                  },
+          },
+          {
+              .device_class =
+                  TelemetryInfo::BusDevice::BusDeviceClass::kDisplayController,
+              .bus_type_info =
+                  TelemetryInfo::BusDevice::PciBusInfo{
+                      .vendor_id = 0xDEAD,
+                      .device_id = 0xBEEF,
+                      .driver = "fake-driver-3",
+                  },
+          },
+          {
+              .device_class =
+                  TelemetryInfo::BusDevice::BusDeviceClass::kDisplayController,
+              .bus_type_info =
+                  TelemetryInfo::BusDevice::UsbBusInfo{
+                      .vendor_id = 0x00AA,
+                      .product_id = 0x1111,
+                  },
+          },
+      },
+  });
+
+  OmahaRequestBuilderXml omaha_request{nullptr, false, false, 0, 0, 0, ""};
+  const string request_xml = omaha_request.GetRequest();
+  EXPECT_EQ(1,
+            CountSubstringInString(
+                request_xml,
+                base::StringPrintf("    <hw"
+                                   " vendor_name=\"%s\""
+                                   " product_name=\"%s\""
+                                   " product_version=\"%s\""
+                                   " bios_version=\"%s\""
+                                   " uefi=\"%" PRId32 "\""
+                                   " system_memory_bytes=\"%" PRIu32 "\""
+                                   " root_disk_drive=\"%" PRIu64 "\""
+                                   " cpu_name=\"%s\""
+                                   " wireless_drivers=\"%s\""
+                                   " wireless_ids=\"%s\""
+                                   " gpu_drivers=\"%s\""
+                                   " gpu_ids=\"%s\""
+                                   " />\n",
+                                   sys_vendor.c_str(),
+                                   product_name.c_str(),
+                                   product_version.c_str(),
+                                   bios_version.c_str(),
+                                   static_cast<int32_t>(boot_mode),
+                                   total_memory_kib,
+                                   size,
+                                   model_name.c_str(),
+                                   "fake-driver-1",
+                                   "0001:0002 0003:0004",
+                                   "fake-driver-2 fake-driver-3",
+                                   "0005:0006 DEAD:BEEF 00AA:1111")))
+      << request_xml;
+}
+
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlHwCheckMissingCrosHealthd) {
   params_.set_hw_details(true);
 
@@ -636,6 +781,7 @@
                                    " cpu_name=\"\""
                                    " wireless_drivers=\"\""
                                    " wireless_ids=\"\""
+                                   " gpu_drivers=\"\""
                                    " gpu_ids=\"\""
                                    " />\n"))
       << request_xml;