Commit 51fcef46 authored by Hongchan Choi's avatar Hongchan Choi Committed by Commit Bot

Use ErrorEvent for AudioWorkletNode.onprocessorerror

This is to catch up the spec change in AudioWorkletNode.onprocessorerror
event handler. The current implementation uses a regular Event object to
report an error, but the spec has changed to use a proper ErrorEvent.

The CL also cleaned up redundant modification in the test file,
which was caused by the previous revision.

Bug: 1064240
Test: external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-onerror.https.html
Change-Id: If7ac7eee96138ec0dbe02a3a046a5bdee27389db
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2168542Reviewed-by: default avatarRaymond Toy <rtoy@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#763506}
parent fd4f9adc
......@@ -7,6 +7,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_param_descriptor.h"
#include "third_party/blink/renderer/core/events/error_event.h"
#include "third_party/blink/renderer/core/messaging/message_channel.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/modules/event_modules.h"
......@@ -227,7 +228,7 @@ void AudioWorkletHandler::NotifyProcessorError(
if (!Context() || !Context()->GetExecutionContext() || !GetNode())
return;
static_cast<AudioWorkletNode*>(GetNode())->FireProcessorError();
static_cast<AudioWorkletNode*>(GetNode())->FireProcessorError(error_state);
}
// ----------------------------------------------------------------
......@@ -408,8 +409,27 @@ MessagePort* AudioWorkletNode::port() const {
return node_port_;
}
void AudioWorkletNode::FireProcessorError() {
DispatchEvent(*Event::Create(event_type_names::kProcessorerror));
void AudioWorkletNode::FireProcessorError(
AudioWorkletProcessorErrorState error_state) {
DCHECK(IsMainThread());
DCHECK(error_state == AudioWorkletProcessorErrorState::kConstructionError ||
error_state == AudioWorkletProcessorErrorState::kProcessError);
String error_message = "an error thrown from ";
switch (error_state) {
case AudioWorkletProcessorErrorState::kNoError:
NOTREACHED();
return;
case AudioWorkletProcessorErrorState::kConstructionError:
error_message = error_message + "AudioWorkletProcessor constructor";
break;
case AudioWorkletProcessorErrorState::kProcessError:
error_message = error_message + "AudioWorkletProcessor::process() method";
break;
}
ErrorEvent* event = ErrorEvent::Create(
error_message, SourceLocation::Capture(GetExecutionContext()), nullptr);
DispatchEvent(*event);
}
scoped_refptr<AudioWorkletHandler> AudioWorkletNode::GetWorkletHandler() const {
......
......@@ -118,9 +118,9 @@ class AudioWorkletNode final : public AudioNode,
// IDL
AudioParamMap* parameters() const;
MessagePort* port() const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(processorerror, kProcessorerror)
DEFINE_ATTRIBUTE_EVENT_LISTENER(processorerror, kError)
void FireProcessorError();
void FireProcessorError(AudioWorkletProcessorErrorState);
void Trace(Visitor*) override;
......
This is a testharness.js-based test.
PASS # AUDIT TASK RUNNER STARTED.
PASS Executing "constructor-error"
PASS Executing "process-error"
PASS Audit report
PASS > [constructor-error]
FAIL X onprocessorerror argument should be an ErrorEvent when
the constructor of AudioWorkletProcessor has
an error. is not true. Got false. assert_true: expected true got false
FAIL < [constructor-error] 1 out of 1 assertions were failed. assert_true: expected true got false
PASS > [process-error]
FAIL X onprocessorerror argument should be an ErrorEvent when
the process method of the AudioWorkletProcessor method
has an error is not true. Got false. assert_true: expected true got false
FAIL < [process-error] 1 out of 1 assertions were failed. assert_true: expected true got false
FAIL # AUDIT TASK RUNNER FINISHED: 2 out of 2 tasks were failed. assert_true: expected true got false
Harness: the test ran to completion.
......@@ -10,56 +10,51 @@
</head>
<body>
<script id="layout-test-code">
let audit = Audit.createTaskRunner();
const audit = Audit.createTaskRunner();
setup(() => {
const sampleRate = 48000;
const renderLength = sampleRate * 0.1;
let context = new OfflineAudioContext(1, renderLength, sampleRate);
const filePath = 'processors/error-processor.js';
const sampleRate = 48000;
const renderLength = sampleRate * 0.1;
const context = new OfflineAudioContext(1, renderLength, sampleRate);
let filePath = 'processors/error-processor.js';
// Test |onprocessorerror| called upon failure of processor constructor.
audit.define('constructor-error', (task, should) => {
const constructorErrorWorkletNode =
new AudioWorkletNode(context, 'constructor-error');
constructorErrorWorkletNode.onprocessorerror = (error) => {
should(error instanceof ErrorEvent,
`onprocessorerror argument should be an ErrorEvent when
the constructor of AudioWorkletProcessor has an error.`)
.beTrue();
// Test |onprocessorerror| called upon failure of processor constructor.
audit.define('constructor-error',
(task, should) => {
let constructorErrorWorkletNode =
new AudioWorkletNode(context, 'constructor-error');
constructorErrorWorkletNode.onprocessorerror = (e) => {
should(e instanceof ErrorEvent,
`onprocessorerror argument should be an ErrorEvent when
the constructor of AudioWorkletProcessor has
an error.`).beTrue();
// Without 'processorerror' event callback, this test will be
// timed out.
task.done();
};
});
// Without 'processorerror' event callback, this test will be
// timed out.
task.done();
};
});
// Test |onprocessorerror| called upon failure of process() method.
audit.define('process-error',
(task, should) => {
let processErrorWorkletNode =
new AudioWorkletNode(context, 'process-error');
processErrorWorkletNode.connect(context.destination);
processErrorWorkletNode.onprocessorerror = (e) => {
should(e instanceof ErrorEvent,
`onprocessorerror argument should be an ErrorEvent when
the process method of the AudioWorkletProcessor method
has an error`).beTrue();
// Without 'processorerror' event callback, this test will be
// timed out.
task.done();
};
// Test |onprocessorerror| called upon failure of process() method.
audit.define('process-error', (task, should) => {
const processErrorWorkletNode =
new AudioWorkletNode(context, 'process-error');
processErrorWorkletNode.onprocessorerror = (error) => {
should(error instanceof ErrorEvent,
`onprocessorerror argument should be an ErrorEvent when
the process method of the AudioWorkletProcessor method
has an error.`)
.beTrue();
context.startRendering();
});
// Without 'processorerror' event callback, this test will be
// timed out.
task.done();
};
// 'error-processor.js' contains 2 class definitions represents an error
// in the constructor and an error in the process method respectively.
context.audioWorklet.addModule(filePath).then(() => {
audit.run();
});
context.startRendering();
});
// 'error-processor.js' contains 2 class definitions represents an error
// in the constructor and an error in the process method respectively.
context.audioWorklet.addModule(filePath).then(() => audit.run());
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment