Bug 1420422 - Enable ESLint rule mozilla/use-services for services/. r?markh draft
authorMark Banner <standard8@mozilla.com>
Fri, 24 Nov 2017 14:46:33 +0000
changeset 703642 d5cbd1198abdcd4ba805778c6778eba3b34ef4fc
parent 703549 da90245d47b17c750560dedb5cbe1973181166e3
child 741850 a7f107446b08f4876ca16c955814159afbd055ef
push id90903
push userbmo:standard8@mozilla.com
push dateMon, 27 Nov 2017 10:15:53 +0000
reviewersmarkh
bugs1420422
milestone59.0a1
Bug 1420422 - Enable ESLint rule mozilla/use-services for services/. r?markh MozReview-Commit-ID: LQiMr3ppDuG
services/.eslintrc.js
services/common/blocklist-clients.js
services/common/observers.js
services/common/tests/unit/test_blocklist_pinning.js
services/crypto/tests/unit/head_helpers.js
services/sync/Weave.js
services/sync/modules/engines/bookmarks.js
services/sync/modules/engines/prefs.js
services/sync/modules/util.js
services/sync/tests/unit/test_addon_utils.js
services/sync/tests/unit/test_addons_store.js
services/sync/tests/unit/test_bookmark_engine.js
services/sync/tests/unit/test_places_guid_downgrade.js
services/sync/tests/unit/test_resource_header.js
services/sync/tests/unit/test_utils_misc.js
services/sync/tps/extensions/tps/components/tps-cmdline.js
services/sync/tps/extensions/tps/resource/logger.jsm
services/sync/tps/extensions/tps/resource/modules/prefs.jsm
services/sync/tps/extensions/tps/resource/modules/tabs.jsm
services/sync/tps/extensions/tps/resource/modules/windows.jsm
services/sync/tps/extensions/tps/resource/quit.js
services/sync/tps/extensions/tps/resource/tps.jsm
--- a/services/.eslintrc.js
+++ b/services/.eslintrc.js
@@ -1,10 +1,12 @@
 "use strict";
 
 module.exports = {
   plugins: [
     "mozilla"
   ],
   "rules": {
     "no-throw-literal": 2,
+
+    "mozilla/use-services": "error",
   },
 }
--- a/services/common/blocklist-clients.js
+++ b/services/common/blocklist-clients.js
@@ -376,30 +376,28 @@ async function updateCertBlocklist(recor
  * collection.
  *
  * @param {Object} records   current records in the local db.
  */
 async function updatePinningList(records) {
   if (!Services.prefs.getBoolPref(PREF_BLOCKLIST_PINNING_ENABLED)) {
     return;
   }
-  const appInfo = Cc["@mozilla.org/xre/app-info;1"]
-      .getService(Ci.nsIXULAppInfo);
 
   const siteSecurityService = Cc["@mozilla.org/ssservice;1"]
       .getService(Ci.nsISiteSecurityService);
 
   // clear the current preload list
   siteSecurityService.clearPreloads();
 
   // write each KeyPin entry to the preload list
   for (let item of records) {
     try {
       const {pinType, pins = [], versions} = item;
-      if (versions.indexOf(appInfo.version) != -1) {
+      if (versions.indexOf(Services.appinfo.version) != -1) {
         if (pinType == "KeyPin" && pins.length) {
           siteSecurityService.setKeyPins(item.hostName,
               item.includeSubdomains,
               item.expires,
               pins.length,
               pins, true);
         }
         if (pinType == "STSPin") {
--- a/services/common/observers.js
+++ b/services/common/observers.js
@@ -5,16 +5,17 @@
 this.EXPORTED_SYMBOLS = ["Observers"];
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cr = Components.results;
 var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 /**
  * A service for adding, removing and notifying observers of notifications.
  * Wraps the nsIObserverService interface.
  *
  * @version 0.2
  */
 this.Observers = {
@@ -31,17 +32,17 @@ this.Observers = {
    * @param   thisObject  {Object}  [optional]
    *          the object to use as |this| when calling a Function callback
    *
    * @returns the observer
    */
   add(topic, callback, thisObject) {
     let observer = new Observer(topic, callback, thisObject);
     this._cache.push(observer);
-    this._service.addObserver(observer, topic, true);
+    Services.obs.addObserver(observer, topic, true);
 
     return observer;
   },
 
   /**
    * Unregister the given callback as an observer of the given topic.
    *
    * @param topic       {String}
@@ -57,17 +58,17 @@ this.Observers = {
     // This seems fairly inefficient, but I'm not sure how much better
     // we can make it.  We could index by topic, but we can't index by callback
     // or thisObject, as far as I know, since the keys to JavaScript hashes
     // (a.k.a. objects) can apparently only be primitive values.
     let [observer] = this._cache.filter(v => v.topic == topic &&
                                              v.callback == callback &&
                                              v.thisObject == thisObject);
     if (observer) {
-      this._service.removeObserver(observer, topic);
+      Services.obs.removeObserver(observer, topic);
       this._cache.splice(this._cache.indexOf(observer), 1);
     } else {
       throw new Error("Attempt to remove non-existing observer");
     }
   },
 
   /**
    * Notify observers about something.
@@ -83,22 +84,19 @@ this.Observers = {
    *        is sufficient to pass all needed information to the JS observers
    *        that this module targets; if you have multiple values to pass to
    *        the observer, wrap them in an object and pass them via the subject
    *        parameter (i.e.: { foo: 1, bar: "some string", baz: myObject })
    */
   notify(topic, subject, data) {
     subject = (typeof subject == "undefined") ? null : new Subject(subject);
        data = (typeof data == "undefined") ? null : data;
-    this._service.notifyObservers(subject, topic, data);
+    Services.obs.notifyObservers(subject, topic, data);
   },
 
-  _service: Cc["@mozilla.org/observer-service;1"].
-            getService(Ci.nsIObserverService),
-
   /**
    * A cache of observers that have been added.
    *
    * We use this to remove observers when a caller calls |remove|.
    *
    * XXX This might result in reference cycles, causing memory leaks,
    * if we hold a reference to an observer that holds a reference to us.
    * Could we fix that by making this an independent top-level object
--- a/services/common/tests/unit/test_blocklist_pinning.js
+++ b/services/common/tests/unit/test_blocklist_pinning.js
@@ -2,17 +2,17 @@
 
 const { Constructor: CC } = Components;
 
 Cu.import("resource://testing-common/httpd.js");
 
 const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
   "nsIBinaryInputStream", "setInputStream");
 
-// First, we need to setup appInfo or we can't do version checks
+// First, we need to setup Services.appinfo or we can't do version checks
 var id = "xpcshell@tests.mozilla.org";
 var appName = "XPCShell";
 var version = "1";
 var platformVersion = "1.9.2";
 Cu.import("resource://testing-common/AppInfo.jsm", this);
 
 updateAppInfo({
   name: appName,
@@ -161,19 +161,16 @@ function run_test() {
 
   do_register_cleanup(function() {
     server.stop(() => { });
   });
 }
 
 // get a response for a given request from sample data
 function getSampleResponse(req, port) {
-  const appInfo = Cc["@mozilla.org/xre/app-info;1"]
-                     .getService(Ci.nsIXULAppInfo);
-
   const responses = {
     "OPTIONS": {
       "sampleHeaders": [
         "Access-Control-Allow-Headers: Content-Length,Expires,Backoff,Retry-After,Last-Modified,Total-Records,ETag,Pragma,Cache-Control,authorization,content-type,if-none-match,Alert,Next-Page",
         "Access-Control-Allow-Methods: GET,HEAD,OPTIONS,POST,DELETE,OPTIONS",
         "Access-Control-Allow-Origin: *",
         "Content-Type: application/json; charset=UTF-8",
         "Server: waitress"
@@ -211,17 +208,17 @@ function getSampleResponse(req, port) {
       "status": {status: 200, statusText: "OK"},
       "responseBody": JSON.stringify({"data": [{
         "pinType": "KeyPin",
         "hostName": "one.example.com",
         "includeSubdomains": false,
         "expires": new Date().getTime() + 1000000,
         "pins": ["cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
                   "M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="],
-        "versions": [appInfo.version],
+        "versions": [Services.appinfo.version],
         "id": "78cf8900-fdea-4ce5-f8fb-b78710617718",
         "last_modified": 3000
       }]})
     },
     "GET:/v1/buckets/pinning/collections/pins/records?_sort=-last_modified&_since=3000": {
       "sampleHeaders": [
         "Access-Control-Allow-Origin: *",
         "Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff",
@@ -232,27 +229,27 @@ function getSampleResponse(req, port) {
       "status": {status: 200, statusText: "OK"},
       "responseBody": JSON.stringify({"data": [{
         "pinType": "KeyPin",
         "hostName": "two.example.com",
         "includeSubdomains": false,
         "expires": new Date().getTime() + 1000000,
         "pins": ["cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
                   "M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="],
-        "versions": [appInfo.version],
+        "versions": [Services.appinfo.version],
         "id": "dabafde9-df4a-ddba-2548-748da04cc02c",
         "last_modified": 4000
       }, {
         "pinType": "KeyPin",
         "hostName": "three.example.com",
         "includeSubdomains": false,
         "expires": new Date().getTime() + 1000000,
         "pins": ["cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
                   "M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="],
-        "versions": [appInfo.version, "some other version that won't match"],
+        "versions": [Services.appinfo.version, "some other version that won't match"],
         "id": "dabafde9-df4a-ddba-2548-748da04cc02d",
         "last_modified": 4000
       }, {
         "pinType": "KeyPin",
         "hostName": "four.example.com",
         "includeSubdomains": false,
         "expires": new Date().getTime() + 1000000,
         "pins": ["cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
@@ -260,17 +257,17 @@ function getSampleResponse(req, port) {
         "versions": ["some version that won't match"],
         "id": "dabafde9-df4a-ddba-2548-748da04cc02e",
         "last_modified": 4000
       }, {
         "pinType": "STSPin",
         "hostName": "five.example.com",
         "includeSubdomains": false,
         "expires": new Date().getTime() + 1000000,
-        "versions": [appInfo.version, "some version that won't match"],
+        "versions": [Services.appinfo.version, "some version that won't match"],
         "id": "dabafde9-df4a-ddba-2548-748da04cc032",
         "last_modified": 4000
       }]})
     },
     "GET:/v1/buckets/pinning/collections/pins/records?_sort=-last_modified&_since=4000": {
       "sampleHeaders": [
         "Access-Control-Allow-Origin: *",
         "Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff",
@@ -294,25 +291,25 @@ function getSampleResponse(req, port) {
         "id": "dabafde9-df4a-ddba-2548-748da04cc030",
         "last_modified": 5000
       }, {
         "irrelevant": "this entry is missing the actual pins",
         "pinType": "KeyPin",
         "hostName": "missingpins.example.com",
         "includeSubdomains": false,
         "expires": new Date().getTime() + 1000000,
-        "versions": [appInfo.version],
+        "versions": [Services.appinfo.version],
         "id": "dabafde9-df4a-ddba-2548-748da04cc031",
         "last_modified": 5000
       }, {
         "pinType": "STSPin",
         "hostName": "five.example.com",
         "includeSubdomains": true,
         "expires": new Date().getTime() + 1000000,
-        "versions": [appInfo.version, "some version that won't match"],
+        "versions": [Services.appinfo.version, "some version that won't match"],
         "id": "dabafde9-df4a-ddba-2548-748da04cc032",
         "last_modified": 5000
       }]})
     }
   };
   return responses[`${req.method}:${req.path}?${req.queryString}`] ||
          responses[req.method];
 
--- a/services/crypto/tests/unit/head_helpers.js
+++ b/services/crypto/tests/unit/head_helpers.js
@@ -4,16 +4,17 @@ var Cr = Components.results;
 var Cu = Components.utils;
 
 /* import-globals-from ../../../common/tests/unit/head_helpers.js */
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 try {
   // In the context of xpcshell tests, there won't be a default AppInfo
+  // eslint-disable-next-line mozilla/use-services
   Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
 } catch (ex) {
 
 // Make sure to provide the right OS so crypto loads the right binaries
 var OS = "XPCShell";
 if (mozinfo.os == "win")
   OS = "WINNT";
 else if (mozinfo.os == "mac")
--- a/services/sync/Weave.js
+++ b/services/sync/Weave.js
@@ -150,19 +150,18 @@ AboutWeaveLog.prototype = {
     let channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
 
     channel.originalURI = aURI;
 
     // Ensure that the about page has the same privileges as a regular directory
     // view. That way links to files can be opened. make sure we use the correct
     // origin attributes when creating the principal for accessing the
     // about:sync-log data.
-    let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
-                .getService(Ci.nsIScriptSecurityManager);
-    let principal = ssm.createCodebasePrincipal(uri, aLoadInfo.originAttributes);
+    let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri,
+      aLoadInfo.originAttributes);
 
     channel.owner = principal;
     return channel;
   }
 };
 
 const components = [WeaveService, AboutWeaveLog];
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/services/sync/modules/engines/bookmarks.js
+++ b/services/sync/modules/engines/bookmarks.js
@@ -16,19 +16,17 @@ Cu.import("resource://services-common/as
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/record.js");
 Cu.import("resource://services-sync/util.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "BookmarkValidator",
                                   "resource://services-sync/bookmark_validator.js");
 XPCOMUtils.defineLazyGetter(this, "PlacesBundle", () => {
-  let bundleService = Cc["@mozilla.org/intl/stringbundle;1"]
-                        .getService(Ci.nsIStringBundleService);
-  return bundleService.createBundle("chrome://places/locale/places.properties");
+  return Services.strings.createBundle("chrome://places/locale/places.properties");
 });
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesSyncUtils",
                                   "resource://gre/modules/PlacesSyncUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups",
                                   "resource://gre/modules/PlacesBackups.jsm");
 
--- a/services/sync/modules/engines/prefs.js
+++ b/services/sync/modules/engines/prefs.js
@@ -86,20 +86,18 @@ PrefStore.prototype = {
   get _prefs() {
     if (!this.__prefs) {
       this.__prefs = new Preferences();
     }
     return this.__prefs;
   },
 
   _getSyncPrefs() {
-    let syncPrefs = Cc["@mozilla.org/preferences-service;1"]
-                      .getService(Ci.nsIPrefService)
-                      .getBranch(PREF_SYNC_PREFS_PREFIX)
-                      .getChildList("", {});
+    let syncPrefs = Services.prefs.getBranch(PREF_SYNC_PREFS_PREFIX)
+                                  .getChildList("", {});
     // Also sync preferences that determine which prefs get synced.
     let controlPrefs = syncPrefs.map(pref => PREF_SYNC_PREFS_PREFIX + pref);
     return controlPrefs.concat(syncPrefs);
   },
 
   _isSynced(pref) {
     return pref.startsWith(PREF_SYNC_PREFS_PREFIX) ||
            this._prefs.get(PREF_SYNC_PREFS_PREFIX + pref, false);
--- a/services/sync/modules/util.js
+++ b/services/sync/modules/util.js
@@ -611,17 +611,17 @@ this.Utils = {
     try {
       // hostname of the system, usually assigned by the user or admin
       hostname = Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService).myHostName;
     } catch (ex) {
       Cu.reportError(ex);
     }
     let system =
       // 'device' is defined on unix systems
-      Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2).get("device") ||
+      Services.sysinfo.get("device") ||
       hostname ||
       // fall back on ua info string
       Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).oscpu;
 
     let syncStrings = Services.strings.createBundle("chrome://weave/locale/sync.properties");
     return syncStrings.formatStringFromName("client.name2", [user, brandName, system], 3);
   },
 
--- a/services/sync/tests/unit/test_addon_utils.js
+++ b/services/sync/tests/unit/test_addon_utils.js
@@ -64,35 +64,32 @@ add_test(function test_handle_empty_sour
   do_check_true(result.skipped.includes(ID));
 
   server.stop(run_next_test);
 });
 
 add_test(function test_ignore_untrusted_source_uris() {
   _("Ensures that source URIs from insecure schemes are rejected.");
 
-  let ioService = Cc["@mozilla.org/network/io-service;1"]
-                  .getService(Ci.nsIIOService);
-
   const bad = ["http://example.com/foo.xpi",
                "ftp://example.com/foo.xpi",
                "silly://example.com/foo.xpi"];
 
   const good = ["https://example.com/foo.xpi"];
 
   for (let s of bad) {
-    let sourceURI = ioService.newURI(s);
+    let sourceURI = Services.io.newURI(s);
     let addon = {sourceURI, name: "bad", id: "bad"};
 
     let canInstall = AddonUtils.canInstallAddon(addon);
     do_check_false(canInstall, "Correctly rejected a bad URL");
   }
 
   for (let s of good) {
-    let sourceURI = ioService.newURI(s);
+    let sourceURI = Services.io.newURI(s);
     let addon = {sourceURI, name: "good", id: "good"};
 
     let canInstall = AddonUtils.canInstallAddon(addon);
     do_check_true(canInstall, "Correctly accepted a good URL");
   }
   run_next_test();
 });
 
--- a/services/sync/tests/unit/test_addons_store.js
+++ b/services/sync/tests/unit/test_addons_store.js
@@ -290,48 +290,42 @@ add_test(function test_addon_syncability
   dummy.foreignInstall = true;
   do_check_false(store.isAddonSyncable(dummy));
   dummy.foreignInstall = false;
 
   uninstallAddon(addon);
 
   do_check_false(store.isSourceURITrusted(null));
 
-  function createURI(s) {
-    let service = Components.classes["@mozilla.org/network/io-service;1"]
-                  .getService(Components.interfaces.nsIIOService);
-    return service.newURI(s);
-  }
-
   let trusted = [
     "https://addons.mozilla.org/foo",
     "https://other.example.com/foo"
   ];
 
   let untrusted = [
     "http://addons.mozilla.org/foo",     // non-https
     "ftps://addons.mozilla.org/foo",     // non-https
     "https://untrusted.example.com/foo", // non-trusted hostname`
   ];
 
   for (let uri of trusted) {
-    do_check_true(store.isSourceURITrusted(createURI(uri)));
+    do_check_true(store.isSourceURITrusted(Services.io.newURI(uri)));
   }
 
   for (let uri of untrusted) {
-    do_check_false(store.isSourceURITrusted(createURI(uri)));
+    do_check_false(store.isSourceURITrusted(Services.io.newURI(uri)));
   }
 
   Svc.Prefs.set("addons.trustedSourceHostnames", "");
   for (let uri of trusted) {
-    do_check_false(store.isSourceURITrusted(createURI(uri)));
+    do_check_false(store.isSourceURITrusted(Services.io.newURI(uri)));
   }
 
   Svc.Prefs.set("addons.trustedSourceHostnames", "addons.mozilla.org");
-  do_check_true(store.isSourceURITrusted(createURI("https://addons.mozilla.org/foo")));
+  do_check_true(store.isSourceURITrusted(Services.io.newURI("https://addons.mozilla.org/foo")));
 
   Svc.Prefs.reset("addons.trustedSourceHostnames");
 
   run_next_test();
 });
 
 add_test(function test_ignore_hotfixes() {
   _("Ensure that hotfix extensions are ignored.");
@@ -351,19 +345,17 @@ add_test(function test_ignore_hotfixes()
 
   // Basic sanity check.
   do_check_true(store.isAddonSyncable(dummy));
 
   extensionPrefs.set("hotfix.id", dummy.id);
   do_check_false(store.isAddonSyncable(dummy));
 
   // Verify that int values don't throw off checking.
-  let prefSvc = Cc["@mozilla.org/preferences-service;1"]
-                .getService(Ci.nsIPrefService)
-                .getBranch("extensions.");
+  let prefSvc = Services.prefs.getBranch("extensions.");
   // Need to delete pref before changing type.
   prefSvc.deleteBranch("hotfix.id");
   prefSvc.setIntPref("hotfix.id", 0xdeadbeef);
 
   do_check_true(store.isAddonSyncable(dummy));
 
   uninstallAddon(addon);
 
--- a/services/sync/tests/unit/test_bookmark_engine.js
+++ b/services/sync/tests/unit/test_bookmark_engine.js
@@ -248,20 +248,17 @@ async function test_restoreOrImport(aRep
     _("Create a single record.");
     let bmk1 = await PlacesUtils.bookmarks.insert({
       parentGuid: folder1.guid,
       url: "http://getfirefox.com/",
       title: "Get Firefox!",
     });
     _(`Get Firefox!: ${bmk1.guid}`);
 
-    let dirSvc = Cc["@mozilla.org/file/directory_service;1"]
-      .getService(Ci.nsIProperties);
-
-    let backupFile = dirSvc.get("TmpD", Ci.nsIFile);
+    let backupFile = Services.dirsvc.get("TmpD", Ci.nsIFile);
 
     _("Make a backup.");
     backupFile.append("t_b_e_" + Date.now() + ".json");
 
     _(`Backing up to file ${backupFile.path}`);
     await bookmarkUtils.exportToFile(backupFile.path);
 
     _("Create a different record and sync.");
--- a/services/sync/tests/unit/test_places_guid_downgrade.js
+++ b/services/sync/tests/unit/test_places_guid_downgrade.js
@@ -4,18 +4,16 @@
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/history.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
 
 const kDBName = "places.sqlite";
-const storageSvc = Cc["@mozilla.org/storage/service;1"]
-                     .getService(Ci.mozIStorageService);
 
 function setPlacesDatabase(aFileName) {
   removePlacesDatabase();
   _("Copying over places.sqlite.");
   let file = do_get_file(aFileName);
   file.copyTo(gSyncProfile, kDBName);
 }
 
@@ -38,17 +36,17 @@ Svc.Obs.add("places-shutdown", function(
 // Verify initial database state. Function borrowed from places tests.
 add_test(function test_initial_state() {
   _("Verify initial setup: v11 database is available");
 
   // Mostly sanity checks our starting DB to make sure it's setup as we expect
   // it to be.
   let dbFile = gSyncProfile.clone();
   dbFile.append(kDBName);
-  let db = storageSvc.openUnsharedDatabase(dbFile);
+  let db = Services.storage.openUnsharedDatabase(dbFile);
 
   let stmt = db.createStatement("PRAGMA journal_mode");
   do_check_true(stmt.executeStep());
   // WAL journal mode should have been unset this database when it was migrated
   // down to v10.
   do_check_neq(stmt.getString(0).toLowerCase(), "wal");
   stmt.finalize();
 
--- a/services/sync/tests/unit/test_resource_header.js
+++ b/services/sync/tests/unit/test_resource_header.js
@@ -35,18 +35,17 @@ function contentHandler(metadata, respon
 
 // Set a proxy function to cause an internal redirect.
 function triggerRedirect() {
   const PROXY_FUNCTION = "function FindProxyForURL(url, host) {" +
                          "  return 'PROXY a_non_existent_domain_x7x6c572v:80; " +
                                    "PROXY localhost:" + HTTP_PORT + "';" +
                          "}";
 
-  let prefsService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
-  let prefs = prefsService.getBranch("network.proxy.");
+  let prefs = Services.prefs.getBranch("network.proxy.");
   prefs.setIntPref("type", 2);
   prefs.setCharPref("autoconfig_url", "data:text/plain," + PROXY_FUNCTION);
 }
 
 add_task(async function test_headers_copied() {
   triggerRedirect();
 
   _("Issuing request.");
--- a/services/sync/tests/unit/test_utils_misc.js
+++ b/services/sync/tests/unit/test_utils_misc.js
@@ -7,17 +7,17 @@ add_test(function test_default_device_na
   // We are just hoping to avoid a repeat of bug 1369285.
   let def = Utils._orig_getDefaultDeviceName(); // make sure it doesn't throw.
   _("default value is " + def);
   ok(def.length > 0);
 
   // This is obviously tied to the implementation, but we want early warning
   // if any of these things fail.
   // We really want one of these 2 to provide a value.
-  let hostname = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2).get("device") ||
+  let hostname = Services.sysinfo.get("device") ||
                  Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService).myHostName;
   _("hostname is " + hostname);
   ok(hostname.length > 0);
   // the hostname should be in the default.
   ok(def.includes(hostname));
   // We expect the following to work as a fallback to the above.
   let fallback = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).oscpu;
   _("UA fallback is " + fallback);
--- a/services/sync/tps/extensions/tps/components/tps-cmdline.js
+++ b/services/sync/tps/extensions/tps/components/tps-cmdline.js
@@ -58,20 +58,18 @@ TPSCmdLineHandler.prototype = {
 
     options.ignoreUnusedEngines = cmdLine.handleFlag("ignore-unused-engines",
                                                      false);
     let uri = cmdLine.resolveURI(OS.Path.normalize(uristr)).spec;
 
     const onStartupFinished = () => {
       Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished");
       /* Ignore the platform's online/offline status while running tests. */
-      var 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;
       Components.utils.import("resource://tps/tps.jsm");
       Components.utils.import("resource://tps/quit.js", TPS);
       TPS.RunTestPhase(uri, phase, logfile, options).catch(err => TPS.DumpError("TestPhase failed", err));
     };
     Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished");
   },
 
   helpInfo: "  --tps <file>              Run TPS tests with the given test file.\n" +
--- a/services/sync/tps/extensions/tps/resource/logger.jsm
+++ b/services/sync/tps/extensions/tps/resource/logger.jsm
@@ -6,33 +6,33 @@
     Components.utils.import() and acts as a singleton.
     Only the following listed symbols will exposed on import, and only when
     and where imported. */
 
 var EXPORTED_SYMBOLS = ["Logger"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 var Logger = {
   _foStream: null,
   _converter: null,
   _potentialError: null,
 
   init(path) {
     if (this._converter != null) {
       // we're already open!
       return;
     }
 
-    let prefs = Cc["@mozilla.org/preferences-service;1"]
-                .getService(Ci.nsIPrefBranch);
     if (path) {
-      prefs.setCharPref("tps.logfile", path);
+      Services.prefs.setCharPref("tps.logfile", path);
     } else {
-      path = prefs.getCharPref("tps.logfile");
+      path = Services.prefs.getCharPref("tps.logfile");
     }
 
     this._file = Cc["@mozilla.org/file/local;1"]
                  .createInstance(Ci.nsIFile);
     this._file.initWithPath(path);
     var exists = this._file.exists();
 
     // Make a file output stream and converter to handle it.
@@ -138,9 +138,8 @@ var Logger = {
     else
       this.log("CROSSWEAVE INFO: " + msg);
   },
 
   logPass(msg) {
     this.log("CROSSWEAVE TEST PASS: " + msg);
   },
 };
-
--- a/services/sync/tps/extensions/tps/resource/modules/prefs.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/prefs.jsm
@@ -8,19 +8,17 @@
    and where imported. */
 
 var EXPORTED_SYMBOLS = ["Preference"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 const WEAVE_PREF_PREFIX = "services.sync.prefs.sync.";
 
-var prefs = Cc["@mozilla.org/preferences-service;1"]
-            .getService(Ci.nsIPrefBranch);
-
+Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://tps/logger.jsm");
 
 /**
  * Preference class constructor
  *
  * Initializes instance properties.
  */
 function Preference(props) {
@@ -42,41 +40,41 @@ Preference.prototype = {
    * Throws on error.
    *
    * @return nothing
    */
   Modify() {
     // Determine if this pref is actually something Weave even looks at.
     let weavepref = WEAVE_PREF_PREFIX + this.name;
     try {
-      let syncPref = prefs.getBoolPref(weavepref);
+      let syncPref = Services.prefs.getBoolPref(weavepref);
       if (!syncPref)
-        prefs.setBoolPref(weavepref, true);
+        Services.prefs.setBoolPref(weavepref, true);
     } catch (e) {
       Logger.AssertTrue(false, "Weave doesn't sync pref " + this.name);
     }
 
     // Modify the pref; throw an exception if the pref type is different
     // than the value type specified in the test.
-    let prefType = prefs.getPrefType(this.name);
+    let prefType = Services.prefs.getPrefType(this.name);
     switch (prefType) {
       case Ci.nsIPrefBranch.PREF_INT:
         Logger.AssertEqual(typeof(this.value), "number",
           "Wrong type used for preference value");
-        prefs.setIntPref(this.name, this.value);
+        Services.prefs.setIntPref(this.name, this.value);
         break;
       case Ci.nsIPrefBranch.PREF_STRING:
         Logger.AssertEqual(typeof(this.value), "string",
           "Wrong type used for preference value");
-        prefs.setCharPref(this.name, this.value);
+        Services.prefs.setCharPref(this.name, this.value);
         break;
       case Ci.nsIPrefBranch.PREF_BOOL:
         Logger.AssertEqual(typeof(this.value), "boolean",
           "Wrong type used for preference value");
-        prefs.setBoolPref(this.name, this.value);
+        Services.prefs.setBoolPref(this.name, this.value);
         break;
     }
   },
 
   /**
    * Find
    *
    * Verifies that the preference this.name has the value
@@ -84,32 +82,31 @@ Preference.prototype = {
    * doesn't match.
    *
    * @return nothing
    */
   Find() {
     // Read the pref value.
     let value;
     try {
-      let prefType = prefs.getPrefType(this.name);
+      let prefType = Services.prefs.getPrefType(this.name);
       switch (prefType) {
         case Ci.nsIPrefBranch.PREF_INT:
-          value = prefs.getIntPref(this.name);
+          value = Services.prefs.getIntPref(this.name);
           break;
         case Ci.nsIPrefBranch.PREF_STRING:
-          value = prefs.getCharPref(this.name);
+          value = Services.prefs.getCharPref(this.name);
           break;
         case Ci.nsIPrefBranch.PREF_BOOL:
-          value = prefs.getBoolPref(this.name);
+          value = Services.prefs.getBoolPref(this.name);
           break;
       }
     } catch (e) {
       Logger.AssertTrue(false, "Error accessing pref " + this.name);
     }
 
     // Throw an exception if the current and expected values aren't of
     // the same type, or don't have the same values.
     Logger.AssertEqual(typeof(value), typeof(this.value),
       "Value types don't match");
     Logger.AssertEqual(value, this.value, "Preference values don't match");
   },
 };
-
--- a/services/sync/tps/extensions/tps/resource/modules/tabs.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/tabs.jsm
@@ -6,16 +6,17 @@
    Components.utils.import() and acts as a singleton.
    Only the following listed symbols will exposed on import, and only when
    and where imported. */
 
 const EXPORTED_SYMBOLS = ["BrowserTabs"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
+Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://services-sync/main.js");
 
 // Unfortunately, due to where TPS is run, we can't directly reuse the logic from
 // BrowserTestUtils.jsm. Moreover, we can't resolve the URI it loads the content
 // frame script from ("chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js"),
 // hence the hackiness here and in BrowserTabs.Add.
 Cc["@mozilla.org/globalmessagemanager;1"]
 .getService(Ci.nsIMessageListenerManager)
@@ -35,19 +36,17 @@ var BrowserTabs = {
    *
    * @param uri The uri to load in the new tab
    * @return nothing
    */
   Add(uri, fn) {
 
     // Open the uri in a new tab in the current browser window, and calls
     // the callback fn from the tab's onload handler.
-    let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
-               .getService(Ci.nsIWindowMediator);
-    let mainWindow = wm.getMostRecentWindow("navigator:browser");
+    let mainWindow = Services.wm.getMostRecentWindow("navigator:browser");
     let browser = mainWindow.getBrowser();
     let mm = browser.ownerGlobal.messageManager;
     mm.addMessageListener("tps:loadEvent", function onLoad(msg) {
       mm.removeMessageListener("tps:loadEvent", onLoad);
       fn();
     });
     let newtab = browser.addTab(uri);
     browser.selectedTab = newtab;
@@ -77,9 +76,8 @@ var BrowserTabs = {
         if (uri == weaveTabUrl && profile == client.clientName)
           if (title == undefined || title == tab.title)
             return true;
       }
     }
     return false;
   },
 };
-
--- a/services/sync/tps/extensions/tps/resource/modules/windows.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/windows.jsm
@@ -7,29 +7,28 @@
    Components.utils.import() and acts as a singleton.
    Only the following listed symbols will exposed on import, and only when
    and where imported. */
 
 const EXPORTED_SYMBOLS = ["BrowserWindows"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
+Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://services-sync/main.js");
 
 var BrowserWindows = {
   /**
    * Add
    *
    * Opens a new window. Throws on error.
    *
    * @param aPrivate The private option.
    * @return nothing
    */
   Add(aPrivate, fn) {
-    let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
-               .getService(Ci.nsIWindowMediator);
-    let mainWindow = wm.getMostRecentWindow("navigator:browser");
+    let mainWindow = Services.wm.getMostRecentWindow("navigator:browser");
     let win = mainWindow.OpenBrowserWindow({private: aPrivate});
     win.addEventListener("load", function() {
       fn.call(win);
     }, {once: true});
   }
 };
--- a/services/sync/tps/extensions/tps/resource/quit.js
+++ b/services/sync/tps/extensions/tps/resource/quit.js
@@ -32,28 +32,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 new Error("goQuitApplication: no AppStartup/appShell");
   }
 
   try {
     appService.quit(forceQuit);
   } catch (ex) {
     throw new Error(`goQuitApplication: ${ex.message}`);
   }
 
   return true;
 }
-
--- a/services/sync/tps/extensions/tps/resource/tps.jsm
+++ b/services/sync/tps/extensions/tps/resource/tps.jsm
@@ -43,18 +43,16 @@ Cu.import("resource://tps/modules/forms.
 Cu.import("resource://tps/modules/history.jsm");
 Cu.import("resource://tps/modules/passwords.jsm");
 Cu.import("resource://tps/modules/prefs.jsm");
 Cu.import("resource://tps/modules/tabs.jsm");
 Cu.import("resource://tps/modules/windows.jsm");
 
 var hh = Cc["@mozilla.org/network/protocol;1?name=http"]
          .getService(Ci.nsIHttpProtocolHandler);
-var prefs = Cc["@mozilla.org/preferences-service;1"]
-            .getService(Ci.nsIPrefBranch);
 
 XPCOMUtils.defineLazyGetter(this, "fileProtocolHandler", () => {
   let fileHandler = Services.io.getProtocolHandler("file");
   return fileHandler.QueryInterface(Ci.nsIFileProtocolHandler);
 });
 
 XPCOMUtils.defineLazyGetter(this, "gTextDecoder", () => {
   return new TextDecoder();
@@ -739,17 +737,17 @@ var TPS = {
         SyncTelemetry.shutdown();
         // we're all done
         Logger.logInfo("test phase " + this._currentPhase + ": " +
                        (this._errors ? "FAIL" : "PASS"));
         this._phaseFinished = true;
         this.quit();
         return;
       }
-      this.seconds_since_epoch = prefs.getIntPref("tps.seconds_since_epoch");
+      this.seconds_since_epoch = Services.prefs.getIntPref("tps.seconds_since_epoch");
       if (this.seconds_since_epoch)
         this._usSinceEpoch = this.seconds_since_epoch * 1000 * 1000;
       else {
         this.DumpError("seconds-since-epoch not set");
         return;
       }
 
       let phase = this._phaselist[this._currentPhase];
@@ -882,17 +880,17 @@ var TPS = {
 
   /**
    * Executes a single test phase.
    *
    * This is called by RunTestPhase() after the environment is validated.
    */
   async _executeTestPhase(file, phase, settings) {
     try {
-      this.config = JSON.parse(prefs.getCharPref("tps.config"));
+      this.config = JSON.parse(Services.prefs.getCharPref("tps.config"));
       // parse the test file
       Services.scriptloader.loadSubScript(file, this);
       this._currentPhase = phase;
       // cleanup phases are in the format `cleanup-${profileName}`.
       if (this._currentPhase.startsWith("cleanup-")) {
         let profileToClean = this._currentPhase.slice("cleanup-".length);
         this.phases[this._currentPhase] = profileToClean;
         this.Phase(this._currentPhase, [[this.Cleanup]]);