Bug 1190106 - Preserve the playing and muted icons when swapping browsers; r=jaws
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 01 Aug 2015 18:10:29 -0400
changeset 287833 4a9d48b58545fa05fc488f3e5c163af2725cbca3
parent 287832 2c75751cea070d66f6eab5f86c125c971b26725f
child 287834 081d48ca7e97320a209ed4af829b85a0caa8d76b
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1190106
milestone42.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 1190106 - Preserve the playing and muted icons when swapping browsers; r=jaws
browser/base/content/tabbrowser.xml
browser/base/content/test/general/browser_audioTabIcon.js
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2445,16 +2445,26 @@
             var isPending = aOtherTab.hasAttribute("pending");
 
             // First, start teardown of the other browser.  Make sure to not
             // fire the beforeunload event in the process.  Close the other
             // window if this was its last tab.
             if (!remoteBrowser._beginRemoveTab(aOtherTab, true, true))
               return;
 
+            let modifiedAttrs = [];
+            if (aOtherTab.hasAttribute("muted")) {
+              aOurTab.setAttribute("muted", "true");
+              modifiedAttrs.push("muted");
+            }
+            if (aOtherTab.hasAttribute("soundplaying")) {
+              aOurTab.setAttribute("soundplaying", "true");
+              modifiedAttrs.push("soundplaying");
+            }
+
             let ourBrowser = this.getBrowserForTab(aOurTab);
             let otherBrowser = aOtherTab.linkedBrowser;
 
             // If the other tab is pending (i.e. has not been restored, yet)
             // then do not switch docShells but retrieve the other tab's state
             // and apply it to our tab.
             if (isPending) {
               SessionStore.setTabState(aOurTab, SessionStore.getTabState(aOtherTab));
@@ -2464,17 +2474,17 @@
             } else {
               // Workarounds for bug 458697
               // Icon might have been set on DOMLinkAdded, don't override that.
               if (!ourBrowser.mIconURL && otherBrowser.mIconURL)
                 this.setIcon(aOurTab, otherBrowser.mIconURL);
               var isBusy = aOtherTab.hasAttribute("busy");
               if (isBusy) {
                 aOurTab.setAttribute("busy", "true");
-                this._tabAttrModified(aOurTab, ["busy"]);
+                modifiedAttrs.push("busy");
                 if (aOurTab.selected)
                   this.mIsBusy = true;
               }
 
               this._swapBrowserDocShells(aOurTab, otherBrowser);
             }
 
             // Handle findbar data (if any)
@@ -2494,16 +2504,20 @@
               this.setTabTitleLoading(aOurTab);
             else
               this.setTabTitle(aOurTab);
 
             // If the tab was already selected (this happpens in the scenario
             // of replaceTabWithWindow), notify onLocationChange, etc.
             if (aOurTab.selected)
               this.updateCurrentBrowser(true);
+
+            if (modifiedAttrs.length) {
+              this._tabAttrModified(aOurTab, modifiedAttrs);
+            }
           ]]>
         </body>
       </method>
 
       <method name="_swapBrowserDocShells">
         <parameter name="aOurTab"/>
         <parameter name="aOtherBrowser"/>
         <body>
--- a/browser/base/content/test/general/browser_audioTabIcon.js
+++ b/browser/base/content/test/general/browser_audioTabIcon.js
@@ -101,16 +101,69 @@ function* test_playing_icon_on_tab(tab, 
   yield test_tooltip(icon, "This tab has been muted");
 
   yield test_mute_tab(tab, icon, false);
 
   ok(!tab.hasAttribute("muted") &&
      !tab.hasAttribute("soundplaying"), "Tab should not be be muted or playing");
 }
 
+function* test_swapped_browser(oldTab, newBrowser, isPlaying) {
+  ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab");
+  is(oldTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the old tab");
+
+  let newTab = gBrowser.getTabForBrowser(newBrowser);
+  let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => {
+    return (event.detail.changed.indexOf("soundplaying") >= 0 || !isPlaying) &&
+           event.detail.changed.indexOf("muted") >= 0;
+  });
+
+  gBrowser.swapBrowsersAndCloseOther(newTab, oldTab);
+  yield AttrChangePromise;
+
+  ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
+  is(newTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the new tab");
+}
+
+function* test_browser_swapping(tab, browser) {
+  // First, test swapping with a playing but muted tab.
+  yield ContentTask.spawn(browser, {}, function* () {
+    let audio = content.document.querySelector("audio");
+    audio.play();
+  });
+  yield wait_for_tab_playing_event(tab, true);
+
+  let icon = document.getAnonymousElementByAttribute(tab, "anonid",
+                                                     "soundplaying-icon");
+  yield test_mute_tab(tab, icon, true);
+
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: "about:blank",
+  }, function*(newBrowser) {
+    yield test_swapped_browser(tab, newBrowser, true)
+
+    // FIXME: this is needed to work around bug 1190903.
+    yield new Promise(resolve => setTimeout(resolve, 1000));
+
+    // Now, test swapping with a muted but not playing tab.
+    // Note that the tab remains muted, so we only need to pause playback.
+    tab = gBrowser.getTabForBrowser(newBrowser);
+    yield ContentTask.spawn(newBrowser, {}, function* () {
+      let audio = content.document.querySelector("audio");
+      audio.pause();
+    });
+
+    yield BrowserTestUtils.withNewTab({
+      gBrowser,
+      url: "about:blank",
+    }, newBrowser => test_swapped_browser(tab, newBrowser, false));
+  });
+}
+
 function* test_on_browser(browser) {
   let tab = gBrowser.getTabForBrowser(browser);
 
   // Test the icon in a normal tab.
   yield test_playing_icon_on_tab(tab, browser, false);
 
   gBrowser.pinTab(tab);
 
@@ -120,16 +173,18 @@ function* test_on_browser(browser) {
   gBrowser.unpinTab(tab);
 
   // Retest with another browser in the foreground tab
   if (gBrowser.selectedBrowser.currentURI.spec == PAGE) {
     yield BrowserTestUtils.withNewTab({
       gBrowser,
       url: "data:text/html,test"
     }, () => test_on_browser(browser));
+  } else {
+    yield test_browser_swapping(tab, browser);
   }
 }
 
 add_task(function*() {
   yield new Promise((resolve) => {
     SpecialPowers.pushPrefEnv({"set": [
                                 ["media.useAudioChannelService", true],
                                 ["browser.tabs.showAudioPlayingIcon", true],