Backed out 2 changesets (bug 1425688) on request from jorgk for breaking the Certificate Manager r=backout a=backout
authorCosmin Sabou <csabou@mozilla.com>
Thu, 28 Dec 2017 15:26:09 +0200
changeset 449226 c2daa4c032b7f23a708a89237940ac8c49bba6cf
parent 449225 d8d0222927b44d384e9caef796ee52372050659e
child 449227 beed8ab0e0f7ca629fd122c09c8dc1ecca12b43c
child 449232 15ea666d32007bbfc3df6bf710aa040a92667180
child 449241 0f453e37e68e87407d6265fd0b9031517604b18b
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout, backout
bugs1425688
milestone59.0a1
backs outf73324a4d03387924eccf434e56a8844e361823a
bd2bf7b7fead94ac8483f811abd26c517c7989da
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 2 changesets (bug 1425688) on request from jorgk for breaking the Certificate Manager r=backout a=backout Backed out changeset f73324a4d033 (bug 1425688) Backed out changeset bd2bf7b7fead (bug 1425688)
.eslintrc.js
security/manager/pki/resources/content/certManager.js
security/manager/pki/resources/content/certViewer.js
security/manager/pki/resources/content/certViewer.xul
security/manager/pki/resources/content/changepassword.js
security/manager/pki/resources/content/clientauthask.js
security/manager/pki/resources/content/deletecert.js
security/manager/pki/resources/content/deletecert.xul
security/manager/pki/resources/content/device_manager.js
security/manager/pki/resources/content/downloadcert.js
security/manager/pki/resources/content/downloadcert.xul
security/manager/pki/resources/content/editcacert.js
security/manager/pki/resources/content/exceptionDialog.js
security/manager/pki/resources/content/load_device.js
security/manager/pki/resources/content/pippki.js
security/manager/pki/resources/content/resetpassword.js
security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js
security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html
security/manager/ssl/tests/unit/head_psm.js
security/manager/ssl/tests/unit/test_cert_overrides.js
security/manager/ssl/tests/unit/test_ocsp_stapling.js
security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js
security/manager/ssl/tests/unit/test_pinning.js
security/manager/ssl/tests/unit/test_pkcs11_module.js
security/manager/ssl/tests/unit/test_pkcs11_token.js
security/manager/tools/getHSTSPreloadList.js
security/sandbox/test/browser_content_sandbox_fs.js
security/sandbox/test/browser_content_sandbox_syscalls.js
security/sandbox/test/browser_content_sandbox_utils.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -32,16 +32,17 @@ module.exports = {
       // Browser: Bug 1421379
       "browser/extensions/shield-recipe-client/test/browser/head.js",
       "browser/modules/offlineAppCache.jsm",
       "devtools/**",
       "dom/indexedDB/**",
       "dom/media/**",
       "extensions/pref/**",
       "mobile/android/**",
+      "security/**",
       "testing/**",
       "tools/profiler/**",
     ],
     "rules": {
       "mozilla/use-services": "off",
     }
   }]
 };
--- a/security/manager/pki/resources/content/certManager.js
+++ b/security/manager/pki/resources/content/certManager.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 /* import-globals-from pippki.js */
 "use strict";
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
 const nsIFilePicker = Components.interfaces.nsIFilePicker;
 const nsFilePicker = "@mozilla.org/filepicker;1";
 const nsIX509CertDB = Components.interfaces.nsIX509CertDB;
 const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
 const nsIX509Cert = Components.interfaces.nsIX509Cert;
 const nsICertTree = Components.interfaces.nsICertTree;
 const nsCertTree = "@mozilla.org/security/nsCertTree;1";
 
--- a/security/manager/pki/resources/content/certViewer.js
+++ b/security/manager/pki/resources/content/certViewer.js
@@ -1,36 +1,43 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* import-globals-from pippki.js */
 "use strict";
 
 /**
  * @file Implements functionality for certViewer.xul and its tabs certDump.xul
  *       and viewCertDetails.xul: a dialog that allows various attributes of a
  *       certificate to be viewed.
  * @argument {nsISupports} window.arguments[0]
  *           The cert to view, queryable to nsIX509Cert.
  */
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
 const nsIX509Cert = Ci.nsIX509Cert;
 const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
 const nsIX509CertDB = Ci.nsIX509CertDB;
 const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
 const nsIPK11TokenDB = Ci.nsIPK11TokenDB;
 const nsIASN1Object = Ci.nsIASN1Object;
 const nsIASN1Sequence = Ci.nsIASN1Sequence;
 const nsIASN1PrintableItem = Ci.nsIASN1PrintableItem;
 const nsIASN1Tree = Ci.nsIASN1Tree;
 const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1";
 
 var bundle;
 
+function doPrompt(msg) {
+  let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+    getService(Components.interfaces.nsIPromptService);
+  prompts.alert(window, null, msg);
+}
+
 /**
  * Fills out the "Certificate Hierarchy" tree of the cert viewer "Details" tab.
  *
  * @param {tree} node
  *        Parent tree node to append to.
  * @param {Array} chain
  *        An array of nsIX509Cert where cert n is issued by cert n + 1.
  */
@@ -352,17 +359,19 @@ function DisplayGeneralDataFromCert(cert
   addAttributeFromCert("issuerorgunit", cert.issuerOrganizationUnit);
 }
 
 function updateCertDump() {
   var asn1Tree = document.getElementById("prettyDumpTree")
           .view.QueryInterface(nsIASN1Tree);
 
   var tree = document.getElementById("treesetDump");
-  if (tree.currentIndex >= 0) {
+  if (tree.currentIndex < 0) {
+    doPrompt("No items are selected."); // This should never happen.
+  } else {
     var item = tree.contentView.getItemAtIndex(tree.currentIndex);
     var dbKey = item.firstChild.firstChild.getAttribute("display");
     //  Get the cert from the cert database
     var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB);
     var cert = certdb.findCertByDBKey(dbKey);
     asn1Tree.loadASN1Structure(cert.ASN1Structure);
   }
   displaySelected();
--- a/security/manager/pki/resources/content/certViewer.xul
+++ b/security/manager/pki/resources/content/certViewer.xul
@@ -15,19 +15,19 @@
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   buttons="accept"
   buttonlabelaccept="&certmgr.close.label;"
   buttonaccesskeyaccept="&certmgr.close.accesskey;"
   onload="setWindowName();">
 
 <stringbundle id="pippki_bundle" src="chrome://pippki/locale/pippki.properties"/>
 
-<script type="application/javascript" src="chrome://pippki/content/pippki.js"/>
 <script type="application/javascript"
         src="chrome://pippki/content/certViewer.js"/>
+<script type="application/javascript" src="chrome://pippki/content/pippki.js"/>
 
   <tabbox flex="1">
     <tabs>
       <tab id="general_tab" label="&certmgr.detail.general_tab.title;"
            accesskey="&certmgr.detail.general_tab.accesskey;"/>
       <tab id="prettyprint_tab" label="&certmgr.detail.prettyprint_tab.title;"
            accesskey="&certmgr.detail.prettyprint_tab.accesskey;"/>
     </tabs>
--- a/security/manager/pki/resources/content/changepassword.js
+++ b/security/manager/pki/resources/content/changepassword.js
@@ -1,28 +1,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
 const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
 const nsIPKCS11ModuleDB = Components.interfaces.nsIPKCS11ModuleDB;
 const nsIPKCS11Slot = Components.interfaces.nsIPKCS11Slot;
 const nsIPK11Token = Components.interfaces.nsIPK11Token;
 
 var params;
 var tokenName = "";
 var pw1;
 
 function doPrompt(msg) {
-  Services.prompt.alert(window, null, msg);
+  let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+    getService(Components.interfaces.nsIPromptService);
+  prompts.alert(window, null, msg);
 }
 
 function onLoad() {
   document.documentElement.getButton("accept").disabled = true;
 
   pw1 = document.getElementById("pw1");
   params = window.arguments[0].QueryInterface(Ci.nsIDialogParamBlock);
   tokenName = params.GetString(1);
--- a/security/manager/pki/resources/content/clientauthask.js
+++ b/security/manager/pki/resources/content/clientauthask.js
@@ -34,16 +34,20 @@
  * @property {Boolean} rememberSelection
  *           Set to true if the user wanted their cert selection to be
  *           remembered, false otherwise.
  * @property {Number} selectedIndex
  *           The index the chosen cert is at for the given cert list. Undefined
  *           value if |certChosen| is not true.
  */
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
 /**
  * The pippki <stringbundle> element.
  * @type <stringbundle>
  */
 var bundle;
 /**
  * The array of certs the user can choose from.
  * @type nsIArray<nsIX509Cert>
--- a/security/manager/pki/resources/content/deletecert.js
+++ b/security/manager/pki/resources/content/deletecert.js
@@ -18,16 +18,18 @@
 /**
  * @typedef DeleteCertReturnValues
  * @type Object
  * @property {Boolean} deleteConfirmed
  *           Set to true if the user confirmed deletion of the given certs,
  *           false otherwise.
  */
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
 /**
  * Returns the most appropriate string to represent the given nsICertTreeItem.
  * @param {nsICertTreeItem} certTreeItem
  *        The item to represent.
  * @returns {String}
  *          A representative string.
  */
 function certTreeItemToString(certTreeItem) {
--- a/security/manager/pki/resources/content/deletecert.xul
+++ b/security/manager/pki/resources/content/deletecert.xul
@@ -12,17 +12,17 @@
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   onload="onLoad();"
   buttons="accept,cancel"
   ondialogaccept="return onDialogAccept();"
   ondialogcancel="return onDialogCancel();">
 
   <stringbundle id="pippki_bundle" src="chrome://pippki/locale/pippki.properties"/>
 
+  <script type="application/javascript" src="chrome://pippki/content/deletecert.js"/>
   <script type="application/javascript" src="pippki.js" />
-  <script type="application/javascript" src="chrome://pippki/content/deletecert.js"/>
 
   <description id="confirm" style="width: 400px;"/>
   <richlistbox id="certlist" class="box-padded" flex="1"
                style="min-height: 8em; height: 8em; min-width: 35em;"/>
   <description id="impact" style="width: 400px;"/>
 
 </dialog>
--- a/security/manager/pki/resources/content/device_manager.js
+++ b/security/manager/pki/resources/content/device_manager.js
@@ -1,16 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-
 const nsIPKCS11Slot = Components.interfaces.nsIPKCS11Slot;
 const nsIPKCS11Module = Components.interfaces.nsIPKCS11Module;
 const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
 const nsIPKCS11ModuleDB = Components.interfaces.nsIPKCS11ModuleDB;
 const nsIPK11Token = Components.interfaces.nsIPK11Token;
 const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
 const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
 const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
@@ -27,21 +24,25 @@ function LoadModules() {
   RefreshDeviceList();
 }
 
 function getNSSString(name) {
   return document.getElementById("pipnss_bundle").getString(name);
 }
 
 function doPrompt(msg) {
-  Services.prompt.alert(window, null, msg);
+  let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+    getService(Components.interfaces.nsIPromptService);
+  prompts.alert(window, null, msg);
 }
 
 function doConfirm(msg) {
-  return Services.prompt.confirm(window, null, msg);
+  let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+    getService(Components.interfaces.nsIPromptService);
+  return prompts.confirm(window, null, msg);
 }
 
 function RefreshDeviceList() {
   let modules = secmoddb.listModules();
   while (modules.hasMoreElements()) {
     let module = modules.getNext().QueryInterface(nsIPKCS11Module);
     let slotnames = [];
     let slots = module.listSlots();
--- a/security/manager/pki/resources/content/downloadcert.js
+++ b/security/manager/pki/resources/content/downloadcert.js
@@ -24,16 +24,18 @@
  * @property {Boolean} trustForSSL
  *           Set to true if the cert should be trusted for SSL, false otherwise.
  *           Undefined value if |importConfirmed| is not true.
  * @property {Boolean} trustForEmail
  *           Set to true if the cert should be trusted for e-mail, false
  *           otherwise. Undefined value if |importConfirmed| is not true.
  */
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
 /**
  * The cert to potentially import.
  * @type nsIX509Cert
  */
 var gCert;
 
 /**
  * onload() handler.
--- a/security/manager/pki/resources/content/downloadcert.xul
+++ b/security/manager/pki/resources/content/downloadcert.xul
@@ -13,18 +13,18 @@
         style="width: 46em;"
         buttons="accept,cancel"
         ondialogaccept="return onDialogAccept();"
         ondialogcancel="return onDialogCancel();"
         onload="onLoad();">
 
 <stringbundle id="pippki_bundle" src="chrome://pippki/locale/pippki.properties"/>
 
+<script type="application/javascript" src="chrome://pippki/content/downloadcert.js"/>
 <script type="application/javascript" src="chrome://pippki/content/pippki.js"/>
-<script type="application/javascript" src="chrome://pippki/content/downloadcert.js"/>
 
 
   <!--  Let 'em know what they're doing -->
   <vbox>
     <description>&downloadCert.message1;</description>
   </vbox>
 
   <separator/>
--- a/security/manager/pki/resources/content/editcacert.js
+++ b/security/manager/pki/resources/content/editcacert.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 /* import-globals-from pippki.js */
 "use strict";
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
 var gCertDB = Cc["@mozilla.org/security/x509certdb;1"]
                 .getService(Ci.nsIX509CertDB);
 /**
  * Cert to edit the trust of.
  * @type nsIX509Cert
  */
 var gCert;
 
--- a/security/manager/pki/resources/content/exceptionDialog.js
+++ b/security/manager/pki/resources/content/exceptionDialog.js
@@ -44,17 +44,19 @@ badCertListener.prototype = {
   }
 };
 
 function initExceptionDialog() {
   gNeedReset = false;
   gDialog = document.documentElement;
   gBundleBrand = document.getElementById("brand_bundle");
   gPKIBundle = document.getElementById("pippki_bundle");
-  gSecHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
+  gSecHistogram = Components.classes["@mozilla.org/base/telemetry;1"].
+                    getService(Components.interfaces.nsITelemetry).
+                    getHistogramById("SECURITY_UI");
   gNsISecTel = Components.interfaces.nsISecurityUITelemetry;
 
   var brandName = gBundleBrand.getString("brandShortName");
   setText("warningText", gPKIBundle.getFormattedString("addExceptionBrandedWarning2", [brandName]));
   gDialog.getButton("extra1").disabled = true;
 
   var args = window.arguments;
   if (args && args[0]) {
@@ -136,18 +138,20 @@ function checkCert() {
  * @returns {nsIURI}
  *          URI constructed from the information supplied on success, null
  *          otherwise.
  */
 function getURI() {
   // Use fixup service instead of just ioservice's newURI since it's quite
   // likely that the host will be supplied without a protocol prefix, resulting
   // in malformed uri exceptions being thrown.
+  let fus = Components.classes["@mozilla.org/docshell/urifixup;1"]
+                      .getService(Components.interfaces.nsIURIFixup);
   let locationTextBox = document.getElementById("locationTextBox");
-  let uri = Services.uriFixup.createFixupURI(locationTextBox.value, 0);
+  let uri = fus.createFixupURI(locationTextBox.value, 0);
 
   if (!uri) {
     return null;
   }
 
   if (uri.scheme == "http") {
     uri.scheme = "https";
   }
@@ -255,17 +259,19 @@ function updateCertStatus() {
       document.getElementById("permanent").disabled = true;
     }
 
     // We're done checking the certificate, so allow the user to check it again.
     document.getElementById("checkCertButton").disabled = false;
     document.getElementById("viewCertButton").disabled = false;
 
     // Notify observers about the availability of the certificate
-    Services.obs.notifyObservers(null, "cert-exception-ui-ready");
+    Components.classes["@mozilla.org/observer-service;1"]
+              .getService(Components.interfaces.nsIObserverService)
+              .notifyObservers(null, "cert-exception-ui-ready");
   } else if (gChecking) {
     shortDesc = "addExceptionCheckingShort";
     longDesc  = "addExceptionCheckingLong2";
     // We're checking the certificate, so we disable the Get Certificate
     // button to make sure that the user can't interrupt the process and
     // trigger another certificate fetch.
     document.getElementById("checkCertButton").disabled = true;
     document.getElementById("viewCertButton").disabled = true;
--- a/security/manager/pki/resources/content/load_device.js
+++ b/security/manager/pki/resources/content/load_device.js
@@ -4,16 +4,20 @@
 /* import-globals-from pippki.js */
 "use strict";
 
 /**
  * @file Implements the functionality of load_device.xul: a dialog that allows
  *       a PKCS #11 module to be loaded into Firefox.
  */
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
 function onBrowseBtnPress() {
   let bundle = document.getElementById("pippki_bundle");
   let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
   fp.init(window, bundle.getString("loadPK11ModuleFilePickerTitle"),
           Ci.nsIFilePicker.modeOpen);
   fp.appendFilters(Ci.nsIFilePicker.filterAll);
   fp.open(rv => {
     if (rv == Ci.nsIFilePicker.returnOK) {
--- a/security/manager/pki/resources/content/pippki.js
+++ b/security/manager/pki/resources/content/pippki.js
@@ -5,19 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 /*
  * These are helper functions to be included
  * pippki UI js files.
  */
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-
 function setText(id, value) {
   let element = document.getElementById(id);
   if (!element) {
     return;
   }
   if (element.hasChildNodes()) {
     element.firstChild.remove();
   }
@@ -62,19 +59,16 @@ function getPEMString(cert) {
   // (as specified in RFC 1421).
   var wrapped = derb64.replace(/(\S{64}(?!$))/g, "$1\r\n");
   return "-----BEGIN CERTIFICATE-----\r\n"
          + wrapped
          + "\r\n-----END CERTIFICATE-----\r\n";
 }
 
 function alertPromptService(title, message) {
-  // XXX Bug 1425832 - Using Services.prompt here causes tests to report memory
-  // leaks.
-  // eslint-disable-next-line mozilla/use-services
   var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
            getService(Components.interfaces.nsIPromptService);
   ps.alert(window, title, message);
 }
 
 const DEFAULT_CERT_EXTENSION = "crt";
 
 /**
--- a/security/manager/pki/resources/content/resetpassword.js
+++ b/security/manager/pki/resources/content/resetpassword.js
@@ -6,17 +6,19 @@
 
 function resetPassword() {
   var pk11db = Components.classes["@mozilla.org/security/pk11tokendb;1"]
                                  .getService(Components.interfaces.nsIPK11TokenDB);
   var token = pk11db.getInternalKeyToken();
   token.reset();
 
   try {
-    Services.logins.removeAllLogins();
+    var loginManager = Components.classes["@mozilla.org/login-manager;1"].
+                       getService(Components.interfaces.nsILoginManager);
+    loginManager.removeAllLogins();
   } catch (e) {
   }
 
   var bundle = document.getElementById("pippki_bundle");
   var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
   promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
   if (promptService && bundle) {
     promptService.alert(window,
--- a/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js
@@ -1,17 +1,16 @@
 // Any copyright is dedicated to the Public Domain.
 // http://creativecommons.org/publicdomain/zero/1.0/
 "use strict";
 
 // Tests the dialog used for loading PKCS #11 modules.
 
 const { MockRegistrar } =
   Cu.import("resource://testing-common/MockRegistrar.jsm", {});
-const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 const gMockPKCS11ModuleDB = {
   addModuleCallCount: 0,
   expectedLibPath: "",
   expectedModuleName: "",
   throwOnAddModule: false,
 
   addModule(moduleName, libraryFullPath, cryptoMechanismFlags, cipherFlags) {
@@ -91,17 +90,19 @@ var gMockPKCS11CID =
                          gMockPKCS11ModuleDB);
 var gMockPromptServiceCID =
   MockRegistrar.register("@mozilla.org/embedcomp/prompt-service;1",
                          gMockPromptService);
 
 var gMockFilePicker = SpecialPowers.MockFilePicker;
 gMockFilePicker.init(window);
 
-var gTempFile = Services.dirsvc.get("TmpD", Ci.nsIFile);
+var gTempFile = Cc["@mozilla.org/file/directory_service;1"]
+                  .getService(Ci.nsIProperties)
+                  .get("TmpD", Ci.nsIFile);
 gTempFile.append("browser_loadPKCS11Module_ui-fakeModule");
 
 registerCleanupFunction(() => {
   gMockFilePicker.cleanup();
   MockRegistrar.unregister(gMockPKCS11CID);
   MockRegistrar.unregister(gMockPromptServiceCID);
 });
 
--- a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html
+++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html
@@ -15,33 +15,36 @@
   // We want to start this test from an insecure context
   loadAsInsecure = true;
   // We don't want to go through the navigation back/forward test
   bypassNavigationTest = true;
 
   function runTest() {
     let script = SpecialPowers.loadChromeScript(function() {
       const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-      const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
       // Force download to be w/o user assistance for our testing mime type
       const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
       let handlerInfo =
         mimeSvc.getFromTypeAndExtension("application/x-auto-download", "auto");
       handlerInfo.preferredAction = Ci.nsIHandlerInfo.saveToDisk;
       handlerInfo.alwaysAskBeforeHandling = false;
       handlerInfo.preferredApplicationHandler = null;
 
       const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"]
                            .getService(Ci.nsIHandlerService);
       handlerSvc.store(handlerInfo);
 
-      let profileDir = Services.dirsvc.get("ProfDS", Ci.nsIFile);
+      let dirProvider = Cc["@mozilla.org/file/directory_service;1"]
+                          .getService(Ci.nsIProperties);
+      let profileDir = dirProvider.get("ProfDS", Ci.nsIFile);
       profileDir.append("downloads");
 
-      let prefBranch = Services.prefs.getBranch("browser.download.");
+      let prefs = Cc["@mozilla.org/preferences-service;1"]
+                    .getService(Ci.nsIPrefService);
+      let prefBranch = prefs.getBranch("browser.download.");
 
       prefBranch.setCharPref("dir", profileDir.path);
       prefBranch.setBoolPref("useDownloadDir", true);
       prefBranch.setIntPref("folderList", 2);
 
       const { Downloads } =
         Cu.import("resource://gre/modules/Downloads.jsm", {});
       Downloads.getList(Downloads.PUBLIC).then(list => {
@@ -61,27 +64,28 @@
       window.location = url;
     });
   }
 
   function afterNavigationTest() {}
 
   testCleanUp = function cleanup() {
     SpecialPowers.loadChromeScript(function() {
-      const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-      const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+      const { classes: Cc, interfaces: Ci } = Components;
       const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
       let handlerInfo =
         mimeSvc.getFromTypeAndExtension("application/x-auto-download", "auto");
 
       const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"]
                            .getService(Ci.nsIHandlerService);
       handlerSvc.remove(handlerInfo);
 
-      let prefBranch = Services.prefs.getBranch("browser.download.");
+      let prefs = Cc["@mozilla.org/preferences-service;1"]
+                    .getService(Ci.nsIPrefService);
+      let prefBranch = prefs.getBranch("browser.download.");
 
       const prefKeys = ["dir", "useDownloadDir", "folderList"];
       for (let prefKey of prefKeys) {
         if (prefBranch.prefHasUserValue(prefKey)) {
           prefBranch.clearUserPref(prefKey);
         }
       }
     });
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -371,17 +371,19 @@ function add_tls_server_setup(serverBinN
 function add_connection_test(aHost, aExpectedResult,
                              aBeforeConnect, aWithSecurityInfo,
                              aAfterStreamOpen,
                              /* optional */ aOriginAttributes) {
   const REMOTE_PORT = 8443;
 
   function Connection(host) {
     this.host = host;
-    this.thread = Services.tm.currentThread;
+    let threadManager = Cc["@mozilla.org/thread-manager;1"]
+                          .getService(Ci.nsIThreadManager);
+    this.thread = threadManager.currentThread;
     this.defer = Promise.defer();
     let sts = Cc["@mozilla.org/network/socket-transport-service;1"]
                 .getService(Ci.nsISocketTransportService);
     this.transport = sts.createTransport(["ssl"], 1, host, REMOTE_PORT, null);
     // See bug 1129771 - attempting to connect to [::1] when the server is
     // listening on 127.0.0.1 causes frequent failures on OS X 10.10.
     this.transport.connectionFlags |= Ci.nsISocketTransport.DISABLE_IPV6;
     this.transport.setEventSink(this, this.thread);
@@ -464,22 +466,25 @@ function add_connection_test(aHost, aExp
                               .QueryInterface(Ci.nsITransportSecurityInfo));
       }
       run_next_test();
     });
   });
 }
 
 function _getBinaryUtil(binaryUtilName) {
-  let utilBin = Services.dirsvc.get("CurProcD", Ci.nsIFile);
+  let directoryService = Cc["@mozilla.org/file/directory_service;1"]
+                           .getService(Ci.nsIProperties);
+
+  let utilBin = directoryService.get("CurProcD", Ci.nsIFile);
   utilBin.append(binaryUtilName + mozinfo.bin_suffix);
   // If we're testing locally, the above works. If not, the server executable
   // is in another location.
   if (!utilBin.exists()) {
-    utilBin = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+    utilBin = directoryService.get("CurWorkD", Ci.nsIFile);
     while (utilBin.path.indexOf("xpcshell") != -1) {
       utilBin = utilBin.parent;
     }
     utilBin.append("bin");
     utilBin.append(binaryUtilName + mozinfo.bin_suffix);
   }
   // But maybe we're on Android or B2G, where binaries are in /data/local/xpcb.
   if (!utilBin.exists()) {
@@ -494,19 +499,21 @@ function _getBinaryUtil(binaryUtilName) 
 function _setupTLSServerTest(serverBinName, certsPath) {
   let certdb = Cc["@mozilla.org/security/x509certdb;1"]
                   .getService(Ci.nsIX509CertDB);
   // The trusted CA that is typically used for "good" certificates.
   addCertFromFile(certdb, `${certsPath}/test-ca.pem`, "CTu,u,u");
 
   const CALLBACK_PORT = 8444;
 
+  let directoryService = Cc["@mozilla.org/file/directory_service;1"]
+                           .getService(Ci.nsIProperties);
   let envSvc = Cc["@mozilla.org/process/environment;1"]
                  .getService(Ci.nsIEnvironment);
-  let greBinDir = Services.dirsvc.get("GreBinD", Ci.nsIFile);
+  let greBinDir = directoryService.get("GreBinD", Ci.nsIFile);
   envSvc.set("DYLD_LIBRARY_PATH", greBinDir.path);
   // TODO(bug 1107794): Android libraries are in /data/local/xpcb, but "GreBinD"
   // does not return this path on Android, so hard code it here.
   envSvc.set("LD_LIBRARY_PATH", greBinDir.path + ":/data/local/xpcb");
   envSvc.set("MOZ_TLS_SERVER_DEBUG_LEVEL", "3");
   envSvc.set("MOZ_TLS_SERVER_CALLBACK_PORT", CALLBACK_PORT);
 
   let httpServer = new HttpServer();
@@ -520,17 +527,17 @@ function _setupTLSServerTest(serverBinNa
           httpServer.stop(run_next_test);
         });
       });
   httpServer.start(CALLBACK_PORT);
 
   let serverBin = _getBinaryUtil(serverBinName);
   let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
   process.init(serverBin);
-  let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+  let certDir = directoryService.get("CurWorkD", Ci.nsIFile);
   certDir.append(`${certsPath}`);
   Assert.ok(certDir.exists(), `certificate folder (${certsPath}) should exist`);
   // Using "sql:" causes the SQL DB to be used so we can run tests on Android.
   process.run(false, [ "sql:" + certDir.path ], 1);
 
   registerCleanupFunction(function() {
     process.kill();
   });
--- a/security/manager/ssl/tests/unit/test_cert_overrides.js
+++ b/security/manager/ssl/tests/unit/test_cert_overrides.js
@@ -9,17 +9,18 @@
 // 1. Attempt to connect to the given host. This should fail with the
 //    given error and override bits.
 // 2. Add an override for that host/port/certificate/override bits.
 // 3. Connect again. This should succeed.
 
 do_get_profile();
 
 function check_telemetry() {
-  let histogram = Services.telemetry
+  let histogram = Cc["@mozilla.org/base/telemetry;1"]
+                    .getService(Ci.nsITelemetry)
                     .getHistogramById("SSL_CERT_ERROR_OVERRIDES")
                     .snapshot();
   equal(histogram.counts[0], 0, "Should have 0 unclassified counts");
   equal(histogram.counts[2], 9,
         "Actual and expected SEC_ERROR_UNKNOWN_ISSUER counts should match");
   equal(histogram.counts[3], 1,
         "Actual and expected SEC_ERROR_CA_CERT_INVALID counts should match");
   equal(histogram.counts[4], 0,
@@ -46,17 +47,18 @@ function check_telemetry() {
         "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE counts should match");
   equal(histogram.counts[15], 1,
         "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE counts should match");
   equal(histogram.counts[16], 2,
         "Actual and expected SEC_ERROR_INVALID_TIME counts should match");
   equal(histogram.counts[17], 1,
         "Actual and expected MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME counts should match");
 
-  let keySizeHistogram = Services.telemetry
+  let keySizeHistogram = Cc["@mozilla.org/base/telemetry;1"]
+                           .getService(Ci.nsITelemetry)
                            .getHistogramById("CERT_CHAIN_KEY_SIZE_STATUS")
                            .snapshot();
   equal(keySizeHistogram.counts[0], 0,
         "Actual and expected unchecked key size counts should match");
   equal(keySizeHistogram.counts[1], 16,
         "Actual and expected successful verifications of 2048-bit keys should match");
   equal(keySizeHistogram.counts[2], 0,
         "Actual and expected successful verifications of 1024-bit keys should match");
--- a/security/manager/ssl/tests/unit/test_ocsp_stapling.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_stapling.js
@@ -160,17 +160,18 @@ function add_tests() {
   add_ocsp_test("keysize-ocsp-delegated.example.com",
                 SEC_ERROR_OCSP_INVALID_SIGNING_CERT, true, true);
 
   add_ocsp_test("revoked-ca-cert-used-as-end-entity.example.com",
                 SEC_ERROR_REVOKED_CERTIFICATE, true);
 }
 
 function check_ocsp_stapling_telemetry() {
-  let histogram = Services.telemetry
+  let histogram = Cc["@mozilla.org/base/telemetry;1"]
+                    .getService(Ci.nsITelemetry)
                     .getHistogramById("SSL_OCSP_STAPLING")
                     .snapshot();
   equal(histogram.counts[0], 0,
         "Should have 0 connections for unused histogram bucket 0");
   equal(histogram.counts[1], 5,
         "Actual and expected connections with a good response should match");
   equal(histogram.counts[2], 18,
         "Actual and expected connections with no stapled response should match");
--- a/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js
@@ -188,17 +188,18 @@ function run_test() {
                 PRErrorCodeSuccess, ocspResponseGoodMustStaple, willNotRetry);
 
   add_test(function () { ocspResponder.stop(run_next_test); });
   add_test(check_ocsp_stapling_telemetry);
   run_next_test();
 }
 
 function check_ocsp_stapling_telemetry() {
-  let histogram = Services.telemetry
+  let histogram = Cc["@mozilla.org/base/telemetry;1"]
+                    .getService(Ci.nsITelemetry)
                     .getHistogramById("SSL_OCSP_STAPLING")
                     .snapshot();
   equal(histogram.counts[0], 0,
         "Should have 0 connections for unused histogram bucket 0");
   equal(histogram.counts[1], 0,
         "Actual and expected connections with a good response should match");
   equal(histogram.counts[2], 0,
         "Actual and expected connections with no stapled response should match");
--- a/security/manager/ssl/tests/unit/test_pinning.js
+++ b/security/manager/ssl/tests/unit/test_pinning.js
@@ -202,46 +202,47 @@ function test_enforce_test_mode() {
   add_prevented_cert_override_test(
     "unknownissuer.test-mode.pinning.example.com",
     Ci.nsICertOverrideService.ERROR_UNTRUSTED,
     SEC_ERROR_UNKNOWN_ISSUER);
   add_clear_override("unknownissuer.test-mode.pinning.example.com");
 }
 
 function check_pinning_telemetry() {
-  let prod_histogram = Services.telemetry.getHistogramById("CERT_PINNING_RESULTS")
+  let service = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
+  let prod_histogram = service.getHistogramById("CERT_PINNING_RESULTS")
                          .snapshot();
-  let test_histogram = Services.telemetry.getHistogramById("CERT_PINNING_TEST_RESULTS")
+  let test_histogram = service.getHistogramById("CERT_PINNING_TEST_RESULTS")
                          .snapshot();
   // Because all of our test domains are pinned to user-specified trust
   // anchors, effectively only strict mode and enforce test-mode get evaluated
   equal(prod_histogram.counts[0], 4,
         "Actual and expected prod (non-Mozilla) failure count should match");
   equal(prod_histogram.counts[1], 4,
         "Actual and expected prod (non-Mozilla) success count should match");
   equal(test_histogram.counts[0], 2,
         "Actual and expected test (non-Mozilla) failure count should match");
   equal(test_histogram.counts[1], 0,
         "Actual and expected test (non-Mozilla) success count should match");
 
-  let moz_prod_histogram = Services.telemetry.getHistogramById("CERT_PINNING_MOZ_RESULTS")
+  let moz_prod_histogram = service.getHistogramById("CERT_PINNING_MOZ_RESULTS")
                              .snapshot();
   let moz_test_histogram =
-    Services.telemetry.getHistogramById("CERT_PINNING_MOZ_TEST_RESULTS").snapshot();
+    service.getHistogramById("CERT_PINNING_MOZ_TEST_RESULTS").snapshot();
   equal(moz_prod_histogram.counts[0], 0,
         "Actual and expected prod (Mozilla) failure count should match");
   equal(moz_prod_histogram.counts[1], 0,
         "Actual and expected prod (Mozilla) success count should match");
   equal(moz_test_histogram.counts[0], 0,
         "Actual and expected test (Mozilla) failure count should match");
   equal(moz_test_histogram.counts[1], 0,
         "Actual and expected test (Mozilla) success count should match");
 
   let per_host_histogram =
-    Services.telemetry.getHistogramById("CERT_PINNING_MOZ_RESULTS_BY_HOST").snapshot();
+    service.getHistogramById("CERT_PINNING_MOZ_RESULTS_BY_HOST").snapshot();
   equal(per_host_histogram.counts[0], 0,
         "Actual and expected per host (Mozilla) failure count should match");
   equal(per_host_histogram.counts[1], 2,
         "Actual and expected per host (Mozilla) success count should match");
   run_next_test();
 }
 
 function run_test() {
--- a/security/manager/ssl/tests/unit/test_pkcs11_module.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_module.js
@@ -61,17 +61,19 @@ function checkTestModuleExists() {
 function checkModuleTelemetry(additionalExpectedModule = undefined) {
   let expectedModules = [
     "NSS Internal PKCS #11 Module",
   ];
   if (additionalExpectedModule) {
     expectedModules.push(additionalExpectedModule);
   }
   expectedModules.sort();
-  let telemetry = Services.telemetry.snapshotKeyedScalars(
+  let telemetryService = Cc["@mozilla.org/base/telemetry;1"]
+                           .getService(Ci.nsITelemetry);
+  let telemetry = telemetryService.snapshotKeyedScalars(
     Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT).parent;
   let moduleTelemetry = telemetry["security.pkcs11_modules_loaded"];
   let actualModules = [];
   Object.keys(moduleTelemetry).forEach((key) => {
     ok(moduleTelemetry[key], "each keyed scalar should be true");
     actualModules.push(key);
   });
   actualModules.sort();
--- a/security/manager/ssl/tests/unit/test_pkcs11_token.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_token.js
@@ -13,18 +13,20 @@
 //      We want to test such functionality.
 //   3. Using the internal token lets us actually test the internal token works
 //      as expected.
 
 // Ensure that the appropriate initialization has happened.
 do_get_profile();
 
 function checkBasicAttributes(token) {
+  let strBundleSvc = Cc["@mozilla.org/intl/stringbundle;1"]
+                       .getService(Ci.nsIStringBundleService);
   let bundle =
-    Services.strings.createBundle("chrome://pipnss/locale/pipnss.properties");
+    strBundleSvc.createBundle("chrome://pipnss/locale/pipnss.properties");
 
   let expectedTokenName = bundle.GetStringFromName("PrivateTokenDescription");
   equal(token.tokenName, expectedTokenName,
         "Actual and expected name should match");
   equal(token.tokenLabel, expectedTokenName,
         "Actual and expected label should match");
   equal(token.tokenManID, bundle.GetStringFromName("ManufacturerID"),
         "Actual and expected manufacturer ID should match");
--- a/security/manager/tools/getHSTSPreloadList.js
+++ b/security/manager/tools/getHSTSPreloadList.js
@@ -342,17 +342,19 @@ function getHSTSStatuses(inHosts, outSta
     }
   }
 }
 
 // Since all events are processed on the main thread, and since event
 // handlers are not preemptible, there shouldn't be any concurrency issues.
 function waitForAResponse(outputList) {
   // From <https://developer.mozilla.org/en/XPConnect/xpcshell/HOWTO>
-  Services.tm.spinEventLoopUntil(() => outputList.length != 0);
+  var threadManager = Cc["@mozilla.org/thread-manager;1"]
+                      .getService(Ci.nsIThreadManager);
+  threadManager.spinEventLoopUntil(() => outputList.length != 0);
 }
 
 function readCurrentList(filename) {
   var currentHosts = {};
   var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
   file.initWithPath(filename);
   var fis = Cc["@mozilla.org/network/file-input-stream;1"]
               .createInstance(Ci.nsILineInputStream);
--- a/security/sandbox/test/browser_content_sandbox_fs.js
+++ b/security/sandbox/test/browser_content_sandbox_fs.js
@@ -1,13 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
  /* import-globals-from browser_content_sandbox_utils.js */
  "use strict";
 
+var prefs = Cc["@mozilla.org/preferences-service;1"]
+            .getService(Ci.nsIPrefBranch);
+
 Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/" +
     "security/sandbox/test/browser_content_sandbox_utils.js", this);
 
 const FONT_EXTENSIONS = [ "otf", "ttf", "ttc", "otc", "dfont" ];
 
 /*
  * This test exercises file I/O from web and file content processes using
  * OS.File methods to validate that calls that are meant to be blocked by
@@ -182,17 +185,17 @@ add_task(async function() {
   let prefExists = true;
 
   // Read the security.sandbox.content.level pref.
   // If the pref isn't set and we're running on Linux on !isNightly(),
   // exit without failing. The Linux content sandbox is only enabled
   // on Nightly at this time.
   // eslint-disable-next-line mozilla/use-default-preference-values
   try {
-    level = Services.prefs.getIntPref("security.sandbox.content.level");
+    level = prefs.getIntPref("security.sandbox.content.level");
   } catch (e) {
     prefExists = false;
   }
 
   ok(prefExists, "pref security.sandbox.content.level exists");
   if (!prefExists) {
     return;
   }
@@ -299,31 +302,31 @@ function getBadFontTestPaths(baseDir) {
 
 // Test reading files and dirs from web and file content processes.
 async function testFileAccess() {
   // for tests that run in a web content process
   let webBrowser = gBrowser.selectedBrowser;
 
   // Ensure that the file content process is enabled.
   let fileContentProcessEnabled =
-    Services.prefs.getBoolPref("browser.tabs.remote.separateFileUriProcess");
+    prefs.getBoolPref("browser.tabs.remote.separateFileUriProcess");
   ok(fileContentProcessEnabled, "separate file content process is enabled");
 
   // for tests that run in a file content process
   let fileBrowser = undefined;
   if (fileContentProcessEnabled) {
     // open a tab in a file content process
     gBrowser.selectedTab =
       BrowserTestUtils.addTab(gBrowser, "about:blank", {preferredRemoteType: "file"});
     // get the browser for the file content process tab
     fileBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
   }
 
   // Current level
-  let level = Services.prefs.getIntPref("security.sandbox.content.level");
+  let level = prefs.getIntPref("security.sandbox.content.level");
 
   // Directories/files to test accessing from content processes.
   // For directories, we test whether a directory listing is allowed
   // or blocked. For files, we test if we can read from the file.
   // Each entry in the array represents a test file or directory
   // that will be read from either a web or file process.
   let tests = [];
 
--- a/security/sandbox/test/browser_content_sandbox_syscalls.js
+++ b/security/sandbox/test/browser_content_sandbox_syscalls.js
@@ -1,13 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
  /* import-globals-from browser_content_sandbox_utils.js */
 "use strict";
 
+var prefs = Cc["@mozilla.org/preferences-service;1"]
+            .getService(Ci.nsIPrefBranch);
+
 Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/" +
     "security/sandbox/test/browser_content_sandbox_utils.js", this);
 
 /*
  * This test is for executing system calls in content processes to validate
  * that calls that are meant to be blocked by content sandboxing are blocked.
  * We use the term system calls loosely so that any OS API call such as
  * fopen could be included.
@@ -144,17 +147,17 @@ add_task(async function() {
   let prefExists = true;
 
   // Read the security.sandbox.content.level pref.
   // If the pref isn't set and we're running on Linux on !isNightly(),
   // exit without failing. The Linux content sandbox is only enabled
   // on Nightly at this time.
   // eslint-disable-next-line mozilla/use-default-preference-values
   try {
-    level = Services.prefs.getIntPref("security.sandbox.content.level");
+    level = prefs.getIntPref("security.sandbox.content.level");
   } catch (e) {
     prefExists = false;
   }
 
   ok(prefExists, "pref security.sandbox.content.level exists");
   if (!prefExists) {
     return;
   }
--- a/security/sandbox/test/browser_content_sandbox_utils.js
+++ b/security/sandbox/test/browser_content_sandbox_utils.js
@@ -11,17 +11,18 @@ const environment = Cc["@mozilla.org/pro
  * Utility functions for the browser content sandbox tests.
  */
 
 function isMac() { return Services.appinfo.OS == "Darwin"; }
 function isWin() { return Services.appinfo.OS == "WINNT"; }
 function isLinux() { return Services.appinfo.OS == "Linux"; }
 
 function isNightly() {
-  let version = SpecialPowers.Services.appinfo.version;
+  let version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].
+    getService(SpecialPowers.Ci.nsIXULAppInfo).version;
   return (version.endsWith("a1"));
 }
 
 function uuid() {
   return uuidGenerator.generateUUID().toString();
 }
 
 // Returns a file object for a new file in the home dir ($HOME/<UUID>).