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