Backed out 5 changesets (bug 1531838) for causing linux asan leaks. CLOSED TREE
authorOana Pop Rus <opoprus@mozilla.com>
Fri, 12 Apr 2019 02:15:40 +0300
changeset 469121 236d2bc601b0604b30e03b2e61a50a3886961edb
parent 469120 6922b4c2b5c57ca3ac2d20d1062312d335a0845e
child 469122 6826a3ede4cab76cf3a9a9d2f94a0ac8252c6cf7
push id35856
push usercsabou@mozilla.com
push dateFri, 12 Apr 2019 03:19:48 +0000
treeherdermozilla-central@940684cd1065 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1531838
milestone68.0a1
backs out7e886806ae987d8008486c878921a8a33329c55b
24d7fb7fd3afbc15a4018d926fa091f1c5ad4fc6
3e538caf5af2417e46ba5232e2c9ab51f6b69c6c
ae727251b8026d80fe223511c8bbeff92b7820cc
9b0dab8154c0957fbdfba6c220b6b952afb54a4a
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
Backed out 5 changesets (bug 1531838) for causing linux asan leaks. CLOSED TREE Backed out changeset 7e886806ae98 (bug 1531838) Backed out changeset 24d7fb7fd3af (bug 1531838) Backed out changeset 3e538caf5af2 (bug 1531838) Backed out changeset ae727251b802 (bug 1531838) Backed out changeset 9b0dab8154c0 (bug 1531838)
browser/base/content/test/plugins/browser_private_clicktoplay.js
browser/extensions/fxmonitor/moz.build
browser/extensions/fxmonitor/privileged/FirefoxMonitor.jsm
browser/extensions/fxmonitor/privileged/subscripts/PanelUI.jsm
--- a/browser/base/content/test/plugins/browser_private_clicktoplay.js
+++ b/browser/base/content/test/plugins/browser_private_clicktoplay.js
@@ -105,19 +105,17 @@ add_task(async function test2a() {
   });
 });
 
 add_task(async function test2c() {
   let topicObserved = TestUtils.topicObserved("PopupNotifications-updateNotShowing");
   await createPrivateWindow(gHttpTestRoot + "plugin_test.html");
   await topicObserved;
 
-  let popupNotification = await TestUtils.waitForCondition(() => {
-    return gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
-  }, "Waiting for click-to-play-plugins notification in the private window");
+  let popupNotification = gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
   ok(popupNotification, "Test 2c, Should have a click-to-play notification");
 
   await ContentTask.spawn(gPrivateBrowser, null, function() {
     let plugin = content.document.getElementById("test");
     let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
     ok(objLoadingContent.activated, "Test 2c, Plugin should be activated");
   });
 
@@ -169,19 +167,17 @@ add_task(async function test3a() {
   });
 });
 
 add_task(async function test3c() {
   let topicObserved = TestUtils.topicObserved("PopupNotifications-updateNotShowing");
   await createPrivateWindow(gHttpTestRoot + "plugin_test.html");
   await topicObserved;
 
-  let popupNotification = await TestUtils.waitForCondition(() => {
-    return gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
-  }, "Waiting for click-to-play-plugins notification in the private window");
+  let popupNotification = gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
   ok(popupNotification, "Test 3c, Should have a click-to-play notification");
 
   // Check the button status
   let promiseShown = BrowserTestUtils.waitForEvent(gPrivateWindow.PopupNotifications.panel,
                                                    "Shown");
   popupNotification.reshow();
   await promiseShown;
   is(gPrivateWindow.PopupNotifications.panel.firstElementChild.secondaryButton.hidden, true,
--- a/browser/extensions/fxmonitor/moz.build
+++ b/browser/extensions/fxmonitor/moz.build
@@ -23,13 +23,14 @@ FINAL_TARGET_FILES.features['fxmonitor@m
   'privileged/api.js',
   'privileged/FirefoxMonitor.css',
   'privileged/FirefoxMonitor.jsm',
   'privileged/schema.json'
 ]
 
 FINAL_TARGET_FILES.features['fxmonitor@mozilla.org']['privileged']['subscripts'] += [
   'privileged/subscripts/EveryWindow.jsm',
-  'privileged/subscripts/Globals.jsm'
+  'privileged/subscripts/Globals.jsm',
+  'privileged/subscripts/PanelUI.jsm'
 ]
 
 with Files('**'):
   BUG_COMPONENT = ('Firefox', 'Firefox Monitor')
--- a/browser/extensions/fxmonitor/privileged/FirefoxMonitor.jsm
+++ b/browser/extensions/fxmonitor/privileged/FirefoxMonitor.jsm
@@ -68,17 +68,17 @@ this.FirefoxMonitor = {
   getFormattedString(aKey, args) {
     return this.strings.formatStringFromName(aKey, args, args.length);
   },
 
   init(aExtension) {
     this.extension = aExtension;
 
     XPCOMUtils.defineLazyPreferenceGetter(
-      this, "enabled", this.kEnabledPref, true,
+      this, "enabled", this.kEnabledPref, false,
       (pref, oldVal, newVal) => {
         if (newVal) {
           this.startObserving();
         } else {
           this.stopObserving();
         }
       }
     );
@@ -99,16 +99,20 @@ this.FirefoxMonitor = {
     /* globals Preferences, RemoteSettings, fetch, btoa, XUL_NS */
     Services.scriptloader.loadSubScript(
       this.getURL("privileged/subscripts/Globals.jsm"));
 
     /* globals EveryWindow */
     Services.scriptloader.loadSubScript(
       this.getURL("privileged/subscripts/EveryWindow.jsm"));
 
+    /* globals PanelUI */
+    Services.scriptloader.loadSubScript(
+      this.getURL("privileged/subscripts/PanelUI.jsm"));
+
     // Expire our telemetry on November 1, at which time
     // we should redo data-review.
     let telemetryExpiryDate = new Date(2019, 10, 1); // Month is zero-index
     let today = new Date();
     let expired = today.getTime() > telemetryExpiryDate.getTime();
 
     Services.telemetry.registerEvents("fxmonitor", {
       "interaction": {
@@ -223,44 +227,51 @@ this.FirefoxMonitor = {
       // If we can't get the host for the URL, it's not one we
       // care about for breach alerts anyway.
       return;
     }
 
     this.warnIfNeeded(aBrowser, host);
   },
 
-  notificationsByWindow: new WeakMap(),
-  panelUIsByWindow: new WeakMap(),
-
   async startObserving() {
     if (this.observerAdded) {
       return;
     }
 
     await this.delayedInit();
 
     EveryWindow.registerCallback(
       this.kNotificationID,
       (win) => {
-        if (this.notificationsByWindow.has(win)) {
-          // We've already set up this window.
-          return;
-        }
-
-        this.notificationsByWindow.set(win, new Set());
+        // Inject our stylesheet.
+        let DOMWindowUtils = win.windowUtils;
+        DOMWindowUtils.loadSheetUsingURIString(this.getURL("privileged/FirefoxMonitor.css"),
+                                               DOMWindowUtils.AUTHOR_SHEET);
 
-        // Inject our stylesheet. This is queued in order to avoid spinning
-        // a nested event loop during a MozAfterPaint handler.
-        // See bug 1531838 comment 15.
-        Services.tm.dispatchToMainThread(() => {
-          let DOMWindowUtils = win.windowUtils;
-          DOMWindowUtils.loadSheetUsingURIString(this.getURL("privileged/FirefoxMonitor.css"),
-                                                 DOMWindowUtils.AUTHOR_SHEET);
-        });
+        // Set up some helper functions on the window object
+        // for the popup notification to use.
+        win.FirefoxMonitorUtils = {
+          // Keeps track of all notifications currently shown,
+          // so that we can clear them out properly if we get
+          // disabled.
+          notifications: new Set(),
+          disable: () => {
+            this.disable();
+          },
+          getString: (aKey) => {
+            return this.getString(aKey);
+          },
+          getFormattedString: (aKey, args) => {
+            return this.getFormattedString(aKey, args);
+          },
+          getFirefoxMonitorURL: (aSiteName) => {
+            return `${this.FirefoxMonitorURL}/?breach=${encodeURIComponent(aSiteName)}&utm_source=firefox&utm_medium=popup`;
+          },
+        };
 
         // Setup the popup notification stuff. First, the URL bar icon:
         let doc = win.document;
         let notificationBox = doc.getElementById("notification-popup-box");
         // We create a box to use as the anchor, and put an icon image
         // inside it. This way, when we animate the icon, its scale change
         // does not cause the popup notification to bounce due to the anchor
         // point moving.
@@ -282,43 +293,46 @@ this.FirefoxMonitor = {
         let pn = doc.createElementNS(XUL_NS, "popupnotification");
         let pnContent = doc.createElementNS(XUL_NS, "popupnotificationcontent");
         let panelUI = new PanelUI(doc);
         pnContent.appendChild(panelUI.box);
         pn.appendChild(pnContent);
         pn.setAttribute("id", `${this.kNotificationID}-notification`);
         pn.setAttribute("hidden", "true");
         parentElt.appendChild(pn);
-        this.panelUIsByWindow.set(win, panelUI);
+        win.FirefoxMonitorPanelUI = panelUI;
 
         // Start listening across all tabs!
         win.gBrowser.addTabsProgressListener(this);
       },
       (win) => {
         // If the window is being destroyed and gBrowser no longer exists,
         // don't bother doing anything.
         if (!win.gBrowser) {
           return;
         }
 
-        Services.tm.dispatchToMainThread(() => {
-          let DOMWindowUtils = win.windowUtils;
-          DOMWindowUtils.removeSheetUsingURIString(this.getURL("privileged/FirefoxMonitor.css"),
-                                                   DOMWindowUtils.AUTHOR_SHEET);
-        });
+        let DOMWindowUtils = win.windowUtils;
+        if (!DOMWindowUtils) {
+          // win.windowUtils was added in 63, fallback if it's not available.
+          DOMWindowUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
+                              .getInterface(Ci.nsIDOMWindowUtils);
+        }
+        DOMWindowUtils.removeSheetUsingURIString(this.getURL("privileged/FirefoxMonitor.css"),
+                                                 DOMWindowUtils.AUTHOR_SHEET);
 
-        this.notificationsByWindow.get(win).forEach(n => {
+        win.FirefoxMonitorUtils.notifications.forEach(n => {
           n.remove();
         });
-        this.notificationsByWindow.delete(win);
+        delete win.FirefoxMonitorUtils;
 
         let doc = win.document;
         doc.getElementById(`${this.kNotificationID}-notification-anchor`).remove();
         doc.getElementById(`${this.kNotificationID}-notification`).remove();
-        this.panelUIsByWindow.delete(win);
+        delete win.FirefoxMonitorPanelUI;
 
         win.gBrowser.removeTabsProgressListener(this);
       },
     );
 
     this.observerAdded = true;
   },
 
@@ -355,17 +369,17 @@ this.FirefoxMonitor = {
       Preferences.set(this.kFirstAlertShownPref, true);
     }
 
     this.warnedHostsSet.add(host);
     Preferences.set(this.kWarnedHostsPref, JSON.stringify([...this.warnedHostsSet]));
 
     let doc = browser.ownerDocument;
     let win = doc.defaultView;
-    let panelUI = this.panelUIsByWindow.get(win);
+    let panelUI = doc.defaultView.FirefoxMonitorPanelUI;
 
     let animatedOnce = false;
     let populatePanel = (event) => {
       switch (event) {
         case "showing":
           panelUI.refresh(site);
           if (animatedOnce) {
             // If we've already animated once for this site, don't animate again.
@@ -381,17 +395,17 @@ this.FirefoxMonitor = {
              .removeAttribute("fxmonitoranimationdone");
           doc.getElementById(`${this.kNotificationID}-notification-anchor`)
              .removeAttribute("fxmonitoranimationdone");
           break;
         case "shown":
           animatedOnce = true;
           break;
         case "removed":
-          this.notificationsByWindow.get(win).delete(
+          win.FirefoxMonitorUtils.notifications.delete(
             win.PopupNotifications.getNotification(this.kNotificationID, browser));
           Services.telemetry.recordEvent("fxmonitor", "interaction", "doorhanger_removed");
           break;
       }
     };
 
     let n = win.PopupNotifications.show(
       browser, this.kNotificationID, "",
@@ -401,123 +415,11 @@ this.FirefoxMonitor = {
         hideClose: true,
         eventCallback: populatePanel,
         popupIconURL: this.getURL("assets/monitor32.svg"),
       }
     );
 
     Services.telemetry.recordEvent("fxmonitor", "interaction", "doorhanger_shown");
 
-    this.notificationsByWindow.get(win).add(n);
+    win.FirefoxMonitorUtils.notifications.add(n);
   },
 };
-
-/* globals PluralForm */
-
-function PanelUI(doc) {
-  this.site = null;
-  this.doc = doc;
-
-  let box = doc.createElementNS(XUL_NS, "vbox");
-
-  let elt = doc.createElementNS(XUL_NS, "description");
-  elt.textContent = this.getString("fxmonitor.popupHeader");
-  elt.classList.add("headerText");
-  box.appendChild(elt);
-
-  elt = doc.createElementNS(XUL_NS, "description");
-  elt.classList.add("popupText");
-  box.appendChild(elt);
-
-  this.box = box;
-}
-
-PanelUI.prototype = {
-  getString(aKey) {
-    return FirefoxMonitor.getString(aKey);
-  },
-
-  getFormattedString(aKey, args) {
-    return FirefoxMonitor.getFormattedString(aKey, args);
-  },
-
-  get brandString() {
-    if (this._brandString) {
-      return this._brandString;
-    }
-    return this._brandString = this.getString("fxmonitor.brandName");
-  },
-
-  getFirefoxMonitorURL: (aSiteName) => {
-    return `${FirefoxMonitor.FirefoxMonitorURL}/?breach=${encodeURIComponent(aSiteName)}&utm_source=firefox&utm_medium=popup`;
-  },
-
-  get primaryAction() {
-    if (this._primaryAction) {
-      return this._primaryAction;
-    }
-    return this._primaryAction = {
-      label: this.getFormattedString("fxmonitor.checkButton.label", [this.brandString]),
-      accessKey: this.getString("fxmonitor.checkButton.accessKey"),
-      callback: () => {
-        let win = this.doc.defaultView;
-        win.openTrustedLinkIn(
-          this.getFirefoxMonitorURL(this.site.Name), "tab", { });
-
-        Services.telemetry.recordEvent("fxmonitor", "interaction", "check_btn");
-      },
-    };
-  },
-
-  get secondaryActions() {
-    if (this._secondaryActions) {
-      return this._secondaryActions;
-    }
-    return this._secondaryActions = [
-      {
-        label: this.getString("fxmonitor.dismissButton.label"),
-        accessKey: this.getString("fxmonitor.dismissButton.accessKey"),
-        callback: () => {
-          Services.telemetry.recordEvent("fxmonitor", "interaction", "dismiss_btn");
-        },
-      }, {
-        label: this.getFormattedString("fxmonitor.neverShowButton.label", [this.brandString]),
-        accessKey: this.getString("fxmonitor.neverShowButton.accessKey"),
-        callback: () => {
-          FirefoxMonitor.disable();
-          Services.telemetry.recordEvent("fxmonitor", "interaction", "never_show_btn");
-        },
-      },
-    ];
-  },
-
-  refresh(site) {
-    this.site = site;
-
-    let elt = this.box.querySelector(".popupText");
-
-    // If > 100k, the PwnCount is rounded down to the most significant
-    // digit and prefixed with "More than".
-    // Ex.: 12,345 -> 12,345
-    //      234,567 -> More than 200,000
-    //      345,678,901 -> More than 300,000,000
-    //      4,567,890,123 -> More than 4,000,000,000
-    let k100k = 100000;
-    let pwnCount = site.PwnCount;
-    let stringName = "fxmonitor.popupText";
-    if (pwnCount > k100k) {
-      let multiplier = 1;
-      while (pwnCount >= 10) {
-        pwnCount /= 10;
-        multiplier *= 10;
-      }
-      pwnCount = Math.floor(pwnCount) * multiplier;
-      stringName = "fxmonitor.popupTextRounded";
-    }
-
-    elt.textContent =
-      PluralForm.get(pwnCount, this.getString(stringName))
-                .replace("#1", pwnCount.toLocaleString())
-                .replace("#2", site.Name)
-                .replace("#3", site.Year)
-                .replace("#4", this.brandString);
-  },
-};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/fxmonitor/privileged/subscripts/PanelUI.jsm
@@ -0,0 +1,117 @@
+/* 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/. */
+
+/* globals XUL_NS, Services, PluralForm */
+
+function PanelUI(doc) {
+  this.site = null;
+  this.doc = doc;
+
+  let box = doc.createElementNS(XUL_NS, "vbox");
+
+  let elt = doc.createElementNS(XUL_NS, "description");
+  elt.textContent = this.getString("fxmonitor.popupHeader");
+  elt.classList.add("headerText");
+  box.appendChild(elt);
+
+  elt = doc.createElementNS(XUL_NS, "description");
+  elt.classList.add("popupText");
+  box.appendChild(elt);
+
+  this.box = box;
+}
+
+PanelUI.prototype = {
+  get FirefoxMonitorUtils() {
+    // Set on every window by FirefoxMonitor.jsm for PanelUI to use.
+    // Because sharing is caring.
+    return this.doc.defaultView.FirefoxMonitorUtils;
+  },
+
+  getString(aKey) {
+    return this.FirefoxMonitorUtils.getString(aKey);
+  },
+
+  getFormattedString(aKey, args) {
+    return this.FirefoxMonitorUtils.getFormattedString(aKey, args);
+  },
+
+  get brandString() {
+    if (this._brandString) {
+      return this._brandString;
+    }
+    return this._brandString = this.getString("fxmonitor.brandName");
+  },
+
+  get primaryAction() {
+    if (this._primaryAction) {
+      return this._primaryAction;
+    }
+    return this._primaryAction = {
+      label: this.getFormattedString("fxmonitor.checkButton.label", [this.brandString]),
+      accessKey: this.getString("fxmonitor.checkButton.accessKey"),
+      callback: () => {
+        let win = this.doc.defaultView;
+        win.openTrustedLinkIn(
+          win.FirefoxMonitorUtils.getFirefoxMonitorURL(this.site.Name), "tab", { });
+
+        Services.telemetry.recordEvent("fxmonitor", "interaction", "check_btn");
+      },
+    };
+  },
+
+  get secondaryActions() {
+    if (this._secondaryActions) {
+      return this._secondaryActions;
+    }
+    return this._secondaryActions = [
+      {
+        label: this.getString("fxmonitor.dismissButton.label"),
+        accessKey: this.getString("fxmonitor.dismissButton.accessKey"),
+        callback: () => {
+          Services.telemetry.recordEvent("fxmonitor", "interaction", "dismiss_btn");
+        },
+      }, {
+        label: this.getFormattedString("fxmonitor.neverShowButton.label", [this.brandString]),
+        accessKey: this.getString("fxmonitor.neverShowButton.accessKey"),
+        callback: () => {
+          this.FirefoxMonitorUtils.disable();
+          Services.telemetry.recordEvent("fxmonitor", "interaction", "never_show_btn");
+        },
+      },
+    ];
+  },
+
+  refresh(site) {
+    this.site = site;
+
+    let elt = this.box.querySelector(".popupText");
+
+    // If > 100k, the PwnCount is rounded down to the most significant
+    // digit and prefixed with "More than".
+    // Ex.: 12,345 -> 12,345
+    //      234,567 -> More than 200,000
+    //      345,678,901 -> More than 300,000,000
+    //      4,567,890,123 -> More than 4,000,000,000
+    let k100k = 100000;
+    let pwnCount = site.PwnCount;
+    let stringName = "fxmonitor.popupText";
+    if (pwnCount > k100k) {
+      let multiplier = 1;
+      while (pwnCount >= 10) {
+        pwnCount /= 10;
+        multiplier *= 10;
+      }
+      pwnCount = Math.floor(pwnCount) * multiplier;
+      stringName = "fxmonitor.popupTextRounded";
+    }
+
+    elt.textContent =
+      PluralForm.get(pwnCount, this.getString(stringName))
+                .replace("#1", pwnCount.toLocaleString())
+                .replace("#2", site.Name)
+                .replace("#3", site.Year)
+                .replace("#4", this.brandString);
+  },
+};