[M108 Migration] Support standard build for armv7hl architecture
[platform/framework/web/chromium-efl.git] / components / metrics / motherboard.cc
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/metrics/motherboard.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/strings/string_util.h"
13 #include "build/build_config.h"
14 #include "third_party/abseil-cpp/absl/types/optional.h"
15
16 #if BUILDFLAG(IS_WIN)
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/threading/scoped_blocking_call.h"
19 #include "base/win/scoped_bstr.h"
20 #include "base/win/scoped_com_initializer.h"
21 #include "base/win/scoped_variant.h"
22 #include "base/win/wmi.h"
23 #endif
24
25 namespace metrics {
26 namespace {
27
28 struct MotherboardDetails {
29   absl::optional<std::string> manufacturer;
30   absl::optional<std::string> model;
31   absl::optional<std::string> bios_manufacturer;
32   absl::optional<std::string> bios_version;
33   absl::optional<Motherboard::BiosType> bios_type;
34 };
35
36 #if BUILDFLAG(IS_LINUX)
37 using base::FilePath;
38 using base::PathExists;
39 using base::ReadFileToString;
40 using base::TrimWhitespaceASCII;
41 using base::TRIM_TRAILING;
42
43 MotherboardDetails ReadMotherboardDetails() {
44   constexpr FilePath::CharType kDmiPath[] = "/sys/devices/virtual/dmi/id";
45   constexpr FilePath::CharType kEfiPath[] = "/sys/firmware/efi";
46   const FilePath dmi_path(kDmiPath);
47   MotherboardDetails details;
48   std::string temp;
49   if (ReadFileToString(dmi_path.Append("board_vendor"), &temp)) {
50     details.manufacturer =
51         std::string(TrimWhitespaceASCII(temp, TRIM_TRAILING));
52   }
53   if (ReadFileToString(dmi_path.Append("board_name"), &temp)) {
54     details.model = std::string(TrimWhitespaceASCII(temp, TRIM_TRAILING));
55   }
56   if (ReadFileToString(dmi_path.Append("bios_vendor"), &temp)) {
57     details.bios_manufacturer =
58         std::string(TrimWhitespaceASCII(temp, TRIM_TRAILING));
59   }
60   if (ReadFileToString(dmi_path.Append("bios_version"), &temp)) {
61     details.bios_version =
62         std::string(TrimWhitespaceASCII(temp, TRIM_TRAILING));
63   }
64   if (PathExists(FilePath(kEfiPath))) {
65     details.bios_type = Motherboard::BiosType::kUefi;
66   } else {
67     details.bios_type = Motherboard::BiosType::kLegacy;
68   }
69   return details;
70 }
71 #endif
72
73 #if BUILDFLAG(IS_WIN)
74 using Microsoft::WRL::ComPtr;
75 using base::win::ScopedBstr;
76 using base::win::ScopedVariant;
77
78 absl::optional<std::string> ReadStringMember(
79     ComPtr<IWbemClassObject> class_object, const wchar_t* key) {
80   ScopedVariant variant;
81   HRESULT hr = class_object->Get(key, 0, variant.Receive(), 0, 0);
82   if (SUCCEEDED(hr) && variant.type() == VT_BSTR) {
83     const auto len = ::SysStringLen(V_BSTR(variant.ptr()));
84     std::wstring wstr(V_BSTR(variant.ptr()), len);
85     return base::WideToUTF8(wstr);
86   }
87   return {};
88 }
89
90 void ReadWin32BaseBoard(const ComPtr<IWbemServices>& services,
91                         absl::optional<std::string>* manufacturer,
92                         absl::optional<std::string>* model) {
93   static constexpr wchar_t kManufacturer[] = L"Manufacturer";
94   static constexpr wchar_t kProduct[] = L"Product";
95   static constexpr wchar_t kQueryProcessor[] =
96       L"SELECT Manufacturer,Product FROM Win32_BaseBoard";
97
98   ComPtr<IEnumWbemClassObject> enumerator_base_board;
99   HRESULT hr = services->ExecQuery(
100       ScopedBstr(L"WQL").Get(), ScopedBstr(kQueryProcessor).Get(),
101       WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr,
102       &enumerator_base_board);
103   if (FAILED(hr) || !enumerator_base_board.Get())
104     return;
105
106   ComPtr<IWbemClassObject> class_object;
107   ULONG items_returned = 0;
108   hr = enumerator_base_board->Next(WBEM_INFINITE, 1, &class_object,
109                                    &items_returned);
110   if (FAILED(hr) || !items_returned)
111     return;
112   *manufacturer = ReadStringMember(class_object, kManufacturer);
113   *model = ReadStringMember(class_object, kProduct);
114 }
115
116 void ReadWin32Bios(const ComPtr<IWbemServices>& services,
117                    absl::optional<std::string>* bios_manufacturer,
118                    absl::optional<std::string>* bios_version) {
119   static constexpr wchar_t kManufacturer[] = L"Manufacturer";
120   static constexpr wchar_t kVersion[] = L"Version";
121   static constexpr wchar_t kQueryProcessor[] =
122       L"SELECT Manufacturer,Version FROM Win32_BIOS";
123
124   ComPtr<IEnumWbemClassObject> enumerator_base_board;
125   HRESULT hr = services->ExecQuery(
126       ScopedBstr(L"WQL").Get(), ScopedBstr(kQueryProcessor).Get(),
127       WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr,
128       &enumerator_base_board);
129   if (FAILED(hr) || !enumerator_base_board.Get())
130     return;
131
132   ComPtr<IWbemClassObject> class_object;
133   ULONG items_returned = 0;
134   hr = enumerator_base_board->Next(WBEM_INFINITE, 1, &class_object,
135                                    &items_returned);
136   if (FAILED(hr) || !items_returned)
137     return;
138   *bios_manufacturer = ReadStringMember(class_object, kManufacturer);
139   *bios_version = ReadStringMember(class_object, kVersion);
140 }
141
142 MotherboardDetails ReadMotherboardDetails() {
143   base::win::ScopedCOMInitializer scoped_com_initializer;
144   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
145                                                 base::BlockingType::MAY_BLOCK);
146   ComPtr<IWbemServices> services;
147   MotherboardDetails details;
148   if (!base::win::CreateLocalWmiConnection(true, &services))
149     return details;
150   ReadWin32BaseBoard(services, &details.manufacturer, &details.model);
151   ReadWin32Bios(services, &details.bios_manufacturer, &details.bios_version);
152   return details;
153 }
154 #endif
155 }  // namespace
156
157 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
158 Motherboard::Motherboard() {
159   const auto details = ReadMotherboardDetails();
160   manufacturer_ = std::move(details.manufacturer),
161   model_ = std::move(details.model),
162   bios_manufacturer_ = std::move(details.bios_manufacturer),
163   bios_version_ = std::move(details.bios_version),
164   bios_type_ = std::move(details.bios_type);
165 }
166 #else
167 Motherboard::Motherboard() = default;
168 #endif
169
170 Motherboard::~Motherboard() = default;
171
172 }  // namespace metrics