diff --git a/toolkit/components/telemetry/app/TelemetryEnvironment.jsm b/toolkit/components/telemetry/app/TelemetryEnvironment.jsm index bff499f0b50b..3923b49c7608 100644 --- a/toolkit/components/telemetry/app/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/app/TelemetryEnvironment.jsm @@ -1110,11 +1110,28 @@ EnvironmentCache.prototype = { * This gets called when the delayed init completes. */ async delayedInit() { + this._processData = await Services.sysinfo.processInfo; + let processData = await Services.sysinfo.processInfo; + // Remove isWow64 and isWowARM64 from processData + // to strip it down to just CPU info + delete processData.isWow64; + delete processData.isWowARM64; + + let oldEnv = null; + if (!this._initTask) { + oldEnv = this.currentEnvironment; + } + + this._cpuData = this._getCPUData(); + // Augment the return value from the promises with cached values + this._cpuData = { ...processData, ...this._cpuData }; + + this._currentEnvironment.system.cpu = this._getCPUData(); + if (AppConstants.platform == "win") { this._hddData = await Services.sysinfo.diskInfo; - this._processData = await Services.sysinfo.processInfo; let osData = await Services.sysinfo.osInfo; - let oldEnv = null; + if (!this._initTask) { // We've finished creating the initial env, so notify for the update // This is all a bit awkward because `currentEnvironment` clones @@ -1132,12 +1149,14 @@ EnvironmentCache.prototype = { this._currentEnvironment.system.os = this._getOSData(); this._currentEnvironment.system.hdd = this._getHDDData(); + + // Windows only values stored in processData this._currentEnvironment.system.isWow64 = this._getProcessData().isWow64; this._currentEnvironment.system.isWowARM64 = this._getProcessData().isWowARM64; + } - if (!this._initTask) { - this._onEnvironmentChange("system-info", oldEnv); - } + if (!this._initTask) { + this._onEnvironmentChange("system-info", oldEnv); } }, @@ -1859,17 +1878,7 @@ EnvironmentCache.prototype = { return this._cpuData; } - this._cpuData = { - count: getSysinfoProperty("cpucount", null), - cores: getSysinfoProperty("cpucores", null), - vendor: getSysinfoProperty("cpuvendor", null), - family: getSysinfoProperty("cpufamily", null), - model: getSysinfoProperty("cpumodel", null), - stepping: getSysinfoProperty("cpustepping", null), - l2cacheKB: getSysinfoProperty("cpucachel2", null), - l3cacheKB: getSysinfoProperty("cpucachel3", null), - speedMHz: getSysinfoProperty("cpuspeed", null), - }; + this._cpuData = {}; const CPU_EXTENSIONS = [ "hasMMX", diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js index ff35302f7bcf..1b769ad282b6 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js @@ -625,26 +625,26 @@ function checkSystemSection(data, assertProcessData) { "MemoryMB must be a number." ); - if (gIsWindows || gIsMac || gIsLinux) { - let EXTRA_CPU_FIELDS = [ - "cores", - "model", - "family", - "stepping", - "l2cacheKB", - "l3cacheKB", - "speedMHz", - "vendor", - ]; + if (assertProcessData) { + if (gIsWindows || gIsMac || gIsLinux) { + let EXTRA_CPU_FIELDS = [ + "cores", + "model", + "family", + "stepping", + "l2cacheKB", + "l3cacheKB", + "speedMHz", + "vendor", + ]; - for (let f of EXTRA_CPU_FIELDS) { - // Note this is testing TelemetryEnvironment.js only, not that the - // values are valid - null is the fallback. - Assert.ok(f in data.system.cpu, f + " must be available under cpu."); - } + for (let f of EXTRA_CPU_FIELDS) { + // Note this is testing TelemetryEnvironment.js only, not that the + // values are valid - null is the fallback. + Assert.ok(f in data.system.cpu, f + " must be available under cpu."); + } - if (gIsWindows) { - if (assertProcessData) { + if (gIsWindows) { Assert.equal( typeof data.system.isWow64, "boolean", @@ -655,45 +655,61 @@ function checkSystemSection(data, assertProcessData) { "boolean", "isWowARM64 must be available on Windows and have the correct type." ); + Assert.ok( + "virtualMaxMB" in data.system, + "virtualMaxMB must be available." + ); + Assert.ok( + Number.isFinite(data.system.virtualMaxMB), + "virtualMaxMB must be a number." + ); + + for (let f of [ + "count", + "model", + "family", + "stepping", + "l2cacheKB", + "l3cacheKB", + "speedMHz", + ]) { + Assert.ok( + Number.isFinite(data.system.cpu[f]), + f + " must be a number if non null." + ); + } } - Assert.ok( - "virtualMaxMB" in data.system, - "virtualMaxMB must be available." - ); - Assert.ok( - Number.isFinite(data.system.virtualMaxMB), - "virtualMaxMB must be a number." - ); - } - // We insist these are available - for (let f of ["cores"]) { - Assert.ok( - !(f in data.system.cpu) || Number.isFinite(data.system.cpu[f]), - f + " must be a number if non null." - ); - } + // These should be numbers if they are not null + for (let f of [ + "count", + "model", + "family", + "stepping", + "l2cacheKB", + "l3cacheKB", + "speedMHz", + ]) { + Assert.ok( + !(f in data.system.cpu) || + data.system.cpu[f] === null || + Number.isFinite(data.system.cpu[f]), + f + " must be a number if non null." + ); + } - // These should be numbers if they are not null - for (let f of [ - "model", - "family", - "stepping", - "l2cacheKB", - "l3cacheKB", - "speedMHz", - ]) { - Assert.ok( - !(f in data.system.cpu) || - data.system.cpu[f] === null || - Number.isFinite(data.system.cpu[f]), - f + " must be a number if non null." - ); + // We insist these are available + for (let f of ["cores"]) { + Assert.ok( + !(f in data.system.cpu) || Number.isFinite(data.system.cpu[f]), + f + " must be a number if non null." + ); + } } } let cpuData = data.system.cpu; - Assert.ok(Number.isFinite(cpuData.count), "CPU count must be a number."); + Assert.ok( Array.isArray(cpuData.extensions), "CPU extensions must be available." @@ -2520,6 +2536,28 @@ if (gIsWindows) { "boolean", "isWowARM64 must be a boolean." ); + // These should be numbers if they are not null + for (let f of [ + "count", + "model", + "family", + "stepping", + "l2cacheKB", + "l3cacheKB", + "speedMHz", + "cores", + ]) { + Assert.ok( + !(f in data.system.cpu) || + data.system.cpu[f] === null || + Number.isFinite(data.system.cpu[f]), + f + " must be a number if non null." + ); + } + Assert.ok( + checkString(data.system.cpu.vendor), + "vendor must be a valid string." + ); }); add_task(async function test_environmentOSInfo() { diff --git a/xpcom/base/nsSystemInfo.cpp b/xpcom/base/nsSystemInfo.cpp index 4ddd7275b8b7..82a4689e4dfb 100644 --- a/xpcom/base/nsSystemInfo.cpp +++ b/xpcom/base/nsSystemInfo.cpp @@ -100,42 +100,66 @@ static void SimpleParseKeyValuePairs( } #endif +#ifdef XP_WIN +// Lifted from media/webrtc/trunk/webrtc/base/systeminfo.cc, +// so keeping the _ instead of switching to camel case for now. +typedef BOOL(WINAPI* LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); +static void GetProcessorInformation(int* physical_cpus, int* cache_size_L2, + int* cache_size_L3) { + MOZ_ASSERT(physical_cpus && cache_size_L2 && cache_size_L3); + + *physical_cpus = 0; + *cache_size_L2 = 0; // This will be in kbytes + *cache_size_L3 = 0; // This will be in kbytes + + // GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond. + LPFN_GLPI glpi = reinterpret_cast(GetProcAddress( + GetModuleHandle(L"kernel32"), "GetLogicalProcessorInformation")); + if (nullptr == glpi) { + return; + } + // Determine buffer size, allocate and get processor information. + // Size can change between calls (unlikely), so a loop is done. + SYSTEM_LOGICAL_PROCESSOR_INFORMATION info_buffer[32]; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION* infos = &info_buffer[0]; + DWORD return_length = sizeof(info_buffer); + while (!glpi(infos, &return_length)) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && + infos == &info_buffer[0]) { + infos = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION + [return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)]; + } else { + return; + } + } + + for (size_t i = 0; + i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) { + if (infos[i].Relationship == RelationProcessorCore) { + ++*physical_cpus; + } else if (infos[i].Relationship == RelationCache) { + // Only care about L2 and L3 cache + switch (infos[i].Cache.Level) { + case 2: + *cache_size_L2 = static_cast(infos[i].Cache.Size / 1024); + break; + case 3: + *cache_size_L3 = static_cast(infos[i].Cache.Size / 1024); + break; + default: + break; + } + } + } + if (infos != &info_buffer[0]) { + delete[] infos; + } + return; +} +#endif + #if defined(XP_WIN) namespace { -nsresult CollectProcessInfo(ProcessInfo& info) { - // IsWow64Process2 is only available on Windows 10+, so we have to dynamically - // check for its existence. - typedef BOOL(WINAPI * LPFN_IWP2)(HANDLE, USHORT*, USHORT*); - LPFN_IWP2 iwp2 = reinterpret_cast( - GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process2")); - BOOL isWow64 = false; - USHORT processMachine = IMAGE_FILE_MACHINE_UNKNOWN; - USHORT nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; - BOOL gotWow64Value; - if (iwp2) { - gotWow64Value = iwp2(GetCurrentProcess(), &processMachine, &nativeMachine); - if (gotWow64Value) { - info.isWow64 = (processMachine != IMAGE_FILE_MACHINE_UNKNOWN); - } - } else { - gotWow64Value = IsWow64Process(GetCurrentProcess(), &isWow64); - // The function only indicates a WOW64 environment if it's 32-bit x86 - // running on x86-64, so emulate what IsWow64Process2 would have given. - if (gotWow64Value && info.isWow64) { - processMachine = IMAGE_FILE_MACHINE_I386; - nativeMachine = IMAGE_FILE_MACHINE_AMD64; - } - } - NS_WARNING_ASSERTION(gotWow64Value, "IsWow64Process failed"); - if (gotWow64Value) { - // Set this always, even for the x86-on-arm64 case. - // Additional information if we're running x86-on-arm64 - info.isWowARM64 = (processMachine == IMAGE_FILE_MACHINE_I386 && - nativeMachine == IMAGE_FILE_MACHINE_ARM64); - } - return NS_OK; -} - static nsresult GetFolderDiskInfo(nsIFile* file, FolderDiskInfo& info) { info.model.Truncate(); info.revision.Truncate(); @@ -458,102 +482,7 @@ static const struct PropItems { {"hasARMv7", mozilla::supports_armv7}, {"hasNEON", mozilla::supports_neon}}; -#ifdef XP_WIN -// Lifted from media/webrtc/trunk/webrtc/base/systeminfo.cc, -// so keeping the _ instead of switching to camel case for now. -typedef BOOL(WINAPI* LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); -static void GetProcessorInformation(int* physical_cpus, int* cache_size_L2, - int* cache_size_L3) { - MOZ_ASSERT(physical_cpus && cache_size_L2 && cache_size_L3); - - *physical_cpus = 0; - *cache_size_L2 = 0; // This will be in kbytes - *cache_size_L3 = 0; // This will be in kbytes - - // GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond. - LPFN_GLPI glpi = reinterpret_cast(GetProcAddress( - GetModuleHandle(L"kernel32"), "GetLogicalProcessorInformation")); - if (nullptr == glpi) { - return; - } - // Determine buffer size, allocate and get processor information. - // Size can change between calls (unlikely), so a loop is done. - SYSTEM_LOGICAL_PROCESSOR_INFORMATION info_buffer[32]; - SYSTEM_LOGICAL_PROCESSOR_INFORMATION* infos = &info_buffer[0]; - DWORD return_length = sizeof(info_buffer); - while (!glpi(infos, &return_length)) { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && - infos == &info_buffer[0]) { - infos = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION - [return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)]; - } else { - return; - } - } - - for (size_t i = 0; - i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) { - if (infos[i].Relationship == RelationProcessorCore) { - ++*physical_cpus; - } else if (infos[i].Relationship == RelationCache) { - // Only care about L2 and L3 cache - switch (infos[i].Cache.Level) { - case 2: - *cache_size_L2 = static_cast(infos[i].Cache.Size / 1024); - break; - case 3: - *cache_size_L3 = static_cast(infos[i].Cache.Size / 1024); - break; - default: - break; - } - } - } - if (infos != &info_buffer[0]) { - delete[] infos; - } - return; -} -#endif - -nsresult nsSystemInfo::Init() { - // check that it is called from the main thread on all platforms. - MOZ_ASSERT(NS_IsMainThread()); - - nsresult rv; - - static const struct { - PRSysInfo cmd; - const char* name; - } items[] = {{PR_SI_SYSNAME, "name"}, - {PR_SI_ARCHITECTURE, "arch"}, - {PR_SI_RELEASE, "version"}}; - - for (uint32_t i = 0; i < (sizeof(items) / sizeof(items[0])); i++) { - char buf[SYS_INFO_BUFFER_LENGTH]; - if (PR_GetSystemInfo(items[i].cmd, buf, sizeof(buf)) == PR_SUCCESS) { - rv = SetPropertyAsACString(NS_ConvertASCIItoUTF16(items[i].name), - nsDependentCString(buf)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - } else { - NS_WARNING("PR_GetSystemInfo failed"); - } - } - - rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16("hasWindowsTouchInterface"), - false); - NS_ENSURE_SUCCESS(rv, rv); - - // Additional informations not available through PR_GetSystemInfo. - SetInt32Property(NS_LITERAL_STRING("pagesize"), PR_GetPageSize()); - SetInt32Property(NS_LITERAL_STRING("pageshift"), PR_GetPageShift()); - SetInt32Property(NS_LITERAL_STRING("memmapalign"), PR_GetMemMapAlignment()); - SetUint64Property(NS_LITERAL_STRING("memsize"), PR_GetPhysicalMemorySize()); - SetUint32Property(NS_LITERAL_STRING("umask"), nsSystemInfo::gUserUmask); - - uint64_t virtualMem = 0; +nsresult CollectProcessInfo(ProcessInfo& info) { nsAutoCString cpuVendor; int cpuSpeed = -1; int cpuFamily = -1; @@ -565,11 +494,35 @@ nsresult nsSystemInfo::Init() { int cacheSizeL3 = -1; #if defined(XP_WIN) - // Virtual memory: - MEMORYSTATUSEX memStat; - memStat.dwLength = sizeof(memStat); - if (GlobalMemoryStatusEx(&memStat)) { - virtualMem = memStat.ullTotalVirtual; + // IsWow64Process2 is only available on Windows 10+, so we have to dynamically + // check for its existence. + typedef BOOL(WINAPI * LPFN_IWP2)(HANDLE, USHORT*, USHORT*); + LPFN_IWP2 iwp2 = reinterpret_cast( + GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process2")); + BOOL isWow64 = false; + USHORT processMachine = IMAGE_FILE_MACHINE_UNKNOWN; + USHORT nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; + BOOL gotWow64Value; + if (iwp2) { + gotWow64Value = iwp2(GetCurrentProcess(), &processMachine, &nativeMachine); + if (gotWow64Value) { + info.isWow64 = (processMachine != IMAGE_FILE_MACHINE_UNKNOWN); + } + } else { + gotWow64Value = IsWow64Process(GetCurrentProcess(), &isWow64); + // The function only indicates a WOW64 environment if it's 32-bit x86 + // running on x86-64, so emulate what IsWow64Process2 would have given. + if (gotWow64Value && info.isWow64) { + processMachine = IMAGE_FILE_MACHINE_I386; + nativeMachine = IMAGE_FILE_MACHINE_AMD64; + } + } + NS_WARNING_ASSERTION(gotWow64Value, "IsWow64Process failed"); + if (gotWow64Value) { + // Set this always, even for the x86-on-arm64 case. + // Additional information if we're running x86-on-arm64 + info.isWowARM64 = (processMachine == IMAGE_FILE_MACHINE_I386 && + nativeMachine == IMAGE_FILE_MACHINE_ARM64); } // CPU speed @@ -683,7 +636,7 @@ nsresult nsSystemInfo::Init() { SimpleParseKeyValuePairs("/proc/cpuinfo", keyValuePairs); // cpuVendor from "vendor_id" - cpuVendor.Assign(keyValuePairs[NS_LITERAL_CSTRING("vendor_id")]); + info.cpuVendor.Assign(keyValuePairs[NS_LITERAL_CSTRING("vendor_id")]); { // cpuFamily from "cpu family" @@ -772,31 +725,95 @@ nsresult nsSystemInfo::Init() { } } - SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors()); + info.cpuCount = PR_GetNumberOfProcessors(); #else - SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors()); + info.cpuCount = PR_GetNumberOfProcessors(); #endif + if (cpuSpeed >= 0) { + info.cpuSpeed = cpuSpeed; + } else { + info.cpuSpeed = 0; + } + if (!cpuVendor.IsEmpty()) { + info.cpuVendor = cpuVendor; + } + if (cpuFamily >= 0) { + info.cpuFamily = cpuFamily; + } + if (cpuModel >= 0) { + info.cpuModel = cpuModel; + } + if (cpuStepping >= 0) { + info.cpuStepping = cpuStepping; + } + + if (logicalCPUs >= 0) { + info.cpuCount = logicalCPUs; + } + if (physicalCPUs >= 0) { + info.cpuCores = physicalCPUs; + } + + if (cacheSizeL2 >= 0) { + info.l2cacheKB = cacheSizeL2; + } + if (cacheSizeL3 >= 0) { + info.l3cacheKB = cacheSizeL3; + } + + return NS_OK; +} + +nsresult nsSystemInfo::Init() { + // check that it is called from the main thread on all platforms. + MOZ_ASSERT(NS_IsMainThread()); + + nsresult rv; + + static const struct { + PRSysInfo cmd; + const char* name; + } items[] = {{PR_SI_SYSNAME, "name"}, + {PR_SI_ARCHITECTURE, "arch"}, + {PR_SI_RELEASE, "version"}}; + + for (uint32_t i = 0; i < (sizeof(items) / sizeof(items[0])); i++) { + char buf[SYS_INFO_BUFFER_LENGTH]; + if (PR_GetSystemInfo(items[i].cmd, buf, sizeof(buf)) == PR_SUCCESS) { + rv = SetPropertyAsACString(NS_ConvertASCIItoUTF16(items[i].name), + nsDependentCString(buf)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } else { + NS_WARNING("PR_GetSystemInfo failed"); + } + } + + rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16("hasWindowsTouchInterface"), + false); + NS_ENSURE_SUCCESS(rv, rv); + + // Additional informations not available through PR_GetSystemInfo. + SetInt32Property(NS_LITERAL_STRING("pagesize"), PR_GetPageSize()); + SetInt32Property(NS_LITERAL_STRING("pageshift"), PR_GetPageShift()); + SetInt32Property(NS_LITERAL_STRING("memmapalign"), PR_GetMemMapAlignment()); + SetUint64Property(NS_LITERAL_STRING("memsize"), PR_GetPhysicalMemorySize()); + SetUint32Property(NS_LITERAL_STRING("umask"), nsSystemInfo::gUserUmask); + + uint64_t virtualMem = 0; + +#if defined(XP_WIN) + // Virtual memory: + MEMORYSTATUSEX memStat; + memStat.dwLength = sizeof(memStat); + if (GlobalMemoryStatusEx(&memStat)) { + virtualMem = memStat.ullTotalVirtual; + } +#endif if (virtualMem) SetUint64Property(NS_LITERAL_STRING("virtualmemsize"), virtualMem); - if (cpuSpeed >= 0) SetInt32Property(NS_LITERAL_STRING("cpuspeed"), cpuSpeed); - if (!cpuVendor.IsEmpty()) - SetPropertyAsACString(NS_LITERAL_STRING("cpuvendor"), cpuVendor); - if (cpuFamily >= 0) - SetInt32Property(NS_LITERAL_STRING("cpufamily"), cpuFamily); - if (cpuModel >= 0) SetInt32Property(NS_LITERAL_STRING("cpumodel"), cpuModel); - if (cpuStepping >= 0) - SetInt32Property(NS_LITERAL_STRING("cpustepping"), cpuStepping); - - if (logicalCPUs >= 0) - SetInt32Property(NS_LITERAL_STRING("cpucount"), logicalCPUs); - if (physicalCPUs >= 0) - SetInt32Property(NS_LITERAL_STRING("cpucores"), physicalCPUs); - - if (cacheSizeL2 >= 0) - SetInt32Property(NS_LITERAL_STRING("cpucachel2"), cacheSizeL2); - if (cacheSizeL3 >= 0) - SetInt32Property(NS_LITERAL_STRING("cpucachel3"), cacheSizeL3); for (uint32_t i = 0; i < ArrayLength(cpuPropItems); i++) { rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16(cpuPropItems[i].name), @@ -1097,11 +1114,43 @@ JSObject* GetJSObjForOSInfo(JSContext* aCx, const OSInfo& info) { JSObject* GetJSObjForProcessInfo(JSContext* aCx, const ProcessInfo& info) { JS::Rooted jsInfo(aCx, JS_NewPlainObject(aCx)); +#if defined(XP_WIN) JS::Rooted valisWow64(aCx, JS::BooleanValue(info.isWow64)); JS_SetProperty(aCx, jsInfo, "isWow64", valisWow64); JS::Rooted valisWowARM64(aCx, JS::BooleanValue(info.isWowARM64)); JS_SetProperty(aCx, jsInfo, "isWowARM64", valisWowARM64); +#endif + + JS::Rooted valCountInfo(aCx, JS::Int32Value(info.cpuCount)); + JS_SetProperty(aCx, jsInfo, "count", valCountInfo); + + JS::Rooted valCoreInfo(aCx, JS::Int32Value(info.cpuCores)); + JS_SetProperty(aCx, jsInfo, "cores", valCoreInfo); + + JSString* strVendor = + JS_NewStringCopyN(aCx, info.cpuVendor.get(), info.cpuVendor.Length()); + JS::Rooted valVendor(aCx, JS::StringValue(strVendor)); + JS_SetProperty(aCx, jsInfo, "vendor", valVendor); + + JS::Rooted valFamilyInfo(aCx, JS::Int32Value(info.cpuFamily)); + JS_SetProperty(aCx, jsInfo, "family", valFamilyInfo); + + JS::Rooted valModelInfo(aCx, JS::Int32Value(info.cpuModel)); + JS_SetProperty(aCx, jsInfo, "model", valModelInfo); + + JS::Rooted valSteppingInfo(aCx, JS::Int32Value(info.cpuStepping)); + JS_SetProperty(aCx, jsInfo, "stepping", valSteppingInfo); + + JS::Rooted valL2CacheInfo(aCx, JS::Int32Value(info.l2cacheKB)); + JS_SetProperty(aCx, jsInfo, "l2cacheKB", valL2CacheInfo); + + JS::Rooted valL3CacheInfo(aCx, JS::Int32Value(info.l3cacheKB)); + JS_SetProperty(aCx, jsInfo, "l3cacheKB", valL3CacheInfo); + + JS::Rooted valSpeedInfo(aCx, JS::Int32Value(info.cpuSpeed)); + JS_SetProperty(aCx, jsInfo, "speedMHz", valSpeedInfo); + return jsInfo; } @@ -1329,7 +1378,7 @@ nsSystemInfo::GetProcessInfo(JSContext* aCx, Promise** aResult) { if (!XRE_IsParentProcess()) { return NS_ERROR_FAILURE; } -#if defined(XP_WIN) + nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx); if (NS_WARN_IF(!global)) { return NS_ERROR_FAILURE; @@ -1375,6 +1424,6 @@ nsSystemInfo::GetProcessInfo(JSContext* aCx, Promise** aResult) { }); promise.forget(aResult); -#endif + return NS_OK; } diff --git a/xpcom/base/nsSystemInfo.h b/xpcom/base/nsSystemInfo.h index a4144b8e90d5..1e05effc80b7 100644 --- a/xpcom/base/nsSystemInfo.h +++ b/xpcom/base/nsSystemInfo.h @@ -35,6 +35,15 @@ struct OSInfo { struct ProcessInfo { bool isWow64; bool isWowARM64; + uint32_t cpuCount; + uint32_t cpuCores; + nsCString cpuVendor; + uint32_t cpuFamily; + uint32_t cpuModel; + uint32_t cpuStepping; + uint32_t l2cacheKB; + uint32_t l3cacheKB; + uint32_t cpuSpeed; }; typedef mozilla::MozPromise diff --git a/xpcom/tests/unit/test_systemInfo.js b/xpcom/tests/unit/test_systemInfo.js index 628f687fc61a..87426815fda0 100644 --- a/xpcom/tests/unit/test_systemInfo.js +++ b/xpcom/tests/unit/test_systemInfo.js @@ -10,7 +10,6 @@ function run_test() { "pagesize", "pageshift", "memmapalign", - "cpucount", "memsize", ]; let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);