зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f571e0f7e0
Коммит
575792962a
|
@ -109,6 +109,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaRecorder,
|
||||||
DOMEventTargetHelper)
|
DOMEventTargetHelper)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStream)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStream)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioNode)
|
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(mDocument)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
@ -116,6 +118,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaRecorder,
|
||||||
DOMEventTargetHelper)
|
DOMEventTargetHelper)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStream)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStream)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioNode)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioNode)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSecurityDomException)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mUnknownDomException)
|
||||||
tmp->UnRegisterActivityObserver();
|
tmp->UnRegisterActivityObserver();
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
@ -1055,6 +1059,9 @@ void
|
||||||
MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult)
|
MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult)
|
||||||
{
|
{
|
||||||
LOG(LogLevel::Debug, ("MediaRecorder.Start %p", this));
|
LOG(LogLevel::Debug, ("MediaRecorder.Start %p", this));
|
||||||
|
|
||||||
|
InitializeDomExceptions();
|
||||||
|
|
||||||
if (mState != RecordingState::Inactive) {
|
if (mState != RecordingState::Inactive) {
|
||||||
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||||
return;
|
return;
|
||||||
|
@ -1397,12 +1404,27 @@ MediaRecorder::NotifyError(nsresult aRv)
|
||||||
MediaRecorderErrorEventInit init;
|
MediaRecorderErrorEventInit init;
|
||||||
init.mBubbles = false;
|
init.mBubbles = false;
|
||||||
init.mCancelable = 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) {
|
switch (aRv) {
|
||||||
case NS_ERROR_DOM_SECURITY_ERR:
|
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;
|
break;
|
||||||
default:
|
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(
|
RefPtr<MediaRecorderErrorEvent> event = MediaRecorderErrorEvent::Constructor(
|
||||||
|
@ -1450,6 +1472,13 @@ MediaRecorder::GetSourceMediaStream()
|
||||||
return mPipeStream ? mPipeStream.get() : mAudioNode->GetStream();
|
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
|
size_t
|
||||||
MediaRecorder::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
MediaRecorder::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@ class GlobalObject;
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class AudioNode;
|
class AudioNode;
|
||||||
|
class DOMException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html
|
* 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);
|
void RemoveSession(Session* aSession);
|
||||||
// Functions for Session to query input source info.
|
// Functions for Session to query input source info.
|
||||||
MediaStream* GetSourceMediaStream();
|
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.
|
// DOM wrapper for source media stream. Will be null when input is audio node.
|
||||||
RefPtr<DOMMediaStream> mDOMStream;
|
RefPtr<DOMMediaStream> mDOMStream;
|
||||||
// Source audio node. Will be null when input is a media stream.
|
// Source audio node. Will be null when input is a media stream.
|
||||||
|
@ -159,6 +166,12 @@ protected:
|
||||||
uint32_t mVideoBitsPerSecond;
|
uint32_t mVideoBitsPerSecond;
|
||||||
uint32_t mBitsPerSecond;
|
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:
|
private:
|
||||||
// Register MediaRecorder into Document to listen the activity changes.
|
// Register MediaRecorder into Document to listen the activity changes.
|
||||||
void RegisterActivityObserver();
|
void RegisterActivityObserver();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче