Bug 1437584 - Enable ESLint rule mozilla/use-services for testing/. r=jmaher
authorMark Banner <standard8@mozilla.com>
Mon, 12 Feb 2018 17:10:00 +0000
changeset 404557 a8300f975833c8ddd95cb1537343de8634a42d37
parent 404556 ecb24bcac0cf500f3bb66705a5f947b74b1e1ab0
child 404558 f57e04801a922a8f680f892b41e6f2b4811709ca
push id33482
push userrgurzau@mozilla.com
push dateWed, 21 Feb 2018 10:00:30 +0000
treeherdermozilla-central@bb0271610fd8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1437584
milestone60.0a1
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
Bug 1437584 - Enable ESLint rule mozilla/use-services for testing/. r=jmaher 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
@@ -54,19 +54,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;
 };
 
@@ -151,20 +148,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) {
@@ -176,28 +170,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);
@@ -828,17 +820,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;
@@ -881,35 +873,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);
 
@@ -917,9 +909,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"]