blob: b1f0921f4ebc310a6344bd1180a995486174317f [file] [log] [blame] [edit]
// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flex_hwis/flex_hardware_cache.h"
#include <map>
#include <string>
#include <vector>
#include <chromeos/constants/flex_hwis.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
namespace flex_hwis {
namespace {
// RepeatedField will be a RepeatedPtrField from a protobuf.
template <typename RepeatedField>
std::string GetNames(const RepeatedField& device_list) {
std::vector<std::string> names;
for (auto dev : device_list) {
names.push_back(dev.name());
}
return base::JoinString(names, ", ");
}
template <typename RepeatedField>
std::string GetDrivers(const RepeatedField& device_list) {
std::vector<std::string> drivers;
for (auto& dev : device_list) {
// Named 'driver', singular, but it's a repeated field.
std::vector<std::string> device_drivers(dev.driver().begin(),
dev.driver().end());
// Use the slash as a separator to match rubber-chicken-tool.
drivers.push_back(base::JoinString(device_drivers, "/"));
}
return base::JoinString(drivers, ", ");
}
template <typename RepeatedField>
std::string GetIds(const RepeatedField& device_list) {
std::vector<std::string> ids;
for (auto dev : device_list) {
ids.push_back(dev.id());
}
return base::JoinString(ids, ", ");
}
std::string BoolToString(bool value) {
return value ? "true" : "false";
}
} // namespace
bool WriteCacheToDisk(hwis_proto::Device& data, const base::FilePath& root) {
std::map<std::string, std::string> file_contents = {
{kFlexProductNameKey, data.dmi_info().product_name()},
{kFlexProductVendorKey, data.dmi_info().vendor()},
{kFlexProductVersionKey, data.dmi_info().product_version()},
{kFlexTotalMemoryKey, base::NumberToString(data.memory().total_kib())},
{kFlexBiosVersionKey, data.bios().bios_version()},
{kFlexSecurebootKey, BoolToString(data.bios().secureboot())},
{kFlexUefiKey, BoolToString(data.bios().uefi())},
{kFlexBluetoothDriverKey, GetDrivers(data.bluetooth_adapter())},
{kFlexBluetoothIdKey, GetIds(data.bluetooth_adapter())},
{kFlexBluetoothNameKey, GetNames(data.bluetooth_adapter())},
{kFlexEthernetDriverKey, GetDrivers(data.ethernet_adapter())},
{kFlexEthernetIdKey, GetIds(data.ethernet_adapter())},
{kFlexEthernetNameKey, GetNames(data.ethernet_adapter())},
{kFlexWirelessDriverKey, GetDrivers(data.wireless_adapter())},
{kFlexWirelessIdKey, GetIds(data.wireless_adapter())},
{kFlexWirelessNameKey, GetNames(data.wireless_adapter())},
{kFlexGpuDriverKey, GetDrivers(data.gpu())},
{kFlexGpuIdKey, GetIds(data.gpu())},
{kFlexGpuNameKey, GetNames(data.gpu())},
{kFlexGlVersionKey, data.graphics_info().gl_version()},
{kFlexGlShadingVersionKey, data.graphics_info().gl_shading_version()},
{kFlexGlVendorKey, data.graphics_info().gl_vendor()},
{kFlexGlRendererKey, data.graphics_info().gl_renderer()},
{kFlexTpmVersionKey, data.tpm().tpm_version()},
{kFlexTpmSpecLevelKey, base::NumberToString(data.tpm().spec_level())},
{kFlexTpmManufacturerKey,
base::NumberToString(data.tpm().manufacturer())},
{kFlexTpmDidVidKey, data.tpm().did_vid()},
{kFlexTpmAllowListedKey, BoolToString(data.tpm().tpm_allow_listed())},
{kFlexTpmOwnedKey, BoolToString(data.tpm().tpm_owned())},
{kFlexTouchpadStackKey, data.touchpad().stack()},
};
std::vector gl_extensions(data.graphics_info().gl_extensions().begin(),
data.graphics_info().gl_extensions().end());
file_contents.insert(
{kFlexGlExtensionsKey, base::JoinString(gl_extensions, ", ")});
// If no CPUs, ignore. Otherwise grab the first one, because although there
// are multiple cpu info structures, the name matches across all of them for
// the devices we've seen.
if (!data.cpu().empty()) {
file_contents.insert({kFlexCpuNameKey, data.cpu(0).name()});
}
base::FilePath cache_dir = root.Append(kFlexHardwareCacheDir);
bool all_succeeded = true;
for (const auto& [filename, contents] : file_contents) {
base::FilePath path(cache_dir.Append(filename));
if (!base::WriteFile(path, contents)) {
// Don't stop for failures, let's write what we can.
all_succeeded = false;
LOG(WARNING) << "Couldn't write: " << filename << " to " << path;
}
}
// Return true only if all writes were successful.
return all_succeeded;
}
} // namespace flex_hwis