2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
23 #include "threads/SystemClock.h"
25 #include "SystemInfo.h"
29 #include <sys/utsname.h>
31 #include "GUIInfoManager.h"
32 #include "filesystem/CurlFile.h"
33 #include "network/Network.h"
34 #include "Application.h"
35 #include "windowing/WindowingFactory.h"
36 #include "guilib/LocalizeStrings.h"
38 #include "utils/TimeUtils.h"
39 #include "utils/log.h"
43 #if defined(TARGET_DARWIN)
44 #include "osx/DarwinUtils.h"
45 #include "osx/CocoaInterface.h"
47 #include "powermanagement/PowerManager.h"
48 #include "utils/StringUtils.h"
49 #include "utils/XMLUtils.h"
50 #if defined(TARGET_ANDROID)
51 #include "android/jni/Build.h"
52 #include "utils/AMLUtils.h"
55 /* Target identification */
56 #if defined(TARGET_DARWIN)
57 #include <Availability.h>
58 #elif defined(TARGET_ANDROID)
59 #include <android/api-level.h>
60 #elif defined(TARGET_FREEBSD)
61 #include <sys/param.h>
62 #elif defined(TARGET_LINUX)
63 #include <linux/version.h>
68 CSysInfoJob::CSysInfoJob()
72 bool CSysInfoJob::DoWork()
74 m_info.systemUptime = GetSystemUpTime(false);
75 m_info.systemTotalUptime = GetSystemUpTime(true);
76 m_info.internetState = GetInternetState();
77 m_info.videoEncoder = GetVideoEncoder();
78 m_info.cpuFrequency = GetCPUFreqInfo();
79 m_info.kernelVersion = CSysInfo::GetKernelVersion();
80 m_info.macAddress = GetMACAddress();
81 m_info.batteryLevel = GetBatteryLevel();
85 const CSysData &CSysInfoJob::GetData() const
90 CStdString CSysInfoJob::GetCPUFreqInfo()
92 double CPUFreq = GetCPUFrequency();
93 return StringUtils::Format("%4.2fMHz", CPUFreq);;
96 CSysData::INTERNET_STATE CSysInfoJob::GetInternetState()
98 // Internet connection state!
99 XFILE::CCurlFile http;
100 if (http.IsInternet())
101 return CSysData::CONNECTED;
102 if (http.IsInternet(false))
103 return CSysData::NO_DNS;
104 return CSysData::DISCONNECTED;
107 CStdString CSysInfoJob::GetMACAddress()
109 #if defined(HAS_LINUX_NETWORK) || defined(HAS_WIN32_NETWORK)
110 CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
112 return iface->GetMacAddress();
117 CStdString CSysInfoJob::GetVideoEncoder()
119 return "GPU: " + g_Windowing.GetRenderRenderer();
122 CStdString CSysInfoJob::GetBatteryLevel()
124 return StringUtils::Format("%d%%", g_powerManager.BatteryLevel());
127 double CSysInfoJob::GetCPUFrequency()
129 #if defined (TARGET_POSIX) || defined(TARGET_WINDOWS)
130 return double (g_cpuInfo.getCPUFrequency());
136 bool CSysInfoJob::SystemUpTime(int iInputMinutes, int &iMinutes, int &iHours, int &iDays)
138 iMinutes=0;iHours=0;iDays=0;
139 iMinutes = iInputMinutes;
140 if (iMinutes >= 60) // Hour's
142 iHours = iMinutes / 60;
143 iMinutes = iMinutes - (iHours *60);
145 if (iHours >= 24) // Days
148 iHours = iHours - (iDays * 24);
153 CStdString CSysInfoJob::GetSystemUpTime(bool bTotalUptime)
155 CStdString strSystemUptime;
156 int iInputMinutes, iMinutes,iHours,iDays;
161 iInputMinutes = g_sysinfo.GetTotalUptime() + ((int)(XbmcThreads::SystemClockMillis() / 60000));
166 iInputMinutes = (int)(XbmcThreads::SystemClockMillis() / 60000);
169 SystemUpTime(iInputMinutes,iMinutes, iHours, iDays);
172 strSystemUptime = StringUtils::Format("%i %s, %i %s, %i %s",
173 iDays, g_localizeStrings.Get(12393).c_str(),
174 iHours, g_localizeStrings.Get(12392).c_str(),
175 iMinutes, g_localizeStrings.Get(12391).c_str());
177 else if (iDays == 0 && iHours >= 1 )
179 strSystemUptime = StringUtils::Format("%i %s, %i %s",
180 iHours, g_localizeStrings.Get(12392).c_str(),
181 iMinutes, g_localizeStrings.Get(12391).c_str());
183 else if (iDays == 0 && iHours == 0 && iMinutes >= 0)
185 strSystemUptime = StringUtils::Format("%i %s",
186 iMinutes, g_localizeStrings.Get(12391).c_str());
188 return strSystemUptime;
191 CStdString CSysInfo::TranslateInfo(int info) const
195 case SYSTEM_VIDEO_ENCODER_INFO:
196 return m_info.videoEncoder;
197 case NETWORK_MAC_ADDRESS:
198 return m_info.macAddress;
199 case SYSTEM_KERNEL_VERSION:
200 return m_info.kernelVersion;
201 case SYSTEM_CPUFREQUENCY:
202 return m_info.cpuFrequency;
204 return m_info.systemUptime;
205 case SYSTEM_TOTALUPTIME:
206 return m_info.systemTotalUptime;
207 case SYSTEM_INTERNET_STATE:
208 if (m_info.internetState == CSysData::CONNECTED)
209 return g_localizeStrings.Get(13296);
210 else if (m_info.internetState == CSysData::NO_DNS)
211 return g_localizeStrings.Get(13274);
213 return g_localizeStrings.Get(13297);
214 case SYSTEM_BATTERY_LEVEL:
215 return m_info.batteryLevel;
221 void CSysInfo::Reset()
226 CSysInfo::CSysInfo(void) : CInfoLoader(15 * 1000)
228 memset(MD5_Sign, 0, sizeof(MD5_Sign));
229 m_iSystemTimeTotalUp = 0;
232 CSysInfo::~CSysInfo()
236 bool CSysInfo::Load(const TiXmlNode *settings)
238 if (settings == NULL)
241 const TiXmlElement *pElement = settings->FirstChildElement("general");
243 XMLUtils::GetInt(pElement, "systemtotaluptime", m_iSystemTimeTotalUp, 0, INT_MAX);
248 bool CSysInfo::Save(TiXmlNode *settings) const
250 if (settings == NULL)
253 TiXmlNode *generalNode = settings->FirstChild("general");
254 if (generalNode == NULL)
256 TiXmlElement generalNodeNew("general");
257 generalNode = settings->InsertEndChild(generalNodeNew);
258 if (generalNode == NULL)
261 XMLUtils::SetInt(generalNode, "systemtotaluptime", m_iSystemTimeTotalUp);
266 bool CSysInfo::GetDiskSpace(const CStdString& drive,int& iTotal, int& iTotalFree, int& iTotalUsed, int& iPercentFree, int& iPercentUsed)
269 ULARGE_INTEGER ULTotal= { { 0 } };
270 ULARGE_INTEGER ULTotalFree= { { 0 } };
272 if( !drive.empty() && !drive.Equals("*") )
274 #ifdef TARGET_WINDOWS
275 UINT uidriveType = GetDriveType(( drive + ":\\" ));
276 if(uidriveType != DRIVE_UNKNOWN && uidriveType != DRIVE_NO_ROOT_DIR)
278 bRet= ( 0 != GetDiskFreeSpaceEx( ( drive + ":\\" ), NULL, &ULTotal, &ULTotalFree) );
282 ULARGE_INTEGER ULTotalTmp= { { 0 } };
283 ULARGE_INTEGER ULTotalFreeTmp= { { 0 } };
284 #ifdef TARGET_WINDOWS
285 char* pcBuffer= NULL;
286 DWORD dwStrLength= GetLogicalDriveStrings( 0, pcBuffer );
287 if( dwStrLength != 0 )
290 pcBuffer= new char [dwStrLength];
291 GetLogicalDriveStrings( dwStrLength, pcBuffer );
294 if( DRIVE_FIXED == GetDriveType( pcBuffer + iPos ) &&
295 GetDiskFreeSpaceEx( ( pcBuffer + iPos ), NULL, &ULTotal, &ULTotalFree ) )
297 ULTotalTmp.QuadPart+= ULTotal.QuadPart;
298 ULTotalFreeTmp.QuadPart+= ULTotalFree.QuadPart;
300 iPos += (strlen( pcBuffer + iPos) + 1 );
301 }while( strlen( pcBuffer + iPos ) > 0 );
304 #else // for linux and osx
305 static const char *drv_letter[] = { "C:\\", "E:\\", "F:\\", "G:\\", "X:\\", "Y:\\", "Z:\\", NULL };
306 for( int i = 0; drv_letter[i]; i++)
308 if( GetDiskFreeSpaceEx( drv_letter[i], NULL, &ULTotal, &ULTotalFree ) )
310 ULTotalTmp.QuadPart+= ULTotal.QuadPart;
311 ULTotalFreeTmp.QuadPart+= ULTotalFree.QuadPart;
315 if( ULTotalTmp.QuadPart || ULTotalFreeTmp.QuadPart )
317 ULTotal.QuadPart= ULTotalTmp.QuadPart;
318 ULTotalFree.QuadPart= ULTotalFreeTmp.QuadPart;
325 iTotal = (int)( ULTotal.QuadPart / MB );
326 iTotalFree = (int)( ULTotalFree.QuadPart / MB );
327 iTotalUsed = iTotal - iTotalFree;
328 if( ULTotal.QuadPart > 0 )
330 iPercentUsed = (int)( 100.0f * ( ULTotal.QuadPart - ULTotalFree.QuadPart ) / ULTotal.QuadPart + 0.5f );
336 iPercentFree = 100 - iPercentUsed;
342 CStdString CSysInfo::GetCPUModel()
344 return "CPU: " + g_cpuInfo.getCPUModel();
347 CStdString CSysInfo::GetCPUBogoMips()
349 return "BogoMips: " + g_cpuInfo.getCPUBogoMips();
352 CStdString CSysInfo::GetCPUHardware()
354 return "Hardware: " + g_cpuInfo.getCPUHardware();
357 CStdString CSysInfo::GetCPURevision()
359 return "Revision: " + g_cpuInfo.getCPURevision();
362 CStdString CSysInfo::GetCPUSerial()
364 return "Serial: " + g_cpuInfo.getCPUSerial();
367 CStdString CSysInfo::GetManufacturer()
369 CStdString manufacturer = "";
370 #if defined(TARGET_ANDROID)
371 manufacturer = CJNIBuild::MANUFACTURER;
376 CStdString CSysInfo::GetModel()
378 CStdString model = "";
379 #if defined(TARGET_ANDROID)
380 model = CJNIBuild::MODEL;
385 CStdString CSysInfo::GetProduct()
387 CStdString product = "";
388 #if defined(TARGET_ANDROID)
389 product = CJNIBuild::PRODUCT;
394 bool CSysInfo::IsAeroDisabled()
396 #ifdef TARGET_WINDOWS
397 BOOL aeroEnabled = FALSE;
398 HRESULT res = DwmIsCompositionEnabled(&aeroEnabled);
405 bool CSysInfo::HasHW3DInterlaced()
407 #if defined(TARGET_ANDROID)
408 if (aml_hw3d_present())
414 CSysInfo::WindowsVersion CSysInfo::m_WinVer = WindowsVersionUnknown;
416 bool CSysInfo::IsWindowsVersion(WindowsVersion ver)
418 if (ver == WindowsVersionUnknown)
420 return GetWindowsVersion() == ver;
423 bool CSysInfo::IsWindowsVersionAtLeast(WindowsVersion ver)
425 if (ver == WindowsVersionUnknown)
427 return GetWindowsVersion() >= ver;
430 CSysInfo::WindowsVersion CSysInfo::GetWindowsVersion()
432 #ifdef TARGET_WINDOWS
433 if (m_WinVer == WindowsVersionUnknown)
435 OSVERSIONINFOEX osvi;
436 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
437 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
438 if (GetVersionEx((OSVERSIONINFO *)&osvi))
440 if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
441 m_WinVer = WindowsVersionVista;
442 else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
443 m_WinVer = WindowsVersionWin7;
444 else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2)
445 m_WinVer = WindowsVersionWin8;
446 else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3)
447 m_WinVer = WindowsVersionWin8_1;
448 /* Insert checks for new Windows versions here */
449 else if ( (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion > 3) || osvi.dwMajorVersion > 6)
450 m_WinVer = WindowsVersionFuture;
453 #endif // TARGET_WINDOWS
457 int CSysInfo::GetKernelBitness(void)
459 #ifdef TARGET_WINDOWS
462 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
465 BOOL (WINAPI *ptrIsWow64) (HANDLE, PBOOL);
466 HMODULE hKernel32 = GetModuleHandleA("kernel32");
467 if (hKernel32 == NULL)
468 return 0; // Can't detect OS
469 ptrIsWow64 = (BOOL (WINAPI *) (HANDLE, PBOOL)) GetProcAddress(hKernel32, "IsWow64Process");
470 BOOL wow64proc = FALSE;
471 if (ptrIsWow64 == NULL || ptrIsWow64(GetCurrentProcess(), &wow64proc) == FALSE)
472 return 0; // Can't detect OS
473 return (wow64proc == FALSE) ? 32 : 64;
474 #elif defined(TARGET_POSIX)
478 std::string machine(un.machine);
479 if (machine == "x86_64" || machine == "amd64" || machine == "arm64" || machine == "aarch64" || machine == "ppc64" || machine == "ia64")
483 return 0; // can't detect
489 int CSysInfo::GetXbmcBitness(void)
491 #if defined (__aarch64__) || defined(__arm64__) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) || defined(__ppc64__)
493 #elif defined(__thumb__) || defined(_M_ARMT) || defined(__arm__) || defined(_M_ARM) || defined(__mips__) || defined(mips) || defined(__mips) || defined(i386) || \
494 defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(_X86_) || defined(__powerpc) || \
495 defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
502 CStdString CSysInfo::GetKernelVersion()
504 #if defined(TARGET_DARWIN)
505 return g_sysinfo.GetUnameVersion();
506 #elif defined (TARGET_POSIX)
510 return StringUtils::Format("%s %s %s %s", un.sysname, un.release, un.version, un.machine);;
515 OSVERSIONINFOEX osvi;
516 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
517 osvi.dwOSVersionInfoSize = sizeof(osvi);
519 std::string strKernel = "Windows";
520 if (GetVersionEx((OSVERSIONINFO *)&osvi))
522 switch (GetWindowsVersion())
524 case WindowsVersionVista:
525 if (osvi.wProductType == VER_NT_WORKSTATION)
526 strKernel.append(" Vista");
528 strKernel.append(" Server 2008");
530 case WindowsVersionWin7:
531 if (osvi.wProductType == VER_NT_WORKSTATION)
532 strKernel.append(" 7");
534 strKernel.append(" Server 2008 R2");
536 case WindowsVersionWin8:
537 if (osvi.wProductType == VER_NT_WORKSTATION)
538 strKernel.append(" 8");
540 strKernel.append(" Server 2012");
542 case WindowsVersionWin8_1:
543 if (osvi.wProductType == VER_NT_WORKSTATION)
544 strKernel.append(" 8.1");
546 strKernel.append(" Server 2012 R2");
548 case WindowsVersionFuture:
549 strKernel.append(" Unknown Future Version");
552 strKernel.append(" Unknown version");
556 // Append Service Pack version if any
557 if (osvi.wServicePackMajor > 0)
559 strKernel.append(StringUtils::Format(" SP%d", osvi.wServicePackMajor));
560 if (osvi.wServicePackMinor > 0)
562 strKernel.append(StringUtils::Format(".%d", osvi.wServicePackMinor));
566 strKernel.append(StringUtils::Format(" %d-bit", GetKernelBitness()));
568 strKernel.append(StringUtils::Format(", build %d", osvi.dwBuildNumber));
572 strKernel.append(" unknown");
573 strKernel.append(StringUtils::Format(" %d-bit", GetKernelBitness()));
580 bool CSysInfo::HasInternet()
582 if (m_info.internetState != CSysData::UNKNOWN)
583 return m_info.internetState == CSysData::CONNECTED;
584 return (m_info.internetState = CSysInfoJob::GetInternetState()) == CSysData::CONNECTED;
587 CStdString CSysInfo::GetHddSpaceInfo(int drive, bool shortText)
590 return GetHddSpaceInfo( percent, drive, shortText);
593 CStdString CSysInfo::GetHddSpaceInfo(int& percent, int drive, bool shortText)
595 int total, totalFree, totalUsed, percentFree, percentused;
598 if (g_sysinfo.GetDiskSpace("", total, totalFree, totalUsed, percentFree, percentused))
604 case SYSTEM_FREE_SPACE:
605 percent = percentFree;
607 case SYSTEM_USED_SPACE:
608 percent = percentused;
616 case SYSTEM_FREE_SPACE:
617 strRet = StringUtils::Format("%i MB %s", totalFree, g_localizeStrings.Get(160).c_str());
619 case SYSTEM_USED_SPACE:
620 strRet = StringUtils::Format("%i MB %s", totalUsed, g_localizeStrings.Get(20162).c_str());
622 case SYSTEM_TOTAL_SPACE:
623 strRet = StringUtils::Format("%i MB %s", total, g_localizeStrings.Get(20161).c_str());
625 case SYSTEM_FREE_SPACE_PERCENT:
626 strRet = StringUtils::Format("%i %% %s", percentFree, g_localizeStrings.Get(160).c_str());
628 case SYSTEM_USED_SPACE_PERCENT:
629 strRet = StringUtils::Format("%i %% %s", percentused, g_localizeStrings.Get(20162).c_str());
639 strRet = g_localizeStrings.Get(161);
644 #if defined(TARGET_LINUX)
645 CStdString CSysInfo::GetLinuxDistro()
647 #if defined(TARGET_ANDROID)
650 static const char* release_file[] = { "/etc/debian_version",
652 "/etc/mandrake-release",
653 "/etc/fedora-release",
654 "/etc/redhat-release",
655 "/etc/gentoo-release",
656 "/etc/slackware-version",
658 "/etc/buildroot-release",
660 CStdString result("");
661 char buffer[256] = {'\0'};
663 /* Try reading PRETTY_NAME from /etc/os-release first.
664 * If this fails, fall back to lsb_release or distro-specific release-file. */
666 FILE *os_release = fopen("/etc/os-release", "r");
673 while (fgets(buffer, sizeof(buffer), os_release))
678 if (strcmp(key, "PRETTY_NAME") == 0)
680 char *pretty_name = val;
682 // remove newline and enclosing quotes
683 if (pretty_name[strlen(pretty_name) - 1] == '\n')
684 pretty_name[strlen(pretty_name) - 1] = '\0';
686 if (pretty_name[0] == '\'' || pretty_name[0] == '\"')
689 pretty_name[strlen(pretty_name) - 1] = '\0';
692 // unescape quotes and backslashes
693 char *p = pretty_name;
697 char *next_char = p + 1;
699 if (*this_char == '\\' &&
700 (*next_char == '\'' || *next_char == '\"' || *next_char == '\\'))
704 *this_char = *next_char;
713 result = pretty_name;
724 FILE* pipe = popen("unset PYTHONHOME; unset PYTHONPATH; lsb_release -d 2>/dev/null | cut -f2", "r");
727 if (fread(buffer, sizeof(char), sizeof(buffer), pipe) > 0 && !ferror(pipe))
731 return StringUtils::Trim(result);
735 for (int i = 0; result.empty() && release_file[i]; i++)
737 file = fopen(release_file[i], "r");
740 if (fgets(buffer, sizeof(buffer), file))
744 return StringUtils::Trim(result);
750 CLog::Log(LOGWARNING, "Unable to determine Linux distribution");
756 CStdString CSysInfo::GetUnameVersion()
758 CStdString result = "";
760 #if defined(TARGET_ANDROID)
762 if (uname(&name) == -1)
764 result += name.release;
766 result += name.machine;
767 #elif defined(TARGET_DARWIN_IOS)
768 result = GetDarwinOSReleaseString();
770 result += GetDarwinVersionString();
772 FILE* pipe = popen("uname -rm", "r");
776 if (fgets(buffer, sizeof(buffer), pipe))
779 #if defined(TARGET_DARWIN)
780 StringUtils::Trim(result);
782 result += GetDarwinVersionString();
786 CLog::Log(LOGWARNING, "Unable to determine Uname version");
789 #endif//else !TARGET_ANDROID
791 return StringUtils::Trim(result);
795 #if defined(TARGET_WINDOWS)
796 CStdString CSysInfo::GetUAWindowsVersion()
798 OSVERSIONINFOEX osvi = {};
800 osvi.dwOSVersionInfoSize = sizeof(osvi);
801 CStdString strVersion = "Windows NT";
803 if (GetVersionEx((OSVERSIONINFO *)&osvi))
805 strVersion += StringUtils::Format(" %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
812 if (IsWow64Process(GetCurrentProcess(), &bIsWow))
816 strVersion.append(";WOW64");
817 GetNativeSystemInfo(&si); // different function to read the info under Wow
821 if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
822 strVersion.append(";Win64;x64");
823 else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64)
824 strVersion.append(";Win64;IA64");
831 CStdString CSysInfo::GetUserAgent()
834 result = "XBMC/" + g_infoManager.GetLabel(SYSTEM_BUILD_VERSION) + " (";
835 #if defined(TARGET_WINDOWS)
836 result += GetUAWindowsVersion();
837 #elif defined(TARGET_DARWIN)
838 #if defined(TARGET_DARWIN_IOS)
841 result += "Mac OS X; ";
843 result += GetUnameVersion();
844 #elif defined(TARGET_FREEBSD)
845 result += "FreeBSD; ";
846 result += GetUnameVersion();
847 #elif defined(TARGET_POSIX)
849 result += GetLinuxDistro();
851 result += GetUnameVersion();
853 result += "; http://xbmc.org)";
858 bool CSysInfo::IsAppleTV2()
860 #if defined(TARGET_DARWIN)
861 return DarwinIsAppleTV2();
867 bool CSysInfo::HasVideoToolBoxDecoder()
871 #if defined(HAVE_VIDEOTOOLBOXDECODER)
872 result = DarwinHasVideoToolboxDecoder();
877 std::string CSysInfo::GetBuildTargetPlatformName(void)
879 #if defined(TARGET_DARWIN_OSX)
881 #elif defined(TARGET_DARWIN_IOS_ATV2)
882 return "Darwin iOS ATV2";
883 #elif defined(TARGET_DARWIN_IOS)
885 #elif defined(TARGET_FREEBSD)
887 #elif defined(TARGET_ANDROID)
889 #elif defined(TARGET_LINUX)
891 #elif defined(TARGET_WINDOWS)
894 return "unknown platform";
898 std::string CSysInfo::GetBuildTargetPlatformVersion(void)
900 /* Expand macro before stringify */
901 #define STR_MACRO(x) #x
902 #define XSTR_MACRO(x) STR_MACRO(x)
904 #if defined(TARGET_DARWIN_OSX)
905 return "version " XSTR_MACRO(__MAC_OS_X_VERSION_MIN_REQUIRED);
906 #elif defined(TARGET_DARWIN_IOS)
907 return "version " XSTR_MACRO(__IPHONE_OS_VERSION_MIN_REQUIRED);
908 #elif defined(TARGET_FREEBSD)
909 return "version " XSTR_MACRO(__FreeBSD_version);
910 #elif defined(TARGET_ANDROID)
911 return "API level " XSTR_MACRO(__ANDROID_API__);
912 #elif defined(TARGET_LINUX)
913 std::string ver = StringUtils::Format("%i.%i.%i", LINUX_VERSION_CODE >> 16, (LINUX_VERSION_CODE >> 8) & 0xff, LINUX_VERSION_CODE & 0xff);
915 #elif defined(TARGET_WINDOWS)
916 return "version " XSTR_MACRO(NTDDI_VERSION);
918 return "(unknown platform)";
922 std::string CSysInfo::GetBuildTargetCpuFamily(void)
924 #if defined(__thumb__) || defined(_M_ARMT)
925 return "ARM (Thumb)";
926 #elif defined(__arm__) || defined(_M_ARM) || defined (__aarch64__)
928 #elif defined(__mips__) || defined(mips) || defined(__mips)
930 #elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) || \
931 defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(_X86_)
933 #elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC)
936 return "unknown CPU family";
941 CJob *CSysInfo::GetJob() const
943 return new CSysInfoJob();
946 void CSysInfo::OnJobComplete(unsigned int jobID, bool success, CJob *job)
948 m_info = ((CSysInfoJob *)job)->GetData();
949 CInfoLoader::OnJobComplete(jobID, success, job);