xref: /aosp_15_r20/external/cronet/base/system/sys_info_ios.mm (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker// Copyright 2012 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#import <UIKit/UIKit.h>
8*6777b538SAndroid Build Coastguard Worker#include <mach/mach.h>
9*6777b538SAndroid Build Coastguard Worker#include <stddef.h>
10*6777b538SAndroid Build Coastguard Worker#include <stdint.h>
11*6777b538SAndroid Build Coastguard Worker#include <sys/sysctl.h>
12*6777b538SAndroid Build Coastguard Worker#include <sys/types.h>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker#include "base/apple/scoped_mach_port.h"
15*6777b538SAndroid Build Coastguard Worker#include "base/check_op.h"
16*6777b538SAndroid Build Coastguard Worker#include "base/no_destructor.h"
17*6777b538SAndroid Build Coastguard Worker#include "base/notreached.h"
18*6777b538SAndroid Build Coastguard Worker#include "base/numerics/safe_conversions.h"
19*6777b538SAndroid Build Coastguard Worker#include "base/posix/sysctl.h"
20*6777b538SAndroid Build Coastguard Worker#include "base/process/process_metrics.h"
21*6777b538SAndroid Build Coastguard Worker#include "base/strings/string_util.h"
22*6777b538SAndroid Build Coastguard Worker#include "base/strings/stringprintf.h"
23*6777b538SAndroid Build Coastguard Worker#include "base/strings/sys_string_conversions.h"
24*6777b538SAndroid Build Coastguard Worker#include "build/build_config.h"
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Workernamespace base {
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker#if BUILDFLAG(IS_IOS)
29*6777b538SAndroid Build Coastguard Workernamespace {
30*6777b538SAndroid Build Coastguard Worker// Accessor for storage of overridden HardwareModelName.
31*6777b538SAndroid Build Coastguard Workerstd::string& GetHardwareModelNameStorage() {
32*6777b538SAndroid Build Coastguard Worker  static base::NoDestructor<std::string> instance;
33*6777b538SAndroid Build Coastguard Worker  return *instance;
34*6777b538SAndroid Build Coastguard Worker}
35*6777b538SAndroid Build Coastguard Worker}  // namespace
36*6777b538SAndroid Build Coastguard Worker#endif
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker// static
39*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::OperatingSystemName() {
40*6777b538SAndroid Build Coastguard Worker  static dispatch_once_t get_system_name_once;
41*6777b538SAndroid Build Coastguard Worker  static std::string* system_name;
42*6777b538SAndroid Build Coastguard Worker  dispatch_once(&get_system_name_once, ^{
43*6777b538SAndroid Build Coastguard Worker    @autoreleasepool {
44*6777b538SAndroid Build Coastguard Worker      system_name =
45*6777b538SAndroid Build Coastguard Worker          new std::string(SysNSStringToUTF8(UIDevice.currentDevice.systemName));
46*6777b538SAndroid Build Coastguard Worker    }
47*6777b538SAndroid Build Coastguard Worker  });
48*6777b538SAndroid Build Coastguard Worker  // Examples of returned value: 'iPhone OS' on iPad 5.1.1
49*6777b538SAndroid Build Coastguard Worker  // and iPhone 5.1.1.
50*6777b538SAndroid Build Coastguard Worker  return *system_name;
51*6777b538SAndroid Build Coastguard Worker}
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker// static
54*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::OperatingSystemVersion() {
55*6777b538SAndroid Build Coastguard Worker  static dispatch_once_t get_system_version_once;
56*6777b538SAndroid Build Coastguard Worker  static std::string* system_version;
57*6777b538SAndroid Build Coastguard Worker  dispatch_once(&get_system_version_once, ^{
58*6777b538SAndroid Build Coastguard Worker    @autoreleasepool {
59*6777b538SAndroid Build Coastguard Worker      system_version = new std::string(
60*6777b538SAndroid Build Coastguard Worker          SysNSStringToUTF8(UIDevice.currentDevice.systemVersion));
61*6777b538SAndroid Build Coastguard Worker    }
62*6777b538SAndroid Build Coastguard Worker  });
63*6777b538SAndroid Build Coastguard Worker  return *system_version;
64*6777b538SAndroid Build Coastguard Worker}
65*6777b538SAndroid Build Coastguard Worker
66*6777b538SAndroid Build Coastguard Worker// static
67*6777b538SAndroid Build Coastguard Workervoid SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
68*6777b538SAndroid Build Coastguard Worker                                            int32_t* minor_version,
69*6777b538SAndroid Build Coastguard Worker                                            int32_t* bugfix_version) {
70*6777b538SAndroid Build Coastguard Worker  NSOperatingSystemVersion version =
71*6777b538SAndroid Build Coastguard Worker      NSProcessInfo.processInfo.operatingSystemVersion;
72*6777b538SAndroid Build Coastguard Worker  *major_version = saturated_cast<int32_t>(version.majorVersion);
73*6777b538SAndroid Build Coastguard Worker  *minor_version = saturated_cast<int32_t>(version.minorVersion);
74*6777b538SAndroid Build Coastguard Worker  *bugfix_version = saturated_cast<int32_t>(version.patchVersion);
75*6777b538SAndroid Build Coastguard Worker}
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker// static
78*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::OperatingSystemArchitecture() {
79*6777b538SAndroid Build Coastguard Worker#if defined(ARCH_CPU_X86)
80*6777b538SAndroid Build Coastguard Worker  return "x86";
81*6777b538SAndroid Build Coastguard Worker#elif defined(ARCH_CPU_X86_64)
82*6777b538SAndroid Build Coastguard Worker  return "x86_64";
83*6777b538SAndroid Build Coastguard Worker#elif defined(ARCH_CPU_ARMEL)
84*6777b538SAndroid Build Coastguard Worker  return "arm";
85*6777b538SAndroid Build Coastguard Worker#elif defined(ARCH_CPU_ARM64)
86*6777b538SAndroid Build Coastguard Worker  return "arm64";
87*6777b538SAndroid Build Coastguard Worker#else
88*6777b538SAndroid Build Coastguard Worker#error Unsupported CPU architecture
89*6777b538SAndroid Build Coastguard Worker#endif
90*6777b538SAndroid Build Coastguard Worker}
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker// static
93*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::GetIOSBuildNumber() {
94*6777b538SAndroid Build Coastguard Worker  std::optional<std::string> build_number =
95*6777b538SAndroid Build Coastguard Worker      StringSysctl({CTL_KERN, KERN_OSVERSION});
96*6777b538SAndroid Build Coastguard Worker  return build_number.value();
97*6777b538SAndroid Build Coastguard Worker}
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker// static
100*6777b538SAndroid Build Coastguard Workervoid SysInfo::OverrideHardwareModelName(std::string name) {
101*6777b538SAndroid Build Coastguard Worker  // Normally, HardwareModelName() should not be called before overriding the
102*6777b538SAndroid Build Coastguard Worker  // value, but StartCrashController(), which eventually calls
103*6777b538SAndroid Build Coastguard Worker  // HardwareModelName(), is called before overriding the name.
104*6777b538SAndroid Build Coastguard Worker  CHECK(!name.empty());
105*6777b538SAndroid Build Coastguard Worker  GetHardwareModelNameStorage() = std::move(name);
106*6777b538SAndroid Build Coastguard Worker}
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard Worker// static
109*6777b538SAndroid Build Coastguard Workeruint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
110*6777b538SAndroid Build Coastguard Worker  struct host_basic_info hostinfo;
111*6777b538SAndroid Build Coastguard Worker  mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
112*6777b538SAndroid Build Coastguard Worker  base::apple::ScopedMachSendRight host(mach_host_self());
113*6777b538SAndroid Build Coastguard Worker  int result = host_info(host.get(), HOST_BASIC_INFO,
114*6777b538SAndroid Build Coastguard Worker                         reinterpret_cast<host_info_t>(&hostinfo), &count);
115*6777b538SAndroid Build Coastguard Worker  if (result != KERN_SUCCESS) {
116*6777b538SAndroid Build Coastguard Worker    NOTREACHED();
117*6777b538SAndroid Build Coastguard Worker    return 0;
118*6777b538SAndroid Build Coastguard Worker  }
119*6777b538SAndroid Build Coastguard Worker  DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
120*6777b538SAndroid Build Coastguard Worker  return hostinfo.max_mem;
121*6777b538SAndroid Build Coastguard Worker}
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker// static
124*6777b538SAndroid Build Coastguard Workeruint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
125*6777b538SAndroid Build Coastguard Worker  SystemMemoryInfoKB info;
126*6777b538SAndroid Build Coastguard Worker  if (!GetSystemMemoryInfo(&info))
127*6777b538SAndroid Build Coastguard Worker    return 0;
128*6777b538SAndroid Build Coastguard Worker  // We should add inactive file-backed memory also but there is no such
129*6777b538SAndroid Build Coastguard Worker  // information from iOS unfortunately.
130*6777b538SAndroid Build Coastguard Worker  return checked_cast<uint64_t>(info.free + info.speculative) * 1024;
131*6777b538SAndroid Build Coastguard Worker}
132*6777b538SAndroid Build Coastguard Worker
133*6777b538SAndroid Build Coastguard Worker// static
134*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::CPUModelName() {
135*6777b538SAndroid Build Coastguard Worker  return StringSysctlByName("machdep.cpu.brand_string").value_or(std::string{});
136*6777b538SAndroid Build Coastguard Worker}
137*6777b538SAndroid Build Coastguard Worker
138*6777b538SAndroid Build Coastguard Worker// static
139*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::HardwareModelName() {
140*6777b538SAndroid Build Coastguard Worker#if TARGET_OS_SIMULATOR
141*6777b538SAndroid Build Coastguard Worker  // On the simulator, "hw.machine" returns "i386" or "x86_64" which doesn't
142*6777b538SAndroid Build Coastguard Worker  // match the expected format, so supply a fake string here.
143*6777b538SAndroid Build Coastguard Worker  const char* model = getenv("SIMULATOR_MODEL_IDENTIFIER");
144*6777b538SAndroid Build Coastguard Worker  if (model == nullptr) {
145*6777b538SAndroid Build Coastguard Worker    switch (UIDevice.currentDevice.userInterfaceIdiom) {
146*6777b538SAndroid Build Coastguard Worker      case UIUserInterfaceIdiomPhone:
147*6777b538SAndroid Build Coastguard Worker        model = "iPhone";
148*6777b538SAndroid Build Coastguard Worker        break;
149*6777b538SAndroid Build Coastguard Worker      case UIUserInterfaceIdiomPad:
150*6777b538SAndroid Build Coastguard Worker        model = "iPad";
151*6777b538SAndroid Build Coastguard Worker        break;
152*6777b538SAndroid Build Coastguard Worker      default:
153*6777b538SAndroid Build Coastguard Worker        model = "Unknown";
154*6777b538SAndroid Build Coastguard Worker        break;
155*6777b538SAndroid Build Coastguard Worker    }
156*6777b538SAndroid Build Coastguard Worker  }
157*6777b538SAndroid Build Coastguard Worker  return base::StringPrintf("iOS Simulator (%s)", model);
158*6777b538SAndroid Build Coastguard Worker#else
159*6777b538SAndroid Build Coastguard Worker  const std::string& override = GetHardwareModelNameStorage();
160*6777b538SAndroid Build Coastguard Worker  if (!override.empty()) {
161*6777b538SAndroid Build Coastguard Worker    return override;
162*6777b538SAndroid Build Coastguard Worker  }
163*6777b538SAndroid Build Coastguard Worker  // Note: This uses "hw.machine" instead of "hw.model" like the Mac code,
164*6777b538SAndroid Build Coastguard Worker  // because "hw.model" doesn't always return the right string on some devices.
165*6777b538SAndroid Build Coastguard Worker  return StringSysctl({CTL_HW, HW_MACHINE}).value_or(std::string{});
166*6777b538SAndroid Build Coastguard Worker#endif
167*6777b538SAndroid Build Coastguard Worker}
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker// static
170*6777b538SAndroid Build Coastguard WorkerSysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
171*6777b538SAndroid Build Coastguard Worker  HardwareInfo info;
172*6777b538SAndroid Build Coastguard Worker  info.manufacturer = "Apple Inc.";
173*6777b538SAndroid Build Coastguard Worker  info.model = HardwareModelName();
174*6777b538SAndroid Build Coastguard Worker  DCHECK(IsStringUTF8(info.manufacturer));
175*6777b538SAndroid Build Coastguard Worker  DCHECK(IsStringUTF8(info.model));
176*6777b538SAndroid Build Coastguard Worker  return info;
177*6777b538SAndroid Build Coastguard Worker}
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker}  // namespace base
180