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