290 lines
8.4 KiB
Plaintext
290 lines
8.4 KiB
Plaintext
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "Host/SystemInfo.hpp"
|
|
#include "Base/Logger.hpp"
|
|
#include "IosDeviceNameDecoder.hpp"
|
|
#include <sstream>
|
|
|
|
#include <mach/mach.h>
|
|
#include <os/proc.h>
|
|
#include <sys/utsname.h>
|
|
|
|
#import <Foundation/NSProcessInfo.h>
|
|
#import <UIKit/UIApplication.h>
|
|
#import <UIKit/UIDevice.h>
|
|
#import <UIKit/UIWindowScene.h>
|
|
|
|
namespace OpenVulkano
|
|
{
|
|
Event<> SystemInfo::OnLowPowerModeChanged;
|
|
Event<> SystemInfo::OnBatteryStateChanged;
|
|
Event<> SystemInfo::OnBatteryLevelChanged;
|
|
Event<> SystemInfo::OnDeviceOrientationChanged;
|
|
|
|
size_t SystemInfo::GetSystemRam()
|
|
{
|
|
static const size_t ram = [NSProcessInfo processInfo].physicalMemory;
|
|
return ram;
|
|
}
|
|
|
|
size_t SystemInfo::GetSystemRamAvailable()
|
|
{
|
|
return os_proc_available_memory();
|
|
}
|
|
|
|
size_t SystemInfo::GetAppRamMax()
|
|
{
|
|
return GetAppRamAvailable() + GetAppRamUsed();
|
|
}
|
|
|
|
size_t SystemInfo::GetAppVirtualMemoryMax()
|
|
{
|
|
return INT64_MAX;
|
|
}
|
|
|
|
size_t SystemInfo::GetAppRamAvailable()
|
|
{
|
|
return os_proc_available_memory();
|
|
}
|
|
|
|
size_t SystemInfo::GetAppRamUsed()
|
|
{
|
|
struct task_basic_info info;
|
|
mach_msg_type_number_t size = sizeof(info);
|
|
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
|
|
if( kerr == KERN_SUCCESS )
|
|
{
|
|
return info.resident_size;
|
|
}
|
|
Logger::PERF->error("Failed to read memory consumption: {}", mach_error_string(kerr));
|
|
return 0;
|
|
}
|
|
|
|
const std::string& SystemInfo::GetUserName()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
const std::string& SystemInfo::GetHostName()
|
|
{
|
|
static const std::string hostName = [[NSProcessInfo processInfo].hostName UTF8String];
|
|
return hostName;
|
|
}
|
|
|
|
const std::string& SystemInfo::GetDeviceName()
|
|
{
|
|
static const std::string devName = [[[UIDevice currentDevice] name] UTF8String];
|
|
return devName;
|
|
}
|
|
|
|
const std::string& SystemInfo::GetDeviceVendorName()
|
|
{
|
|
return "Apple";
|
|
}
|
|
|
|
const std::string& SystemInfo::GetDeviceModelName()
|
|
{
|
|
static std::string modelName;
|
|
if (modelName.empty())
|
|
{
|
|
struct utsname systemInfo;
|
|
uname(&systemInfo);
|
|
modelName = DecodeModelString(systemInfo.machine);
|
|
if (modelName.empty()) modelName = [[[UIDevice currentDevice] model] UTF8String];
|
|
}
|
|
return modelName;
|
|
}
|
|
|
|
const std::string& SystemInfo::GetOsName()
|
|
{
|
|
static const std::string osName = [[[UIDevice currentDevice] systemName] UTF8String];
|
|
return osName;
|
|
}
|
|
|
|
OsVersion SystemInfo::GetOsVersion()
|
|
{
|
|
static OsVersion osv = {};
|
|
if (osv.major == 0 && osv.minor == 0)
|
|
{
|
|
NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion;
|
|
osv = { static_cast<int>(osVersion.majorVersion), static_cast<int>(osVersion.minorVersion),
|
|
static_cast<int>(osVersion.patchVersion), 0 };
|
|
}
|
|
return osv;
|
|
}
|
|
|
|
const std::string& SystemInfo::GetOsNameHumanReadable()
|
|
{
|
|
static std::string hrName;
|
|
if (hrName.empty())
|
|
{
|
|
OsVersion osVersion = GetOsVersion();
|
|
hrName = fmt::format("{} {}.{}", GetOsName(), osVersion.major, osVersion.minor);
|
|
}
|
|
return hrName;
|
|
}
|
|
|
|
DeviceType SystemInfo::GetDeviceType()
|
|
{
|
|
static DeviceType devType = DeviceType::Unknown;
|
|
if (devType == DeviceType::Unknown)
|
|
{
|
|
switch ([UIDevice currentDevice].userInterfaceIdiom)
|
|
{
|
|
case UIUserInterfaceIdiomPhone:
|
|
devType = DeviceType::Phone;
|
|
case UIUserInterfaceIdiomPad:
|
|
devType = DeviceType::Tablet;
|
|
case UIUserInterfaceIdiomTV:
|
|
devType = DeviceType::TV;
|
|
case UIUserInterfaceIdiomMac:
|
|
devType = DeviceType::PC;
|
|
case UIUserInterfaceIdiomVision:
|
|
devType = DeviceType::VR;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return devType;
|
|
}
|
|
|
|
size_t SystemInfo::GetCpuCoreCount()
|
|
{
|
|
static const size_t coreCount = [NSProcessInfo processInfo].processorCount;
|
|
return coreCount;
|
|
}
|
|
|
|
size_t SystemInfo::GetCpuThreadCount()
|
|
{
|
|
static const size_t threadCount = [NSProcessInfo processInfo].activeProcessorCount;
|
|
return threadCount;
|
|
}
|
|
|
|
int32_t SystemInfo::GetCpuTemperature()
|
|
{
|
|
switch([NSProcessInfo processInfo].thermalState)
|
|
{
|
|
case NSProcessInfoThermalStateNominal: return 20;
|
|
case NSProcessInfoThermalStateFair: return 50;
|
|
case NSProcessInfoThermalStateSerious: return 80;
|
|
case NSProcessInfoThermalStateCritical: return 100;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
CpuThermalState SystemInfo::GetCpuThermalState()
|
|
{
|
|
switch([NSProcessInfo processInfo].thermalState)
|
|
{
|
|
case NSProcessInfoThermalStateNominal: return CpuThermalState::Normal;
|
|
case NSProcessInfoThermalStateFair: return CpuThermalState::Fair;
|
|
case NSProcessInfoThermalStateSerious: return CpuThermalState::Serious;
|
|
case NSProcessInfoThermalStateCritical: return CpuThermalState::Critical;
|
|
}
|
|
return CpuThermalState::Normal;
|
|
}
|
|
|
|
bool SystemInfo::IsDeviceInLowPowerMode()
|
|
{
|
|
return [NSProcessInfo processInfo].lowPowerModeEnabled;
|
|
}
|
|
|
|
void SystemInfo::EnableEnergyEvents()
|
|
{
|
|
[[NSNotificationCenter defaultCenter] addObserverForName:NSProcessInfoPowerStateDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
|
SystemInfo::OnLowPowerModeChanged.NotifyAll();
|
|
}];
|
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceBatteryLevelDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
|
SystemInfo::OnBatteryLevelChanged.NotifyAll();
|
|
}];
|
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceBatteryStateDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
|
SystemInfo::OnBatteryStateChanged.NotifyAll();
|
|
}];
|
|
}
|
|
|
|
BatteryState SystemInfo::GetDeviceBatteryState()
|
|
{
|
|
switch([UIDevice currentDevice].batteryState)
|
|
{
|
|
case UIDeviceBatteryStateUnplugged: return BatteryState::Unplugged;
|
|
case UIDeviceBatteryStateCharging: return BatteryState::Charging;
|
|
case UIDeviceBatteryStateFull: return BatteryState::ChargingFull;
|
|
default: break;
|
|
}
|
|
return BatteryState::Unavailable;
|
|
}
|
|
|
|
float SystemInfo::GetDeviceBatteryLevel()
|
|
{
|
|
return [UIDevice currentDevice].batteryLevel;
|
|
}
|
|
|
|
bool SystemInfo::IsMultitaskingSupported()
|
|
{
|
|
return [UIDevice currentDevice].multitaskingSupported;
|
|
}
|
|
|
|
DeviceOrientation SystemInfo::GetDeviceOrientation()
|
|
{
|
|
switch([UIDevice currentDevice].orientation)
|
|
{
|
|
case UIDeviceOrientationPortrait: return DeviceOrientation::Portrait;
|
|
case UIDeviceOrientationPortraitUpsideDown: return DeviceOrientation::PortraitUpsideDown;
|
|
case UIDeviceOrientationLandscapeLeft: return DeviceOrientation::LandscapeLeft;
|
|
case UIDeviceOrientationLandscapeRight: return DeviceOrientation::LandscapeRight;
|
|
case UIDeviceOrientationFaceUp: return DeviceOrientation::FaceUp;
|
|
case UIDeviceOrientationFaceDown: return DeviceOrientation::FaceDown;
|
|
default: break;
|
|
}
|
|
return DeviceOrientation::Unknown;
|
|
}
|
|
|
|
void SystemInfo::EnableDeviceOrientationEvents()
|
|
{
|
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceOrientationDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
|
SystemInfo::OnDeviceOrientationChanged.NotifyAll();
|
|
}];
|
|
[[UIDevice currentDevice]beginGeneratingDeviceOrientationNotifications];
|
|
}
|
|
|
|
InterfaceOrientation SystemInfo::GetInterfaceOrientation()
|
|
{
|
|
if (@available(iOS 15.0, *))
|
|
{ //TODO support multi scene at some point
|
|
UIInterfaceOrientation interfaceOrientation;
|
|
for (UIScene *scene in [UIApplication sharedApplication].connectedScenes)
|
|
{
|
|
if ([scene isKindOfClass:[UIWindowScene class]])
|
|
{
|
|
interfaceOrientation = ((UIWindowScene *)scene).interfaceOrientation;
|
|
break;
|
|
}
|
|
}
|
|
switch(interfaceOrientation)
|
|
{
|
|
case UIInterfaceOrientationPortrait: return InterfaceOrientation::Portrait;
|
|
case UIInterfaceOrientationPortraitUpsideDown: return InterfaceOrientation::PortraitUpsideDown;
|
|
case UIInterfaceOrientationLandscapeLeft: return InterfaceOrientation::LandscapeLeft;
|
|
case UIInterfaceOrientationLandscapeRight: return InterfaceOrientation::LandscapeRight;
|
|
default: break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(GetDeviceOrientation())
|
|
{
|
|
case DeviceOrientation::Portrait: return InterfaceOrientation::Portrait;
|
|
case DeviceOrientation::PortraitUpsideDown: return InterfaceOrientation::PortraitUpsideDown;
|
|
case DeviceOrientation::LandscapeLeft: return InterfaceOrientation::LandscapeRight;
|
|
case DeviceOrientation::LandscapeRight: return InterfaceOrientation::LandscapeLeft;
|
|
default: break;
|
|
}
|
|
}
|
|
return InterfaceOrientation::Landscape;
|
|
}
|
|
}
|