1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
base / system / sys_info.h [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_SYSTEM_SYS_INFO_H_
#define BASE_SYSTEM_SYS_INFO_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <optional>
#include <string>
#include <string_view>
#include "base/base_export.h"
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/time/time.h"
#include "build/build_config.h"
#if BUILDFLAG(IS_MAC)
#include "base/feature_list.h"
#endif
namespace base {
#if BUILDFLAG(IS_MAC)
// When enabled, NumberOfProcessors() returns the number of physical processors
// instead of the number of logical processors if CPU security mitigations are
// enabled for the current process.
BASE_EXPORT BASE_DECLARE_FEATURE(kNumberOfCoresWithCpuSecurityMitigation);
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Strings for environment variables.
BASE_EXPORT extern const char kLsbReleaseKey[];
BASE_EXPORT extern const char kLsbReleaseTimeKey[];
#endif
namespace debug {
FORWARD_DECLARE_TEST(SystemMetricsTest, ParseMeminfo);
}
namespace test {
class ScopedAmountOfPhysicalMemoryOverride;
}
class FilePath;
struct SystemMemoryInfoKB;
class BASE_EXPORT SysInfo {
public:
// Returns the number of processors/cores available for the current
// application. This is typically the number of logical cores installed on the
// system, but could instead be the number of physical cores when
// SetCpuSecurityMitigationsEnabled() has been invoked to indicate that CPU
// security mitigations are enabled on Mac.
// On some platforms this may cache the resulting value in its implementation,
// e.g. on Linux/ChromeOS where this function cannot run in a sandbox and so
// a cached value must be returned.
static int NumberOfProcessors();
// Returns the number of the most efficient logical processors for the current
// application. This is typically e-cores on Intel hybrid architecture, or
// LITTLE cores on ARM bit.LITTLE architecture.
// Returns 0 on symmetric architecture or when it failed to recognize.
// This function will cache the result value in its implementation.
static int NumberOfEfficientProcessors();
// Return the number of bytes of physical memory on the current machine.
// If low-end device mode is manually enabled via command line flag, this
// will return the lesser of the actual physical memory, or 512MB.
static uint64_t AmountOfPhysicalMemory();
// Return the number of bytes of current available physical memory on the
// machine.
// (The amount of memory that can be allocated without any significant
// impact on the system. It can lead to freeing inactive file-backed
// and/or speculative file-backed memory).
static uint64_t AmountOfAvailablePhysicalMemory();
// Return the number of bytes of virtual memory of this process. A return
// value of zero means that there is no limit on the available virtual
// memory.
static uint64_t AmountOfVirtualMemory();
// Return the number of megabytes of physical memory on the current machine.
static int AmountOfPhysicalMemoryMB() {
return static_cast<int>(AmountOfPhysicalMemory() / 1024 / 1024);
}
// Return the number of megabytes of available virtual memory, or zero if it
// is unlimited.
static int AmountOfVirtualMemoryMB() {
return static_cast<int>(AmountOfVirtualMemory() / 1024 / 1024);
}
// Return the available disk space in bytes on the volume containing |path|,
// or -1 on failure.
static int64_t AmountOfFreeDiskSpace(const FilePath& path);
// Return the total disk space in bytes on the volume containing |path|, or -1
// on failure.
static int64_t AmountOfTotalDiskSpace(const FilePath& path);
#if BUILDFLAG(IS_FUCHSIA)
// Sets the total amount of disk space to report under the specified |path|.
// If |bytes| is -ve then any existing entry for |path| is removed.
static void SetAmountOfTotalDiskSpace(const FilePath& path, int64_t bytes);
#endif
// Returns system uptime.
static TimeDelta Uptime();
// Returns a descriptive string for the current machine model or an empty
// string if the machine model is unknown or an error occurred.
// e.g. "MacPro1,1" on Mac, "iPhone9,3" on iOS or "Nexus 5" on Android. Only
// implemented on macOS, iOS, Android, Chrome OS and Windows. This returns an
// empty string on other platforms.
//
// For macOS, a useful reference of the resulting strings returned by this
// function and their corresponding hardware can be found at
// https://everymac.com/systems/by_capability/mac-specs-by-machine-model-machine-id.html
//
// For iOS, corresponding hardware can be found at
// https://deviceatlas.com/resources/clientside/ios-hardware-identification
static std::string HardwareModelName();
// Returns the SOC manufacturer's name or an empty string if the manufacturer
// is unknown or an error occurred.
// e.g. "Google" on Pixel 8 Pro. Only implemented on Android, returns an
// empty string on other platforms.
static std::string SocManufacturer();
#if BUILDFLAG(IS_MAC)
struct HardwareModelNameSplit {
std::string category;
int model = 0;
int variant = 0;
};
// Hardware model names on the Mac are of the shape "Mac𝓍,𝓎" where the
// prefix is the general category, the 𝓍 is the model, and the 𝓎 is the
// variant. This function takes the hardware model name as returned by
// HardwareModelName() above, and returns it split into its constituent parts.
// Returns nullopt if the value cannot be parsed.
//
// /!\ WARNING
//
// This is NOT A USEFUL FUNCTION and SHOULD NOT BE USED. While the `model`
// value does inform as to what generation of hardware it is within the
// `category`, this is not useful in determining the capabilities of the
// hardware. Instead of using the `model` value, check the actual capabilities
// of the hardware to verify what it can do rather than relying on a hardware
// model name. In addition, while the `category` value used to have meaning
// and could be used to determine the type of hardware (e.g. desktop vs
// laptop), in 2022 Apple started using the generic category of "Mac", thus
// removing its usefulness when used alone. While the entire model string as
// returned by HardwareModelName() above can be useful for identifying a
// specific piece of equipment, splitting apart it is not useful.
//
// Do not add any further callers! When the aforementioned 2022-era hardware
// is the minimum requirement for Chromium, remove this function and adjust
// all callers appropriately.
static std::optional<HardwareModelNameSplit> SplitHardwareModelNameDoNotUse(
std::string_view name);
#endif
struct HardwareInfo {
std::string manufacturer;
std::string model;
};
// Returns via |callback| a struct containing descriptive UTF-8 strings for
// the current machine manufacturer and model, or empty strings if the
// information is unknown or an error occurred. Implemented on Windows, macOS,
// iOS, Linux, Chrome OS and Android.
static void GetHardwareInfo(base::OnceCallback<void(HardwareInfo)> callback);
// Returns the name of the host operating system.
static std::string OperatingSystemName();
// Returns the version of the host operating system.
static std::string OperatingSystemVersion();
// Retrieves detailed numeric values for the OS version.
// DON'T USE THIS ON THE MAC OR WINDOWS to determine the current OS release
// for OS version-specific feature checks and workarounds. If you must use an
// OS version check instead of a feature check, use
// base::mac::MacOSVersion()/MacOSMajorVersion() family from
// base/mac/mac_util.h, or base::win::GetVersion() from
// base/win/windows_version.h.
static void OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version);
// Returns the architecture of the running operating system.
// Exact return value may differ across platforms.
// e.g. a 32-bit x86 kernel on a 64-bit capable CPU will return "x86",
// whereas a x86-64 kernel on the same CPU will return "x86_64"
static std::string OperatingSystemArchitecture();
// Returns the architecture of the running process, which might be different
// than the architecture returned by OperatingSystemArchitecture() (e.g.
// macOS Rosetta, a 32-bit binary on a 64-bit OS, etc).
// Will return one of: "x86", "x86_64", "ARM", "ARM_64", or an empty string if
// none of the above.
static std::string ProcessCPUArchitecture();
// Returns the CPU model name of the system. If it can not be figured out,
// an empty string is returned.
// More detailed info can be obtained from base/cpu.h.
static std::string CPUModelName();
// Return the smallest amount of memory (in bytes) which the VM system will
// allocate.
static size_t VMAllocationGranularity();
#if BUILDFLAG(IS_CHROMEOS)
// Set |value| and return true if LsbRelease contains information about |key|.
static bool GetLsbReleaseValue(const std::string& key, std::string* value);
// Convenience function for GetLsbReleaseValue("CHROMEOS_RELEASE_BOARD",...).
// Returns "unknown" if CHROMEOS_RELEASE_BOARD is not set. Otherwise, returns
// the full name of the board. Note that the returned value often differs
// between developers' systems and devices that use official builds. E.g. for
// a developer-built image, the function could return 'glimmer', while in an
// official build, it may be something like 'glimmer-signed-mp-v4keys'.
//
// NOTE: Strings returned by this function should be treated as opaque values
// within Chrome (e.g. for reporting metrics elsewhere). If you need to make
// Chrome behave differently for different Chrome OS devices, either directly
// check for the hardware feature that you care about (preferred) or add a
// command-line flag to Chrome and pass it from session_manager (based on
// whether a USE flag is set or not). See https://goo.gl/BbBkzg for more
// details.
static std::string GetLsbReleaseBoard();
// Returns the creation time of /etc/lsb-release. (Used to get the date and
// time of the Chrome OS build).
static Time GetLsbReleaseTime();
// Returns true when actually running in a Chrome OS environment.
static bool IsRunningOnChromeOS();
// Overrides |lsb_release| and |lsb_release_time|. Overrides cannot be nested.
// Call ResetChromeOSVersionInfoForTest() to restore the previous values.
// Prefer base::test::ScopedChromeOSVersionInfo to calling this function.
static void SetChromeOSVersionInfoForTest(const std::string& lsb_release,
const Time& lsb_release_time);
// Undoes the function above.
static void ResetChromeOSVersionInfoForTest();
// Returns the kernel version of the host operating system.
static std::string KernelVersion();
// Crashes if running on Chrome OS non-test image. Use only for really
// sensitive and risky use cases. Only works while running in verified mode,
// this check an easily be bypassed in dev mode.
static void CrashIfChromeOSNonTestImage();
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_ANDROID)
// Returns the Android build's codename.
static std::string GetAndroidBuildCodename();
// Returns the Android build ID.
static std::string GetAndroidBuildID();
// Returns the Android hardware EGL system property.
static std::string GetAndroidHardwareEGL();
#endif // BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_IOS)
// Returns the iOS build number string which is normally an alphanumeric
// string like 12E456. This build number can differentiate between different
// versions of iOS that may have the same major/minor/bugfix version numbers.
// For example, iOS beta releases have the same version number but different
// build number strings.
static std::string GetIOSBuildNumber();
// Overrides the hardware model name. The overridden value is used instead of
// `StringSysctl({CTL_HW, HW_MACHINE})`. `name` should not be empty.
static void OverrideHardwareModelName(std::string name);
#endif // BUILDFLAG(IS_IOS)
// Returns true for low-end devices that may require extreme tradeoffs,
// including user-visible changes, for acceptable performance.
// For general memory optimizations, consider |AmountOfPhysicalMemoryMB|.
//
// On Android this returns:
// true when memory <= 1GB on Android O and later.
// true when memory <= 512MB on Android N and earlier.
// This is not the same as "low-memory" and will be false on a large number of
// <=1GB pre-O Android devices. See: |detectLowEndDevice| in SysUtils.java.
// On Desktop this returns true when memory <= 2GB.
static bool IsLowEndDevice();
// The same as IsLowEndDevice() except on Android.
//
// On Android this returns:
// true when IsLowEndDevice() returns true.
// true when the physical memory of the device is 4gb or 6gb and
// the feature: kPartialLowEndModeOnMidEndDevices() is enabled.
static bool IsLowEndDeviceOrPartialLowEndModeEnabled();
static bool IsLowEndDeviceOrPartialLowEndModeEnabled(
const FeatureParam<bool>& param_for_exclusion);
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
// Returns true for Android devices whose memory is X GB, considering
// carveouts. The carveouts is memory reserved by the system, e.g.
// for drivers, MTE, etc. It's very common for querying app to see
// hundreds MBs less than actual physical memory installed on the system.
// Addendum: This logic should also work for ChromeOS.
static bool Is3GbDevice();
static bool Is4GbDevice();
static bool Is6GbDevice();
// Returns true for Android devices whose memory is 4GB or 6GB, considering
// carveouts.
static bool Is4GbOr6GbDevice();
#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_MAC)
// Indicates that CPU security mitigations are enabled for the current
// process. This is used to control the behavior of NumberOfProcessors(), see
// comment on that method.
static void SetCpuSecurityMitigationsEnabled();
// Resets all state associated with CPU security mitigations.
static void ResetCpuSecurityMitigationsEnabledForTesting();
#endif
private:
friend class test::ScopedAmountOfPhysicalMemoryOverride;
FRIEND_TEST_ALL_PREFIXES(SysInfoTest, AmountOfAvailablePhysicalMemory);
FRIEND_TEST_ALL_PREFIXES(debug::SystemMetricsTest, ParseMeminfo);
static int NumberOfEfficientProcessorsImpl();
static uint64_t AmountOfPhysicalMemoryImpl();
static uint64_t AmountOfAvailablePhysicalMemoryImpl();
static bool IsLowEndDeviceImpl();
static HardwareInfo GetHardwareInfoSync();
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
BUILDFLAG(IS_AIX)
static uint64_t AmountOfAvailablePhysicalMemory(
const SystemMemoryInfoKB& meminfo);
#endif
// Sets the amount of physical memory in MB for testing, thus allowing tests
// to run irrespective of the host machine's configuration.
static std::optional<uint64_t> SetAmountOfPhysicalMemoryMbForTesting(
uint64_t amount_of_memory_mb);
static void ClearAmountOfPhysicalMemoryMbForTesting();
};
} // namespace base
#endif // BASE_SYSTEM_SYS_INFO_H_