Bug 1508806 - Toggling between content blocking categories correctly changes when there are multiple windows. r=johannh
authorErica Wright <ewright@mozilla.com>
Fri, 23 Nov 2018 16:08:58 +0000
changeset 507087 0fb9b230634c1bed2090b8f899861d59aa1b4f13
parent 507086 3f6e77ccc5a4ed8cbdd2f08c9cf7444dce072ada
child 507088 8ab07484e939f28ef182671a0cac6e444efa06bf
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1508806
milestone65.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 1508806 - Toggling between content blocking categories correctly changes when there are multiple windows. r=johannh We no longer set up a listener on a per-window basis for category preference changes. Differential Revision: https://phabricator.services.mozilla.com/D12667
browser/base/content/browser-contentblocking.js
browser/components/nsBrowserGlue.js
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -222,38 +222,20 @@ var ThirdPartyCookies = {
 
 var ContentBlocking = {
   // If the user ignores the doorhanger, we stop showing it after some time.
   MAX_INTROS: 20,
   PREF_ANIMATIONS_ENABLED: "toolkit.cosmeticAnimations.enabled",
   PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.reportBreakage.enabled",
   PREF_REPORT_BREAKAGE_URL: "browser.contentblocking.reportBreakage.url",
   PREF_INTRO_COUNT_CB: "browser.contentblocking.introCount",
-  PREF_CB_CATEGORY: "browser.contentblocking.category",
-  // The prefs inside CATEGORY_PREFS set expected behavior for each CB category.
-  // A null value means that pref is default.
-  CATEGORY_PREFS: {
-    strict: [
-      [TrackingProtection.PREF_TRACKING_TABLE, null],
-      [ThirdPartyCookies.PREF_ENABLED, Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN],
-      [TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS, true],
-      [TrackingProtection.PREF_ENABLED_GLOBALLY, true],
-    ],
-    standard: [
-      [TrackingProtection.PREF_TRACKING_TABLE, null],
-      [ThirdPartyCookies.PREF_ENABLED, null],
-      [TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS, null],
-      [TrackingProtection.PREF_ENABLED_GLOBALLY, null],
-    ],
-  },
   content: null,
   icon: null,
   activeTooltipText: null,
   disabledTooltipText: null,
-  switchingCategory: false,
 
   get prefIntroCount() {
     return this.PREF_INTRO_COUNT_CB;
   },
 
   get appMenuLabel() {
     delete this.appMenuLabel;
     return this.appMenuLabel = document.getElementById("appMenu-tp-label");
@@ -337,38 +319,26 @@ var ContentBlocking = {
 
     this.appMenuLabel.setAttribute("label", this.strings.appMenuTitle);
     this.appMenuLabel.setAttribute("tooltiptext", this.strings.appMenuTooltip);
 
     this.activeTooltipText =
       gNavigatorBundle.getString("trackingProtection.icon.activeTooltip");
     this.disabledTooltipText =
       gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip");
-
-    this.matchCBCategory = this.matchCBCategory.bind(this);
-    this.updateCBCategory = this.updateCBCategory.bind(this);
-    this.matchCBCategory();
-    Services.prefs.addObserver(TrackingProtection.PREF_ENABLED_GLOBALLY, this.matchCBCategory);
-    Services.prefs.addObserver(TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS, this.matchCBCategory);
-    Services.prefs.addObserver(ThirdPartyCookies.PREF_ENABLED, this.matchCBCategory);
-    Services.prefs.addObserver(this.PREF_CB_CATEGORY, this.updateCBCategory);
   },
 
   uninit() {
     for (let blocker of this.blockers) {
       if (blocker.uninit) {
         blocker.uninit();
       }
     }
 
     Services.prefs.removeObserver(this.PREF_ANIMATIONS_ENABLED, this.updateAnimationsEnabled);
-    Services.prefs.removeObserver(TrackingProtection.PREF_ENABLED_GLOBALLY, this.matchCBCategory);
-    Services.prefs.removeObserver(TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS, this.matchCBCategory);
-    Services.prefs.removeObserver(ThirdPartyCookies.PREF_ENABLED, this.matchCBCategory);
-    Services.prefs.removeObserver(this.PREF_CB_CATEGORY, this.updateCBCategory);
   },
 
   hideIdentityPopupAndReload() {
     this.identityPopup.hidePopup();
     BrowserReload();
   },
 
   openPreferences(origin) {
@@ -635,94 +605,9 @@ var ContentBlocking = {
       },
     ];
 
     let panelTarget = await UITour.getTarget(window, "trackingProtection");
     UITour.initForBrowser(gBrowser.selectedBrowser, window);
     UITour.showInfo(window, panelTarget, introTitle, introDescription, undefined, buttons,
                     { closeButtonCallback: () => this.dontShowIntroPanelAgain() });
   },
-
-  /**
-   * Checks if CB prefs match perfectly with one of our pre-defined categories.
-   */
-  prefsMatch(category) {
-    // The category pref must be either unset, or match.
-    if (Services.prefs.prefHasUserValue(this.PREF_CB_CATEGORY) &&
-        Services.prefs.getStringPref(this.PREF_CB_CATEGORY) != category) {
-      return false;
-    }
-    for (let [pref, value] of this.CATEGORY_PREFS[category]) {
-      if (!value) {
-        if (Services.prefs.prefHasUserValue(pref)) {
-          return false;
-        }
-      } else {
-        let prefType = Services.prefs.getPrefType(pref);
-        if ((prefType == Services.prefs.PREF_BOOL && Services.prefs.getBoolPref(pref) != value) ||
-            (prefType == Services.prefs.PREF_INT && Services.prefs.getIntPref(pref) != value) ||
-            (prefType == Services.prefs.PREF_STRING && Services.prefs.getStringPref(pref) != value)) {
-          return false;
-        }
-      }
-    }
-    return true;
-  },
-
-  async matchCBCategory() {
-    if (this.switchingCategory) {
-      return;
-    }
-    // If PREF_CB_CATEGORY is not set match users to a Content Blocking category. Check if prefs fit
-    // perfectly into strict or standard, otherwise match with custom. If PREF_CB_CATEGORY has previously been set,
-    // a change of one of these prefs necessarily puts us in "custom".
-    if (this.prefsMatch("standard")) {
-      Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "standard");
-    } else if (this.prefsMatch("strict")) {
-      Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "strict");
-    } else {
-      Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "custom");
-    }
-  },
-
-  updateCBCategory() {
-    if (this.switchingCategory) {
-      return;
-    }
-    // Turn on switchingCategory flag, to ensure that when the individual prefs that change as a result
-    // of the category change do not trigger yet another category change.
-    this.switchingCategory = true;
-    let value = Services.prefs.getStringPref(this.PREF_CB_CATEGORY);
-    this.setPrefsToCategory(value);
-    this.switchingCategory = false;
-  },
-
-  /**
-   * Sets all user-exposed content blocking preferences to values that match the selected category.
-   */
-  setPrefsToCategory(category) {
-    // Leave prefs as they were if we are switching to "custom" category.
-    if (category == "custom") {
-      return;
-    }
-
-    for (let [pref, value] of this.CATEGORY_PREFS[category]) {
-      // this.setPrefIfNotLocked(pref[0], pref[1]);
-      if (!Services.prefs.prefIsLocked(pref)) {
-        if (!value) {
-          Services.prefs.clearUserPref(pref);
-        } else {
-          switch (Services.prefs.getPrefType(pref)) {
-          case Services.prefs.PREF_BOOL:
-            Services.prefs.setBoolPref(pref, value);
-            break;
-          case Services.prefs.PREF_INT:
-            Services.prefs.setIntPref(pref, value);
-            break;
-          case Services.prefs.PREF_STRING:
-            Services.prefs.setStringPref(pref, value);
-            break;
-          }
-        }
-      }
-    }
-  },
 };
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -989,16 +989,22 @@ BrowserGlue.prototype = {
     os.removeObserver(this, "handle-xul-text-link");
     os.removeObserver(this, "profile-before-change");
     os.removeObserver(this, "keyword-search");
     os.removeObserver(this, "browser-search-engine-modified");
     os.removeObserver(this, "flash-plugin-hang");
     os.removeObserver(this, "xpi-signature-changed");
     os.removeObserver(this, "sync-ui-state:update");
     os.removeObserver(this, "shield-init-complete");
+
+    Services.prefs.removeObserver("privacy.trackingprotection.enabled", this._matchCBCategory);
+    Services.prefs.removeObserver("privacy.trackingprotection.pbmode.enabled", this._matchCBCategory);
+    Services.prefs.removeObserver("urlclassifier.trackingTable", this._matchCBCategory);
+    Services.prefs.removeObserver("network.cookie.cookieBehavior", this._matchCBCategory);
+    Services.prefs.removeObserver(ContentBlockingCategoriesPrefs.PREF_CB_CATEGORY, this._updateCBCategory);
   },
 
   // runs on startup, before the first command line handler is invoked
   // (i.e. before the first window is opened)
   _beforeUIStartup: function BG__beforeUIStartup() {
     SessionStartup.init();
 
     if (Services.prefs.prefHasUserValue(PREF_PDFJS_ENABLED_CACHE_STATE)) {
@@ -1359,16 +1365,31 @@ BrowserGlue.prototype = {
 
     PageActions.init();
 
     this._firstWindowTelemetry(aWindow);
     this._firstWindowLoaded();
 
     // Set the default favicon size for UI views that use the page-icon protocol.
     PlacesUtils.favicons.setDefaultIconURIPreferredSize(16 * aWindow.devicePixelRatio);
+
+    this._matchCBCategory();
+    Services.prefs.addObserver("privacy.trackingprotection.enabled", this._matchCBCategory);
+    Services.prefs.addObserver("privacy.trackingprotection.pbmode.enabled", this._matchCBCategory);
+    Services.prefs.addObserver("urlclassifier.trackingTable", this._matchCBCategory);
+    Services.prefs.addObserver("network.cookie.cookieBehavior", this._matchCBCategory);
+    Services.prefs.addObserver(ContentBlockingCategoriesPrefs.PREF_CB_CATEGORY, this._updateCBCategory);
+  },
+
+  _matchCBCategory() {
+    ContentBlockingCategoriesPrefs.matchCBCategory();
+  },
+
+  _updateCBCategory() {
+    ContentBlockingCategoriesPrefs.updateCBCategory();
   },
 
   _recordContentBlockingTelemetry() {
     let recordIdentityPopupEvents = Services.prefs.getBoolPref("security.identitypopup.recordEventElemetry");
     Services.telemetry.setEventRecordingEnabled("security.ui.identitypopup", recordIdentityPopupEvents);
 
     let tpEnabled = Services.prefs.getBoolPref("privacy.trackingprotection.enabled");
     Services.telemetry.getHistogramById("TRACKING_PROTECTION_ENABLED").add(tpEnabled);
@@ -2952,16 +2973,121 @@ BrowserGlue.prototype = {
   classID:          Components.ID("{eab9012e-5f74-4cbc-b2b5-a590235513cc}"),
 
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
                                           Ci.nsISupportsWeakReference]),
 
   _xpcom_factory: XPCOMUtils.generateSingletonFactory(BrowserGlue),
 };
 
+var ContentBlockingCategoriesPrefs = {
+  PREF_CB_CATEGORY: "browser.contentblocking.category",
+  // The prefs inside CATEGORY_PREFS set expected value for each CB category.
+  // A null value means that pref is default.
+  CATEGORY_PREFS: {
+    strict: [
+      ["urlclassifier.trackingTable", null],
+      ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN],
+      ["privacy.trackingprotection.pbmode.enabled", true],
+      ["privacy.trackingprotection.enabled", true],
+    ],
+    standard: [
+      ["urlclassifier.trackingTable", null],
+      ["network.cookie.cookieBehavior", null],
+      ["privacy.trackingprotection.pbmode.enabled", null],
+      ["privacy.trackingprotection.enabled", null],
+    ],
+  },
+  switchingCategory: false,
+
+  /**
+   * Checks if CB prefs match perfectly with one of our pre-defined categories.
+   */
+  prefsMatch(category) {
+    // The category pref must be either unset, or match.
+    if (Services.prefs.prefHasUserValue(this.PREF_CB_CATEGORY) &&
+        Services.prefs.getStringPref(this.PREF_CB_CATEGORY) != category) {
+      return false;
+    }
+    for (let [pref, value] of this.CATEGORY_PREFS[category]) {
+      if (!value) {
+        if (Services.prefs.prefHasUserValue(pref)) {
+          return false;
+        }
+      } else {
+        let prefType = Services.prefs.getPrefType(pref);
+        if ((prefType == Services.prefs.PREF_BOOL && Services.prefs.getBoolPref(pref) != value) ||
+            (prefType == Services.prefs.PREF_INT && Services.prefs.getIntPref(pref) != value) ||
+            (prefType == Services.prefs.PREF_STRING && Services.prefs.getStringPref(pref) != value)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  },
+
+  matchCBCategory() {
+    if (this.switchingCategory) {
+      return;
+    }
+    // If PREF_CB_CATEGORY is not set match users to a Content Blocking category. Check if prefs fit
+    // perfectly into strict or standard, otherwise match with custom. If PREF_CB_CATEGORY has previously been set,
+    // a change of one of these prefs necessarily puts us in "custom".
+    if (this.prefsMatch("standard")) {
+      Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "standard");
+    } else if (this.prefsMatch("strict")) {
+      Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "strict");
+    } else {
+      Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "custom");
+    }
+  },
+
+  updateCBCategory() {
+    if (this.switchingCategory) {
+      return;
+    }
+    // Turn on switchingCategory flag, to ensure that when the individual prefs that change as a result
+    // of the category change do not trigger yet another category change.
+    this.switchingCategory = true;
+    let value = Services.prefs.getStringPref(this.PREF_CB_CATEGORY);
+    this.setPrefsToCategory(value);
+    this.switchingCategory = false;
+  },
+
+  /**
+   * Sets all user-exposed content blocking preferences to values that match the selected category.
+   */
+  setPrefsToCategory(category) {
+    // Leave prefs as they were if we are switching to "custom" category.
+    if (category == "custom") {
+      return;
+    }
+
+    for (let [pref, value] of this.CATEGORY_PREFS[category]) {
+      if (!Services.prefs.prefIsLocked(pref)) {
+        if (!value) {
+          Services.prefs.clearUserPref(pref);
+        } else {
+          switch (Services.prefs.getPrefType(pref)) {
+          case Services.prefs.PREF_BOOL:
+            Services.prefs.setBoolPref(pref, value);
+            break;
+          case Services.prefs.PREF_INT:
+            Services.prefs.setIntPref(pref, value);
+            break;
+          case Services.prefs.PREF_STRING:
+            Services.prefs.setStringPref(pref, value);
+            break;
+          }
+        }
+      }
+    }
+  },
+};
+
 /**
  * ContentPermissionIntegration is responsible for showing the user
  * simple permission prompts when content requests additional
  * capabilities.
  *
  * While there are some built-in permission prompts, createPermissionPrompt
  * can also be overridden by system add-ons or tests to provide new ones.
  *