Bug 1348803 - part1 : move fennec-only code to android/browser.js.
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
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3646,19 +3646,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)
}],
@@ -3761,19 +3761,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;
@@ -4594,16 +4594,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;
}
@@ -4656,27 +4671,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);
}
},