Files
OpenVulkano/openVulkanoCpp/Host/iOS/SystemInfo.mm

263 lines
7.8 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()
{
return [NSProcessInfo processInfo].physicalMemory;
}
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;
}
std::string SystemInfo::GetUserName()
{
return "";
}
std::string SystemInfo::GetHostName()
{
return [[NSProcessInfo processInfo].hostName UTF8String];
}
std::string SystemInfo::GetDeviceName()
{
return [[[UIDevice currentDevice] name] UTF8String];
}
std::string SystemInfo::GetDeviceVendorName()
{
return "Apple";
}
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;
}
std::string SystemInfo::GetOsName()
{
return [[[UIDevice currentDevice] systemName] UTF8String];
}
OsVersion SystemInfo::GetOsVersion()
{
NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion;
return { static_cast<int>(osVersion.majorVersion), static_cast<int>(osVersion.minorVersion), static_cast<int>(osVersion.patchVersion), 0 };
}
std::string SystemInfo::GetOsNameHumanReadable()
{
OsVersion osVersion = GetOsVersion();
return fmt::format("{} {}.{}", GetOsName(), osVersion.major, osVersion.minor, Get);
}
DeviceType SystemInfo::GetDeviceType()
{
switch ([UIDevice currentDevice].userInterfaceIdiom)
{
case UIUserInterfaceIdiomPhone: return DeviceType::Phone;
case UIUserInterfaceIdiomPad: return DeviceType::Tablet;
case UIUserInterfaceIdiomTV: return DeviceType::TV;
case UIUserInterfaceIdiomMac: return DeviceType::PC;
case UIUserInterfaceIdiomVision: return DeviceType::VR;
default: break;
}
return DeviceType::Unknown;
}
size_t SystemInfo::GetCpuCoreCount()
{
return [NSProcessInfo processInfo].processorCount;
}
size_t SystemInfo::GetCpuThreadCount()
{
return [NSProcessInfo processInfo].activeProcessorCount;
}
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;
}
}