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/BUILD.gn b/pc/BUILD.gn
index dc0f55a..7e82c49 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -206,6 +206,7 @@
   deps = [
     ":audio_rtp_receiver",
     ":audio_track",
+    ":connection_context",
     ":dtmf_sender",
     ":jitter_buffer_delay",
     ":jitter_buffer_delay_interface",
@@ -282,6 +283,24 @@
   ]
 }
 
+rtc_library("connection_context") {
+  sources = [
+    "connection_context.cc",
+    "connection_context.h",
+  ]
+  deps = [
+    ":rtc_pc_base",
+    "../api:libjingle_peerconnection_api",
+    "../api:media_stream_interface",
+    "../api:scoped_refptr",
+    "../api/transport:field_trial_based_config",
+    "../media:rtc_data",
+    "../media:rtc_media_base",
+    "../p2p:rtc_p2p",
+    "../rtc_base",
+  ]
+}
+
 rtc_library("peer_connection_message_handler") {
   sources = [
     "peer_connection_message_handler.cc",
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
diff --git a/pc/connection_context.h b/pc/connection_context.h
new file mode 100644
index 0000000..6dc91a1
--- /dev/null
+++ b/pc/connection_context.h
@@ -0,0 +1,120 @@
+/*
+ *  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.
+ */
+
+#ifndef PC_CONNECTION_CONTEXT_H_
+#define PC_CONNECTION_CONTEXT_H_
+
+#include <memory>
+#include <string>
+
+#include "api/media_stream_interface.h"
+#include "api/peer_connection_interface.h"
+#include "api/scoped_refptr.h"
+#include "media/sctp/sctp_transport_internal.h"
+#include "p2p/base/basic_packet_socket_factory.h"
+#include "pc/channel_manager.h"
+#include "rtc_base/rtc_certificate_generator.h"
+#include "rtc_base/thread.h"
+
+namespace rtc {
+class BasicNetworkManager;
+class BasicPacketSocketFactory;
+}  // namespace rtc
+
+namespace webrtc {
+
+class RtcEventLog;
+
+// This class contains resources needed by PeerConnection and associated
+// objects. A reference to this object is passed to each PeerConnection. The
+// methods on this object are assumed not to change the state in any way that
+// interferes with the operation of other PeerConnections.
+class ConnectionContext : public rtc::RefCountInterface {
+ public:
+  // Functions called from PeerConnectionFactory
+  void SetOptions(const PeerConnectionFactoryInterface::Options& options);
+
+  bool Initialize();
+
+  // Functions called from PeerConnection and friends
+  SctpTransportFactoryInterface* sctp_transport_factory() const {
+    RTC_DCHECK_RUN_ON(signaling_thread());
+    return sctp_factory_.get();
+  }
+
+  cricket::ChannelManager* channel_manager() const;
+
+  rtc::Thread* signaling_thread() const { return signaling_thread_; }
+  rtc::Thread* worker_thread() const { return worker_thread_; }
+  rtc::Thread* network_thread() const { return network_thread_; }
+
+  const PeerConnectionFactoryInterface::Options& options() const {
+    return options_;
+  }
+
+  const WebRtcKeyValueConfig& trials() const { return *trials_.get(); }
+
+  // Accessors only used from the PeerConnectionFactory class
+  rtc::BasicNetworkManager* default_network_manager() const {
+    RTC_DCHECK_RUN_ON(signaling_thread());
+    return default_network_manager_.get();
+  }
+  rtc::BasicPacketSocketFactory* default_socket_factory() const {
+    RTC_DCHECK_RUN_ON(signaling_thread());
+    return default_socket_factory_.get();
+  }
+  CallFactoryInterface* call_factory() const {
+    RTC_DCHECK_RUN_ON(worker_thread());
+    return call_factory_.get();
+  }
+
+ protected:
+  // The Dependencies class allows simple management of all new dependencies
+  // being added to the ConnectionContext.
+  explicit ConnectionContext(PeerConnectionFactoryDependencies& dependencies);
+
+  virtual ~ConnectionContext();
+
+ private:
+  bool wraps_current_thread_;
+  // Note: Since owned_network_thread_ and owned_worker_thread_ are used
+  // in the initialization of network_thread_ and worker_thread_, they
+  // must be declared before them, so that they are initialized first.
+  std::unique_ptr<rtc::Thread> owned_network_thread_
+      RTC_GUARDED_BY(signaling_thread());
+  std::unique_ptr<rtc::Thread> owned_worker_thread_
+      RTC_GUARDED_BY(signaling_thread());
+  rtc::Thread* const network_thread_;
+  rtc::Thread* const worker_thread_;
+  rtc::Thread* const signaling_thread_;
+  PeerConnectionFactoryInterface::Options options_
+      RTC_GUARDED_BY(signaling_thread());
+  // Accessed both on signaling thread and worker thread.
+  std::unique_ptr<cricket::ChannelManager> channel_manager_;
+  std::unique_ptr<rtc::NetworkMonitorFactory> const network_monitor_factory_
+      RTC_GUARDED_BY(signaling_thread());
+  std::unique_ptr<rtc::BasicNetworkManager> default_network_manager_
+      RTC_GUARDED_BY(signaling_thread());
+  std::unique_ptr<webrtc::CallFactoryInterface> const call_factory_
+      RTC_GUARDED_BY(worker_thread());
+
+  std::unique_ptr<rtc::BasicPacketSocketFactory> default_socket_factory_
+      RTC_GUARDED_BY(signaling_thread());
+  std::unique_ptr<cricket::MediaEngineInterface> media_engine_
+      RTC_GUARDED_BY(signaling_thread());
+  std::unique_ptr<SctpTransportFactoryInterface> sctp_factory_
+      RTC_GUARDED_BY(signaling_thread());
+  // Accessed both on signaling thread and worker thread.
+  std::unique_ptr<WebRtcKeyValueConfig> const trials_;
+};
+
+}  // namespace webrtc
+
+#endif  // PC_CONNECTION_CONTEXT_H_
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index bf05151..3b090a2 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -335,10 +335,10 @@
   return !(*this == o);
 }
 
-PeerConnection::PeerConnection(PeerConnectionFactory* factory,
+PeerConnection::PeerConnection(rtc::scoped_refptr<ConnectionContext> context,
                                std::unique_ptr<RtcEventLog> event_log,
                                std::unique_ptr<Call> call)
-    : factory_(factory),
+    : context_(context),
       event_log_(std::move(event_log)),
       event_log_ptr_(event_log_.get()),
       call_(std::move(call)),
@@ -464,7 +464,7 @@
   RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family,
                             kPeerConnectionAddressFamilyCounter_Max);
 
-  const PeerConnectionFactoryInterface::Options& options = factory_->options();
+  const PeerConnectionFactoryInterface::Options& options = context_->options();
 
   // RFC 3264: The numeric value of the session id and version in the
   // o line MUST be representable with a "64 bit signed integer".
@@ -474,7 +474,7 @@
   JsepTransportController::Config config;
   config.redetermine_role_on_ice_restart =
       configuration.redetermine_role_on_ice_restart;
-  config.ssl_max_version = factory_->options().ssl_max_version;
+  config.ssl_max_version = context_->options().ssl_max_version;
   config.disable_encryption = options.disable_encryption;
   config.bundle_policy = configuration.bundle_policy;
   config.rtcp_mux_policy = configuration.rtcp_mux_policy;
@@ -520,7 +520,7 @@
     // DTLS has to be enabled to use SCTP.
     if (!options.disable_sctp_data_channels && dtls_enabled_) {
       data_channel_controller_.set_data_channel_type(cricket::DCT_SCTP);
-      config.sctp_factory = factory_->sctp_transport_factory();
+      config.sctp_factory = context_->sctp_transport_factory();
     }
   }
 
@@ -1650,7 +1650,7 @@
     return;
   }
   auto audio_state =
-      factory_->channel_manager()->media_engine()->voice().GetAudioState();
+      context_->channel_manager()->media_engine()->voice().GetAudioState();
   audio_state->SetPlayout(playout);
 }
 
@@ -1662,7 +1662,7 @@
     return;
   }
   auto audio_state =
-      factory_->channel_manager()->media_engine()->voice().GetAudioState();
+      context_->channel_manager()->media_engine()->voice().GetAudioState();
   audio_state->SetRecording(recording);
 }
 
@@ -1723,7 +1723,7 @@
 bool PeerConnection::StartRtcEventLog(
     std::unique_ptr<RtcEventLogOutput> output) {
   int64_t output_period_ms = webrtc::RtcEventLog::kImmediateOutput;
-  if (absl::StartsWith(factory_->trials().Lookup("WebRTC-RtcEventLogNewFormat"),
+  if (absl::StartsWith(context_->trials().Lookup("WebRTC-RtcEventLogNewFormat"),
                        "Enabled")) {
     output_period_ms = 5000;
   }
@@ -2400,7 +2400,7 @@
   // by experiment.
   if (configuration.disable_ipv6) {
     port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
-  } else if (absl::StartsWith(factory_->trials().Lookup("WebRTC-IPv6Default"),
+  } else if (absl::StartsWith(context_->trials().Lookup("WebRTC-IPv6Default"),
                               "Disabled")) {
     port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
   }
@@ -2480,7 +2480,7 @@
 }
 
 cricket::ChannelManager* PeerConnection::channel_manager() const {
-  return factory_->channel_manager();
+  return context_->channel_manager();
 }
 
 bool PeerConnection::StartRtcEventLog_w(
@@ -3196,7 +3196,7 @@
   // after it has been removed.
   return configuration_.crypto_options.has_value()
              ? *configuration_.crypto_options
-             : factory_->options().crypto_options;
+             : context_->options().crypto_options;
 }
 
 void PeerConnection::ClearStatsCache() {
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index db3621b..8a2be28 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -22,6 +22,7 @@
 #include "api/peer_connection_interface.h"
 #include "api/transport/data_channel_transport_interface.h"
 #include "api/turn_customizer.h"
+#include "pc/connection_context.h"
 #include "pc/data_channel_controller.h"
 #include "pc/ice_server_parsing.h"
 #include "pc/jsep_transport_controller.h"
@@ -71,7 +72,7 @@
                        public RtpSenderBase::SetStreamsObserver,
                        public sigslot::has_slots<> {
  public:
-  explicit PeerConnection(PeerConnectionFactory* factory,
+  explicit PeerConnection(rtc::scoped_refptr<ConnectionContext> context,
                           std::unique_ptr<RtcEventLog> event_log,
                           std::unique_ptr<Call> call);
 
@@ -220,14 +221,14 @@
   void Close() override;
 
   rtc::Thread* signaling_thread() const final {
-    return factory_->signaling_thread();
+    return context_->signaling_thread();
   }
 
   // PeerConnectionInternal implementation.
   rtc::Thread* network_thread() const final {
-    return factory_->network_thread();
+    return context_->network_thread();
   }
-  rtc::Thread* worker_thread() const final { return factory_->worker_thread(); }
+  rtc::Thread* worker_thread() const final { return context_->worker_thread(); }
 
   std::string session_id() const override {
     RTC_DCHECK_RUN_ON(signaling_thread());
@@ -717,7 +718,7 @@
   // However, since the reference counting is done in the
   // PeerConnectionFactoryInterface all instances created using the raw pointer
   // will refer to the same reference count.
-  const rtc::scoped_refptr<PeerConnectionFactory> factory_;
+  const rtc::scoped_refptr<ConnectionContext> context_;
   PeerConnectionObserver* observer_ RTC_GUARDED_BY(signaling_thread()) =
       nullptr;
 
diff --git a/pc/peer_connection_factory.cc b/pc/peer_connection_factory.cc
index 3565c52..9e7c17c 100644
--- a/pc/peer_connection_factory.cc
+++ b/pc/peer_connection_factory.cc
@@ -69,124 +69,45 @@
 
 PeerConnectionFactory::PeerConnectionFactory(
     PeerConnectionFactoryDependencies dependencies)
-    : wraps_current_thread_(false),
-      network_thread_(dependencies.network_thread),
-      worker_thread_(dependencies.worker_thread),
-      signaling_thread_(dependencies.signaling_thread),
+    : context_(new rtc::RefCountedObject<ConnectionContext>(dependencies)),
       task_queue_factory_(std::move(dependencies.task_queue_factory)),
-      network_monitor_factory_(std::move(dependencies.network_monitor_factory)),
-      media_engine_(std::move(dependencies.media_engine)),
-      call_factory_(std::move(dependencies.call_factory)),
       event_log_factory_(std::move(dependencies.event_log_factory)),
       fec_controller_factory_(std::move(dependencies.fec_controller_factory)),
       network_state_predictor_factory_(
           std::move(dependencies.network_state_predictor_factory)),
       injected_network_controller_factory_(
           std::move(dependencies.network_controller_factory)),
-      neteq_factory_(std::move(dependencies.neteq_factory)),
-      sctp_factory_(std::move(dependencies.sctp_factory)),
-      trials_(dependencies.trials ? std::move(dependencies.trials)
-                                  : std::make_unique<FieldTrialBasedConfig>()) {
-  if (!network_thread_) {
-    owned_network_thread_ = rtc::Thread::CreateWithSocketServer();
-    owned_network_thread_->SetName("pc_network_thread", nullptr);
-    owned_network_thread_->Start();
-    network_thread_ = owned_network_thread_.get();
-  }
-
-  if (!worker_thread_) {
-    owned_worker_thread_ = rtc::Thread::Create();
-    owned_worker_thread_->SetName("pc_worker_thread", nullptr);
-    owned_worker_thread_->Start();
-    worker_thread_ = owned_worker_thread_.get();
-  }
-
-  if (!signaling_thread_) {
-    signaling_thread_ = rtc::Thread::Current();
-    if (!signaling_thread_) {
-      // If this thread isn't already wrapped by an rtc::Thread, create a
-      // wrapper and own it in this class.
-      signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
-      wraps_current_thread_ = true;
-    }
-  }
-  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
-}
+      neteq_factory_(std::move(dependencies.neteq_factory)) {}
 
 PeerConnectionFactory::~PeerConnectionFactory() {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
-  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();
+  RTC_DCHECK_RUN_ON(signaling_thread());
 }
 
 bool PeerConnectionFactory::Initialize() {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
-  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);
-  if (!channel_manager_->Init()) {
-    return false;
-  }
-
-  return true;
+  return context_->Initialize();
 }
 
 void PeerConnectionFactory::SetOptions(const Options& options) {
-  options_ = options;
+  context_->SetOptions(options);
 }
 
 RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities(
     cricket::MediaType kind) const {
-  RTC_DCHECK_RUN_ON(signaling_thread_);
+  RTC_DCHECK_RUN_ON(signaling_thread());
   switch (kind) {
     case cricket::MEDIA_TYPE_AUDIO: {
       cricket::AudioCodecs cricket_codecs;
-      channel_manager_->GetSupportedAudioSendCodecs(&cricket_codecs);
+      channel_manager()->GetSupportedAudioSendCodecs(&cricket_codecs);
       return ToRtpCapabilities(
           cricket_codecs,
-          channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions());
+          channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions());
     }
     case cricket::MEDIA_TYPE_VIDEO: {
       cricket::VideoCodecs cricket_codecs;
-      channel_manager_->GetSupportedVideoSendCodecs(&cricket_codecs);
+      channel_manager()->GetSupportedVideoSendCodecs(&cricket_codecs);
       return ToRtpCapabilities(
           cricket_codecs,
-          channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions());
+          channel_manager()->GetDefaultEnabledVideoRtpHeaderExtensions());
     }
     case cricket::MEDIA_TYPE_DATA:
       return RtpCapabilities();
@@ -197,21 +118,21 @@
 
 RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities(
     cricket::MediaType kind) const {
-  RTC_DCHECK_RUN_ON(signaling_thread_);
+  RTC_DCHECK_RUN_ON(signaling_thread());
   switch (kind) {
     case cricket::MEDIA_TYPE_AUDIO: {
       cricket::AudioCodecs cricket_codecs;
-      channel_manager_->GetSupportedAudioReceiveCodecs(&cricket_codecs);
+      channel_manager()->GetSupportedAudioReceiveCodecs(&cricket_codecs);
       return ToRtpCapabilities(
           cricket_codecs,
-          channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions());
+          channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions());
     }
     case cricket::MEDIA_TYPE_VIDEO: {
       cricket::VideoCodecs cricket_codecs;
-      channel_manager_->GetSupportedVideoReceiveCodecs(&cricket_codecs);
+      channel_manager()->GetSupportedVideoReceiveCodecs(&cricket_codecs);
       return ToRtpCapabilities(
           cricket_codecs,
-          channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions());
+          channel_manager()->GetDefaultEnabledVideoRtpHeaderExtensions());
     }
     case cricket::MEDIA_TYPE_DATA:
       return RtpCapabilities();
@@ -222,20 +143,20 @@
 
 rtc::scoped_refptr<AudioSourceInterface>
 PeerConnectionFactory::CreateAudioSource(const cricket::AudioOptions& options) {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
+  RTC_DCHECK(signaling_thread()->IsCurrent());
   rtc::scoped_refptr<LocalAudioSource> source(
       LocalAudioSource::Create(&options));
   return source;
 }
 
 bool PeerConnectionFactory::StartAecDump(FILE* file, int64_t max_size_bytes) {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
-  return channel_manager_->StartAecDump(FileWrapper(file), max_size_bytes);
+  RTC_DCHECK(signaling_thread()->IsCurrent());
+  return channel_manager()->StartAecDump(FileWrapper(file), max_size_bytes);
 }
 
 void PeerConnectionFactory::StopAecDump() {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
-  channel_manager_->StopAecDump();
+  RTC_DCHECK(signaling_thread()->IsCurrent());
+  channel_manager()->StopAecDump();
 }
 
 rtc::scoped_refptr<PeerConnectionInterface>
@@ -256,7 +177,7 @@
 PeerConnectionFactory::CreatePeerConnection(
     const PeerConnectionInterface::RTCConfiguration& configuration,
     PeerConnectionDependencies dependencies) {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
+  RTC_DCHECK(signaling_thread()->IsCurrent());
   RTC_DCHECK(!(dependencies.allocator && dependencies.packet_socket_factory))
       << "You can't set both allocator and packet_socket_factory; "
          "the former is going away (see bugs.webrtc.org/7447";
@@ -264,18 +185,18 @@
   // Set internal defaults if optional dependencies are not set.
   if (!dependencies.cert_generator) {
     dependencies.cert_generator =
-        std::make_unique<rtc::RTCCertificateGenerator>(signaling_thread_,
-                                                       network_thread_);
+        std::make_unique<rtc::RTCCertificateGenerator>(signaling_thread(),
+                                                       network_thread());
   }
   if (!dependencies.allocator) {
     rtc::PacketSocketFactory* packet_socket_factory;
     if (dependencies.packet_socket_factory)
       packet_socket_factory = dependencies.packet_socket_factory.get();
     else
-      packet_socket_factory = default_socket_factory_.get();
+      packet_socket_factory = context_->default_socket_factory();
 
     dependencies.allocator = std::make_unique<cricket::BasicPortAllocator>(
-        default_network_manager_.get(), packet_socket_factory,
+        context_->default_network_manager(), packet_socket_factory,
         configuration.turn_customizer);
   }
 
@@ -289,19 +210,19 @@
         std::make_unique<DefaultIceTransportFactory>();
   }
 
-  dependencies.allocator->SetNetworkIgnoreMask(options_.network_ignore_mask);
+  dependencies.allocator->SetNetworkIgnoreMask(options().network_ignore_mask);
 
   std::unique_ptr<RtcEventLog> event_log =
-      worker_thread_->Invoke<std::unique_ptr<RtcEventLog>>(
+      worker_thread()->Invoke<std::unique_ptr<RtcEventLog>>(
           RTC_FROM_HERE,
           rtc::Bind(&PeerConnectionFactory::CreateRtcEventLog_w, this));
 
-  std::unique_ptr<Call> call = worker_thread_->Invoke<std::unique_ptr<Call>>(
+  std::unique_ptr<Call> call = worker_thread()->Invoke<std::unique_ptr<Call>>(
       RTC_FROM_HERE,
       rtc::Bind(&PeerConnectionFactory::CreateCall_w, this, event_log.get()));
 
   rtc::scoped_refptr<PeerConnection> pc(
-      new rtc::RefCountedObject<PeerConnection>(this, std::move(event_log),
+      new rtc::RefCountedObject<PeerConnection>(context_, std::move(event_log),
                                                 std::move(call)));
   ActionsBeforeInitializeForTesting(pc);
   if (!pc->Initialize(configuration, std::move(dependencies))) {
@@ -312,34 +233,34 @@
 
 rtc::scoped_refptr<MediaStreamInterface>
 PeerConnectionFactory::CreateLocalMediaStream(const std::string& stream_id) {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
-  return MediaStreamProxy::Create(signaling_thread_,
+  RTC_DCHECK(signaling_thread()->IsCurrent());
+  return MediaStreamProxy::Create(signaling_thread(),
                                   MediaStream::Create(stream_id));
 }
 
 rtc::scoped_refptr<VideoTrackInterface> PeerConnectionFactory::CreateVideoTrack(
     const std::string& id,
     VideoTrackSourceInterface* source) {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
+  RTC_DCHECK(signaling_thread()->IsCurrent());
   rtc::scoped_refptr<VideoTrackInterface> track(
-      VideoTrack::Create(id, source, worker_thread_));
-  return VideoTrackProxy::Create(signaling_thread_, worker_thread_, track);
+      VideoTrack::Create(id, source, worker_thread()));
+  return VideoTrackProxy::Create(signaling_thread(), worker_thread(), track);
 }
 
 rtc::scoped_refptr<AudioTrackInterface> PeerConnectionFactory::CreateAudioTrack(
     const std::string& id,
     AudioSourceInterface* source) {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
+  RTC_DCHECK(signaling_thread()->IsCurrent());
   rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source));
-  return AudioTrackProxy::Create(signaling_thread_, track);
+  return AudioTrackProxy::Create(signaling_thread(), track);
 }
 
 cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
-  return channel_manager_.get();
+  return context_->channel_manager();
 }
 
 std::unique_ptr<RtcEventLog> PeerConnectionFactory::CreateRtcEventLog_w() {
-  RTC_DCHECK_RUN_ON(worker_thread_);
+  RTC_DCHECK_RUN_ON(worker_thread());
 
   auto encoding_type = RtcEventLog::EncodingType::Legacy;
   if (IsTrialEnabled("WebRTC-RtcEventLogNewFormat"))
@@ -351,14 +272,14 @@
 
 std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
     RtcEventLog* event_log) {
-  RTC_DCHECK_RUN_ON(worker_thread_);
+  RTC_DCHECK_RUN_ON(worker_thread());
 
   webrtc::Call::Config call_config(event_log);
-  if (!channel_manager_->media_engine() || !call_factory_) {
+  if (!channel_manager()->media_engine() || !context_->call_factory()) {
     return nullptr;
   }
   call_config.audio_state =
-      channel_manager_->media_engine()->voice().GetAudioState();
+      channel_manager()->media_engine()->voice().GetAudioState();
 
   FieldTrialParameter<DataRate> min_bandwidth("min",
                                               DataRate::KilobitsPerSec(30));
@@ -367,7 +288,7 @@
   FieldTrialParameter<DataRate> max_bandwidth("max",
                                               DataRate::KilobitsPerSec(2000));
   ParseFieldTrial({&min_bandwidth, &start_bandwidth, &max_bandwidth},
-                  trials_->Lookup("WebRTC-PcFactoryDefaultBitrates"));
+                  trials().Lookup("WebRTC-PcFactoryDefaultBitrates"));
 
   call_config.bitrate_config.min_bitrate_bps =
       rtc::saturated_cast<int>(min_bandwidth->bps());
@@ -390,14 +311,14 @@
     RTC_LOG(LS_INFO) << "Using default network controller factory";
   }
 
-  call_config.trials = trials_.get();
+  call_config.trials = &trials();
 
-  return std::unique_ptr<Call>(call_factory_->CreateCall(call_config));
+  return std::unique_ptr<Call>(
+      context_->call_factory()->CreateCall(call_config));
 }
 
 bool PeerConnectionFactory::IsTrialEnabled(absl::string_view key) const {
-  RTC_DCHECK(trials_);
-  return absl::StartsWith(trials_->Lookup(key), "Enabled");
+  return absl::StartsWith(trials().Lookup(key), "Enabled");
 }
 
 }  // namespace webrtc
diff --git a/pc/peer_connection_factory.h b/pc/peer_connection_factory.h
index 552d5ab..430eca5 100644
--- a/pc/peer_connection_factory.h
+++ b/pc/peer_connection_factory.h
@@ -20,6 +20,7 @@
 #include "api/scoped_refptr.h"
 #include "media/sctp/sctp_transport_internal.h"
 #include "pc/channel_manager.h"
+#include "pc/connection_context.h"
 #include "rtc_base/rtc_certificate_generator.h"
 #include "rtc_base/thread.h"
 
@@ -72,22 +73,22 @@
   void StopAecDump() override;
 
   SctpTransportFactoryInterface* sctp_transport_factory() {
-    return sctp_factory_.get();
+    return context_->sctp_transport_factory();
   }
 
   virtual cricket::ChannelManager* channel_manager();
 
-  rtc::Thread* signaling_thread() {
+  rtc::Thread* signaling_thread() const {
     // This method can be called on a different thread when the factory is
     // created in CreatePeerConnectionFactory().
-    return signaling_thread_;
+    return context_->signaling_thread();
   }
-  rtc::Thread* worker_thread() { return worker_thread_; }
-  rtc::Thread* network_thread() { return network_thread_; }
+  rtc::Thread* worker_thread() const { return context_->worker_thread(); }
+  rtc::Thread* network_thread() const { return context_->network_thread(); }
 
-  const Options& options() const { return options_; }
+  const Options& options() const { return context_->options(); }
 
-  const WebRtcKeyValueConfig& trials() const { return *trials_.get(); }
+  const WebRtcKeyValueConfig& trials() const { return context_->trials(); }
 
  protected:
   // This structure allows simple management of all new dependencies being added
@@ -103,24 +104,15 @@
 
  private:
   bool IsTrialEnabled(absl::string_view key) const;
+  const cricket::ChannelManager* channel_manager() const {
+    return context_->channel_manager();
+  }
 
   std::unique_ptr<RtcEventLog> CreateRtcEventLog_w();
   std::unique_ptr<Call> CreateCall_w(RtcEventLog* event_log);
 
-  bool wraps_current_thread_;
-  rtc::Thread* network_thread_;
-  rtc::Thread* worker_thread_;
-  rtc::Thread* signaling_thread_;
-  std::unique_ptr<rtc::Thread> owned_network_thread_;
-  std::unique_ptr<rtc::Thread> owned_worker_thread_;
-  const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
-  Options options_;
-  std::unique_ptr<cricket::ChannelManager> channel_manager_;
-  const std::unique_ptr<rtc::NetworkMonitorFactory> network_monitor_factory_;
-  std::unique_ptr<rtc::BasicNetworkManager> default_network_manager_;
-  std::unique_ptr<rtc::BasicPacketSocketFactory> default_socket_factory_;
-  std::unique_ptr<cricket::MediaEngineInterface> media_engine_;
-  std::unique_ptr<webrtc::CallFactoryInterface> call_factory_;
+  rtc::scoped_refptr<ConnectionContext> context_;
+  std::unique_ptr<TaskQueueFactory> task_queue_factory_;
   std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory_;
   std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory_;
   std::unique_ptr<NetworkStatePredictorFactoryInterface>
@@ -128,8 +120,6 @@
   std::unique_ptr<NetworkControllerFactoryInterface>
       injected_network_controller_factory_;
   std::unique_ptr<NetEqFactory> neteq_factory_;
-  std::unique_ptr<SctpTransportFactoryInterface> sctp_factory_;
-  const std::unique_ptr<WebRtcKeyValueConfig> trials_;
 };
 
 }  // namespace webrtc