Copied from: https://hg.mozilla.org/releases/mozilla-esr38/rev/f746c38d160e Security advisory: https://www.mozilla.org/en-US/security/advisories/mfsa2016-01/ Mozilla Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1223670 # HG changeset patch # User Karl Tomlinson # Date 1449764754 18000 # Node ID f746c38d160ea29088c15cacae44f3662befaec5 # Parent fc78180165a8262c80bbb722ed99b2e0c27b02d0 bug 1223670 replace public constructors with fallible factory methods r=baku a=abillings diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp --- a/dom/media/webaudio/AudioContext.cpp +++ b/dom/media/webaudio/AudioContext.cpp @@ -299,32 +299,29 @@ AudioContext::CreateMediaElementSource(H aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return nullptr; } #endif nsRefPtr stream = aMediaElement.MozCaptureStream(aRv); if (aRv.Failed()) { return nullptr; } - nsRefPtr mediaElementAudioSourceNode = - new MediaElementAudioSourceNode(this, stream); - return mediaElementAudioSourceNode.forget(); + return MediaElementAudioSourceNode::Create(this, stream, aRv); } already_AddRefed AudioContext::CreateMediaStreamSource(DOMMediaStream& aMediaStream, ErrorResult& aRv) { if (mIsOffline) { aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return nullptr; } - nsRefPtr mediaStreamAudioSourceNode = - new MediaStreamAudioSourceNode(this, &aMediaStream); - return mediaStreamAudioSourceNode.forget(); + + return MediaStreamAudioSourceNode::Create(this, &aMediaStream, aRv); } already_AddRefed AudioContext::CreateGain() { nsRefPtr gainNode = new GainNode(this); return gainNode.forget(); } diff --git a/dom/media/webaudio/AudioNode.cpp b/dom/media/webaudio/AudioNode.cpp --- a/dom/media/webaudio/AudioNode.cpp +++ b/dom/media/webaudio/AudioNode.cpp @@ -61,34 +61,29 @@ AudioNode::AudioNode(AudioContext* aCont ChannelInterpretation aChannelInterpretation) : DOMEventTargetHelper(aContext->GetParentObject()) , mContext(aContext) , mChannelCount(aChannelCount) , mChannelCountMode(aChannelCountMode) , mChannelInterpretation(aChannelInterpretation) , mId(gId++) , mPassThrough(false) -#ifdef DEBUG - , mDemiseNotified(false) -#endif { MOZ_ASSERT(aContext); DOMEventTargetHelper::BindToOwner(aContext->GetParentObject()); aContext->UpdateNodeCount(1); } AudioNode::~AudioNode() { MOZ_ASSERT(mInputNodes.IsEmpty()); MOZ_ASSERT(mOutputNodes.IsEmpty()); MOZ_ASSERT(mOutputParams.IsEmpty()); -#ifdef DEBUG - MOZ_ASSERT(mDemiseNotified, + MOZ_ASSERT(!mStream, "The webaudio-node-demise notification must have been sent"); -#endif if (mContext) { mContext->UpdateNodeCount(-1); } } size_t AudioNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { @@ -399,19 +394,16 @@ AudioNode::DestroyMediaStream() mStream = nullptr; nsCOMPtr obs = services::GetObserverService(); if (obs) { nsAutoString id; id.AppendPrintf("%u", mId); obs->NotifyObservers(nullptr, "webaudio-node-demise", id.get()); } -#ifdef DEBUG - mDemiseNotified = true; -#endif } } void AudioNode::RemoveOutputParam(AudioParam* aParam) { mOutputParams.RemoveElement(aParam); } diff --git a/dom/media/webaudio/AudioNode.h b/dom/media/webaudio/AudioNode.h --- a/dom/media/webaudio/AudioNode.h +++ b/dom/media/webaudio/AudioNode.h @@ -239,19 +239,14 @@ private: nsTArray > mOutputParams; uint32_t mChannelCount; ChannelCountMode mChannelCountMode; ChannelInterpretation mChannelInterpretation; const uint32_t mId; // Whether the node just passes through its input. This is a devtools API that // only works for some node types. bool mPassThrough; -#ifdef DEBUG - // In debug builds, check to make sure that the node demise notification has - // been properly sent before the node is destroyed. - bool mDemiseNotified; -#endif }; } } #endif diff --git a/dom/media/webaudio/MediaElementAudioSourceNode.cpp b/dom/media/webaudio/MediaElementAudioSourceNode.cpp --- a/dom/media/webaudio/MediaElementAudioSourceNode.cpp +++ b/dom/media/webaudio/MediaElementAudioSourceNode.cpp @@ -5,22 +5,36 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "MediaElementAudioSourceNode.h" #include "mozilla/dom/MediaElementAudioSourceNodeBinding.h" namespace mozilla { namespace dom { -MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext, - DOMMediaStream* aStream) - : MediaStreamAudioSourceNode(aContext, aStream) +MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext) + : MediaStreamAudioSourceNode(aContext) { } +/* static */ already_AddRefed +MediaElementAudioSourceNode::Create(AudioContext* aContext, + DOMMediaStream* aStream, ErrorResult& aRv) +{ + nsRefPtr node = + new MediaElementAudioSourceNode(aContext); + + node->Init(aStream, aRv); + if (aRv.Failed()) { + return nullptr; + } + + return node.forget(); +} + JSObject* MediaElementAudioSourceNode::WrapObject(JSContext* aCx) { return MediaElementAudioSourceNodeBinding::Wrap(aCx, this); } } } diff --git a/dom/media/webaudio/MediaElementAudioSourceNode.h b/dom/media/webaudio/MediaElementAudioSourceNode.h --- a/dom/media/webaudio/MediaElementAudioSourceNode.h +++ b/dom/media/webaudio/MediaElementAudioSourceNode.h @@ -10,28 +10,30 @@ #include "MediaStreamAudioSourceNode.h" namespace mozilla { namespace dom { class MediaElementAudioSourceNode : public MediaStreamAudioSourceNode { public: - MediaElementAudioSourceNode(AudioContext* aContext, - DOMMediaStream* aStream); + static already_AddRefed + Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv); virtual JSObject* WrapObject(JSContext* aCx) override; virtual const char* NodeType() const override { return "MediaElementAudioSourceNode"; } virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override { return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); } +private: + explicit MediaElementAudioSourceNode(AudioContext* aContext); }; } } #endif diff --git a/dom/media/webaudio/MediaStreamAudioSourceNode.cpp b/dom/media/webaudio/MediaStreamAudioSourceNode.cpp --- a/dom/media/webaudio/MediaStreamAudioSourceNode.cpp +++ b/dom/media/webaudio/MediaStreamAudioSourceNode.cpp @@ -25,26 +25,45 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaStreamAudioSourceNode) NS_INTERFACE_MAP_END_INHERITING(AudioNode) NS_IMPL_ADDREF_INHERITED(MediaStreamAudioSourceNode, AudioNode) NS_IMPL_RELEASE_INHERITED(MediaStreamAudioSourceNode, AudioNode) -MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* aContext, - DOMMediaStream* aMediaStream) +MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* aContext) : AudioNode(aContext, 2, ChannelCountMode::Max, - ChannelInterpretation::Speakers), - mInputStream(aMediaStream) + ChannelInterpretation::Speakers) { +} + +/* static */ already_AddRefed +MediaStreamAudioSourceNode::Create(AudioContext* aContext, + DOMMediaStream* aStream, ErrorResult& aRv) +{ + nsRefPtr node = + new MediaStreamAudioSourceNode(aContext); + + node->Init(aStream, aRv); + if (aRv.Failed()) { + return nullptr; + } + + return node.forget(); +} + +void +MediaStreamAudioSourceNode::Init(DOMMediaStream* aMediaStream, ErrorResult& aRv) +{ + mInputStream = aMediaStream; AudioNodeEngine* engine = new MediaStreamAudioSourceNodeEngine(this); - mStream = aContext->Graph()->CreateAudioNodeExternalInputStream(engine); + mStream = Context()->Graph()->CreateAudioNodeExternalInputStream(engine); ProcessedMediaStream* outputStream = static_cast(mStream.get()); mInputPort = outputStream->AllocateInputPort(aMediaStream->GetStream(), MediaInputPort::FLAG_BLOCK_INPUT); mInputStream->AddConsumerToKeepAlive(static_cast(this)); PrincipalChanged(mInputStream); // trigger enabling/disabling of the connector mInputStream->AddPrincipalChangeObserver(this); } diff --git a/dom/media/webaudio/MediaStreamAudioSourceNode.h b/dom/media/webaudio/MediaStreamAudioSourceNode.h --- a/dom/media/webaudio/MediaStreamAudioSourceNode.h +++ b/dom/media/webaudio/MediaStreamAudioSourceNode.h @@ -38,17 +38,18 @@ public: private: bool mEnabled; }; class MediaStreamAudioSourceNode : public AudioNode, public DOMMediaStream::PrincipalChangeObserver { public: - MediaStreamAudioSourceNode(AudioContext* aContext, DOMMediaStream* aMediaStream); + static already_AddRefed + Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamAudioSourceNode, AudioNode) virtual JSObject* WrapObject(JSContext* aCx) override; virtual void DestroyMediaStream() override; @@ -60,16 +61,18 @@ public: } virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override; virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override; virtual void PrincipalChanged(DOMMediaStream* aMediaStream) override; protected: + explicit MediaStreamAudioSourceNode(AudioContext* aContext); + void Init(DOMMediaStream* aMediaStream, ErrorResult& aRv); virtual ~MediaStreamAudioSourceNode(); private: nsRefPtr mInputPort; nsRefPtr mInputStream; }; }