1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/system/sys_info.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <fidl/fuchsia.buildinfo/cpp/fidl.h>
8*6777b538SAndroid Build Coastguard Worker #include <fidl/fuchsia.hwinfo/cpp/fidl.h>
9*6777b538SAndroid Build Coastguard Worker #include <sys/statvfs.h>
10*6777b538SAndroid Build Coastguard Worker #include <zircon/syscalls.h>
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard Worker #include <string>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_map.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_logging.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/system_info.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/notimplemented.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/numerics/clamped_math.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/threading/scoped_blocking_call.h"
25*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker namespace base {
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker namespace {
30*6777b538SAndroid Build Coastguard Worker
GetDiskSpaceInfo(const FilePath & path,int64_t * available_bytes,int64_t * total_bytes)31*6777b538SAndroid Build Coastguard Worker bool GetDiskSpaceInfo(const FilePath& path,
32*6777b538SAndroid Build Coastguard Worker int64_t* available_bytes,
33*6777b538SAndroid Build Coastguard Worker int64_t* total_bytes) {
34*6777b538SAndroid Build Coastguard Worker struct statvfs stats;
35*6777b538SAndroid Build Coastguard Worker if (statvfs(path.value().c_str(), &stats) != 0) {
36*6777b538SAndroid Build Coastguard Worker PLOG(ERROR) << "statvfs() for path:" << path;
37*6777b538SAndroid Build Coastguard Worker return false;
38*6777b538SAndroid Build Coastguard Worker }
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker if (available_bytes) {
41*6777b538SAndroid Build Coastguard Worker ClampedNumeric<int64_t> available_blocks(stats.f_bavail);
42*6777b538SAndroid Build Coastguard Worker *available_bytes = available_blocks * stats.f_frsize;
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker if (total_bytes) {
46*6777b538SAndroid Build Coastguard Worker ClampedNumeric<int64_t> total_blocks(stats.f_blocks);
47*6777b538SAndroid Build Coastguard Worker *total_bytes = total_blocks * stats.f_frsize;
48*6777b538SAndroid Build Coastguard Worker }
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker return true;
51*6777b538SAndroid Build Coastguard Worker }
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker struct TotalDiskSpace {
54*6777b538SAndroid Build Coastguard Worker Lock lock;
55*6777b538SAndroid Build Coastguard Worker flat_map<FilePath, int64_t> space_map GUARDED_BY(lock);
56*6777b538SAndroid Build Coastguard Worker };
57*6777b538SAndroid Build Coastguard Worker
GetTotalDiskSpace()58*6777b538SAndroid Build Coastguard Worker TotalDiskSpace& GetTotalDiskSpace() {
59*6777b538SAndroid Build Coastguard Worker static NoDestructor<TotalDiskSpace> total_disk_space;
60*6777b538SAndroid Build Coastguard Worker return *total_disk_space;
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker // Returns the total-disk-space set for the volume containing |path|. If
64*6777b538SAndroid Build Coastguard Worker // |volume_path| is non-null then it receives the path to the relevant volume.
65*6777b538SAndroid Build Coastguard Worker // Returns -1, and does not modify |volume_path|, if no match is found. Also
66*6777b538SAndroid Build Coastguard Worker // returns -1 if |path| is not absolute.
GetAmountOfTotalDiskSpaceAndVolumePath(const FilePath & path,FilePath * volume_path)67*6777b538SAndroid Build Coastguard Worker int64_t GetAmountOfTotalDiskSpaceAndVolumePath(const FilePath& path,
68*6777b538SAndroid Build Coastguard Worker FilePath* volume_path) {
69*6777b538SAndroid Build Coastguard Worker if (!path.IsAbsolute()) {
70*6777b538SAndroid Build Coastguard Worker return -1;
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker TotalDiskSpace& total_disk_space = GetTotalDiskSpace();
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker AutoLock l(total_disk_space.lock);
75*6777b538SAndroid Build Coastguard Worker int64_t result = -1;
76*6777b538SAndroid Build Coastguard Worker FilePath matched_path;
77*6777b538SAndroid Build Coastguard Worker for (const auto& path_and_size : total_disk_space.space_map) {
78*6777b538SAndroid Build Coastguard Worker if (path_and_size.first == path || path_and_size.first.IsParent(path)) {
79*6777b538SAndroid Build Coastguard Worker // If a deeper path was already matched then ignore this entry.
80*6777b538SAndroid Build Coastguard Worker if (!matched_path.empty() && !matched_path.IsParent(path_and_size.first))
81*6777b538SAndroid Build Coastguard Worker continue;
82*6777b538SAndroid Build Coastguard Worker matched_path = path_and_size.first;
83*6777b538SAndroid Build Coastguard Worker result = path_and_size.second;
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker }
86*6777b538SAndroid Build Coastguard Worker
87*6777b538SAndroid Build Coastguard Worker if (volume_path)
88*6777b538SAndroid Build Coastguard Worker *volume_path = matched_path;
89*6777b538SAndroid Build Coastguard Worker return result;
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker } // namespace
93*6777b538SAndroid Build Coastguard Worker
94*6777b538SAndroid Build Coastguard Worker // static
AmountOfPhysicalMemoryImpl()95*6777b538SAndroid Build Coastguard Worker uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
96*6777b538SAndroid Build Coastguard Worker return zx_system_get_physmem();
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker // static
AmountOfAvailablePhysicalMemoryImpl()100*6777b538SAndroid Build Coastguard Worker uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
101*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/986608): Implement this when Fuchsia supports it.
102*6777b538SAndroid Build Coastguard Worker NOTIMPLEMENTED_LOG_ONCE();
103*6777b538SAndroid Build Coastguard Worker return 0;
104*6777b538SAndroid Build Coastguard Worker }
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker // static
NumberOfProcessors()107*6777b538SAndroid Build Coastguard Worker int SysInfo::NumberOfProcessors() {
108*6777b538SAndroid Build Coastguard Worker return static_cast<int>(zx_system_get_num_cpus());
109*6777b538SAndroid Build Coastguard Worker }
110*6777b538SAndroid Build Coastguard Worker
111*6777b538SAndroid Build Coastguard Worker // static
AmountOfVirtualMemory()112*6777b538SAndroid Build Coastguard Worker uint64_t SysInfo::AmountOfVirtualMemory() {
113*6777b538SAndroid Build Coastguard Worker // Fuchsia does not provide this type of information.
114*6777b538SAndroid Build Coastguard Worker // Return zero to indicate that there is unlimited available virtual memory.
115*6777b538SAndroid Build Coastguard Worker return 0;
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker // static
OperatingSystemName()119*6777b538SAndroid Build Coastguard Worker std::string SysInfo::OperatingSystemName() {
120*6777b538SAndroid Build Coastguard Worker return "Fuchsia";
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker // static
AmountOfFreeDiskSpace(const FilePath & path)124*6777b538SAndroid Build Coastguard Worker int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
125*6777b538SAndroid Build Coastguard Worker ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK);
126*6777b538SAndroid Build Coastguard Worker
127*6777b538SAndroid Build Coastguard Worker // First check whether there is a soft-quota that applies to |path|.
128*6777b538SAndroid Build Coastguard Worker FilePath volume_path;
129*6777b538SAndroid Build Coastguard Worker const int64_t total_space =
130*6777b538SAndroid Build Coastguard Worker GetAmountOfTotalDiskSpaceAndVolumePath(path, &volume_path);
131*6777b538SAndroid Build Coastguard Worker if (total_space >= 0) {
132*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1148334): Replace this with an efficient implementation.
133*6777b538SAndroid Build Coastguard Worker const int64_t used_space = ComputeDirectorySize(volume_path);
134*6777b538SAndroid Build Coastguard Worker return std::max(0l, total_space - used_space);
135*6777b538SAndroid Build Coastguard Worker }
136*6777b538SAndroid Build Coastguard Worker
137*6777b538SAndroid Build Coastguard Worker // Report the actual amount of free space in |path|'s filesystem.
138*6777b538SAndroid Build Coastguard Worker int64_t available;
139*6777b538SAndroid Build Coastguard Worker if (GetDiskSpaceInfo(path, &available, nullptr))
140*6777b538SAndroid Build Coastguard Worker return available;
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker return -1;
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker
145*6777b538SAndroid Build Coastguard Worker // static
AmountOfTotalDiskSpace(const FilePath & path)146*6777b538SAndroid Build Coastguard Worker int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
147*6777b538SAndroid Build Coastguard Worker ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK);
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker if (path.empty())
150*6777b538SAndroid Build Coastguard Worker return -1;
151*6777b538SAndroid Build Coastguard Worker
152*6777b538SAndroid Build Coastguard Worker // Return the soft-quota that applies to |path|, if one is configured.
153*6777b538SAndroid Build Coastguard Worker int64_t total_space = GetAmountOfTotalDiskSpaceAndVolumePath(path, nullptr);
154*6777b538SAndroid Build Coastguard Worker if (total_space >= 0)
155*6777b538SAndroid Build Coastguard Worker return total_space;
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard Worker // Report the actual space in |path|'s filesystem.
158*6777b538SAndroid Build Coastguard Worker if (GetDiskSpaceInfo(path, nullptr, &total_space))
159*6777b538SAndroid Build Coastguard Worker return total_space;
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker return -1;
162*6777b538SAndroid Build Coastguard Worker }
163*6777b538SAndroid Build Coastguard Worker
164*6777b538SAndroid Build Coastguard Worker // static
SetAmountOfTotalDiskSpace(const FilePath & path,int64_t bytes)165*6777b538SAndroid Build Coastguard Worker void SysInfo::SetAmountOfTotalDiskSpace(const FilePath& path, int64_t bytes) {
166*6777b538SAndroid Build Coastguard Worker DCHECK(path.IsAbsolute());
167*6777b538SAndroid Build Coastguard Worker TotalDiskSpace& total_disk_space = GetTotalDiskSpace();
168*6777b538SAndroid Build Coastguard Worker AutoLock l(total_disk_space.lock);
169*6777b538SAndroid Build Coastguard Worker if (bytes >= 0)
170*6777b538SAndroid Build Coastguard Worker total_disk_space.space_map[path] = bytes;
171*6777b538SAndroid Build Coastguard Worker else
172*6777b538SAndroid Build Coastguard Worker total_disk_space.space_map.erase(path);
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker
175*6777b538SAndroid Build Coastguard Worker // static
OperatingSystemVersion()176*6777b538SAndroid Build Coastguard Worker std::string SysInfo::OperatingSystemVersion() {
177*6777b538SAndroid Build Coastguard Worker const auto& build_info = GetCachedBuildInfo();
178*6777b538SAndroid Build Coastguard Worker return build_info.version().value_or("");
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker
181*6777b538SAndroid Build Coastguard Worker // static
OperatingSystemVersionNumbers(int32_t * major_version,int32_t * minor_version,int32_t * bugfix_version)182*6777b538SAndroid Build Coastguard Worker void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
183*6777b538SAndroid Build Coastguard Worker int32_t* minor_version,
184*6777b538SAndroid Build Coastguard Worker int32_t* bugfix_version) {
185*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1348711): Implement this when Fuchsia supports it.
186*6777b538SAndroid Build Coastguard Worker NOTIMPLEMENTED_LOG_ONCE();
187*6777b538SAndroid Build Coastguard Worker *major_version = 0;
188*6777b538SAndroid Build Coastguard Worker *minor_version = 0;
189*6777b538SAndroid Build Coastguard Worker *bugfix_version = 0;
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard Worker // static
OperatingSystemArchitecture()193*6777b538SAndroid Build Coastguard Worker std::string SysInfo::OperatingSystemArchitecture() {
194*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_64)
195*6777b538SAndroid Build Coastguard Worker return "x86_64";
196*6777b538SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_ARM64)
197*6777b538SAndroid Build Coastguard Worker return "aarch64";
198*6777b538SAndroid Build Coastguard Worker #else
199*6777b538SAndroid Build Coastguard Worker #error Unsupported architecture.
200*6777b538SAndroid Build Coastguard Worker #endif
201*6777b538SAndroid Build Coastguard Worker }
202*6777b538SAndroid Build Coastguard Worker
203*6777b538SAndroid Build Coastguard Worker // static
CPUModelName()204*6777b538SAndroid Build Coastguard Worker std::string SysInfo::CPUModelName() {
205*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1233859): Implement this when Fuchsia supports it.
206*6777b538SAndroid Build Coastguard Worker NOTIMPLEMENTED_LOG_ONCE();
207*6777b538SAndroid Build Coastguard Worker return std::string();
208*6777b538SAndroid Build Coastguard Worker }
209*6777b538SAndroid Build Coastguard Worker
210*6777b538SAndroid Build Coastguard Worker // static
VMAllocationGranularity()211*6777b538SAndroid Build Coastguard Worker size_t SysInfo::VMAllocationGranularity() {
212*6777b538SAndroid Build Coastguard Worker return static_cast<size_t>(getpagesize());
213*6777b538SAndroid Build Coastguard Worker }
214*6777b538SAndroid Build Coastguard Worker
215*6777b538SAndroid Build Coastguard Worker // static
NumberOfEfficientProcessorsImpl()216*6777b538SAndroid Build Coastguard Worker int SysInfo::NumberOfEfficientProcessorsImpl() {
217*6777b538SAndroid Build Coastguard Worker NOTIMPLEMENTED();
218*6777b538SAndroid Build Coastguard Worker return 0;
219*6777b538SAndroid Build Coastguard Worker }
220*6777b538SAndroid Build Coastguard Worker
GetHardwareInfoSync()221*6777b538SAndroid Build Coastguard Worker SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
222*6777b538SAndroid Build Coastguard Worker const auto product_info = GetProductInfo();
223*6777b538SAndroid Build Coastguard Worker
224*6777b538SAndroid Build Coastguard Worker return {
225*6777b538SAndroid Build Coastguard Worker .manufacturer = product_info.manufacturer().value_or(""),
226*6777b538SAndroid Build Coastguard Worker .model = product_info.model().value_or(""),
227*6777b538SAndroid Build Coastguard Worker };
228*6777b538SAndroid Build Coastguard Worker }
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker } // namespace base
231