Bug 1533362 - Record contentBlockingEvent for background tabs. r=Ehsan
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 15 Mar 2019 17:37:26 +0000
changeset 522081 f6a8502a80bfdab610ea7343c6e7d21fb7e17da0
parent 522080 8937817294094795018b3bb908fb78b4fa9416aa
child 522082 0b05d8817659edbbccb23a92be96105c2a0805c9
push id10871
push usercbrindusan@mozilla.com
push dateMon, 18 Mar 2019 15:49:32 +0000
treeherdermozilla-beta@018abdd16060 [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);
+});