sys_info.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/system/sys_info.h"
  5. #include <algorithm>
  6. #include "base/base_switches.h"
  7. #include "base/bind.h"
  8. #include "base/callback.h"
  9. #include "base/command_line.h"
  10. #include "base/location.h"
  11. #include "base/notreached.h"
  12. #include "base/system/sys_info_internal.h"
  13. #include "base/task/task_traits.h"
  14. #include "base/task/thread_pool.h"
  15. #include "base/threading/sequenced_task_runner_handle.h"
  16. #include "base/time/time.h"
  17. #include "build/build_config.h"
  18. namespace base {
  19. namespace {
  20. #if BUILDFLAG(IS_IOS)
  21. // For M99, 45% of devices have 2GB of RAM, and 55% have more.
  22. constexpr uint64_t kLowMemoryDeviceThresholdMB = 1024;
  23. #else
  24. // Updated Desktop default threshold to match the Android 2021 definition.
  25. constexpr uint64_t kLowMemoryDeviceThresholdMB = 2048;
  26. #endif
  27. } // namespace
  28. // static
  29. uint64_t SysInfo::AmountOfPhysicalMemory() {
  30. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  31. switches::kEnableLowEndDeviceMode)) {
  32. // Keep using 512MB as the simulated RAM amount for when users or tests have
  33. // manually enabled low-end device mode. Note this value is different from
  34. // the threshold used for low end devices.
  35. constexpr uint64_t kSimulatedMemoryForEnableLowEndDeviceMode =
  36. 512 * 1024 * 1024;
  37. return std::min(kSimulatedMemoryForEnableLowEndDeviceMode,
  38. AmountOfPhysicalMemoryImpl());
  39. }
  40. return AmountOfPhysicalMemoryImpl();
  41. }
  42. // static
  43. uint64_t SysInfo::AmountOfAvailablePhysicalMemory() {
  44. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  45. switches::kEnableLowEndDeviceMode)) {
  46. // Estimate the available memory by subtracting our memory used estimate
  47. // from the fake |kLowMemoryDeviceThresholdMB| limit.
  48. uint64_t memory_used =
  49. AmountOfPhysicalMemoryImpl() - AmountOfAvailablePhysicalMemoryImpl();
  50. uint64_t memory_limit = kLowMemoryDeviceThresholdMB * 1024 * 1024;
  51. // std::min ensures no underflow, as |memory_used| can be > |memory_limit|.
  52. return memory_limit - std::min(memory_used, memory_limit);
  53. }
  54. return AmountOfAvailablePhysicalMemoryImpl();
  55. }
  56. bool SysInfo::IsLowEndDevice() {
  57. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  58. switches::kEnableLowEndDeviceMode)) {
  59. return true;
  60. }
  61. return IsLowEndDeviceImpl();
  62. }
  63. #if !BUILDFLAG(IS_ANDROID)
  64. // The Android equivalent of this lives in `detectLowEndDevice()` at:
  65. // base/android/java/src/org/chromium/base/SysUtils.java
  66. bool DetectLowEndDevice() {
  67. CommandLine* command_line = CommandLine::ForCurrentProcess();
  68. if (command_line->HasSwitch(switches::kEnableLowEndDeviceMode))
  69. return true;
  70. if (command_line->HasSwitch(switches::kDisableLowEndDeviceMode))
  71. return false;
  72. int ram_size_mb = SysInfo::AmountOfPhysicalMemoryMB();
  73. return ram_size_mb > 0 &&
  74. static_cast<uint64_t>(ram_size_mb) <= kLowMemoryDeviceThresholdMB;
  75. }
  76. // static
  77. bool SysInfo::IsLowEndDeviceImpl() {
  78. static internal::LazySysInfoValue<bool, DetectLowEndDevice> instance;
  79. return instance.value();
  80. }
  81. #endif
  82. #if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_WIN) && \
  83. !BUILDFLAG(IS_CHROMEOS)
  84. std::string SysInfo::HardwareModelName() {
  85. return std::string();
  86. }
  87. #endif
  88. void SysInfo::GetHardwareInfo(base::OnceCallback<void(HardwareInfo)> callback) {
  89. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
  90. constexpr base::TaskTraits kTraits = {base::MayBlock()};
  91. #else
  92. constexpr base::TaskTraits kTraits = {};
  93. #endif
  94. base::ThreadPool::PostTaskAndReplyWithResult(
  95. FROM_HERE, kTraits, base::BindOnce(&GetHardwareInfoSync),
  96. std::move(callback));
  97. }
  98. // static
  99. base::TimeDelta SysInfo::Uptime() {
  100. // This code relies on an implementation detail of TimeTicks::Now() - that
  101. // its return value happens to coincide with the system uptime value in
  102. // microseconds, on Win/Mac/iOS/Linux/ChromeOS and Android.
  103. int64_t uptime_in_microseconds = TimeTicks::Now().ToInternalValue();
  104. return base::Microseconds(uptime_in_microseconds);
  105. }
  106. // static
  107. std::string SysInfo::ProcessCPUArchitecture() {
  108. #if defined(ARCH_CPU_X86)
  109. return "x86";
  110. #elif defined(ARCH_CPU_X86_64)
  111. return "x86_64";
  112. #elif defined(ARCH_CPU_ARMEL)
  113. return "ARM";
  114. #elif defined(ARCH_CPU_ARM64)
  115. return "ARM_64";
  116. #else
  117. return std::string();
  118. #endif
  119. }
  120. } // namespace base