1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2020 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "pc/connection_context.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <type_traits>
14*d9f75844SAndroid Build Coastguard Worker #include <utility>
15*d9f75844SAndroid Build Coastguard Worker #include <vector>
16*d9f75844SAndroid Build Coastguard Worker
17*d9f75844SAndroid Build Coastguard Worker #include "api/transport/field_trial_based_config.h"
18*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_engine.h"
19*d9f75844SAndroid Build Coastguard Worker #include "media/sctp/sctp_transport_factory.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/helpers.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/internal/default_socket_server.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_server.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
24*d9f75844SAndroid Build Coastguard Worker
25*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
26*d9f75844SAndroid Build Coastguard Worker
27*d9f75844SAndroid Build Coastguard Worker namespace {
28*d9f75844SAndroid Build Coastguard Worker
MaybeStartNetworkThread(rtc::Thread * old_thread,std::unique_ptr<rtc::SocketFactory> & socket_factory_holder,std::unique_ptr<rtc::Thread> & thread_holder)29*d9f75844SAndroid Build Coastguard Worker rtc::Thread* MaybeStartNetworkThread(
30*d9f75844SAndroid Build Coastguard Worker rtc::Thread* old_thread,
31*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::SocketFactory>& socket_factory_holder,
32*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::Thread>& thread_holder) {
33*d9f75844SAndroid Build Coastguard Worker if (old_thread) {
34*d9f75844SAndroid Build Coastguard Worker return old_thread;
35*d9f75844SAndroid Build Coastguard Worker }
36*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::SocketServer> socket_server =
37*d9f75844SAndroid Build Coastguard Worker rtc::CreateDefaultSocketServer();
38*d9f75844SAndroid Build Coastguard Worker thread_holder = std::make_unique<rtc::Thread>(socket_server.get());
39*d9f75844SAndroid Build Coastguard Worker socket_factory_holder = std::move(socket_server);
40*d9f75844SAndroid Build Coastguard Worker
41*d9f75844SAndroid Build Coastguard Worker thread_holder->SetName("pc_network_thread", nullptr);
42*d9f75844SAndroid Build Coastguard Worker thread_holder->Start();
43*d9f75844SAndroid Build Coastguard Worker return thread_holder.get();
44*d9f75844SAndroid Build Coastguard Worker }
45*d9f75844SAndroid Build Coastguard Worker
MaybeWrapThread(rtc::Thread * signaling_thread,bool & wraps_current_thread)46*d9f75844SAndroid Build Coastguard Worker rtc::Thread* MaybeWrapThread(rtc::Thread* signaling_thread,
47*d9f75844SAndroid Build Coastguard Worker bool& wraps_current_thread) {
48*d9f75844SAndroid Build Coastguard Worker wraps_current_thread = false;
49*d9f75844SAndroid Build Coastguard Worker if (signaling_thread) {
50*d9f75844SAndroid Build Coastguard Worker return signaling_thread;
51*d9f75844SAndroid Build Coastguard Worker }
52*d9f75844SAndroid Build Coastguard Worker auto this_thread = rtc::Thread::Current();
53*d9f75844SAndroid Build Coastguard Worker if (!this_thread) {
54*d9f75844SAndroid Build Coastguard Worker // If this thread isn't already wrapped by an rtc::Thread, create a
55*d9f75844SAndroid Build Coastguard Worker // wrapper and own it in this class.
56*d9f75844SAndroid Build Coastguard Worker this_thread = rtc::ThreadManager::Instance()->WrapCurrentThread();
57*d9f75844SAndroid Build Coastguard Worker wraps_current_thread = true;
58*d9f75844SAndroid Build Coastguard Worker }
59*d9f75844SAndroid Build Coastguard Worker return this_thread;
60*d9f75844SAndroid Build Coastguard Worker }
61*d9f75844SAndroid Build Coastguard Worker
MaybeCreateSctpFactory(std::unique_ptr<SctpTransportFactoryInterface> factory,rtc::Thread * network_thread,const FieldTrialsView & field_trials)62*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SctpTransportFactoryInterface> MaybeCreateSctpFactory(
63*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SctpTransportFactoryInterface> factory,
64*d9f75844SAndroid Build Coastguard Worker rtc::Thread* network_thread,
65*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& field_trials) {
66*d9f75844SAndroid Build Coastguard Worker if (factory) {
67*d9f75844SAndroid Build Coastguard Worker return factory;
68*d9f75844SAndroid Build Coastguard Worker }
69*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_HAVE_SCTP
70*d9f75844SAndroid Build Coastguard Worker return std::make_unique<cricket::SctpTransportFactory>(network_thread);
71*d9f75844SAndroid Build Coastguard Worker #else
72*d9f75844SAndroid Build Coastguard Worker return nullptr;
73*d9f75844SAndroid Build Coastguard Worker #endif
74*d9f75844SAndroid Build Coastguard Worker }
75*d9f75844SAndroid Build Coastguard Worker
76*d9f75844SAndroid Build Coastguard Worker } // namespace
77*d9f75844SAndroid Build Coastguard Worker
78*d9f75844SAndroid Build Coastguard Worker // Static
Create(PeerConnectionFactoryDependencies * dependencies)79*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
80*d9f75844SAndroid Build Coastguard Worker PeerConnectionFactoryDependencies* dependencies) {
81*d9f75844SAndroid Build Coastguard Worker return rtc::scoped_refptr<ConnectionContext>(
82*d9f75844SAndroid Build Coastguard Worker new ConnectionContext(dependencies));
83*d9f75844SAndroid Build Coastguard Worker }
84*d9f75844SAndroid Build Coastguard Worker
ConnectionContext(PeerConnectionFactoryDependencies * dependencies)85*d9f75844SAndroid Build Coastguard Worker ConnectionContext::ConnectionContext(
86*d9f75844SAndroid Build Coastguard Worker PeerConnectionFactoryDependencies* dependencies)
87*d9f75844SAndroid Build Coastguard Worker : network_thread_(MaybeStartNetworkThread(dependencies->network_thread,
88*d9f75844SAndroid Build Coastguard Worker owned_socket_factory_,
89*d9f75844SAndroid Build Coastguard Worker owned_network_thread_)),
90*d9f75844SAndroid Build Coastguard Worker worker_thread_(dependencies->worker_thread,
91*d9f75844SAndroid Build Coastguard Worker []() {
92*d9f75844SAndroid Build Coastguard Worker auto thread_holder = rtc::Thread::Create();
93*d9f75844SAndroid Build Coastguard Worker thread_holder->SetName("pc_worker_thread", nullptr);
94*d9f75844SAndroid Build Coastguard Worker thread_holder->Start();
95*d9f75844SAndroid Build Coastguard Worker return thread_holder;
96*d9f75844SAndroid Build Coastguard Worker }),
97*d9f75844SAndroid Build Coastguard Worker signaling_thread_(MaybeWrapThread(dependencies->signaling_thread,
98*d9f75844SAndroid Build Coastguard Worker wraps_current_thread_)),
99*d9f75844SAndroid Build Coastguard Worker trials_(dependencies->trials ? std::move(dependencies->trials)
100*d9f75844SAndroid Build Coastguard Worker : std::make_unique<FieldTrialBasedConfig>()),
101*d9f75844SAndroid Build Coastguard Worker media_engine_(std::move(dependencies->media_engine)),
102*d9f75844SAndroid Build Coastguard Worker network_monitor_factory_(
103*d9f75844SAndroid Build Coastguard Worker std::move(dependencies->network_monitor_factory)),
104*d9f75844SAndroid Build Coastguard Worker default_network_manager_(std::move(dependencies->network_manager)),
105*d9f75844SAndroid Build Coastguard Worker call_factory_(std::move(dependencies->call_factory)),
106*d9f75844SAndroid Build Coastguard Worker default_socket_factory_(std::move(dependencies->packet_socket_factory)),
107*d9f75844SAndroid Build Coastguard Worker sctp_factory_(
108*d9f75844SAndroid Build Coastguard Worker MaybeCreateSctpFactory(std::move(dependencies->sctp_factory),
109*d9f75844SAndroid Build Coastguard Worker network_thread(),
110*d9f75844SAndroid Build Coastguard Worker *trials_.get())) {
111*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(signaling_thread_);
112*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!(default_network_manager_ && network_monitor_factory_))
113*d9f75844SAndroid Build Coastguard Worker << "You can't set both network_manager and network_monitor_factory.";
114*d9f75844SAndroid Build Coastguard Worker
115*d9f75844SAndroid Build Coastguard Worker signaling_thread_->AllowInvokesToThread(worker_thread());
116*d9f75844SAndroid Build Coastguard Worker signaling_thread_->AllowInvokesToThread(network_thread_);
117*d9f75844SAndroid Build Coastguard Worker worker_thread_->AllowInvokesToThread(network_thread_);
118*d9f75844SAndroid Build Coastguard Worker if (!network_thread_->IsCurrent()) {
119*d9f75844SAndroid Build Coastguard Worker // network_thread_->IsCurrent() == true means signaling_thread_ is
120*d9f75844SAndroid Build Coastguard Worker // network_thread_. In this case, no further action is required as
121*d9f75844SAndroid Build Coastguard Worker // signaling_thread_ can already invoke network_thread_.
122*d9f75844SAndroid Build Coastguard Worker network_thread_->PostTask(
__anond3b917870302null123*d9f75844SAndroid Build Coastguard Worker [thread = network_thread_, worker_thread = worker_thread_.get()] {
124*d9f75844SAndroid Build Coastguard Worker thread->DisallowBlockingCalls();
125*d9f75844SAndroid Build Coastguard Worker thread->DisallowAllInvokes();
126*d9f75844SAndroid Build Coastguard Worker if (worker_thread == thread) {
127*d9f75844SAndroid Build Coastguard Worker // In this case, worker_thread_ == network_thread_
128*d9f75844SAndroid Build Coastguard Worker thread->AllowInvokesToThread(thread);
129*d9f75844SAndroid Build Coastguard Worker }
130*d9f75844SAndroid Build Coastguard Worker });
131*d9f75844SAndroid Build Coastguard Worker }
132*d9f75844SAndroid Build Coastguard Worker
133*d9f75844SAndroid Build Coastguard Worker rtc::InitRandom(rtc::Time32());
134*d9f75844SAndroid Build Coastguard Worker
135*d9f75844SAndroid Build Coastguard Worker rtc::SocketFactory* socket_factory = dependencies->socket_factory;
136*d9f75844SAndroid Build Coastguard Worker if (socket_factory == nullptr) {
137*d9f75844SAndroid Build Coastguard Worker if (owned_socket_factory_) {
138*d9f75844SAndroid Build Coastguard Worker socket_factory = owned_socket_factory_.get();
139*d9f75844SAndroid Build Coastguard Worker } else {
140*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/13145): This case should be deleted. Either
141*d9f75844SAndroid Build Coastguard Worker // require that a PacketSocketFactory and NetworkManager always are
142*d9f75844SAndroid Build Coastguard Worker // injected (with no need to construct these default objects), or require
143*d9f75844SAndroid Build Coastguard Worker // that if a network_thread is injected, an approprite rtc::SocketServer
144*d9f75844SAndroid Build Coastguard Worker // should be injected too.
145*d9f75844SAndroid Build Coastguard Worker socket_factory = network_thread()->socketserver();
146*d9f75844SAndroid Build Coastguard Worker }
147*d9f75844SAndroid Build Coastguard Worker }
148*d9f75844SAndroid Build Coastguard Worker if (!default_network_manager_) {
149*d9f75844SAndroid Build Coastguard Worker // If network_monitor_factory_ is non-null, it will be used to create a
150*d9f75844SAndroid Build Coastguard Worker // network monitor while on the network thread.
151*d9f75844SAndroid Build Coastguard Worker default_network_manager_ = std::make_unique<rtc::BasicNetworkManager>(
152*d9f75844SAndroid Build Coastguard Worker network_monitor_factory_.get(), socket_factory, &field_trials());
153*d9f75844SAndroid Build Coastguard Worker }
154*d9f75844SAndroid Build Coastguard Worker if (!default_socket_factory_) {
155*d9f75844SAndroid Build Coastguard Worker default_socket_factory_ =
156*d9f75844SAndroid Build Coastguard Worker std::make_unique<rtc::BasicPacketSocketFactory>(socket_factory);
157*d9f75844SAndroid Build Coastguard Worker }
158*d9f75844SAndroid Build Coastguard Worker // Set warning levels on the threads, to give warnings when response
159*d9f75844SAndroid Build Coastguard Worker // may be slower than is expected of the thread.
160*d9f75844SAndroid Build Coastguard Worker // Since some of the threads may be the same, start with the least
161*d9f75844SAndroid Build Coastguard Worker // restrictive limits and end with the least permissive ones.
162*d9f75844SAndroid Build Coastguard Worker // This will give warnings for all cases.
163*d9f75844SAndroid Build Coastguard Worker signaling_thread_->SetDispatchWarningMs(100);
164*d9f75844SAndroid Build Coastguard Worker worker_thread_->SetDispatchWarningMs(30);
165*d9f75844SAndroid Build Coastguard Worker network_thread_->SetDispatchWarningMs(10);
166*d9f75844SAndroid Build Coastguard Worker
167*d9f75844SAndroid Build Coastguard Worker if (media_engine_) {
168*d9f75844SAndroid Build Coastguard Worker // TODO(tommi): Change VoiceEngine to do ctor time initialization so that
169*d9f75844SAndroid Build Coastguard Worker // this isn't necessary.
__anond3b917870402null170*d9f75844SAndroid Build Coastguard Worker worker_thread_->BlockingCall([&] { media_engine_->Init(); });
171*d9f75844SAndroid Build Coastguard Worker }
172*d9f75844SAndroid Build Coastguard Worker }
173*d9f75844SAndroid Build Coastguard Worker
~ConnectionContext()174*d9f75844SAndroid Build Coastguard Worker ConnectionContext::~ConnectionContext() {
175*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(signaling_thread_);
176*d9f75844SAndroid Build Coastguard Worker worker_thread_->BlockingCall([&] {
177*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread());
178*d9f75844SAndroid Build Coastguard Worker // While `media_engine_` is const throughout the ConnectionContext's
179*d9f75844SAndroid Build Coastguard Worker // lifetime, it requires destruction to happen on the worker thread. Instead
180*d9f75844SAndroid Build Coastguard Worker // of marking the pointer as non-const, we live with this const_cast<> in
181*d9f75844SAndroid Build Coastguard Worker // the destructor.
182*d9f75844SAndroid Build Coastguard Worker const_cast<std::unique_ptr<cricket::MediaEngineInterface>&>(media_engine_)
183*d9f75844SAndroid Build Coastguard Worker .reset();
184*d9f75844SAndroid Build Coastguard Worker });
185*d9f75844SAndroid Build Coastguard Worker
186*d9f75844SAndroid Build Coastguard Worker // Make sure `worker_thread()` and `signaling_thread()` outlive
187*d9f75844SAndroid Build Coastguard Worker // `default_socket_factory_` and `default_network_manager_`.
188*d9f75844SAndroid Build Coastguard Worker default_socket_factory_ = nullptr;
189*d9f75844SAndroid Build Coastguard Worker default_network_manager_ = nullptr;
190*d9f75844SAndroid Build Coastguard Worker
191*d9f75844SAndroid Build Coastguard Worker if (wraps_current_thread_)
192*d9f75844SAndroid Build Coastguard Worker rtc::ThreadManager::Instance()->UnwrapCurrentThread();
193*d9f75844SAndroid Build Coastguard Worker }
194*d9f75844SAndroid Build Coastguard Worker
195*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
196