Commit 4ea28756 authored by Steve Anton's avatar Steve Anton Committed by Commit Bot

Implement RTCQuicTransport.onquicstream and stream reset/finish

This CL implements the RTCQuicTransport createStream method and the
corresponding quicstream event hooked up to the QUIC adapters. It
also implements RTCQuicStream.reset/finish and statechange event to
allow end-to-end testing.

Bug: 874296
Change-Id: I331d37f3e21c606697b8768bf9eea59c90487163
Reviewed-on: https://chromium-review.googlesource.com/c/1217846
Commit-Queue: Steve Anton <steveanton@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarHenrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596068}
parent 32b267c2
...@@ -13,19 +13,25 @@ ...@@ -13,19 +13,25 @@
// The following helper functions are called from RTCQuicTransport-helper.js: // The following helper functions are called from RTCQuicTransport-helper.js:
// makeStandaloneQuicTransport // makeStandaloneQuicTransport
// makeTwoConnectedQuicTransports
promise_test(async t => { promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t); const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
const quicStream = quicTransport.createStream(); const quicStream = quicTransport.createStream();
assert_equals(quicStream.transport, quicTransport, assert_equals(quicStream.transport, quicTransport,
'Expect transport to be set to the creating RTCQuicTransport.'); 'Expect transport to be set to the creating RTCQuicTransport.');
assert_equals(quicStream.state, 'new', `Expect state to be 'new'.`); assert_equals(quicStream.state, 'open', `Expect state to be 'open'.`);
assert_equals(quicStream.readBufferedAmount, 0, assert_equals(quicStream.readBufferedAmount, 0,
'Expect read buffered amount to be 0.'); 'Expect read buffered amount to be 0.');
assert_equals(quicStream.writeBufferedAmount, 0, assert_equals(quicStream.writeBufferedAmount, 0,
'Expect write buffered amount to be 0.'); 'Expect write buffered amount to be 0.');
}, 'createStream() returns an RTCQuicStream with initial properties set.'); }, 'createStream() returns an RTCQuicStream with initial properties set.');
promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t);
assert_throws('InvalidStateError', () => quicTransport.createStream());
}, 'createStream() throws if the transport is not connected.');
promise_test(async t => { promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t); const quicTransport = await makeStandaloneQuicTransport(t);
quicTransport.stop(); quicTransport.stop();
...@@ -33,12 +39,120 @@ promise_test(async t => { ...@@ -33,12 +39,120 @@ promise_test(async t => {
}, 'createStream() throws if the transport is closed.'); }, 'createStream() throws if the transport is closed.');
promise_test(async t => { promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t); const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
const firstQuicStream = quicTransport.createStream(); const firstQuicStream = quicTransport.createStream();
const secondQuicStream = quicTransport.createStream(); const secondQuicStream = quicTransport.createStream();
quicTransport.stop(); quicTransport.stop();
assert_equals(firstQuicStream.state, 'closed'); assert_equals(firstQuicStream.state, 'closed');
assert_equals(secondQuicStream.state, 'closed'); assert_equals(secondQuicStream.state, 'closed');
}, 'RTCQuicTransport.stop() closes all streams.'); }, 'RTCQuicTransport.stop() closes all local streams.');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const firstLocalStream = localQuicTransport.createStream();
firstLocalStream.finish();
const secondLocalStream = localQuicTransport.createStream();
secondLocalStream.finish();
const remoteWatcher =
new EventWatcher(t, remoteQuicTransport, [ 'quicstream', 'statechange' ]);
const { stream: firstRemoteStream } =
await remoteWatcher.wait_for('quicstream');
const { stream: secondRemoteStream } =
await remoteWatcher.wait_for('quicstream');
localQuicTransport.stop();
await remoteWatcher.wait_for('statechange');
assert_equals(firstRemoteStream.state, 'closed');
assert_equals(secondRemoteStream.state, 'closed');
}, 'RTCQuicTransport.stop() closes all remote streams.');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
assert_equals(localStream.state, 'closing');
}, `finish() changes state to 'closing'.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
localStream.finish();
assert_equals(localStream.state, 'closing');
}, `finish() twice does not change state.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.reset();
assert_equals(localStream.state, 'closed');
}, `reset() changes state to 'closed'.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
localStream.reset();
assert_equals(localStream.state, 'closed');
}, `reset() following finish() changes state to 'closed'.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
assert_equals(remoteStream.state, 'open');
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closing');
}, 'createStream() followed by finish() fires a quicstream event followed by ' +
`a statechange event to 'closing' on the remote side.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.reset();
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
assert_equals(remoteStream.state, 'open');
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closed');
}, 'createStream() followed by reset() fires a quicstream event followed ' +
`by a statechange event to 'closed' on the remote side.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
remoteQuicTransport.onquicstream = ({ stream }) => stream.reset();
const localStream = localQuicTransport.createStream();
localStream.finish();
const localWatcher = new EventWatcher(t, localStream, 'statechange');
await localWatcher.wait_for('statechange');
assert_equals(localStream.state, 'closed');
}, 'finish() on a remote stream that has already finished fires a ' +
`statechange event to 'closed' on the remote side.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
localStream.reset();
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closing');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closed');
}, 'finish() then reset() fires two statechange events on the remote side.');
</script> </script>
...@@ -79,4 +79,3 @@ async function makeTwoConnectedQuicTransports(t) { ...@@ -79,4 +79,3 @@ async function makeTwoConnectedQuicTransports(t) {
]); ]);
return [ localQuicTransport, remoteQuicTransport ]; return [ localQuicTransport, remoteQuicTransport ];
} }
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
// makeAndGatherTwoIceTransports // makeAndGatherTwoIceTransports
// The following helper functions are called from RTCQuicTransport-helper.js: // The following helper functions are called from RTCQuicTransport-helper.js:
// generateCertificate
// makeQuicTransport // makeQuicTransport
// makeStandaloneQuicTransport // makeStandaloneQuicTransport
// makeAndStartTwoQuicTransports // makeAndStartTwoQuicTransports
......
...@@ -5569,16 +5569,25 @@ interface RTCPeerConnectionIceEvent : Event ...@@ -5569,16 +5569,25 @@ interface RTCPeerConnectionIceEvent : Event
attribute @@toStringTag attribute @@toStringTag
getter candidate getter candidate
method constructor method constructor
interface RTCQuicStream interface RTCQuicStream : EventTarget
attribute @@toStringTag attribute @@toStringTag
getter onstatechange
getter readBufferedAmount getter readBufferedAmount
getter state getter state
getter transport getter transport
getter writeBufferedAmount getter writeBufferedAmount
method constructor method constructor
method finish
method reset
setter onstatechange
interface RTCQuicStreamEvent : Event
attribute @@toStringTag
getter stream
method constructor
interface RTCQuicTransport : EventTarget interface RTCQuicTransport : EventTarget
attribute @@toStringTag attribute @@toStringTag
getter onerror getter onerror
getter onquicstream
getter onstatechange getter onstatechange
getter state getter state
getter transport getter transport
...@@ -5591,6 +5600,7 @@ interface RTCQuicTransport : EventTarget ...@@ -5591,6 +5600,7 @@ interface RTCQuicTransport : EventTarget
method start method start
method stop method stop
setter onerror setter onerror
setter onquicstream
setter onstatechange setter onstatechange
interface RTCRtpContributingSource interface RTCRtpContributingSource
attribute @@toStringTag attribute @@toStringTag
......
...@@ -41,6 +41,7 @@ generate_event_interfaces("modules_bindings_generated_event_interfaces") { ...@@ -41,6 +41,7 @@ generate_event_interfaces("modules_bindings_generated_event_interfaces") {
"//third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl",
"//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl", "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl",
"//third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl", "//third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl",
"//third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl", "//third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl",
......
...@@ -216,6 +216,7 @@ ...@@ -216,6 +216,7 @@
"progress", "progress",
"processorerror", "processorerror",
"push", "push",
"quicstream",
"ratechange", "ratechange",
"reading", "reading",
"readystatechange", "readystatechange",
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
"modules/notifications/Notification", "modules/notifications/Notification",
"modules/payments/PaymentRequest", "modules/payments/PaymentRequest",
"modules/peerconnection/RTCIceTransport", "modules/peerconnection/RTCIceTransport",
"modules/peerconnection/RTCQuicStream",
"modules/peerconnection/RTCQuicTransport", "modules/peerconnection/RTCQuicTransport",
"modules/permissions/PermissionStatus", "modules/permissions/PermissionStatus",
"modules/picture_in_picture/HTMLVideoElementPictureInPicture", "modules/picture_in_picture/HTMLVideoElementPictureInPicture",
......
...@@ -228,6 +228,7 @@ modules_idl_files = ...@@ -228,6 +228,7 @@ modules_idl_files =
"peerconnection/rtc_peer_connection.idl", "peerconnection/rtc_peer_connection.idl",
"peerconnection/rtc_peer_connection_ice_event.idl", "peerconnection/rtc_peer_connection_ice_event.idl",
"peerconnection/rtc_quic_stream.idl", "peerconnection/rtc_quic_stream.idl",
"peerconnection/rtc_quic_stream_event.idl",
"peerconnection/rtc_quic_transport.idl", "peerconnection/rtc_quic_transport.idl",
"peerconnection/rtc_rtp_contributing_source.idl", "peerconnection/rtc_rtp_contributing_source.idl",
"peerconnection/rtc_rtp_receiver.idl", "peerconnection/rtc_rtp_receiver.idl",
...@@ -614,6 +615,7 @@ modules_dictionary_idl_files = ...@@ -614,6 +615,7 @@ modules_dictionary_idl_files =
"peerconnection/rtc_offer_options.idl", "peerconnection/rtc_offer_options.idl",
"peerconnection/rtc_peer_connection_ice_event_init.idl", "peerconnection/rtc_peer_connection_ice_event_init.idl",
"peerconnection/rtc_quic_parameters.idl", "peerconnection/rtc_quic_parameters.idl",
"peerconnection/rtc_quic_stream_event_init.idl",
"peerconnection/rtc_rtcp_parameters.idl", "peerconnection/rtc_rtcp_parameters.idl",
"peerconnection/rtc_rtp_capabilities.idl", "peerconnection/rtc_rtp_capabilities.idl",
"peerconnection/rtc_rtp_codec_capability.idl", "peerconnection/rtc_rtp_codec_capability.idl",
......
...@@ -24,6 +24,10 @@ blink_modules_sources("peerconnection") { ...@@ -24,6 +24,10 @@ blink_modules_sources("peerconnection") {
"adapters/p2p_quic_transport_factory_impl.h", "adapters/p2p_quic_transport_factory_impl.h",
"adapters/p2p_quic_transport_impl.cc", "adapters/p2p_quic_transport_impl.cc",
"adapters/p2p_quic_transport_impl.h", "adapters/p2p_quic_transport_impl.h",
"adapters/quic_stream_host.cc",
"adapters/quic_stream_host.h",
"adapters/quic_stream_proxy.cc",
"adapters/quic_stream_proxy.h",
"adapters/quic_transport_host.cc", "adapters/quic_transport_host.cc",
"adapters/quic_transport_host.h", "adapters/quic_transport_host.h",
"adapters/quic_transport_proxy.cc", "adapters/quic_transport_proxy.cc",
...@@ -54,6 +58,8 @@ blink_modules_sources("peerconnection") { ...@@ -54,6 +58,8 @@ blink_modules_sources("peerconnection") {
"rtc_peer_connection_ice_event.h", "rtc_peer_connection_ice_event.h",
"rtc_quic_stream.cc", "rtc_quic_stream.cc",
"rtc_quic_stream.h", "rtc_quic_stream.h",
"rtc_quic_stream_event.cc",
"rtc_quic_stream_event.h",
"rtc_quic_transport.cc", "rtc_quic_transport.cc",
"rtc_quic_transport.h", "rtc_quic_transport.h",
"rtc_rtp_contributing_source.cc", "rtc_rtp_contributing_source.cc",
......
...@@ -14,10 +14,14 @@ namespace blink { ...@@ -14,10 +14,14 @@ namespace blink {
IceTransportHost::IceTransportHost( IceTransportHost::IceTransportHost(
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread, scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
scoped_refptr<base::SingleThreadTaskRunner> host_thread,
base::WeakPtr<IceTransportProxy> proxy) base::WeakPtr<IceTransportProxy> proxy)
: proxy_thread_(std::move(proxy_thread)), proxy_(std::move(proxy)) { : proxy_thread_(std::move(proxy_thread)),
host_thread_(std::move(host_thread)),
proxy_(std::move(proxy)) {
DETACH_FROM_THREAD(thread_checker_); DETACH_FROM_THREAD(thread_checker_);
DCHECK(proxy_thread_); DCHECK(proxy_thread_);
DCHECK(host_thread_);
DCHECK(proxy_); DCHECK(proxy_);
} }
...@@ -33,6 +37,18 @@ void IceTransportHost::Initialize( ...@@ -33,6 +37,18 @@ void IceTransportHost::Initialize(
transport_ = adapter_factory->ConstructOnWorkerThread(this); transport_ = adapter_factory->ConstructOnWorkerThread(this);
} }
scoped_refptr<base::SingleThreadTaskRunner> IceTransportHost::proxy_thread()
const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return proxy_thread_;
}
scoped_refptr<base::SingleThreadTaskRunner> IceTransportHost::host_thread()
const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return host_thread_;
}
void IceTransportHost::StartGathering( void IceTransportHost::StartGathering(
const cricket::IceParameters& local_parameters, const cricket::IceParameters& local_parameters,
const cricket::ServerAddresses& stun_servers, const cricket::ServerAddresses& stun_servers,
......
...@@ -42,12 +42,16 @@ class QuicTransportHost; ...@@ -42,12 +42,16 @@ class QuicTransportHost;
class IceTransportHost final : public IceTransportAdapter::Delegate { class IceTransportHost final : public IceTransportAdapter::Delegate {
public: public:
IceTransportHost(scoped_refptr<base::SingleThreadTaskRunner> proxy_thread, IceTransportHost(scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
scoped_refptr<base::SingleThreadTaskRunner> host_thread,
base::WeakPtr<IceTransportProxy> proxy); base::WeakPtr<IceTransportProxy> proxy);
~IceTransportHost() override; ~IceTransportHost() override;
void Initialize( void Initialize(
std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory); std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
void StartGathering( void StartGathering(
const cricket::IceParameters& local_parameters, const cricket::IceParameters& local_parameters,
const cricket::ServerAddresses& stun_servers, const cricket::ServerAddresses& stun_servers,
...@@ -75,6 +79,7 @@ class IceTransportHost final : public IceTransportAdapter::Delegate { ...@@ -75,6 +79,7 @@ class IceTransportHost final : public IceTransportAdapter::Delegate {
void OnStateChanged(cricket::IceTransportState new_state) override; void OnStateChanged(cricket::IceTransportState new_state) override;
const scoped_refptr<base::SingleThreadTaskRunner> proxy_thread_; const scoped_refptr<base::SingleThreadTaskRunner> proxy_thread_;
const scoped_refptr<base::SingleThreadTaskRunner> host_thread_;
std::unique_ptr<IceTransportAdapter> transport_; std::unique_ptr<IceTransportAdapter> transport_;
base::WeakPtr<IceTransportProxy> proxy_; base::WeakPtr<IceTransportProxy> proxy_;
QuicTransportHost* consumer_host_ = nullptr; QuicTransportHost* consumer_host_ = nullptr;
......
...@@ -33,8 +33,8 @@ IceTransportProxy::IceTransportProxy( ...@@ -33,8 +33,8 @@ IceTransportProxy::IceTransportProxy(
// The IceTransportHost is constructed on the proxy thread but should only be // The IceTransportHost is constructed on the proxy thread but should only be
// interacted with via PostTask to the host thread. The OnTaskRunnerDeleter // interacted with via PostTask to the host thread. The OnTaskRunnerDeleter
// (configured above) will ensure it gets deleted on the host thread. // (configured above) will ensure it gets deleted on the host thread.
host_.reset( host_.reset(new IceTransportHost(proxy_thread_, host_thread_,
new IceTransportHost(proxy_thread_, weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
PostCrossThreadTask(*host_thread_, FROM_HERE, PostCrossThreadTask(*host_thread_, FROM_HERE,
CrossThreadBind(&IceTransportHost::Initialize, CrossThreadBind(&IceTransportHost::Initialize,
CrossThreadUnretained(host_.get()), CrossThreadUnretained(host_.get()),
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
namespace blink {
QuicStreamHost::QuicStreamHost() {
DETACH_FROM_THREAD(thread_checker_);
}
QuicStreamHost::~QuicStreamHost() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
void QuicStreamHost::set_proxy(base::WeakPtr<QuicStreamProxy> stream_proxy) {
DETACH_FROM_THREAD(thread_checker_);
stream_proxy_ = stream_proxy;
}
void QuicStreamHost::Initialize(QuicTransportHost* transport_host,
P2PQuicStream* p2p_stream) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(transport_host);
DCHECK(p2p_stream);
transport_host_ = transport_host;
p2p_stream_ = p2p_stream;
p2p_stream_->SetDelegate(this);
}
scoped_refptr<base::SingleThreadTaskRunner> QuicStreamHost::proxy_thread()
const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(transport_host_);
return transport_host_->proxy_thread();
}
void QuicStreamHost::Reset() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(p2p_stream_);
p2p_stream_->Reset();
Delete();
}
void QuicStreamHost::Finish() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(p2p_stream_);
p2p_stream_->Finish();
writeable_ = false;
if (!readable_ && !writeable_) {
Delete();
}
}
void QuicStreamHost::OnRemoteReset() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask(
*proxy_thread(), FROM_HERE,
CrossThreadBind(&QuicStreamProxy::OnRemoteReset, stream_proxy_));
Delete();
}
void QuicStreamHost::OnRemoteFinish() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask(
*proxy_thread(), FROM_HERE,
CrossThreadBind(&QuicStreamProxy::OnRemoteFinish, stream_proxy_));
readable_ = false;
if (!readable_ && !writeable_) {
Delete();
}
}
void QuicStreamHost::Delete() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(transport_host_);
// OnRemoveStream will delete |this|.
transport_host_->OnRemoveStream(this);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_HOST_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_HOST_H_
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h"
namespace blink {
class QuicStreamProxy;
class QuicTransportHost;
// This class is the host side correspondent to the QuicStreamProxy. See the
// QuicStreamProxy documentation for background. This class lives on the host
// thread and proxies calls between the QuicStreamProxy and the P2PQuicStream
// (which is single-threaded).
//
// The QuicStreamHost is owned by the QuicTransportHost and constructed when
// either a new local QUIC stream is created or when a remote QUIC stream has
// been created. The stream host will be deleted in the following circumstances:
// 1) Reset() is called.
// 2) OnRemoteReset() is indicated.
// 3) Finish() and OnRemoteFinish() have been called.
// The QuicStreamHost will instruct the QuicTransportHost to delete it when any
// condition has been met.
//
// Since the QuicStreamHost can be constructed from either the proxy or host
// thread, initialization happens in three steps:
// 1) QuicStreamHost is constructed.
// 2) set_proxy is called when a WeakPtr to the corresponding proxy-thread
// object.
// 3) Initialize is called on the host thread.
class QuicStreamHost final : public base::SupportsWeakPtr<QuicStreamHost>,
public P2PQuicStream::Delegate {
public:
QuicStreamHost();
~QuicStreamHost() override;
// Sets a WeakPtr to the corresponding QuicStreamProxy. This is valid on
// either the proxy or host thread. Should happen right after construction.
void set_proxy(base::WeakPtr<QuicStreamProxy> stream_proxy);
// Initializes the QuicStreamHost. Must be called on the host thread.
// |transport_host| must outlive this object.
void Initialize(QuicTransportHost* transport_host, P2PQuicStream* p2p_stream);
// The remaining methods can only be called from the host thread and must be
// preceded by Initialize().
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
void Reset();
void Finish();
private:
// Instruct the QuicTransportHost to remove and delete this stream host.
void Delete();
// P2PQuicStream::Delegate overrides.
void OnRemoteReset() override;
void OnRemoteFinish() override;
// Up reference. Owned by QuicTransportProxy.
QuicTransportHost* transport_host_ = nullptr;
// Forward reference. Owned by P2PQuicTransport.
P2PQuicStream* p2p_stream_ = nullptr;
// Back reference. Owned by QuicTransportProxy.
base::WeakPtr<QuicStreamProxy> stream_proxy_;
// |readable_| transitions to false when OnRemoteFinish() is called.
bool readable_ = true;
// |writeable_| transitions to false when Finish() is called.
bool writeable_ = true;
THREAD_CHECKER(thread_checker_);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_HOST_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
namespace blink {
QuicStreamProxy::QuicStreamProxy() {
DETACH_FROM_THREAD(thread_checker_);
}
QuicStreamProxy::~QuicStreamProxy() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
void QuicStreamProxy::set_host(base::WeakPtr<QuicStreamHost> stream_host) {
DETACH_FROM_THREAD(thread_checker_);
stream_host_ = stream_host;
}
void QuicStreamProxy::Initialize(QuicTransportProxy* transport_proxy) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(transport_proxy);
transport_proxy_ = transport_proxy;
}
void QuicStreamProxy::set_delegate(Delegate* delegate) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(delegate);
delegate_ = delegate;
}
scoped_refptr<base::SingleThreadTaskRunner> QuicStreamProxy::host_thread()
const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(transport_proxy_);
return transport_proxy_->host_thread();
}
void QuicStreamProxy::Reset() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask(*host_thread(), FROM_HERE,
CrossThreadBind(&QuicStreamHost::Reset, stream_host_));
Delete();
}
void QuicStreamProxy::Finish() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask(*host_thread(), FROM_HERE,
CrossThreadBind(&QuicStreamHost::Finish, stream_host_));
writeable_ = false;
if (!readable_ && !writeable_) {
Delete();
}
}
void QuicStreamProxy::OnRemoteReset() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(delegate_);
// Need to copy the |delegate_| member since Delete() will destroy |this|.
Delegate* delegate_copy = delegate_;
Delete();
delegate_copy->OnRemoteReset();
}
void QuicStreamProxy::OnRemoteFinish() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(delegate_);
// Need to copy the |delegate_| member since Delete() will destroy |this|.
Delegate* delegate_copy = delegate_;
readable_ = false;
if (!readable_ && !writeable_) {
Delete();
}
delegate_copy->OnRemoteFinish();
}
void QuicStreamProxy::Delete() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// OnRemoveStream will delete |this|.
transport_proxy_->OnRemoveStream(this);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_PROXY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_PROXY_H_
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
namespace blink {
class QuicStreamHost;
class QuicTransportProxy;
// This class allows interactions with a QUIC stream that runs on a thread
// different from which it is controlled. All interactions with the QUIC
// implementation happen asynchronously.
//
// The QuicStreamProxy is owned by the QuicTransportProxy and constructed when
// either a new local QUIC stream is created or when a remote QUIC stream has
// been created. The stream proxy will be deleted in the following
// circumstances:
// 1) Reset() is called.
// 2) OnRemoteReset() is indicated.
// 3) Finish() and OnRemoteFinish() have been called.
// The client is responsible for knowing when any of these conditions have been
// met and clearing its reference accordingly.
//
// Since the QuicStreamProxy can be constructed from either the proxy or host
// thread, initialization happens in four steps:
// 1) QuicStreamProxy is constructed.
// 2) set_host is called with a WeakPtr to the corresponding host-thread object.
// 3) Initialize is called on the proxy thread.
// 4) set_delegate is called on the proxy thread.
class QuicStreamProxy final : public base::SupportsWeakPtr<QuicStreamProxy> {
public:
class Delegate {
public:
virtual ~Delegate() = default;
// Called when the remote side resets the stream.
virtual void OnRemoteReset() {}
// Called when the remote side finishes the stream.
virtual void OnRemoteFinish() {}
};
QuicStreamProxy();
~QuicStreamProxy();
// Sets a WeakPtr to the corresponding QuicStreamHost. This is valid on either
// the proxy or host thread. Should happen right after construction.
void set_host(base::WeakPtr<QuicStreamHost> stream_host);
// Initializes the QuicStreamProxy. Must be called on the proxy thread.
// |transport_proxy| must outlive this object.
void Initialize(QuicTransportProxy* transport_proxy);
// Sets the delegate for receiving remote callbacks.
void set_delegate(Delegate* delegate);
// The remaining methods can only be called from the proxy thread and must
// be preceded by Initialize().
scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
void Reset();
void Finish();
private:
// Instruct the QuicTransportProxy to remove and delete this stream proxy.
void Delete();
// Callbacks from QuicStreamHost.
friend class QuicStreamHost;
void OnRemoteReset();
void OnRemoteFinish();
// Up reference. Owned by the QuicTransportProxy client.
QuicTransportProxy* transport_proxy_ = nullptr;
// Forward reference. Owned by the QuicTransportHost.
base::WeakPtr<QuicStreamHost> stream_host_;
// Back reference. Owned by the RTCQuicTransport.
Delegate* delegate_ = nullptr;
// |readable_| transitions to false when OnRemoteFinish() is called.
bool readable_ = true;
// |writeable_| transitions to false when Finish() is called.
bool writeable_ = true;
THREAD_CHECKER(thread_checker_);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_PROXY_H_
...@@ -4,10 +4,14 @@ ...@@ -4,10 +4,14 @@
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h"
#include <utility>
#include "net/quic/quic_chromium_alarm_factory.h" #include "net/quic/quic_chromium_alarm_factory.h"
#include "net/third_party/quic/platform/impl/quic_chromium_clock.h" #include "net/third_party/quic/platform/impl/quic_chromium_clock.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h"
...@@ -15,12 +19,9 @@ ...@@ -15,12 +19,9 @@
namespace blink { namespace blink {
QuicTransportHost::QuicTransportHost( QuicTransportHost::QuicTransportHost(base::WeakPtr<QuicTransportProxy> proxy)
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread, : proxy_(std::move(proxy)) {
base::WeakPtr<QuicTransportProxy> proxy)
: proxy_thread_(std::move(proxy_thread)), proxy_(std::move(proxy)) {
DETACH_FROM_THREAD(thread_checker_); DETACH_FROM_THREAD(thread_checker_);
DCHECK(proxy_thread_);
DCHECK(proxy_); DCHECK(proxy_);
} }
...@@ -35,7 +36,6 @@ QuicTransportHost::~QuicTransportHost() { ...@@ -35,7 +36,6 @@ QuicTransportHost::~QuicTransportHost() {
void QuicTransportHost::Initialize( void QuicTransportHost::Initialize(
IceTransportHost* ice_transport_host, IceTransportHost* ice_transport_host,
scoped_refptr<base::SingleThreadTaskRunner> host_thread,
quic::Perspective perspective, quic::Perspective perspective,
const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates) { const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -43,8 +43,8 @@ void QuicTransportHost::Initialize( ...@@ -43,8 +43,8 @@ void QuicTransportHost::Initialize(
DCHECK(!ice_transport_host_); DCHECK(!ice_transport_host_);
ice_transport_host_ = ice_transport_host; ice_transport_host_ = ice_transport_host;
quic::QuicClock* clock = quic::QuicChromiumClock::GetInstance(); quic::QuicClock* clock = quic::QuicChromiumClock::GetInstance();
auto alarm_factory = auto alarm_factory = std::make_unique<net::QuicChromiumAlarmFactory>(
std::make_unique<net::QuicChromiumAlarmFactory>(host_thread.get(), clock); host_thread().get(), clock);
quic_transport_factory_.reset( quic_transport_factory_.reset(
new P2PQuicTransportFactoryImpl(clock, std::move(alarm_factory))); new P2PQuicTransportFactoryImpl(clock, std::move(alarm_factory)));
P2PQuicTransportConfig config( P2PQuicTransportConfig config(
...@@ -55,6 +55,18 @@ void QuicTransportHost::Initialize( ...@@ -55,6 +55,18 @@ void QuicTransportHost::Initialize(
quic_transport_factory_->CreateQuicTransport(std::move(config)); quic_transport_factory_->CreateQuicTransport(std::move(config));
} }
scoped_refptr<base::SingleThreadTaskRunner> QuicTransportHost::proxy_thread()
const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return ice_transport_host_->proxy_thread();
}
scoped_refptr<base::SingleThreadTaskRunner> QuicTransportHost::host_thread()
const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return ice_transport_host_->host_thread();
}
void QuicTransportHost::Start( void QuicTransportHost::Start(
std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints) { std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -66,17 +78,37 @@ void QuicTransportHost::Stop() { ...@@ -66,17 +78,37 @@ void QuicTransportHost::Stop() {
quic_transport_->Stop(); quic_transport_->Stop();
} }
void QuicTransportHost::CreateStream(
std::unique_ptr<QuicStreamHost> stream_host) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
P2PQuicStream* p2p_stream = quic_transport_->CreateStream();
stream_host->Initialize(this, p2p_stream);
stream_hosts_.insert(
std::make_pair(stream_host.get(), std::move(stream_host)));
}
void QuicTransportHost::OnRemoveStream(QuicStreamHost* stream_host_to_remove) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = stream_hosts_.find(stream_host_to_remove);
DCHECK(it != stream_hosts_.end());
stream_hosts_.erase(it);
}
void QuicTransportHost::OnRemoteStopped() { void QuicTransportHost::OnRemoteStopped() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
stream_hosts_.clear();
PostCrossThreadTask( PostCrossThreadTask(
*proxy_thread_, FROM_HERE, *proxy_thread(), FROM_HERE,
CrossThreadBind(&QuicTransportProxy::OnRemoteStopped, proxy_)); CrossThreadBind(&QuicTransportProxy::OnRemoteStopped, proxy_));
} }
void QuicTransportHost::OnConnectionFailed(const std::string& error_details, void QuicTransportHost::OnConnectionFailed(const std::string& error_details,
bool from_remote) { bool from_remote) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask(*proxy_thread_, FROM_HERE, stream_hosts_.clear();
PostCrossThreadTask(*proxy_thread(), FROM_HERE,
CrossThreadBind(&QuicTransportProxy::OnConnectionFailed, CrossThreadBind(&QuicTransportProxy::OnConnectionFailed,
proxy_, error_details, from_remote)); proxy_, error_details, from_remote));
} }
...@@ -84,8 +116,27 @@ void QuicTransportHost::OnConnectionFailed(const std::string& error_details, ...@@ -84,8 +116,27 @@ void QuicTransportHost::OnConnectionFailed(const std::string& error_details,
void QuicTransportHost::OnConnected() { void QuicTransportHost::OnConnected() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask( PostCrossThreadTask(
*proxy_thread_, FROM_HERE, *proxy_thread(), FROM_HERE,
CrossThreadBind(&QuicTransportProxy::OnConnected, proxy_)); CrossThreadBind(&QuicTransportProxy::OnConnected, proxy_));
} }
void QuicTransportHost::OnStream(P2PQuicStream* p2p_stream) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(p2p_stream);
auto stream_proxy = std::make_unique<QuicStreamProxy>();
auto stream_host = std::make_unique<QuicStreamHost>();
stream_proxy->set_host(stream_host->AsWeakPtr());
stream_host->set_proxy(stream_proxy->AsWeakPtr());
stream_host->Initialize(this, p2p_stream);
stream_hosts_.insert(
std::make_pair(stream_host.get(), std::move(stream_host)));
PostCrossThreadTask(*proxy_thread(), FROM_HERE,
CrossThreadBind(&QuicTransportProxy::OnStream, proxy_,
WTF::Passed(std::move(stream_proxy))));
}
} // namespace blink } // namespace blink
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_HOST_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_HOST_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_HOST_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_HOST_H_
#include <unordered_map>
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
...@@ -16,6 +18,7 @@ namespace blink { ...@@ -16,6 +18,7 @@ namespace blink {
class IceTransportHost; class IceTransportHost;
class P2PQuicTransportFactory; class P2PQuicTransportFactory;
class QuicStreamHost;
class QuicTransportProxy; class QuicTransportProxy;
// The host class is the host side correspondent to the QuicTransportProxy. See // The host class is the host side correspondent to the QuicTransportProxy. See
...@@ -42,32 +45,40 @@ class QuicTransportProxy; ...@@ -42,32 +45,40 @@ class QuicTransportProxy;
// must be called on the host thread. // must be called on the host thread.
class QuicTransportHost final : public P2PQuicTransport::Delegate { class QuicTransportHost final : public P2PQuicTransport::Delegate {
public: public:
QuicTransportHost(scoped_refptr<base::SingleThreadTaskRunner> proxy_thread, QuicTransportHost(base::WeakPtr<QuicTransportProxy> transport_proxy);
base::WeakPtr<QuicTransportProxy> transport_proxy);
~QuicTransportHost() override; ~QuicTransportHost() override;
void Initialize( void Initialize(
IceTransportHost* ice_transport_host, IceTransportHost* ice_transport_host,
scoped_refptr<base::SingleThreadTaskRunner> host_thread,
quic::Perspective perspective, quic::Perspective perspective,
const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates); const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates);
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
void Start( void Start(
std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints); std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints);
void Stop(); void Stop();
void CreateStream(std::unique_ptr<QuicStreamHost> stream_host);
// QuicStreamHost callbacks.
void OnRemoveStream(QuicStreamHost* stream_host_to_remove);
private: private:
// P2PQuicTransport::Delegate overrides. // P2PQuicTransport::Delegate overrides.
void OnRemoteStopped() override; void OnRemoteStopped() override;
void OnConnectionFailed(const std::string& error_details, void OnConnectionFailed(const std::string& error_details,
bool from_remote) override; bool from_remote) override;
void OnConnected() override; void OnConnected() override;
void OnStream(P2PQuicStream* stream) override;
const scoped_refptr<base::SingleThreadTaskRunner> proxy_thread_;
std::unique_ptr<P2PQuicTransportFactory> quic_transport_factory_; std::unique_ptr<P2PQuicTransportFactory> quic_transport_factory_;
std::unique_ptr<P2PQuicTransport> quic_transport_; std::unique_ptr<P2PQuicTransport> quic_transport_;
base::WeakPtr<QuicTransportProxy> proxy_; base::WeakPtr<QuicTransportProxy> proxy_;
IceTransportHost* ice_transport_host_ = nullptr; IceTransportHost* ice_transport_host_ = nullptr;
std::unordered_map<QuicStreamHost*, std::unique_ptr<QuicStreamHost>>
stream_hosts_;
THREAD_CHECKER(thread_checker_); THREAD_CHECKER(thread_checker_);
}; };
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h"
...@@ -32,8 +34,7 @@ QuicTransportProxy::QuicTransportProxy( ...@@ -32,8 +34,7 @@ QuicTransportProxy::QuicTransportProxy(
// The QuicTransportHost is constructed on the proxy thread but should only be // The QuicTransportHost is constructed on the proxy thread but should only be
// interacted with via PostTask to the host thread. The OnTaskRunnerDeleter // interacted with via PostTask to the host thread. The OnTaskRunnerDeleter
// (configured above) will ensure it gets deleted on the host thread. // (configured above) will ensure it gets deleted on the host thread.
host_.reset( host_.reset(new QuicTransportHost(weak_ptr_factory_.GetWeakPtr()));
new QuicTransportHost(proxy_thread, weak_ptr_factory_.GetWeakPtr()));
// Connect to the IceTransportProxy. This gives us a reference to the // Connect to the IceTransportProxy. This gives us a reference to the
// underlying IceTransportHost that should be connected by the // underlying IceTransportHost that should be connected by the
// QuicTransportHost on the host thread. It is safe to post it unretained // QuicTransportHost on the host thread. It is safe to post it unretained
...@@ -42,12 +43,11 @@ QuicTransportProxy::QuicTransportProxy( ...@@ -42,12 +43,11 @@ QuicTransportProxy::QuicTransportProxy(
// object. // object.
IceTransportHost* ice_transport_host = IceTransportHost* ice_transport_host =
ice_transport_proxy->ConnectConsumer(this); ice_transport_proxy->ConnectConsumer(this);
PostCrossThreadTask( PostCrossThreadTask(*host_thread(), FROM_HERE,
*host_thread(), FROM_HERE, CrossThreadBind(&QuicTransportHost::Initialize,
CrossThreadBind(&QuicTransportHost::Initialize, CrossThreadUnretained(host_.get()),
CrossThreadUnretained(host_.get()), CrossThreadUnretained(ice_transport_host),
CrossThreadUnretained(ice_transport_host), host_thread(), perspective, certificates));
perspective, certificates));
} }
QuicTransportProxy::~QuicTransportProxy() { QuicTransportProxy::~QuicTransportProxy() {
...@@ -85,6 +85,36 @@ void QuicTransportProxy::Stop() { ...@@ -85,6 +85,36 @@ void QuicTransportProxy::Stop() {
CrossThreadUnretained(host_.get()))); CrossThreadUnretained(host_.get())));
} }
QuicStreamProxy* QuicTransportProxy::CreateStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto stream_proxy = std::make_unique<QuicStreamProxy>();
auto stream_host = std::make_unique<QuicStreamHost>();
stream_proxy->set_host(stream_host->AsWeakPtr());
stream_host->set_proxy(stream_proxy->AsWeakPtr());
stream_proxy->Initialize(this);
PostCrossThreadTask(*host_thread(), FROM_HERE,
CrossThreadBind(&QuicTransportHost::CreateStream,
CrossThreadUnretained(host_.get()),
WTF::Passed(std::move(stream_host))));
QuicStreamProxy* stream_proxy_ptr = stream_proxy.get();
stream_proxies_.insert(
std::make_pair(stream_proxy_ptr, std::move(stream_proxy)));
return stream_proxy_ptr;
}
void QuicTransportProxy::OnRemoveStream(
QuicStreamProxy* stream_proxy_to_remove) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = stream_proxies_.find(stream_proxy_to_remove);
DCHECK(it != stream_proxies_.end());
stream_proxies_.erase(it);
}
void QuicTransportProxy::OnConnected() { void QuicTransportProxy::OnConnected() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
delegate_->OnConnected(); delegate_->OnConnected();
...@@ -92,6 +122,7 @@ void QuicTransportProxy::OnConnected() { ...@@ -92,6 +122,7 @@ void QuicTransportProxy::OnConnected() {
void QuicTransportProxy::OnRemoteStopped() { void QuicTransportProxy::OnRemoteStopped() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
stream_proxies_.clear();
delegate_->OnRemoteStopped(); delegate_->OnRemoteStopped();
} }
...@@ -99,6 +130,19 @@ void QuicTransportProxy::OnConnectionFailed(const std::string& error_details, ...@@ -99,6 +130,19 @@ void QuicTransportProxy::OnConnectionFailed(const std::string& error_details,
bool from_remote) { bool from_remote) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
delegate_->OnConnectionFailed(error_details, from_remote); delegate_->OnConnectionFailed(error_details, from_remote);
stream_proxies_.clear();
}
void QuicTransportProxy::OnStream(
std::unique_ptr<QuicStreamProxy> stream_proxy) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
stream_proxy->Initialize(this);
QuicStreamProxy* stream_proxy_ptr = stream_proxy.get();
stream_proxies_.insert(
std::make_pair(stream_proxy_ptr, std::move(stream_proxy)));
delegate_->OnStream(stream_proxy_ptr);
} }
} // namespace blink } // namespace blink
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_PROXY_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_PROXY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_PROXY_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_PROXY_H_
#include <unordered_map>
#include <vector> #include <vector>
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
...@@ -22,6 +23,7 @@ struct SSLFingerprint; ...@@ -22,6 +23,7 @@ struct SSLFingerprint;
namespace blink { namespace blink {
class IceTransportProxy; class IceTransportProxy;
class QuicStreamProxy;
class QuicTransportHost; class QuicTransportHost;
// This class allows the QUIC implementation (P2PQuicTransport) to run on a // This class allows the QUIC implementation (P2PQuicTransport) to run on a
...@@ -49,6 +51,8 @@ class QuicTransportProxy final { ...@@ -49,6 +51,8 @@ class QuicTransportProxy final {
// locally by the framer or remotely by the peer. // locally by the framer or remotely by the peer.
virtual void OnConnectionFailed(const std::string& error_details, virtual void OnConnectionFailed(const std::string& error_details,
bool from_remote) {} bool from_remote) {}
// Called when the remote side has created a new stream.
virtual void OnStream(QuicStreamProxy* stream_proxy) {}
}; };
// Construct a Proxy with the underlying QUIC implementation running on the // Construct a Proxy with the underlying QUIC implementation running on the
...@@ -72,18 +76,26 @@ class QuicTransportProxy final { ...@@ -72,18 +76,26 @@ class QuicTransportProxy final {
std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints); std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints);
void Stop(); void Stop();
QuicStreamProxy* CreateStream();
// QuicStreamProxy callbacks.
void OnRemoveStream(QuicStreamProxy* stream_proxy);
private: private:
// Callbacks from QuicTransportHost. // Callbacks from QuicTransportHost.
friend class QuicTransportHost; friend class QuicTransportHost;
void OnConnected(); void OnConnected();
void OnRemoteStopped(); void OnRemoteStopped();
void OnConnectionFailed(const std::string& error_details, bool from_remote); void OnConnectionFailed(const std::string& error_details, bool from_remote);
void OnStream(std::unique_ptr<QuicStreamProxy> stream_proxy);
// Since the Host is deleted on the host thread (Via OnTaskRunnerDeleter), as // Since the Host is deleted on the host thread (Via OnTaskRunnerDeleter), as
// long as this is alive it is safe to post tasks to it (using unretained). // long as this is alive it is safe to post tasks to it (using unretained).
std::unique_ptr<QuicTransportHost, base::OnTaskRunnerDeleter> host_; std::unique_ptr<QuicTransportHost, base::OnTaskRunnerDeleter> host_;
Delegate* const delegate_; Delegate* const delegate_;
IceTransportProxy* ice_transport_proxy_; IceTransportProxy* ice_transport_proxy_;
std::unordered_map<QuicStreamProxy*, std::unique_ptr<QuicStreamProxy>>
stream_proxies_;
THREAD_CHECKER(thread_checker_); THREAD_CHECKER(thread_checker_);
......
...@@ -3,13 +3,20 @@ ...@@ -3,13 +3,20 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
namespace blink { namespace blink {
RTCQuicStream::RTCQuicStream(RTCQuicTransport* transport) RTCQuicStream::RTCQuicStream(ExecutionContext* context,
: transport_(transport) { RTCQuicTransport* transport,
QuicStreamProxy* stream_proxy)
: EventTargetWithInlineData(),
ContextClient(context),
transport_(transport),
proxy_(stream_proxy) {
DCHECK(transport_); DCHECK(transport_);
DCHECK(proxy_);
} }
RTCQuicStream::~RTCQuicStream() = default; RTCQuicStream::~RTCQuicStream() = default;
...@@ -42,13 +49,75 @@ uint32_t RTCQuicStream::writeBufferedAmount() const { ...@@ -42,13 +49,75 @@ uint32_t RTCQuicStream::writeBufferedAmount() const {
return write_buffered_amount_; return write_buffered_amount_;
} }
void RTCQuicStream::finish() {
if (!writeable_) {
return;
}
proxy_->Finish();
writeable_ = false;
if (readable_) {
DCHECK_EQ(state_, RTCQuicStreamState::kOpen);
state_ = RTCQuicStreamState::kClosing;
} else {
DCHECK_EQ(state_, RTCQuicStreamState::kClosing);
Close();
}
}
void RTCQuicStream::reset() {
if (IsClosed()) {
return;
}
proxy_->Reset();
writeable_ = false;
readable_ = false;
Close();
}
void RTCQuicStream::Stop() { void RTCQuicStream::Stop() {
readable_ = false;
writeable_ = false;
state_ = RTCQuicStreamState::kClosed; state_ = RTCQuicStreamState::kClosed;
proxy_ = nullptr;
}
void RTCQuicStream::Close() {
Stop();
transport_->RemoveStream(this);
}
void RTCQuicStream::OnRemoteReset() {
DCHECK_NE(state_, RTCQuicStreamState::kClosed);
Close();
DispatchEvent(*Event::Create(EventTypeNames::statechange));
}
void RTCQuicStream::OnRemoteFinish() {
DCHECK_NE(state_, RTCQuicStreamState::kClosed);
DCHECK(readable_);
readable_ = false;
if (writeable_) {
DCHECK_EQ(state_, RTCQuicStreamState::kOpen);
state_ = RTCQuicStreamState::kClosing;
} else {
DCHECK_EQ(state_, RTCQuicStreamState::kClosing);
Close();
}
DispatchEvent(*Event::Create(EventTypeNames::statechange));
}
const AtomicString& RTCQuicStream::InterfaceName() const {
return EventTargetNames::RTCQuicStream;
}
ExecutionContext* RTCQuicStream::GetExecutionContext() const {
return ContextClient::GetExecutionContext();
} }
void RTCQuicStream::Trace(blink::Visitor* visitor) { void RTCQuicStream::Trace(blink::Visitor* visitor) {
visitor->Trace(transport_); visitor->Trace(transport_);
ScriptWrappable::Trace(visitor); EventTargetWithInlineData::Trace(visitor);
ContextClient::Trace(visitor);
} }
} // namespace blink } // namespace blink
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
namespace blink { namespace blink {
...@@ -14,29 +16,54 @@ class RTCQuicTransport; ...@@ -14,29 +16,54 @@ class RTCQuicTransport;
enum class RTCQuicStreamState { kNew, kOpening, kOpen, kClosing, kClosed }; enum class RTCQuicStreamState { kNew, kOpening, kOpen, kClosing, kClosed };
class MODULES_EXPORT RTCQuicStream final : public ScriptWrappable { class MODULES_EXPORT RTCQuicStream final : public EventTargetWithInlineData,
public ContextClient,
public QuicStreamProxy::Delegate {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
public: public:
RTCQuicStream(RTCQuicTransport* transport); RTCQuicStream(ExecutionContext* context,
RTCQuicTransport* transport,
QuicStreamProxy* stream_proxy);
~RTCQuicStream() override; ~RTCQuicStream() override;
// Called from the RTCQuicTransport when it is being stopped.
void Stop(); void Stop();
bool IsClosed() const { return state_ == RTCQuicStreamState::kClosed; }
// rtc_quic_stream.idl // rtc_quic_stream.idl
RTCQuicTransport* transport() const; RTCQuicTransport* transport() const;
String state() const; String state() const;
uint32_t readBufferedAmount() const; uint32_t readBufferedAmount() const;
uint32_t writeBufferedAmount() const; uint32_t writeBufferedAmount() const;
void finish();
void reset();
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange);
// EventTarget overrides.
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
// For garbage collection. // For garbage collection.
void Trace(blink::Visitor* visitor) override; void Trace(blink::Visitor* visitor) override;
private: private:
// Closes the stream. This will change the state to kClosed and deregister it
// from the RTCQuicTransport. The QuicStreamProxy can no longer be used after
// this point.
void Close();
// QuicStreamProxy::Delegate overrides.
void OnRemoteReset() override;
void OnRemoteFinish() override;
Member<RTCQuicTransport> transport_; Member<RTCQuicTransport> transport_;
RTCQuicStreamState state_ = RTCQuicStreamState::kNew; RTCQuicStreamState state_ = RTCQuicStreamState::kOpen;
bool readable_ = true;
bool writeable_ = true;
uint32_t read_buffered_amount_ = 0; uint32_t read_buffered_amount_ = 0;
uint32_t write_buffered_amount_ = 0; uint32_t write_buffered_amount_ = 0;
QuicStreamProxy* proxy_;
}; };
} // namespace blink } // namespace blink
......
...@@ -14,12 +14,15 @@ enum RTCQuicStreamState { ...@@ -14,12 +14,15 @@ enum RTCQuicStreamState {
// https://w3c.github.io/webrtc-quic/#quicstream* // https://w3c.github.io/webrtc-quic/#quicstream*
[ [
Exposed=Window, Exposed=Window,
RuntimeEnabled=RTCQuicStream RuntimeEnabled=RTCQuicTransport
] interface RTCQuicStream { ] interface RTCQuicStream : EventTarget {
readonly attribute RTCQuicTransport transport; readonly attribute RTCQuicTransport transport;
readonly attribute RTCQuicStreamState state; readonly attribute RTCQuicStreamState state;
readonly attribute unsigned long readBufferedAmount; readonly attribute unsigned long readBufferedAmount;
readonly attribute unsigned long writeBufferedAmount; readonly attribute unsigned long writeBufferedAmount;
void finish();
void reset();
attribute EventHandler onstatechange;
// TODO(crbug.com/868068): Implement remaining methods, attributes, and events. // TODO(crbug.com/868068): Implement remaining methods, attributes, and events.
}; };
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.h"
namespace blink {
RTCQuicStreamEvent* RTCQuicStreamEvent::Create(RTCQuicStream* stream) {
return new RTCQuicStreamEvent(stream);
}
RTCQuicStreamEvent* RTCQuicStreamEvent::Create(
const AtomicString& type,
const RTCQuicStreamEventInit& initializer) {
return new RTCQuicStreamEvent(type, initializer);
}
RTCQuicStreamEvent::RTCQuicStreamEvent(RTCQuicStream* stream)
: Event(EventTypeNames::quicstream, Bubbles::kNo, Cancelable::kNo),
stream_(stream) {}
RTCQuicStreamEvent::RTCQuicStreamEvent(
const AtomicString& type,
const RTCQuicStreamEventInit& initializer)
: Event(type, initializer), stream_(initializer.stream()) {}
RTCQuicStreamEvent::~RTCQuicStreamEvent() = default;
RTCQuicStream* RTCQuicStreamEvent::stream() const {
return stream_.Get();
}
const AtomicString& RTCQuicStreamEvent::InterfaceName() const {
return EventNames::RTCQuicStreamEvent;
}
void RTCQuicStreamEvent::Trace(blink::Visitor* visitor) {
visitor->Trace(stream_);
Event::Trace(visitor);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_EVENT_H_
#include "third_party/blink/renderer/modules/event_modules.h"
namespace blink {
class RTCQuicStream;
class RTCQuicStreamEventInit;
class RTCQuicStreamEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
static RTCQuicStreamEvent* Create(RTCQuicStream* stream);
static RTCQuicStreamEvent* Create(const AtomicString& type,
const RTCQuicStreamEventInit& init);
~RTCQuicStreamEvent() override;
// rtc_quic_stream_event.idl
RTCQuicStream* stream() const;
// Event overrides.
const AtomicString& InterfaceName() const override;
// For garbage collection.
void Trace(blink::Visitor*) override;
private:
RTCQuicStreamEvent(RTCQuicStream* stream);
RTCQuicStreamEvent(const AtomicString& type,
const RTCQuicStreamEventInit& init);
Member<RTCQuicStream> stream_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_EVENT_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://w3c.github.io/webrtc-quic/#rtcquicstreamevent
[
RuntimeEnabled=RTCQuicTransport,
Constructor(DOMString type, optional RTCQuicStreamEventInit eventInitDict),
Exposed=Window
] interface RTCQuicStreamEvent : Event {
readonly attribute RTCQuicStream stream;
};
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://w3c.github.io/webrtc-quic/#dom-rtcquicstreameventinit
dictionary RTCQuicStreamEventInit : EventInit {
RTCQuicStream stream;
};
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h"
namespace blink { namespace blink {
...@@ -199,14 +200,31 @@ void RTCQuicTransport::stop() { ...@@ -199,14 +200,31 @@ void RTCQuicTransport::stop() {
} }
RTCQuicStream* RTCQuicTransport::createStream(ExceptionState& exception_state) { RTCQuicStream* RTCQuicTransport::createStream(ExceptionState& exception_state) {
if (RaiseExceptionIfClosed(exception_state)) { // TODO(github.com/w3c/webrtc-quic/issues/50): Maybe support createStream in
// the 'new' or 'connecting' states.
if (state_ != RTCQuicTransportState::kConnected) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"RTCQuicTransport.createStream() is only "
"valid in the 'connected' state.");
return nullptr; return nullptr;
} }
RTCQuicStream* stream = new RTCQuicStream(this); return AddStream(proxy_->CreateStream());
}
RTCQuicStream* RTCQuicTransport::AddStream(QuicStreamProxy* stream_proxy) {
auto* stream = new RTCQuicStream(GetExecutionContext(), this, stream_proxy);
stream_proxy->set_delegate(stream);
streams_.insert(stream); streams_.insert(stream);
return stream; return stream;
} }
void RTCQuicTransport::RemoveStream(RTCQuicStream* stream) {
DCHECK(stream);
auto it = streams_.find(stream);
DCHECK(it != streams_.end());
streams_.erase(it);
}
void RTCQuicTransport::OnConnected() { void RTCQuicTransport::OnConnected() {
state_ = RTCQuicTransportState::kConnected; state_ = RTCQuicTransportState::kConnected;
DispatchEvent(*Event::Create(EventTypeNames::statechange)); DispatchEvent(*Event::Create(EventTypeNames::statechange));
...@@ -223,6 +241,11 @@ void RTCQuicTransport::OnRemoteStopped() { ...@@ -223,6 +241,11 @@ void RTCQuicTransport::OnRemoteStopped() {
DispatchEvent(*Event::Create(EventTypeNames::statechange)); DispatchEvent(*Event::Create(EventTypeNames::statechange));
} }
void RTCQuicTransport::OnStream(QuicStreamProxy* stream_proxy) {
RTCQuicStream* stream = AddStream(stream_proxy);
DispatchEvent(*RTCQuicStreamEvent::Create(stream));
}
bool RTCQuicTransport::RaiseExceptionIfClosed( bool RTCQuicTransport::RaiseExceptionIfClosed(
ExceptionState& exception_state) const { ExceptionState& exception_state) const {
if (IsClosed()) { if (IsClosed()) {
......
...@@ -44,6 +44,9 @@ class MODULES_EXPORT RTCQuicTransport final ...@@ -44,6 +44,9 @@ class MODULES_EXPORT RTCQuicTransport final
~RTCQuicTransport() override; ~RTCQuicTransport() override;
RTCQuicStream* AddStream(QuicStreamProxy* stream_proxy);
void RemoveStream(RTCQuicStream* stream);
// https://w3c.github.io/webrtc-quic/#quic-transport* // https://w3c.github.io/webrtc-quic/#quic-transport*
RTCIceTransport* transport() const; RTCIceTransport* transport() const;
String state() const; String state() const;
...@@ -57,6 +60,7 @@ class MODULES_EXPORT RTCQuicTransport final ...@@ -57,6 +60,7 @@ class MODULES_EXPORT RTCQuicTransport final
RTCQuicStream* createStream(ExceptionState& exception_state); RTCQuicStream* createStream(ExceptionState& exception_state);
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange); DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(error); DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
DEFINE_ATTRIBUTE_EVENT_LISTENER(quicstream);
// Called by the RTCIceTransport when its start() method is called. // Called by the RTCIceTransport when its start() method is called.
void OnTransportStarted(); void OnTransportStarted();
...@@ -85,6 +89,7 @@ class MODULES_EXPORT RTCQuicTransport final ...@@ -85,6 +89,7 @@ class MODULES_EXPORT RTCQuicTransport final
void OnConnectionFailed(const std::string& error_details, void OnConnectionFailed(const std::string& error_details,
bool from_remote) override; bool from_remote) override;
void OnRemoteStopped() override; void OnRemoteStopped() override;
void OnStream(QuicStreamProxy* stream_proxy) override;
bool IsClosed() const { return state_ == RTCQuicTransportState::kClosed; } bool IsClosed() const { return state_ == RTCQuicTransportState::kClosed; }
bool RaiseExceptionIfClosed(ExceptionState& exception_state) const; bool RaiseExceptionIfClosed(ExceptionState& exception_state) const;
......
...@@ -28,8 +28,8 @@ enum RTCQuicTransportState { ...@@ -28,8 +28,8 @@ enum RTCQuicTransportState {
sequence<ArrayBuffer> getRemoteCertificates(); sequence<ArrayBuffer> getRemoteCertificates();
[RaisesException] void start(RTCQuicParameters remoteParameters); [RaisesException] void start(RTCQuicParameters remoteParameters);
void stop(); void stop();
[RaisesException, RuntimeEnabled=RTCQuicStream] RTCQuicStream createStream(); [RaisesException] RTCQuicStream createStream();
attribute EventHandler onstatechange; attribute EventHandler onstatechange;
attribute EventHandler onerror; attribute EventHandler onerror;
// TODO(crbug.com/868068): Implement onstream. attribute EventHandler onquicstream;
}; };
...@@ -1076,11 +1076,6 @@ ...@@ -1076,11 +1076,6 @@
origin_trial_feature_name: "RtcPeerConnectionId", origin_trial_feature_name: "RtcPeerConnectionId",
status: "experimental", status: "experimental",
}, },
// Enables the use of the RTCQuicStream object.
{
name: "RTCQuicStream",
status: "test",
},
// Enables the use of the RTCQuicTransport object. // Enables the use of the RTCQuicTransport object.
{ {
name: "RTCQuicTransport", name: "RTCQuicTransport",
......
...@@ -47,6 +47,7 @@ _CONFIG = [ ...@@ -47,6 +47,7 @@ _CONFIG = [
'base::SequencedTaskRunner', 'base::SequencedTaskRunner',
'base::SingleThreadTaskRunner', 'base::SingleThreadTaskRunner',
'base::ScopedFD', 'base::ScopedFD',
'base::SupportsWeakPtr',
'base::SysInfo', 'base::SysInfo',
'base::ThreadChecker', 'base::ThreadChecker',
'base::Time', 'base::Time',
......
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