Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 14:04:28 +01:00
parent 81b91f4139
commit f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions

View file

@ -0,0 +1,125 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <algorithm>
#include "base/base_switches.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/system/sys_info_internal.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/task_runner_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
namespace base {
namespace {
static const int kLowMemoryDeviceThresholdMB = 512;
} // namespace
// static
int64_t SysInfo::AmountOfPhysicalMemory() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLowEndDeviceMode)) {
return kLowMemoryDeviceThresholdMB * 1024 * 1024;
}
return AmountOfPhysicalMemoryImpl();
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemory() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLowEndDeviceMode)) {
// Estimate the available memory by subtracting our memory used estimate
// from the fake |kLowMemoryDeviceThresholdMB| limit.
size_t memory_used =
AmountOfPhysicalMemoryImpl() - AmountOfAvailablePhysicalMemoryImpl();
size_t memory_limit = kLowMemoryDeviceThresholdMB * 1024 * 1024;
// std::min ensures no underflow, as |memory_used| can be > |memory_limit|.
return memory_limit - std::min(memory_used, memory_limit);
}
return AmountOfAvailablePhysicalMemoryImpl();
}
bool SysInfo::IsLowEndDevice() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLowEndDeviceMode)) {
return true;
}
return IsLowEndDeviceImpl();
}
#if !defined(OS_ANDROID)
bool DetectLowEndDevice() {
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kEnableLowEndDeviceMode))
return true;
if (command_line->HasSwitch(switches::kDisableLowEndDeviceMode))
return false;
int ram_size_mb = SysInfo::AmountOfPhysicalMemoryMB();
return (ram_size_mb > 0 && ram_size_mb <= kLowMemoryDeviceThresholdMB);
}
// static
bool SysInfo::IsLowEndDeviceImpl() {
static base::NoDestructor<
internal::LazySysInfoValue<bool, DetectLowEndDevice>>
instance;
return instance->value();
}
#endif
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
std::string SysInfo::HardwareModelName() {
return std::string();
}
#endif
void SysInfo::GetHardwareInfo(base::OnceCallback<void(HardwareInfo)> callback) {
#if defined(OS_WIN)
// On Windows the calls to GetHardwareInfoSync can take a really long time to
// complete as they depend on WMI, using the CONTINUE_ON_SHUTDOWN traits will
// prevent this task from blocking shutdown.
base::PostTaskAndReplyWithResult(
base::ThreadPool::CreateCOMSTATaskRunner(
{TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})
.get(),
FROM_HERE, base::BindOnce(&GetHardwareInfoSync), std::move(callback));
#elif defined(OS_ANDROID) || defined(OS_MACOSX)
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {}, base::BindOnce(&GetHardwareInfoSync), std::move(callback));
#elif defined(OS_LINUX)
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&GetHardwareInfoSync),
std::move(callback));
#else
NOTIMPLEMENTED();
base::ThreadPool::PostTask(
FROM_HERE, {}, base::BindOnce(std::move(callback), HardwareInfo()));
#endif
}
// static
base::TimeDelta SysInfo::Uptime() {
// This code relies on an implementation detail of TimeTicks::Now() - that
// its return value happens to coincide with the system uptime value in
// microseconds, on Win/Mac/iOS/Linux/ChromeOS and Android.
int64_t uptime_in_microseconds = TimeTicks::Now().ToInternalValue();
return base::TimeDelta::FromMicroseconds(uptime_in_microseconds);
}
} // namespace base

View file

@ -0,0 +1,217 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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 <string>
#include "base/base_export.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
namespace base {
namespace debug {
FORWARD_DECLARE_TEST(SystemMetricsTest, ParseMeminfo);
}
struct SystemMemoryInfoKB;
class BASE_EXPORT SysInfo {
public:
// Return the number of logical processors/cores on the current machine.
static int NumberOfProcessors();
// Return the number of bytes of physical memory on the current machine.
static int64_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 int64_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 int64_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);
// 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 OS X, iOS, and Android. This returns an empty string on
// other platforms.
static std::string HardwareModelName();
struct HardwareInfo {
std::string manufacturer;
std::string model;
// On Windows, this is the BIOS serial number. Unsupported platforms will be
// set to an empty string.
// Note: validate any new usage with the privacy team.
// TODO(crbug.com/907518): Implement support on other platforms.
std::string serial_number;
bool operator==(const HardwareInfo& rhs) const {
return manufacturer == rhs.manufacturer && model == rhs.model &&
serial_number == rhs.serial_number;
}
};
// 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, OS X,
// 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 the base::mac::IsOS*
// 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();
// Avoid using this. Use base/cpu.h to get information about the CPU instead.
// http://crbug.com/148884
// Returns the CPU model name of the system. If it can not be figured out,
// an empty string is returned.
static std::string CPUModelName();
// Return the smallest amount of memory (in bytes) which the VM system will
// allocate.
static size_t VMAllocationGranularity();
#if defined(OS_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();
// Test method to force re-parsing of lsb-release.
static void SetChromeOSVersionInfoForTest(const std::string& lsb_release,
const Time& lsb_release_time);
// Returns the kernel version of the host operating system.
static std::string KernelVersion();
#endif // defined(OS_CHROMEOS)
#if defined(OS_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();
static int DalvikHeapSizeMB();
static int DalvikHeapGrowthLimitMB();
#endif // defined(OS_ANDROID)
#if defined(OS_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();
#endif // defined(OS_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 <= 512MB.
static bool IsLowEndDevice();
private:
FRIEND_TEST_ALL_PREFIXES(SysInfoTest, AmountOfAvailablePhysicalMemory);
FRIEND_TEST_ALL_PREFIXES(debug::SystemMetricsTest, ParseMeminfo);
static int64_t AmountOfPhysicalMemoryImpl();
static int64_t AmountOfAvailablePhysicalMemoryImpl();
static bool IsLowEndDeviceImpl();
static HardwareInfo GetHardwareInfoSync();
#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX)
static int64_t AmountOfAvailablePhysicalMemory(
const SystemMemoryInfoKB& meminfo);
#endif
};
} // namespace base
#endif // BASE_SYSTEM_SYS_INFO_H_

View file

@ -0,0 +1,264 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <dlfcn.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/system_properties.h>
#include "base/android/jni_android.h"
#include "base/android/sys_utils.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info_internal.h"
#if (__ANDROID_API__ >= 21 /* 5.0 - Lollipop */)
namespace {
typedef int(SystemPropertyGetFunction)(const char*, char*);
SystemPropertyGetFunction* DynamicallyLoadRealSystemPropertyGet() {
// libc.so should already be open, get a handle to it.
void* handle = dlopen("libc.so", RTLD_NOLOAD);
if (!handle) {
LOG(FATAL) << "Cannot dlopen libc.so: " << dlerror();
}
SystemPropertyGetFunction* real_system_property_get =
reinterpret_cast<SystemPropertyGetFunction*>(
dlsym(handle, "__system_property_get"));
if (!real_system_property_get) {
LOG(FATAL) << "Cannot resolve __system_property_get(): " << dlerror();
}
return real_system_property_get;
}
static base::LazyInstance<base::internal::LazySysInfoValue<
SystemPropertyGetFunction*,
DynamicallyLoadRealSystemPropertyGet>>::Leaky
g_lazy_real_system_property_get = LAZY_INSTANCE_INITIALIZER;
} // namespace
// Android 'L' removes __system_property_get from the NDK, however it is still
// a hidden symbol in libc. Until we remove all calls of __system_property_get
// from Chrome we work around this by defining a weak stub here, which uses
// dlsym to but ensures that Chrome uses the real system
// implementatation when loaded. http://crbug.com/392191.
BASE_EXPORT int __system_property_get(const char* name, char* value) {
return g_lazy_real_system_property_get.Get().value()(name, value);
}
#endif
namespace {
// Default version of Android to fall back to when actual version numbers
// cannot be acquired. Use the latest Android release with a higher bug fix
// version to avoid unnecessarily comparison errors with the latest release.
// This should be manually kept up to date on each Android release.
const int kDefaultAndroidMajorVersion = 10;
const int kDefaultAndroidMinorVersion = 0;
const int kDefaultAndroidBugfixVersion = 99;
// Get and parse out the OS version numbers from the system properties.
// Note if parse fails, the "default" version is returned as fallback.
void GetOsVersionStringAndNumbers(std::string* version_string,
int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
// Read the version number string out from the properties.
char os_version_str[PROP_VALUE_MAX];
__system_property_get("ro.build.version.release", os_version_str);
if (os_version_str[0]) {
// Try to parse out the version numbers from the string.
int num_read = sscanf(os_version_str, "%d.%d.%d", major_version,
minor_version, bugfix_version);
if (num_read > 0) {
// If we don't have a full set of version numbers, make the extras 0.
if (num_read < 2)
*minor_version = 0;
if (num_read < 3)
*bugfix_version = 0;
*version_string = std::string(os_version_str);
return;
}
}
// For some reason, we couldn't parse the version number string.
*major_version = kDefaultAndroidMajorVersion;
*minor_version = kDefaultAndroidMinorVersion;
*bugfix_version = kDefaultAndroidBugfixVersion;
*version_string = ::base::StringPrintf("%d.%d.%d", *major_version,
*minor_version, *bugfix_version);
}
// Parses a system property (specified with unit 'k','m' or 'g').
// Returns a value in bytes.
// Returns -1 if the string could not be parsed.
int64_t ParseSystemPropertyBytes(const base::StringPiece& str) {
const int64_t KB = 1024;
const int64_t MB = 1024 * KB;
const int64_t GB = 1024 * MB;
if (str.size() == 0u)
return -1;
int64_t unit_multiplier = 1;
size_t length = str.size();
if (str[length - 1] == 'k') {
unit_multiplier = KB;
length--;
} else if (str[length - 1] == 'm') {
unit_multiplier = MB;
length--;
} else if (str[length - 1] == 'g') {
unit_multiplier = GB;
length--;
}
int64_t result = 0;
bool parsed = base::StringToInt64(str.substr(0, length), &result);
bool negative = result <= 0;
bool overflow =
result >= std::numeric_limits<int64_t>::max() / unit_multiplier;
if (!parsed || negative || overflow)
return -1;
return result * unit_multiplier;
}
int GetDalvikHeapSizeMB() {
char heap_size_str[PROP_VALUE_MAX];
__system_property_get("dalvik.vm.heapsize", heap_size_str);
// dalvik.vm.heapsize property is writable by a root user.
// Clamp it to reasonable range as a sanity check,
// a typical android device will never have less than 48MB.
const int64_t MB = 1024 * 1024;
int64_t result = ParseSystemPropertyBytes(heap_size_str);
if (result == -1) {
// We should consider not exposing these values if they are not reliable.
LOG(ERROR) << "Can't parse dalvik.vm.heapsize: " << heap_size_str;
result = base::SysInfo::AmountOfPhysicalMemoryMB() / 3;
}
result =
std::min<int64_t>(std::max<int64_t>(32 * MB, result), 1024 * MB) / MB;
return static_cast<int>(result);
}
int GetDalvikHeapGrowthLimitMB() {
char heap_size_str[PROP_VALUE_MAX];
__system_property_get("dalvik.vm.heapgrowthlimit", heap_size_str);
// dalvik.vm.heapgrowthlimit property is writable by a root user.
// Clamp it to reasonable range as a sanity check,
// a typical android device will never have less than 24MB.
const int64_t MB = 1024 * 1024;
int64_t result = ParseSystemPropertyBytes(heap_size_str);
if (result == -1) {
// We should consider not exposing these values if they are not reliable.
LOG(ERROR) << "Can't parse dalvik.vm.heapgrowthlimit: " << heap_size_str;
result = base::SysInfo::AmountOfPhysicalMemoryMB() / 6;
}
result = std::min<int64_t>(std::max<int64_t>(16 * MB, result), 512 * MB) / MB;
return static_cast<int>(result);
}
std::string HardwareManufacturerName() {
char device_model_str[PROP_VALUE_MAX];
__system_property_get("ro.product.manufacturer", device_model_str);
return std::string(device_model_str);
}
} // anonymous namespace
namespace base {
std::string SysInfo::HardwareModelName() {
char device_model_str[PROP_VALUE_MAX];
__system_property_get("ro.product.model", device_model_str);
return std::string(device_model_str);
}
std::string SysInfo::OperatingSystemName() {
return "Android";
}
std::string SysInfo::OperatingSystemVersion() {
std::string version_string;
int32_t major, minor, bugfix;
GetOsVersionStringAndNumbers(&version_string, &major, &minor, &bugfix);
return version_string;
}
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
std::string version_string;
GetOsVersionStringAndNumbers(&version_string, major_version, minor_version,
bugfix_version);
}
std::string SysInfo::GetAndroidBuildCodename() {
char os_version_codename_str[PROP_VALUE_MAX];
__system_property_get("ro.build.version.codename", os_version_codename_str);
return std::string(os_version_codename_str);
}
std::string SysInfo::GetAndroidBuildID() {
char os_build_id_str[PROP_VALUE_MAX];
__system_property_get("ro.build.id", os_build_id_str);
return std::string(os_build_id_str);
}
std::string SysInfo::GetAndroidHardwareEGL() {
char os_hardware_egl_str[PROP_VALUE_MAX];
__system_property_get("ro.hardware.egl", os_hardware_egl_str);
return std::string(os_hardware_egl_str);
}
int SysInfo::DalvikHeapSizeMB() {
static int heap_size = GetDalvikHeapSizeMB();
return heap_size;
}
int SysInfo::DalvikHeapGrowthLimitMB() {
static int heap_growth_limit = GetDalvikHeapGrowthLimitMB();
return heap_growth_limit;
}
static base::LazyInstance<base::internal::LazySysInfoValue<
bool,
android::SysUtils::IsLowEndDeviceFromJni>>::Leaky g_lazy_low_end_device =
LAZY_INSTANCE_INITIALIZER;
bool SysInfo::IsLowEndDeviceImpl() {
// This code might be used in some environments
// which might not have a Java environment.
// Note that we need to call the Java version here.
// There exists a complete native implementation in
// sys_info.cc but calling that here would mean that
// the Java code and the native code would call different
// implementations which could give different results.
// Also the Java code cannot depend on the native code
// since it might not be loaded yet.
if (!base::android::IsVMInitialized())
return false;
return g_lazy_low_end_device.Get().value();
}
// static
SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
HardwareInfo info;
info.manufacturer = HardwareManufacturerName();
info.model = HardwareModelName();
DCHECK(IsStringUTF8(info.manufacturer));
DCHECK(IsStringUTF8(info.model));
return info;
}
} // namespace base

View file

@ -0,0 +1,225 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/utsname.h>
#include "base/environment.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
namespace base {
namespace {
const char* const kLinuxStandardBaseVersionKeys[] = {
"CHROMEOS_RELEASE_VERSION", "GOOGLE_RELEASE", "DISTRIB_RELEASE",
};
const char kChromeOsReleaseNameKey[] = "CHROMEOS_RELEASE_NAME";
const char* const kChromeOsReleaseNames[] = {
"Chrome OS", "Chromium OS",
};
const char kLinuxStandardBaseReleaseFile[] = "/etc/lsb-release";
const char kLsbReleaseKey[] = "LSB_RELEASE";
const char kLsbReleaseTimeKey[] = "LSB_RELEASE_TIME"; // Seconds since epoch
const char kLsbReleaseSourceKey[] = "lsb-release";
const char kLsbReleaseSourceEnv[] = "env";
const char kLsbReleaseSourceFile[] = "file";
class ChromeOSVersionInfo {
public:
ChromeOSVersionInfo() { Parse(); }
void Parse() {
lsb_release_map_.clear();
major_version_ = 0;
minor_version_ = 0;
bugfix_version_ = 0;
is_running_on_chromeos_ = false;
std::string lsb_release, lsb_release_time_str;
std::unique_ptr<Environment> env(Environment::Create());
bool parsed_from_env =
env->GetVar(kLsbReleaseKey, &lsb_release) &&
env->GetVar(kLsbReleaseTimeKey, &lsb_release_time_str);
if (parsed_from_env) {
double us = 0;
if (StringToDouble(lsb_release_time_str, &us))
lsb_release_time_ = Time::FromDoubleT(us);
} else {
// If the LSB_RELEASE and LSB_RELEASE_TIME environment variables are not
// set, fall back to a blocking read of the lsb_release file. This should
// only happen in non Chrome OS environments.
ThreadRestrictions::ScopedAllowIO allow_io;
FilePath path(kLinuxStandardBaseReleaseFile);
ReadFileToString(path, &lsb_release);
File::Info fileinfo;
if (GetFileInfo(path, &fileinfo))
lsb_release_time_ = fileinfo.creation_time;
}
ParseLsbRelease(lsb_release);
// For debugging:
lsb_release_map_[kLsbReleaseSourceKey] =
parsed_from_env ? kLsbReleaseSourceEnv : kLsbReleaseSourceFile;
}
bool GetLsbReleaseValue(const std::string& key, std::string* value) {
LsbReleaseMap::const_iterator iter = lsb_release_map_.find(key);
if (iter == lsb_release_map_.end())
return false;
*value = iter->second;
return true;
}
void GetVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
*major_version = major_version_;
*minor_version = minor_version_;
*bugfix_version = bugfix_version_;
}
const Time& lsb_release_time() const { return lsb_release_time_; }
bool is_running_on_chromeos() const { return is_running_on_chromeos_; }
private:
void ParseLsbRelease(const std::string& lsb_release) {
// Parse and cache lsb_release key pairs. There should only be a handful
// of entries so the overhead for this will be small, and it can be
// useful for debugging.
base::StringPairs pairs;
SplitStringIntoKeyValuePairs(lsb_release, '=', '\n', &pairs);
for (size_t i = 0; i < pairs.size(); ++i) {
std::string key, value;
TrimWhitespaceASCII(pairs[i].first, TRIM_ALL, &key);
TrimWhitespaceASCII(pairs[i].second, TRIM_ALL, &value);
if (key.empty())
continue;
lsb_release_map_[key] = value;
}
// Parse the version from the first matching recognized version key.
std::string version;
for (size_t i = 0; i < base::size(kLinuxStandardBaseVersionKeys); ++i) {
std::string key = kLinuxStandardBaseVersionKeys[i];
if (GetLsbReleaseValue(key, &version) && !version.empty())
break;
}
StringTokenizer tokenizer(version, ".");
if (tokenizer.GetNext()) {
StringToInt(tokenizer.token_piece(), &major_version_);
}
if (tokenizer.GetNext()) {
StringToInt(tokenizer.token_piece(), &minor_version_);
}
if (tokenizer.GetNext()) {
StringToInt(tokenizer.token_piece(), &bugfix_version_);
}
// Check release name for Chrome OS.
std::string release_name;
if (GetLsbReleaseValue(kChromeOsReleaseNameKey, &release_name)) {
for (size_t i = 0; i < base::size(kChromeOsReleaseNames); ++i) {
if (release_name == kChromeOsReleaseNames[i]) {
is_running_on_chromeos_ = true;
break;
}
}
}
}
using LsbReleaseMap = std::map<std::string, std::string>;
Time lsb_release_time_;
LsbReleaseMap lsb_release_map_;
int32_t major_version_;
int32_t minor_version_;
int32_t bugfix_version_;
bool is_running_on_chromeos_;
};
static LazyInstance<ChromeOSVersionInfo>::Leaky g_chrome_os_version_info =
LAZY_INSTANCE_INITIALIZER;
ChromeOSVersionInfo& GetChromeOSVersionInfo() {
return g_chrome_os_version_info.Get();
}
} // namespace
// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
return GetChromeOSVersionInfo().GetVersionNumbers(
major_version, minor_version, bugfix_version);
}
// static
std::string SysInfo::OperatingSystemVersion() {
int32_t major, minor, bugfix;
GetChromeOSVersionInfo().GetVersionNumbers(&major, &minor, &bugfix);
return base::StringPrintf("%d.%d.%d", major, minor, bugfix);
}
// static
std::string SysInfo::KernelVersion() {
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
return std::string();
}
return std::string(info.release);
}
// static
bool SysInfo::GetLsbReleaseValue(const std::string& key, std::string* value) {
return GetChromeOSVersionInfo().GetLsbReleaseValue(key, value);
}
// static
std::string SysInfo::GetLsbReleaseBoard() {
const char kMachineInfoBoard[] = "CHROMEOS_RELEASE_BOARD";
std::string board;
if (!GetLsbReleaseValue(kMachineInfoBoard, &board))
board = "unknown";
return board;
}
// static
Time SysInfo::GetLsbReleaseTime() {
return GetChromeOSVersionInfo().lsb_release_time();
}
// static
bool SysInfo::IsRunningOnChromeOS() {
return GetChromeOSVersionInfo().is_running_on_chromeos();
}
// static
void SysInfo::SetChromeOSVersionInfoForTest(const std::string& lsb_release,
const Time& lsb_release_time) {
std::unique_ptr<Environment> env(Environment::Create());
env->SetVar(kLsbReleaseKey, lsb_release);
env->SetVar(kLsbReleaseTimeKey, NumberToString(lsb_release_time.ToDoubleT()));
g_chrome_os_version_info.Get().Parse();
}
} // namespace base

View file

@ -0,0 +1,38 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/sysctl.h>
#include "base/logging.h"
namespace base {
int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
int pages, page_size;
size_t size = sizeof(pages);
sysctlbyname("vm.stats.vm.v_page_count", &pages, &size, NULL, 0);
sysctlbyname("vm.stats.vm.v_page_size", &page_size, &size, NULL, 0);
if (pages == -1 || page_size == -1) {
NOTREACHED();
return 0;
}
return static_cast<int64_t>(pages) * page_size;
}
// static
uint64_t SysInfo::MaxSharedMemorySize() {
size_t limit;
size_t size = sizeof(limit);
if (sysctlbyname("kern.ipc.shmmax", &limit, &size, NULL, 0) < 0) {
NOTREACHED();
return 0;
}
return static_cast<uint64_t>(limit);
}
} // namespace base

View file

@ -0,0 +1,90 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <zircon/syscalls.h>
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/build_config.h"
namespace base {
// static
int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
return zx_system_get_physmem();
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
// TODO(https://crbug.com/986608): Implement this.
NOTIMPLEMENTED_LOG_ONCE();
return 0;
}
// static
int SysInfo::NumberOfProcessors() {
return zx_system_get_num_cpus();
}
// static
int64_t SysInfo::AmountOfVirtualMemory() {
return 0;
}
// static
std::string SysInfo::OperatingSystemName() {
return "Fuchsia";
}
// static
int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
NOTIMPLEMENTED_LOG_ONCE();
return -1;
}
// static
int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
NOTIMPLEMENTED_LOG_ONCE();
return -1;
}
// static
std::string SysInfo::OperatingSystemVersion() {
return zx_system_get_version_string();
}
// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
// Fuchsia doesn't have OS version numbers.
*major_version = 0;
*minor_version = 0;
*bugfix_version = 0;
}
// static
std::string SysInfo::OperatingSystemArchitecture() {
#if defined(ARCH_CPU_X86_64)
return "x86_64";
#elif defined(ARCH_CPU_ARM64)
return "aarch64";
#else
#error Unsupported architecture.
#endif
}
// static
size_t SysInfo::VMAllocationGranularity() {
return getpagesize();
}
} // namespace base

View file

@ -0,0 +1,33 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// 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_INTERNAL_H_
#define BASE_SYSTEM_SYS_INFO_INTERNAL_H_
#include "base/macros.h"
namespace base {
namespace internal {
template <typename T, T (*F)(void)>
class LazySysInfoValue {
public:
LazySysInfoValue() : value_(F()) {}
~LazySysInfoValue() = default;
T value() { return value_; }
private:
const T value_;
DISALLOW_COPY_AND_ASSIGN(LazySysInfoValue);
};
} // namespace internal
} // namespace base
#endif // BASE_SYSTEM_SYS_INFO_INTERNAL_H_

View file

@ -0,0 +1,153 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#import <UIKit/UIKit.h>
#include <mach/mach.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include "base/logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/process/process_metrics.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
namespace base {
namespace {
// Queries sysctlbyname() for the given key and returns the value from the
// system or the empty string on failure.
std::string GetSysctlValue(const char* key_name) {
char value[256];
size_t len = base::size(value);
if (sysctlbyname(key_name, &value, &len, nullptr, 0) == 0) {
DCHECK_GE(len, 1u);
DCHECK_EQ('\0', value[len - 1]);
return std::string(value, len - 1);
}
return std::string();
}
} // namespace
// static
std::string SysInfo::OperatingSystemName() {
static dispatch_once_t get_system_name_once;
static std::string* system_name;
dispatch_once(&get_system_name_once, ^{
@autoreleasepool {
system_name = new std::string(
SysNSStringToUTF8([[UIDevice currentDevice] systemName]));
}
});
// Examples of returned value: 'iPhone OS' on iPad 5.1.1
// and iPhone 5.1.1.
return *system_name;
}
// static
std::string SysInfo::OperatingSystemVersion() {
static dispatch_once_t get_system_version_once;
static std::string* system_version;
dispatch_once(&get_system_version_once, ^{
@autoreleasepool {
system_version = new std::string(
SysNSStringToUTF8([[UIDevice currentDevice] systemVersion]));
}
});
return *system_version;
}
// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
@autoreleasepool {
std::string system_version = OperatingSystemVersion();
if (!system_version.empty()) {
// Try to parse out the version numbers from the string.
int num_read = sscanf(system_version.c_str(), "%d.%d.%d", major_version,
minor_version, bugfix_version);
if (num_read < 1)
*major_version = 0;
if (num_read < 2)
*minor_version = 0;
if (num_read < 3)
*bugfix_version = 0;
}
}
}
// static
std::string SysInfo::GetIOSBuildNumber() {
int mib[2] = {CTL_KERN, KERN_OSVERSION};
unsigned int namelen = sizeof(mib) / sizeof(mib[0]);
size_t buffer_size = 0;
sysctl(mib, namelen, nullptr, &buffer_size, nullptr, 0);
char build_number[buffer_size];
int result = sysctl(mib, namelen, build_number, &buffer_size, nullptr, 0);
DCHECK(result == 0);
return build_number;
}
// static
int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
struct host_basic_info hostinfo;
mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
base::mac::ScopedMachSendRight host(mach_host_self());
int result = host_info(host.get(), HOST_BASIC_INFO,
reinterpret_cast<host_info_t>(&hostinfo), &count);
if (result != KERN_SUCCESS) {
NOTREACHED();
return 0;
}
DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
return static_cast<int64_t>(hostinfo.max_mem);
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
SystemMemoryInfoKB info;
if (!GetSystemMemoryInfo(&info))
return 0;
// We should add inactive file-backed memory also but there is no such
// information from iOS unfortunately.
return static_cast<int64_t>(info.free + info.speculative) * 1024;
}
// static
std::string SysInfo::CPUModelName() {
return GetSysctlValue("machdep.cpu.brand_string");
}
// static
std::string SysInfo::HardwareModelName() {
#if TARGET_OS_SIMULATOR
// On the simulator, "hw.machine" returns "i386" or "x86_64" which doesn't
// match the expected format, so supply a fake string here.
return "Simulator1,1";
#else
// Note: This uses "hw.machine" instead of "hw.model" like the Mac code,
// because "hw.model" doesn't always return the right string on some devices.
return GetSysctlValue("hw.machine");
#endif
}
// static
SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
HardwareInfo info;
info.manufacturer = "Apple Inc.";
info.model = HardwareModelName();
DCHECK(IsStringUTF8(info.manufacturer));
DCHECK(IsStringUTF8(info.model));
return info;
}
} // namespace base

View file

@ -0,0 +1,117 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <stddef.h>
#include <stdint.h>
#include <limits>
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/process/process_metrics.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info_internal.h"
#include "build/build_config.h"
namespace {
int64_t AmountOfMemory(int pages_name) {
long pages = sysconf(pages_name);
long page_size = sysconf(_SC_PAGESIZE);
if (pages == -1 || page_size == -1) {
NOTREACHED();
return 0;
}
return static_cast<int64_t>(pages) * page_size;
}
int64_t AmountOfPhysicalMemory() {
return AmountOfMemory(_SC_PHYS_PAGES);
}
base::LazyInstance<
base::internal::LazySysInfoValue<int64_t, AmountOfPhysicalMemory>>::Leaky
g_lazy_physical_memory = LAZY_INSTANCE_INITIALIZER;
} // namespace
namespace base {
// static
int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
return g_lazy_physical_memory.Get().value();
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
SystemMemoryInfoKB info;
if (!GetSystemMemoryInfo(&info))
return 0;
return AmountOfAvailablePhysicalMemory(info);
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemory(
const SystemMemoryInfoKB& info) {
// See details here:
// https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
// The fallback logic (when there is no MemAvailable) would be more precise
// if we had info about zones watermarks (/proc/zoneinfo).
int64_t res_kb = info.available != 0
? info.available - info.active_file
: info.free + info.reclaimable + info.inactive_file;
return res_kb * 1024;
}
// static
std::string SysInfo::CPUModelName() {
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
const char kCpuModelPrefix[] = "Hardware";
#else
const char kCpuModelPrefix[] = "model name";
#endif
std::string contents;
ReadFileToString(FilePath("/proc/cpuinfo"), &contents);
DCHECK(!contents.empty());
if (!contents.empty()) {
std::istringstream iss(contents);
std::string line;
while (std::getline(iss, line)) {
if (line.compare(0, strlen(kCpuModelPrefix), kCpuModelPrefix) == 0) {
size_t pos = line.find(": ");
return line.substr(pos + 2);
}
}
}
return std::string();
}
#if !defined(OS_ANDROID)
// static
SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
static const size_t kMaxStringSize = 100u;
HardwareInfo info;
std::string data;
if (ReadFileToStringWithMaxSize(
FilePath("/sys/devices/virtual/dmi/id/sys_vendor"), &data,
kMaxStringSize)) {
TrimWhitespaceASCII(data, TrimPositions::TRIM_ALL, &info.manufacturer);
}
if (ReadFileToStringWithMaxSize(
FilePath("/sys/devices/virtual/dmi/id/product_name"), &data,
kMaxStringSize)) {
TrimWhitespaceASCII(data, TrimPositions::TRIM_ALL, &info.model);
}
DCHECK(IsStringUTF8(info.manufacturer));
DCHECK(IsStringUTF8(info.model));
return info;
}
#endif
} // namespace base

View file

@ -0,0 +1,112 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <ApplicationServices/ApplicationServices.h>
#include <CoreServices/CoreServices.h>
#import <Foundation/Foundation.h>
#include <mach/mach_host.h>
#include <mach/mach_init.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_mach_port.h"
#include "base/process/process_metrics.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
namespace base {
namespace {
// Queries sysctlbyname() for the given key and returns the value from the
// system or the empty string on failure.
std::string GetSysctlValue(const char* key_name) {
char value[256];
size_t len = base::size(value);
if (sysctlbyname(key_name, &value, &len, nullptr, 0) == 0) {
DCHECK_GE(len, 1u);
DCHECK_EQ('\0', value[len - 1]);
return std::string(value, len - 1);
}
return std::string();
}
} // namespace
// static
std::string SysInfo::OperatingSystemName() {
return "Mac OS X";
}
// static
std::string SysInfo::OperatingSystemVersion() {
int32_t major, minor, bugfix;
OperatingSystemVersionNumbers(&major, &minor, &bugfix);
return base::StringPrintf("%d.%d.%d", major, minor, bugfix);
}
// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
NSOperatingSystemVersion version =
[[NSProcessInfo processInfo] operatingSystemVersion];
*major_version = version.majorVersion;
*minor_version = version.minorVersion;
*bugfix_version = version.patchVersion;
}
// static
int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
struct host_basic_info hostinfo;
mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
base::mac::ScopedMachSendRight host(mach_host_self());
int result = host_info(host.get(), HOST_BASIC_INFO,
reinterpret_cast<host_info_t>(&hostinfo), &count);
if (result != KERN_SUCCESS) {
NOTREACHED();
return 0;
}
DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
return static_cast<int64_t>(hostinfo.max_mem);
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
SystemMemoryInfoKB info;
if (!GetSystemMemoryInfo(&info))
return 0;
// We should add inactive file-backed memory also but there is no such
// information from Mac OS unfortunately.
return static_cast<int64_t>(info.free + info.speculative) * 1024;
}
// static
std::string SysInfo::CPUModelName() {
return GetSysctlValue("machdep.cpu.brand_string");
}
// static
std::string SysInfo::HardwareModelName() {
return GetSysctlValue("hw.model");
}
// static
SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
HardwareInfo info;
info.manufacturer = "Apple Inc.";
info.model = HardwareModelName();
DCHECK(IsStringUTF8(info.manufacturer));
DCHECK(IsStringUTF8(info.model));
return info;
}
} // namespace base

View file

@ -0,0 +1,80 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/param.h>
#include <sys/shm.h>
#include <sys/sysctl.h>
#include "base/logging.h"
#include "base/stl_util.h"
namespace {
int64_t AmountOfMemory(int pages_name) {
long pages = sysconf(pages_name);
long page_size = sysconf(_SC_PAGESIZE);
if (pages == -1 || page_size == -1) {
NOTREACHED();
return 0;
}
return static_cast<int64_t>(pages) * page_size;
}
} // namespace
namespace base {
// static
int SysInfo::NumberOfProcessors() {
int mib[] = {CTL_HW, HW_NCPU};
int ncpu;
size_t size = sizeof(ncpu);
if (sysctl(mib, base::size(mib), &ncpu, &size, NULL, 0) < 0) {
NOTREACHED();
return 1;
}
return ncpu;
}
// static
int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
return AmountOfMemory(_SC_PHYS_PAGES);
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
// We should add inactive file-backed memory also but there is no such
// information from OpenBSD unfortunately.
return AmountOfMemory(_SC_AVPHYS_PAGES);
}
// static
uint64_t SysInfo::MaxSharedMemorySize() {
int mib[] = {CTL_KERN, KERN_SHMINFO, KERN_SHMINFO_SHMMAX};
size_t limit;
size_t size = sizeof(limit);
if (sysctl(mib, base::size(mib), &limit, &size, NULL, 0) < 0) {
NOTREACHED();
return 0;
}
return static_cast<uint64_t>(limit);
}
// static
std::string SysInfo::CPUModelName() {
int mib[] = {CTL_HW, HW_MODEL};
char name[256];
size_t len = base::size(name);
if (sysctl(mib, base::size(mib), name, &len, NULL, 0) < 0) {
NOTREACHED();
return std::string();
}
return name;
}
} // namespace base

View file

@ -0,0 +1,234 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/utsname.h>
#include <unistd.h>
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info_internal.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/build_config.h"
#if defined(OS_ANDROID)
#include <sys/vfs.h>
#define statvfs statfs // Android uses a statvfs-like statfs struct and call.
#else
#include <sys/statvfs.h>
#endif
#if defined(OS_LINUX)
#include <linux/magic.h>
#include <sys/vfs.h>
#endif
namespace {
#if !defined(OS_OPENBSD)
int NumberOfProcessors() {
// sysconf returns the number of "logical" (not "physical") processors on both
// Mac and Linux. So we get the number of max available "logical" processors.
//
// Note that the number of "currently online" processors may be fewer than the
// returned value of NumberOfProcessors(). On some platforms, the kernel may
// make some processors offline intermittently, to save power when system
// loading is low.
//
// One common use case that needs to know the processor count is to create
// optimal number of threads for optimization. It should make plan according
// to the number of "max available" processors instead of "currently online"
// ones. The kernel should be smart enough to make all processors online when
// it has sufficient number of threads waiting to run.
long res = sysconf(_SC_NPROCESSORS_CONF);
if (res == -1) {
NOTREACHED();
return 1;
}
return static_cast<int>(res);
}
base::LazyInstance<base::internal::LazySysInfoValue<int, NumberOfProcessors>>::
Leaky g_lazy_number_of_processors = LAZY_INSTANCE_INITIALIZER;
#endif // !defined(OS_OPENBSD)
int64_t AmountOfVirtualMemory() {
struct rlimit limit;
int result = getrlimit(RLIMIT_DATA, &limit);
if (result != 0) {
NOTREACHED();
return 0;
}
return limit.rlim_cur == RLIM_INFINITY ? 0 : limit.rlim_cur;
}
base::LazyInstance<
base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky
g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER;
#if defined(OS_LINUX)
bool IsStatsZeroIfUnlimited(const base::FilePath& path) {
struct statfs stats;
if (HANDLE_EINTR(statfs(path.value().c_str(), &stats)) != 0)
return false;
switch (stats.f_type) {
case TMPFS_MAGIC:
case HUGETLBFS_MAGIC:
case RAMFS_MAGIC:
return true;
}
return false;
}
#endif // defined(OS_LINUX)
bool GetDiskSpaceInfo(const base::FilePath& path,
int64_t* available_bytes,
int64_t* total_bytes) {
struct statvfs stats;
if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0)
return false;
#if defined(OS_LINUX)
const bool zero_size_means_unlimited =
stats.f_blocks == 0 && IsStatsZeroIfUnlimited(path);
#else
const bool zero_size_means_unlimited = false;
#endif
if (available_bytes) {
*available_bytes =
zero_size_means_unlimited
? std::numeric_limits<int64_t>::max()
: static_cast<int64_t>(stats.f_bavail) * stats.f_frsize;
}
if (total_bytes) {
*total_bytes = zero_size_means_unlimited
? std::numeric_limits<int64_t>::max()
: static_cast<int64_t>(stats.f_blocks) * stats.f_frsize;
}
return true;
}
} // namespace
namespace base {
#if !defined(OS_OPENBSD)
int SysInfo::NumberOfProcessors() {
return g_lazy_number_of_processors.Get().value();
}
#endif // !defined(OS_OPENBSD)
// static
int64_t SysInfo::AmountOfVirtualMemory() {
return g_lazy_virtual_memory.Get().value();
}
// static
int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
int64_t available;
if (!GetDiskSpaceInfo(path, &available, nullptr))
return -1;
return available;
}
// static
int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
int64_t total;
if (!GetDiskSpaceInfo(path, nullptr, &total))
return -1;
return total;
}
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
// static
std::string SysInfo::OperatingSystemName() {
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
return std::string();
}
return std::string(info.sysname);
}
#endif //! defined(OS_MACOSX) && !defined(OS_ANDROID)
#if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
// static
std::string SysInfo::OperatingSystemVersion() {
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
return std::string();
}
return std::string(info.release);
}
#endif
#if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
*major_version = 0;
*minor_version = 0;
*bugfix_version = 0;
return;
}
int num_read = sscanf(info.release, "%d.%d.%d", major_version, minor_version,
bugfix_version);
if (num_read < 1)
*major_version = 0;
if (num_read < 2)
*minor_version = 0;
if (num_read < 3)
*bugfix_version = 0;
}
#endif
// static
std::string SysInfo::OperatingSystemArchitecture() {
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
return std::string();
}
std::string arch(info.machine);
if (arch == "i386" || arch == "i486" || arch == "i586" || arch == "i686") {
arch = "x86";
} else if (arch == "amd64") {
arch = "x86_64";
} else if (std::string(info.sysname) == "AIX") {
arch = "ppc64";
}
return arch;
}
// static
size_t SysInfo::VMAllocationGranularity() {
return getpagesize();
}
} // namespace base

View file

@ -0,0 +1,182 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/sys_info.h"
#include <stddef.h>
#include <stdint.h>
#include <windows.h>
#include <limits>
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/process/process_metrics.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/win/windows_version.h"
#include "base/win/wmi.h"
namespace {
int64_t AmountOfMemory(DWORDLONG MEMORYSTATUSEX::*memory_field) {
MEMORYSTATUSEX memory_info;
memory_info.dwLength = sizeof(memory_info);
if (!GlobalMemoryStatusEx(&memory_info)) {
NOTREACHED();
return 0;
}
int64_t rv = static_cast<int64_t>(memory_info.*memory_field);
return rv < 0 ? std::numeric_limits<int64_t>::max() : rv;
}
bool GetDiskSpaceInfo(const base::FilePath& path,
int64_t* available_bytes,
int64_t* total_bytes) {
ULARGE_INTEGER available;
ULARGE_INTEGER total;
ULARGE_INTEGER free;
if (!GetDiskFreeSpaceExW(path.value().c_str(), &available, &total, &free))
return false;
if (available_bytes) {
*available_bytes = static_cast<int64_t>(available.QuadPart);
if (*available_bytes < 0)
*available_bytes = std::numeric_limits<int64_t>::max();
}
if (total_bytes) {
*total_bytes = static_cast<int64_t>(total.QuadPart);
if (*total_bytes < 0)
*total_bytes = std::numeric_limits<int64_t>::max();
}
return true;
}
} // namespace
namespace base {
// static
int SysInfo::NumberOfProcessors() {
return win::OSInfo::GetInstance()->processors();
}
// static
int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
return AmountOfMemory(&MEMORYSTATUSEX::ullTotalPhys);
}
// static
int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
SystemMemoryInfoKB info;
if (!GetSystemMemoryInfo(&info))
return 0;
return static_cast<int64_t>(info.avail_phys) * 1024;
}
// static
int64_t SysInfo::AmountOfVirtualMemory() {
return AmountOfMemory(&MEMORYSTATUSEX::ullTotalVirtual);
}
// static
int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
int64_t available;
if (!GetDiskSpaceInfo(path, &available, nullptr))
return -1;
return available;
}
// static
int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
int64_t total;
if (!GetDiskSpaceInfo(path, nullptr, &total))
return -1;
return total;
}
std::string SysInfo::OperatingSystemName() {
return "Windows NT";
}
// static
std::string SysInfo::OperatingSystemVersion() {
win::OSInfo* os_info = win::OSInfo::GetInstance();
win::OSInfo::VersionNumber version_number = os_info->version_number();
std::string version(StringPrintf("%d.%d.%d", version_number.major,
version_number.minor, version_number.build));
win::OSInfo::ServicePack service_pack = os_info->service_pack();
if (service_pack.major != 0) {
version += StringPrintf(" SP%d", service_pack.major);
if (service_pack.minor != 0)
version += StringPrintf(".%d", service_pack.minor);
}
return version;
}
// TODO: Implement OperatingSystemVersionComplete, which would include
// patchlevel/service pack number.
// See chrome/browser/feedback/feedback_util.h, FeedbackUtil::SetOSVersion.
// static
std::string SysInfo::OperatingSystemArchitecture() {
win::OSInfo::WindowsArchitecture arch = win::OSInfo::GetArchitecture();
switch (arch) {
case win::OSInfo::X86_ARCHITECTURE:
return "x86";
case win::OSInfo::X64_ARCHITECTURE:
return "x86_64";
case win::OSInfo::IA64_ARCHITECTURE:
return "ia64";
case win::OSInfo::ARM64_ARCHITECTURE:
return "arm64";
default:
return "";
}
}
// static
std::string SysInfo::CPUModelName() {
return win::OSInfo::GetInstance()->processor_model_name();
}
// static
size_t SysInfo::VMAllocationGranularity() {
return win::OSInfo::GetInstance()->allocation_granularity();
}
// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
int32_t* minor_version,
int32_t* bugfix_version) {
win::OSInfo* os_info = win::OSInfo::GetInstance();
*major_version = os_info->version_number().major;
*minor_version = os_info->version_number().minor;
*bugfix_version = 0;
}
// static
SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
win::WmiComputerSystemInfo wmi_info = win::WmiComputerSystemInfo::Get();
HardwareInfo info;
info.manufacturer = WideToUTF8(wmi_info.manufacturer());
info.model = WideToUTF8(wmi_info.model());
info.serial_number = WideToUTF8(wmi_info.serial_number());
DCHECK(IsStringUTF8(info.manufacturer));
DCHECK(IsStringUTF8(info.model));
DCHECK(IsStringUTF8(info.serial_number));
return info;
}
} // namespace base

View file

@ -0,0 +1,51 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/system/system_monitor.h"
#include <utility>
#include "base/logging.h"
#include "base/time/time.h"
namespace base {
static SystemMonitor* g_system_monitor = nullptr;
SystemMonitor::SystemMonitor()
: devices_changed_observer_list_(
new ObserverListThreadSafe<DevicesChangedObserver>()) {
DCHECK(!g_system_monitor);
g_system_monitor = this;
}
SystemMonitor::~SystemMonitor() {
DCHECK_EQ(this, g_system_monitor);
g_system_monitor = nullptr;
}
// static
SystemMonitor* SystemMonitor::Get() {
return g_system_monitor;
}
void SystemMonitor::ProcessDevicesChanged(DeviceType device_type) {
NotifyDevicesChanged(device_type);
}
void SystemMonitor::AddDevicesChangedObserver(DevicesChangedObserver* obs) {
devices_changed_observer_list_->AddObserver(obs);
}
void SystemMonitor::RemoveDevicesChangedObserver(DevicesChangedObserver* obs) {
devices_changed_observer_list_->RemoveObserver(obs);
}
void SystemMonitor::NotifyDevicesChanged(DeviceType device_type) {
DVLOG(1) << "DevicesChanged with device type " << device_type;
devices_changed_observer_list_->Notify(
FROM_HERE, &DevicesChangedObserver::OnDevicesChanged, device_type);
}
} // namespace base

View file

@ -0,0 +1,75 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_SYSTEM_SYSTEM_MONITOR_H_
#define BASE_SYSTEM_SYSTEM_MONITOR_H_
#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list_threadsafe.h"
#include "build/build_config.h"
namespace base {
// Class for monitoring various system-related subsystems
// such as power management, network status, etc.
// TODO(mbelshe): Add support beyond just power management.
class BASE_EXPORT SystemMonitor {
public:
// Type of devices whose change need to be monitored, such as add/remove.
enum DeviceType {
DEVTYPE_AUDIO, // Audio device, e.g., microphone.
DEVTYPE_VIDEO_CAPTURE, // Video capture device, e.g., webcam.
DEVTYPE_UNKNOWN, // Other devices.
};
// Create SystemMonitor. Only one SystemMonitor instance per application
// is allowed.
SystemMonitor();
~SystemMonitor();
// Get the application-wide SystemMonitor (if not present, returns NULL).
static SystemMonitor* Get();
class BASE_EXPORT DevicesChangedObserver {
public:
// Notification that the devices connected to the system have changed.
// This is only implemented on Windows currently.
virtual void OnDevicesChanged(DeviceType device_type) {}
protected:
virtual ~DevicesChangedObserver() = default;
};
// Add a new observer.
// Can be called from any thread.
// Must not be called from within a notification callback.
void AddDevicesChangedObserver(DevicesChangedObserver* obs);
// Remove an existing observer.
// Can be called from any thread.
// Must not be called from within a notification callback.
void RemoveDevicesChangedObserver(DevicesChangedObserver* obs);
// The ProcessFoo() style methods are a broken pattern and should not
// be copied. Any significant addition to this class is blocked on
// refactoring to improve the state of affairs. See http://crbug.com/149059
// Cross-platform handling of a device change event.
void ProcessDevicesChanged(DeviceType device_type);
private:
// Functions to trigger notifications.
void NotifyDevicesChanged(DeviceType device_type);
scoped_refptr<ObserverListThreadSafe<DevicesChangedObserver>>
devices_changed_observer_list_;
DISALLOW_COPY_AND_ASSIGN(SystemMonitor);
};
} // namespace base
#endif // BASE_SYSTEM_SYSTEM_MONITOR_H_