LCOV - code coverage report
Current view: top level - xpcom/base - nsSystemInfo.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 5 136 3.7 %
Date: 2018-08-07 16:35:00 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/ArrayUtils.h"
       8             : 
       9             : #include "nsSystemInfo.h"
      10             : #include "prsystem.h"
      11             : #include "prio.h"
      12             : #include "mozilla/SSE.h"
      13             : #include "mozilla/arm.h"
      14             : #include "mozilla/Sprintf.h"
      15             : 
      16             : #ifdef XP_WIN
      17             : #include <comutil.h>
      18             : #include <time.h>
      19             : #ifndef __MINGW32__
      20             : #include <iwscapi.h>
      21             : #endif // __MINGW32__
      22             : #include <windows.h>
      23             : #include <winioctl.h>
      24             : #ifndef __MINGW32__
      25             : #include <wscapi.h>
      26             : #endif // __MINGW32__
      27             : #include "base/scoped_handle_win.h"
      28             : #include "nsAppDirectoryServiceDefs.h"
      29             : #include "nsDirectoryServiceDefs.h"
      30             : #include "nsDirectoryServiceUtils.h"
      31             : #include "nsIObserverService.h"
      32             : #include "nsWindowsHelpers.h"
      33             : 
      34             : #endif
      35             : 
      36             : #ifdef XP_MACOSX
      37             : #include "MacHelpers.h"
      38             : #endif
      39             : 
      40             : #ifdef MOZ_WIDGET_GTK
      41             : #include <gtk/gtk.h>
      42             : #include <dlfcn.h>
      43             : #endif
      44             : 
      45             : #if defined (XP_LINUX) && !defined (ANDROID)
      46             : #include <unistd.h>
      47             : #include <fstream>
      48             : #include "mozilla/Tokenizer.h"
      49             : #include "nsCharSeparatedTokenizer.h"
      50             : 
      51             : #include <map>
      52             : #include <string>
      53             : #endif
      54             : 
      55             : #ifdef MOZ_WIDGET_ANDROID
      56             : #include "AndroidBridge.h"
      57             : #include "mozilla/dom/ContentChild.h"
      58             : #endif
      59             : 
      60             : #ifdef ANDROID
      61             : extern "C" {
      62             : NS_EXPORT int android_sdk_version;
      63             : }
      64             : #endif
      65             : 
      66             : #ifdef XP_MACOSX
      67             : #include <sys/sysctl.h>
      68             : #endif
      69             : 
      70             : #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
      71             : #include "mozilla/SandboxInfo.h"
      72             : #endif
      73             : 
      74             : // Slot for NS_InitXPCOM2 to pass information to nsSystemInfo::Init.
      75             : // Only set to nonzero (potentially) if XP_UNIX.  On such systems, the
      76             : // system call to discover the appropriate value is not thread-safe,
      77             : // so we must call it before going multithreaded, but nsSystemInfo::Init
      78             : // only happens well after that point.
      79             : uint32_t nsSystemInfo::gUserUmask = 0;
      80             : 
      81             : using namespace mozilla::dom;
      82             : 
      83             : #if defined (XP_LINUX) && !defined (ANDROID)
      84             : static void
      85           0 : SimpleParseKeyValuePairs(const std::string& aFilename,
      86             :                          std::map<nsCString, nsCString>& aKeyValuePairs)
      87             : {
      88           0 :   std::ifstream input(aFilename.c_str());
      89           0 :   for (std::string line; std::getline(input, line); ) {
      90           0 :     nsAutoCString key, value;
      91             : 
      92           0 :     nsCCharSeparatedTokenizer tokens(nsDependentCString(line.c_str()), ':');
      93           0 :     if (tokens.hasMoreTokens()) {
      94           0 :       key = tokens.nextToken();
      95           0 :       if (tokens.hasMoreTokens()) {
      96           0 :         value = tokens.nextToken();
      97             :       }
      98             :       // We want the value even if there was just one token, to cover the
      99             :       // case where we had the key, and the value was blank (seems to be
     100             :       // a valid scenario some files.)
     101           0 :       aKeyValuePairs[key] = value;
     102             :     }
     103             :   }
     104           0 : }
     105             : #endif
     106             : 
     107             : #if defined(XP_WIN)
     108             : namespace {
     109             : nsresult
     110             : GetHDDInfo(const char* aSpecialDirName, nsAutoCString& aModel,
     111             :            nsAutoCString& aRevision)
     112             : {
     113             :   aModel.Truncate();
     114             :   aRevision.Truncate();
     115             : 
     116             :   nsCOMPtr<nsIFile> profDir;
     117             :   nsresult rv = NS_GetSpecialDirectory(aSpecialDirName,
     118             :                                        getter_AddRefs(profDir));
     119             :   NS_ENSURE_SUCCESS(rv, rv);
     120             :   nsAutoString profDirPath;
     121             :   rv = profDir->GetPath(profDirPath);
     122             :   NS_ENSURE_SUCCESS(rv, rv);
     123             :   wchar_t volumeMountPoint[MAX_PATH] = {L'\\', L'\\', L'.', L'\\'};
     124             :   const size_t PREFIX_LEN = 4;
     125             :   if (!::GetVolumePathNameW(profDirPath.get(), volumeMountPoint + PREFIX_LEN,
     126             :                             mozilla::ArrayLength(volumeMountPoint) -
     127             :                             PREFIX_LEN)) {
     128             :     return NS_ERROR_UNEXPECTED;
     129             :   }
     130             :   size_t volumeMountPointLen = wcslen(volumeMountPoint);
     131             :   // Since we would like to open a drive and not a directory, we need to
     132             :   // remove any trailing backslash. A drive handle is valid for
     133             :   // DeviceIoControl calls, a directory handle is not.
     134             :   if (volumeMountPoint[volumeMountPointLen - 1] == L'\\') {
     135             :     volumeMountPoint[volumeMountPointLen - 1] = L'\0';
     136             :   }
     137             :   ScopedHandle handle(::CreateFileW(volumeMountPoint, 0,
     138             :                                     FILE_SHARE_READ | FILE_SHARE_WRITE,
     139             :                                     nullptr, OPEN_EXISTING, 0, nullptr));
     140             :   if (!handle.IsValid()) {
     141             :     return NS_ERROR_UNEXPECTED;
     142             :   }
     143             :   STORAGE_PROPERTY_QUERY queryParameters = {
     144             :     StorageDeviceProperty, PropertyStandardQuery
     145             :   };
     146             :   STORAGE_DEVICE_DESCRIPTOR outputHeader = {sizeof(STORAGE_DEVICE_DESCRIPTOR)};
     147             :   DWORD bytesRead = 0;
     148             :   if (!::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY,
     149             :                          &queryParameters, sizeof(queryParameters),
     150             :                          &outputHeader, sizeof(outputHeader), &bytesRead,
     151             :                          nullptr)) {
     152             :     return NS_ERROR_FAILURE;
     153             :   }
     154             :   PSTORAGE_DEVICE_DESCRIPTOR deviceOutput =
     155             :     (PSTORAGE_DEVICE_DESCRIPTOR)malloc(outputHeader.Size);
     156             :   if (!::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY,
     157             :                          &queryParameters, sizeof(queryParameters),
     158             :                          deviceOutput, outputHeader.Size, &bytesRead,
     159             :                          nullptr)) {
     160             :     free(deviceOutput);
     161             :     return NS_ERROR_FAILURE;
     162             :   }
     163             :   // Some HDDs are including product ID info in the vendor field. Since PNP
     164             :   // IDs include vendor info and product ID concatenated together, we'll do
     165             :   // that here and interpret the result as a unique ID for the HDD model.
     166             :   if (deviceOutput->VendorIdOffset) {
     167             :     aModel = reinterpret_cast<char*>(deviceOutput) +
     168             :       deviceOutput->VendorIdOffset;
     169             :   }
     170             :   if (deviceOutput->ProductIdOffset) {
     171             :     aModel += reinterpret_cast<char*>(deviceOutput) +
     172             :       deviceOutput->ProductIdOffset;
     173             :   }
     174             :   aModel.CompressWhitespace();
     175             :   if (deviceOutput->ProductRevisionOffset) {
     176             :     aRevision = reinterpret_cast<char*>(deviceOutput) +
     177             :       deviceOutput->ProductRevisionOffset;
     178             :     aRevision.CompressWhitespace();
     179             :   }
     180             :   free(deviceOutput);
     181             :   return NS_OK;
     182             : }
     183             : 
     184             : nsresult GetInstallYear(uint32_t& aYear)
     185             : {
     186             :   HKEY hKey;
     187             :   LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
     188             :                               L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
     189             :                               0, KEY_READ | KEY_WOW64_64KEY, &hKey);
     190             : 
     191             :   if (status != ERROR_SUCCESS) {
     192             :     return NS_ERROR_UNEXPECTED;
     193             :   }
     194             : 
     195             :   nsAutoRegKey key(hKey);
     196             : 
     197             :   DWORD type = 0;
     198             :   time_t raw_time = 0;
     199             :   DWORD time_size = sizeof(time_t);
     200             : 
     201             :   status = RegQueryValueExW(hKey, L"InstallDate",
     202             :                             nullptr, &type, (LPBYTE)&raw_time, &time_size);
     203             : 
     204             :   if (status != ERROR_SUCCESS) {
     205             :     return NS_ERROR_UNEXPECTED;
     206             :   }
     207             : 
     208             :   if (type != REG_DWORD) {
     209             :     return NS_ERROR_UNEXPECTED;
     210             :   }
     211             : 
     212             :   tm time;
     213             :   if (localtime_s(&time, &raw_time) != 0) {
     214             :     return NS_ERROR_UNEXPECTED;
     215             :   }
     216             : 
     217             :   aYear = 1900UL + time.tm_year;
     218             :   return NS_OK;
     219             : }
     220             : 
     221             : nsresult GetCountryCode(nsAString& aCountryCode)
     222             : {
     223             :   GEOID geoid = GetUserGeoID(GEOCLASS_NATION);
     224             :   if (geoid == GEOID_NOT_AVAILABLE) {
     225             :     return NS_ERROR_NOT_AVAILABLE;
     226             :   }
     227             :   // Get required length
     228             :   int numChars = GetGeoInfoW(geoid, GEO_ISO2, nullptr, 0, 0);
     229             :   if (!numChars) {
     230             :     return NS_ERROR_FAILURE;
     231             :   }
     232             :   // Now get the string for real
     233             :   aCountryCode.SetLength(numChars);
     234             :   numChars = GetGeoInfoW(geoid, GEO_ISO2, char16ptr_t(aCountryCode.BeginWriting()),
     235             :                          aCountryCode.Length(), 0);
     236             :   if (!numChars) {
     237             :     return NS_ERROR_FAILURE;
     238             :   }
     239             : 
     240             :   // numChars includes null terminator
     241             :   aCountryCode.Truncate(numChars - 1);
     242             :   return NS_OK;
     243             : }
     244             : 
     245             : } // namespace
     246             : 
     247             : #ifndef __MINGW32__
     248             : 
     249             : static HRESULT
     250             : EnumWSCProductList(nsAString& aOutput, NotNull<IWSCProductList*> aProdList)
     251             : {
     252             :   MOZ_ASSERT(aOutput.IsEmpty());
     253             : 
     254             :   LONG count;
     255             :   HRESULT hr = aProdList->get_Count(&count);
     256             :   if (FAILED(hr)) {
     257             :     return hr;
     258             :   }
     259             : 
     260             :   for (LONG index = 0; index < count; ++index) {
     261             :     RefPtr<IWscProduct> product;
     262             :     hr = aProdList->get_Item(index, getter_AddRefs(product));
     263             :     if (FAILED(hr)) {
     264             :       return hr;
     265             :     }
     266             : 
     267             :     WSC_SECURITY_PRODUCT_STATE state;
     268             :     hr = product->get_ProductState(&state);
     269             :     if (FAILED(hr)) {
     270             :       return hr;
     271             :     }
     272             : 
     273             :     // We only care about products that are active
     274             :     if (state == WSC_SECURITY_PRODUCT_STATE_OFF ||
     275             :         state == WSC_SECURITY_PRODUCT_STATE_SNOOZED) {
     276             :       continue;
     277             :     }
     278             : 
     279             :     _bstr_t bName;
     280             :     hr = product->get_ProductName(bName.GetAddress());
     281             :     if (FAILED(hr)) {
     282             :       return hr;
     283             :     }
     284             : 
     285             :     if (!aOutput.IsEmpty()) {
     286             :       aOutput.AppendLiteral(u";");
     287             :     }
     288             : 
     289             :     aOutput.Append((wchar_t*)bName, bName.length());
     290             :   }
     291             : 
     292             :   return S_OK;
     293             : }
     294             : 
     295             : static nsresult
     296             : GetWindowsSecurityCenterInfo(nsAString& aAVInfo, nsAString& aAntiSpyInfo,
     297             :                              nsAString& aFirewallInfo)
     298             : {
     299             :   aAVInfo.Truncate();
     300             :   aAntiSpyInfo.Truncate();
     301             :   aFirewallInfo.Truncate();
     302             : 
     303             :   if (!XRE_IsParentProcess()) {
     304             :     return NS_ERROR_NOT_AVAILABLE;
     305             :   }
     306             : 
     307             :   const CLSID clsid = __uuidof(WSCProductList);
     308             :   const IID iid = __uuidof(IWSCProductList);
     309             : 
     310             :   // NB: A separate instance of IWSCProductList is needed for each distinct
     311             :   // security provider type; MSDN says that we cannot reuse the same object
     312             :   // and call Initialize() to pave over the previous data.
     313             : 
     314             :   WSC_SECURITY_PROVIDER providerTypes[] = { WSC_SECURITY_PROVIDER_ANTIVIRUS,
     315             :                                             WSC_SECURITY_PROVIDER_ANTISPYWARE,
     316             :                                             WSC_SECURITY_PROVIDER_FIREWALL };
     317             : 
     318             :   // Each output must match the corresponding entry in providerTypes.
     319             :   nsAString* outputs[] = { &aAVInfo, &aAntiSpyInfo, &aFirewallInfo };
     320             : 
     321             :   static_assert(ArrayLength(providerTypes) == ArrayLength(outputs),
     322             :                 "Length of providerTypes and outputs arrays must match");
     323             : 
     324             :   for (uint32_t index = 0; index < ArrayLength(providerTypes); ++index) {
     325             :     RefPtr<IWSCProductList> prodList;
     326             :     HRESULT hr = ::CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, iid,
     327             :                                     getter_AddRefs(prodList));
     328             :     if (FAILED(hr)) {
     329             :       return NS_ERROR_NOT_AVAILABLE;
     330             :     }
     331             : 
     332             :     hr = prodList->Initialize(providerTypes[index]);
     333             :     if (FAILED(hr)) {
     334             :       return NS_ERROR_UNEXPECTED;
     335             :     }
     336             : 
     337             :     hr = EnumWSCProductList(*outputs[index], WrapNotNull(prodList.get()));
     338             :     if (FAILED(hr)) {
     339             :       return NS_ERROR_UNEXPECTED;
     340             :     }
     341             :   }
     342             : 
     343             :   return NS_OK;
     344             : }
     345             : 
     346             : #endif // __MINGW32__
     347             : 
     348             : #endif // defined(XP_WIN)
     349             : 
     350             : #ifdef XP_MACOSX
     351             : static nsresult GetAppleModelId(nsAutoCString& aModelId)
     352             : {
     353             :   size_t numChars = 0;
     354             :   size_t result = sysctlbyname("hw.model", nullptr, &numChars, nullptr, 0);
     355             :   if (result != 0 || !numChars) {
     356             :     return NS_ERROR_FAILURE;
     357             :   }
     358             :   aModelId.SetLength(numChars);
     359             :   result = sysctlbyname("hw.model", aModelId.BeginWriting(), &numChars, nullptr,
     360             :                         0);
     361             :   if (result != 0) {
     362             :     return NS_ERROR_FAILURE;
     363             :   }
     364             :   // numChars includes null terminator
     365             :   aModelId.Truncate(numChars - 1);
     366             :   return NS_OK;
     367             : }
     368             : #endif
     369             : 
     370             : using namespace mozilla;
     371             : 
     372           0 : nsSystemInfo::nsSystemInfo()
     373             : {
     374           0 : }
     375             : 
     376           0 : nsSystemInfo::~nsSystemInfo()
     377             : {
     378           0 : }
     379             : 
     380             : // CPU-specific information.
     381             : static const struct PropItems
     382             : {
     383             :   const char* name;
     384             :   bool (*propfun)(void);
     385             : } cpuPropItems[] = {
     386             :   // x86-specific bits.
     387             :   { "hasMMX", mozilla::supports_mmx },
     388             :   { "hasSSE", mozilla::supports_sse },
     389             :   { "hasSSE2", mozilla::supports_sse2 },
     390             :   { "hasSSE3", mozilla::supports_sse3 },
     391             :   { "hasSSSE3", mozilla::supports_ssse3 },
     392             :   { "hasSSE4A", mozilla::supports_sse4a },
     393             :   { "hasSSE4_1", mozilla::supports_sse4_1 },
     394             :   { "hasSSE4_2", mozilla::supports_sse4_2 },
     395             :   { "hasAVX", mozilla::supports_avx },
     396             :   { "hasAVX2", mozilla::supports_avx2 },
     397             :   { "hasAES", mozilla::supports_aes },
     398             :   // ARM-specific bits.
     399             :   { "hasEDSP", mozilla::supports_edsp },
     400             :   { "hasARMv6", mozilla::supports_armv6 },
     401             :   { "hasARMv7", mozilla::supports_armv7 },
     402             :   { "hasNEON", mozilla::supports_neon }
     403             : };
     404             : 
     405             : #ifdef XP_WIN
     406             : // Lifted from media/webrtc/trunk/webrtc/base/systeminfo.cc,
     407             : // so keeping the _ instead of switching to camel case for now.
     408             : typedef BOOL (WINAPI *LPFN_GLPI)(
     409             :     PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
     410             :     PDWORD);
     411             : static void
     412             : GetProcessorInformation(int* physical_cpus, int* cache_size_L2, int* cache_size_L3)
     413             : {
     414             :   MOZ_ASSERT(physical_cpus && cache_size_L2 && cache_size_L3);
     415             : 
     416             :   *physical_cpus = 0;
     417             :   *cache_size_L2 = 0; // This will be in kbytes
     418             :   *cache_size_L3 = 0; // This will be in kbytes
     419             : 
     420             :   // GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond.
     421             :   LPFN_GLPI glpi = reinterpret_cast<LPFN_GLPI>(GetProcAddress(
     422             :       GetModuleHandle(L"kernel32"),
     423             :       "GetLogicalProcessorInformation"));
     424             :   if (nullptr == glpi) {
     425             :     return;
     426             :   }
     427             :   // Determine buffer size, allocate and get processor information.
     428             :   // Size can change between calls (unlikely), so a loop is done.
     429             :   SYSTEM_LOGICAL_PROCESSOR_INFORMATION info_buffer[32];
     430             :   SYSTEM_LOGICAL_PROCESSOR_INFORMATION* infos = &info_buffer[0];
     431             :   DWORD return_length = sizeof(info_buffer);
     432             :   while (!glpi(infos, &return_length)) {
     433             :     if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && infos == &info_buffer[0]) {
     434             :       infos = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)];
     435             :     } else {
     436             :       return;
     437             :     }
     438             :   }
     439             : 
     440             :   for (size_t i = 0;
     441             :       i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
     442             :     if (infos[i].Relationship == RelationProcessorCore) {
     443             :       ++*physical_cpus;
     444             :     } else if (infos[i].Relationship == RelationCache) {
     445             :       // Only care about L2 and L3 cache
     446             :       switch (infos[i].Cache.Level) {
     447             :         case 2:
     448             :           *cache_size_L2 = static_cast<int>(infos[i].Cache.Size/1024);
     449             :           break;
     450             :         case 3:
     451             :           *cache_size_L3 = static_cast<int>(infos[i].Cache.Size/1024);
     452             :           break;
     453             :         default:
     454             :           break;
     455             :       }
     456             :     }
     457             :   }
     458             :   if (infos != &info_buffer[0]) {
     459             :     delete [] infos;
     460             :   }
     461             :   return;
     462             : }
     463             : #endif
     464             : 
     465             : nsresult
     466           0 : nsSystemInfo::Init()
     467             : {
     468             :   // This uses the observer service on Windows, so for simplicity
     469             :   // check that it is called from the main thread on all platforms.
     470           0 :   MOZ_ASSERT(NS_IsMainThread());
     471             : 
     472             :   nsresult rv;
     473             : 
     474             :   static const struct
     475             :   {
     476             :     PRSysInfo cmd;
     477             :     const char* name;
     478             :   } items[] = {
     479             :     { PR_SI_SYSNAME, "name" },
     480             :     { PR_SI_ARCHITECTURE, "arch" },
     481             :     { PR_SI_RELEASE, "version" }
     482             :   };
     483             : 
     484           0 :   for (uint32_t i = 0; i < (sizeof(items) / sizeof(items[0])); i++) {
     485             :     char buf[SYS_INFO_BUFFER_LENGTH];
     486           0 :     if (PR_GetSystemInfo(items[i].cmd, buf, sizeof(buf)) == PR_SUCCESS) {
     487           0 :       rv = SetPropertyAsACString(NS_ConvertASCIItoUTF16(items[i].name),
     488           0 :                                  nsDependentCString(buf));
     489           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     490           0 :         return rv;
     491             :       }
     492             :     } else {
     493           0 :       NS_WARNING("PR_GetSystemInfo failed");
     494             :     }
     495             :   }
     496             : 
     497           0 :   rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16("hasWindowsTouchInterface"),
     498           0 :                          false);
     499           0 :   NS_ENSURE_SUCCESS(rv, rv);
     500             : 
     501             :   // Additional informations not available through PR_GetSystemInfo.
     502           0 :   SetInt32Property(NS_LITERAL_STRING("pagesize"), PR_GetPageSize());
     503           0 :   SetInt32Property(NS_LITERAL_STRING("pageshift"), PR_GetPageShift());
     504           0 :   SetInt32Property(NS_LITERAL_STRING("memmapalign"), PR_GetMemMapAlignment());
     505           0 :   SetUint64Property(NS_LITERAL_STRING("memsize"), PR_GetPhysicalMemorySize());
     506           0 :   SetUint32Property(NS_LITERAL_STRING("umask"), nsSystemInfo::gUserUmask);
     507             : 
     508           0 :   uint64_t virtualMem = 0;
     509           0 :   nsAutoCString cpuVendor;
     510           0 :   int cpuSpeed = -1;
     511           0 :   int cpuFamily = -1;
     512           0 :   int cpuModel = -1;
     513           0 :   int cpuStepping = -1;
     514           0 :   int logicalCPUs = -1;
     515           0 :   int physicalCPUs = -1;
     516           0 :   int cacheSizeL2 = -1;
     517           0 :   int cacheSizeL3 = -1;
     518             : 
     519             : #if defined (XP_WIN)
     520             :   // Virtual memory:
     521             :   MEMORYSTATUSEX memStat;
     522             :   memStat.dwLength = sizeof(memStat);
     523             :   if (GlobalMemoryStatusEx(&memStat)) {
     524             :     virtualMem = memStat.ullTotalVirtual;
     525             :   }
     526             : 
     527             :   // CPU speed
     528             :   HKEY key;
     529             :   static const WCHAR keyName[] =
     530             :     L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
     531             : 
     532             :   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName , 0, KEY_QUERY_VALUE, &key)
     533             :       == ERROR_SUCCESS) {
     534             :     DWORD data, len, vtype;
     535             :     len = sizeof(data);
     536             : 
     537             :     if (RegQueryValueEx(key, L"~Mhz", 0, 0, reinterpret_cast<LPBYTE>(&data),
     538             :                         &len) == ERROR_SUCCESS) {
     539             :       cpuSpeed = static_cast<int>(data);
     540             :     }
     541             : 
     542             :     // Limit to 64 double byte characters, should be plenty, but create
     543             :     // a buffer one larger as the result may not be null terminated. If
     544             :     // it is more than 64, we will not get the value.
     545             :     wchar_t cpuVendorStr[64+1];
     546             :     len = sizeof(cpuVendorStr)-2;
     547             :     if (RegQueryValueExW(key, L"VendorIdentifier",
     548             :                          0, &vtype,
     549             :                          reinterpret_cast<LPBYTE>(cpuVendorStr),
     550             :                          &len) == ERROR_SUCCESS &&
     551             :         vtype == REG_SZ && len % 2 == 0 && len > 1) {
     552             :       cpuVendorStr[len/2] = 0; // In case it isn't null terminated
     553             :       CopyUTF16toUTF8(nsDependentString(cpuVendorStr), cpuVendor);
     554             :     }
     555             : 
     556             :     RegCloseKey(key);
     557             :   }
     558             : 
     559             :   // Other CPU attributes:
     560             :   SYSTEM_INFO si;
     561             :   GetNativeSystemInfo(&si);
     562             :   logicalCPUs = si.dwNumberOfProcessors;
     563             :   GetProcessorInformation(&physicalCPUs, &cacheSizeL2, &cacheSizeL3);
     564             :   if (physicalCPUs <= 0) {
     565             :     physicalCPUs = logicalCPUs;
     566             :   }
     567             :   cpuFamily = si.wProcessorLevel;
     568             :   cpuModel = si.wProcessorRevision >> 8;
     569             :   cpuStepping = si.wProcessorRevision & 0xFF;
     570             : #elif defined (XP_MACOSX)
     571             :   // CPU speed
     572             :   uint64_t sysctlValue64 = 0;
     573             :   uint32_t sysctlValue32 = 0;
     574             :   size_t len = 0;
     575             :   len = sizeof(sysctlValue64);
     576             :   if (!sysctlbyname("hw.cpufrequency_max", &sysctlValue64, &len, NULL, 0)) {
     577             :     cpuSpeed = static_cast<int>(sysctlValue64/1000000);
     578             :   }
     579             :   MOZ_ASSERT(sizeof(sysctlValue64) == len);
     580             : 
     581             :   len = sizeof(sysctlValue32);
     582             :   if (!sysctlbyname("hw.physicalcpu_max", &sysctlValue32, &len, NULL, 0)) {
     583             :     physicalCPUs = static_cast<int>(sysctlValue32);
     584             :   }
     585             :   MOZ_ASSERT(sizeof(sysctlValue32) == len);
     586             : 
     587             :   len = sizeof(sysctlValue32);
     588             :   if (!sysctlbyname("hw.logicalcpu_max", &sysctlValue32, &len, NULL, 0)) {
     589             :     logicalCPUs = static_cast<int>(sysctlValue32);
     590             :   }
     591             :   MOZ_ASSERT(sizeof(sysctlValue32) == len);
     592             : 
     593             :   len = sizeof(sysctlValue64);
     594             :   if (!sysctlbyname("hw.l2cachesize", &sysctlValue64, &len, NULL, 0)) {
     595             :     cacheSizeL2 = static_cast<int>(sysctlValue64/1024);
     596             :   }
     597             :   MOZ_ASSERT(sizeof(sysctlValue64) == len);
     598             : 
     599             :   len = sizeof(sysctlValue64);
     600             :   if (!sysctlbyname("hw.l3cachesize", &sysctlValue64, &len, NULL, 0)) {
     601             :     cacheSizeL3 = static_cast<int>(sysctlValue64/1024);
     602             :   }
     603             :   MOZ_ASSERT(sizeof(sysctlValue64) == len);
     604             : 
     605             :   if (!sysctlbyname("machdep.cpu.vendor", NULL, &len, NULL, 0)) {
     606             :     char* cpuVendorStr = new char[len];
     607             :     if (!sysctlbyname("machdep.cpu.vendor", cpuVendorStr, &len, NULL, 0)) {
     608             :       cpuVendor = cpuVendorStr;
     609             :     }
     610             :     delete [] cpuVendorStr;
     611             :   }
     612             : 
     613             :   len = sizeof(sysctlValue32);
     614             :   if (!sysctlbyname("machdep.cpu.family", &sysctlValue32, &len, NULL, 0)) {
     615             :     cpuFamily = static_cast<int>(sysctlValue32);
     616             :   }
     617             :   MOZ_ASSERT(sizeof(sysctlValue32) == len);
     618             : 
     619             :   len = sizeof(sysctlValue32);
     620             :   if (!sysctlbyname("machdep.cpu.model", &sysctlValue32, &len, NULL, 0)) {
     621             :     cpuModel = static_cast<int>(sysctlValue32);
     622             :   }
     623             :   MOZ_ASSERT(sizeof(sysctlValue32) == len);
     624             : 
     625             :   len = sizeof(sysctlValue32);
     626             :   if (!sysctlbyname("machdep.cpu.stepping", &sysctlValue32, &len, NULL, 0)) {
     627             :     cpuStepping = static_cast<int>(sysctlValue32);
     628             :   }
     629             :   MOZ_ASSERT(sizeof(sysctlValue32) == len);
     630             : 
     631             : #elif defined (XP_LINUX) && !defined (ANDROID)
     632             :   // Get vendor, family, model, stepping, physical cores, L3 cache size
     633             :   // from /proc/cpuinfo file
     634             :   {
     635           0 :     std::map<nsCString, nsCString> keyValuePairs;
     636           0 :     SimpleParseKeyValuePairs("/proc/cpuinfo", keyValuePairs);
     637             : 
     638             :     // cpuVendor from "vendor_id"
     639           0 :     cpuVendor.Assign(keyValuePairs[NS_LITERAL_CSTRING("vendor_id")]);
     640             : 
     641             :     {
     642             :       // cpuFamily from "cpu family"
     643           0 :       Tokenizer::Token t;
     644           0 :       Tokenizer p(keyValuePairs[NS_LITERAL_CSTRING("cpu family")]);
     645           0 :       if (p.Next(t) && t.Type() == Tokenizer::TOKEN_INTEGER &&
     646           0 :           t.AsInteger() <= INT32_MAX) {
     647           0 :         cpuFamily = static_cast<int>(t.AsInteger());
     648             :       }
     649             :     }
     650             : 
     651             :     {
     652             :       // cpuModel from "model"
     653           0 :       Tokenizer::Token t;
     654           0 :       Tokenizer p(keyValuePairs[NS_LITERAL_CSTRING("model")]);
     655           0 :       if (p.Next(t) && t.Type() == Tokenizer::TOKEN_INTEGER &&
     656           0 :           t.AsInteger() <= INT32_MAX) {
     657           0 :         cpuModel = static_cast<int>(t.AsInteger());
     658             :       }
     659             :     }
     660             : 
     661             :     {
     662             :       // cpuStepping from "stepping"
     663           0 :       Tokenizer::Token t;
     664           0 :       Tokenizer p(keyValuePairs[NS_LITERAL_CSTRING("stepping")]);
     665           0 :       if (p.Next(t) && t.Type() == Tokenizer::TOKEN_INTEGER &&
     666           0 :           t.AsInteger() <= INT32_MAX) {
     667           0 :         cpuStepping = static_cast<int>(t.AsInteger());
     668             :       }
     669             :     }
     670             : 
     671             :     {
     672             :       // physicalCPUs from "cpu cores"
     673           0 :       Tokenizer::Token t;
     674           0 :       Tokenizer p(keyValuePairs[NS_LITERAL_CSTRING("cpu cores")]);
     675           0 :       if (p.Next(t) && t.Type() == Tokenizer::TOKEN_INTEGER &&
     676           0 :           t.AsInteger() <= INT32_MAX) {
     677           0 :         physicalCPUs = static_cast<int>(t.AsInteger());
     678             :       }
     679             :     }
     680             : 
     681             :     {
     682             :       // cacheSizeL3 from "cache size"
     683           0 :       Tokenizer::Token t;
     684           0 :       Tokenizer p(keyValuePairs[NS_LITERAL_CSTRING("cache size")]);
     685           0 :       if (p.Next(t) && t.Type() == Tokenizer::TOKEN_INTEGER &&
     686           0 :           t.AsInteger() <= INT32_MAX) {
     687           0 :         cacheSizeL3 = static_cast<int>(t.AsInteger());
     688           0 :         if (p.Next(t) && t.Type() == Tokenizer::TOKEN_WORD &&
     689           0 :             t.AsString() != NS_LITERAL_CSTRING("KB")) {
     690             :           // If we get here, there was some text after the cache size value
     691             :           // and that text was not KB.  For now, just don't report the
     692             :           // L3 cache.
     693           0 :           cacheSizeL3 = -1;
     694             :         }
     695             :       }
     696             :     }
     697             :   }
     698             : 
     699             :   {
     700             :     // Get cpuSpeed from another file.
     701           0 :     std::ifstream input("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq");
     702           0 :     std::string line;
     703           0 :     if (getline(input, line)) {
     704           1 :       Tokenizer::Token t;
     705           1 :       Tokenizer p(line.c_str());
     706           1 :       if (p.Next(t) && t.Type() == Tokenizer::TOKEN_INTEGER &&
     707           1 :           t.AsInteger() <= INT32_MAX) {
     708           1 :         cpuSpeed = static_cast<int>(t.AsInteger()/1000);
     709             :       }
     710             :     }
     711             :   }
     712             : 
     713             :   {
     714             :     // Get cacheSizeL2 from yet another file
     715           0 :     std::ifstream input("/sys/devices/system/cpu/cpu0/cache/index2/size");
     716           0 :     std::string line;
     717           0 :     if (getline(input, line)) {
     718           0 :       Tokenizer::Token t;
     719           0 :       Tokenizer p(line.c_str(), nullptr, "K");
     720           0 :       if (p.Next(t) && t.Type() == Tokenizer::TOKEN_INTEGER &&
     721           0 :           t.AsInteger() <= INT32_MAX) {
     722           0 :         cacheSizeL2 = static_cast<int>(t.AsInteger());
     723             :       }
     724             :     }
     725             :   }
     726             : 
     727           0 :   SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors());
     728             : #else
     729             :   SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors());
     730             : #endif
     731             : 
     732             :   if (virtualMem) SetUint64Property(NS_LITERAL_STRING("virtualmemsize"), virtualMem);
     733           0 :   if (cpuSpeed >= 0) SetInt32Property(NS_LITERAL_STRING("cpuspeed"), cpuSpeed);
     734           0 :   if (!cpuVendor.IsEmpty()) SetPropertyAsACString(NS_LITERAL_STRING("cpuvendor"), cpuVendor);
     735           0 :   if (cpuFamily >= 0) SetInt32Property(NS_LITERAL_STRING("cpufamily"), cpuFamily);
     736           0 :   if (cpuModel >= 0) SetInt32Property(NS_LITERAL_STRING("cpumodel"), cpuModel);
     737           0 :   if (cpuStepping >= 0) SetInt32Property(NS_LITERAL_STRING("cpustepping"), cpuStepping);
     738             : 
     739             :   if (logicalCPUs >= 0) SetInt32Property(NS_LITERAL_STRING("cpucount"), logicalCPUs);
     740           0 :   if (physicalCPUs >= 0) SetInt32Property(NS_LITERAL_STRING("cpucores"), physicalCPUs);
     741             : 
     742           0 :   if (cacheSizeL2 >= 0) SetInt32Property(NS_LITERAL_STRING("cpucachel2"), cacheSizeL2);
     743           0 :   if (cacheSizeL3 >= 0) SetInt32Property(NS_LITERAL_STRING("cpucachel3"), cacheSizeL3);
     744             : 
     745           0 :   for (uint32_t i = 0; i < ArrayLength(cpuPropItems); i++) {
     746           0 :     rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16(cpuPropItems[i].name),
     747           0 :                            cpuPropItems[i].propfun());
     748           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     749             :       return rv;
     750             :     }
     751             :   }
     752             : 
     753             : #ifdef XP_WIN
     754             :   BOOL isWow64;
     755             :   BOOL gotWow64Value = IsWow64Process(GetCurrentProcess(), &isWow64);
     756             :   NS_WARNING_ASSERTION(gotWow64Value, "IsWow64Process failed");
     757             :   if (gotWow64Value) {
     758             :     rv = SetPropertyAsBool(NS_LITERAL_STRING("isWow64"), !!isWow64);
     759             :     if (NS_WARN_IF(NS_FAILED(rv))) {
     760             :       return rv;
     761             :     }
     762             :   }
     763             :   if (NS_FAILED(GetProfileHDDInfo())) {
     764             :     // We might have been called before profile-do-change. We'll observe that
     765             :     // event so that we can fill this in later.
     766             :     nsCOMPtr<nsIObserverService> obsService =
     767             :       do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
     768             :     if (NS_WARN_IF(NS_FAILED(rv))) {
     769             :       return rv;
     770             :     }
     771             :     rv = obsService->AddObserver(this, "profile-do-change", false);
     772             :     if (NS_FAILED(rv)) {
     773             :       return rv;
     774             :     }
     775             :   }
     776             :   nsAutoCString hddModel, hddRevision;
     777             :   if (NS_SUCCEEDED(GetHDDInfo(NS_GRE_DIR, hddModel, hddRevision))) {
     778             :     rv = SetPropertyAsACString(NS_LITERAL_STRING("binHDDModel"), hddModel);
     779             :     NS_ENSURE_SUCCESS(rv, rv);
     780             :     rv = SetPropertyAsACString(NS_LITERAL_STRING("binHDDRevision"),
     781             :                                hddRevision);
     782             :     NS_ENSURE_SUCCESS(rv, rv);
     783             :   }
     784             :   if (NS_SUCCEEDED(GetHDDInfo(NS_WIN_WINDOWS_DIR, hddModel, hddRevision))) {
     785             :     rv = SetPropertyAsACString(NS_LITERAL_STRING("winHDDModel"), hddModel);
     786             :     NS_ENSURE_SUCCESS(rv, rv);
     787             :     rv = SetPropertyAsACString(NS_LITERAL_STRING("winHDDRevision"),
     788             :                                hddRevision);
     789             :     NS_ENSURE_SUCCESS(rv, rv);
     790             :   }
     791             : 
     792             :   nsAutoString countryCode;
     793             :   if (NS_SUCCEEDED(GetCountryCode(countryCode))) {
     794             :     rv = SetPropertyAsAString(NS_LITERAL_STRING("countryCode"), countryCode);
     795             :     NS_ENSURE_SUCCESS(rv, rv);
     796             :   }
     797             : 
     798             :   uint32_t installYear = 0;
     799             :   if (NS_SUCCEEDED(GetInstallYear(installYear))) {
     800             :     rv = SetPropertyAsUint32(NS_LITERAL_STRING("installYear"), installYear);
     801             :     if (NS_WARN_IF(NS_FAILED(rv))) {
     802             :       return rv;
     803             :     }
     804             :   }
     805             : 
     806             : #ifndef __MINGW32__
     807             :   nsAutoString avInfo, antiSpyInfo, firewallInfo;
     808             :   if (NS_SUCCEEDED(GetWindowsSecurityCenterInfo(avInfo, antiSpyInfo,
     809             :                                                 firewallInfo))) {
     810             :     if (!avInfo.IsEmpty()) {
     811             :       rv = SetPropertyAsAString(NS_LITERAL_STRING("registeredAntiVirus"),
     812             :                                 avInfo);
     813             :       if (NS_WARN_IF(NS_FAILED(rv))) {
     814             :         return rv;
     815             :       }
     816             :     }
     817             : 
     818             :     if (!antiSpyInfo.IsEmpty()) {
     819             :       rv = SetPropertyAsAString(NS_LITERAL_STRING("registeredAntiSpyware"),
     820             :                                 antiSpyInfo);
     821             :       if (NS_WARN_IF(NS_FAILED(rv))) {
     822             :         return rv;
     823             :       }
     824             :     }
     825             : 
     826             :     if (!firewallInfo.IsEmpty()) {
     827             :       rv = SetPropertyAsAString(NS_LITERAL_STRING("registeredFirewall"),
     828             :                                 firewallInfo);
     829             :       if (NS_WARN_IF(NS_FAILED(rv))) {
     830             :         return rv;
     831             :       }
     832             :     }
     833             :   }
     834             : #endif // __MINGW32__
     835             : #endif
     836             : 
     837             : #if defined(XP_MACOSX)
     838             :   nsAutoString countryCode;
     839             :   if (NS_SUCCEEDED(GetSelectedCityInfo(countryCode))) {
     840             :     rv = SetPropertyAsAString(NS_LITERAL_STRING("countryCode"), countryCode);
     841             :     NS_ENSURE_SUCCESS(rv, rv);
     842             :   }
     843             : 
     844             :   nsAutoCString modelId;
     845             :   if (NS_SUCCEEDED(GetAppleModelId(modelId))) {
     846             :     rv = SetPropertyAsACString(NS_LITERAL_STRING("appleModelId"), modelId);
     847             :     NS_ENSURE_SUCCESS(rv, rv);
     848             :   }
     849             : #endif
     850             : 
     851             : #if defined(MOZ_WIDGET_GTK)
     852             :   // This must be done here because NSPR can only separate OS's when compiled, not libraries.
     853             :   // 64 bytes is going to be well enough for "GTK " followed by 3 integers
     854             :   // separated with dots.
     855             :   char gtkver[64];
     856           0 :   ssize_t gtkver_len = 0;
     857             : 
     858             :   if (gtkver_len <= 0) {
     859           0 :     gtkver_len = SprintfLiteral(gtkver, "GTK %u.%u.%u", gtk_major_version,
     860             :                                 gtk_minor_version, gtk_micro_version);
     861             :   }
     862             : 
     863           0 :   nsAutoCString secondaryLibrary;
     864           0 :   if (gtkver_len > 0 && gtkver_len < int(sizeof(gtkver))) {
     865           0 :     secondaryLibrary.Append(nsDependentCSubstring(gtkver, gtkver_len));
     866             :   }
     867             : 
     868           0 :   void* libpulse = dlopen("libpulse.so.0", RTLD_LAZY);
     869           0 :   const char* libpulseVersion = "not-available";
     870           0 :   if (libpulse) {
     871             :     auto pa_get_library_version = reinterpret_cast<const char* (*)()>
     872           0 :       (dlsym(libpulse, "pa_get_library_version"));
     873             : 
     874           0 :     if (pa_get_library_version) {
     875           0 :       libpulseVersion = pa_get_library_version();
     876             :     }
     877             :   }
     878             : 
     879           0 :   secondaryLibrary.AppendPrintf(",libpulse %s", libpulseVersion);
     880             : 
     881           0 :   if (libpulse) {
     882           0 :     dlclose(libpulse);
     883             :   }
     884             : 
     885           0 :   rv = SetPropertyAsACString(NS_LITERAL_STRING("secondaryLibrary"),
     886           0 :                              secondaryLibrary);
     887           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     888             :     return rv;
     889             :   }
     890             : #endif
     891             : 
     892             : #ifdef MOZ_WIDGET_ANDROID
     893             :   AndroidSystemInfo info;
     894             :   if (XRE_IsContentProcess()) {
     895             :     dom::ContentChild* child = dom::ContentChild::GetSingleton();
     896             :     if (child) {
     897             :       child->SendGetAndroidSystemInfo(&info);
     898             :       SetupAndroidInfo(info);
     899             :     }
     900             :   } else {
     901             :     GetAndroidSystemInfo(&info);
     902             :     SetupAndroidInfo(info);
     903             :   }
     904             : #endif
     905             : 
     906             : #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
     907             :   SandboxInfo sandInfo = SandboxInfo::Get();
     908             : 
     909             :   SetPropertyAsBool(NS_LITERAL_STRING("hasSeccompBPF"),
     910             :                     sandInfo.Test(SandboxInfo::kHasSeccompBPF));
     911             :   SetPropertyAsBool(NS_LITERAL_STRING("hasSeccompTSync"),
     912             :                     sandInfo.Test(SandboxInfo::kHasSeccompTSync));
     913             :   SetPropertyAsBool(NS_LITERAL_STRING("hasUserNamespaces"),
     914             :                     sandInfo.Test(SandboxInfo::kHasUserNamespaces));
     915             :   SetPropertyAsBool(NS_LITERAL_STRING("hasPrivilegedUserNamespaces"),
     916             :                     sandInfo.Test(SandboxInfo::kHasPrivilegedUserNamespaces));
     917             : 
     918             :   if (sandInfo.Test(SandboxInfo::kEnabledForContent)) {
     919             :     SetPropertyAsBool(NS_LITERAL_STRING("canSandboxContent"),
     920             :                       sandInfo.CanSandboxContent());
     921             :   }
     922             : 
     923             :   if (sandInfo.Test(SandboxInfo::kEnabledForMedia)) {
     924             :     SetPropertyAsBool(NS_LITERAL_STRING("canSandboxMedia"),
     925             :                       sandInfo.CanSandboxMedia());
     926             :   }
     927             : #endif // XP_LINUX && MOZ_SANDBOX
     928             : 
     929           0 :   return NS_OK;
     930             : }
     931             : 
     932             : #ifdef MOZ_WIDGET_ANDROID
     933             : // Prerelease versions of Android use a letter instead of version numbers.
     934             : // Unfortunately this breaks websites due to the user agent.
     935             : // Chrome works around this by hardcoding an Android version when a
     936             : // numeric version can't be obtained. We're doing the same.
     937             : // This version will need to be updated whenever there is a new official
     938             : // Android release.
     939             : // See: https://cs.chromium.org/chromium/src/base/sys_info_android.cc?l=61
     940             : #define DEFAULT_ANDROID_VERSION "6.0.99"
     941             : 
     942             : /* static */
     943             : void
     944             : nsSystemInfo::GetAndroidSystemInfo(AndroidSystemInfo* aInfo)
     945             : {
     946             :   MOZ_ASSERT(XRE_IsParentProcess());
     947             : 
     948             :   if (!mozilla::AndroidBridge::Bridge()) {
     949             :     aInfo->sdk_version() = 0;
     950             :     return;
     951             :   }
     952             : 
     953             :   nsAutoString str;
     954             :   if (mozilla::AndroidBridge::Bridge()->GetStaticStringField(
     955             :       "android/os/Build", "MODEL", str)) {
     956             :     aInfo->device() = str;
     957             :   }
     958             :   if (mozilla::AndroidBridge::Bridge()->GetStaticStringField(
     959             :       "android/os/Build", "MANUFACTURER", str)) {
     960             :     aInfo->manufacturer() = str;
     961             :   }
     962             :   if (mozilla::AndroidBridge::Bridge()->GetStaticStringField(
     963             :       "android/os/Build$VERSION", "RELEASE", str)) {
     964             :     int major_version;
     965             :     int minor_version;
     966             :     int bugfix_version;
     967             :     int num_read = sscanf(NS_ConvertUTF16toUTF8(str).get(), "%d.%d.%d", &major_version, &minor_version, &bugfix_version);
     968             :     if (num_read == 0) {
     969             :       aInfo->release_version() = NS_LITERAL_STRING(DEFAULT_ANDROID_VERSION);
     970             :     } else {
     971             :       aInfo->release_version() = str;
     972             :     }
     973             :   }
     974             :   if (mozilla::AndroidBridge::Bridge()->GetStaticStringField(
     975             :       "android/os/Build", "HARDWARE", str)) {
     976             :     aInfo->hardware() = str;
     977             :   }
     978             :   int32_t sdk_version;
     979             :   if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField(
     980             :       "android/os/Build$VERSION", "SDK_INT", &sdk_version)) {
     981             :     sdk_version = 0;
     982             :   }
     983             :   aInfo->sdk_version() = sdk_version;
     984             :   aInfo->isTablet() = java::GeckoAppShell::IsTablet();
     985             : }
     986             : 
     987             : void
     988             : nsSystemInfo::SetupAndroidInfo(const AndroidSystemInfo& aInfo)
     989             : {
     990             :   if (!aInfo.device().IsEmpty()) {
     991             :     SetPropertyAsAString(NS_LITERAL_STRING("device"), aInfo.device());
     992             :   }
     993             :   if (!aInfo.manufacturer().IsEmpty()) {
     994             :     SetPropertyAsAString(NS_LITERAL_STRING("manufacturer"), aInfo.manufacturer());
     995             :   }
     996             :   if (!aInfo.release_version().IsEmpty()) {
     997             :     SetPropertyAsAString(NS_LITERAL_STRING("release_version"), aInfo.release_version());
     998             :   }
     999             :   SetPropertyAsBool(NS_LITERAL_STRING("tablet"), aInfo.isTablet());
    1000             :   // NSPR "version" is the kernel version. For Android we want the Android version.
    1001             :   // Rename SDK version to version and put the kernel version into kernel_version.
    1002             :   nsAutoString str;
    1003             :   nsresult rv = GetPropertyAsAString(NS_LITERAL_STRING("version"), str);
    1004             :   if (NS_SUCCEEDED(rv)) {
    1005             :     SetPropertyAsAString(NS_LITERAL_STRING("kernel_version"), str);
    1006             :   }
    1007             :   // When AndroidBridge is not available (eg. in xpcshell tests), sdk_version is 0.
    1008             :   if (aInfo.sdk_version() != 0) {
    1009             :     android_sdk_version = aInfo.sdk_version();
    1010             :     if (android_sdk_version >= 8 && !aInfo.hardware().IsEmpty()) {
    1011             :       SetPropertyAsAString(NS_LITERAL_STRING("hardware"), aInfo.hardware());
    1012             :     }
    1013             :     SetPropertyAsInt32(NS_LITERAL_STRING("version"), android_sdk_version);
    1014             :   }
    1015             : }
    1016             : #endif // MOZ_WIDGET_ANDROID
    1017             : 
    1018             : void
    1019           0 : nsSystemInfo::SetInt32Property(const nsAString& aPropertyName,
    1020             :                                const int32_t aValue)
    1021             : {
    1022           0 :   NS_WARNING_ASSERTION(aValue > 0, "Unable to read system value");
    1023           0 :   if (aValue > 0) {
    1024             : #ifdef DEBUG
    1025             :     nsresult rv =
    1026             : #endif
    1027           0 :       SetPropertyAsInt32(aPropertyName, aValue);
    1028           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Unable to set property");
    1029             :   }
    1030           0 : }
    1031             : 
    1032             : void
    1033           0 : nsSystemInfo::SetUint32Property(const nsAString& aPropertyName,
    1034             :                                 const uint32_t aValue)
    1035             : {
    1036             :   // Only one property is currently set via this function.
    1037             :   // It may legitimately be zero.
    1038             : #ifdef DEBUG
    1039             :   nsresult rv =
    1040             : #endif
    1041           0 :     SetPropertyAsUint32(aPropertyName, aValue);
    1042           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Unable to set property");
    1043           0 : }
    1044             : 
    1045             : void
    1046           0 : nsSystemInfo::SetUint64Property(const nsAString& aPropertyName,
    1047             :                                 const uint64_t aValue)
    1048             : {
    1049           0 :   NS_WARNING_ASSERTION(aValue > 0, "Unable to read system value");
    1050           0 :   if (aValue > 0) {
    1051             : #ifdef DEBUG
    1052             :     nsresult rv =
    1053             : #endif
    1054           0 :       SetPropertyAsUint64(aPropertyName, aValue);
    1055           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Unable to set property");
    1056             :   }
    1057           0 : }
    1058             : 
    1059             : #if defined(XP_WIN)
    1060             : NS_IMETHODIMP
    1061             : nsSystemInfo::Observe(nsISupports* aSubject, const char* aTopic,
    1062             :                       const char16_t* aData)
    1063             : {
    1064             :   if (!strcmp(aTopic, "profile-do-change")) {
    1065             :     nsresult rv;
    1066             :     nsCOMPtr<nsIObserverService> obsService =
    1067             :       do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
    1068             :     if (NS_FAILED(rv)) {
    1069             :       return rv;
    1070             :     }
    1071             :     rv = obsService->RemoveObserver(this, "profile-do-change");
    1072             :     if (NS_FAILED(rv)) {
    1073             :       return rv;
    1074             :     }
    1075             :     return GetProfileHDDInfo();
    1076             :   }
    1077             :   return NS_OK;
    1078             : }
    1079             : 
    1080             : nsresult
    1081             : nsSystemInfo::GetProfileHDDInfo()
    1082             : {
    1083             :   nsAutoCString hddModel, hddRevision;
    1084             :   nsresult rv = GetHDDInfo(NS_APP_USER_PROFILE_50_DIR, hddModel, hddRevision);
    1085             :   if (NS_FAILED(rv)) {
    1086             :     return rv;
    1087             :   }
    1088             :   rv = SetPropertyAsACString(NS_LITERAL_STRING("profileHDDModel"), hddModel);
    1089             :   if (NS_FAILED(rv)) {
    1090             :     return rv;
    1091             :   }
    1092             :   rv = SetPropertyAsACString(NS_LITERAL_STRING("profileHDDRevision"),
    1093             :                              hddRevision);
    1094             :   return rv;
    1095             : }
    1096             : 
    1097             : NS_IMPL_ISUPPORTS_INHERITED(nsSystemInfo, nsHashPropertyBag, nsIObserver)
    1098             : #endif // defined(XP_WIN)
    1099             : 

Generated by: LCOV version 1.13-14-ga5dd952