Bug 1437584 - Enable ESLint rule mozilla/use-services for testing/. draft
authorMark Banner <standard8@mozilla.com>
Mon, 12 Feb 2018 17:10:00 +0000
changeset 757570 1351d5eeefae4a9cd3fdb19a8bf0811ad33d56d5
parent 757133 dc70d241f90df43505ece5ac12261339e9694c50
push id99780
push userbmo:standard8@mozilla.com
push dateTue, 20 Feb 2018 20:54:48 +0000
bugs1437584
milestone60.0a1
Bug 1437584 - Enable ESLint rule mozilla/use-services for testing/. MozReview-Commit-ID: DMkgj5UAId4
.eslintrc.js
testing/modules/AppData.jsm
testing/modules/AppInfo.jsm
testing/specialpowers/content/SpecialPowersObserver.jsm
testing/specialpowers/content/specialpowersAPI.js
testing/talos/talos/pageloader/chrome/MozillaFileLogger.js
testing/talos/talos/pageloader/chrome/Profiler.js
testing/talos/talos/pageloader/chrome/pageloader.js
testing/talos/talos/pageloader/chrome/quit.js
testing/talos/talos/scripts/MozillaFileLogger.js
testing/talos/talos/scripts/Profiler.js
testing/talos/talos/startup_test/tresize/addon/content/Profiler.js
testing/talos/talos/startup_test/tspaint_test.html
testing/talos/talos/talos-powers/chrome/talos-powers-content.js
testing/talos/talos/tests/devtools/addon/content/Profiler.js
testing/talos/talos/tests/devtools/addon/content/damp.js
testing/talos/talos/tests/tart/addon/content/Profiler.js
testing/talos/talos/tests/tart/addon/content/tart.js
testing/xpcshell/example/unit/check_profile.js
testing/xpcshell/head.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -40,17 +40,16 @@ module.exports = {
       "mozilla/browser-window": true
     }
   },{
     // XXX Bug 1421969. These files/directories are still being fixed,
     // so turn off mozilla/use-services for them for now.
     "files": [
       "extensions/pref/**",
       "mobile/android/**",
-      "testing/**",
     ],
     "rules": {
       "mozilla/use-services": "off",
     }
   }, {
     // XXX Bug 1434446. These directories have jsm files still being fixed, so
     // turn off global no-unused-vars checking for them.
     "files": [
--- a/testing/modules/AppData.jsm
+++ b/testing/modules/AppData.jsm
@@ -5,16 +5,17 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = [
   "makeFakeAppDir",
 ];
 
 ChromeUtils.import("resource://gre/modules/osfile.jsm");
 ChromeUtils.import("resource://gre/modules/Promise.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 // Reference needed in order for fake app dir provider to be active.
 var gFakeAppDirectoryProvider;
 
 /**
  * Installs a fake UAppData directory.
  *
  * This is needed by tests because a UAppData directory typically isn't
@@ -24,19 +25,17 @@ var gFakeAppDirectoryProvider;
  * because the profile directory is automatically cleaned as part of
  * test shutdown.
  *
  * This returns a promise that will be resolved once the new directory
  * is created and installed.
  */
 this.makeFakeAppDir = function() {
   let dirMode = OS.Constants.libc.S_IRWXU;
-  let dirService = Cc["@mozilla.org/file/directory_service;1"]
-                     .getService(Ci.nsIProperties);
-  let baseFile = dirService.get("ProfD", Ci.nsIFile);
+  let baseFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
   let appD = baseFile.clone();
   appD.append("UAppData");
 
   if (gFakeAppDirectoryProvider) {
     return Promise.resolve(appD.path);
   }
 
   function makeDir(f) {
@@ -78,22 +77,20 @@ this.makeFakeAppDir = function() {
         return this;
       }
 
       throw Cr.NS_ERROR_NO_INTERFACE;
     },
   };
 
   // Register the new provider.
-  dirService.QueryInterface(Ci.nsIDirectoryService)
-            .registerProvider(provider);
+  Services.dirsvc.registerProvider(provider);
 
   // And undefine the old one.
   try {
-    dirService.undefine("UAppData");
+    Services.dirsvc.undefine("UAppData");
   } catch (ex) {}
 
   gFakeAppDirectoryProvider = provider;
 
   dump("Successfully installed fake UAppDir\n");
   return Promise.resolve(appD.path);
 };
-
--- a/testing/modules/AppInfo.jsm
+++ b/testing/modules/AppInfo.jsm
@@ -11,16 +11,17 @@ this.EXPORTED_SYMBOLS = [
 ];
 
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 let origPlatformInfo = Cc["@mozilla.org/xre/app-info;1"]
     .getService(Ci.nsIPlatformInfo);
 
+// eslint-disable-next-line mozilla/use-services
 let origRuntime = Cc["@mozilla.org/xre/app-info;1"]
     .getService(Ci.nsIXULRuntime);
 
 /**
  * Create new XULAppInfo instance with specified options.
  *
  * options is a object with following keys:
  *   ID:              nsIXULAppInfo.ID
@@ -134,9 +135,8 @@ this.updateAppInfo = function(options) {
 
   registrar.registerFactory(id, "XULAppInfo", cid, factory);
 
   // Ensure that Cc actually maps cid to the new shim AppInfo. This is
   // needed when JSM global sharing is enabled, because some prior
   // code may already have looked up |Cc[cid]|.
   Cc.initialize(Cc[cid], cid);
 };
-
--- a/testing/specialpowers/content/SpecialPowersObserver.jsm
+++ b/testing/specialpowers/content/SpecialPowersObserver.jsm
@@ -18,19 +18,17 @@ ChromeUtils.import("resource://gre/modul
 Components.utils.importGlobalProperties(["File"]);
 
 const CHILD_SCRIPT = "chrome://specialpowers/content/specialpowers.js";
 const CHILD_SCRIPT_API = "chrome://specialpowers/content/specialpowersAPI.js";
 const CHILD_LOGGER_SCRIPT = "chrome://specialpowers/content/MozillaLogger.js";
 
 
 // Glue to add in the observer API to this object.  This allows us to share code with chrome tests
-var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
-                       .getService(Components.interfaces.mozIJSSubScriptLoader);
-loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js");
+Services.scriptloader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js");
 
 /* XPCOM gunk */
 this.SpecialPowersObserver = function SpecialPowersObserver() {
   this._isFrameScriptLoaded = false;
   this._messageManager = Cc["@mozilla.org/globalmessagemanager;1"].
                          getService(Ci.nsIMessageBroadcaster);
 };
 
@@ -103,23 +101,19 @@ SpecialPowersObserver.prototype._receive
   return this._receiveMessageAPI(aMessage);
 };
 
 SpecialPowersObserver.prototype.init = function() {
   var obs = Services.obs;
   obs.addObserver(this, "chrome-document-global-created");
 
   // Register special testing modules.
-  var testsURI = Cc["@mozilla.org/file/directory_service;1"].
-                   getService(Ci.nsIProperties).
-                   get("ProfD", Ci.nsIFile);
+  var testsURI = Services.dirsvc.get("ProfD", Ci.nsIFile);
   testsURI.append("tests.manifest");
-  var ioSvc = Cc["@mozilla.org/network/io-service;1"].
-                getService(Ci.nsIIOService);
-  var manifestFile = ioSvc.newFileURI(testsURI).
+  var manifestFile = Services.io.newFileURI(testsURI).
                        QueryInterface(Ci.nsIFileURL).file;
 
   Components.manager.QueryInterface(Ci.nsIComponentRegistrar).
                  autoRegister(manifestFile);
 
   obs.addObserver(this, "http-on-modify-request");
 
   this._loadFrameScript();
@@ -165,34 +159,28 @@ SpecialPowersObserver.prototype.uninit =
   }
 };
 
 SpecialPowersObserver.prototype._addProcessCrashObservers = function() {
   if (this._processCrashObserversRegistered) {
     return;
   }
 
-  var obs = Components.classes["@mozilla.org/observer-service;1"]
-                      .getService(Components.interfaces.nsIObserverService);
-
-  obs.addObserver(this, "plugin-crashed");
-  obs.addObserver(this, "ipc:content-shutdown");
+  Services.obs.addObserver(this, "plugin-crashed");
+  Services.obs.addObserver(this, "ipc:content-shutdown");
   this._processCrashObserversRegistered = true;
 };
 
 SpecialPowersObserver.prototype._removeProcessCrashObservers = function() {
   if (!this._processCrashObserversRegistered) {
     return;
   }
 
-  var obs = Components.classes["@mozilla.org/observer-service;1"]
-                      .getService(Components.interfaces.nsIObserverService);
-
-  obs.removeObserver(this, "plugin-crashed");
-  obs.removeObserver(this, "ipc:content-shutdown");
+  Services.obs.removeObserver(this, "plugin-crashed");
+  Services.obs.removeObserver(this, "ipc:content-shutdown");
   this._processCrashObserversRegistered = false;
 };
 
 SpecialPowersObserver.prototype._registerObservers = {
   _self: null,
   _topics: [],
   _add(topic) {
     if (!this._topics.includes(topic)) {
@@ -232,18 +220,17 @@ SpecialPowersObserver.prototype.receiveM
     case "SPPingService":
       if (aMessage.json.op == "ping") {
         aMessage.target.frameLoader
                 .messageManager
                 .sendAsyncMessage("SPPingService", { op: "pong" });
       }
       break;
     case "SpecialPowers.Quit":
-      let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
-      appStartup.quit(Ci.nsIAppStartup.eForceQuit);
+      Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
       break;
     case "SpecialPowers.Focus":
       aMessage.target.focus();
       break;
     case "SpecialPowers.CreateFiles":
       let filePaths = [];
       if (!this._createdFiles) {
         this._createdFiles = [];
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -41,18 +41,16 @@ function SpecialPowersAPI() {
   this._mfl = null;
   this._prefEnvUndoStack = [];
   this._pendingPrefs = [];
   this._applyingPrefs = false;
   this._permissionsUndoStack = [];
   this._pendingPermissions = [];
   this._applyingPermissions = false;
   this._observingPermissions = false;
-  this._fm = null;
-  this._cb = null;
 }
 
 function bindDOMWindowUtils(aWindow) {
   if (!aWindow)
     return undefined;
 
   var util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIDOMWindowUtils);
@@ -1615,32 +1613,28 @@ SpecialPowersAPI.prototype = {
   },
 
   setGCZeal(zeal) {
     Cu.setGCZeal(zeal);
   },
 
   isMainProcess() {
     try {
-      return Cc["@mozilla.org/xre/app-info;1"].
-               getService(Ci.nsIXULRuntime).
-               processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+      return Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
     } catch (e) { }
     return true;
   },
 
   _xpcomabi: null,
 
   get XPCOMABI() {
     if (this._xpcomabi != null)
       return this._xpcomabi;
 
-    var xulRuntime = Cc["@mozilla.org/xre/app-info;1"]
-                        .getService(Components.interfaces.nsIXULAppInfo)
-                        .QueryInterface(Components.interfaces.nsIXULRuntime);
+    var xulRuntime = Services.appinfo.QueryInterface(Components.interfaces.nsIXULRuntime);
 
     this._xpcomabi = xulRuntime.XPCOMABI;
     return this._xpcomabi;
   },
 
   // The optional aWin parameter allows the caller to specify a given window in
   // whose scope the runnable should be dispatched. If aFun throws, the
   // exception will be reported to aWin.
@@ -1654,33 +1648,25 @@ SpecialPowersAPI.prototype = {
   },
 
   _os: null,
 
   get OS() {
     if (this._os != null)
       return this._os;
 
-    var xulRuntime = Cc["@mozilla.org/xre/app-info;1"]
-                        .getService(Components.interfaces.nsIXULAppInfo)
-                        .QueryInterface(Components.interfaces.nsIXULRuntime);
-
-    this._os = xulRuntime.OS;
+    this._os = Services.appinfo.OS;
     return this._os;
   },
 
   addSystemEventListener(target, type, listener, useCapture) {
-    Cc["@mozilla.org/eventlistenerservice;1"].
-      getService(Ci.nsIEventListenerService).
-      addSystemEventListener(target, type, listener, useCapture);
+    Services.els.addSystemEventListener(target, type, listener, useCapture);
   },
   removeSystemEventListener(target, type, listener, useCapture) {
-    Cc["@mozilla.org/eventlistenerservice;1"].
-      getService(Ci.nsIEventListenerService).
-      removeSystemEventListener(target, type, listener, useCapture);
+    Services.els.removeSystemEventListener(target, type, listener, useCapture);
   },
 
   // helper method to check if the event is consumed by either default group's
   // event listener or system group's event listener.
   defaultPreventedInAnyGroup(event) {
     // FYI: Event.defaultPrevented returns false in content context if the
     //      event is consumed only by system group's event listeners.
     return event.defaultPrevented;
@@ -1741,38 +1727,32 @@ SpecialPowersAPI.prototype = {
         obj = obj[p];
       } else {
         return null;
       }
     }
     return obj;
   },
 
-  get focusManager() {
-    if (this._fm != null)
-      return this._fm;
-
-    this._fm = Components.classes["@mozilla.org/focus-manager;1"].
-                        getService(Components.interfaces.nsIFocusManager);
-
-    return this._fm;
-  },
-
   getFocusedElementForWindow(targetWindow, aDeep) {
     var outParam = {};
-    this.focusManager.getFocusedElementForWindow(targetWindow, aDeep, outParam);
+    Services.focus.getFocusedElementForWindow(targetWindow, aDeep, outParam);
     return outParam.value;
   },
 
+  get focusManager() {
+    return Services.focus;
+  },
+
   activeWindow() {
-    return this.focusManager.activeWindow;
+    return Services.focus.activeWindow;
   },
 
   focusedWindow() {
-    return this.focusManager.focusedWindow;
+    return Services.focus.focusedWindow;
   },
 
   focus(aWindow) {
     // This is called inside TestRunner._makeIframe without aWindow, because of assertions in oop mochitests
     // With aWindow, it is called in SimpleTest.waitForFocus to allow popup window opener focus switching
     if (aWindow)
       aWindow.focus();
     var mm = global;
@@ -1786,31 +1766,28 @@ SpecialPowersAPI.prototype = {
         /* Ignore exceptions for e.g. XUL chrome windows from mochitest-chrome
          * which won't have a message manager */
       }
     }
     mm.sendAsyncMessage("SpecialPowers.Focus", {});
   },
 
   getClipboardData(flavor, whichClipboard) {
-    if (this._cb == null)
-      this._cb = Components.classes["@mozilla.org/widget/clipboard;1"].
-                            getService(Components.interfaces.nsIClipboard);
     if (whichClipboard === undefined)
-      whichClipboard = this._cb.kGlobalClipboard;
+      whichClipboard = Services.clipboard.kGlobalClipboard;
 
     var xferable = Components.classes["@mozilla.org/widget/transferable;1"].
                    createInstance(Components.interfaces.nsITransferable);
     // in e10s b-c tests |content.window| is a CPOW whereas |window| works fine.
     // for some non-e10s mochi tests, |window| is null whereas |content.window|
     // works fine.  So we take whatever is non-null!
     xferable.init(this._getDocShell(typeof(window) == "undefined" ? content.window : window)
                       .QueryInterface(Components.interfaces.nsILoadContext));
     xferable.addDataFlavor(flavor);
-    this._cb.getData(xferable, whichClipboard);
+    Services.clipboard.getData(xferable, whichClipboard);
     var data = {};
     try {
       xferable.getTransferData(flavor, data, {});
     } catch (e) {}
     data = data.value || null;
     if (data == null)
       return "";
 
@@ -1819,21 +1796,17 @@ SpecialPowersAPI.prototype = {
 
   clipboardCopyString(str) {
     Cc["@mozilla.org/widget/clipboardhelper;1"].
       getService(Ci.nsIClipboardHelper).
       copyString(str);
   },
 
   supportsSelectionClipboard() {
-    if (this._cb == null) {
-      this._cb = Components.classes["@mozilla.org/widget/clipboard;1"].
-                            getService(Components.interfaces.nsIClipboard);
-    }
-    return this._cb.supportsSelectionClipboard();
+    return Services.clipboard.supportsSelectionClipboard();
   },
 
   swapFactoryRegistration(cid, contractID, newFactory, oldFactory) {
     newFactory = Cu.waiveXrays(newFactory);
     oldFactory = Cu.waiveXrays(oldFactory);
 
     var componentRegistrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
 
--- a/testing/talos/talos/pageloader/chrome/MozillaFileLogger.js
+++ b/testing/talos/talos/pageloader/chrome/MozillaFileLogger.js
@@ -1,12 +1,14 @@
 /**
  * MozillaFileLogger, a log listener that can write to a local file.
  */
 
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
 // double logging to account for normal mode and ipc mode (mobile_profile only)
 // Ideally we would remove the dump() and just do ipc logging
 function dumpLog(msg) {
   dump(msg);
   MozillaFileLogger.log(msg);
 }
 
 const FOSTREAM_CID = "@mozilla.org/network/file-output-stream;1";
@@ -73,13 +75,11 @@ MozillaFileLogger.close = function() {
   if (MozillaFileLogger._foStream)
     MozillaFileLogger._foStream.close();
 
   MozillaFileLogger._foStream = null;
   MozillaFileLogger._file = null;
 };
 
 try {
-  var prefs = Cc["@mozilla.org/preferences-service;1"]
-    .getService(Ci.nsIPrefBranch);
-  var filename = prefs.getCharPref("talos.logfile");
+  var filename = Services.prefs.getCharPref("talos.logfile");
   MozillaFileLogger.init(filename);
 } catch (ex) {} // pref does not exist, return empty string
--- a/testing/talos/talos/pageloader/chrome/Profiler.js
+++ b/testing/talos/talos/pageloader/chrome/Profiler.js
@@ -40,16 +40,17 @@ var Profiler;
     // (It's not required nor allowed for addons since Firefox 17)
     // It's used inside talos from non-privileged pages (like during tscroll),
     // and it works because talos disables all/most security measures.
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   } catch (e) {}
 
   /* eslint-disable mozilla/use-chromeutils-import */
   try {
+    // eslint-disable-next-line mozilla/use-services
     _profiler = Components.classes["@mozilla.org/tools/profiler;1"].getService(Components.interfaces.nsIProfiler);
   } catch (ex) { (typeof(dumpLog) == "undefined" ? dump : dumpLog)(ex + "\n"); }
 
   // Parses an url query string into a JS object.
   function searchToObject(locationSearch) {
     var pairs = locationSearch.substring(1).split("&");
     var result = {};
 
--- a/testing/talos/talos/pageloader/chrome/pageloader.js
+++ b/testing/talos/talos/pageloader/chrome/pageloader.js
@@ -53,19 +53,16 @@ var content;
 var TEST_DOES_OWN_TIMING = 1;
 var EXECUTE_SCROLL_TEST  = 2;
 
 var browserWindow = null;
 
 var recordedName = null;
 var pageUrls;
 
-// the io service
-var gIOS = null;
-
 /**
  * SingleTimeout class. Allow to register one and only one callback using
  * setTimeout at a time.
  */
 var SingleTimeout = function() {
   this.timeoutEvent = undefined;
 };
 
@@ -150,20 +147,17 @@ function plInit() {
 
     if (forceCC &&
         !window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                .getInterface(Components.interfaces.nsIDOMWindowUtils)
                .garbageCollect) {
       forceCC = false;
     }
 
-    gIOS = Cc["@mozilla.org/network/io-service;1"]
-      .getService(Ci.nsIIOService);
-
-    var fileURI = gIOS.newURI(manifestURI);
+    var fileURI = Services.io.newURI(manifestURI);
     pages = plLoadURLsFromURI(fileURI);
 
     if (!pages) {
       dumpLine("tp: could not load URLs, quitting");
       plStop(true);
     }
 
     if (pages.length == 0) {
@@ -175,28 +169,26 @@ function plInit() {
     report = new Report();
 
     pageIndex = 0;
     if (profilingInfo) {
       TalosParentProfiler.beginTest(getCurrentPageShortName());
     }
 
     // Create a new chromed browser window for content
-    var wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"]
-      .getService(Ci.nsIWindowWatcher);
     var blank = Cc["@mozilla.org/supports-string;1"]
       .createInstance(Ci.nsISupportsString);
     blank.data = "about:blank";
 
     let toolbars = "all";
     if (!useBrowserChrome) {
       toolbars = "titlebar,resizable";
     }
 
-    browserWindow = wwatch.openWindow(null, "chrome://browser/content/", "_blank",
+    browserWindow = Services.ww.openWindow(null, "chrome://browser/content/", "_blank",
        `chrome,${toolbars},dialog=no,width=${winWidth},height=${winHeight}`, blank);
 
     gPaintWindow = browserWindow;
     // get our window out of the way
     window.resizeTo(10, 10);
 
     var browserLoadFunc = function(ev) {
       browserWindow.removeEventListener("load", browserLoadFunc, true);
@@ -796,17 +788,17 @@ function plLoadURLsFromURI(manifestUri) 
     // split on whitespace, and figure out if we have any flags
     var items = s.split(/\s+/);
     if (items[0] == "include") {
       if (items.length != 2) {
         dumpLine("tp: Error on line " + lineNo + " in " + manifestUri.spec + ": include must be followed by the manifest to include!");
         return null;
       }
 
-      var subManifest = gIOS.newURI(items[1], null, manifestUri);
+      var subManifest = Services.io.newURI(items[1], null, manifestUri);
       if (subManifest == null) {
         dumpLine("tp: invalid URI on line " + manifestUri.spec + ":" + lineNo + " : '" + line.value + "'");
         return null;
       }
 
       var subItems = plLoadURLsFromURI(subManifest);
       if (subItems == null)
         return null;
@@ -849,35 +841,35 @@ function plLoadURLsFromURI(manifestUri) 
       } else if (items.length != 1) {
         dumpLine("tp: Error on line " + lineNo + " in " + manifestUri.spec + ": whitespace must be %-escaped!");
         return null;
       }
 
       var url;
 
       if (!baseVsRef) {
-        url = gIOS.newURI(urlspec, null, manifestUri);
+        url = Services.io.newURI(urlspec, null, manifestUri);
 
         if (pageFilterRegexp && !pageFilterRegexp.test(url.spec))
           continue;
 
         url_array.push({ url, flags });
       } else {
         // base vs ref type of talos test
         // we add a 'pre' prefix here indicating that this particular page is a base page or a reference
         // page; later on this 'pre' is used when recording the actual time value/result; because in
         // the results we use the url as the results key; but we might use the same test page as a reference
         // page in the same test suite, so we need to add a prefix so this results key is always unique
-        url = gIOS.newURI(urlspecBase, null, manifestUri);
+        url = Services.io.newURI(urlspecBase, null, manifestUri);
         if (pageFilterRegexp && !pageFilterRegexp.test(url.spec))
           continue;
         var pre = "base_page_" + baseVsRefIndex + "_";
         url_array.push({ url, flags, pre });
 
-        url = gIOS.newURI(urlspecRef, null, manifestUri);
+        url = Services.io.newURI(urlspecRef, null, manifestUri);
         if (pageFilterRegexp && !pageFilterRegexp.test(url.spec))
           continue;
         pre = "ref_page_" + baseVsRefIndex + "_";
         url_array.push({ url, flags, pre });
       }
     }
   } while (more);
 
@@ -885,9 +877,8 @@ function plLoadURLsFromURI(manifestUri) 
 }
 
 function dumpLine(str) {
   if (MozillaFileLogger && MozillaFileLogger._foStream)
     MozillaFileLogger.log(str + "\n");
   dump(str);
   dump("\n");
 }
-
--- a/testing/talos/talos/pageloader/chrome/quit.js
+++ b/testing/talos/talos/pageloader/chrome/quit.js
@@ -35,27 +35,23 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
   From mozilla/toolkit/content
   These files did not have a license
 */
 
+/* import-globals-from pageloader.js */
+
 function canQuitApplication() {
-  var os = Components.classes["@mozilla.org/observer-service;1"]
-    .getService(Components.interfaces.nsIObserverService);
-  if (!os) {
-    return true;
-  }
-
   try {
     var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
       .createInstance(Components.interfaces.nsISupportsPRBool);
-    os.notifyObservers(cancelQuit, "quit-application-requested");
+    Services.obs.notifyObservers(cancelQuit, "quit-application-requested");
 
     // Something aborted the quit process.
     if (cancelQuit.data) {
       return false;
     }
   } catch (ex) {
   }
   return true;
@@ -67,28 +63,25 @@ function goQuitApplication() {
   }
 
   const kAppStartup = "@mozilla.org/toolkit/app-startup;1";
   const kAppShell   = "@mozilla.org/appshell/appShellService;1";
   var appService;
   var forceQuit;
 
   if (kAppStartup in Components.classes) {
-    appService = Components.classes[kAppStartup].
-      getService(Components.interfaces.nsIAppStartup);
+    appService = Services.startup;
     forceQuit  = Components.interfaces.nsIAppStartup.eForceQuit;
   } else if (kAppShell in Components.classes) {
-    appService = Components.classes[kAppShell].
-      getService(Components.interfaces.nsIAppShellService);
+    appService = Services.appShell;
     forceQuit = Components.interfaces.nsIAppShellService.eForceQuit;
   } else {
     throw "goQuitApplication: no AppStartup/appShell";
   }
 
   try {
     appService.quit(forceQuit);
   } catch (ex) {
     throw ("goQuitApplication: " + ex);
   }
 
   return true;
 }
-
--- a/testing/talos/talos/scripts/MozillaFileLogger.js
+++ b/testing/talos/talos/scripts/MozillaFileLogger.js
@@ -111,13 +111,14 @@ MozFileLogger.close = function() {
   if (MozFileLogger._foStream)
     MozFileLogger._foStream.close();
 
   MozFileLogger._foStream = null;
   MozFileLogger._file = null;
 };
 
 try {
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"]
-    .getService(Components.interfaces.nsIPrefBranch);
-  var filename = prefs.getCharPref("talos.logfile");
+  // ChromeUtils is not available in this scope.
+  // eslint-disable-next-line mozilla/use-chromeutils-import
+  Cu.import("resource://gre/modules/Services.jsm");
+  var filename = Services.prefs.getCharPref("talos.logfile");
   MozFileLogger.init(filename);
 } catch (ex) {} // pref does not exist, return empty string
--- a/testing/talos/talos/scripts/Profiler.js
+++ b/testing/talos/talos/scripts/Profiler.js
@@ -39,16 +39,17 @@ var Profiler;
     // Outside of talos, this throws a security exception which no-op this file.
     // (It's not required nor allowed for addons since Firefox 17)
     // It's used inside talos from non-privileged pages (like during tscroll),
     // and it works because talos disables all/most security measures.
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   } catch (e) {}
 
   try {
+    // eslint-disable-next-line mozilla/use-services
     _profiler = Components.classes["@mozilla.org/tools/profiler;1"].getService(Components.interfaces.nsIProfiler);
   } catch (ex) { (typeof(dumpLog) == "undefined" ? dump : dumpLog)(ex + "\n"); }
 
   // Parses an url query string into a JS object.
   function searchToObject(locationSearch) {
     var pairs = locationSearch.substring(1).split("&");
     var result = {};
 
--- a/testing/talos/talos/startup_test/tresize/addon/content/Profiler.js
+++ b/testing/talos/talos/startup_test/tresize/addon/content/Profiler.js
@@ -39,16 +39,17 @@ var Profiler;
     // Outside of talos, this throws a security exception which no-op this file.
     // (It's not required nor allowed for addons since Firefox 17)
     // It's used inside talos from non-privileged pages (like during tscroll),
     // and it works because talos disables all/most security measures.
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   } catch (e) {}
 
   try {
+    // eslint-disable-next-line mozilla/use-services
     _profiler = Components.classes["@mozilla.org/tools/profiler;1"].getService(Components.interfaces.nsIProfiler);
   } catch (ex) { (typeof(dumpLog) == "undefined" ? dump : dumpLog)(ex + "\n"); }
 
   // Parses an url query string into a JS object.
   function searchToObject(locationSearch) {
     var pairs = locationSearch.substring(1).split("&");
     var result = {};
 
--- a/testing/talos/talos/startup_test/tspaint_test.html
+++ b/testing/talos/talos/startup_test/tspaint_test.html
@@ -36,18 +36,20 @@ function failed() {
   dumpConsoleAndQuit();
 }
 
 function dumpConsoleAndQuit() {
   var messages = {};
 
   try {
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-    var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
-    consoleService.getMessageArray(messages, {});
+    // ChromeUtils is not available in this scope.
+    // eslint-disable-next-line mozilla/use-chromeutils-import
+    Cu.import("resource://gre/modules/Services.jsm");
+    Services.console.getMessageArray(messages, {});
   } catch (ex) {
     dumpLog(ex + "\n");
   }
 
   for (var i = 0; i < messages.value.length; i++)
     dumpLog(messages.value[i].message + "\n");
 
   // Close window asynchronously, there might still be startup operations that still need to run
--- a/testing/talos/talos/talos-powers/chrome/talos-powers-content.js
+++ b/testing/talos/talos/talos-powers/chrome/talos-powers-content.js
@@ -1,42 +1,36 @@
 /* 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/. */
 
 // This file is loaded as a framescript
+/* global docShell */
+// eslint-env mozilla/frame-script
 
-/* globals docShell */
+ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function canQuitApplication() {
-  var os = Components.classes["@mozilla.org/observer-service;1"]
-    .getService(Components.interfaces.nsIObserverService);
-  if (!os) {
-    return true;
-  }
-
   try {
     var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
       .createInstance(Components.interfaces.nsISupportsPRBool);
-    os.notifyObservers(cancelQuit, "quit-application-requested");
+    Services.obs.notifyObservers(cancelQuit, "quit-application-requested");
 
     // Something aborted the quit process.
     if (cancelQuit.data) {
       return false;
     }
   } catch (ex) {
   }
-  os.notifyObservers(null, "quit-application-granted");
+  Services.obs.notifyObservers(null, "quit-application-granted");
   return true;
 }
 
 function goQuitApplication(waitForSafeBrowsing) {
-  var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
-                 .getService(Components.interfaces.nsIXULRuntime);
-  if (xulRuntime.processType == xulRuntime.PROCESS_TYPE_CONTENT) {
+  if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
     // If we're running in a remote browser, emit an event for a
     // frame script to pick up to quit the whole browser.
     var event = new content.CustomEvent("TalosQuitApplication", {bubbles: true, detail: {waitForSafeBrowsing}});
     content.document.dispatchEvent(event);
     return false;
   }
 
   if (waitForSafeBrowsing) {
@@ -56,22 +50,19 @@ function goQuitApplication(waitForSafeBr
     return false;
   }
 
   const kAppStartup = "@mozilla.org/toolkit/app-startup;1";
   const kAppShell   = "@mozilla.org/appshell/appShellService;1";
   var appService;
 
   if (kAppStartup in Components.classes) {
-    appService = Components.classes[kAppStartup].
-      getService(Components.interfaces.nsIAppStartup);
-
+    appService = Services.startup;
   } else if (kAppShell in Components.classes) {
-    appService = Components.classes[kAppShell].
-      getService(Components.interfaces.nsIAppShellService);
+    appService = Services.appShell;
   } else {
     throw "goQuitApplication: no AppStartup/appShell";
   }
 
   var windowManager = Components.
     classes["@mozilla.org/appshell/window-mediator;1"].getService();
 
   var windowManagerInterface = windowManager.
--- a/testing/talos/talos/tests/devtools/addon/content/Profiler.js
+++ b/testing/talos/talos/tests/devtools/addon/content/Profiler.js
@@ -39,16 +39,17 @@ var Profiler;
     // Outside of talos, this throws a security exception which no-op this file.
     // (It's not required nor allowed for addons since Firefox 17)
     // It's used inside talos from non-privileged pages (like during tscroll),
     // and it works because talos disables all/most security measures.
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   } catch (e) {}
 
   try {
+    // eslint-disable-next-line mozilla/use-services
     _profiler = Components.classes["@mozilla.org/tools/profiler;1"].getService(Components.interfaces.nsIProfiler);
   } catch (ex) { (typeof(dumpLog) == "undefined" ? dump : dumpLog)(ex + "\n"); }
 
   // Parses an url query string into a JS object.
   function searchToObject(locationSearch) {
     var pairs = locationSearch.substring(1).split("&");
     var result = {};
 
--- a/testing/talos/talos/tests/devtools/addon/content/damp.js
+++ b/testing/talos/talos/tests/devtools/addon/content/damp.js
@@ -1052,18 +1052,17 @@ async _consoleOpenWithCachedMessagesTest
 
   startTest(doneCallback, config) {
     this._onTestComplete = function(results) {
       TalosParentProfiler.pause("DAMP - end");
       doneCallback(results);
     };
     this._config = config;
 
-    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
-    this._win = wm.getMostRecentWindow("navigator:browser");
+    this._win = Services.wm.getMostRecentWindow("navigator:browser");
     this._dampTab = this._win.gBrowser.selectedTab;
     this._win.gBrowser.selectedBrowser.focus(); // Unfocus the URL bar to avoid caret blink
 
     TalosParentProfiler.resume("DAMP - start");
 
     let tests = {};
 
     // Run cold test only once
--- a/testing/talos/talos/tests/tart/addon/content/Profiler.js
+++ b/testing/talos/talos/tests/tart/addon/content/Profiler.js
@@ -39,16 +39,17 @@ var Profiler;
     // Outside of talos, this throws a security exception which no-op this file.
     // (It's not required nor allowed for addons since Firefox 17)
     // It's used inside talos from non-privileged pages (like during tscroll),
     // and it works because talos disables all/most security measures.
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   } catch (e) {}
 
   try {
+    // eslint-disable-next-line mozilla/use-services
     _profiler = Components.classes["@mozilla.org/tools/profiler;1"].getService(Components.interfaces.nsIProfiler);
   } catch (ex) { (typeof(dumpLog) == "undefined" ? dump : dumpLog)(ex + "\n"); }
 
   // Parses an url query string into a JS object.
   function searchToObject(locationSearch) {
     var pairs = locationSearch.substring(1).split("&");
     var result = {};
 
--- a/testing/talos/talos/tests/tart/addon/content/tart.js
+++ b/testing/talos/talos/tests/tart/addon/content/tart.js
@@ -678,18 +678,17 @@ Tart.prototype = {
 
   startTest(doneCallback, config) {
     this._onTestComplete = function(results) {
       Profiler.mark("TART - end", true);
       doneCallback(results);
     };
     this._config = config;
 
-    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
-    this._win = wm.getMostRecentWindow("navigator:browser");
+    this._win = Services.wm.getMostRecentWindow("navigator:browser");
     this._tartTab = this._win.gBrowser.selectedTab;
     this._win.gBrowser.selectedBrowser.focus(); // Unfocus the URL bar to avoid caret blink
 
     Profiler.mark("TART - start", true);
 
     return this._startTest();
   }
 };
--- a/testing/xpcshell/example/unit/check_profile.js
+++ b/testing/xpcshell/example/unit/check_profile.js
@@ -1,35 +1,33 @@
 /* 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/. */
 
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
 function check_profile_dir(profd) {
   Assert.ok(profd.exists());
   Assert.ok(profd.isDirectory());
-  let dirSvc = Cc["@mozilla.org/file/directory_service;1"]
-                 .getService(Ci.nsIProperties);
-  let profd2 = dirSvc.get("ProfD", Ci.nsIFile);
+  let profd2 = Services.dirsvc.get("ProfD", Ci.nsIFile);
   Assert.ok(profd2.exists());
   Assert.ok(profd2.isDirectory());
   // make sure we got the same thing back...
   Assert.ok(profd.equals(profd2));
 }
 
 function check_do_get_profile(fireProfileAfterChange) {
   const observedTopics = new Map([
     ["profile-do-change", 0],
     ["profile-after-change", 0],
   ]);
   const expectedTopics = new Map(observedTopics);
 
-  const obs = Cc["@mozilla.org/observer-service;1"]
-                   .getService(Ci.nsIObserverService);
   for (let [topic, ] of observedTopics) {
-    obs.addObserver(() => {
+    Services.obs.addObserver(() => {
       let val = observedTopics.get(topic) + 1;
       observedTopics.set(topic, val);
     }, topic);
   }
 
   // Trigger profile creation.
   let profd = do_get_profile();
   check_profile_dir(profd);
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -30,19 +30,19 @@ var _cleanupFunctions = [];
 var _pendingTimers = [];
 var _profileInitialized = false;
 
 // Assigned in do_load_child_test_harness.
 var _XPCSHELL_PROCESS;
 
 // Register the testing-common resource protocol early, to have access to its
 // modules.
+var _Services = ChromeUtils.import("resource://gre/modules/Services.jsm", {}).Services;
 _register_modules_protocol_handler();
 
-var _Promise = ChromeUtils.import("resource://gre/modules/Promise.jsm", {}).Promise;
 var _PromiseTestUtils = ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm", {}).PromiseTestUtils;
 var _Task = ChromeUtils.import("resource://gre/modules/Task.jsm", {}).Task;
 
 let _NetUtil = ChromeUtils.import("resource://gre/modules/NetUtil.jsm", {}).NetUtil;
 
 Components.utils.importGlobalProperties(["XMLHttpRequest"]);
 
 // Support a common assertion library, Assert.jsm.
@@ -66,53 +66,47 @@ var _dumpLog = function(raw_msg) {
   dump("\n" + JSON.stringify(raw_msg) + "\n");
 };
 
 var _LoggerClass = ChromeUtils.import("resource://testing-common/StructuredLog.jsm", null).StructuredLogger;
 var _testLogger = new _LoggerClass("xpcshell/head.js", _dumpLog, [_add_params]);
 
 // Disable automatic network detection, so tests work correctly when
 // not connected to a network.
-{
-  let ios = Components.classes["@mozilla.org/network/io-service;1"]
-                      .getService(Components.interfaces.nsIIOService);
-  ios.manageOfflineStatus = false;
-  ios.offline = false;
-}
+_Services.io.manageOfflineStatus = false;
+_Services.io.offline = false;
 
 // Determine if we're running on parent or child
 var runningInParent = true;
 try {
+  // Don't use Services.appinfo here as it disables replacing appinfo with stubs
+  // for test usage.
+  // eslint-disable-next-line mozilla/use-services
   runningInParent = Components.classes["@mozilla.org/xre/runtime;1"].
-                    getService(Components.interfaces.nsIXULRuntime).processType
-                    == Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+                      getService(Components.interfaces.nsIXULRuntime).processType
+                      == Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
 } catch (e) { }
 
 // Only if building of places is enabled.
 if (runningInParent &&
     "mozIAsyncHistory" in Components.interfaces) {
   // Ensure places history is enabled for xpcshell-tests as some non-FF
   // apps disable it.
-  let prefs = Components.classes["@mozilla.org/preferences-service;1"]
-              .getService(Components.interfaces.nsIPrefBranch);
-  prefs.setBoolPref("places.history.enabled", true);
+  _Services.prefs.setBoolPref("places.history.enabled", true);
 }
 
 try {
   if (runningInParent) {
-    let prefs = Components.classes["@mozilla.org/preferences-service;1"]
-                .getService(Components.interfaces.nsIPrefBranch);
-
     // disable necko IPC security checks for xpcshell, as they lack the
     // docshells needed to pass them
-    prefs.setBoolPref("network.disable.ipc.security", true);
+    _Services.prefs.setBoolPref("network.disable.ipc.security", true);
 
     // Disable IPv6 lookups for 'localhost' on windows.
     if ("@mozilla.org/windows-registry-key;1" in Components.classes) {
-      prefs.setCharPref("network.dns.ipv4OnlyDomains", "localhost");
+      _Services.prefs.setCharPref("network.dns.ipv4OnlyDomains", "localhost");
     }
   }
 } catch (e) { }
 
 // Configure crash reporting, if possible
 // We rely on the Python harness to set MOZ_CRASHREPORTER,
 // MOZ_CRASHREPORTER_NO_REPORT, and handle checking for minidumps.
 // Note that if we're in a child process, we don't want to init the
@@ -144,16 +138,19 @@ try {
       }
       return this;
     },
     observe(msg) {
       if (typeof info === "function")
         info("CONSOLE_MESSAGE: (" + levelNames[msg.logLevel] + ") " + msg.toString());
     }
   };
+  // Don't use _Services.console here as it causes one of the devtools tests
+  // to fail, probably due to initializing Services.console too early.
+  // eslint-disable-next-line mozilla/use-services
   Components.classes["@mozilla.org/consoleservice;1"]
             .getService(Components.interfaces.nsIConsoleService)
             .registerListener(listener);
 } catch (e) {}
 /**
  * Date.now() is not necessarily monotonically increasing (insert sob story
  * about times not being the right tool to use for measuring intervals of time,
  * robarnold can tell all), so be wary of error by erring by at least
@@ -326,77 +323,70 @@ function do_get_idle() {
   _fakeIdleService.deactivate();
   return Components.classes[_fakeIdleService.contractID]
                    .getService(Components.interfaces.nsIIdleService);
 }
 
 // Map resource://test/ to current working directory and
 // resource://testing-common/ to the shared test modules directory.
 function _register_protocol_handlers() {
-  let ios = Components.classes["@mozilla.org/network/io-service;1"]
-                      .getService(Components.interfaces.nsIIOService);
   let protocolHandler =
-    ios.getProtocolHandler("resource")
-       .QueryInterface(Components.interfaces.nsIResProtocolHandler);
+    _Services.io.getProtocolHandler("resource")
+                .QueryInterface(Components.interfaces.nsIResProtocolHandler);
 
-  let curDirURI = ios.newFileURI(do_get_cwd());
+  let curDirURI = _Services.io.newFileURI(do_get_cwd());
   protocolHandler.setSubstitution("test", curDirURI);
 
   _register_modules_protocol_handler();
 }
 
 function _register_modules_protocol_handler() {
   if (!_TESTING_MODULES_DIR) {
     throw new Error("Please define a path where the testing modules can be " +
                     "found in a variable called '_TESTING_MODULES_DIR' before " +
                     "head.js is included.");
   }
 
-  let ios = Components.classes["@mozilla.org/network/io-service;1"]
-                      .getService(Components.interfaces.nsIIOService);
   let protocolHandler =
-    ios.getProtocolHandler("resource")
-       .QueryInterface(Components.interfaces.nsIResProtocolHandler);
+    _Services.io.getProtocolHandler("resource")
+                .QueryInterface(Components.interfaces.nsIResProtocolHandler);
 
   let modulesFile = Components.classes["@mozilla.org/file/local;1"].
                     createInstance(Components.interfaces.nsIFile);
   modulesFile.initWithPath(_TESTING_MODULES_DIR);
 
   if (!modulesFile.exists()) {
     throw new Error("Specified modules directory does not exist: " +
                     _TESTING_MODULES_DIR);
   }
 
   if (!modulesFile.isDirectory()) {
     throw new Error("Specified modules directory is not a directory: " +
                     _TESTING_MODULES_DIR);
   }
 
-  let modulesURI = ios.newFileURI(modulesFile);
+  let modulesURI = _Services.io.newFileURI(modulesFile);
 
   protocolHandler.setSubstitution("testing-common", modulesURI);
 }
 
 /* Debugging support */
 // Used locally and by our self-tests.
 function _setupDebuggerServer(breakpointFiles, callback) {
-  let prefs = Components.classes["@mozilla.org/preferences-service;1"]
-              .getService(Components.interfaces.nsIPrefBranch);
-
   // Always allow remote debugging.
-  prefs.setBoolPref("devtools.debugger.remote-enabled", true);
+  _Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
 
   // for debugging-the-debugging, let an env var cause log spew.
   let env = Components.classes["@mozilla.org/process/environment;1"]
                       .getService(Components.interfaces.nsIEnvironment);
   if (env.get("DEVTOOLS_DEBUGGER_LOG")) {
-    prefs.setBoolPref("devtools.debugger.log", true);
+    _Services.prefs.setBoolPref("devtools.debugger.log", true);
   }
   if (env.get("DEVTOOLS_DEBUGGER_LOG_VERBOSE")) {
-    prefs.setBoolPref("devtools.debugger.log.verbose", true);
+    _Services.prefs.setBoolPref("devtools.debugger.log.verbose", true);
   }
 
   let require;
   try {
     ({ require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {}));
   } catch (e) {
     throw new Error("resource://devtools appears to be inaccessible from the " +
                     "xpcshell environment.\n" +
@@ -412,19 +402,16 @@ function _setupDebuggerServer(breakpoint
   let { OriginalLocation } = require("devtools/server/actors/common");
   DebuggerServer.init();
   DebuggerServer.registerAllActors();
   DebuggerServer.addActors("resource://testing-common/dbg-actors.js");
   DebuggerServer.allowChromeProcess = true;
 
   // An observer notification that tells us when we can "resume" script
   // execution.
-  let obsSvc = Components.classes["@mozilla.org/observer-service;1"].
-               getService(Components.interfaces.nsIObserverService);
-
   const TOPICS = ["devtools-thread-resumed", "xpcshell-test-devtools-shutdown"];
   let observe = function(subject, topic, data) {
     switch (topic) {
       case "devtools-thread-resumed":
         // Exceptions in here aren't reported and block the debugger from
         // resuming, so...
         try {
           // Add a breakpoint for the first line in our test files.
@@ -439,23 +426,23 @@ function _setupDebuggerServer(breakpoint
         }
         break;
       case "xpcshell-test-devtools-shutdown":
         // the debugger has shutdown before we got a resume event - nothing
         // special to do here.
         break;
     }
     for (let topicToRemove of TOPICS) {
-      obsSvc.removeObserver(observe, topicToRemove);
+      _Services.obs.removeObserver(observe, topicToRemove);
     }
     callback();
   };
 
   for (let topic of TOPICS) {
-    obsSvc.addObserver(observe, topic);
+    _Services.obs.addObserver(observe, topic);
   }
   return DebuggerServer;
 }
 
 function _initDebugging(port) {
   let initialized = false;
   let DebuggerServer = _setupDebuggerServer(_TEST_FILE, () => { initialized = true; });
 
@@ -614,22 +601,20 @@ function _execute_test() {
   tm.spinEventLoopUntil(() => complete);
 
   // Restore idle service to avoid leaks.
   _fakeIdleService.deactivate();
 
   if (_profileInitialized) {
     // Since we have a profile, we will notify profile shutdown topics at
     // the end of the current test, to ensure correct cleanup on shutdown.
-    let obs = Components.classes["@mozilla.org/observer-service;1"]
-                        .getService(Components.interfaces.nsIObserverService);
-    obs.notifyObservers(null, "profile-change-net-teardown");
-    obs.notifyObservers(null, "profile-change-teardown");
-    obs.notifyObservers(null, "profile-before-change");
-    obs.notifyObservers(null, "profile-before-change-qm");
+    _Services.obs.notifyObservers(null, "profile-change-net-teardown");
+    _Services.obs.notifyObservers(null, "profile-change-teardown");
+    _Services.obs.notifyObservers(null, "profile-before-change");
+    _Services.obs.notifyObservers(null, "profile-before-change-qm");
 
     _profileInitialized = false;
   }
 
   try {
     _PromiseTestUtils.ensureDOMPromiseRejectionsProcessed();
     _PromiseTestUtils.assertNoUncaughtRejections();
     _PromiseTestUtils.assertNoMoreExpectedRejections();
@@ -689,20 +674,18 @@ function info(msg, data) {
  */
 function do_timeout(delay, func) {
   new _Timer(func, Number(delay));
 }
 
 function executeSoon(callback, aName) {
   let funcName = (aName ? aName : callback.name);
   do_test_pending(funcName);
-  var tm = Components.classes["@mozilla.org/thread-manager;1"]
-                     .getService(Components.interfaces.nsIThreadManager);
 
-  tm.dispatchToMainThread({
+  _Services.tm.dispatchToMainThread({
     run() {
       try {
         callback();
       } catch (e) {
         // do_check failures are already logged and set _quit to true and throw
         // NS_ERROR_ABORT. If both of those are true it is likely this exception
         // has already been logged so there is no need to log it again. It's
         // possible that this will mask an NS_ERROR_ABORT that happens after a
@@ -977,19 +960,17 @@ function do_test_finished(aName) {
                    (aName ? " " + aName : "") +
                    " finished (" + _tests_pending + ")");
   if (--_tests_pending == 0)
     _do_quit();
 }
 
 function do_get_file(path, allowNonexistent) {
   try {
-    let lf = Components.classes["@mozilla.org/file/directory_service;1"]
-      .getService(Components.interfaces.nsIProperties)
-      .get("CurWorkD", Components.interfaces.nsIFile);
+    let lf = _Services.dirsvc.get("CurWorkD", Components.interfaces.nsIFile);
 
     let bits = path.split("/");
     for (let i = 0; i < bits.length; i++) {
       if (bits[i]) {
         if (bits[i] == "..")
           lf = lf.parent;
         else
           lf.append(bits[i]);
@@ -1041,20 +1022,18 @@ function do_parse_document(aPath, aType)
       break;
 
     default:
       do_throw("type: expected application/xhtml+xml, application/xml or text/xml," +
                  " got '" + aType + "'",
                Components.stack.caller);
   }
 
-  let file = do_get_file(aPath),
-      ios = Components.classes["@mozilla.org/network/io-service;1"]
-            .getService(Components.interfaces.nsIIOService),
-      url = ios.newFileURI(file).spec;
+  let file = do_get_file(aPath);
+  let url = _Services.io.newFileURI(file).spec;
   file = null;
   return new Promise((resolve, reject) => {
     let xhr = new XMLHttpRequest();
     xhr.open("GET", url);
     xhr.responseType = "document";
     xhr.onerror = reject;
     xhr.onload = () => {
       resolve(xhr.response);
@@ -1126,18 +1105,16 @@ function do_get_profile(notifyProfileAft
   let env = Components.classes["@mozilla.org/process/environment;1"]
                       .getService(Components.interfaces.nsIEnvironment);
   // the python harness sets this in the environment for us
   let profd = env.get("XPCSHELL_TEST_PROFILE_DIR");
   let file = Components.classes["@mozilla.org/file/local;1"]
                        .createInstance(Components.interfaces.nsIFile);
   file.initWithPath(profd);
 
-  let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
-                         .getService(Components.interfaces.nsIProperties);
   let provider = {
     getFile(prop, persistent) {
       persistent.value = true;
       if (prop == "ProfD" || prop == "ProfLD" || prop == "ProfDS" ||
           prop == "ProfLDS" || prop == "TmpD") {
         return file.clone();
       }
       return null;
@@ -1145,46 +1122,41 @@ function do_get_profile(notifyProfileAft
     QueryInterface(iid) {
       if (iid.equals(Components.interfaces.nsIDirectoryServiceProvider) ||
           iid.equals(Components.interfaces.nsISupports)) {
         return this;
       }
       throw Components.results.NS_ERROR_NO_INTERFACE;
     }
   };
-  dirSvc.QueryInterface(Components.interfaces.nsIDirectoryService)
-        .registerProvider(provider);
-
-  let obsSvc = Components.classes["@mozilla.org/observer-service;1"].
-        getService(Components.interfaces.nsIObserverService);
+  _Services.dirsvc.QueryInterface(Components.interfaces.nsIDirectoryService)
+           .registerProvider(provider);
 
   // We need to update the crash events directory when the profile changes.
   if (runningInParent &&
       "@mozilla.org/toolkit/crash-reporter;1" in Components.classes) {
     let crashReporter =
         Components.classes["@mozilla.org/toolkit/crash-reporter;1"]
                           .getService(Components.interfaces.nsICrashReporter);
     crashReporter.UpdateCrashEventsDir();
   }
 
   if (!_profileInitialized) {
-    obsSvc.notifyObservers(null, "profile-do-change", "xpcshell-do-get-profile");
+    _Services.obs.notifyObservers(null, "profile-do-change", "xpcshell-do-get-profile");
     _profileInitialized = true;
     if (notifyProfileAfterChange) {
-      obsSvc.notifyObservers(null, "profile-after-change", "xpcshell-do-get-profile");
+      _Services.obs.notifyObservers(null, "profile-after-change", "xpcshell-do-get-profile");
     }
   }
 
   // The methods of 'provider' will retain this scope so null out everything
   // to avoid spurious leak reports.
   env = null;
   profd = null;
-  dirSvc = null;
   provider = null;
-  obsSvc = null;
   return file.clone();
 }
 
 /**
  * This function loads head.js (this file) in the child process, so that all
  * functions defined in this file (do_throw, etc) are available to subsequent
  * sendCommand calls.  It also sets various constants used by these functions.
  *
@@ -1488,48 +1460,39 @@ function run_next_test() {
     do_test_finished(_gRunningTest.name);
   }
 }
 
 try {
   if (runningInParent) {
     // Always use network provider for geolocation tests
     // so we bypass the OSX dialog raised by the corelocation provider
-    let prefs = Components.classes["@mozilla.org/preferences-service;1"]
-      .getService(Components.interfaces.nsIPrefBranch);
-
-    prefs.setBoolPref("geo.provider.testing", true);
+    _Services.prefs.setBoolPref("geo.provider.testing", true);
   }
 } catch (e) { }
 // We need to avoid hitting the network with certain components.
 try {
   if (runningInParent) {
-    let prefs = Components.classes["@mozilla.org/preferences-service;1"]
-      .getService(Components.interfaces.nsIPrefBranch);
-
-    prefs.setCharPref("media.gmp-manager.url.override", "http://%(server)s/dummy-gmp-manager.xml");
-    prefs.setCharPref("media.gmp-manager.updateEnabled", false);
-    prefs.setCharPref("extensions.systemAddon.update.url", "http://%(server)s/dummy-system-addons.xml");
-    prefs.setCharPref("extensions.shield-recipe-client.api_url",
-                      "https://%(server)s/selfsupport-dummy/");
-    prefs.setCharPref("toolkit.telemetry.server", "https://%(server)s/telemetry-dummy");
-    prefs.setCharPref("browser.search.geoip.url", "https://%(server)s/geoip-dummy");
-    prefs.setCharPref("browser.safebrowsing.downloads.remote.url", "https://%(server)s/safebrowsing-dummy");
+    _Services.prefs.setCharPref("media.gmp-manager.url.override", "http://%(server)s/dummy-gmp-manager.xml");
+    _Services.prefs.setCharPref("media.gmp-manager.updateEnabled", false);
+    _Services.prefs.setCharPref("extensions.systemAddon.update.url", "http://%(server)s/dummy-system-addons.xml");
+    _Services.prefs.setCharPref("extensions.shield-recipe-client.api_url",
+                                "https://%(server)s/selfsupport-dummy/");
+    _Services.prefs.setCharPref("toolkit.telemetry.server", "https://%(server)s/telemetry-dummy");
+    _Services.prefs.setCharPref("browser.search.geoip.url", "https://%(server)s/geoip-dummy");
+    _Services.prefs.setCharPref("browser.safebrowsing.downloads.remote.url", "https://%(server)s/safebrowsing-dummy");
   }
 } catch (e) { }
 
 // Make tests run consistently on DevEdition (which has a lightweight theme
 // selected by default).
 try {
   if (runningInParent) {
-    let prefs = Components.classes["@mozilla.org/preferences-service;1"]
-      .getService(Components.interfaces.nsIPrefBranch);
-
-    prefs.deleteBranch("lightweightThemes.selectedThemeID");
-    prefs.deleteBranch("browser.devedition.theme.enabled");
+    _Services.prefs.deleteBranch("lightweightThemes.selectedThemeID");
+    _Services.prefs.deleteBranch("browser.devedition.theme.enabled");
   }
 } catch (e) { }
 
 function _load_mozinfo() {
   let mozinfoFile = Components.classes["@mozilla.org/file/local;1"]
     .createInstance(Components.interfaces.nsIFile);
   mozinfoFile.initWithPath(_MOZINFO_JS_PATH);
   let stream = Components.classes["@mozilla.org/network/file-input-stream;1"]