Bug 1508944 - Avoid dispatching the OnSecurityChange notification repeatedly when nothing has changed r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 23 Nov 2018 18:07:46 +0000
changeset 504308 8ab07484e939f28ef182671a0cac6e444efa06bf
parent 504307 0fb9b230634c1bed2090b8f899861d59aa1b4f13
child 504309 306f3bd4760aa5224173f6b6d9c138a4f856384f
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1508944
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 1508944 - Avoid dispatching the OnSecurityChange notification repeatedly when nothing has changed r=baku Differential Revision: https://phabricator.services.mozilla.com/D12601
browser/base/content/test/trackingUI/browser_trackingUI_animation_2.js
browser/base/content/test/trackingUI/browser_trackingUI_trackers_subview.js
dom/base/nsGlobalWindowOuter.cpp
--- a/browser/base/content/test/trackingUI/browser_trackingUI_animation_2.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_animation_2.js
@@ -1,8 +1,9 @@
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
 /*
  * Test that the Content Blocking icon is properly animated in the identity
  * block when loading tabs and switching between tabs.
  * See also Bug 1175858.
  */
 
 const TP_PREF = "privacy.trackingprotection.enabled";
 const TP_PB_PREF = "privacy.trackingprotection.enabled";
@@ -25,17 +26,17 @@ function waitForSecurityChange(tabbrowse
   return new Promise(resolve => {
     let n = 0;
     let listener = {
       onSecurityChange() {
         n = n + 1;
         info("Received onSecurityChange event " + n + " of " + numChanges);
         if (n >= numChanges) {
           tabbrowser.removeProgressListener(listener);
-          resolve();
+          resolve(n);
         }
       },
     };
     tabbrowser.addProgressListener(listener);
   });
 }
 
 async function testTrackingProtectionAnimation(tabbrowser) {
@@ -80,76 +81,84 @@ async function testTrackingProtectionAni
   securityChanged = waitForSecurityChange(tabbrowser);
   tabbrowser.selectedTab = trackingCookiesTab;
   await securityChanged;
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   info("Reload tracking cookies tab");
-  securityChanged = waitForSecurityChange(tabbrowser, 4);
+  securityChanged = waitForSecurityChange(tabbrowser, 3);
   tabbrowser.reload();
   await securityChanged;
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(ContentBlocking.iconBox.hasAttribute("animate"), "iconBox animating");
   await BrowserTestUtils.waitForEvent(ContentBlocking.animatedIcon, "animationend");
 
   info("Reload tracking tab");
-  securityChanged = waitForSecurityChange(tabbrowser, 5);
+  securityChanged = waitForSecurityChange(tabbrowser, 4);
   tabbrowser.selectedTab = trackingTab;
   tabbrowser.reload();
   await securityChanged;
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(ContentBlocking.iconBox.hasAttribute("animate"), "iconBox animating");
   await BrowserTestUtils.waitForEvent(ContentBlocking.animatedIcon, "animationend");
 
   info("Inject tracking cookie inside tracking tab");
-  securityChanged = waitForSecurityChange(tabbrowser, 2);
+  securityChanged = waitForSecurityChange(tabbrowser);
+  let timeoutPromise = new Promise(resolve => setTimeout(resolve, 500));
   await ContentTask.spawn(tabbrowser.selectedBrowser, {},
                           function() {
     content.postMessage("cookie", "*");
   });
-  await securityChanged;
+  let result = await Promise.race([securityChanged, timeoutPromise]);
+  is(result, undefined, "No securityChange events should be received");
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   info("Inject tracking element inside tracking tab");
   securityChanged = waitForSecurityChange(tabbrowser);
+  timeoutPromise = new Promise(resolve => setTimeout(resolve, 500));
   await ContentTask.spawn(tabbrowser.selectedBrowser, {},
                           function() {
     content.postMessage("tracking", "*");
   });
-  await securityChanged;
+  result = await Promise.race([securityChanged, timeoutPromise]);
+  is(result, undefined, "No securityChange events should be received");
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   tabbrowser.selectedTab = trackingCookiesTab;
 
   info("Inject tracking cookie inside tracking cookies tab");
-  securityChanged = waitForSecurityChange(tabbrowser, 2);
+  securityChanged = waitForSecurityChange(tabbrowser);
+  timeoutPromise = new Promise(resolve => setTimeout(resolve, 500));
   await ContentTask.spawn(tabbrowser.selectedBrowser, {},
                           function() {
     content.postMessage("cookie", "*");
   });
-  await securityChanged;
+  result = await Promise.race([securityChanged, timeoutPromise]);
+  is(result, undefined, "No securityChange events should be received");
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   info("Inject tracking element inside tracking cookies tab");
-  securityChanged = waitForSecurityChange(tabbrowser, 2);
+  securityChanged = waitForSecurityChange(tabbrowser);
+  timeoutPromise = new Promise(resolve => setTimeout(resolve, 500));
   await ContentTask.spawn(tabbrowser.selectedBrowser, {},
                           function() {
     content.postMessage("tracking", "*");
   });
-  await securityChanged;
+  result = await Promise.race([securityChanged, timeoutPromise]);
+  is(result, undefined, "No securityChange events should be received");
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   while (tabbrowser.tabs.length > 1) {
     tabbrowser.removeCurrentTab();
   }
 }
--- a/browser/base/content/test/trackingUI/browser_trackingUI_trackers_subview.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_trackers_subview.js
@@ -1,8 +1,9 @@
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
 /* 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 TP_PREF = "privacy.trackingprotection.enabled";
@@ -22,17 +23,17 @@ function waitForSecurityChange(counter) 
   return new Promise(resolve => {
     let webProgressListener = {
       onStateChange: () => {},
       onStatusChange: () => {},
       onLocationChange: () => {},
       onSecurityChange: (webProgress, request, oldState, state) => {
         if (--counter == 0) {
           gBrowser.removeProgressListener(webProgressListener);
-          resolve();
+          resolve(counter);
         }
       },
       onProgressChange: () => {},
       QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener]),
     };
 
     gBrowser.addProgressListener(webProgressListener);
   });
@@ -62,23 +63,25 @@ async function assertSitesListed(blocked
     let mainView = document.getElementById("identity-popup-mainView");
     viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
     let backButton = trackersView.querySelector(".subviewbutton-back");
     backButton.click();
     await viewShown;
 
     ok(true, "Main view was shown");
 
-    let change = waitForSecurityChange(2);
+    let change = waitForSecurityChange(1);
+    let timeoutPromise = new Promise(resolve => setTimeout(resolve, 1000));
 
     await ContentTask.spawn(browser, {}, function() {
       content.postMessage("more-tracking", "*");
     });
 
-    await change;
+    let result = await Promise.race([change, timeoutPromise]);
+    is(result, undefined, "No securityChange events should be received");
 
     viewShown = BrowserTestUtils.waitForEvent(trackersView, "ViewShown");
     categoryItem.click();
     await viewShown;
 
     ok(true, "Trackers view was shown");
 
     listItems = Array.from(document.querySelectorAll(".identity-popup-trackersView-list-item"));
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -5389,16 +5389,21 @@ nsGlobalWindowOuter::NotifyContentBlocki
   }
   const uint32_t oldState = state;
   if (aBlocked) {
     state |= aState;
   } else if (unblocked) {
     state &= ~aState;
   }
 
+  if (state == oldState) {
+    // Avoid dispatching repeated notifications when nothing has changed
+    return;
+  }
+
   eventSink->OnSecurityChange(aChannel, oldState, state, doc->GetContentBlockingLog());
 }
 
 //static
 bool
 nsGlobalWindowOuter::SameLoadingURI(nsIDocument *aDoc, nsIChannel *aChannel)
 {
   nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();