Bug 1522058 - Fix race in clearing global permissions. r=johannh a=lizzard
authorDale Harvey <dale@arandomurl.com>
Thu, 28 Feb 2019 22:03:48 +0000
changeset 516229 7e003748ec6260407407f96076f892ad20ad07cf
parent 516228 02370e541eb933f3798c3c6fe22be8cc89cf9476
child 516230 d380e82c33fb1a719acecd1df968aea3b63c7de1
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh, lizzard
bugs1522058
milestone66.0
Bug 1522058 - Fix race in clearing global permissions. r=johannh a=lizzard 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");
 }
 
@@ -113,8 +118,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.