Bug 1533362 - Record contentBlockingEvent for background tabs. r=Ehsan
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 15 Mar 2019 17:37:26 +0000
changeset 464408 f6a8502a80bf
parent 464407 893781729409
child 464409 0b05d8817659
push id35716
push useraciure@mozilla.com
push dateSun, 17 Mar 2019 09:42:17 +0000
treeherdermozilla-central@8ee97c045359 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEhsan
bugs1533362
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 1533362 - Record contentBlockingEvent for background tabs. r=Ehsan When switching tabs we use the securityUI.contentBlockingEvent property to update the shield state. That property is set in https://searchfox.org/mozilla-central/rev/aae527894a97ee3bbe0c2cfce9c67c59e8b8fcb9/browser/base/content/browser.js#5025. Unfortunately, that event is only received by the current browser because is is registered with gBrowser.addProgressListener instead of gBrowser.addTabsProgressListener. Thus, the background tab is not storing its content blocking event. To fix this, we also listen for content blocking events with addTabsProgressListener, but exclude the currently selected tab there. Differential Revision: https://phabricator.services.mozilla.com/D23485
browser/base/content/browser.js
browser/base/content/test/trackingUI/browser.ini
browser/base/content/test/trackingUI/browser_trackingUI_background_tabs.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5086,16 +5086,19 @@ var XULBrowserWindow = {
     this._event = aEvent;
     this._lastLocationForEvent = spec;
 
     if (typeof(aIsSimulated) != "boolean" && typeof(aIsSimulated) != "undefined") {
       throw "onContentBlockingEvent: aIsSimulated receieved an unexpected type";
     }
 
     ContentBlocking.onContentBlockingEvent(this._event, aWebProgress, aIsSimulated);
+    // Because this function will only receive content blocking event updates
+    // for the currently selected tab, we handle updates to background tabs in
+    // TabsProgressListener.onContentBlockingEvent.
     gBrowser.selectedBrowser.updateSecurityUIForContentBlockingEvent(aEvent);
   },
 
   // This is called in multiple ways:
   //  1. Due to the nsIWebProgressListener.onSecurityChange notification.
   //  2. Called by tabbrowser.xml when updating the current browser.
   //  3. Called directly during this object's initializations.
   // aRequest will be null always in case 2 and 3, and sometimes in case 1.
@@ -5456,16 +5459,24 @@ const AccessibilityRefreshBlocker = {
       this._loaded = true;
       let mm = window.getGroupMessageManager("browsers");
       mm.loadFrameScript("chrome://browser/content/content-refreshblocker.js", true, true);
     }
   },
 };
 
 var TabsProgressListener = {
+  onContentBlockingEvent(aBrowser, aWebProgress, aRequest, aEvent) {
+    // Handle content blocking events for background (=non-selected) tabs.
+    // This event is processed for the selected tab in XULBrowserWindow.onContentBlockingEvent.
+    if (aBrowser != gBrowser.selectedBrowser) {
+      aBrowser.updateSecurityUIForContentBlockingEvent(aEvent);
+    }
+  },
+
   onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
     // Collect telemetry data about tab load times.
     if (aWebProgress.isTopLevel && (!aRequest.originalURI || aRequest.originalURI.scheme != "about")) {
       let stopwatchRunning = TelemetryStopwatch.running("FX_PAGE_LOAD_MS_2", aBrowser);
 
       if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
         if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
           if (stopwatchRunning) {
--- a/browser/base/content/test/trackingUI/browser.ini
+++ b/browser/base/content/test/trackingUI/browser.ini
@@ -10,16 +10,17 @@ support-files =
   embeddedPage.html
   trackingAPI.js
   trackingPage.html
 
 [browser_trackingUI_3.js]
 [browser_trackingUI_animation.js]
 [browser_trackingUI_animation_2.js]
 [browser_trackingUI_appMenu.js]
+[browser_trackingUI_background_tabs.js]
 [browser_trackingUI_categories.js]
 [browser_trackingUI_cookies_subview.js]
 [browser_trackingUI_cryptominers.js]
 [browser_trackingUI_fetch.js]
 support-files =
   file_trackingUI_fetch.html
   file_trackingUI_fetch.js
   file_trackingUI_fetch.js^headers^
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_background_tabs.js
@@ -0,0 +1,55 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
+const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
+
+const TP_PREF = "privacy.trackingprotection.enabled";
+
+add_task(async function testBackgroundTabs() {
+  info("Testing receiving and storing content blocking events in non-selected tabs.");
+
+  await SpecialPowers.pushPrefEnv({set: [
+    [ContentBlocking.prefIntroCount, ContentBlocking.MAX_INTROS],
+    [TP_PREF, true],
+  ]});
+  await UrlClassifierTestUtils.addTestTrackers();
+
+  registerCleanupFunction(() => {
+    UrlClassifierTestUtils.cleanupTestTrackers();
+  });
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, BENIGN_PAGE);
+
+  let backgroundTab = BrowserTestUtils.addTab(gBrowser);
+  let browser = backgroundTab.linkedBrowser;
+  let hasContentBlockingEvent = TestUtils.waitForCondition(() =>
+    browser.securityUI.contentBlockingEvent != 0);
+  await promiseTabLoadEvent(backgroundTab, TRACKING_PAGE);
+  await hasContentBlockingEvent;
+
+  is(browser.securityUI.contentBlockingEvent,
+     Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT,
+     "Background tab has the correct content blocking event.");
+
+  is(tab.linkedBrowser.securityUI.contentBlockingEvent, 0,
+     "Foreground tab has the correct content blocking event.");
+
+  ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
+
+  await BrowserTestUtils.switchTab(gBrowser, backgroundTab);
+
+  is(browser.securityUI.contentBlockingEvent,
+     Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT,
+     "Background tab still has the correct content blocking event.");
+
+  is(tab.linkedBrowser.securityUI.contentBlockingEvent, 0,
+     "Foreground tab still has the correct content blocking event.");
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
+
+  gBrowser.removeTab(backgroundTab);
+  gBrowser.removeTab(tab);
+});