system.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const { Cc, Ci, Cu } = require("chrome");
  6. const { Task } = require("devtools/shared/task");
  7. loader.lazyRequireGetter(this, "Services");
  8. loader.lazyRequireGetter(this, "promise");
  9. loader.lazyRequireGetter(this, "defer", "devtools/shared/defer");
  10. loader.lazyRequireGetter(this, "OS", "resource://gre/modules/commonjs/node/os.js");
  11. loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
  12. loader.lazyRequireGetter(this, "AppConstants",
  13. "resource://gre/modules/AppConstants.jsm", true);
  14. loader.lazyGetter(this, "screenManager", () => {
  15. return Cc["@mozilla.org/gfx/screenmanager;1"].getService(Ci.nsIScreenManager);
  16. });
  17. loader.lazyGetter(this, "oscpu", () => {
  18. return Cc["@mozilla.org/network/protocol;1?name=http"]
  19. .getService(Ci.nsIHttpProtocolHandler).oscpu;
  20. });
  21. const APP_MAP = {
  22. "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": "firefox",
  23. "{3550f703-e582-4d05-9a08-453d09bdfdc6}": "thunderbird",
  24. "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}": "seamonkey",
  25. "{718e30fb-e89b-41dd-9da7-e25a45638b28}": "sunbird",
  26. "{3c2e2abc-06d4-11e1-ac3b-374f68613e61}": "b2g",
  27. "{aa3c5121-dab2-40e2-81ca-7ea25febc110}": "mobile/android",
  28. "{a23983c0-fd0e-11dc-95ff-0800200c9a66}": "mobile/xul"
  29. };
  30. var CACHED_INFO = null;
  31. function* getSystemInfo() {
  32. if (CACHED_INFO) {
  33. return CACHED_INFO;
  34. }
  35. let appInfo = Services.appinfo;
  36. let win = Services.wm.getMostRecentWindow(DebuggerServer.chromeWindowType);
  37. let [processor, compiler] = appInfo.XPCOMABI.split("-");
  38. let dpi,
  39. useragent,
  40. width,
  41. height,
  42. physicalWidth,
  43. physicalHeight,
  44. os,
  45. brandName;
  46. let appid = appInfo.ID;
  47. let apptype = APP_MAP[appid];
  48. let geckoVersion = appInfo.platformVersion;
  49. let hardware = "unknown";
  50. let version = "unknown";
  51. // B2G specific
  52. if (apptype === "b2g") {
  53. os = "B2G";
  54. // `getSetting` does not work in child processes on b2g.
  55. // TODO bug 1205797, make this work in child processes.
  56. try {
  57. hardware = yield exports.getSetting("deviceinfo.hardware");
  58. version = yield exports.getSetting("deviceinfo.os");
  59. } catch (e) {
  60. }
  61. }
  62. // Not B2G
  63. else {
  64. os = appInfo.OS;
  65. version = appInfo.version;
  66. }
  67. let bundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
  68. if (bundle) {
  69. brandName = bundle.GetStringFromName("brandFullName");
  70. } else {
  71. brandName = null;
  72. }
  73. if (win) {
  74. let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
  75. dpi = utils.displayDPI;
  76. useragent = win.navigator.userAgent;
  77. width = win.screen.width;
  78. height = win.screen.height;
  79. physicalWidth = win.screen.width * win.devicePixelRatio;
  80. physicalHeight = win.screen.height * win.devicePixelRatio;
  81. }
  82. let info = {
  83. /**
  84. * Information from nsIXULAppInfo, regarding
  85. * the application itself.
  86. */
  87. // The XUL application's UUID.
  88. appid,
  89. // Name of the app, "firefox", "thunderbird", etc., listed in APP_MAP
  90. apptype,
  91. // Mixed-case or empty string of vendor, like "Mozilla"
  92. vendor: appInfo.vendor,
  93. // Name of the application, like "Firefox", "Thunderbird".
  94. name: appInfo.name,
  95. // The application's version, for example "0.8.0+" or "3.7a1pre".
  96. // Typically, the version of Firefox, for example.
  97. // It is different than the version of Gecko or the XULRunner platform.
  98. // On B2G, this is the Gaia version.
  99. version,
  100. // The application's build ID/date, for example "2004051604".
  101. appbuildid: appInfo.appBuildID,
  102. // The application's changeset.
  103. changeset: exports.getAppIniString("App", "SourceStamp"),
  104. // The build ID/date of Gecko and the XULRunner platform.
  105. platformbuildid: appInfo.platformBuildID,
  106. geckobuildid: appInfo.platformBuildID,
  107. // The version of Gecko or XULRunner platform, for example "1.8.1.19" or
  108. // "1.9.3pre". In "Firefox 3.7 alpha 1" the application version is "3.7a1pre"
  109. // while the platform version is "1.9.3pre"
  110. platformversion: geckoVersion,
  111. geckoversion: geckoVersion,
  112. // Locale used in this build
  113. locale: Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),
  114. /**
  115. * Information regarding the operating system.
  116. */
  117. // Returns the endianness of the architecture: either "LE" or "BE"
  118. endianness: OS.endianness(),
  119. // Returns the hostname of the machine
  120. hostname: OS.hostname(),
  121. // Name of the OS type. Typically the same as `uname -s`. Possible values:
  122. // https://developer.mozilla.org/en/OS_TARGET
  123. // Also may be "B2G".
  124. os,
  125. platform: os,
  126. // hardware and version info from `deviceinfo.hardware`
  127. // and `deviceinfo.os`.
  128. hardware,
  129. // Type of process architecture running:
  130. // "arm", "ia32", "x86", "x64"
  131. // Alias to both `arch` and `processor` for node/deviceactor compat
  132. arch: processor,
  133. processor,
  134. // Name of compiler used for build:
  135. // `'msvc', 'n32', 'gcc2', 'gcc3', 'sunc', 'ibmc'...`
  136. compiler,
  137. // Location for the current profile
  138. profile: getProfileLocation(),
  139. // Update channel
  140. channel: AppConstants.MOZ_UPDATE_CHANNEL,
  141. dpi,
  142. useragent,
  143. width,
  144. height,
  145. physicalWidth,
  146. physicalHeight,
  147. brandName,
  148. };
  149. CACHED_INFO = info;
  150. return info;
  151. }
  152. function getProfileLocation() {
  153. // In child processes, we cannot access the profile location.
  154. try {
  155. let profd = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
  156. let profservice = Cc["@mozilla.org/toolkit/profile-service;1"].getService(Ci.nsIToolkitProfileService);
  157. var profiles = profservice.profiles;
  158. while (profiles.hasMoreElements()) {
  159. let profile = profiles.getNext().QueryInterface(Ci.nsIToolkitProfile);
  160. if (profile.rootDir.path == profd.path) {
  161. return profile = profile.name;
  162. }
  163. }
  164. return profd.leafName;
  165. } catch (e) {
  166. return "";
  167. }
  168. }
  169. function getAppIniString(section, key) {
  170. let inifile = Services.dirsvc.get("GreD", Ci.nsIFile);
  171. inifile.append("application.ini");
  172. if (!inifile.exists()) {
  173. inifile = Services.dirsvc.get("CurProcD", Ci.nsIFile);
  174. inifile.append("application.ini");
  175. }
  176. if (!inifile.exists()) {
  177. return undefined;
  178. }
  179. let iniParser = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].getService(Ci.nsIINIParserFactory).createINIParser(inifile);
  180. try {
  181. return iniParser.getString(section, key);
  182. } catch (e) {
  183. return undefined;
  184. }
  185. }
  186. /**
  187. * Function for fetching screen dimensions and returning
  188. * an enum for Telemetry.
  189. */
  190. function getScreenDimensions() {
  191. let width = {};
  192. let height = {};
  193. screenManager.primaryScreen.GetRect({}, {}, width, height);
  194. let dims = width.value + "x" + height.value;
  195. if (width.value < 800 || height.value < 600) {
  196. return 0;
  197. }
  198. if (dims === "800x600") {
  199. return 1;
  200. }
  201. if (dims === "1024x768") {
  202. return 2;
  203. }
  204. if (dims === "1280x800") {
  205. return 3;
  206. }
  207. if (dims === "1280x1024") {
  208. return 4;
  209. }
  210. if (dims === "1366x768") {
  211. return 5;
  212. }
  213. if (dims === "1440x900") {
  214. return 6;
  215. }
  216. if (dims === "1920x1080") {
  217. return 7;
  218. }
  219. if (dims === "2560×1440") {
  220. return 8;
  221. }
  222. if (dims === "2560×1600") {
  223. return 9;
  224. }
  225. if (dims === "2880x1800") {
  226. return 10;
  227. }
  228. if (width.value > 2880 || height.value > 1800) {
  229. return 12;
  230. }
  231. // Other dimension such as a VM.
  232. return 11;
  233. }
  234. /**
  235. * Function for fetching OS CPU and returning
  236. * an enum for Telemetry.
  237. */
  238. function getOSCPU() {
  239. if (oscpu.includes("NT 5.1") || oscpu.includes("NT 5.2")) {
  240. return 0;
  241. }
  242. if (oscpu.includes("NT 6.0")) {
  243. return 1;
  244. }
  245. if (oscpu.includes("NT 6.1")) {
  246. return 2;
  247. }
  248. if (oscpu.includes("NT 6.2")) {
  249. return 3;
  250. }
  251. if (oscpu.includes("NT 6.3")) {
  252. return 4;
  253. }
  254. if (oscpu.includes("OS X")) {
  255. return 5;
  256. }
  257. if (oscpu.includes("Linux")) {
  258. return 6;
  259. }
  260. if (oscpu.includes("NT 10.")) {
  261. return 7;
  262. }
  263. // Other OS.
  264. return 12;
  265. }
  266. function getSetting(name) {
  267. let deferred = defer();
  268. if ("@mozilla.org/settingsService;1" in Cc) {
  269. let settingsService;
  270. // settingsService fails in b2g child processes
  271. // TODO bug 1205797, make this work in child processes.
  272. try {
  273. settingsService = Cc["@mozilla.org/settingsService;1"].getService(Ci.nsISettingsService);
  274. } catch (e) {
  275. return promise.reject(e);
  276. }
  277. let req = settingsService.createLock().get(name, {
  278. handle: (name, value) => deferred.resolve(value),
  279. handleError: (error) => deferred.reject(error),
  280. });
  281. } else {
  282. deferred.reject(new Error("No settings service"));
  283. }
  284. return deferred.promise;
  285. }
  286. exports.getSystemInfo = Task.async(getSystemInfo);
  287. exports.getAppIniString = getAppIniString;
  288. exports.getSetting = getSetting;
  289. exports.getScreenDimensions = getScreenDimensions;
  290. exports.getOSCPU = getOSCPU;
  291. exports.constants = AppConstants;