Diff
Modified: trunk/LayoutTests/ChangeLog (280957 => 280958)
--- trunk/LayoutTests/ChangeLog 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/LayoutTests/ChangeLog 2021-08-12 09:37:05 UTC (rev 280958)
@@ -1,3 +1,15 @@
+2021-08-12 Youenn Fablet <[email protected]>
+
+ Implement SFrameTransform error handling
+ https://bugs.webkit.org/show_bug.cgi?id=228947
+
+ Reviewed by Eric Carlson.
+
+ * http/wpt/webrtc/sframe-transform-error-worker.js: Added.
+ (onrtctransform.async event):
+ * http/wpt/webrtc/sframe-transform-error.html: Added.
+ * http/wpt/webrtc/sframe-transform-error-expected: Added.
+
2021-08-11 Lauro Moura <[email protected]>
[GLIB] Gardening a few failures and passes
Added: trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error-expected.txt (0 => 280958)
--- trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error-expected.txt 2021-08-12 09:37:05 UTC (rev 280958)
@@ -0,0 +1,5 @@
+
+
+PASS Missing key triggers an error that can be corrected by adding a key
+PASS Tampered data should trigger SFrameTransform errors
+
Added: trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error-worker.js (0 => 280958)
--- trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error-worker.js (rev 0)
+++ trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error-worker.js 2021-08-12 09:37:05 UTC (rev 280958)
@@ -0,0 +1,32 @@
+let triggerError;
+_onmessage_ = (event) => triggerError = event.data.action;
+
+_onrtctransform_ = async (event) => {
+ const transformer = event.transformer;
+
+ const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+ const sframeTransform = new SFrameTransform({ role: "encrypt", authenticationSize: "4" });
+ sframeTransform.setEncryptionKey(key, 1);
+
+ const postTransform = new TransformStream({transform: (frame, controller) => {
+ if (triggerError === "authenticationError") {
+ const data = "" Uint8Array(frame.data);
+ // We change the authentication tag.
+ data[data.byteLength - 1] = !data[data.byteLength - 1];
+ frame.data = ""
+ } else if (triggerError === "syntaxError") {
+ const data = "" Uint8Array(frame.data);
+ // We set the signature bit.
+ data[0] = 255;
+ frame.data = ""
+ }
+ triggerError = undefined;
+ controller.enqueue(frame);
+ }});
+
+ transformer.readable.pipeThrough(sframeTransform)
+ .pipeThrough(postTransform)
+ .pipeTo(transformer.writable);
+}
+self.postMessage("registered");
+
Added: trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error.html (0 => 280958)
--- trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error.html (rev 0)
+++ trunk/LayoutTests/http/wpt/webrtc/sframe-transform-error.html 2021-08-12 09:37:05 UTC (rev 280958)
@@ -0,0 +1,92 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script src=""
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <video id='video' controls autoplay playsinline></video>
+ <script>
+promise_test(async (test) => {
+ const key1 = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+ const key2 = await crypto.subtle.importKey("raw", new Uint8Array([144, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+ const key3 = await crypto.subtle.importKey("raw", new Uint8Array([145, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+ const key4 = await crypto.subtle.importKey("raw", new Uint8Array([146, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+
+ const localStream = await navigator.mediaDevices.getUserMedia({audio: true});
+ let receiver;
+ const stream = await new Promise((resolve, reject) => {
+ const connections = createConnections(test, (firstConnection) => {
+ const sender = firstConnection.addTrack(localStream.getAudioTracks()[0], localStream);
+ const transform = new SFrameTransform;
+ transform.setEncryptionKey(key1, 1);
+ sender.transform = transform;
+ }, (secondConnection) => {
+ secondConnection._ontrack_ = (trackEvent) => {
+ const transform = new SFrameTransform;
+ transform.setEncryptionKey(key1, 0);
+ receiver = trackEvent.receiver;
+ receiver.transform = transform;
+ resolve(trackEvent.streams[0]);
+ };
+ });
+ test.step_timeout(() => reject("Test timed out"), 5000);
+ });
+
+ let error = await new Promise(resolve => receiver.transform._onerror_ = resolve);
+ assert_equals(error.errorType, "keyID");
+ receiver.transform.setEncryptionKey(key1, 1);
+
+ await new Promise((resolve, reject) => {
+ receiver.transform._onerror_ = () => reject('sframe still has errors');
+ test.step_timeout(resolve, 100);
+ });
+}, "Missing key triggers an error that can be corrected by adding a key");
+
+promise_test(async (test) => {
+ worker = new Worker('sframe-transform-error-worker.js');
+ const data = "" new Promise(resolve => worker._onmessage_ = (event) => resolve(event.data));
+ assert_equals(data, "registered");
+ const localStream = await navigator.mediaDevices.getUserMedia({ audio: true });
+
+ let sender, receiver;
+
+ const receiverTransform = new SFrameTransform();
+ const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+ receiverTransform.setEncryptionKey(key, 1);
+
+ const senderTransform = new RTCRtpScriptTransform(worker, "SFrameRTCRtpTransform");
+
+ const startedPromise = new Promise(resolve => worker._onmessage_ = (event) => resolve(event.data));
+
+ const remoteStream = await new Promise((resolve, reject) => {
+ createConnections(test, (firstConnection) => {
+ pc1 = firstConnection;
+ sender = firstConnection.addTrack(localStream.getTracks()[0], localStream);
+ sender.transform = senderTransform;
+ }, (secondConnection) => {
+ pc2 = secondConnection;
+ secondConnection._ontrack_ = (trackEvent) => {
+ receiver = trackEvent.receiver;
+ receiver.transform = receiverTransform;
+ resolve(trackEvent.streams[0]);
+ };
+ });
+ test.step_timeout(() => reject("Test timed out"), 5000);
+ });
+
+ video.srcObject = remoteStream;
+
+ worker.postMessage({action:"authenticationError"});
+ let error = await new Promise(resolve => receiver.transform._onerror_ = resolve);
+ assert_equals(error.errorType, "authentication");
+
+ worker.postMessage({action:"syntaxError"});
+ error = await new Promise(resolve => receiver.transform._onerror_ = resolve);
+ assert_equals(error.errorType, "syntax");
+}, "Tampered data should trigger SFrameTransform errors");
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/CMakeLists.txt (280957 => 280958)
--- trunk/Source/WebCore/CMakeLists.txt 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/CMakeLists.txt 2021-08-12 09:37:05 UTC (rev 280958)
@@ -412,6 +412,7 @@
Modules/mediastream/RTCRtpReceiver.idl
Modules/mediastream/RTCRtpRtxParameters.idl
Modules/mediastream/RTCRtpSFrameTransform.idl
+ Modules/mediastream/RTCRtpSFrameTransformErrorEvent.idl
Modules/mediastream/RTCRtpScriptTransform.idl
Modules/mediastream/RTCRtpScriptTransformProvider.idl
Modules/mediastream/RTCRtpScriptTransformer.idl
Modified: trunk/Source/WebCore/ChangeLog (280957 => 280958)
--- trunk/Source/WebCore/ChangeLog 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/ChangeLog 2021-08-12 09:37:05 UTC (rev 280958)
@@ -1,3 +1,52 @@
+2021-08-12 Youenn Fablet <[email protected]>
+
+ Implement SFrameTransform error handling
+ https://bugs.webkit.org/show_bug.cgi?id=228947
+
+ Reviewed by Eric Carlson.
+
+ Add support for RTCRtpSFrameTransformErrorEvent.
+ When RTCRtpSFrameTransformer encounters an issue, dispatch a task to RTCRtpSFrameTransform context and fire a corresponding event.
+ This follows https://w3c.github.io/webrtc-encoded-transform/#sframe-transform-algorithm, except that:
+ - we are not yet exposing some fields in RTCRtpSFrameTransformErrorEvent.
+ - we are using errorType instead of type which should be fixed in the spec.
+
+ Test: imported/w3c/web-platform-tests/webrtc-encoded-transform/sframe-transform-error.html
+
+ * CMakeLists.txt:
+ * DerivedSources-input.xcfilelist:
+ * DerivedSources-output.xcfilelist:
+ * DerivedSources.make:
+ * Modules/mediastream/RTCRtpSFrameTransform.cpp:
+ (WebCore::RTCRtpSFrameTransform::RTCRtpSFrameTransform):
+ (WebCore::errorTypeFromInformation):
+ (WebCore::processFrame):
+ (WebCore::RTCRtpSFrameTransform::hasKey const):
+ (WebCore::RTCRtpSFrameTransform::initializeTransformer):
+ (WebCore::transformFrame):
+ (WebCore::RTCRtpSFrameTransform::createStreams):
+ (WebCore::RTCRtpSFrameTransform::writable):
+ (WebCore::RTCRtpSFrameTransform::virtualHasPendingActivity const):
+ * Modules/mediastream/RTCRtpSFrameTransform.h:
+ * Modules/mediastream/RTCRtpSFrameTransform.idl:
+ * Modules/mediastream/RTCRtpSFrameTransformErrorEvent.cpp: Added.
+ (WebCore::RTCRtpSFrameTransformErrorEvent::create):
+ (WebCore::RTCRtpSFrameTransformErrorEvent::RTCRtpSFrameTransformErrorEvent):
+ (WebCore::RTCRtpSFrameTransformErrorEvent::eventInterface const):
+ * Modules/mediastream/RTCRtpSFrameTransformErrorEvent.h: Added.
+ * Modules/mediastream/RTCRtpSFrameTransformErrorEvent.idl: Added.
+ * Modules/mediastream/RTCRtpSFrameTransformer.cpp:
+ (WebCore::RTCRtpSFrameTransformer::hasKey const):
+ (WebCore::RTCRtpSFrameTransformer::decryptFrame):
+ (WebCore::RTCRtpSFrameTransformer::encryptFrame):
+ (WebCore::RTCRtpSFrameTransformer::transform):
+ * Modules/mediastream/RTCRtpSFrameTransformer.h:
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/WebCoreBuiltinNames.h:
+ * dom/EventNames.in:
+ * dom/EventTargetFactory.in:
+
2021-08-11 Alex Christensen <[email protected]>
Remove optimistic assertion added in r280931
Modified: trunk/Source/WebCore/DerivedSources-input.xcfilelist (280957 => 280958)
--- trunk/Source/WebCore/DerivedSources-input.xcfilelist 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/DerivedSources-input.xcfilelist 2021-08-12 09:37:05 UTC (rev 280958)
@@ -256,6 +256,7 @@
$(PROJECT_DIR)/Modules/mediastream/RTCRtpReceiver.idl
$(PROJECT_DIR)/Modules/mediastream/RTCRtpRtxParameters.idl
$(PROJECT_DIR)/Modules/mediastream/RTCRtpSFrameTransform.idl
+$(PROJECT_DIR)/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.idl
$(PROJECT_DIR)/Modules/mediastream/RTCRtpScriptTransform.idl
$(PROJECT_DIR)/Modules/mediastream/RTCRtpScriptTransformProvider.idl
$(PROJECT_DIR)/Modules/mediastream/RTCRtpScriptTransformer.idl
Modified: trunk/Source/WebCore/DerivedSources-output.xcfilelist (280957 => 280958)
--- trunk/Source/WebCore/DerivedSources-output.xcfilelist 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/DerivedSources-output.xcfilelist 2021-08-12 09:37:05 UTC (rev 280958)
@@ -1697,6 +1697,8 @@
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpRtxParameters.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpSFrameTransform.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpSFrameTransform.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpSFrameTransformErrorEvent.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpSFrameTransformErrorEvent.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpScriptTransform.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpScriptTransform.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRTCRtpScriptTransformProvider.cpp
Modified: trunk/Source/WebCore/DerivedSources.make (280957 => 280958)
--- trunk/Source/WebCore/DerivedSources.make 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/DerivedSources.make 2021-08-12 09:37:05 UTC (rev 280958)
@@ -283,6 +283,7 @@
$(WebCore)/Modules/mediastream/RTCRtpSender.idl \
$(WebCore)/Modules/mediastream/RTCRtpSender+Transform.idl \
$(WebCore)/Modules/mediastream/RTCRtpSFrameTransform.idl \
+ $(WebCore)/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.idl \
$(WebCore)/Modules/mediastream/RTCRtpScriptTransform.idl \
$(WebCore)/Modules/mediastream/RTCRtpScriptTransformProvider.idl \
$(WebCore)/Modules/mediastream/RTCRtpScriptTransformer.idl \
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp (280957 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp 2021-08-12 09:37:05 UTC (rev 280958)
@@ -35,6 +35,7 @@
#include "Logging.h"
#include "RTCEncodedAudioFrame.h"
#include "RTCEncodedVideoFrame.h"
+#include "RTCRtpSFrameTransformErrorEvent.h"
#include "RTCRtpSFrameTransformer.h"
#include "RTCRtpTransformBackend.h"
#include "RTCRtpTransformableFrame.h"
@@ -43,13 +44,18 @@
#include "SharedBuffer.h"
#include "WritableStream.h"
#include "WritableStreamSink.h"
+#include <wtf/IsoMallocInlines.h>
namespace WebCore {
+WTF_MAKE_ISO_ALLOCATED_IMPL(RTCRtpSFrameTransform);
+
RTCRtpSFrameTransform::RTCRtpSFrameTransform(ScriptExecutionContext& context, Options options)
- : ContextDestructionObserver(&context)
+ : ActiveDOMObject(&context)
, m_transformer(RTCRtpSFrameTransformer::create(options.compatibilityMode))
{
+ suspendIfNeeded();
+
m_transformer->setIsEncrypting(options.role == Role::Encrypt);
m_transformer->setAuthenticationSize(options.authenticationSize);
}
@@ -95,10 +101,53 @@
return m_isAttached || (m_readable && m_readable->isLocked()) || (m_writable && m_writable->isLocked());
}
+static RTCRtpSFrameTransformErrorEvent::Type errorTypeFromInformation(const RTCRtpSFrameTransformer::ErrorInformation& errorInformation)
+{
+ switch (errorInformation.error) {
+ case RTCRtpSFrameTransformer::Error::KeyID:
+ return RTCRtpSFrameTransformErrorEvent::Type::KeyID;
+ case RTCRtpSFrameTransformer::Error::Authentication:
+ return RTCRtpSFrameTransformErrorEvent::Type::Authentication;
+ case RTCRtpSFrameTransformer::Error::Syntax:
+ return RTCRtpSFrameTransformErrorEvent::Type::Syntax;
+ case RTCRtpSFrameTransformer::Error::Other:
+ return RTCRtpSFrameTransformErrorEvent::Type::Other;
+ }
+}
+
+static std::optional<Vector<uint8_t>> processFrame(const uint8_t* data, size_t size, RTCRtpSFrameTransformer& transformer, ScriptExecutionContextIdentifier identifier, const WeakPtr<RTCRtpSFrameTransform>& weakTransform)
+{
+ auto result = transformer.transform(data, size);
+ if (!result.has_value()) {
+ auto errorInformation = WTFMove(result.error());
+ errorInformation.message = { };
+ RELEASE_LOG_ERROR(WebRTC, "RTCRtpSFrameTransform failed transforming a frame with error %d", errorInformation.error);
+ // Call the error event handler.
+ ScriptExecutionContext::postTaskTo(identifier, [errorInformation, weakTransform](auto&&) {
+ if (!weakTransform || weakTransform->isContextStopped())
+ return;
+ if (errorInformation.error == RTCRtpSFrameTransformer::Error::KeyID && weakTransform->hasKey(errorInformation.keyId))
+ return;
+ weakTransform->dispatchEvent(RTCRtpSFrameTransformErrorEvent::create(Event::CanBubble::No, Event::IsCancelable::No, errorTypeFromInformation(errorInformation)));
+ });
+ return { };
+ }
+ return WTFMove(result.value());
+}
+
+bool RTCRtpSFrameTransform::hasKey(uint64_t keyID) const
+{
+ return m_transformer->hasKey(keyID);
+}
+
void RTCRtpSFrameTransform::initializeTransformer(RTCRtpTransformBackend& backend, Side side)
{
ASSERT(!isAttached());
+ auto* context = scriptExecutionContext();
+ if (!context)
+ return;
+
m_isAttached = true;
if (m_readable)
m_readable->lock();
@@ -108,16 +157,16 @@
m_transformer->setIsEncrypting(side == Side::Sender);
m_transformer->setMediaType(backend.mediaType());
- backend.setTransformableFrameCallback([transformer = m_transformer, backend = makeRef(backend)](auto&& frame) {
+ backend.setTransformableFrameCallback([transformer = m_transformer, identifier = context->contextIdentifier(), backend = makeRef(backend), weakThis = makeWeakPtr(this)](auto&& frame) {
auto chunk = frame->data();
- auto result = transformer->transform(chunk.data, chunk.size);
+ if (!chunk.data || !chunk.size)
+ return;
+ auto result = processFrame(chunk.data, chunk.size, transformer.get(), identifier, weakThis);
- if (result.hasException()) {
- RELEASE_LOG_ERROR(WebRTC, "RTCRtpSFrameTransform failed transforming a frame");
+ if (!result)
return;
- }
- frame->setData({ result.returnValue().data(), result.returnValue().size() });
+ frame->setData({ result.value().data(), result.value().size() });
backend->processTransformedFrame(frame.get());
});
@@ -138,31 +187,25 @@
backend.clearTransformableFrameCallback();
}
+static void transformFrame(const uint8_t* data, size_t size, JSDOMGlobalObject& globalObject, RTCRtpSFrameTransformer& transformer, SimpleReadableStreamSource& source, ScriptExecutionContextIdentifier identifier, const WeakPtr<RTCRtpSFrameTransform>& weakTransform)
+{
+ auto result = processFrame(data, size, transformer, identifier, weakTransform);
+ auto buffer = result ? SharedBuffer::create(WTFMove(*result)) : SharedBuffer::create();
+ source.enqueue(toJS(&globalObject, &globalObject, buffer->tryCreateArrayBuffer().get()));
+}
+
template<typename Frame>
-void transformFrame(Frame& frame, JSDOMGlobalObject& globalObject, RTCRtpSFrameTransformer& transformer, SimpleReadableStreamSource& source)
+void transformFrame(Frame& frame, JSDOMGlobalObject& globalObject, RTCRtpSFrameTransformer& transformer, SimpleReadableStreamSource& source, ScriptExecutionContextIdentifier identifier, const WeakPtr<RTCRtpSFrameTransform>& weakTransform)
{
auto chunk = frame.rtcFrame().data();
- auto result = transformer.transform(chunk.data, chunk.size);
- RELEASE_LOG_ERROR_IF(result.hasException(), WebRTC, "RTCRtpSFrameTransform failed transforming a frame");
-
+ auto result = processFrame(chunk.data, chunk.size, transformer, identifier, weakTransform);
RTCRtpTransformableFrame::Data transformedChunk;
- // In case of error, we just pass along the frame with empty data.
- if (!result.hasException())
- transformedChunk = { result.returnValue().data(), result.returnValue().size() };
-
+ if (result)
+ transformedChunk = { result->data(), result->size() };
frame.rtcFrame().setData(transformedChunk);
source.enqueue(toJS(&globalObject, &globalObject, frame));
}
-static void transformFrame(const uint8_t* data, size_t size, JSDOMGlobalObject& globalObject, RTCRtpSFrameTransformer& transformer, SimpleReadableStreamSource& source)
-{
- auto result = transformer.transform(data, size);
- RELEASE_LOG_ERROR_IF(result.hasException(), WebRTC, "RTCRtpSFrameTransform failed transforming a frame");
-
- auto buffer = result.hasException() ? SharedBuffer::create() : SharedBuffer::create(result.releaseReturnValue());
- source.enqueue(toJS(&globalObject, &globalObject, buffer->tryCreateArrayBuffer().get()));
-}
-
void RTCRtpSFrameTransform::createStreams(JSC::JSGlobalObject& globalObject)
{
m_readableStreamSource = SimpleReadableStreamSource::create();
@@ -170,7 +213,7 @@
if (readable.hasException())
return;
- auto writable = WritableStream::create(globalObject, SimpleWritableStreamSink::create([transformer = m_transformer, readableStreamSource = m_readableStreamSource](auto& context, auto value) -> ExceptionOr<void> {
+ auto writable = WritableStream::create(globalObject, SimpleWritableStreamSink::create([transformer = m_transformer, readableStreamSource = m_readableStreamSource, weakThis = makeWeakPtr(this)](auto& context, auto value) -> ExceptionOr<void> {
if (!context.globalObject())
return Exception { InvalidStateError };
auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(context.globalObject());
@@ -182,13 +225,13 @@
// We do not want to throw any exception in the transform to make sure we do not error the transform.
WTF::switchOn(frame, [&](RefPtr<RTCEncodedAudioFrame>& value) {
- transformFrame(*value, globalObject, transformer.get(), *readableStreamSource);
+ transformFrame(*value, globalObject, transformer.get(), *readableStreamSource, context.contextIdentifier(), weakThis);
}, [&](RefPtr<RTCEncodedVideoFrame>& value) {
- transformFrame(*value, globalObject, transformer.get(), *readableStreamSource);
+ transformFrame(*value, globalObject, transformer.get(), *readableStreamSource, context.contextIdentifier(), weakThis);
}, [&](RefPtr<ArrayBuffer>& value) {
- transformFrame(static_cast<const uint8_t*>(value->data()), value->byteLength(), globalObject, transformer.get(), *readableStreamSource);
+ transformFrame(static_cast<const uint8_t*>(value->data()), value->byteLength(), globalObject, transformer.get(), *readableStreamSource, context.contextIdentifier(), weakThis);
}, [&](RefPtr<ArrayBufferView>& value) {
- transformFrame(static_cast<const uint8_t*>(value->data()), value->byteLength(), globalObject, transformer.get(), *readableStreamSource);
+ transformFrame(static_cast<const uint8_t*>(value->data()), value->byteLength(), globalObject, transformer.get(), *readableStreamSource, context.contextIdentifier(), weakThis);
});
return { };
}));
@@ -232,9 +275,15 @@
if (!m_writable)
createStreams(*globalObject);
+ m_hasWritable = true;
return m_writable.copyRef();
}
+bool RTCRtpSFrameTransform::virtualHasPendingActivity() const
+{
+ return (m_isAttached || m_hasWritable) && hasEventListeners();
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_RTC)
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h (280957 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h 2021-08-12 09:37:05 UTC (rev 280958)
@@ -27,9 +27,11 @@
#if ENABLE(WEB_RTC)
-#include "ContextDestructionObserver.h"
+#include "ActiveDOMObject.h"
+#include "EventTarget.h"
#include "JSDOMPromiseDeferred.h"
#include "RTCRtpSFrameTransformer.h"
+#include <wtf/WeakPtr.h>
namespace JSC {
class JSGlobalObject;
@@ -43,7 +45,8 @@
class SimpleReadableStreamSource;
class WritableStream;
-class RTCRtpSFrameTransform : public RefCounted<RTCRtpSFrameTransform>, private ContextDestructionObserver {
+class RTCRtpSFrameTransform : public RefCounted<RTCRtpSFrameTransform>, public ActiveDOMObject, public EventTargetWithInlineData {
+ WTF_MAKE_ISO_ALLOCATED(RTCRtpSFrameTransform);
public:
enum class Role { Encrypt, Decrypt };
using CompatibilityMode = RTCRtpSFrameTransformer::CompatibilityMode;
@@ -70,14 +73,30 @@
ExceptionOr<RefPtr<ReadableStream>> readable();
ExceptionOr<RefPtr<WritableStream>> writable();
+ bool hasKey(uint64_t) const;
+
+ using RefCounted<RTCRtpSFrameTransform>::ref;
+ using RefCounted<RTCRtpSFrameTransform>::deref;
+
private:
RTCRtpSFrameTransform(ScriptExecutionContext&, Options);
+ // ActiveDOMObject
+ const char* activeDOMObjectName() const final { return "RTCRtpSFrameTransform"; }
+ bool virtualHasPendingActivity() const final;
+
+ // EventTargetWithInlineData
+ EventTargetInterface eventTargetInterface() const final { return RTCRtpSFrameTransformEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
+
enum class Side { Sender, Receiver };
void initializeTransformer(RTCRtpTransformBackend&, Side);
void createStreams(JSC::JSGlobalObject&);
bool m_isAttached { false };
+ bool m_hasWritable { false };
Ref<RTCRtpSFrameTransformer> m_transformer;
RefPtr<ReadableStream> m_readable;
RefPtr<WritableStream> m_writable;
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl (280957 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl 2021-08-12 09:37:05 UTC (rev 280958)
@@ -41,6 +41,7 @@
};
[
+ ActiveDOMObject,
Conditional=WEB_RTC,
EnabledBySetting=WebRTCInsertableStreams,
ExportMacro=WEBCORE_EXPORT,
@@ -47,7 +48,7 @@
Exposed=(Window,DedicatedWorker),
InterfaceName=SFrameTransform,
JSGenerateToNativeObject,
-] interface RTCRtpSFrameTransform {
+] interface RTCRtpSFrameTransform : EventTarget {
[CallWith=ScriptExecutionContext] constructor(optional RTCRtpSFrameTransformOptions options);
[Custom] Promise<undefined> setEncryptionKey(CryptoKey key, optional any keyID);
@@ -57,4 +58,6 @@
readonly attribute ReadableStream readable;
readonly attribute WritableStream writable;
+
+ attribute EventHandler onerror;
};
Added: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.cpp (0 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.cpp 2021-08-12 09:37:05 UTC (rev 280958)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RTCRtpSFrameTransformErrorEvent.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "EventNames.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(RTCRtpSFrameTransformErrorEvent);
+
+Ref<RTCRtpSFrameTransformErrorEvent> RTCRtpSFrameTransformErrorEvent::create(CanBubble canBubble, IsCancelable isCancelable, Type errorType)
+{
+ return adoptRef(*new RTCRtpSFrameTransformErrorEvent(eventNames().errorEvent, canBubble, isCancelable, errorType));
+}
+
+Ref<RTCRtpSFrameTransformErrorEvent> RTCRtpSFrameTransformErrorEvent::create(const AtomString& type, Init&& init)
+{
+ return adoptRef(*new RTCRtpSFrameTransformErrorEvent(type, init.bubbles ? CanBubble::Yes : CanBubble::No,
+ init.cancelable ? IsCancelable::Yes : IsCancelable::No, init.errorType));
+}
+
+RTCRtpSFrameTransformErrorEvent::RTCRtpSFrameTransformErrorEvent(const AtomString& type, CanBubble canBubble, IsCancelable cancelable, Type errorType)
+ : Event(type, canBubble, cancelable)
+ , m_errorType(errorType)
+{
+}
+
+RTCRtpSFrameTransformErrorEvent::~RTCRtpSFrameTransformErrorEvent() = default;
+
+EventInterface RTCRtpSFrameTransformErrorEvent::eventInterface() const
+{
+ return RTCRtpSFrameTransformErrorEventInterfaceType;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
Copied: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.h (from rev 280957, trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl) (0 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.h (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.h 2021-08-12 09:37:05 UTC (rev 280958)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "Event.h"
+
+namespace WebCore {
+
+class RTCRtpSFrameTransformErrorEvent final : public Event {
+ WTF_MAKE_ISO_ALLOCATED(RTCRtpSFrameTransformErrorEvent);
+public:
+ virtual ~RTCRtpSFrameTransformErrorEvent();
+
+ enum Type { Authentication, KeyID, Other, Syntax };
+
+ struct Init : EventInit {
+ Type errorType;
+ };
+
+ static Ref<RTCRtpSFrameTransformErrorEvent> create(const AtomString& type, Init&&);
+ static Ref<RTCRtpSFrameTransformErrorEvent> create(CanBubble, IsCancelable, Type);
+
+ Type errorType() const { return m_errorType; }
+
+ virtual EventInterface eventInterface() const;
+
+private:
+ RTCRtpSFrameTransformErrorEvent(const AtomString& type, CanBubble, IsCancelable, Type);
+
+ Type m_errorType;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
Copied: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.idl (from rev 280957, trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl) (0 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.idl (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformErrorEvent.idl 2021-08-12 09:37:05 UTC (rev 280958)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+enum RTCRtpSFrameTransformErrorEventType {
+ "authentication",
+ "keyID",
+ "other",
+ "syntax"
+};
+
+dictionary RTCRtpSFrameTransformErrorEventInit : EventInit {
+ required RTCRtpSFrameTransformErrorEventType errorType;
+};
+
+[
+ Conditional=WEB_RTC,
+ EnabledBySetting=WebRTCInsertableStreams,
+ Exposed=(Window,DedicatedWorker),
+ InterfaceName=SFrameTransformErrorEvent
+] interface RTCRtpSFrameTransformErrorEvent : Event {
+ constructor(DOMString type, RTCRtpSFrameTransformErrorEventInit eventInitDict);
+
+ readonly attribute RTCRtpSFrameTransformErrorEventType errorType;
+ // FIXME: Add below fields
+ // readonly attribute CryptoKeyID? keyID;
+ // readonly attribute any frame;
+};
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp (280957 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp 2021-08-12 09:37:05 UTC (rev 280958)
@@ -29,6 +29,7 @@
#if ENABLE(WEB_RTC)
#include "SFrameUtils.h"
+#include <wtf/Algorithms.h>
namespace WebCore {
@@ -160,6 +161,12 @@
return updateEncryptionKey(rawKey, keyId, ShouldUpdateKeys::Yes);
}
+bool RTCRtpSFrameTransformer::hasKey(uint64_t keyId) const
+{
+ Locker locker { m_keyLock };
+ return WTF::anyOf(m_keys, [keyId](auto& key) { return keyId == key.keyId; });
+}
+
ExceptionOr<void> RTCRtpSFrameTransformer::updateEncryptionKey(const Vector<uint8_t>& rawKey, std::optional<uint64_t> keyId, ShouldUpdateKeys shouldUpdateKeys)
{
ASSERT(m_keyLock.isLocked());
@@ -199,7 +206,7 @@
return { };
}
-ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::decryptFrame(const uint8_t* frameData, size_t frameSize)
+RTCRtpSFrameTransformer::TransformResult RTCRtpSFrameTransformer::decryptFrame(const uint8_t* frameData, size_t frameSize)
{
Vector<uint8_t> buffer;
switch (m_compatibilityMode) {
@@ -229,23 +236,23 @@
auto header = parseSFrameHeader(frameData, frameSize);
if (!header)
- return Exception { NotSupportedError };
+ return makeUnexpected(ErrorInformation {Error::Syntax, "Invalid header"_s, 0 });
if (header->counter <= m_counter && m_counter)
- return Exception { InvalidStateError };
+ return makeUnexpected(ErrorInformation {Error::Syntax, "Invalid counter"_s, 0 });
m_counter = header->counter;
if (header->keyId != m_keyId) {
auto position = m_keys.findMatching([keyId = header->keyId](auto& item) { return item.keyId == keyId; });
if (position == notFound)
- return Exception { DataError, "Key ID is unknown" };
+ return makeUnexpected(ErrorInformation { Error::KeyID, "Key ID is unknown"_s, header->keyId });
auto result = updateEncryptionKey(m_keys[position].keyData, header->keyId, ShouldUpdateKeys::No);
if (result.hasException())
- return result.releaseException();
+ return makeUnexpected(ErrorInformation {Error::Other, result.exception().message(), 0 });
}
if (frameSize < (header->size + m_authenticationSize))
- return Exception { DataError, "Chunk is too small for authentication size" };
+ return makeUnexpected(ErrorInformation { Error::Syntax, "Chunk is too small for authentication size"_s, 0 });
auto iv = computeIV(m_counter, m_saltKey);
@@ -255,7 +262,7 @@
for (size_t cptr = 0; cptr < m_authenticationSize; ++cptr) {
if (signature[cptr] != transmittedSignature[cptr]) {
// FIXME: We should try ratcheting.
- return Exception { NotSupportedError };
+ return makeUnexpected(ErrorInformation { Error::Authentication, "Authentication failed"_s, 0 });
}
}
@@ -264,12 +271,12 @@
auto result = decryptData(frameData + header->size, dataSize, iv, m_encryptionKey);
if (result.hasException())
- return result.releaseException();
+ return makeUnexpected(ErrorInformation { Error::Other, result.exception().message(), 0 });
return result.releaseReturnValue();
}
-ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::encryptFrame(const uint8_t* frameData, size_t frameSize)
+RTCRtpSFrameTransformer::TransformResult RTCRtpSFrameTransformer::encryptFrame(const uint8_t* frameData, size_t frameSize)
{
static const unsigned MaxHeaderSize = 17;
@@ -314,7 +321,7 @@
auto encryptedData = encryptData(frameData, frameSize, iv, m_encryptionKey);
ASSERT(!encryptedData.hasException());
if (encryptedData.hasException())
- return encryptedData.releaseException();
+ return makeUnexpected(ErrorInformation { Error::Other, encryptedData.exception().message(), 0 });
std::memcpy(newDataPointer + headerSize, encryptedData.returnValue().data(), frameSize);
@@ -330,10 +337,10 @@
return transformedData;
}
-ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::transform(const uint8_t* data, size_t size)
+RTCRtpSFrameTransformer::TransformResult RTCRtpSFrameTransformer::transform(const uint8_t* data, size_t size)
{
if (!m_hasKey)
- return Exception { InvalidStateError, "Key is not initialized"_s };
+ return makeUnexpected(ErrorInformation { Error::KeyID, "Key is not initialized", 0 });
return m_isEncrypting ? encryptFrame(data, size) : decryptFrame(data, size);
}
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h (280957 => 280958)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h 2021-08-12 09:37:05 UTC (rev 280958)
@@ -48,8 +48,16 @@
void setMediaType(RTCRtpTransformBackend::MediaType);
WEBCORE_EXPORT ExceptionOr<void> setEncryptionKey(const Vector<uint8_t>& rawKey, std::optional<uint64_t>);
- WEBCORE_EXPORT ExceptionOr<Vector<uint8_t>> transform(const uint8_t*, size_t);
+ enum class Error { KeyID, Authentication, Syntax, Other };
+ struct ErrorInformation {
+ Error error;
+ String message;
+ uint64_t keyId { 0 };
+ };
+ using TransformResult = Expected<Vector<uint8_t>, ErrorInformation>;
+ WEBCORE_EXPORT TransformResult transform(const uint8_t*, size_t);
+
const Vector<uint8_t>& authenticationKey() const { return m_authenticationKey; }
const Vector<uint8_t>& encryptionKey() const { return m_encryptionKey; }
const Vector<uint8_t>& saltKey() const { return m_saltKey; }
@@ -58,11 +66,13 @@
uint64_t counter() const { return m_counter; }
void setCounter(uint64_t counter) { m_counter = counter; }
+ bool hasKey(uint64_t) const;
+
private:
WEBCORE_EXPORT explicit RTCRtpSFrameTransformer(CompatibilityMode);
- ExceptionOr<Vector<uint8_t>> decryptFrame(const uint8_t*, size_t);
- ExceptionOr<Vector<uint8_t>> encryptFrame(const uint8_t*, size_t);
+ TransformResult decryptFrame(const uint8_t*, size_t);
+ TransformResult encryptFrame(const uint8_t*, size_t);
enum class ShouldUpdateKeys { No, Yes };
ExceptionOr<void> updateEncryptionKey(const Vector<uint8_t>& rawKey, std::optional<uint64_t>, ShouldUpdateKeys = ShouldUpdateKeys::Yes) WTF_REQUIRES_LOCK(m_keyLock);
@@ -76,7 +86,7 @@
Vector<uint8_t> computeEncryptedDataSignature(const Vector<uint8_t>& nonce, const uint8_t* header, size_t headerSize, const uint8_t* data, size_t dataSize, const Vector<uint8_t>& key);
void updateAuthenticationSize();
- Lock m_keyLock;
+ mutable Lock m_keyLock;
bool m_hasKey { false };
Vector<uint8_t> m_authenticationKey;
Vector<uint8_t> m_encryptionKey;
Modified: trunk/Source/WebCore/Sources.txt (280957 => 280958)
--- trunk/Source/WebCore/Sources.txt 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/Sources.txt 2021-08-12 09:37:05 UTC (rev 280958)
@@ -171,6 +171,7 @@
Modules/mediastream/RTCPeerConnectionIceErrorEvent.cpp
Modules/mediastream/RTCRtpReceiver.cpp
Modules/mediastream/RTCRtpSFrameTransform.cpp
+Modules/mediastream/RTCRtpSFrameTransformErrorEvent.cpp
Modules/mediastream/RTCRtpSFrameTransformer.cpp
Modules/mediastream/RTCRtpScriptTransform.cpp
Modules/mediastream/RTCRtpScriptTransformer.cpp
@@ -3326,6 +3327,7 @@
JSRTCRtpReceiver.cpp
JSRTCRtpRtxParameters.cpp
JSRTCRtpSFrameTransform.cpp
+JSRTCRtpSFrameTransformErrorEvent.cpp
JSRTCRtpScriptTransform.cpp
JSRTCRtpScriptTransformer.cpp
JSRTCRtpSendParameters.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (280957 => 280958)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-08-12 09:37:05 UTC (rev 280958)
@@ -7986,6 +7986,9 @@
41B2A6251EF1BF60002B9D7A /* WebAudioSourceProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebAudioSourceProvider.h; sourceTree = "<group>"; };
41B459DA1F4CADB90000F6FD /* ReadableStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStream.h; sourceTree = "<group>"; };
41B459ED1F55EBC70000F6FD /* ReadableStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReadableStream.cpp; sourceTree = "<group>"; };
+ 41B6AA4F26B995F800AADFA7 /* RTCRtpSFrameTransformErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCRtpSFrameTransformErrorEvent.h; sourceTree = "<group>"; };
+ 41B6AA5126B995F800AADFA7 /* RTCRtpSFrameTransformErrorEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCRtpSFrameTransformErrorEvent.idl; sourceTree = "<group>"; };
+ 41B6AA5226B995F900AADFA7 /* RTCRtpSFrameTransformErrorEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCRtpSFrameTransformErrorEvent.cpp; sourceTree = "<group>"; };
41B8776023DE1042003638B8 /* RealtimeMediaSourceIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RealtimeMediaSourceIdentifier.h; sourceTree = "<group>"; };
41B9137623584D0E0025BFA3 /* MockAudioDestinationCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockAudioDestinationCocoa.h; sourceTree = "<group>"; };
41B9137823584D0F0025BFA3 /* MockAudioDestinationCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockAudioDestinationCocoa.cpp; sourceTree = "<group>"; };
@@ -17241,6 +17244,9 @@
4181C641255B4C2600AEB0FF /* RTCRtpSFrameTransformer.cpp */,
4181C642255B4C2600AEB0FF /* RTCRtpSFrameTransformer.h */,
4181C63F255B4C2500AEB0FF /* RTCRtpSFrameTransformerCocoa.cpp */,
+ 41B6AA5226B995F900AADFA7 /* RTCRtpSFrameTransformErrorEvent.cpp */,
+ 41B6AA4F26B995F800AADFA7 /* RTCRtpSFrameTransformErrorEvent.h */,
+ 41B6AA5126B995F800AADFA7 /* RTCRtpSFrameTransformErrorEvent.idl */,
415E1BB62150152A0022DA96 /* RTCRtpSynchronizationSource.h */,
415E1BB7215015300022DA96 /* RTCRtpSynchronizationSource.idl */,
5E5E2B101CFC3E4B000C0D85 /* RTCRtpTransceiver.cpp */,
Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (280957 => 280958)
--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2021-08-12 09:37:05 UTC (rev 280958)
@@ -219,6 +219,7 @@
macro(Request) \
macro(Response) \
macro(SFrameTransform) \
+ macro(SFrameTransformErrorEvent) \
macro(ScreenLuminance) \
macro(ServiceWorker) \
macro(ServiceWorkerContainer) \
Modified: trunk/Source/WebCore/dom/EventNames.in (280957 => 280958)
--- trunk/Source/WebCore/dom/EventNames.in 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/dom/EventNames.in 2021-08-12 09:37:05 UTC (rev 280958)
@@ -64,6 +64,7 @@
RTCPeerConnectionIceEvent conditional=WEB_RTC
RTCDataChannelEvent conditional=WEB_RTC
RTCDTMFToneChangeEvent conditional=WEB_RTC
+RTCRtpSFrameTransformErrorEvent conditional=WEB_RTC
RTCTrackEvent conditional=WEB_RTC
RTCTransformEvent conditional=WEB_RTC
SpeechRecognitionErrorEvent
Modified: trunk/Source/WebCore/dom/EventTargetFactory.in (280957 => 280958)
--- trunk/Source/WebCore/dom/EventTargetFactory.in 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Source/WebCore/dom/EventTargetFactory.in 2021-08-12 09:37:05 UTC (rev 280958)
@@ -40,6 +40,7 @@
RTCDataChannel conditional=WEB_RTC
RTCDTMFSender conditional=WEB_RTC
RTCPeerConnection conditional=WEB_RTC
+RTCRtpSFrameTransform conditional=WEB_RTC
RTCRtpScriptTransform conditional=WEB_RTC
ServiceWorker conditional=SERVICE_WORKER
ServiceWorkerContainer conditional=SERVICE_WORKER
Modified: trunk/Tools/ChangeLog (280957 => 280958)
--- trunk/Tools/ChangeLog 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Tools/ChangeLog 2021-08-12 09:37:05 UTC (rev 280958)
@@ -1,3 +1,13 @@
+2021-08-12 Youenn Fablet <[email protected]>
+
+ Implement SFrameTransform error handling
+ https://bugs.webkit.org/show_bug.cgi?id=228947
+
+ Reviewed by Eric Carlson.
+
+ * TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp:
+ (TestWebKitAPI::TEST):
+
2021-08-11 Peng Liu <[email protected]>
[ BigSur Debug ] TestWebKitAPI.GPUProcess.CrashWhilePlayingAudioViaCreateMediaElementSource is flaky, hitting ASSERTION FAILED: !isInRoutingArbitrationForToken(token)
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp (280957 => 280958)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp 2021-08-12 04:35:22 UTC (rev 280957)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp 2021-08-12 09:37:05 UTC (rev 280958)
@@ -200,13 +200,13 @@
auto frame = Vector<uint8_t>::from(135, 89, 51, 166, 248, 129, 157, 111, 190, 134, 220);
auto encryptedResult = encryptor->transform(frame.data(), frame.size());
- EXPECT_FALSE(encryptedResult.hasException());
+ EXPECT_TRUE(encryptedResult.has_value());
- auto encrypted = encryptedResult.releaseReturnValue();
+ auto encrypted = WTFMove(encryptedResult.value());
auto decryptedResult = decryptor->transform(encrypted.data(), encrypted.size());
- EXPECT_FALSE(decryptedResult.hasException());
+ EXPECT_TRUE(decryptedResult.has_value());
- checkVectorsAreEqual(decryptedResult.returnValue(), frame);
+ checkVectorsAreEqual(decryptedResult.value(), frame);
}
TEST(RTCRtpSFrameTransformer, EncryptDecryptKeyID0)
@@ -220,13 +220,13 @@
auto frame = Vector<uint8_t>::from(135, 89, 51, 166, 248, 129, 157, 111, 190, 134, 220);
auto encryptedResult = encryptor->transform(frame.data(), frame.size());
- EXPECT_FALSE(encryptedResult.hasException());
+ EXPECT_TRUE(encryptedResult.has_value());
- auto encrypted = encryptedResult.releaseReturnValue();
+ auto encrypted = WTFMove(encryptedResult.value());
auto decryptedResult = decryptor->transform(encrypted.data(), encrypted.size());
- EXPECT_FALSE(decryptedResult.hasException());
+ EXPECT_TRUE(decryptedResult.has_value());
- checkVectorsAreEqual(decryptedResult.returnValue(), frame);
+ checkVectorsAreEqual(decryptedResult.value(), frame);
}
TEST(RTCRtpSFrameTransformer, EncryptDecryptAudio)
@@ -242,13 +242,13 @@
auto frame = Vector<uint8_t>::from(135, 89, 51, 166, 248, 129, 157, 111, 190, 134, 220, 56);
auto encryptedResult = encryptor->transform(frame.data(), frame.size());
- EXPECT_FALSE(encryptedResult.hasException());
+ EXPECT_TRUE(encryptedResult.has_value());
- auto encrypted = encryptedResult.releaseReturnValue();
+ auto encrypted = WTFMove(encryptedResult.value());
auto decryptedResult = decryptor->transform(encrypted.data(), encrypted.size());
- EXPECT_FALSE(decryptedResult.hasException());
+ EXPECT_TRUE(decryptedResult.has_value());
- checkVectorsAreEqual(decryptedResult.returnValue(), frame);
+ checkVectorsAreEqual(decryptedResult.value(), frame);
}
TEST(RTCRtpSFrameTransformer, TransformCounter0)
@@ -257,9 +257,9 @@
uint8_t frame1[] = { 135, 89, 51, 166, 248, 129, 157, 111, 190, 134, 220 };
auto result = transformer->transform(frame1, sizeof(frame1));
- EXPECT_FALSE(result.hasException());
+ EXPECT_TRUE(result.has_value());
- checkVectorsAreEqual(result.releaseReturnValue(), Vector<uint8_t>::from(
+ checkVectorsAreEqual(result.value(), Vector<uint8_t>::from(
15,
198,
31,
@@ -299,14 +299,14 @@
auto transformer = createVideoTransformer();
uint8_t frame1[] = { 8, 164, 189, 18, 61, 117, 132, 43, 117, 169, 42 };
- WebCore::ExceptionOr<Vector<uint8_t>> result = Vector<uint8_t>();
- result = transformer->transform(frame1, sizeof(frame1));
+ auto result = transformer->transform(frame1, sizeof(frame1));
+ EXPECT_TRUE(result.has_value());
for (size_t cptr = 0; cptr < 256; ++cptr) {
result = transformer->transform(frame1, sizeof(frame1));
- EXPECT_FALSE(result.hasException());
+ EXPECT_TRUE(result.has_value());
}
- checkVectorsAreEqual(result.releaseReturnValue(), Vector<uint8_t>::from(
+ checkVectorsAreEqual(result.value(), Vector<uint8_t>::from(
31,
198,
31,
@@ -349,9 +349,9 @@
uint8_t frame1[] = { 0, 33, 244, 24, 236, 156, 127, 8, 48, 88, 220 };
auto result = transformer->transform(frame1, sizeof(frame1));
- EXPECT_FALSE(result.hasException());
+ EXPECT_TRUE(result.has_value());
- checkVectorsAreEqual(result.releaseReturnValue(), Vector<uint8_t>::from(
+ checkVectorsAreEqual(result.value(), Vector<uint8_t>::from(
47,
198,
31,