// 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 #include "base/base_switches.h" #include "base/bind.h" #include "base/callback.h" #include "base/command_line.h" #include "base/location.h" #include "base/notreached.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/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" namespace base { namespace { // Updated Desktop default threshold to match the Android 2021 definition. constexpr int64_t kLowMemoryDeviceThresholdMB = 2048; } // namespace // static int64_t SysInfo::AmountOfPhysicalMemory() { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableLowEndDeviceMode)) { // Keep using 512MB as the simulated RAM amount for when users or tests have // manually enabled low-end device mode. Note this value is different from // the threshold used for low end devices. constexpr int64_t kSimulatedMemoryForEnableLowEndDeviceMode = 512 * 1024 * 1024; return std::min(kSimulatedMemoryForEnableLowEndDeviceMode, AmountOfPhysicalMemoryImpl()); } 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. int64_t memory_used = AmountOfPhysicalMemoryImpl() - AmountOfAvailablePhysicalMemoryImpl(); int64_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 !BUILDFLAG(IS_ANDROID) // The Android equivalent of this lives in `detectLowEndDevice()` at: // base/android/java/src/org/chromium/base/SysUtils.java 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 internal::LazySysInfoValue instance; return instance.value(); } #endif #if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_WIN) && \ !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS) std::string SysInfo::HardwareModelName() { return std::string(); } #endif void SysInfo::GetHardwareInfo(base::OnceCallback callback) { #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {}, base::BindOnce(&GetHardwareInfoSync), std::move(callback)); #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&GetHardwareInfoSync), std::move(callback)); #else NOTIMPLEMENTED(); base::SequencedTaskRunnerHandle::Get()->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::Microseconds(uptime_in_microseconds); } // static std::string SysInfo::ProcessCPUArchitecture() { #if defined(ARCH_CPU_X86) return "x86"; #elif defined(ARCH_CPU_X86_64) return "x86_64"; #elif defined(ARCH_CPU_ARMEL) return "ARM"; #elif defined(ARCH_CPU_ARM64) return "ARM_64"; #else return std::string(); #endif } } // namespace base