Bug 1249579 - part2 : audio competing suspend/resume methods. r=snorp, baku.

MozReview-Commit-ID: EjNvKELCiAy

--HG--
extra : transplant_source : %AE%20%21e%E1%94%DE%29B%9C%F5%04%13%C6%3Dr%D3%9Aj%B4
This commit is contained in:
Alastor Wu 2016-04-18 18:48:41 +08:00
parent 0d34b81b5a
commit b5361feb4b
7 changed files with 82 additions and 2 deletions

View File

@ -384,7 +384,8 @@ AudioChannelService::GetState(nsPIDOMWindowOuter* aWindow, uint32_t aAudioChanne
}
*aVolume *= window->GetAudioVolume();
*aMuted = *aMuted || window->GetAudioMuted();
// TODO : distiguish between suspend and mute, it would be done in bug1242874.
*aMuted = *aMuted || window->GetMediaSuspended() || window->GetAudioMuted();
nsCOMPtr<nsPIDOMWindowOuter> win = window->GetScriptableParent();
if (window == win) {

View File

@ -3679,6 +3679,26 @@ nsDOMWindowUtils::PostRestyleSelfEvent(nsIDOMElement* aElement)
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetMediaSuspended(bool* aSuspended)
{
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
*aSuspended = window->GetMediaSuspended();
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetMediaSuspended(bool aSuspended)
{
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
window->SetMediaSuspended(aSuspended);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetAudioMuted(bool* aMuted)
{

View File

@ -614,7 +614,7 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
mMayHavePointerEnterLeaveEventListener(false),
mInnerObjectsFreed(false),
mIsModalContentWindow(false),
mIsActive(false), mIsBackground(false),
mIsActive(false), mIsBackground(false), mMediaSuspended(false),
mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
mDesktopModeViewport(false), mInnerWindow(nullptr),
mOuterWindow(aOuterWindow),
@ -3673,6 +3673,32 @@ nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded()
}
}
bool
nsPIDOMWindowOuter::GetMediaSuspended() const
{
if (IsInnerWindow()) {
return mOuterWindow->GetMediaSuspended();
}
return mMediaSuspended;
}
void
nsPIDOMWindowOuter::SetMediaSuspended(bool aSuspended)
{
if (IsInnerWindow()) {
mOuterWindow->SetMediaSuspended(aSuspended);
return;
}
if (mMediaSuspended == aSuspended) {
return;
}
mMediaSuspended = aSuspended;
RefreshMediaElements();
}
bool
nsPIDOMWindowOuter::GetAudioMuted() const
{

View File

@ -649,6 +649,7 @@ protected:
// "active". Only used on outer windows.
bool mIsBackground;
bool mMediaSuspended;
bool mAudioMuted;
float mAudioVolume;
@ -855,6 +856,9 @@ public:
}
// Audio API
bool GetMediaSuspended() const;
void SetMediaSuspended(bool aSuspended);
bool GetAudioMuted() const;
void SetAudioMuted(bool aMuted);

View File

@ -1750,6 +1750,12 @@ interface nsIDOMWindowUtils : nsISupports {
*/
void postRestyleSelfEvent(in nsIDOMElement aElement);
/**
* Used to pause or resume all MediaElements in this window. Use-cases are
* audio competing and remote media control.
*/
attribute boolean mediaSuspended;
/**
* With this it's possible to mute all the MediaElements in this window.
* We have audioMuted and audioVolume to preserve the volume across

View File

@ -985,3 +985,7 @@ pref("identity.sync.tokenserver.uri", "https://token.services.mozilla.com/1.0/sy
// Enable Presentation API
pref("dom.presentation.enabled", true);
pref("dom.presentation.discovery.enabled", true);
// TODO : remove it after landing bug1242874 because now it's the only way to
// suspend the MediaElement.
pref("media.useAudioChannelAPI", true);

View File

@ -719,6 +719,8 @@ var AudioPlaybackListener = {
init() {
Services.obs.addObserver(this, "audio-playback", false);
Services.obs.addObserver(this, "AudioFocusChanged", false);
addMessageListener("AudioPlaybackMute", this);
addEventListener("unload", () => {
AudioPlaybackListener.uninit();
@ -727,6 +729,8 @@ var AudioPlaybackListener = {
uninit() {
Services.obs.removeObserver(this, "audio-playback");
Services.obs.removeObserver(this, "AudioFocusChanged");
removeMessageListener("AudioPlaybackMute", this);
},
@ -737,6 +741,21 @@ var AudioPlaybackListener = {
name += (data === "active") ? "Start" : "Stop";
sendAsyncMessage(name);
}
} else if (topic == "AudioFocusChanged") {
let utils = global.content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
switch (data) {
// The AudioFocus:LossTransient means the media would be resumed after
// the interruption ended, but AudioFocus:Loss doesn't.
// TODO : distinguish these types, it would be done in bug1242874.
case "Loss":
case "LossTransient":
utils.mediaSuspended = true;
break;
case "Gain":
utils.mediaSuspended = false;
break;
}
}
},