Bug 1599952 pass MessagePort to AudioWorkletGlobalScope r=baku

Differential Revision: https://phabricator.services.mozilla.com/D53134

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Karl Tomlinson 2019-12-02 11:30:39 +00:00
Родитель 816db578f9
Коммит 5d8f14ddef
3 изменённых файлов: 31 добавлений и 8 удалений

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

@ -12,6 +12,7 @@
#include "jsapi.h"
#include "mozilla/dom/AudioWorkletGlobalScopeBinding.h"
#include "mozilla/dom/AudioWorkletProcessor.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "mozilla/dom/WorkletPrincipals.h"
#include "mozilla/dom/AudioParamDescriptorBinding.h"
@ -296,6 +297,7 @@ AudioParamDescriptorMap AudioWorkletGlobalScope::DescriptorsFromJS(
bool AudioWorkletGlobalScope::ConstructProcessor(
const nsAString& aName, NotNull<StructuredCloneHolder*> aSerializedOptions,
UniqueMessagePortId& aPortIdentifier,
JS::MutableHandle<JSObject*> aRetProcessor) {
/**
* See
@ -307,10 +309,15 @@ bool AudioWorkletGlobalScope::ConstructProcessor(
}
JSContext* cx = jsapi.cx();
ErrorResult rv;
/** TODO https://bugzilla.mozilla.org/show_bug.cgi?id=1565956
/**
* 4. Let deserializedPort be the result of
* StructuredDeserialize(serializedPort, the current Realm).
*/
RefPtr<MessagePort> deserializedPort =
MessagePort::Create(this, aPortIdentifier, rv);
if (NS_WARN_IF(rv.MaybeSetPendingException(cx))) {
return false;
}
/**
* 5. Let deserializedOptions be the result of
* StructuredDeserialize(serializedOptions, the current Realm).
@ -329,11 +336,14 @@ bool AudioWorkletGlobalScope::ConstructProcessor(
// AudioWorkletNode has already checked the definition exists.
// See also https://github.com/WebAudio/web-audio-api/issues/1854
MOZ_ASSERT(processorCtor);
/** TODO https://bugzilla.mozilla.org/show_bug.cgi?id=1565956
/**
* 7. Store nodeReference and deserializedPort to node reference and
* transferred port of this AudioWorkletGlobalScope's pending processor
* construction data respectively.
*/
// |nodeReference| is not required here because the "processorerror" event
// is thrown by WorkletNodeEngine::ConstructProcessor().
mPortForProcessor = std::move(deserializedPort);
/**
* 8. Construct a callback function from processorCtor with the argument
* of deserializedOptions.
@ -344,6 +354,8 @@ bool AudioWorkletGlobalScope::ConstructProcessor(
RefPtr<AudioWorkletProcessor> processor = processorCtor->Construct(
options, rv, "AudioWorkletProcessor construction",
CallbackFunction::eReportExceptions);
// https://github.com/WebAudio/web-audio-api/issues/2096
mPortForProcessor = nullptr;
if (rv.Failed()) {
rv.SuppressException(); // already reported
return false;

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

@ -19,7 +19,9 @@ class AudioWorkletImpl;
namespace dom {
class AudioWorkletProcessorConstructor;
class MessagePort;
class StructuredCloneHolder;
class UniqueMessagePortId;
class AudioWorkletGlobalScope final : public WorkletGlobalScope {
public:
@ -49,6 +51,7 @@ class AudioWorkletGlobalScope final : public WorkletGlobalScope {
MOZ_CAN_RUN_SCRIPT
bool ConstructProcessor(const nsAString& aName,
NotNull<StructuredCloneHolder*> aSerializedOptions,
UniqueMessagePortId& aPortIdentifier,
JS::MutableHandle<JSObject*> aRetProcessor);
private:
@ -66,6 +69,10 @@ class AudioWorkletGlobalScope final : public WorkletGlobalScope {
typedef nsRefPtrHashtable<nsStringHashKey, AudioWorkletProcessorConstructor>
NodeNameToProcessorDefinitionMap;
NodeNameToProcessorDefinitionMap mNameToProcessorMap;
// https://webaudio.github.io/web-audio-api/#pending-processor-construction-data-transferred-port
// This does not need to be traversed during cycle-collection because it is
// only set while this AudioWorkletGlobalScope is on the stack.
RefPtr<MessagePort> mPortForProcessor;
};
} // namespace dom

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

@ -30,7 +30,8 @@ class WorkletNodeEngine final : public AudioNodeEngine {
MOZ_CAN_RUN_SCRIPT
void ConstructProcessor(AudioWorkletImpl* aWorkletImpl,
const nsAString& aName,
NotNull<StructuredCloneHolder*> aSerializedOptions);
NotNull<StructuredCloneHolder*> aSerializedOptions,
UniqueMessagePortId& aPortIdentifier);
void ProcessBlock(AudioNodeTrack* aTrack, GraphTime aFrom,
const AudioBlock& aInput, AudioBlock* aOutput,
@ -120,13 +121,15 @@ void WorkletNodeEngine::SendProcessorError() {
void WorkletNodeEngine::ConstructProcessor(
AudioWorkletImpl* aWorkletImpl, const nsAString& aName,
NotNull<StructuredCloneHolder*> aSerializedOptions) {
NotNull<StructuredCloneHolder*> aSerializedOptions,
UniqueMessagePortId& aPortIdentifier) {
MOZ_ASSERT(mInputs.mPorts.empty() && mOutputs.mPorts.empty());
RefPtr<AudioWorkletGlobalScope> global = aWorkletImpl->GetGlobalScope();
MOZ_ASSERT(global); // global has already been used to register processor
JS::RootingContext* cx = RootingCx();
mProcessor.init(cx);
if (!global->ConstructProcessor(aName, aSerializedOptions, &mProcessor) ||
if (!global->ConstructProcessor(aName, aSerializedOptions, aPortIdentifier,
&mProcessor) ||
// mInputs and mOutputs outer arrays are fixed length and so much of the
// initialization need only be performed once (i.e. here).
NS_WARN_IF(!mInputs.mPorts.growBy(InputCount())) ||
@ -501,11 +504,12 @@ already_AddRefed<AudioWorkletNode> AudioWorkletNode::Constructor(
// See bug 1535398.
[track = audioWorkletNode->mTrack,
workletImpl = RefPtr<AudioWorkletImpl>(workletImpl),
name = nsString(aName), options = std::move(serializedOptions)]()
MOZ_CAN_RUN_SCRIPT_BOUNDARY {
name = nsString(aName), options = std::move(serializedOptions),
portId = std::move(processorPortId)]()
MOZ_CAN_RUN_SCRIPT_BOUNDARY mutable {
auto engine = static_cast<WorkletNodeEngine*>(track->Engine());
engine->ConstructProcessor(workletImpl, name,
WrapNotNull(options.get()));
WrapNotNull(options.get()), portId);
}));
return audioWorkletNode.forget();