xref: /aosp_15_r20/external/webrtc/pc/connection_context.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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