Source/WebCore/ChangeLog

 12017-01-27 Youenn Fablet <youennf@gmail.com>
 2
 3 [WebRTC] Add support for libwebrtc data channel
 4 https://bugs.webkit.org/show_bug.cgi?id=167489
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Partially covered by webrtc/datachannel/basic.html but not yet enabled on bots.
 9
 10 Introducing LibWebRTCDataChannelHandler as the integration layer between WebCore (RTCDataChannel)
 11 and libwebrtc (DataChannelObserver).
 12
 13 * Modules/mediastream/RTCDataChannel.cpp:
 14 (WebCore::RTCDataChannel::create):
 15 (WebCore::RTCDataChannel::RTCDataChannel):
 16 (WebCore::RTCDataChannel::bufferedAmount):
 17 (WebCore::RTCDataChannel::bufferedAmountIsDecreasing):
 18 * Modules/mediastream/RTCDataChannel.h:
 19 * Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.cpp: Added.
 20 (WebCore::LibWebRTCDataChannelHandler::~LibWebRTCDataChannelHandler):
 21 (WebCore::LibWebRTCDataChannelHandler::setClient):
 22 (WebCore::LibWebRTCDataChannelHandler::sendStringData):
 23 (WebCore::LibWebRTCDataChannelHandler::sendRawData):
 24 (WebCore::LibWebRTCDataChannelHandler::close):
 25 (WebCore::LibWebRTCDataChannelHandler::OnStateChange):
 26 (WebCore::LibWebRTCDataChannelHandler::OnMessage):
 27 * Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.h:
 28 * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
 29 (WebCore::LibWebRTCMediaEndpoint::OnRemoveStream):
 30 (WebCore::LibWebRTCMediaEndpoint::addDataChannel):
 31 (): Deleted.
 32 * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
 33 (WebCore::LibWebRTCPeerConnectionBackend::createDataChannelHandler):
 34 * dom/EventNames.h:
 35 * platform/mediastream/RTCDataChannelHandler.h:
 36 * platform/mediastream/RTCDataChannelHandlerClient.h:
 37 * platform/mock/RTCDataChannelHandlerMock.h:
 38
1392017-01-27 Yusuke Suzuki <utatane.tea@gmail.com>
240
341 Implement dynamic-import for WebCore

Source/WebCore/Modules/mediastream/RTCDataChannel.cpp

@@static const AtomicString& arraybufferKeyword()
5555Ref<RTCDataChannel> RTCDataChannel::create(ScriptExecutionContext& context, std::unique_ptr<RTCDataChannelHandler>&& handler, String&& label, RTCDataChannelInit&& options)
5656{
5757 ASSERT(handler);
58  return adoptRef(*new RTCDataChannel(context, WTFMove(handler), WTFMove(label), WTFMove(options)));
 58 auto channel = adoptRef(*new RTCDataChannel(context, WTFMove(handler), WTFMove(label), WTFMove(options)));
 59 channel->m_handler->setClient(&channel.get());
 60 return channel;
5961}
6062
6163RTCDataChannel::RTCDataChannel(ScriptExecutionContext& context, std::unique_ptr<RTCDataChannelHandler>&& handler, String&& label, RTCDataChannelInit&& options)

@@RTCDataChannel::RTCDataChannel(ScriptExecutionContext& context, std::unique_ptr<
6567 , m_label(WTFMove(label))
6668 , m_options(WTFMove(options))
6769{
68  m_handler->setClient(this);
6970}
7071
7172const AtomicString& RTCDataChannel::readyState() const

@@const AtomicString& RTCDataChannel::readyState() const
9091 return emptyAtom;
9192}
9293
93 unsigned RTCDataChannel::bufferedAmount() const
 94size_t RTCDataChannel::bufferedAmount() const
9495{
95  return 0;
 96 return m_handler->bufferedAmount();
9697}
9798
9899const AtomicString& RTCDataChannel::binaryType() const

@@void RTCDataChannel::didDetectError()
222223 scheduleDispatchEvent(Event::create(eventNames().errorEvent, false, false));
223224}
224225
 226void RTCDataChannel::bufferedAmountIsDecreasing()
 227{
 228 if (m_stopped)
 229 return;
 230
 231 if (bufferedAmount() <= m_bufferedAmountLowThreshold)
 232 scheduleDispatchEvent(Event::create(eventNames().bufferedAmountLowThresholdEvent, false, false));
 233}
 234
225235void RTCDataChannel::stop()
226236{
227237 m_stopped = true;

Source/WebCore/Modules/mediastream/RTCDataChannel.h

@@namespace WebCore {
4444class Blob;
4545class RTCPeerConnectionHandler;
4646
47 class RTCDataChannel final : public RefCounted<RTCDataChannel>, public EventTargetWithInlineData, public RTCDataChannelHandlerClient {
 47class RTCDataChannel final : public RTCDataChannelHandlerClient, public EventTargetWithInlineData {
4848public:
4949 static Ref<RTCDataChannel> create(ScriptExecutionContext&, std::unique_ptr<RTCDataChannelHandler>&&, String&&, RTCDataChannelInit&&);
5050

@@public:
5757
5858 String label() const { return m_label; }
5959 const AtomicString& readyState() const;
60  unsigned bufferedAmount() const;
 60 size_t bufferedAmount() const;
 61 size_t bufferedAmountLowThreshold() const { return m_bufferedAmountLowThreshold; }
 62 void setBufferedAmountLowThreshold(size_t value) { m_bufferedAmountLowThreshold = value; }
6163
6264 const AtomicString& binaryType() const;
6365 ExceptionOr<void> setBinaryType(const AtomicString&);

@@public:
7173
7274 void stop();
7375
74  using RefCounted::ref;
75  using RefCounted::deref;
 76 using RTCDataChannelHandlerClient::ref;
 77 using RTCDataChannelHandlerClient::deref;
7678
7779private:
7880 RTCDataChannel(ScriptExecutionContext&, std::unique_ptr<RTCDataChannelHandler>&&, String&&, RTCDataChannelInit&&);

@@private:
8890
8991 ScriptExecutionContext* m_scriptExecutionContext;
9092
 93 // RTCDataChannelHandlerClient API
9194 void didChangeReadyState(ReadyState) final;
9295 void didReceiveStringData(const String&) final;
9396 void didReceiveRawData(const char*, size_t) final;
9497 void didDetectError() final;
95  void protect() final { ref(); }
96  void unprotect() final { deref(); }
 98 void bufferedAmountIsDecreasing() final;
9799
98100 std::unique_ptr<RTCDataChannelHandler> m_handler;
99101

@@private:
109111
110112 String m_label;
111113 RTCDataChannelInit m_options;
 114 size_t m_bufferedAmountLowThreshold { 0 };
112115};
113116
114117} // namespace WebCore

Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.cpp

 1/*
 2 * Copyright (C) 2017 Apple Inc.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 23 */
 24
 25#include "config.h"
 26#include "LibWebRTCDataChannelHandler.h"
 27
 28#if USE(LIBWEBRTC)
 29
 30#include "RTCDataChannel.h"
 31#include <wtf/MainThread.h>
 32
 33namespace WebCore {
 34
 35LibWebRTCDataChannelHandler::~LibWebRTCDataChannelHandler()
 36{
 37 if (m_client)
 38 m_channel->UnregisterObserver();
 39}
 40
 41void LibWebRTCDataChannelHandler::setClient(RTCDataChannelHandlerClient* client)
 42{
 43 m_client = client;
 44 if (m_client)
 45 m_channel->RegisterObserver(this);
 46 else
 47 m_channel->UnregisterObserver();
 48}
 49
 50bool LibWebRTCDataChannelHandler::sendStringData(const String& text)
 51{
 52 return m_channel->Send({rtc::CopyOnWriteBuffer(text.utf8().data(), text.length()), false});
 53}
 54
 55bool LibWebRTCDataChannelHandler::sendRawData(const char* data, size_t length)
 56{
 57 return m_channel->Send({rtc::CopyOnWriteBuffer(data, length), true});
 58}
 59
 60void LibWebRTCDataChannelHandler::close()
 61{
 62 m_channel->Close();
 63}
 64
 65void LibWebRTCDataChannelHandler::OnStateChange()
 66{
 67 RTCDataChannel::ReadyState state;
 68 switch (m_channel->state()) {
 69 case webrtc::DataChannelInterface::kConnecting:
 70 state = RTCDataChannel::ReadyStateConnecting;
 71 break;
 72 case webrtc::DataChannelInterface::kOpen:
 73 state = RTCDataChannel::ReadyStateOpen;
 74 break;
 75 case webrtc::DataChannelInterface::kClosing:
 76 state = RTCDataChannel::ReadyStateClosing;
 77 break;
 78 case webrtc::DataChannelInterface::kClosed:
 79 state = RTCDataChannel::ReadyStateClosed;
 80 break;
 81 }
 82 ASSERT(m_client);
 83 callOnMainThread([protectedClient = makeRef(*m_client), state] {
 84 protectedClient->didChangeReadyState(state);
 85 });
 86}
 87
 88void LibWebRTCDataChannelHandler::OnMessage(const webrtc::DataBuffer& buffer)
 89{
 90 ASSERT(m_client);
 91 std::unique_ptr<webrtc::DataBuffer> protectedBuffer(new webrtc::DataBuffer(buffer));
 92 callOnMainThread([protectedClient = makeRef(*m_client), buffer = WTFMove(protectedBuffer)] {
 93 // FIXME: Ensure this is correct by adding some tests with non-ASCII characters.
 94 const char* data = reinterpret_cast<const char*>(buffer->data.data());
 95 if (buffer->binary)
 96 protectedClient->didReceiveRawData(data, buffer->size());
 97 else
 98 protectedClient->didReceiveStringData(String(data, buffer->size()));
 99 });
 100}
 101
 102void LibWebRTCDataChannelHandler::OnBufferedAmountChange(uint64_t previousAmount)
 103{
 104 if (previousAmount <= m_channel->buffered_amount())
 105 return;
 106 ASSERT(m_client);
 107 callOnMainThread([protectedClient = makeRef(*m_client)] {
 108 protectedClient->bufferedAmountIsDecreasing();
 109 });
 110}
 111
 112} // namespace WebCore
 113
 114#endif // USE(LIBWEBRTC)

Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.h

 1/*
 2 * Copyright (C) 2017 Apple Inc.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 23 */
 24
 25#pragma once
 26
 27#if USE(LIBWEBRTC)
 28
 29#include "LibWebRTCMacros.h"
 30#include "RTCDataChannelHandler.h"
 31#include <webrtc/api/datachannelinterface.h>
 32
 33namespace WebCore {
 34
 35class RTCDataChannelHandlerClient;
 36
 37class LibWebRTCDataChannelHandler final : public RTCDataChannelHandler, private webrtc::DataChannelObserver {
 38public:
 39 explicit LibWebRTCDataChannelHandler(rtc::scoped_refptr<webrtc::DataChannelInterface>&& channel) : m_channel(WTFMove(channel)) { ASSERT(m_channel); }
 40 ~LibWebRTCDataChannelHandler();
 41
 42private:
 43 // RTCDataChannelHandler API
 44 void setClient(RTCDataChannelHandlerClient*) final;
 45 bool sendStringData(const String&) final;
 46 bool sendRawData(const char*, size_t) final;
 47 void close() final;
 48 size_t bufferedAmount() const final { return m_channel->buffered_amount(); }
 49
 50 // webrtc::DataChannelObserver API
 51 void OnStateChange();
 52 void OnMessage(const webrtc::DataBuffer&);
 53 void OnBufferedAmountChange(uint64_t);
 54
 55 rtc::scoped_refptr<webrtc::DataChannelInterface> m_channel;
 56 RTCDataChannelHandlerClient* m_client { nullptr };
 57};
 58
 59} // namespace WebCore
 60
 61#endif // USE(LIBWEBRTC)

Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp

2828#if USE(LIBWEBRTC)
2929
3030#include "EventNames.h"
 31#include "LibWebRTCDataChannelHandler.h"
3132#include "LibWebRTCPeerConnectionBackend.h"
3233#include "LibWebRTCProvider.h"
3334#include "LibWebRTCUtils.h"

@@void LibWebRTCMediaEndpoint::OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamI
285286
286287void LibWebRTCMediaEndpoint::OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>)
287288{
288  ASSERT_NOT_REACHED();
 289 notImplemented();
 290}
 291
 292std::unique_ptr<RTCDataChannelHandler> LibWebRTCMediaEndpoint::createDataChannel(const String& label, const RTCDataChannelInit& options)
 293{
 294 webrtc::DataChannelInit init;
 295 init.ordered = options.ordered;
 296 init.maxRetransmitTime = options.maxRetransmitTime;
 297 init.maxRetransmits = options.maxRetransmits;
 298 init.protocol = options.protocol.utf8().data();
 299 init.negotiated = options.negotiated;
 300 init.id = options.id;
 301
 302 return std::make_unique<LibWebRTCDataChannelHandler>(m_backend->CreateDataChannel(label.utf8().data(), &init));
 303}
 304
 305void LibWebRTCMediaEndpoint::addDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>&& dataChannel)
 306{
 307 auto protocol = dataChannel->protocol();
 308 auto label = dataChannel->label();
 309
 310 RTCDataChannelInit init;
 311 init.ordered = dataChannel->ordered();
 312 init.maxRetransmitTime = dataChannel->maxRetransmitTime();
 313 init.maxRetransmits = dataChannel->maxRetransmits();
 314 init.protocol = String(protocol.data(), protocol.size());
 315 init.negotiated = dataChannel->negotiated();
 316 init.id = dataChannel->id();
 317
 318 bool isOpened = dataChannel->state() == webrtc::DataChannelInterface::kOpen;
 319
 320 auto handler = std::make_unique<LibWebRTCDataChannelHandler>(WTFMove(dataChannel));
 321 ASSERT(m_peerConnectionBackend.connection().scriptExecutionContext());
 322 auto channel = RTCDataChannel::create(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(handler), String(label.data(), label.size()), WTFMove(init));
 323
 324 if (isOpened) {
 325 callOnMainThread([channel = channel.copyRef()] {
 326 // FIXME: We should be able to write channel->didChangeReadyState(...)
 327 RTCDataChannelHandlerClient& client = channel.get();
 328 client.didChangeReadyState(RTCDataChannel::ReadyStateOpen);
 329 });
 330 }
 331
 332 m_peerConnectionBackend.connection().fireEvent(RTCDataChannelEvent::create(eventNames().datachannelEvent, false, false, WTFMove(channel)));
289333}
290334
291335void LibWebRTCMediaEndpoint::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel)

Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h

@@public:
6666 void doCreateOffer();
6767 void doCreateAnswer();
6868 void getStats(MediaStreamTrack*, PeerConnection::StatsPromise&&);
 69 std::unique_ptr<RTCDataChannelHandler> createDataChannel(const String&, const RTCDataChannelInit&);
6970
7071 void storeIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface>&& candidate) { m_pendingCandidates.append(WTFMove(candidate)); }
7172 void addPendingIceCandidates();

Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp

2929
3030#include "Document.h"
3131#include "IceCandidate.h"
 32#include "LibWebRTCDataChannelHandler.h"
3233#include "LibWebRTCMediaEndpoint.h"
3334#include "MediaEndpointConfiguration.h"
3435#include "Page.h"

@@Ref<RTCRtpReceiver> LibWebRTCPeerConnectionBackend::createReceiver(const String&
179180
180181std::unique_ptr<RTCDataChannelHandler> LibWebRTCPeerConnectionBackend::createDataChannelHandler(const String& label, const RTCDataChannelInit& options)
181182{
182  UNUSED_PARAM(label);
183  UNUSED_PARAM(options);
184  ASSERT_NOT_REACHED();
185  return nullptr;
 183 return m_endpoint->createDataChannel(label, options);
186184}
187185
188186} // namespace WebCore

Source/WebCore/dom/EventNames.h

@@namespace WebCore {
6767 macro(blocked) \
6868 macro(blur) \
6969 macro(boundary) \
 70 macro(bufferedAmountLowThreshold) \
7071 macro(cached) \
7172 macro(cancel) \
7273 macro(canplay) \

Source/WebCore/platform/mediastream/RTCDataChannelHandler.h

@@public:
5050 virtual bool sendStringData(const String&) = 0;
5151 virtual bool sendRawData(const char*, size_t) = 0;
5252 virtual void close() = 0;
 53
 54 virtual size_t bufferedAmount() const = 0;
5355};
5456
5557} // namespace WebCore

Source/WebCore/platform/mediastream/RTCDataChannelHandlerClient.h

2222 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2323 */
2424
25 #ifndef RTCDataChannelHandlerClient_h
26 #define RTCDataChannelHandlerClient_h
 25#pragma once
2726
2827#if ENABLE(WEB_RTC)
2928
 29#include <wtf/ThreadSafeRefCounted.h>
3030#include <wtf/text/WTFString.h>
3131
3232namespace WebCore {
3333
34 class RTCDataChannelHandlerClient {
 34class RTCDataChannelHandlerClient : public ThreadSafeRefCounted<RTCDataChannelHandlerClient> {
3535public:
3636 enum ReadyState {
3737 ReadyStateConnecting = 0,

@@public:
4646 virtual void didReceiveStringData(const String&) = 0;
4747 virtual void didReceiveRawData(const char*, size_t) = 0;
4848 virtual void didDetectError() = 0;
49 
50  virtual void protect() = 0;
51  virtual void unprotect() = 0;
 49 virtual void bufferedAmountIsDecreasing() = 0;
5250};
5351
5452} // namespace WebCore
5553
5654#endif // ENABLE(WEB_RTC)
57 
58 #endif // RTCDataChannelHandlerClient_h

Source/WebCore/platform/mock/RTCDataChannelHandlerMock.h

@@private:
4242 bool sendStringData(const String&) final;
4343 bool sendRawData(const char*, size_t) final;
4444 void close() final;
 45 size_t bufferedAmount() const final { return 0; }
4546
4647 RTCDataChannelHandlerClient* m_client;
4748