Bug 1357517 - Remove or delay Preferences.jsm usage from some browser/base/content/* files. r=Gijs
authorMarco Castelluccio <mcastelluccio@mozilla.com>
Mon, 31 Jul 2017 12:51:35 +0200
changeset 420779 10de190a839b48b4271d5bcc6272bd68c74c9d81
parent 420778 e0029dcf7b3eb7c1ab8db350c3d2b9fb2feadc3a
child 420780 0f64ae9515a8efd0e234d7801cdc6b4f1c31a679
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1357517
milestone56.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 1357517 - Remove or delay Preferences.jsm usage from some browser/base/content/* files. r=Gijs
browser/base/content/abouthealthreport/abouthealth.js
browser/base/content/browser-addons.js
browser/base/content/browser-captivePortal.js
browser/base/content/browser-data-submission-info-bar.js
browser/base/content/browser.js
browser/base/content/sanitize.js
browser/base/content/test/about/browser_aboutHealthReport.js
browser/base/content/test/captivePortal/head.js
browser/base/content/test/general/browser_bug553455.js
browser/base/content/test/popupNotifications/browser_popupNotification_2.js
browser/base/content/urlbarBindings.xml
browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
browser/extensions/shield-recipe-client/test/browser/browser_RecipeRunner.js
browser/extensions/shield-recipe-client/test/browser/head.js
toolkit/modules/tests/browser/browser_WebRequest_filtering.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
--- a/browser/base/content/abouthealthreport/abouthealth.js
+++ b/browser/base/content/abouthealthreport/abouthealth.js
@@ -1,34 +1,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
-Cu.import("resource://gre/modules/Preferences.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-const prefs = new Preferences("datareporting.healthreport.");
-
-const PREF_UNIFIED = "toolkit.telemetry.unified";
 const PREF_REPORTING_URL = "datareporting.healthreport.about.reportUrl";
 
 var healthReportWrapper = {
   init() {
     let iframe = document.getElementById("remote-report");
     iframe.addEventListener("load", healthReportWrapper.initRemotePage);
     iframe.src = this._getReportURI().spec;
-    prefs.observe("uploadEnabled", this.updatePrefState, healthReportWrapper);
-  },
-
-  uninit() {
-    prefs.ignore("uploadEnabled", this.updatePrefState, healthReportWrapper);
+    XPCOMUtils.defineLazyPreferenceGetter(this, /* unused */ "_isUploadEnabled",
+                                          "datareporting.healthreport.uploadEnabled",
+                                          false, () => this.updatePrefState());
   },
 
   _getReportURI() {
     let url = Services.urlFormatter.formatURLPref(PREF_REPORTING_URL);
     return Services.io.newURI(url);
   },
 
   setDataSubmission(enabled) {
@@ -170,9 +165,8 @@ var healthReportWrapper = {
   },
 
   handlePayloadFailure() {
     healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PAYLOAD_FAILED);
   },
 }
 
 window.addEventListener("load", function() { healthReportWrapper.init(); });
-window.addEventListener("unload", function() { healthReportWrapper.uninit(); });
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -322,17 +322,17 @@ var gXPInstallObserver = {
       options.contentWindow = browser.contentWindow;
       options.sourceURI = browser.currentURI;
       options.eventCallback = function(aEvent) {
         switch (aEvent) {
           case "shown":
             let notificationElement = [...this.owner.panel.childNodes]
                                       .find(n => n.notification == this);
             if (notificationElement) {
-              if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+              if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
                 notificationElement.setAttribute("mainactiondisabled", "true");
               } else {
                 notificationElement.button.hidden = true;
               }
             }
             break;
           case "removed":
             options.contentWindow = null;
--- a/browser/base/content/browser-captivePortal.js
+++ b/browser/base/content/browser-captivePortal.js
@@ -7,17 +7,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "nsICaptivePortalService");
 
 var CaptivePortalWatcher = {
   /**
    * This constant is chosen to be large enough for a portal recheck to complete,
    * and small enough that the delay in opening a tab isn't too noticeable.
    * Please see comments for _delayedCaptivePortalDetected for more details.
    */
-  PORTAL_RECHECK_DELAY_MS: Preferences.get("captivedetect.portalRecheckDelayMS", 500),
+  PORTAL_RECHECK_DELAY_MS: Services.prefs.getIntPref("captivedetect.portalRecheckDelayMS", 500),
 
   // This is the value used to identify the captive portal notification.
   PORTAL_NOTIFICATION_VALUE: "captive-portal-detected",
 
   // This holds a weak reference to the captive portal tab so that we
   // don't leak it if the user closes it.
   _captivePortalTab: null,
 
@@ -63,16 +63,19 @@ var CaptivePortalWatcher = {
         this.ensureCaptivePortalTab();
       }
     } else if (cps.state == cps.UNKNOWN) {
       // We trigger a portal check after delayed startup to avoid doing a network
       // request before first paint.
       this._delayedRecheckPending = true;
       Services.obs.addObserver(this, "browser-delayed-startup-finished");
     }
+
+    XPCOMUtils.defineLazyPreferenceGetter(this, "PORTAL_RECHECK_DELAY_MS",
+                                          "captivedetect.portalRecheckDelayMS", 500);
   },
 
   uninit() {
     Services.obs.removeObserver(this, "captive-portal-login");
     Services.obs.removeObserver(this, "captive-portal-login-abort");
     Services.obs.removeObserver(this, "captive-portal-login-success");
 
     if (this._delayedRecheckPending) {
--- a/browser/base/content/browser-data-submission-info-bar.js
+++ b/browser/base/content/browser-data-submission-info-bar.js
@@ -1,17 +1,14 @@
 /* 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/. */
 
 const LOGGER_NAME = "Toolkit.Telemetry";
 const LOGGER_PREFIX = "DataNotificationInfoBar::";
-
-XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
-                                  "resource://gre/modules/Preferences.jsm");
 /**
  * Represents an info bar that shows a data submission notification.
  */
 var gDataNotificationInfoBar = {
   _OBSERVERS: [
     "datareporting:notify-data-policy:request",
     "datareporting:notify-data-policy:close",
   ],
@@ -63,17 +60,17 @@ var gDataNotificationInfoBar = {
     let buttons = [{
       label: gNavigatorBundle.getString("dataReportingNotification.button.label"),
       accessKey: gNavigatorBundle.getString("dataReportingNotification.button.accessKey"),
       popup: null,
       callback: () => {
         this._actionTaken = true;
         // The advanced subpanes are only supported in the old organization, which will
         // be removed by bug 1349689.
-        if (Preferences.get("browser.preferences.useOldOrganization")) {
+        if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
           window.openAdvancedPreferences("dataChoicesTab", {origin: "dataReporting"});
         } else {
           window.openPreferences("privacy-reports", {origin: "dataReporting"});
         }
       },
     }];
 
     this._log.info("Creating data reporting policy notification.");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -26,17 +26,17 @@ XPCOMUtils.defineLazyPreferenceGetter(th
 
 /* global AboutHome:false,
           BrowserUITelemetry:false, BrowserUsageTelemetry:false, BrowserUtils:false,
           CastingApps:false, CharsetMenu:false, Color:false, ContentSearch:false,
           CustomizableUI: false, DownloadsCommon: false,
           Deprecated:false, E10SUtils:false, ExtensionsUI: false, FormValidationHandler:false,
           GMPInstallManager:false, LightweightThemeManager:false, Log:false,
           LoginManagerParent:false, NewTabUtils:false, PageThumbs:false,
-          PluralForm:false, Preferences:false, PrivateBrowsingUtils:false,
+          PluralForm:false, PrivateBrowsingUtils:false,
           ProcessHangMonitor:false, PromiseUtils:false, ReaderMode:false,
           ReaderParent:false, RecentWindow:false, SafeBrowsing: false,
           SessionStore:false,
           ShortcutUtils:false, SimpleServiceDiscovery:false, SitePermissions:false,
           Social:false, TabCrashHandler:false, TelemetryStopwatch:false,
           Translation:false, UITour:false, Utils:false, UpdateUtils:false,
           Weave:false,
           WebNavigationFrames: false, fxAccounts:false, gDevTools:false,
@@ -66,17 +66,16 @@ XPCOMUtils.defineLazyPreferenceGetter(th
   ["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"],
   ["GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm"],
   ["LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm"],
   ["Log", "resource://gre/modules/Log.jsm"],
   ["LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"],
   ["NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"],
   ["PageThumbs", "resource://gre/modules/PageThumbs.jsm"],
   ["PluralForm", "resource://gre/modules/PluralForm.jsm"],
-  ["Preferences", "resource://gre/modules/Preferences.jsm"],
   ["PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"],
   ["ProcessHangMonitor", "resource:///modules/ProcessHangMonitor.jsm"],
   ["PromiseUtils", "resource://gre/modules/PromiseUtils.jsm"],
   ["ReaderMode", "resource://gre/modules/ReaderMode.jsm"],
   ["ReaderParent", "resource:///modules/ReaderParent.jsm"],
   ["RecentWindow", "resource:///modules/RecentWindow.jsm"],
   ["SafeBrowsing", "resource://gre/modules/SafeBrowsing.jsm"],
   ["SessionStore", "resource:///modules/sessionstore/SessionStore.jsm"],
@@ -580,17 +579,17 @@ const gStoragePressureObserver = {
       msg = prefStrBundle.getFormattedString(descriptionStringID, [brandShortName]);
       buttons.push({
         label: prefStrBundle.getString(prefButtonLabelStringID),
         accessKey: prefStrBundle.getString(prefButtonAccesskeyStringID),
         callback(notificationBar, button) {
           // The advanced subpanes are only supported in the old organization, which will
           // be removed by bug 1349689.
           let win = gBrowser.ownerGlobal;
-          if (Preferences.get("browser.preferences.useOldOrganization")) {
+          if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
             win.openAdvancedPreferences("networkTab", {origin: "storagePressure"});
           } else {
             win.openPreferences("panePrivacy", {origin: "storagePressure"});
           }
         }
       });
     }
 
@@ -6510,17 +6509,17 @@ var OfflineApps = {
         docId,
       });
     }
   },
 
   manage() {
     // The advanced subpanes are only supported in the old organization, which will
     // be removed by bug 1349689.
-    if (Preferences.get("browser.preferences.useOldOrganization")) {
+    if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
       openAdvancedPreferences("networkTab", {origin: "offlineApps"});
     } else {
       openPreferences("panePrivacy", {origin: "offlineApps"});
     }
   },
 
   receiveMessage(msg) {
     switch (msg.name) {
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -16,18 +16,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
                                   "resource:///modules/DownloadsCommon.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
                                   "resource://gre/modules/TelemetryStopwatch.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "console",
                                   "resource://gre/modules/Console.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
-                                  "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "setTimeout",
                                   "resource://gre/modules/Timer.jsm");
 
 var {classes: Cc, interfaces: Ci} = Components;
 
 /**
  * A number of iterations after which to yield time back
  * to the system.
@@ -105,18 +103,18 @@ Sanitizer.prototype = {
         } catch (ex) {
           return false;
         }
       });
     }
 
     // Store the list of items to clear, in case we are killed before we
     // get a chance to complete.
-    Preferences.set(Sanitizer.PREF_SANITIZE_IN_PROGRESS,
-                    JSON.stringify(itemsToClear));
+    Services.prefs.setStringPref(Sanitizer.PREF_SANITIZE_IN_PROGRESS,
+                                 JSON.stringify(itemsToClear));
 
     // Store the list of items to clear, for debugging/forensics purposes
     for (let k of itemsToClear) {
       progress[k] = "ready";
     }
 
     // Ensure open windows get cleared first, if they're in our list, so that they don't stick
     // around in the recently closed windows list, and so we can cancel the whole thing
@@ -172,17 +170,17 @@ Sanitizer.prototype = {
       progress[handle.name] = "blocking";
       await handle.promise;
     }
 
     // Sanitization is complete.
     TelemetryStopwatch.finish("FX_SANITIZE_TOTAL", refObj);
     // Reset the inProgress preference since we were not killed during
     // sanitization.
-    Preferences.reset(Sanitizer.PREF_SANITIZE_IN_PROGRESS);
+    Services.prefs.clearUserPref(Sanitizer.PREF_SANITIZE_IN_PROGRESS);
     progress = {};
     if (seenError) {
       throw new Error("Error sanitizing");
     }
   },
 
   // Time span only makes sense in certain cases.  Consumers who want
   // to only clear some private data can opt in by setting this to false,
@@ -802,24 +800,24 @@ Sanitizer.showUI = function(aParentWindo
  */
 Sanitizer.sanitize = function(aParentWindow) {
   Sanitizer.showUI(aParentWindow);
 };
 
 Sanitizer.onStartup = async function() {
   // Check if we were interrupted during the last shutdown sanitization.
   let shutownSanitizationWasInterrupted =
-    Preferences.get(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, false) &&
-    !Preferences.has(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
+    Services.prefs.getBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, false) &&
+    Services.prefs.getPrefType(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN) == Ci.nsIPrefBranch.PREF_INVALID;
 
-  if (Preferences.has(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN)) {
+  if (Services.prefs.prefHasUserValue(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN)) {
     // Reset the pref, so that if we crash before having a chance to
     // sanitize on shutdown, we will do at the next startup.
     // Flushing prefs has a cost, so do this only if necessary.
-    Preferences.reset(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
+    Services.prefs.clearUserPref(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
     Services.prefs.savePrefFile(null);
   }
 
   // Make sure that we are triggered during shutdown.
   let shutdownClient = Cc["@mozilla.org/browser/nav-history-service;1"]
                          .getService(Ci.nsPIPlacesDatabase)
                          .shutdownClient
                          .jsclient;
@@ -832,35 +830,35 @@ Sanitizer.onStartup = async function() {
   shutdownClient.addBlocker("sanitize.js: Sanitize on shutdown",
     () => sanitizeOnShutdown({ progress }),
     {
       fetchState: () => ({ progress })
     }
   );
 
   // Check if Firefox crashed during a sanitization.
-  let lastInterruptedSanitization = Preferences.get(Sanitizer.PREF_SANITIZE_IN_PROGRESS, "");
+  let lastInterruptedSanitization = Services.prefs.getStringPref(Sanitizer.PREF_SANITIZE_IN_PROGRESS, "");
   if (lastInterruptedSanitization) {
     let s = new Sanitizer();
     // If the json is invalid this will just throw and reject the Task.
     let itemsToClear = JSON.parse(lastInterruptedSanitization);
     await s.sanitize(itemsToClear);
   } else if (shutownSanitizationWasInterrupted) {
     // Otherwise, could be we were supposed to sanitize on shutdown but we
     // didn't have a chance, due to an earlier crash.
     // In such a case, just redo a shutdown sanitize now, during startup.
     await sanitizeOnShutdown();
   }
 };
 
 var sanitizeOnShutdown = async function(options = {}) {
-  if (!Preferences.get(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN)) {
+  if (!Services.prefs.getBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN)) {
     return;
   }
   // Need to sanitize upon shutdown
   let s = new Sanitizer();
   s.prefDomain = "privacy.clearOnShutdown.";
   await s.sanitize(null, options);
   // We didn't crash during shutdown sanitization, so annotate it to avoid
   // sanitizing again on startup.
-  Preferences.set(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN, true);
+  Services.prefs.setBoolPref(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN, true);
   Services.prefs.savePrefFile(null);
 };
--- a/browser/base/content/test/about/browser_aboutHealthReport.js
+++ b/browser/base/content/test/about/browser_aboutHealthReport.js
@@ -2,26 +2,26 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 
 const CHROME_BASE = "chrome://mochitests/content/browser/browser/base/content/test/about/";
 const HTTPS_BASE = "https://example.com/browser/browser/base/content/test/about/";
 
 const TELEMETRY_LOG_PREF = "toolkit.telemetry.log.level";
-const telemetryOriginalLogPref = Preferences.get(TELEMETRY_LOG_PREF, null);
+const telemetryOriginalLogPref = Services.prefs.getStringPref(TELEMETRY_LOG_PREF, null);
 
 const originalReportUrl = Services.prefs.getCharPref("datareporting.healthreport.about.reportUrl");
 
 registerCleanupFunction(function() {
   // Ensure we don't pollute prefs for next tests.
   if (telemetryOriginalLogPref) {
-    Preferences.set(TELEMETRY_LOG_PREF, telemetryOriginalLogPref);
+    Services.prefs.setStringPref(TELEMETRY_LOG_PREF, telemetryOriginalLogPref);
   } else {
-    Preferences.reset(TELEMETRY_LOG_PREF);
+    Services.prefs.clearUserPref(TELEMETRY_LOG_PREF);
   }
 
   try {
     Services.prefs.setCharPref("datareporting.healthreport.about.reportUrl", originalReportUrl);
     Services.prefs.setBoolPref("datareporting.healthreport.uploadEnabled", true);
   } catch (ex) {}
 });
 
@@ -53,20 +53,20 @@ async function setupPingArchive() {
   }
 }
 
 var gTests = [
 
 {
   desc: "Test the remote commands",
   async setup() {
-    Preferences.set(TELEMETRY_LOG_PREF, "Trace");
+    Services.prefs.setStringPref(TELEMETRY_LOG_PREF, "Trace");
     await setupPingArchive();
-    Preferences.set("datareporting.healthreport.about.reportUrl",
-                    HTTPS_BASE + "healthreport_testRemoteCommands.html");
+    Services.prefs.setCharPref("datareporting.healthreport.about.reportUrl",
+                               HTTPS_BASE + "healthreport_testRemoteCommands.html");
   },
   run(iframe) {
     return new Promise((resolve, reject) => {
       let results = 0;
       try {
         iframe.contentWindow.addEventListener("FirefoxHealthReportTestResponse", function evtHandler(event) {
           let data = event.detail.data;
           if (data.type == "testResult") {
--- a/browser/base/content/test/captivePortal/head.js
+++ b/browser/base/content/test/captivePortal/head.js
@@ -59,17 +59,17 @@ async function freePortal(aSuccess) {
 async function focusWindowAndWaitForPortalUI(aLongRecheck, win) {
   // CaptivePortalWatcher triggers a recheck when a window gains focus. If
   // the time taken for the check to complete is under PORTAL_RECHECK_DELAY_MS,
   // a tab with the login page is opened and selected. If it took longer,
   // no tab is opened. It's not reliable to time things in an async test,
   // so use a delay threshold of -1 to simulate a long recheck (so that any
   // amount of time is considered excessive), and a very large threshold to
   // simulate a short recheck.
-  Preferences.set("captivedetect.portalRecheckDelayMS", aLongRecheck ? -1 : 1000000);
+  Services.prefs.setIntPref("captivedetect.portalRecheckDelayMS", aLongRecheck ? -1 : 1000000);
 
   if (!win) {
     win = await BrowserTestUtils.openNewBrowserWindow();
   }
   await SimpleTest.promiseFocus(win);
 
   // After a new window is opened, CaptivePortalWatcher asks for a recheck, and
   // waits for it to complete. We need to manually tell it a recheck completed.
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -132,17 +132,17 @@ function waitForNotificationClose() {
     info("Waiting for notification to close");
     PopupNotifications.panel.addEventListener("popuphidden", function() {
       resolve();
     }, {once: true});
   });
 }
 
 async function waitForInstallDialog() {
-  if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     let panel = await waitForNotification("addon-install-confirmation");
     return panel.childNodes[0];
   }
 
   info("Waiting for install dialog");
 
   let window = await new Promise(resolve => {
     Services.wm.addListener({
@@ -178,26 +178,26 @@ async function waitForInstallDialog() {
 function removeTab() {
   return Promise.all([
     waitForNotificationClose(),
     BrowserTestUtils.removeTab(gBrowser.selectedTab)
   ]);
 }
 
 function acceptInstallDialog(installDialog) {
-  if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     installDialog.button.click();
   } else {
     let win = Services.wm.getMostRecentWindow("Addons:Install");
     win.document.documentElement.acceptDialog();
   }
 }
 
 function cancelInstallDialog(installDialog) {
-  if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     installDialog.secondaryButton.click();
   } else {
     let win = Services.wm.getMostRecentWindow("Addons:Install");
     win.document.documentElement.cancelDialog();
   }
 }
 
 async function waitForSingleNotification(aCallback) {
@@ -441,17 +441,17 @@ async function test_restartless() {
   gBrowser.removeTab(gBrowser.selectedTab);
   await closePromise;
 },
 
 async function test_sequential() {
   // This test is only relevant if using the new doorhanger UI
   // TODO: this subtest is disabled until multiple notification prompts are
   // reworked in bug 1188152
-  if (true || !Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (true || !Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     return;
   }
   let pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
   let triggers = encodeURIComponent(JSON.stringify({
@@ -514,18 +514,18 @@ async function test_sequential() {
   cancelInstallDialog(installDialog);
   await closePromise;
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 },
 
 async function test_allUnverified() {
   // This test is only relevant if using the new doorhanger UI and allowing
   // unsigned add-ons
-  if (!Preferences.get("xpinstall.customConfirmationUI", false) ||
-      Preferences.get("xpinstall.signatures.required", true) ||
+  if (!Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false) ||
+      Services.prefs.getBoolPref("xpinstall.signatures.required", true) ||
       AppConstants.MOZ_REQUIRE_SIGNING) {
         return;
   }
   let pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
@@ -615,17 +615,17 @@ async function test_localFile() {
   is(notification.getAttribute("label"),
      "This add-on could not be installed because it appears to be corrupt.",
      "Should have seen the right message");
 
   await removeTab();
 },
 
 async function test_tabClose() {
-  if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (!Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     info("Test skipped due to xpinstall.customConfirmationUI being false.");
     return;
   }
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
@@ -642,17 +642,17 @@ async function test_tabClose() {
 
   installs = await getInstalls();
   is(installs.length, 0, "Should be no pending install since the tab is closed");
 },
 
 // Add-ons should be cancelled and the install notification destroyed when
 // navigating to a new origin
 async function test_tabNavigate() {
-  if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
+  if (!Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
     return;
   }
   let pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   let progressPromise = waitForProgressNotification();
   let dialogPromise = waitForInstallDialog();
   let triggers = encodeURIComponent(JSON.stringify({
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
@@ -200,29 +200,29 @@ var tests = [
       ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
       ok(!this.notifyObj.secondaryActionClicked, "secondary action not clicked");
     }
   },
   // Test that notification close button calls secondary action instead of
   // dismissal callback if privacy.permissionPrompts.showCloseButton is set.
   { id: "Test#10",
     run() {
-      Preferences.set("privacy.permissionPrompts.showCloseButton", true);
+      Services.prefs.setBoolPref("privacy.permissionPrompts.showCloseButton", true);
       this.notifyObj = new BasicNotification(this.id);
       this.notification = showNotification(this.notifyObj);
     },
     onShown(popup) {
       checkPopup(popup, this.notifyObj);
       let notification = popup.childNodes[0];
       EventUtils.synthesizeMouseAtCenter(notification.closebutton, {});
     },
     onHidden(popup) {
       ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback not triggered");
       ok(this.notifyObj.secondaryActionClicked, "secondary action clicked");
-      Preferences.reset("privacy.permissionPrompts.showCloseButton");
+      Services.prefs.clearUserPref("privacy.permissionPrompts.showCloseButton");
       this.notification.remove();
       ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
     }
   },
   // Test notification when chrome is hidden
   { id: "Test#11",
     run() {
       window.locationbar.visible = false;
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -2449,17 +2449,17 @@ file, You can obtain one at http://mozil
             if (maxProgress >= 0)
               maxProgress += aInstall.maxProgress;
             if (aInstall.state < AddonManager.STATE_DOWNLOADED)
               downloadingCount++;
           });
 
           if (downloadingCount == 0) {
             this.destroy();
-            if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+            if (Services.prefs.getBoolPref("xpinstall.customConfirmationUI", false)) {
               this.progressmeter.setAttribute("mode", "undetermined");
               let status = gNavigatorBundle.getString("addonDownloadVerifying");
               this.progresstext.setAttribute("value", status);
               this.progresstext.setAttribute("tooltiptext", status);
             } else {
               PopupNotifications.remove(this.notification);
             }
           } else {
--- a/browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
@@ -1,17 +1,14 @@
 "use strict";
 
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/TelemetryController.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/ClientEnvironment.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/PreferenceExperiments.jsm", this);
 
-
 add_task(async function testTelemetry() {
   // setup
   await TelemetryController.submitExternalPing("testfoo", {foo: 1});
   await TelemetryController.submitExternalPing("testbar", {bar: 2});
   const environment = ClientEnvironment.getEnvironment();
 
   // Test it can access telemetry
   const telemetry = await environment.telemetry;
--- a/browser/extensions/shield-recipe-client/test/browser/browser_RecipeRunner.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_RecipeRunner.js
@@ -1,11 +1,10 @@
 "use strict";
 
-Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://shield-recipe-client/lib/RecipeRunner.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/ClientEnvironment.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/CleanupManager.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/NormandyApi.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/ActionSandboxManager.jsm", this);
 
 add_task(async function getFilterContext() {
   const recipe = {id: 17, arguments: {foo: "bar"}, unrelated: false};
--- a/browser/extensions/shield-recipe-client/test/browser/head.js
+++ b/browser/extensions/shield-recipe-client/test/browser/head.js
@@ -1,12 +1,12 @@
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 
-Cu.import("resource://gre/modules/Preferences.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/SandboxManager.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/NormandyDriver.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/NormandyApi.jsm", this);
 Cu.import("resource://shield-recipe-client/lib/Utils.jsm", this);
 
 // Load mocking/stubbing library, sinon
 // docs: http://sinonjs.org/docs/
 const loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
--- a/toolkit/modules/tests/browser/browser_WebRequest_filtering.js
+++ b/toolkit/modules/tests/browser/browser_WebRequest_filtering.js
@@ -54,16 +54,21 @@ function removeDupes(list) {
 function compareLists(list1, list2, kind) {
   list1.sort();
   removeDupes(list1);
   list2.sort();
   removeDupes(list2);
   is(String(list1), String(list2), `${kind} URLs correct`);
 }
 
+add_task(async function setup() {
+  // Disable rcwn to make cache behavior deterministic.
+  await SpecialPowers.pushPrefEnv({set: [["network.http.rcwn.enabled", false]]});
+});
+
 add_task(async function filter_urls() {
   let filter = {urls: new MatchPattern("*://*/*_style_*")};
 
   WebRequest.onBeforeRequest.addListener(onBeforeRequest, filter, ["blocking"]);
   WebRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, filter, ["blocking"]);
   WebRequest.onResponseStarted.addListener(onResponseStarted, filter);
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, URL);
@@ -105,16 +110,8 @@ add_task(async function filter_types() {
 
 function waitForLoad(browser = gBrowser.selectedBrowser) {
   return new Promise(resolve => {
     browser.addEventListener("load", function() {
       resolve();
     }, {capture: true, once: true});
   });
 }
-
-// Disable rcwn to make cache behavior deterministic.
-let rcwnEnabled = Preferences.get("network.http.rcwn.enabled");
-Preferences.set("network.http.rcwn.enabled", false);
-
-registerCleanupFunction(() => {
-  Preferences.set("network.http.rcwn.enabled", rcwnEnabled);
-});
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
@@ -1,14 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests various aspects of the details view
-Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var gManagerWindow;
 var gCategoryUtilities;
 var gProvider;
 
 const SETTINGS_ROWS = 9;
 
 var MockFilePicker = SpecialPowers.MockFilePicker;
@@ -247,17 +246,17 @@ add_test(function() {
     EventUtils.synthesizeKey("b", {}, gManagerWindow);
     EventUtils.synthesizeKey("a", {}, gManagerWindow);
     EventUtils.synthesizeKey("r", {}, gManagerWindow);
     is(input.value, "bar", "Text box should have updated value");
     input.value += "\u03DE"; // Cheat to add this non-ASCII character without typing it.
     EventUtils.synthesizeKey("/", {}, gManagerWindow);
     is(input.value, "bar\u03DE/", "Text box should have updated value");
     is(gManagerWindow.document.getBindingParent(gManagerWindow.document.activeElement), input, "Search box should not have focus");
-    is(Preferences.get("extensions.inlinesettings1.string", "wrong"), "bar\u03DE/", "String pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings1.string", "wrong"), "bar\u03DE/", "String pref should have been updated");
 
     ok(!settings[4].hasAttribute("first-row"), "Not the first row");
     input = settings[4].firstElementChild;
     is(input.value, "1", "Menulist should have initial value");
     input.focus();
     EventUtils.synthesizeKey("b", {}, gManagerWindow);
     is(input.value, "2", "Menulist should have updated value");
     is(gManagerWindow._testValue, "2", "Menulist oncommand handler should've updated the test value");
@@ -292,30 +291,30 @@ add_test(function() {
       MockFilePicker.afterOpenCallback = resolve;
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
     });
 
     promise.then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, testFile.path, "Label value should match file chosen");
       is(input.tooltipText, testFile.path, "Label tooltip should match file chosen");
-      is(Preferences.get("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should match file chosen");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should match file chosen");
 
       MockFilePicker.setFiles([curProcD]);
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
 
       return new Promise(resolve => {
         MockFilePicker.afterOpenCallback = resolve;
         EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       });
     }).then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeOpen, "File picker mode should be open file");
       is(input.value, testFile.path, "Label value should not have changed");
       is(input.tooltipText, testFile.path, "Label tooltip should not have changed");
-      is(Preferences.get("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should not have changed");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.file", "wrong"), testFile.path, "File pref should not have changed");
 
       ok(!settings[7].hasAttribute("first-row"), "Not the first row");
       button = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "button");
       input = gManagerWindow.document.getAnonymousElementByAttribute(settings[7], "anonid", "input");
       is(input.value, "", "Label value should be empty");
       is(input.tooltipText, "", "Label tooltip should be empty");
 
       MockFilePicker.setFiles([testFile]);
@@ -324,30 +323,30 @@ add_test(function() {
       return new Promise(resolve => {
         MockFilePicker.afterOpenCallback = resolve;
         EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       });
     }).then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, testFile.path, "Label value should match file chosen");
       is(input.tooltipText, testFile.path, "Label tooltip should match file chosen");
-      is(Preferences.get("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should match file chosen");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should match file chosen");
 
       MockFilePicker.setFiles([curProcD]);
       MockFilePicker.returnValue = Ci.nsIFilePicker.returnCancel;
 
       return new Promise(resolve => {
         MockFilePicker.afterOpenCallback = resolve;
         EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
       });
     }).then(() => {
       is(MockFilePicker.mode, Ci.nsIFilePicker.modeGetFolder, "File picker mode should be directory");
       is(input.value, testFile.path, "Label value should not have changed");
       is(input.tooltipText, testFile.path, "Label tooltip should not have changed");
-      is(Preferences.get("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should not have changed");
+      is(Services.prefs.getStringPref("extensions.inlinesettings1.directory", "wrong"), testFile.path, "Directory pref should not have changed");
 
       var unsizedInput = gManagerWindow.document.getAnonymousElementByAttribute(settings[2], "anonid", "input");
       var sizedInput = gManagerWindow.document.getAnonymousElementByAttribute(settings[8], "anonid", "input");
       is(unsizedInput.clientWidth > sizedInput.clientWidth, true, "Input with size attribute should be smaller than input without");
     }).then(() => {
       button = gManagerWindow.document.getElementById("detail-prefs-btn");
       is_element_hidden(button, "Preferences button should not be visible");
 
@@ -396,19 +395,19 @@ add_test(function() {
 
     ok(!settings[2].hasAttribute("first-row"), "Not the first row");
     Services.prefs.setCharPref("extensions.inlinesettings3.radioString", "juliet");
     radios = settings[2].getElementsByTagName("radio");
     isnot(radios[0].selected, true, "Correct radio button should be selected");
     is(radios[1].selected, true, "Correct radio button should be selected");
     isnot(radios[2].selected, true, "Correct radio button should be selected");
     EventUtils.synthesizeMouseAtCenter(radios[0], { clickCount: 1 }, gManagerWindow);
-    is(Preferences.get("extensions.inlinesettings3.radioString", "wrong"), "india", "Radio pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings3.radioString", "wrong"), "india", "Radio pref should have been updated");
     EventUtils.synthesizeMouseAtCenter(radios[2], { clickCount: 1 }, gManagerWindow);
-    is(Preferences.get("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
 
     ok(!settings[3].hasAttribute("first-row"), "Not the first row");
     Services.prefs.setIntPref("extensions.inlinesettings3.menulist", 8);
     var input = settings[3].firstElementChild;
     is(input.value, "8", "Menulist should have initial value");
     input.focus();
     EventUtils.synthesizeKey("n", {}, gManagerWindow);
     is(input.value, "9", "Menulist should have updated value");
@@ -604,17 +603,17 @@ add_test(function() {
   observer.checkHidden("inlinesettings2@tests.mozilla.org");
 
   // Ensure these prefs are set. They should be set above, but somebody might
   // change the tests above.
   var profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
   Services.prefs.setBoolPref("extensions.inlinesettings1.bool", false);
   Services.prefs.setIntPref("extensions.inlinesettings1.boolint", 1);
   Services.prefs.setIntPref("extensions.inlinesettings1.integer", 12);
-  Preferences.set("extensions.inlinesettings1.string", "bar\u03DE/");
+  Services.prefs.setStringPref("extensions.inlinesettings1.string", "bar\u03DE/");
   Services.prefs.setCharPref("extensions.inlinesettings1.color", "#FF9900");
   Services.prefs.setCharPref("extensions.inlinesettings1.file", profD.path);
   Services.prefs.setCharPref("extensions.inlinesettings1.directory", profD.path);
 
   var addon = get_addon_element(gManagerWindow, "inlinesettings1@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
@@ -656,17 +655,17 @@ add_test(function() {
 // Tests bindings with existing prefs.
 add_test(function() {
   observer.checkHidden("inlinesettings1@tests.mozilla.org");
 
   // Ensure these prefs are set. They should be set above, but somebody might
   // change the tests above.
   Services.prefs.setBoolPref("extensions.inlinesettings3.radioBool", false);
   Services.prefs.setIntPref("extensions.inlinesettings3.radioInt", 6);
-  Preferences.set("extensions.inlinesettings3.radioString", "kilo \u338F");
+  Services.prefs.setStringPref("extensions.inlinesettings3.radioString", "kilo \u338F");
   Services.prefs.setIntPref("extensions.inlinesettings3.menulist", 9);
 
   var addon = get_addon_element(gManagerWindow, "inlinesettings3@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
@@ -1,14 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests various aspects of the details view
-Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var gManagerWindow;
 var gCategoryUtilities;
 var gProvider;
 
 const SETTINGS_ROWS = 8;
 
 var MockFilePicker = SpecialPowers.MockFilePicker;
@@ -389,17 +388,17 @@ add_test(function() {
     Services.prefs.setCharPref("extensions.inlinesettings3.radioString", "juliet");
     radios = settings[2].getElementsByTagName("radio");
     isnot(radios[0].selected, true, "Correct radio button should be selected");
     is(radios[1].selected, true, "Correct radio button should be selected");
     isnot(radios[2].selected, true, "Correct radio button should be selected");
     EventUtils.synthesizeMouseAtCenter(radios[0], { clickCount: 1 }, gManagerWindow);
     is(Services.prefs.getCharPref("extensions.inlinesettings3.radioString"), "india", "Radio pref should have been updated");
     EventUtils.synthesizeMouseAtCenter(radios[2], { clickCount: 1 }, gManagerWindow);
-    is(Preferences.get("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
+    is(Services.prefs.getStringPref("extensions.inlinesettings3.radioString", "wrong"), "kilo \u338F", "Radio pref should have been updated");
 
     ok(!settings[3].hasAttribute("first-row"), "Not the first row");
     Services.prefs.setIntPref("extensions.inlinesettings3.menulist", 8);
     var input = settings[3].firstElementChild;
     is(input.value, "8", "Menulist should have initial value");
     input.focus();
     EventUtils.synthesizeKey("n", {}, gManagerWindow);
     is(input.value, "9", "Menulist should have updated value");