Bug 1348803 - part1 : move fennec-only code to android/browser.js. r=sebastian
authorAlastor Wu <alwu@mozilla.com>
Tue, 18 Apr 2017 11:03:49 +0800
changeset 353532 e8be047fc5c9b8b0711563f3495620467a896ceb
parent 353531 a28aa86d1ffe2b60267607abe0e69847f2679c17
child 353533 af746f31572fe889ea1f0725657cc837ed9d5221
push id40943
push useralwu@mozilla.com
push dateTue, 18 Apr 2017 06:29:37 +0000
treeherderautoland@af746f31572f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian
bugs1348803
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 1348803 - part1 : move fennec-only code to android/browser.js. r=sebastian We could register media control related event after the tab has active media. But we still need to register "audioFocusChange" in the beginning, because it affect every tab even the tab has no active media. MozReview-Commit-ID: ErIBUobnxbg
mobile/android/chrome/content/browser.js
toolkit/content/browser-content.js
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3638,19 +3638,19 @@ Tab.prototype = {
     this.browser.addEventListener("TabPreZombify", this, true);
     this.browser.addEventListener("DOMWindowFocus", this, true);
 
     // Note that the XBL binding is untrusted
     this.browser.addEventListener("PluginBindingAttached", this, true, true);
     this.browser.addEventListener("VideoBindingAttached", this, true, true);
     this.browser.addEventListener("VideoBindingCast", this, true, true);
 
+    Services.obs.addObserver(this, "AudioFocusChanged", false);
     Services.obs.addObserver(this, "before-first-paint");
     Services.obs.addObserver(this, "media-playback");
-    Services.obs.addObserver(this, "media-playback-resumed");
 
     // Always initialise new tabs with basic session store data to avoid
     // problems with functions that always expect it to be present
     this.browser.__SS_data = {
       entries: [{
         url: aURL,
         title: truncate(title, MAX_TITLE_LENGTH)
       }],
@@ -3753,19 +3753,19 @@ Tab.prototype = {
     this.browser.removeEventListener("MozApplicationManifest", this, true);
     this.browser.removeEventListener("TabPreZombify", this, true);
     this.browser.removeEventListener("DOMWindowFocus", this, true);
 
     this.browser.removeEventListener("PluginBindingAttached", this, true, true);
     this.browser.removeEventListener("VideoBindingAttached", this, true, true);
     this.browser.removeEventListener("VideoBindingCast", this, true, true);
 
+    Services.obs.removeObserver(this, "AudioFocusChanged");
     Services.obs.removeObserver(this, "before-first-paint");
     Services.obs.removeObserver(this, "media-playback");
-    Services.obs.removeObserver(this, "media-playback-resumed");
 
     // Make sure the previously selected panel remains selected. The selected panel of a deck is
     // not stable when panels are removed.
     let selectedPanel = BrowserApp.deck.selectedPanel;
     BrowserApp.deck.removeChild(this.browser);
     BrowserApp.deck.selectedPanel = selectedPanel;
 
     this.browser = null;
@@ -4586,16 +4586,31 @@ Tab.prototype = {
     Services.obs.notifyObservers(this.browser, "Content:HistoryChange");
     return true;
   },
 
   OnHistoryReplaceEntry: function(index) {
     Services.obs.notifyObservers(this.browser, "Content:HistoryChange");
   },
 
+  UpdateMediaPlaybackRelatedObserver: function(active) {
+    // Media control is only used for the tab which has playing media, so we
+    // only need to register observer after having the active media. And the
+    // "media-playback-resumed" is sent when user resume paused media from
+    // page, it notifies us that we should change the icon and content in media
+    // control interface.
+    if (active) {
+      Services.obs.addObserver(this, "MediaControl", false);
+      Services.obs.addObserver(this, "media-playback-resumed", false);
+    } else {
+      Services.obs.removeObserver(this, "MediaControl");
+      Services.obs.removeObserver(this, "media-playback-resumed");
+    }
+  },
+
   ShouldNotifyMediaPlaybackChange: function(activeState) {
     // If the media is active, we would check it's duration, because we don't
     // want to show the media control interface for the short sound which
     // duration is smaller than the threshold. The basic unit is second.
     // Note : the streaming format's duration is infinite.
     if (activeState === "inactive") {
       return true;
     }
@@ -4648,27 +4663,59 @@ Tab.prototype = {
         }
 
         if (!this.ShouldNotifyMediaPlaybackChange(aData)) {
           return;
         }
 
         let status;
         if (aTopic == "media-playback") {
-          status = (aData === "inactive") ? "end" : "start";
+          let isActive = !(aData === "inactive");
+          status = isActive ? "start" : "end";
+          this.UpdateMediaPlaybackRelatedObserver(isActive);
         } else if (aTopic == "media-playback-resumed") {
           status = "resume";
         }
 
         GlobalEventDispatcher.sendRequest({
           type: "Tab:MediaPlaybackChange",
           tabID: this.id,
           status: status
         });
         break;
+
+      case "AudioFocusChanged":
+      case "MediaControl":
+        let win = this.browser.contentWindow;
+        let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+        let suspendTypes = Ci.nsISuspendedTypes;
+        switch (aData) {
+          case "lostAudioFocus":
+            utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE_DISPOSABLE;
+            break;
+          case "lostAudioFocusTransiently":
+            utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE;
+            break;
+          case "gainAudioFocus":
+            utils.mediaSuspend = suspendTypes.NONE_SUSPENDED;
+            break;
+          case "mediaControlPaused":
+            utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE_DISPOSABLE;
+            break;
+          case "mediaControlStopped":
+            utils.mediaSuspend = suspendTypes.SUSPENDED_STOP_DISPOSABLE;
+            break;
+          case "resumeMedia":
+            utils.mediaSuspend = suspendTypes.NONE_SUSPENDED;
+            break;
+          default:
+            dump("Error : wrong media control msg!\n");
+            break;
+        }
+        break;
     }
   },
 
   // nsIBrowserTab
   get window() {
     if (!this.browser)
       return null;
     return this.browser.contentWindow;
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -966,29 +966,25 @@ addMessageListener("WebChannelMessageToC
   }
 });
 
 var AudioPlaybackListener = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
 
   init() {
     Services.obs.addObserver(this, "audio-playback");
-    Services.obs.addObserver(this, "AudioFocusChanged");
-    Services.obs.addObserver(this, "MediaControl");
 
     addMessageListener("AudioPlayback", this);
     addEventListener("unload", () => {
       AudioPlaybackListener.uninit();
     });
   },
 
   uninit() {
     Services.obs.removeObserver(this, "audio-playback");
-    Services.obs.removeObserver(this, "AudioFocusChanged");
-    Services.obs.removeObserver(this, "MediaControl");
 
     removeMessageListener("AudioPlayback", this);
   },
 
   handleMediaControlMessage(msg) {
     let utils = global.content.QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsIDOMWindowUtils);
     let suspendTypes = Ci.nsISuspendedTypes;
@@ -1034,18 +1030,16 @@ var AudioPlaybackListener = {
           name += "BlockStart";
         } else if (data === "blockStop") {
           name += "BlockStop";
         } else {
           name += (data === "active") ? "Start" : "Stop";
         }
         sendAsyncMessage(name);
       }
-    } else if (topic == "AudioFocusChanged" || topic == "MediaControl") {
-      this.handleMediaControlMessage(data);
     }
   },
 
   receiveMessage(msg) {
     if (msg.name == "AudioPlayback") {
       this.handleMediaControlMessage(msg.data.type);
     }
   },