Implement OS detection in Emscripten.

This commit is contained in:
levlam 2020-11-13 15:54:38 +03:00
parent f5dadbb1e5
commit 15b1543e20

View File

@ -20,6 +20,10 @@
#if TD_ANDROID
#include <sys/system_properties.h>
#elif TD_EMSCRIPTEN
#include <cstdlib>
#include <emscripten.h>
#else
#if TD_DARWIN
#include <sys/sysctl.h>
@ -90,6 +94,98 @@ Slice get_operating_system_version() {
if (length > 0) {
return "Android " + string(version, length);
}
#elif TD_EMSCRIPTEN
// clang-format off
char *os_name_js = (char*)EM_ASM_INT(({
function detectOsName() {
if (typeof process === 'object' && typeof process.platform === 'string') { // Node.js
switch (process.platform) {
case 'aix':
return 'IBM AIX';
case 'android':
return 'Android';
case 'darwin':
return 'macOS';
case 'freebsd':
return 'FreeBSD';
case 'linux':
return 'Linux';
case 'openbsd':
return 'OpenBSD';
case 'sunos':
return 'SunOS';
case 'win32':
return 'Windows';
case 'darwin':
return 'macOS';
default:
return 'Node.js';
}
}
var userAgent = 'Unknown';
if (typeof window === 'object') { // Web
userAgent = window.navigator.userAgent;
} else if (typeof importScripts === 'function') { // Web Worker
userAgent = navigator.userAgent;
}
var match = /(Mac OS|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh) ([._0-9]+)/.exec(userAgent);
if (match !== null) {
return 'macOS ' + match[2].replace('_', '.');
}
match = /Android [._0-9]+/.exec(userAgent);
if (match !== null) {
return match[0].replace('_', '.');
}
if (/(iPhone|iPad|iPod)/.test(userAgent)) {
match = /OS ([._0-9]+)/.exec(userAgent);
if (match !== null) {
return 'iOS ' + match[1].replace('_', '.');
}
return 'iOS';
}
var clientStrings = [
{s:'Windows 10', r:/(Windows 10.0|Windows NT 10.0)/},
{s:'Windows 8.1', r:/(Windows 8.1|Windows NT 6.3)/},
{s:'Windows 8', r:/(Windows 8|Windows NT 6.2)/},
{s:'Windows 7', r:/(Windows 7|Windows NT 6.1)/},
{s:'Windows Vista', r:/Windows NT 6.0/},
{s:'Windows Server 2003', r:/Windows NT 5.2/},
{s:'Windows XP', r:/(Windows XP|Windows NT 5.1)/},
{s:'Windows', r:/Windows/},
{s:'Android', r:/Android/},
{s:'FreeBSD', r:/FreeBSD/},
{s:'OpenBSD', r:/OpenBSD/},
{s:'Chrome OS', r:/CrOS/},
{s:'Linux', r:/(Linux|X11)/},
{s:'macOS', r:/(Mac OS|MacPPC|MacIntel|Mac_PowerPC|Macintosh)/},
{s:'QNX', r:/QNX/},
{s:'BeOS', r:/BeOS/}
];
for (var id in clientStrings) {
var cs = clientStrings[id];
if (cs.r.test(userAgent)) {
return cs.s;
}
}
return 'Emscripten';
}
var os_name = detectOsName();
var length = lengthBytesUTF8(os_name) + 1;
var result = _malloc(length);
stringToUTF8(os_name, result, length);
return result;
}));
// clang-format on
string os_name(os_name_js);
std::free(os_name_js);
return os_name;
#else
#if TD_LINUX
auto os_name = read_os_name("/etc/os-release", "PRETTY_NAME=\"", "\"\n");
@ -124,8 +220,6 @@ Slice get_operating_system_version() {
return "NetBSD";
#elif TD_CYGWIN
return "Cygwin";
#elif TD_EMSCRIPTEN
return "Emscripten";
#else
return "Unix";
#endif