• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2012 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/system/sys_info.h"
6
7#import <UIKit/UIKit.h>
8#include <mach/mach.h>
9#include <stddef.h>
10#include <stdint.h>
11#include <sys/sysctl.h>
12#include <sys/types.h>
13
14#include "base/apple/scoped_mach_port.h"
15#include "base/check_op.h"
16#include "base/notreached.h"
17#include "base/numerics/safe_conversions.h"
18#include "base/posix/sysctl.h"
19#include "base/process/process_metrics.h"
20#include "base/strings/string_util.h"
21#include "base/strings/stringprintf.h"
22#include "base/strings/sys_string_conversions.h"
23#include "build/build_config.h"
24
25namespace base {
26
27// static
28std::string SysInfo::OperatingSystemName() {
29  static dispatch_once_t get_system_name_once;
30  static std::string* system_name;
31  dispatch_once(&get_system_name_once, ^{
32    @autoreleasepool {
33      system_name =
34          new std::string(SysNSStringToUTF8(UIDevice.currentDevice.systemName));
35    }
36  });
37  // Examples of returned value: 'iPhone OS' on iPad 5.1.1
38  // and iPhone 5.1.1.
39  return *system_name;
40}
41
42// static
43std::string SysInfo::OperatingSystemVersion() {
44  static dispatch_once_t get_system_version_once;
45  static std::string* system_version;
46  dispatch_once(&get_system_version_once, ^{
47    @autoreleasepool {
48      system_version = new std::string(
49          SysNSStringToUTF8(UIDevice.currentDevice.systemVersion));
50    }
51  });
52  return *system_version;
53}
54
55// static
56void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
57                                            int32_t* minor_version,
58                                            int32_t* bugfix_version) {
59  NSOperatingSystemVersion version =
60      NSProcessInfo.processInfo.operatingSystemVersion;
61  *major_version = saturated_cast<int32_t>(version.majorVersion);
62  *minor_version = saturated_cast<int32_t>(version.minorVersion);
63  *bugfix_version = saturated_cast<int32_t>(version.patchVersion);
64}
65
66// static
67std::string SysInfo::OperatingSystemArchitecture() {
68#if defined(ARCH_CPU_X86)
69  return "x86";
70#elif defined(ARCH_CPU_X86_64)
71  return "x86_64";
72#elif defined(ARCH_CPU_ARMEL)
73  return "arm";
74#elif defined(ARCH_CPU_ARM64)
75  return "arm64";
76#else
77#error Unsupported CPU architecture
78#endif
79}
80
81// static
82std::string SysInfo::GetIOSBuildNumber() {
83  absl::optional<std::string> build_number =
84      StringSysctl({CTL_KERN, KERN_OSVERSION});
85  return build_number.value();
86}
87
88// static
89uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
90  struct host_basic_info hostinfo;
91  mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
92  base::apple::ScopedMachSendRight host(mach_host_self());
93  int result = host_info(host.get(), HOST_BASIC_INFO,
94                         reinterpret_cast<host_info_t>(&hostinfo), &count);
95  if (result != KERN_SUCCESS) {
96    NOTREACHED();
97    return 0;
98  }
99  DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
100  return hostinfo.max_mem;
101}
102
103// static
104uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
105  SystemMemoryInfoKB info;
106  if (!GetSystemMemoryInfo(&info))
107    return 0;
108  // We should add inactive file-backed memory also but there is no such
109  // information from iOS unfortunately.
110  return checked_cast<uint64_t>(info.free + info.speculative) * 1024;
111}
112
113// static
114std::string SysInfo::CPUModelName() {
115  return StringSysctlByName("machdep.cpu.brand_string").value_or(std::string{});
116}
117
118// static
119std::string SysInfo::HardwareModelName() {
120#if TARGET_OS_SIMULATOR
121  // On the simulator, "hw.machine" returns "i386" or "x86_64" which doesn't
122  // match the expected format, so supply a fake string here.
123  const char* model = getenv("SIMULATOR_MODEL_IDENTIFIER");
124  if (model == nullptr) {
125    switch (UIDevice.currentDevice.userInterfaceIdiom) {
126      case UIUserInterfaceIdiomPhone:
127        model = "iPhone";
128        break;
129      case UIUserInterfaceIdiomPad:
130        model = "iPad";
131        break;
132      default:
133        model = "Unknown";
134        break;
135    }
136  }
137  return base::StringPrintf("iOS Simulator (%s)", model);
138#else
139  // Note: This uses "hw.machine" instead of "hw.model" like the Mac code,
140  // because "hw.model" doesn't always return the right string on some devices.
141  return StringSysctl({CTL_HW, HW_MACHINE}).value_or(std::string{});
142#endif
143}
144
145// static
146SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
147  HardwareInfo info;
148  info.manufacturer = "Apple Inc.";
149  info.model = HardwareModelName();
150  DCHECK(IsStringUTF8(info.manufacturer));
151  DCHECK(IsStringUTF8(info.model));
152  return info;
153}
154
155}  // namespace base
156