зеркало из https://github.com/mozilla/gecko-dev.git
Bug 805333 part 2 - MediaElement connected to AudioChannelService, r=kinetik, a=blocking-basecamp
This commit is contained in:
Родитель
109dd4019c
Коммит
661c89ec0c
|
@ -7705,7 +7705,7 @@ nsDocument::CloneDocHelper(nsDocument* clone) const
|
|||
|
||||
if (mCreatingStaticClone) {
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
|
||||
|
||||
// |mDocumentContainer| is the container of the document that is being
|
||||
// created and not the original container. See CreateStaticClone function().
|
||||
nsCOMPtr<nsIDocumentLoader> docLoader = do_QueryReferent(mDocumentContainer);
|
||||
|
@ -9911,6 +9911,8 @@ nsDocument::UpdateVisibilityState()
|
|||
NS_LITERAL_STRING("mozvisibilitychange"),
|
||||
/* bubbles = */ true,
|
||||
/* cancelable = */ false);
|
||||
|
||||
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ public:
|
|||
|
||||
/**
|
||||
* Call this to reevaluate whether we should start/stop due to our owner
|
||||
* document being active or inactive.
|
||||
* document being active, inactive, visible or hidden.
|
||||
*/
|
||||
void NotifyOwnerDocumentActivityChanged();
|
||||
|
||||
|
@ -405,6 +405,9 @@ public:
|
|||
return mSrcStream->GetStream();
|
||||
}
|
||||
|
||||
// Notification from the AudioChannelService.
|
||||
nsresult NotifyAudioChannelStateChanged();
|
||||
|
||||
protected:
|
||||
class MediaLoadListener;
|
||||
class StreamListener;
|
||||
|
@ -648,9 +651,20 @@ protected:
|
|||
*/
|
||||
void ProcessMediaFragmentURI();
|
||||
|
||||
/**
|
||||
* Mute or unmute the audio, without changing the value that |muted| reports.
|
||||
*/
|
||||
void SetMutedInternal(bool aMuted);
|
||||
|
||||
// Check the permissions for audiochannel.
|
||||
bool CheckAudioChannelPermissions(const nsAString& aType);
|
||||
|
||||
// This method does the check for muting/unmuting the audio channel.
|
||||
nsresult UpdateChannelMuteState();
|
||||
|
||||
// Update the audio channel playing state
|
||||
void UpdateAudioChannelPlayingState();
|
||||
|
||||
// The current decoder. Load() has been called on this decoder.
|
||||
// At most one of mDecoder and mSrcStream can be non-null.
|
||||
nsRefPtr<nsMediaDecoder> mDecoder;
|
||||
|
@ -911,6 +925,12 @@ protected:
|
|||
|
||||
// Audio Channel Type.
|
||||
mozilla::dom::AudioChannelType mAudioChannelType;
|
||||
|
||||
// The audiochannel has been muted
|
||||
bool mChannelMuted;
|
||||
|
||||
// Is this media element playing?
|
||||
bool mPlayingThroughTheAudioChannel;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -65,6 +65,8 @@
|
|||
#include "nsDOMMediaStream.h"
|
||||
#include "nsIScriptError.h"
|
||||
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsIMediaList.h"
|
||||
|
||||
|
@ -1515,14 +1517,9 @@ NS_IMETHODIMP nsHTMLMediaElement::GetMuted(bool *aMuted)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLMediaElement::SetMuted(bool aMuted)
|
||||
void nsHTMLMediaElement::SetMutedInternal(bool aMuted)
|
||||
{
|
||||
if (aMuted == mMuted)
|
||||
return NS_OK;
|
||||
|
||||
mMuted = aMuted;
|
||||
|
||||
float effectiveVolume = mMuted ? 0.0f : float(mVolume);
|
||||
float effectiveVolume = aMuted || mChannelMuted ? 0.0f : float(mVolume);
|
||||
if (mDecoder) {
|
||||
mDecoder->SetVolume(effectiveVolume);
|
||||
} else if (mAudioStream) {
|
||||
|
@ -1530,6 +1527,15 @@ NS_IMETHODIMP nsHTMLMediaElement::SetMuted(bool aMuted)
|
|||
} else if (mSrcStream) {
|
||||
GetSrcMediaStream()->SetAudioOutputVolume(this, effectiveVolume);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLMediaElement::SetMuted(bool aMuted)
|
||||
{
|
||||
if (aMuted == mMuted)
|
||||
return NS_OK;
|
||||
|
||||
mMuted = aMuted;
|
||||
SetMutedInternal(aMuted);
|
||||
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
|
||||
|
||||
|
@ -1723,7 +1729,9 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
|||
mCORSMode(CORS_NONE),
|
||||
mHasAudio(false),
|
||||
mDownloadSuspendedByCache(false),
|
||||
mAudioChannelType(AUDIO_CHANNEL_NORMAL)
|
||||
mAudioChannelType(AUDIO_CHANNEL_NORMAL),
|
||||
mChannelMuted(false),
|
||||
mPlayingThroughTheAudioChannel(false)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gMediaElementLog) {
|
||||
|
@ -3193,6 +3201,8 @@ void nsHTMLMediaElement::ChangeReadyState(nsMediaReadyState aState)
|
|||
nsMediaReadyState oldState = mReadyState;
|
||||
mReadyState = aState;
|
||||
|
||||
UpdateAudioChannelPlayingState();
|
||||
|
||||
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY ||
|
||||
oldState == mReadyState) {
|
||||
return;
|
||||
|
@ -3437,6 +3447,10 @@ void nsHTMLMediaElement::NotifyOwnerDocumentActivityChanged()
|
|||
}
|
||||
}
|
||||
|
||||
if (mPlayingThroughTheAudioChannel) {
|
||||
UpdateChannelMuteState();
|
||||
}
|
||||
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
|
||||
|
@ -3475,6 +3489,8 @@ void nsHTMLMediaElement::AddRemoveSelfReference()
|
|||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAudioChannelPlayingState();
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::DoRemoveSelfReference()
|
||||
|
@ -3752,6 +3768,64 @@ void nsHTMLMediaElement::GetMimeType(nsCString& aMimeType)
|
|||
aMimeType = mMimeType;
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::UpdateChannelMuteState()
|
||||
{
|
||||
bool hidden = false;
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(OwnerDoc());
|
||||
if (!domDoc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = domDoc->GetHidden(&hidden);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool mute = false;
|
||||
|
||||
nsRefPtr<AudioChannelService> audioChannelService = AudioChannelService::GetAudioChannelService();
|
||||
if (audioChannelService) {
|
||||
mute = audioChannelService->GetMuted(mAudioChannelType, hidden);
|
||||
}
|
||||
|
||||
// We have to mute this channel:
|
||||
if (mute && !mChannelMuted) {
|
||||
mChannelMuted = true;
|
||||
SetMutedInternal(mMuted);
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
|
||||
} else if (!mute && mChannelMuted) {
|
||||
mChannelMuted = false;
|
||||
SetMutedInternal(mMuted);
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptend"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::UpdateAudioChannelPlayingState()
|
||||
{
|
||||
bool playingThroughTheAudioChannel =
|
||||
(mReadyState >= nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA &&
|
||||
IsPotentiallyPlaying());
|
||||
if (playingThroughTheAudioChannel != mPlayingThroughTheAudioChannel) {
|
||||
mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
|
||||
|
||||
nsRefPtr<AudioChannelService> audioChannelService = AudioChannelService::GetAudioChannelService();
|
||||
if (!audioChannelService) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPlayingThroughTheAudioChannel) {
|
||||
audioChannelService->RegisterMediaElement(this, mAudioChannelType);
|
||||
} else {
|
||||
audioChannelService->UnregisterMediaElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::NotifyAudioChannelStateChanged()
|
||||
{
|
||||
return UpdateChannelMuteState();
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::NotifyAudioAvailableListener()
|
||||
{
|
||||
if (mDecoder) {
|
||||
|
|
|
@ -154,8 +154,7 @@ NotifyEnumerator(nsHTMLMediaElement* aElement,
|
|||
AudioChannelType aType, void* aData)
|
||||
{
|
||||
if (aElement) {
|
||||
// TODO: this part will be cover by a different patch.
|
||||
// aElement->NotifyAudioChannelStateChanged();
|
||||
aElement->NotifyAudioChannelStateChanged();
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
|
|
@ -138,6 +138,10 @@ interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
|
|||
// Use case: dialer, voip
|
||||
// * publicnotification
|
||||
// Always plays in speaker, even when headphones are plugged in.
|
||||
|
||||
attribute DOMString mozAudioChannelType;
|
||||
|
||||
// In addition the media element has these new events:
|
||||
// * onmozinterruptbegin - called when the media element is interrupted
|
||||
// because of the audiochannel manager.
|
||||
// * onmozinterruptend - called when the interruption is concluded
|
||||
};
|
||||
|
|
|
@ -345,7 +345,8 @@
|
|||
"loadstart", "timeupdate", "progress",
|
||||
"playing", "waiting", "canplay", "canplaythrough",
|
||||
"seeking", "seeked", "emptied", "loadedmetadata",
|
||||
"error", "suspend", "stalled"],
|
||||
"error", "suspend", "stalled",
|
||||
"mozinterruptbegin", "mozinterruptend" ],
|
||||
|
||||
firstFrameShown : false,
|
||||
timeUpdateCount : 0,
|
||||
|
@ -641,6 +642,10 @@
|
|||
this.controlsSpacer.removeAttribute("hideCursor");
|
||||
}
|
||||
break;
|
||||
case "mozinterruptbegin":
|
||||
case "mozinterruptend":
|
||||
// Nothing to do...
|
||||
break;
|
||||
default:
|
||||
this.log("!!! event " + aEvent.type + " not handled!");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче