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