Separate PC resources required at runtime from PCfactory
This enables modules that share the resources to reuse the connection
context object but not take a dependency on PeerConnectionFactory.
Bug: webrtc:11967
Change-Id: Ic68cbf061b3226f02f8638abd79ad881e89951d4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/188120
Reviewed-by: Tommi <tommi@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32412}
diff --git a/pc/connection_context.cc b/pc/connection_context.cc
new file mode 100644
index 0000000..846a53e
--- /dev/null
+++ b/pc/connection_context.cc
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "pc/connection_context.h"
+
+#include <utility>
+
+#include "api/transport/field_trial_based_config.h"
+#include "media/base/rtp_data_engine.h"
+
+namespace webrtc {
+
+namespace {
+
+rtc::Thread* MaybeStartThread(rtc::Thread* old_thread,
+ const std::string& thread_name,
+ bool with_socket_server,
+ std::unique_ptr<rtc::Thread>* thread_holder) {
+ if (old_thread) {
+ return old_thread;
+ }
+ if (with_socket_server) {
+ *thread_holder = rtc::Thread::CreateWithSocketServer();
+ } else {
+ *thread_holder = rtc::Thread::Create();
+ }
+ (*thread_holder)->SetName(thread_name, nullptr);
+ (*thread_holder)->Start();
+ return (*thread_holder).get();
+}
+
+rtc::Thread* MaybeWrapThread(rtc::Thread* signaling_thread,
+ bool* wraps_current_thread) {
+ *wraps_current_thread = false;
+ if (signaling_thread) {
+ return signaling_thread;
+ }
+ auto this_thread = rtc::Thread::Current();
+ if (!this_thread) {
+ // If this thread isn't already wrapped by an rtc::Thread, create a
+ // wrapper and own it in this class.
+ this_thread = rtc::ThreadManager::Instance()->WrapCurrentThread();
+ *wraps_current_thread = true;
+ }
+ return this_thread;
+}
+
+} // namespace
+
+ConnectionContext::ConnectionContext(
+ PeerConnectionFactoryDependencies& dependencies)
+ : network_thread_(MaybeStartThread(dependencies.network_thread,
+ "pc_network_thread",
+ true,
+ &owned_network_thread_)),
+ worker_thread_(MaybeStartThread(dependencies.worker_thread,
+ "pc_worker_thread",
+ false,
+ &owned_worker_thread_)),
+ signaling_thread_(MaybeWrapThread(dependencies.signaling_thread,
+ &wraps_current_thread_)),
+ network_monitor_factory_(std::move(dependencies.network_monitor_factory)),
+ call_factory_(std::move(dependencies.call_factory)),
+ media_engine_(std::move(dependencies.media_engine)),
+ sctp_factory_(std::move(dependencies.sctp_factory)),
+ trials_(dependencies.trials ? std::move(dependencies.trials)
+ : std::make_unique<FieldTrialBasedConfig>()) {
+ signaling_thread_->AllowInvokesToThread(worker_thread_);
+ signaling_thread_->AllowInvokesToThread(network_thread_);
+ worker_thread_->AllowInvokesToThread(network_thread_);
+ network_thread_->DisallowAllInvokes();
+
+#ifdef HAVE_SCTP
+ if (!sctp_factory_) {
+ sctp_factory_ =
+ std::make_unique<cricket::SctpTransportFactory>(network_thread());
+ }
+#endif
+}
+
+ConnectionContext::~ConnectionContext() {
+ RTC_DCHECK_RUN_ON(signaling_thread());
+ channel_manager_.reset(nullptr);
+
+ // Make sure |worker_thread()| and |signaling_thread()| outlive
+ // |default_socket_factory_| and |default_network_manager_|.
+ default_socket_factory_ = nullptr;
+ default_network_manager_ = nullptr;
+
+ if (wraps_current_thread_)
+ rtc::ThreadManager::Instance()->UnwrapCurrentThread();
+}
+
+void ConnectionContext::SetOptions(
+ const PeerConnectionFactoryInterface::Options& options) {
+ RTC_DCHECK_RUN_ON(signaling_thread());
+ options_ = options;
+}
+
+bool ConnectionContext::Initialize() {
+ RTC_DCHECK_RUN_ON(signaling_thread());
+ rtc::InitRandom(rtc::Time32());
+
+ // If network_monitor_factory_ is non-null, it will be used to create a
+ // network monitor while on the network thread.
+ default_network_manager_.reset(
+ new rtc::BasicNetworkManager(network_monitor_factory_.get()));
+ if (!default_network_manager_) {
+ return false;
+ }
+
+ default_socket_factory_.reset(
+ new rtc::BasicPacketSocketFactory(network_thread()));
+ if (!default_socket_factory_) {
+ return false;
+ }
+
+ channel_manager_ = std::make_unique<cricket::ChannelManager>(
+ std::move(media_engine_), std::make_unique<cricket::RtpDataEngine>(),
+ worker_thread(), network_thread());
+
+ channel_manager_->SetVideoRtxEnabled(true);
+ return channel_manager_->Init();
+}
+
+cricket::ChannelManager* ConnectionContext::channel_manager() const {
+ return channel_manager_.get();
+}
+
+} // namespace webrtc