Bug 1522058 - Fix race in clearing global permissions. r=johannh
authorDale Harvey <dale@arandomurl.com>
Thu, 28 Feb 2019 22:03:48 +0000
changeset 519707 10ff993159a1bcb71db63f83dece4d063ab4ef20
parent 519706 13511123a2c851b6f92d4e6fef71f8137ddfeb8d
child 519708 e1b938568978bc8912e269a924074bb54737c348
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1522058
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 1522058 - Fix race in clearing global permissions. r=johannh Differential Revision: https://phabricator.services.mozilla.com/D21381
browser/base/content/test/permissions/browser_autoplay_blocked.js
browser/modules/SitePermissions.jsm
--- a/browser/base/content/test/permissions/browser_autoplay_blocked.js
+++ b/browser/base/content/test/permissions/browser_autoplay_blocked.js
@@ -19,16 +19,21 @@ function closeIdentityPopup() {
   return promise;
 }
 
 function autoplayBlockedIcon() {
   return document.querySelector("#blocked-permissions-container " +
                                 ".blocked-permission-icon.autoplay-media-icon");
 }
 
+function sleep(ms) {
+  /* eslint-disable mozilla/no-arbitrary-setTimeout */
+  return new Promise(resolve => setTimeout(resolve, ms));
+}
+
 async function blockedIconShown(browser) {
   // May need to wait for `GloballyAutoplayBlocked` event before showing icon.
   if (BrowserTestUtils.is_hidden(autoplayBlockedIcon())) {
     await BrowserTestUtils.waitForEvent(browser, "GloballyAutoplayBlocked");
   }
   ok(!BrowserTestUtils.is_hidden(autoplayBlockedIcon()), "Blocked icon is shown");
 }
 
@@ -112,8 +117,34 @@ add_task(async function testGloballyBloc
   Assert.deepEqual(SitePermissions.get(uri, AUTOPLAY_PERM, tab.linkedBrowser), {
     state: SitePermissions.BLOCK,
     scope: SitePermissions.SCOPE_PERSISTENT,
   });
 
   SitePermissions.remove(uri, AUTOPLAY_PERM, tab.linkedBrowser);
   await BrowserTestUtils.closeWindow(win);
 });
+
+add_task(async function testBFCache() {
+  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
+
+  await BrowserTestUtils.withNewTab("about:home", async function(browser) {
+    await BrowserTestUtils.loadURI(browser, AUTOPLAY_PAGE);
+    await blockedIconShown(browser);
+    Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.ALLOWED);
+
+    gBrowser.goBack();
+    await TestUtils.waitForCondition(() => {
+      return BrowserTestUtils.is_hidden(autoplayBlockedIcon());
+    });
+
+    gBrowser.goForward();
+
+    // Sleep here to prevent false positives, the icon gets shown with an
+    // async `GloballyAutoplayBlocked` event. The sleep gives it a little
+    // time for it to show otherwise there is a chance it passes before it
+    // would have shown.
+    await sleep(100);
+    ok(BrowserTestUtils.is_hidden(autoplayBlockedIcon()), "Blocked icon is hidden");
+  });
+
+  Services.perms.removeAll();
+});
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -152,27 +152,29 @@ const GloballyBlockedPermissions = {
 
     // Listen to any top level navigations, once we see one clear the flag
     // and remove the listener.
     browser.addProgressListener({
       QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
                                               Ci.nsISupportsWeakReference]),
       onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
         if (aWebProgress.isTopLevel) {
-          GloballyBlockedPermissions.remove(browser, id);
+          GloballyBlockedPermissions.remove(browser, id, prePath);
           browser.removeProgressListener(this);
         }
       },
     });
   },
 
   // Removes a permission with the specified id for the specified browser.
-  remove(browser, id) {
+  remove(browser, id, prePath = null) {
     let entry = this._stateByBrowser.get(browser);
-    let prePath = browser.currentURI.prePath;
+    if (!prePath) {
+      prePath = browser.currentURI.prePath;
+    }
     if (entry && entry[prePath]) {
       delete entry[prePath][id];
     }
   },
 
   // Gets all permissions for the specified browser.
   // Note that only permissions that apply to the current URI
   // of the passed browser element will be returned.