Bug 1275856 - Capture MediaRecorder DOMExceptions early in order to capture JS traces. r=jib

In order to expose the JS stack on aync exceptions from the MediaRecorder,
these exceptions must be created at the time of the operation which led to the
exception. E.g. during the start() operation. This changeset creates the
exceptions ahead of time in order to expose the JS stack traces.

MozReview-Commit-ID: HgDJrpjgidD

--HG--
extra : rebase_source : e7ad0b2a30ac2e7161d3805a22b3873a7382b43b
This commit is contained in:
Bryce Van Dyk 2017-08-07 09:49:24 +12:00
Родитель f571e0f7e0
Коммит 575792962a
2 изменённых файлов: 44 добавлений и 2 удалений

Просмотреть файл

@ -109,6 +109,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaRecorder,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSecurityDomException)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUnknownDomException)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -116,6 +118,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaRecorder,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStream)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSecurityDomException)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mUnknownDomException)
tmp->UnRegisterActivityObserver();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -1055,6 +1059,9 @@ void
MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult)
{
LOG(LogLevel::Debug, ("MediaRecorder.Start %p", this));
InitializeDomExceptions();
if (mState != RecordingState::Inactive) {
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
@ -1397,12 +1404,27 @@ MediaRecorder::NotifyError(nsresult aRv)
MediaRecorderErrorEventInit init;
init.mBubbles = false;
init.mCancelable = false;
// These DOMExceptions have been created earlier so they can contain stack
// traces. We attach the appropriate one here to be fired. We should have
// exceptions here, but defensively check.
switch (aRv) {
case NS_ERROR_DOM_SECURITY_ERR:
init.mError = DOMException::Create(aRv);
if (!mSecurityDomException) {
LOG(LogLevel::Debug, ("MediaRecorder.NotifyError: "
"mSecurityDomException was not initialized"));
mSecurityDomException = DOMException::Create(NS_ERROR_DOM_SECURITY_ERR);
}
init.mError = mSecurityDomException.forget();
break;
default:
init.mError = DOMException::Create(NS_ERROR_DOM_UNKNOWN_ERR);
if (!mUnknownDomException) {
LOG(LogLevel::Debug, ("MediaRecorder.NotifyError: "
"mUnknownDomException was not initialized"));
mUnknownDomException = DOMException::Create(NS_ERROR_DOM_UNKNOWN_ERR);
}
LOG(LogLevel::Debug, ("MediaRecorder.NotifyError: "
"mUnknownDomException being fired for aRv: %X", uint32_t(aRv)));
init.mError = mUnknownDomException.forget();
}
RefPtr<MediaRecorderErrorEvent> event = MediaRecorderErrorEvent::Constructor(
@ -1450,6 +1472,13 @@ MediaRecorder::GetSourceMediaStream()
return mPipeStream ? mPipeStream.get() : mAudioNode->GetStream();
}
void
MediaRecorder::InitializeDomExceptions()
{
mSecurityDomException = DOMException::Create(NS_ERROR_DOM_SECURITY_ERR);
mUnknownDomException = DOMException::Create(NS_ERROR_DOM_UNKNOWN_ERR);
}
size_t
MediaRecorder::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{

Просмотреть файл

@ -28,6 +28,7 @@ class GlobalObject;
namespace dom {
class AudioNode;
class DOMException;
/**
* Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html
@ -133,6 +134,12 @@ protected:
void RemoveSession(Session* aSession);
// Functions for Session to query input source info.
MediaStream* GetSourceMediaStream();
// Create DOMExceptions capturing the JS stack for async errors. These are
// created ahead of time rather than on demand when firing an error as the JS
// stack of the operation that started the async behavior will not be
// available at the time the error event is fired. Note, depending on when
// this is called there may not be a JS stack to capture.
void InitializeDomExceptions();
// DOM wrapper for source media stream. Will be null when input is audio node.
RefPtr<DOMMediaStream> mDOMStream;
// Source audio node. Will be null when input is a media stream.
@ -159,6 +166,12 @@ protected:
uint32_t mVideoBitsPerSecond;
uint32_t mBitsPerSecond;
// DOMExceptions that are created early and possibly thrown in NotifyError.
// Creating them early allows us to capture the JS stack for which cannot be
// done at the time the error event is fired.
RefPtr<DOMException> mSecurityDomException;
RefPtr<DOMException> mUnknownDomException;
private:
// Register MediaRecorder into Document to listen the activity changes.
void RegisterActivityObserver();