Backed out changesets 961f205d340d, 14a4637e9d96 and 14a4637e9d96 (bug 1228564) for failing Android M(4) test_browserElement_inproc_AudioChannel.html. r=backout

This commit is contained in:
Sebastian Hengst 2015-12-27 22:28:08 +01:00
parent f3abb8a9e8
commit 3c1eb47e3a
14 changed files with 103 additions and 92 deletions

View File

@ -41,6 +41,7 @@ AudioChannelAgent::AudioChannelAgent()
: mAudioChannelType(AUDIO_AGENT_CHANNEL_ERROR)
, mInnerWindowID(0)
, mIsRegToService(false)
, mNotifyPlayback(false)
{
}
@ -207,7 +208,8 @@ AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
return NS_OK;
}
NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(float *aVolume,
NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(uint32_t aNotifyPlayback,
float *aVolume,
bool* aMuted)
{
MOZ_ASSERT(aVolume);
@ -226,7 +228,7 @@ NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(float *aVolume,
return NS_ERROR_FAILURE;
}
service->RegisterAudioChannelAgent(this,
service->RegisterAudioChannelAgent(this, aNotifyPlayback,
static_cast<AudioChannel>(mAudioChannelType));
service->GetState(mWindow, mAudioChannelType, aVolume, aMuted);
@ -235,6 +237,7 @@ NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(float *aVolume,
("AudioChannelAgent, NotifyStartedPlaying, this = %p, mute = %d, "
"volume = %f\n", this, *aMuted, *aVolume));
mNotifyPlayback = aNotifyPlayback;
mIsRegToService = true;
return NS_OK;
}
@ -251,7 +254,7 @@ NS_IMETHODIMP AudioChannelAgent::NotifyStoppedPlaying()
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
if (service) {
service->UnregisterAudioChannelAgent(this);
service->UnregisterAudioChannelAgent(this, mNotifyPlayback);
}
mIsRegToService = false;
@ -297,15 +300,8 @@ AudioChannelAgent::WindowID() const
return mWindow ? mWindow->WindowID() : 0;
}
uint64_t
AudioChannelAgent::InnerWindowID() const
{
return mInnerWindowID;
}
void
AudioChannelAgent::WindowAudioCaptureChanged(uint64_t aInnerWindowID,
bool aCapture)
AudioChannelAgent::WindowAudioCaptureChanged(uint64_t aInnerWindowID)
{
if (aInnerWindowID != mInnerWindowID) {
return;
@ -316,9 +312,5 @@ AudioChannelAgent::WindowAudioCaptureChanged(uint64_t aInnerWindowID,
return;
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, WindowAudioCaptureChanged, this = %p, "
"capture = %d\n", this, aCapture));
callback->WindowAudioCaptureChanged(aCapture);
callback->WindowAudioCaptureChanged();
}

View File

@ -34,7 +34,7 @@ public:
AudioChannelAgent();
void WindowVolumeChanged();
void WindowAudioCaptureChanged(uint64_t aInnerWindowID, bool aCapture);
void WindowAudioCaptureChanged(uint64_t aInnerWindowID);
nsPIDOMWindow* Window() const
{
@ -42,7 +42,6 @@ public:
}
uint64_t WindowID() const;
uint64_t InnerWindowID() const;
private:
virtual ~AudioChannelAgent();
@ -67,6 +66,7 @@ private:
int32_t mAudioChannelType;
uint64_t mInnerWindowID;
bool mIsRegToService;
bool mNotifyPlayback;
};
} // namespace dom

View File

@ -268,6 +268,7 @@ AudioChannelService::~AudioChannelService()
void
AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
uint32_t aNotifyPlayback,
AudioChannel aChannel)
{
uint64_t windowID = aAgent->WindowID();
@ -288,24 +289,19 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
}
// If this is the first agent for this window, we must notify the observers.
if (winData->mAgents.Length() == 1) {
if (aNotifyPlayback == nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY &&
winData->mAgents.Length() == 1) {
RefPtr<MediaPlaybackRunnable> runnable =
new MediaPlaybackRunnable(aAgent->Window(), true /* active */);
NS_DispatchToCurrentThread(runnable);
}
// If the window has already been captured, the agent of that window should
// also be captured.
if (winData->mIsAudioCaptured) {
aAgent->WindowAudioCaptureChanged(aAgent->InnerWindowID(),
winData->mIsAudioCaptured);
}
MaybeSendStatusUpdate();
}
void
AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent,
uint32_t aNotifyPlayback)
{
AudioChannelWindow* winData = GetWindowData(aAgent->WindowID());
if (!winData) {
@ -337,17 +333,13 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
#endif
// If this is the last agent for this window, we must notify the observers.
if (winData->mAgents.IsEmpty()) {
if (aNotifyPlayback == nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY &&
winData->mAgents.IsEmpty()) {
RefPtr<MediaPlaybackRunnable> runnable =
new MediaPlaybackRunnable(aAgent->Window(), false /* active */);
NS_DispatchToCurrentThread(runnable);
}
// No need to capture non-audible object.
if (winData->mIsAudioCaptured) {
aAgent->WindowAudioCaptureChanged(aAgent->InnerWindowID(), false);
}
MaybeSendStatusUpdate();
}
@ -635,18 +627,12 @@ AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
}
void
AudioChannelService::SetWindowAudioCaptured(nsPIDOMWindow* aWindow,
uint64_t aInnerWindowID,
bool aCapture)
AudioChannelService::RefreshAgentsCapture(nsPIDOMWindow* aWindow,
uint64_t aInnerWindowID)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsOuterWindow());
MOZ_LOG(GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelService, SetWindowAudioCaptured, window = %p, "
"aCapture = %d\n", aWindow, aCapture));
nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop();
if (!topWindow) {
return;
@ -663,13 +649,10 @@ AudioChannelService::SetWindowAudioCaptured(nsPIDOMWindow* aWindow,
return;
}
if (aCapture != winData->mIsAudioCaptured) {
winData->mIsAudioCaptured = aCapture;
nsTObserverArray<AudioChannelAgent*>::ForwardIterator
iter(winData->mAgents);
while (iter.HasMore()) {
iter.GetNext()->WindowAudioCaptureChanged(aInnerWindowID, aCapture);
}
nsTObserverArray<AudioChannelAgent*>::ForwardIterator
iter(winData->mAgents);
while (iter.HasMore()) {
iter.GetNext()->WindowAudioCaptureChanged(aInnerWindowID);
}
}
@ -807,7 +790,7 @@ AudioChannelService::SetAudioChannelVolume(nsPIDOMWindow* aWindow,
MOZ_LOG(GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelService, SetAudioChannelVolume, window = %p, type = %d, "
"volume = %f\n", aWindow, aAudioChannel, aVolume));
"volume = %d\n", aWindow, aAudioChannel, aVolume));
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
winData->mChannels[(uint32_t)aAudioChannel].mVolume = aVolume;

View File

@ -56,13 +56,15 @@ public:
* this service, sharing the AudioChannel.
*/
void RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
uint32_t aNotifyPlayback,
AudioChannel aChannel);
/**
* Any audio channel agent that stops playing should unregister itself to
* this service.
*/
void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent);
void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent,
uint32_t aNotifyPlayback);
/**
* For nested iframes.
@ -122,9 +124,8 @@ public:
// group agents per top outer window, but we can have multiple innerWindow per
// top outerWindow (subiframes, etc.) and we have to identify all the agents
// just for a particular innerWindow.
void SetWindowAudioCaptured(nsPIDOMWindow* aWindow,
uint64_t aInnerWindowID,
bool aCapture);
void RefreshAgentsCapture(nsPIDOMWindow* aWindow,
uint64_t aInnerWindowID);
#ifdef MOZ_WIDGET_GONK
@ -188,15 +189,13 @@ private:
struct AudioChannelWindow final
{
explicit AudioChannelWindow(uint64_t aWindowID)
: mWindowID(aWindowID),
mIsAudioCaptured(false)
: mWindowID(aWindowID)
{
// Workaround for bug1183033, system channel type can always playback.
mChannels[(int16_t)AudioChannel::System].mMuted = false;
}
uint64_t mWindowID;
bool mIsAudioCaptured;
AudioChannelConfig mChannels[NUMBER_OF_AUDIO_CHANNELS];
// Raw pointer because the AudioChannelAgent must unregister itself.

View File

@ -6,7 +6,7 @@
interface nsIDOMWindow;
[uuid(0a451ee0-972e-11e5-a837-0800200c9a66)]
[uuid(5fe83b24-38b9-4901-a4a1-d1bd57d3fe18)]
interface nsIAudioChannelAgentCallback : nsISupports
{
/**
@ -17,7 +17,7 @@ interface nsIAudioChannelAgentCallback : nsISupports
/**
* Notified when the capture state is changed.
*/
void windowAudioCaptureChanged(in bool aCapture);
void windowAudioCaptureChanged();
};
/**
@ -34,7 +34,7 @@ interface nsIAudioChannelAgentCallback : nsISupports
* 1. Changes to the playable status of this channel.
*/
[uuid(ab7e21c0-970c-11e5-a837-0800200c9a66)]
[uuid(18222148-1b32-463d-b050-b741f43a07ba)]
interface nsIAudioChannelAgent : nsISupports
{
const long AUDIO_AGENT_CHANNEL_NORMAL = 0;
@ -52,6 +52,9 @@ interface nsIAudioChannelAgent : nsISupports
const long AUDIO_AGENT_STATE_MUTED = 1;
const long AUDIO_AGENT_STATE_FADED = 2;
const long AUDIO_AGENT_DONT_NOTIFY = 0;
const long AUDIO_AGENT_NOTIFY = 1;
/**
* Before init() is called, this returns AUDIO_AGENT_CHANNEL_ERROR.
*/
@ -98,6 +101,10 @@ interface nsIAudioChannelAgent : nsISupports
* Note: Gecko component SHOULD call this function first then start to
* play audio stream only when return value is true.
*
* @param notifyPlaying
* Whether to send audio-playback notifications, one of AUDIO_CHANNEL_NOTIFY
* or AUDIO_CHANNEL_DONT_NOTIFY.
*
* @return
* normal state: the agent has registered with audio channel service and
* the component should start playback.
@ -106,7 +113,7 @@ interface nsIAudioChannelAgent : nsISupports
* faded state: the agent has registered with audio channel service the
* component should start playback as well as reducing the volume.
*/
void notifyStartedPlaying(out float volume, out bool muted);
void notifyStartedPlaying(in unsigned long notifyPlayback, out float volume, out bool muted);
/**
* Notify the agent we no longer want to play.

View File

@ -3743,7 +3743,7 @@ nsPIDOMWindow::SetAudioCapture(bool aCapture)
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
if (service) {
service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture);
service->RefreshAgentsCapture(GetOuterWindow(), mWindowID);
}
return NS_OK;

View File

@ -1187,7 +1187,8 @@ nsDOMCameraControl::NotifyRecordingStatusChange(const nsString& aMsg)
// Video recording doesn't output any sound, so it's not necessary to check canPlay.
float volume = 0.0;
bool muted = true;
rv = mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
rv = mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_DONT_NOTIFY,
&volume, &muted);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -454,7 +454,8 @@ FMRadio::EnableAudioChannelAgent()
float volume = 0.0;
bool muted = true;
mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY,
&volume, &muted);
WindowVolumeChanged(volume, muted);
mAudioChannelAgentEnabled = true;
@ -469,7 +470,7 @@ FMRadio::WindowVolumeChanged(float aVolume, bool aMuted)
}
NS_IMETHODIMP
FMRadio::WindowAudioCaptureChanged(bool aCapture)
FMRadio::WindowAudioCaptureChanged()
{
return NS_OK;
}

View File

@ -114,18 +114,31 @@ using mozilla::net::nsMediaFragmentURIParser;
class MOZ_STACK_CLASS AutoNotifyAudioChannelAgent
{
RefPtr<mozilla::dom::HTMLMediaElement> mElement;
bool mShouldNotify;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
public:
explicit AutoNotifyAudioChannelAgent(mozilla::dom::HTMLMediaElement* aElement
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
AutoNotifyAudioChannelAgent(mozilla::dom::HTMLMediaElement* aElement,
bool aNotify
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mElement(aElement)
, mShouldNotify(aNotify)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
if (mShouldNotify) {
// The audio channel agent may not exist now.
if (mElement->MaybeCreateAudioChannelAgent()) {
mElement->NotifyAudioChannelAgent(false);
}
}
}
~AutoNotifyAudioChannelAgent()
{
mElement->UpdateAudioChannelPlayingState();
if (mShouldNotify) {
// The audio channel agent is destroyed at this point.
if (mElement->MaybeCreateAudioChannelAgent()) {
mElement->NotifyAudioChannelAgent(true);
}
}
}
};
@ -3386,7 +3399,10 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
// If the element is gaining or losing an audio track, we need to notify
// the audio channel agent so that the correct audio-playback events will
// get dispatched.
AutoNotifyAudioChannelAgent autoNotify(this);
bool audioTrackChanging = mMediaInfo.HasAudio() != aInfo->HasAudio();
AutoNotifyAudioChannelAgent autoNotify(this,
audioTrackChanging &&
mPlayingThroughTheAudioChannel);
mMediaInfo = *aInfo;
mIsEncrypted = aInfo->IsEncrypted()
@ -4745,11 +4761,6 @@ HTMLMediaElement::IsPlayingThroughTheAudioChannel() const
return false;
}
// If this element doesn't have any audio tracks.
if (!HasAudio()) {
return false;
}
// The volume should not be ~0
if (std::fabs(Volume()) <= 1e-7) {
return false;
@ -4805,15 +4816,23 @@ HTMLMediaElement::UpdateAudioChannelPlayingState()
void
HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying)
{
// Immediately check if this should go to the MSG instead of the normal
// media playback route.
WindowAudioCaptureChanged();
// This is needed to pass nsContentUtils::IsCallerChrome().
// AudioChannel API should not called from content but it can happen that
// this method has some content JS in its stack.
AutoNoJSAPI nojsapi;
if (aPlaying) {
// Don't notify playback if this element doesn't have any audio tracks.
uint32_t notify = HasAudio() ? nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY :
nsIAudioChannelAgent::AUDIO_AGENT_DONT_NOTIFY;
float volume = 0.0;
bool muted = true;
mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
mAudioChannelAgent->NotifyStartedPlaying(notify, &volume, &muted);
WindowVolumeChanged(volume, muted);
} else {
mAudioChannelAgent->NotifyStoppedPlaying();
@ -4975,17 +4994,17 @@ HTMLMediaElement::GetTopLevelPrincipal()
}
#endif // MOZ_EME
NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged(bool aCapture)
NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged()
{
MOZ_ASSERT(mAudioChannelAgent);
MOZ_ASSERT(HasAudio());
if (!OwnerDoc()->GetInnerWindow()) {
return NS_OK;
}
bool captured = OwnerDoc()->GetInnerWindow()->GetAudioCaptured();
if (aCapture != mAudioCapturedByWindow) {
if (aCapture) {
if (captured != mAudioCapturedByWindow) {
if (captured) {
mAudioCapturedByWindow = true;
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(OwnerDoc()->GetParentObject());
@ -5021,7 +5040,7 @@ NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged(bool aCapture)
}
}
return NS_OK;
return NS_OK;
}
AudioTrackList*

View File

@ -537,7 +537,7 @@ AudioDestinationNode::WindowVolumeChanged(float aVolume, bool aMuted)
}
NS_IMETHODIMP
AudioDestinationNode::WindowAudioCaptureChanged(bool aCapture)
AudioDestinationNode::WindowAudioCaptureChanged()
{
MOZ_ASSERT(mAudioChannelAgent);
@ -550,8 +550,10 @@ AudioDestinationNode::WindowAudioCaptureChanged(bool aCapture)
return NS_OK;
}
if (aCapture != mCaptured) {
if (aCapture) {
bool captured = ownerWindow->GetAudioCaptured();
if (captured != mCaptured) {
if (captured) {
nsCOMPtr<nsPIDOMWindow> window = Context()->GetParentObject();
uint64_t id = window->WindowID();
mCaptureStreamPort =
@ -559,7 +561,7 @@ AudioDestinationNode::WindowAudioCaptureChanged(bool aCapture)
} else {
mCaptureStreamPort->Destroy();
}
mCaptured = aCapture;
mCaptured = captured;
}
return NS_OK;
@ -651,7 +653,10 @@ AudioDestinationNode::CreateAudioChannelAgent()
return rv;
}
return NS_OK;
rv = WindowAudioCaptureChanged();
NS_WARN_IF(NS_FAILED(rv));
return rv;
}
void
@ -741,11 +746,13 @@ AudioDestinationNode::InputMuted(bool aMuted)
float volume = 0.0;
bool muted = true;
nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY,
&volume, &muted);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
WindowAudioCaptureChanged();
WindowVolumeChanged(volume, muted);
}

View File

@ -696,7 +696,7 @@ nsSpeechTask::CreateAudioChannelAgent()
this);
float volume = 0.0f;
bool muted = true;
mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY, &volume, &muted);
}
void
@ -716,7 +716,7 @@ nsSpeechTask::WindowVolumeChanged(float aVolume, bool aMuted)
}
NS_IMETHODIMP
nsSpeechTask::WindowAudioCaptureChanged(bool aCapture)
nsSpeechTask::WindowAudioCaptureChanged()
{
// This is not supported yet.
return NS_OK;

View File

@ -2296,7 +2296,8 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
} else {
float volume = 0.0;
bool muted = true;
rv = agent->NotifyStartedPlaying(&volume, &muted);
rv = agent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY,
&volume, &muted);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NPERR_NO_ERROR;
}

View File

@ -1860,7 +1860,7 @@ nsNPAPIPluginInstance::WindowVolumeChanged(float aVolume, bool aMuted)
}
NS_IMETHODIMP
nsNPAPIPluginInstance::WindowAudioCaptureChanged(bool aCapture)
nsNPAPIPluginInstance::WindowAudioCaptureChanged()
{
return NS_OK;
}

View File

@ -562,7 +562,8 @@ Telephony::HandleAudioAgentState()
mIsAudioStartPlaying = true;
float volume;
bool muted;
rv = mAudioAgent->NotifyStartedPlaying(&volume, &muted);
rv = mAudioAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY,
&volume, &muted);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -711,7 +712,7 @@ Telephony::WindowVolumeChanged(float aVolume, bool aMuted)
}
NS_IMETHODIMP
Telephony::WindowAudioCaptureChanged(bool aCapture)
Telephony::WindowAudioCaptureChanged()
{
// Do nothing, it's useless for the telephony object.
return NS_OK;