Bug 1304001 - Update LoginHelper prefs even if no logger was created. r=sfoster
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Fri, 22 Feb 2019 15:40:24 +0000
changeset 460594 61b426c73ccf9351cb3d0fd3a0061f02651b1d2c
parent 460593 a09dd4b000f756a02eba0066bb47645dfbd3c472
child 460595 06877b0fd1a95ec218992e15d8ff08cbf96e99a1
push id35596
push userrmaries@mozilla.com
push dateSat, 23 Feb 2019 04:13:22 +0000
treeherdermozilla-central@fdd04819e350 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfoster
bugs1304001
milestone67.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 1304001 - Update LoginHelper prefs even if no logger was created. r=sfoster This means there is only one signon.* listener for the whole process, not per-logger. Also move LMC prefs to LMH. Differential Revision: https://phabricator.services.mozilla.com/D20391
toolkit/components/passwordmgr/LoginHelper.jsm
toolkit/components/passwordmgr/LoginManagerContent.jsm
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -16,59 +16,67 @@ var EXPORTED_SYMBOLS = [
   "LoginHelper",
 ];
 
 // Globals
 
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-// LoginHelper
-
 /**
  * Contains functions shared by different Login Manager components.
  */
 var LoginHelper = {
-  /**
-   * Warning: these only update if a logger was created.
-   */
-  debug: Services.prefs.getBoolPref("signon.debug"),
-  formlessCaptureEnabled: Services.prefs.getBoolPref("signon.formlessCapture.enabled"),
-  schemeUpgrades: Services.prefs.getBoolPref("signon.schemeUpgrades"),
-  insecureAutofill: Services.prefs.getBoolPref("signon.autofillForms.http"),
-  privateBrowsingCaptureEnabled:
-    Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled"),
+  debug: null,
+  enabled: null,
+  formlessCaptureEnabled: null,
+  schemeUpgrades: null,
+  insecureAutofill: null,
+  privateBrowsingCaptureEnabled: null,
+
+  init() {
+    // Watch for pref changes to update cached pref values.
+    Services.prefs.addObserver("signon.", () => this.updateSignonPrefs());
+    this.updateSignonPrefs();
+  },
+
+  updateSignonPrefs() {
+    this.autofillForms = Services.prefs.getBoolPref("signon.autofillForms");
+    this.debug = Services.prefs.getBoolPref("signon.debug");
+    this.enabled = Services.prefs.getBoolPref("signon.rememberSignons");
+    this.formlessCaptureEnabled = Services.prefs.getBoolPref("signon.formlessCapture.enabled");
+    this.insecureAutofill = Services.prefs.getBoolPref("signon.autofillForms.http");
+    this.privateBrowsingCaptureEnabled =
+      Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled");
+
+    this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
+    this.storeWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
+  },
 
   createLogger(aLogPrefix) {
     let getMaxLogLevel = () => {
-      return this.debug ? "debug" : "warn";
+      return this.debug ? "Debug" : "Warn";
     };
 
     let logger;
     function getConsole() {
       if (!logger) {
         // Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
-        let ConsoleAPI = ChromeUtils.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
         let consoleOptions = {
           maxLogLevel: getMaxLogLevel(),
           prefix: aLogPrefix,
         };
-        logger = new ConsoleAPI(consoleOptions);
+        logger = console.createInstance(consoleOptions);
       }
       return logger;
     }
 
     // Watch for pref changes and update this.debug and the maxLogLevel for created loggers
-    Services.prefs.addObserver("signon.", () => {
+    Services.prefs.addObserver("signon.debug", () => {
       this.debug = Services.prefs.getBoolPref("signon.debug");
-      this.formlessCaptureEnabled = Services.prefs.getBoolPref("signon.formlessCapture.enabled");
-      this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
-      this.insecureAutofill = Services.prefs.getBoolPref("signon.autofillForms.http");
-      this.privateBrowsingCaptureEnabled =
-        Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled");
       if (logger) {
         logger.maxLogLevel = getMaxLogLevel();
       }
     });
 
     return {
       log: (...args) => {
         if (this.debug) {
@@ -781,15 +789,17 @@ var LoginHelper = {
       dataObject = Cc["@mozilla.org/supports-string;1"].
                    createInstance(Ci.nsISupportsString);
       dataObject.data = data;
     }
     Services.obs.notifyObservers(dataObject, "passwordmgr-storage-changed", changeType);
   },
 };
 
+LoginHelper.init();
+
 XPCOMUtils.defineLazyPreferenceGetter(LoginHelper, "showInsecureFieldWarning",
                                       "security.insecure_field_warning.contextual.enabled");
 
 XPCOMUtils.defineLazyGetter(this, "log", () => {
   let logger = LoginHelper.createLogger("LoginHelper");
   return logger;
 });
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -35,18 +35,16 @@ XPCOMUtils.defineLazyGetter(this, "log",
   let logger = LoginHelper.createLogger("LoginManagerContent");
   return logger.log.bind(logger);
 });
 
 Services.cpmm.addMessageListener("clearRecipeCache", () => {
   LoginRecipesContent._clearRecipeCache();
 });
 
-// These mirror signon.* prefs.
-var gEnabled, gAutofillForms, gStoreWhenAutocompleteOff;
 var gLastRightClickTimeStamp = Number.NEGATIVE_INFINITY;
 
 var observer = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
                                           Ci.nsIFormSubmitObserver,
                                           Ci.nsIWebProgressListener,
                                           Ci.nsISupportsWeakReference]),
 
@@ -63,22 +61,16 @@ var observer = {
     } catch (e) {
       log("Caught error in onFormSubmit(", e.lineNumber, "):", e.message);
       Cu.reportError(e);
     }
 
     return true; // Always return true, or form submit will be canceled.
   },
 
-  onPrefChange() {
-    gEnabled = Services.prefs.getBoolPref("signon.rememberSignons");
-    gAutofillForms = Services.prefs.getBoolPref("signon.autofillForms");
-    gStoreWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
-  },
-
   // nsIWebProgressListener
   onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
     // Only handle pushState/replaceState here.
     if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) ||
         !(aWebProgress.loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE)) {
       return;
     }
 
@@ -113,17 +105,17 @@ var observer = {
     LoginManagerContent._onNavigation(aWebProgress.DOMWindow.document);
   },
 
   handleEvent(aEvent) {
     if (!aEvent.isTrusted) {
       return;
     }
 
-    if (!gEnabled) {
+    if (!LoginHelper.enabled) {
       return;
     }
 
     switch (aEvent.type) {
       // Only used for username fields.
       case "focus": {
         LoginManagerContent._onUsernameFocus(aEvent);
         break;
@@ -142,21 +134,16 @@ var observer = {
       default: {
         throw new Error("Unexpected event");
       }
     }
   },
 };
 
 Services.obs.addObserver(observer, "earlyformsubmit");
-var prefBranch = Services.prefs.getBranch("signon.");
-prefBranch.addObserver("", observer.onPrefChange);
-
-observer.onPrefChange(); // read initial values
-
 
 // This object maps to the "child" process (even in the single-process case).
 var LoginManagerContent = {
   __formFillService: null, // FormFillController, for username autocompleting
   get _formFillService() {
     if (!this.__formFillService) {
       this.__formFillService =
                       Cc["@mozilla.org/satchel/form-fill-controller;1"].
@@ -437,17 +424,17 @@ var LoginManagerContent = {
    * @param {Window} window
    */
   _fetchLoginsFromParentAndFillForm(form, window) {
     this._detectInsecureFormLikes(window);
 
     let messageManager = window.docShell.messageManager;
     messageManager.sendAsyncMessage("LoginStats:LoginEncountered");
 
-    if (!gEnabled) {
+    if (!LoginHelper.enabled) {
       return;
     }
 
     this._getLoginDataFromParent(form, { showMasterPassword: true })
         .then(this.loginsFound.bind(this))
         .catch(Cu.reportError);
   },
 
@@ -556,17 +543,17 @@ var LoginManagerContent = {
       clobberUsername,
       clobberPassword: true,
       userTriggered: true,
     });
   },
 
   loginsFound({ form, loginsFound, recipes }) {
     let doc = form.ownerDocument;
-    let autofillForm = gAutofillForms && !PrivateBrowsingUtils.isContentWindowPrivate(doc.defaultView);
+    let autofillForm = LoginHelper.autofillForms && !PrivateBrowsingUtils.isContentWindowPrivate(doc.defaultView);
 
     let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
     LoginRecipesContent.cacheRecipes(formOrigin, doc.defaultView, recipes);
 
     this._fillForm(form, loginsFound, recipes, {autofillForm});
   },
 
   /**
@@ -608,17 +595,17 @@ var LoginManagerContent = {
   /**
    * Listens for DOMAutoComplete event on login form.
    */
   onDOMAutoComplete(event) {
     if (!event.isTrusted) {
       return;
     }
 
-    if (!gEnabled) {
+    if (!LoginHelper.enabled) {
       return;
     }
 
     let acInputField = event.target;
 
     // This is probably a bit over-conservatative.
     if (ChromeUtils.getClassName(acInputField.ownerDocument) != "HTMLDocument") {
       return;
@@ -937,17 +924,17 @@ var LoginManagerContent = {
         !LoginHelper.privateBrowsingCaptureEnabled) {
       // We won't do anything in private browsing mode anyway,
       // so there's no need to perform further checks.
       log("(form submission ignored in private browsing mode)");
       return;
     }
 
     // If password saving is disabled (globally or for host), bail out now.
-    if (!gEnabled) {
+    if (!LoginHelper.enabled) {
       return;
     }
 
     var hostname = LoginUtils._getPasswordOrigin(doc.documentURI);
     if (!hostname) {
       log("(form submission ignored -- invalid hostname)");
       return;
     }
@@ -969,17 +956,17 @@ var LoginManagerContent = {
     // Check for autocomplete=off attribute. We don't use it to prevent
     // autofilling (for existing logins), but won't save logins when it's
     // present and the storeWhenAutocompleteOff pref is false.
     // XXX spin out a bug that we don't update timeLastUsed in this case?
     if ((this._isAutocompleteDisabled(form) ||
          this._isAutocompleteDisabled(usernameField) ||
          this._isAutocompleteDisabled(newPasswordField) ||
          this._isAutocompleteDisabled(oldPasswordField)) &&
-        !gStoreWhenAutocompleteOff) {
+        !LoginHelper.storeWhenAutocompleteOff) {
       log("(form submission ignored -- autocomplete=off found)");
       return;
     }
 
     // Don't try to send DOM nodes over IPC.
     let mockUsername = usernameField ?
                          { name: usernameField.name,
                            value: usernameField.value } :