Bug 1347791 - part4 : keep tab's block state consistent after session restore. r=mikedeboer
☠☠ backed out by db2fabb21b82 ☠ ☠
authorAlastor Wu <alwu@mozilla.com>
Wed, 17 May 2017 11:56:10 +0800
changeset 358737 888dc371081aad0695694e283106b5d2d00f2302
parent 358736 37d295d7eec9d32ca4ef4f5d1e49ea7af52ea4b8
child 358738 6175b270de8d2189846263ec5acca331f27f397d
push id90373
push usercbook@mozilla.com
push dateWed, 17 May 2017 10:28:10 +0000
treeherdermozilla-inbound@89f59c12ff7f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1347791
milestone55.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 1347791 - part4 : keep tab's block state consistent after session restore. r=mikedeboer If the tab was resumed before, it could start playing any autoplay media without user's permission after session restore. MozReview-Commit-ID: C3DHIIsLtJA
browser/base/content/tabbrowser.xml
browser/components/sessionstore/SessionStore.jsm
browser/components/sessionstore/TabAttributes.jsm
browser/components/sessionstore/TabState.jsm
browser/components/sessionstore/test/browser_attributes.js
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2064,17 +2064,17 @@
         "goHome", "homePage", "gotoIndex", "currentURI", "documentURI",
         "preferences", "imageDocument", "isRemoteBrowser", "messageManager",
         "getTabBrowser", "finder", "fastFind", "sessionHistory", "contentTitle",
         "characterSet", "fullZoom", "textZoom", "webProgress",
         "addProgressListener", "removeProgressListener", "audioPlaybackStarted",
         "audioPlaybackStopped", "pauseMedia", "stopMedia",
         "blockMedia", "resumeMedia", "mute", "unmute", "blockedPopups", "lastURI",
         "purgeSessionHistory", "stopScroll", "startScroll",
-        "userTypedValue", "userTypedClear"
+        "userTypedValue", "userTypedClear", "mediaBlocked"
       ]</field>
 
       <method name="_createLazyBrowser">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             let browser = aTab.linkedBrowser;
 
@@ -2117,29 +2117,32 @@
                   getter = () => {
                     return () => {
                       return { permitUnload: true, timedOut: false };
                     };
                   };
                   break;
                 case "reload":
                 case "reloadWithFlags":
+                case "blockMedia":
+                case "resumeMedia":
                   getter = () => {
                     return (params) => {
                       // Wait for load handler to be instantiated before
                       // initializing the reload.
                       aTab.addEventListener("SSTabRestoring", () => {
                         browser[name](params);
                       }, { once: true });
                       gBrowser._insertBrowser(aTab);
                     };
                   };
                   break;
                 case "userTypedValue":
                 case "userTypedClear":
+                case "mediaBlocked":
                   getter = () => {
                     return SessionStore.getLazyTabValue(aTab, name);
                   };
                   break;
                 default:
                   getter = () => {
                     if (AppConstants.NIGHTLY_BUILD) {
                       let message =
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -3583,16 +3583,18 @@ var SessionStoreInternal = {
     } else {
       tabbrowser.showTab(tab);
     }
 
     if (!!tabData.muted != browser.audioMuted) {
       tab.toggleMuteAudio(tabData.muteReason);
     }
 
+    tab.setMediaBlock(!!tabData.mediaBlocked);
+
     if (tabData.lastAccessed) {
       tab.updateLastAccessed(tabData.lastAccessed);
     }
 
     if ("attributes" in tabData) {
       // Ensure that we persist tab attributes restored from previous sessions.
       Object.keys(tabData.attributes).forEach(a => TabAttributes.persist(a));
     }
--- a/browser/components/sessionstore/TabAttributes.jsm
+++ b/browser/components/sessionstore/TabAttributes.jsm
@@ -9,18 +9,20 @@ this.EXPORTED_SYMBOLS = ["TabAttributes"
 // We never want to directly read or write these attributes.
 // 'image' should not be accessed directly but handled by using the
 //         gBrowser.getIcon()/setIcon() methods.
 // 'muted' should not be accessed directly but handled by using the
 //         tab.linkedBrowser.audioMuted/toggleMuteAudio methods.
 // 'pending' is used internal by sessionstore and managed accordingly.
 // 'iconLoadingPrincipal' is same as 'image' that it should be handled by
 //                        using the gBrowser.getIcon()/setIcon() methods.
+// 'mediaBlocked' should not be accessed directly but handled by using the
+//                tab.linkedBrowser.mediaBlocked, setMediaBlock methods.
 const ATTRIBUTES_TO_SKIP = new Set(["image", "muted", "pending", "iconLoadingPrincipal",
-                                    "skipbackgroundnotify"]);
+                                    "skipbackgroundnotify", "mediaBlocked"]);
 
 // A set of tab attributes to persist. We will read a given list of tab
 // attributes when collecting tab data and will re-set those attributes when
 // the given tab data is restored to a new tab.
 this.TabAttributes = Object.freeze({
   persist(name) {
     return TabAttributesInternal.persist(name);
   },
--- a/browser/components/sessionstore/TabState.jsm
+++ b/browser/components/sessionstore/TabState.jsm
@@ -97,16 +97,18 @@ var TabStateInternal = {
 
     tabData.hidden = tab.hidden;
 
     if (browser.audioMuted) {
       tabData.muted = true;
       tabData.muteReason = tab.muteReason;
     }
 
+    tabData.mediaBlocked = browser.mediaBlocked;
+
     // Save tab attributes.
     tabData.attributes = TabAttributes.get(tab);
 
     if (tab.__SS_extdata) {
       tabData.extData = tab.__SS_extdata;
     }
 
     // Copy data from the tab state cache only if the tab has fully finished
--- a/browser/components/sessionstore/test/browser_attributes.js
+++ b/browser/components/sessionstore/test/browser_attributes.js
@@ -20,25 +20,31 @@ add_task(async function test() {
   // Check that the tab has 'image' and 'iconLoadingPrincipal' attributes.
   ok(tab.hasAttribute("image"), "tab.image exists");
   ok(tab.hasAttribute("iconLoadingPrincipal"), "tab.iconLoadingPrincipal exists");
 
   tab.toggleMuteAudio();
   // Check that the tab has a 'muted' attribute.
   ok(tab.hasAttribute("muted"), "tab.muted exists");
 
+  tab.setMediaBlock(true /* block */);
+  // Check that the tab has a 'media-blocked' attribute.
+  ok(tab.hasAttribute("media-blocked"), "tab.media-blocked exists");
+
   // Make sure we do not persist 'image' or 'muted' attributes.
   ss.persistTabAttribute("image");
   ss.persistTabAttribute("muted");
   ss.persistTabAttribute("iconLoadingPrincipal");
+  ss.persistTabAttribute("mediaBlocked");
   let {attributes} = JSON.parse(ss.getTabState(tab));
   ok(!("image" in attributes), "'image' attribute not saved");
   ok(!("iconLoadingPrincipal" in attributes), "'iconLoadingPrincipal' attribute not saved");
   ok(!("muted" in attributes), "'muted' attribute not saved");
   ok(!("custom" in attributes), "'custom' attribute not saved");
+  ok(!("mediaBlocked" in attributes), "'mediaBlocked' attribute not saved");
 
   // Test persisting a custom attribute.
   tab.setAttribute("custom", "foobar");
   ss.persistTabAttribute("custom");
 
   ({attributes} = JSON.parse(ss.getTabState(tab)));
   is(attributes.custom, "foobar", "'custom' attribute is correct");