Simplify ChannelManager initialization.

* A ChannelManager instance is now created via ChannelManager::Create()
* Initialization is performed inside Create(), RAII.
* All member variables in CM are now either const or RTC_GUARDED_BY
  the worker thread.
* Removed dead code (initialization and capturing states are gone).
* ChannelManager now requires construction/destruction on worker thread.
  - one fewer threads that its aware of.
* media_engine_ pointer removed from ConnectionContext.
* Thread policy changes moved from ChannelManager to ConnectionContext.

These changes will make a few other issues easier to fix, so tagging
those bugs with this CL.

Bug: webrtc:12601, webrtc:11988, webrtc:11992, webrtc:11994
Change-Id: I3284cf0a08c773e628af4124e8f52e9faddbe57a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/212617
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33614}
diff --git a/media/base/media_engine.h b/media/base/media_engine.h
index 1d8917c..3baaad2 100644
--- a/media/base/media_engine.h
+++ b/media/base/media_engine.h
@@ -121,9 +121,9 @@
  public:
   virtual ~MediaEngineInterface() {}
 
-  // Initialization
-  // Starts the engine.
+  // Initialization. Needs to be called on the worker thread.
   virtual bool Init() = 0;
+
   virtual VoiceEngineInterface& voice() = 0;
   virtual VideoEngineInterface& video() = 0;
   virtual const VoiceEngineInterface& voice() const = 0;
@@ -141,6 +141,8 @@
   CompositeMediaEngine(std::unique_ptr<VoiceEngineInterface> audio_engine,
                        std::unique_ptr<VideoEngineInterface> video_engine);
   ~CompositeMediaEngine() override;
+
+  // Always succeeds.
   bool Init() override;
 
   VoiceEngineInterface& voice() override;
@@ -150,8 +152,8 @@
 
  private:
   const std::unique_ptr<webrtc::WebRtcKeyValueConfig> trials_;
-  std::unique_ptr<VoiceEngineInterface> voice_engine_;
-  std::unique_ptr<VideoEngineInterface> video_engine_;
+  const std::unique_ptr<VoiceEngineInterface> voice_engine_;
+  const std::unique_ptr<VideoEngineInterface> video_engine_;
 };
 
 enum DataChannelType {
diff --git a/media/engine/null_webrtc_video_engine_unittest.cc b/media/engine/null_webrtc_video_engine_unittest.cc
index 47b9ab2..a23a3b6 100644
--- a/media/engine/null_webrtc_video_engine_unittest.cc
+++ b/media/engine/null_webrtc_video_engine_unittest.cc
@@ -41,8 +41,7 @@
 
   CompositeMediaEngine engine(std::move(audio_engine),
                               std::make_unique<NullWebRtcVideoEngine>());
-
-  EXPECT_TRUE(engine.Init());
+  engine.Init();
 }
 
 }  // namespace cricket
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 4cdefd4..f0bdafa 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -340,6 +340,7 @@
     "../rtc_base",
     "../rtc_base:checks",
     "../rtc_base:threading",
+    "../rtc_base/task_utils:to_queued_task",
   ]
 }
 
diff --git a/pc/channel_manager.cc b/pc/channel_manager.cc
index d16e371..75e728a 100644
--- a/pc/channel_manager.cc
+++ b/pc/channel_manager.cc
@@ -25,45 +25,45 @@
 
 namespace cricket {
 
+// static
+std::unique_ptr<ChannelManager> ChannelManager::Create(
+    std::unique_ptr<MediaEngineInterface> media_engine,
+    std::unique_ptr<DataEngineInterface> data_engine,
+    bool enable_rtx,
+    rtc::Thread* worker_thread,
+    rtc::Thread* network_thread) {
+  RTC_DCHECK_RUN_ON(worker_thread);
+  RTC_DCHECK(network_thread);
+  RTC_DCHECK(worker_thread);
+  RTC_DCHECK(data_engine);
+
+  if (media_engine)
+    media_engine->Init();
+
+  return absl::WrapUnique(new ChannelManager(std::move(media_engine),
+                                             std::move(data_engine), enable_rtx,
+                                             worker_thread, network_thread));
+}
+
 ChannelManager::ChannelManager(
     std::unique_ptr<MediaEngineInterface> media_engine,
     std::unique_ptr<DataEngineInterface> data_engine,
+    bool enable_rtx,
     rtc::Thread* worker_thread,
     rtc::Thread* network_thread)
     : media_engine_(std::move(media_engine)),
       data_engine_(std::move(data_engine)),
-      main_thread_(rtc::Thread::Current()),
       worker_thread_(worker_thread),
-      network_thread_(network_thread) {
+      network_thread_(network_thread),
+      enable_rtx_(enable_rtx) {
   RTC_DCHECK(data_engine_);
   RTC_DCHECK(worker_thread_);
   RTC_DCHECK(network_thread_);
+  RTC_DCHECK_RUN_ON(worker_thread_);
 }
 
 ChannelManager::~ChannelManager() {
-  RTC_DCHECK_RUN_ON(main_thread_);
-  if (initialized_) {
-    Terminate();
-  }
-  // The media engine needs to be deleted on the worker thread for thread safe
-  // destruction,
-  worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] { media_engine_.reset(); });
-}
-
-bool ChannelManager::SetVideoRtxEnabled(bool enable) {
-  RTC_DCHECK_RUN_ON(main_thread_);
-  // To be safe, this call is only allowed before initialization. Apps like
-  // Flute only have a singleton ChannelManager and we don't want this flag to
-  // be toggled between calls or when there's concurrent calls. We expect apps
-  // to enable this at startup and retain that setting for the lifetime of the
-  // app.
-  if (!initialized_) {
-    enable_rtx_ = enable;
-    return true;
-  } else {
-    RTC_LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
-    return false;
-  }
+  RTC_DCHECK_RUN_ON(worker_thread_);
 }
 
 void ChannelManager::GetSupportedAudioSendCodecs(
@@ -121,35 +121,6 @@
   *codecs = data_engine_->data_codecs();
 }
 
-bool ChannelManager::initialized() const {
-  RTC_DCHECK_RUN_ON(main_thread_);
-  return initialized_;
-}
-
-bool ChannelManager::Init() {
-  RTC_DCHECK_RUN_ON(main_thread_);
-  RTC_DCHECK(!initialized_);
-  if (initialized_) {
-    return false;
-  }
-  RTC_DCHECK(network_thread_);
-  RTC_DCHECK(worker_thread_);
-  if (!network_thread_->IsCurrent()) {
-    // Do not allow invoking calls to other threads on the network thread.
-    network_thread_->Invoke<void>(
-        RTC_FROM_HERE, [&] { network_thread_->DisallowBlockingCalls(); });
-  }
-
-  if (media_engine_) {
-    initialized_ = worker_thread_->Invoke<bool>(
-        RTC_FROM_HERE, [&] { return media_engine_->Init(); });
-    RTC_DCHECK(initialized_);
-  } else {
-    initialized_ = true;
-  }
-  return initialized_;
-}
-
 RtpHeaderExtensions ChannelManager::GetDefaultEnabledAudioRtpHeaderExtensions()
     const {
   if (!media_engine_)
@@ -178,24 +149,9 @@
   return media_engine_->video().GetRtpHeaderExtensions();
 }
 
-void ChannelManager::Terminate() {
-  RTC_DCHECK_RUN_ON(main_thread_);
-  RTC_DCHECK(initialized_);
-  if (!initialized_) {
-    return;
-  }
-  // Need to destroy the channels on the worker thread.
-  worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
-    video_channels_.clear();
-    voice_channels_.clear();
-    data_channels_.clear();
-  });
-  initialized_ = false;
-}
-
 VoiceChannel* ChannelManager::CreateVoiceChannel(
     webrtc::Call* call,
-    const cricket::MediaConfig& media_config,
+    const MediaConfig& media_config,
     webrtc::RtpTransportInternal* rtp_transport,
     rtc::Thread* signaling_thread,
     const std::string& content_name,
@@ -249,6 +205,7 @@
     return;
   }
 
+  RTC_DCHECK_RUN_ON(worker_thread_);
   auto it = absl::c_find_if(voice_channels_,
                             [&](const std::unique_ptr<VoiceChannel>& p) {
                               return p.get() == voice_channel;
@@ -263,7 +220,7 @@
 
 VideoChannel* ChannelManager::CreateVideoChannel(
     webrtc::Call* call,
-    const cricket::MediaConfig& media_config,
+    const MediaConfig& media_config,
     webrtc::RtpTransportInternal* rtp_transport,
     rtc::Thread* signaling_thread,
     const std::string& content_name,
@@ -319,6 +276,7 @@
                                  [&] { DestroyVideoChannel(video_channel); });
     return;
   }
+  RTC_DCHECK_RUN_ON(worker_thread_);
 
   auto it = absl::c_find_if(video_channels_,
                             [&](const std::unique_ptr<VideoChannel>& p) {
@@ -333,7 +291,7 @@
 }
 
 RtpDataChannel* ChannelManager::CreateRtpDataChannel(
-    const cricket::MediaConfig& media_config,
+    const MediaConfig& media_config,
     webrtc::RtpTransportInternal* rtp_transport,
     rtc::Thread* signaling_thread,
     const std::string& content_name,
@@ -348,6 +306,8 @@
     });
   }
 
+  RTC_DCHECK_RUN_ON(worker_thread_);
+
   // This is ok to alloc from a thread other than the worker thread.
   DataMediaChannel* media_channel = data_engine_->CreateChannel(media_config);
   if (!media_channel) {
@@ -378,6 +338,7 @@
         RTC_FROM_HERE, [&] { return DestroyRtpDataChannel(data_channel); });
     return;
   }
+  RTC_DCHECK_RUN_ON(worker_thread_);
 
   auto it = absl::c_find_if(data_channels_,
                             [&](const std::unique_ptr<RtpDataChannel>& p) {
@@ -391,6 +352,12 @@
   data_channels_.erase(it);
 }
 
+bool ChannelManager::has_channels() const {
+  RTC_DCHECK_RUN_ON(worker_thread_);
+  return (!voice_channels_.empty() || !video_channels_.empty() ||
+          !data_channels_.empty());
+}
+
 bool ChannelManager::StartAecDump(webrtc::FileWrapper file,
                                   int64_t max_size_bytes) {
   return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
diff --git a/pc/channel_manager.h b/pc/channel_manager.h
index f2a11bc..145bea4 100644
--- a/pc/channel_manager.h
+++ b/pc/channel_manager.h
@@ -45,11 +45,17 @@
 // using device manager.
 class ChannelManager final {
  public:
-  // Construct a ChannelManager with the specified media engine and data engine.
-  ChannelManager(std::unique_ptr<MediaEngineInterface> media_engine,
-                 std::unique_ptr<DataEngineInterface> data_engine,
-                 rtc::Thread* worker_thread,
-                 rtc::Thread* network_thread);
+  // Returns an initialized instance of ChannelManager.
+  // If media_engine is non-nullptr, then the returned ChannelManager instance
+  // will own that reference and media engine initialization
+  static std::unique_ptr<ChannelManager> Create(
+      std::unique_ptr<MediaEngineInterface> media_engine,
+      std::unique_ptr<DataEngineInterface> data_engine,
+      bool enable_rtx,
+      rtc::Thread* worker_thread,
+      rtc::Thread* network_thread);
+
+  ChannelManager() = delete;
   ~ChannelManager();
 
   rtc::Thread* worker_thread() const { return worker_thread_; }
@@ -70,20 +76,13 @@
   std::vector<webrtc::RtpHeaderExtensionCapability>
   GetSupportedVideoRtpHeaderExtensions() const;
 
-  // Indicates whether the media engine is started.
-  bool initialized() const;
-  // Starts up the media engine.
-  bool Init();
-  // Shuts down the media engine.
-  void Terminate();
-
   // The operations below all occur on the worker thread.
   // ChannelManager retains ownership of the created channels, so clients should
   // call the appropriate Destroy*Channel method when done.
 
   // Creates a voice channel, to be associated with the specified session.
   VoiceChannel* CreateVoiceChannel(webrtc::Call* call,
-                                   const cricket::MediaConfig& media_config,
+                                   const MediaConfig& media_config,
                                    webrtc::RtpTransportInternal* rtp_transport,
                                    rtc::Thread* signaling_thread,
                                    const std::string& content_name,
@@ -99,7 +98,7 @@
   // Version of the above that takes PacketTransportInternal.
   VideoChannel* CreateVideoChannel(
       webrtc::Call* call,
-      const cricket::MediaConfig& media_config,
+      const MediaConfig& media_config,
       webrtc::RtpTransportInternal* rtp_transport,
       rtc::Thread* signaling_thread,
       const std::string& content_name,
@@ -112,7 +111,7 @@
   void DestroyVideoChannel(VideoChannel* video_channel);
 
   RtpDataChannel* CreateRtpDataChannel(
-      const cricket::MediaConfig& media_config,
+      const MediaConfig& media_config,
       webrtc::RtpTransportInternal* rtp_transport,
       rtc::Thread* signaling_thread,
       const std::string& content_name,
@@ -123,19 +122,7 @@
   void DestroyRtpDataChannel(RtpDataChannel* data_channel);
 
   // Indicates whether any channels exist.
-  bool has_channels() const {
-    return (!voice_channels_.empty() || !video_channels_.empty() ||
-            !data_channels_.empty());
-  }
-
-  // RTX will be enabled/disabled in engines that support it. The supporting
-  // engines will start offering an RTX codec. Must be called before Init().
-  bool SetVideoRtxEnabled(bool enable);
-
-  // Starts/stops the local microphone and enables polling of the input level.
-  bool capturing() const { return capturing_; }
-
-  // The operations below occur on the main thread.
+  bool has_channels() const;
 
   // Starts AEC dump using existing file, with a specified maximum file size in
   // bytes. When the limit is reached, logging will stop and the file will be
@@ -146,20 +133,26 @@
   void StopAecDump();
 
  private:
-  std::unique_ptr<MediaEngineInterface> media_engine_;  // Nullable.
-  std::unique_ptr<DataEngineInterface> data_engine_;    // Non-null.
-  bool initialized_ RTC_GUARDED_BY(main_thread_) = false;
-  rtc::Thread* const main_thread_;
+  ChannelManager(std::unique_ptr<MediaEngineInterface> media_engine,
+                 std::unique_ptr<DataEngineInterface> data_engine,
+                 bool enable_rtx,
+                 rtc::Thread* worker_thread,
+                 rtc::Thread* network_thread);
+
+  const std::unique_ptr<MediaEngineInterface> media_engine_;  // Nullable.
+  const std::unique_ptr<DataEngineInterface> data_engine_;    // Non-null.
   rtc::Thread* const worker_thread_;
   rtc::Thread* const network_thread_;
 
   // Vector contents are non-null.
-  std::vector<std::unique_ptr<VoiceChannel>> voice_channels_;
-  std::vector<std::unique_ptr<VideoChannel>> video_channels_;
-  std::vector<std::unique_ptr<RtpDataChannel>> data_channels_;
+  std::vector<std::unique_ptr<VoiceChannel>> voice_channels_
+      RTC_GUARDED_BY(worker_thread_);
+  std::vector<std::unique_ptr<VideoChannel>> video_channels_
+      RTC_GUARDED_BY(worker_thread_);
+  std::vector<std::unique_ptr<RtpDataChannel>> data_channels_
+      RTC_GUARDED_BY(worker_thread_);
 
-  bool enable_rtx_ = false;
-  bool capturing_ = false;
+  const bool enable_rtx_;
 };
 
 }  // namespace cricket
diff --git a/pc/channel_manager_unittest.cc b/pc/channel_manager_unittest.cc
index 947acbd..d41fc87 100644
--- a/pc/channel_manager_unittest.cc
+++ b/pc/channel_manager_unittest.cc
@@ -26,11 +26,9 @@
 #include "rtc_base/thread.h"
 #include "test/gtest.h"
 
+namespace cricket {
 namespace {
 const bool kDefaultSrtpRequired = true;
-}
-
-namespace cricket {
 
 static const AudioCodec kAudioCodecs[] = {
     AudioCodec(97, "voice", 1, 2, 3),
@@ -43,86 +41,64 @@
     VideoCodec(96, "rtx"),
 };
 
+std::unique_ptr<MediaEngineInterface> CreateFakeMediaEngine() {
+  auto fme = std::make_unique<FakeMediaEngine>();
+  fme->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs));
+  fme->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs));
+  return fme;
+}
+
+}  // namespace
+
 class ChannelManagerTest : public ::testing::Test {
  protected:
   ChannelManagerTest()
       : network_(rtc::Thread::CreateWithSocketServer()),
-        worker_(rtc::Thread::Create()),
+        worker_(rtc::Thread::Current()),
         video_bitrate_allocator_factory_(
             webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
-        fme_(new cricket::FakeMediaEngine()),
-        fdme_(new cricket::FakeDataEngine()),
-        cm_(new cricket::ChannelManager(
-            std::unique_ptr<MediaEngineInterface>(fme_),
-            std::unique_ptr<DataEngineInterface>(fdme_),
-            worker_.get(),
-            network_.get())),
+        cm_(cricket::ChannelManager::Create(CreateFakeMediaEngine(),
+                                            std::make_unique<FakeDataEngine>(),
+                                            false,
+                                            worker_,
+                                            network_.get())),
         fake_call_() {
-    fme_->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs));
-    fme_->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs));
     network_->SetName("Network", this);
-    worker_->SetName("Worker", this);
     network_->Start();
-    worker_->Start();
   }
 
   void TestCreateDestroyChannels(webrtc::RtpTransportInternal* rtp_transport) {
-    worker_->Invoke<void>(RTC_FROM_HERE, [this, rtp_transport]() {
-      cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
-          &fake_call_, cricket::MediaConfig(), rtp_transport,
-          rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
-          webrtc::CryptoOptions(), &ssrc_generator_, AudioOptions());
-      EXPECT_TRUE(voice_channel != nullptr);
-      cricket::VideoChannel* video_channel = cm_->CreateVideoChannel(
-          &fake_call_, cricket::MediaConfig(), rtp_transport,
-          rtc::Thread::Current(), cricket::CN_VIDEO, kDefaultSrtpRequired,
-          webrtc::CryptoOptions(), &ssrc_generator_, VideoOptions(),
-          video_bitrate_allocator_factory_.get());
-      EXPECT_TRUE(video_channel != nullptr);
-      cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel(
-          cricket::MediaConfig(), rtp_transport, rtc::Thread::Current(),
-          cricket::CN_DATA, kDefaultSrtpRequired, webrtc::CryptoOptions(),
-          &ssrc_generator_);
-      EXPECT_TRUE(rtp_data_channel != nullptr);
-      cm_->DestroyVideoChannel(video_channel);
-      cm_->DestroyVoiceChannel(voice_channel);
-      cm_->DestroyRtpDataChannel(rtp_data_channel);
-    });
-    cm_->Terminate();
+    RTC_DCHECK_RUN_ON(worker_);
+    cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
+        &fake_call_, cricket::MediaConfig(), rtp_transport,
+        rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
+        webrtc::CryptoOptions(), &ssrc_generator_, AudioOptions());
+    EXPECT_TRUE(voice_channel != nullptr);
+    cricket::VideoChannel* video_channel = cm_->CreateVideoChannel(
+        &fake_call_, cricket::MediaConfig(), rtp_transport,
+        rtc::Thread::Current(), cricket::CN_VIDEO, kDefaultSrtpRequired,
+        webrtc::CryptoOptions(), &ssrc_generator_, VideoOptions(),
+        video_bitrate_allocator_factory_.get());
+    EXPECT_TRUE(video_channel != nullptr);
+    cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel(
+        cricket::MediaConfig(), rtp_transport, rtc::Thread::Current(),
+        cricket::CN_DATA, kDefaultSrtpRequired, webrtc::CryptoOptions(),
+        &ssrc_generator_);
+    EXPECT_TRUE(rtp_data_channel != nullptr);
+    cm_->DestroyVideoChannel(video_channel);
+    cm_->DestroyVoiceChannel(voice_channel);
+    cm_->DestroyRtpDataChannel(rtp_data_channel);
   }
 
   std::unique_ptr<rtc::Thread> network_;
-  std::unique_ptr<rtc::Thread> worker_;
+  rtc::Thread* const worker_;
   std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
       video_bitrate_allocator_factory_;
-  // |fme_| and |fdme_| are actually owned by |cm_|.
-  cricket::FakeMediaEngine* fme_;
-  cricket::FakeDataEngine* fdme_;
   std::unique_ptr<cricket::ChannelManager> cm_;
   cricket::FakeCall fake_call_;
   rtc::UniqueRandomIdGenerator ssrc_generator_;
 };
 
-// Test that we startup/shutdown properly.
-TEST_F(ChannelManagerTest, StartupShutdown) {
-  EXPECT_FALSE(cm_->initialized());
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->initialized());
-  cm_->Terminate();
-  EXPECT_FALSE(cm_->initialized());
-}
-
-// Test that we startup/shutdown properly with a worker thread.
-TEST_F(ChannelManagerTest, StartupShutdownOnThread) {
-  EXPECT_FALSE(cm_->initialized());
-  EXPECT_EQ(network_.get(), cm_->network_thread());
-  EXPECT_EQ(worker_.get(), cm_->worker_thread());
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->initialized());
-  cm_->Terminate();
-  EXPECT_FALSE(cm_->initialized());
-}
-
 TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
   std::vector<VideoCodec> send_codecs;
   std::vector<VideoCodec> recv_codecs;
@@ -135,35 +111,25 @@
   EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec));
 
   // Enable and check.
-  EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
+  cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(),
+                                        std::make_unique<FakeDataEngine>(),
+                                        true, worker_, network_.get());
   cm_->GetSupportedVideoSendCodecs(&send_codecs);
   EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec));
   cm_->GetSupportedVideoSendCodecs(&recv_codecs);
   EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec));
 
   // Disable and check.
-  EXPECT_TRUE(cm_->SetVideoRtxEnabled(false));
+  cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(),
+                                        std::make_unique<FakeDataEngine>(),
+                                        false, worker_, network_.get());
   cm_->GetSupportedVideoSendCodecs(&send_codecs);
   EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec));
   cm_->GetSupportedVideoSendCodecs(&recv_codecs);
   EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec));
-
-  // Cannot toggle rtx after initialization.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_FALSE(cm_->SetVideoRtxEnabled(true));
-  EXPECT_FALSE(cm_->SetVideoRtxEnabled(false));
-
-  // Can set again after terminate.
-  cm_->Terminate();
-  EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
-  cm_->GetSupportedVideoSendCodecs(&send_codecs);
-  EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec));
-  cm_->GetSupportedVideoSendCodecs(&recv_codecs);
-  EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec));
 }
 
 TEST_F(ChannelManagerTest, CreateDestroyChannels) {
-  EXPECT_TRUE(cm_->Init());
   auto rtp_dtls_transport = std::make_unique<FakeDtlsTransport>(
       "fake_dtls_transport", cricket::ICE_CANDIDATE_COMPONENT_RTP,
       network_.get());
diff --git a/pc/connection_context.cc b/pc/connection_context.cc
index 858f25d..213a8f3 100644
--- a/pc/connection_context.cc
+++ b/pc/connection_context.cc
@@ -18,6 +18,7 @@
 #include "media/base/rtp_data_engine.h"
 #include "rtc_base/helpers.h"
 #include "rtc_base/ref_counted_object.h"
+#include "rtc_base/task_utils/to_queued_task.h"
 #include "rtc_base/time_utils.h"
 
 namespace webrtc {
@@ -75,11 +76,7 @@
 // Static
 rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
     PeerConnectionFactoryDependencies* dependencies) {
-  auto context = new rtc::RefCountedObject<ConnectionContext>(dependencies);
-  if (!context->channel_manager_->Init()) {
-    return nullptr;
-  }
-  return context;
+  return new rtc::RefCountedObject<ConnectionContext>(dependencies);
 }
 
 ConnectionContext::ConnectionContext(
@@ -97,7 +94,6 @@
       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_(
           MaybeCreateSctpFactory(std::move(dependencies->sctp_factory),
                                  network_thread())),
@@ -107,7 +103,14 @@
   signaling_thread_->AllowInvokesToThread(worker_thread_);
   signaling_thread_->AllowInvokesToThread(network_thread_);
   worker_thread_->AllowInvokesToThread(network_thread_);
-  network_thread_->DisallowAllInvokes();
+  if (network_thread_->IsCurrent()) {
+    network_thread_->DisallowAllInvokes();
+  } else {
+    network_thread_->PostTask(ToQueuedTask([thread = network_thread_] {
+      thread->DisallowBlockingCalls();
+      thread->DisallowAllInvokes();
+    }));
+  }
 
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::InitRandom(rtc::Time32());
@@ -120,11 +123,13 @@
   default_socket_factory_ =
       std::make_unique<rtc::BasicPacketSocketFactory>(network_thread());
 
-  channel_manager_ = std::make_unique<cricket::ChannelManager>(
-      std::move(media_engine_), std::make_unique<cricket::RtpDataEngine>(),
-      worker_thread(), network_thread());
+  worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
+    channel_manager_ = cricket::ChannelManager::Create(
+        std::move(dependencies->media_engine),
+        std::make_unique<cricket::RtpDataEngine>(), /*enable_rtx=*/true,
+        worker_thread(), network_thread());
+  });
 
-  channel_manager_->SetVideoRtxEnabled(true);
   // Set warning levels on the threads, to give warnings when response
   // may be slower than is expected of the thread.
   // Since some of the threads may be the same, start with the least
@@ -137,7 +142,8 @@
 
 ConnectionContext::~ConnectionContext() {
   RTC_DCHECK_RUN_ON(signaling_thread_);
-  channel_manager_.reset(nullptr);
+  worker_thread_->Invoke<void>(RTC_FROM_HERE,
+                               [&]() { channel_manager_.reset(nullptr); });
 
   // Make sure |worker_thread()| and |signaling_thread()| outlive
   // |default_socket_factory_| and |default_network_manager_|.
diff --git a/pc/connection_context.h b/pc/connection_context.h
index 7d4c56b..29ae99a 100644
--- a/pc/connection_context.h
+++ b/pc/connection_context.h
@@ -120,8 +120,6 @@
 
   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> const sctp_factory_;
   // Accessed both on signaling thread and worker thread.
   std::unique_ptr<WebRtcKeyValueConfig> const trials_;
diff --git a/pc/rtp_sender_receiver_unittest.cc b/pc/rtp_sender_receiver_unittest.cc
index 364e87a..4d6d58d 100644
--- a/pc/rtp_sender_receiver_unittest.cc
+++ b/pc/rtp_sender_receiver_unittest.cc
@@ -108,24 +108,25 @@
         // Create fake media engine/etc. so we can create channels to use to
         // test RtpSenders/RtpReceivers.
         media_engine_(new cricket::FakeMediaEngine()),
-        channel_manager_(absl::WrapUnique(media_engine_),
-                         std::make_unique<cricket::RtpDataEngine>(),
-                         worker_thread_,
-                         network_thread_),
         fake_call_(),
         local_stream_(MediaStream::Create(kStreamId1)) {
-    // Create channels to be used by the RtpSenders and RtpReceivers.
-    channel_manager_.Init();
+    worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
+      channel_manager_ = cricket::ChannelManager::Create(
+          absl::WrapUnique(media_engine_),
+          std::make_unique<cricket::RtpDataEngine>(), false, worker_thread_,
+          network_thread_);
+    });
+
     bool srtp_required = true;
     rtp_dtls_transport_ = std::make_unique<cricket::FakeDtlsTransport>(
         "fake_dtls_transport", cricket::ICE_CANDIDATE_COMPONENT_RTP);
     rtp_transport_ = CreateDtlsSrtpTransport();
 
-    voice_channel_ = channel_manager_.CreateVoiceChannel(
+    voice_channel_ = channel_manager_->CreateVoiceChannel(
         &fake_call_, cricket::MediaConfig(), rtp_transport_.get(),
         rtc::Thread::Current(), cricket::CN_AUDIO, srtp_required,
         webrtc::CryptoOptions(), &ssrc_generator_, cricket::AudioOptions());
-    video_channel_ = channel_manager_.CreateVideoChannel(
+    video_channel_ = channel_manager_->CreateVideoChannel(
         &fake_call_, cricket::MediaConfig(), rtp_transport_.get(),
         rtc::Thread::Current(), cricket::CN_VIDEO, srtp_required,
         webrtc::CryptoOptions(), &ssrc_generator_, cricket::VideoOptions(),
@@ -161,6 +162,18 @@
         cricket::StreamParams::CreateLegacy(kVideoSsrc2));
   }
 
+  ~RtpSenderReceiverTest() {
+    audio_rtp_sender_ = nullptr;
+    video_rtp_sender_ = nullptr;
+    audio_rtp_receiver_ = nullptr;
+    video_rtp_receiver_ = nullptr;
+    local_stream_ = nullptr;
+    video_track_ = nullptr;
+    audio_track_ = nullptr;
+    worker_thread_->Invoke<void>(RTC_FROM_HERE,
+                                 [&]() { channel_manager_.reset(); });
+  }
+
   std::unique_ptr<webrtc::RtpTransportInternal> CreateDtlsSrtpTransport() {
     auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
         /*rtcp_mux_required=*/true);
@@ -497,7 +510,7 @@
       video_bitrate_allocator_factory_;
   // |media_engine_| is actually owned by |channel_manager_|.
   cricket::FakeMediaEngine* media_engine_;
-  cricket::ChannelManager channel_manager_;
+  std::unique_ptr<cricket::ChannelManager> channel_manager_;
   cricket::FakeCall fake_call_;
   cricket::VoiceChannel* voice_channel_;
   cricket::VideoChannel* video_channel_;
diff --git a/pc/rtp_transceiver_unittest.cc b/pc/rtp_transceiver_unittest.cc
index 7b72620..fe5c312 100644
--- a/pc/rtp_transceiver_unittest.cc
+++ b/pc/rtp_transceiver_unittest.cc
@@ -82,21 +82,23 @@
 class RtpTransceiverUnifiedPlanTest : public ::testing::Test {
  public:
   RtpTransceiverUnifiedPlanTest()
-      : channel_manager_(std::make_unique<cricket::FakeMediaEngine>(),
-                         std::make_unique<cricket::FakeDataEngine>(),
-                         rtc::Thread::Current(),
-                         rtc::Thread::Current()),
+      : channel_manager_(cricket::ChannelManager::Create(
+            std::make_unique<cricket::FakeMediaEngine>(),
+            std::make_unique<cricket::FakeDataEngine>(),
+            false,
+            rtc::Thread::Current(),
+            rtc::Thread::Current())),
         transceiver_(RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
                          rtc::Thread::Current(),
                          new rtc::RefCountedObject<MockRtpSenderInternal>()),
                      RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
                          rtc::Thread::Current(),
                          new rtc::RefCountedObject<MockRtpReceiverInternal>()),
-                     &channel_manager_,
-                     channel_manager_.GetSupportedAudioRtpHeaderExtensions(),
+                     channel_manager_.get(),
+                     channel_manager_->GetSupportedAudioRtpHeaderExtensions(),
                      /* on_negotiation_needed= */ [] {}) {}
 
-  cricket::ChannelManager channel_manager_;
+  std::unique_ptr<cricket::ChannelManager> channel_manager_;
   RtpTransceiver transceiver_;
 };
 
@@ -117,10 +119,12 @@
 class RtpTransceiverTestForHeaderExtensions : public ::testing::Test {
  public:
   RtpTransceiverTestForHeaderExtensions()
-      : channel_manager_(std::make_unique<cricket::FakeMediaEngine>(),
-                         std::make_unique<cricket::FakeDataEngine>(),
-                         rtc::Thread::Current(),
-                         rtc::Thread::Current()),
+      : channel_manager_(cricket::ChannelManager::Create(
+            std::make_unique<cricket::FakeMediaEngine>(),
+            std::make_unique<cricket::FakeDataEngine>(),
+            false,
+            rtc::Thread::Current(),
+            rtc::Thread::Current())),
         extensions_(
             {RtpHeaderExtensionCapability("uri1",
                                           1,
@@ -140,11 +144,11 @@
                      RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
                          rtc::Thread::Current(),
                          new rtc::RefCountedObject<MockRtpReceiverInternal>()),
-                     &channel_manager_,
+                     channel_manager_.get(),
                      extensions_,
                      /* on_negotiation_needed= */ [] {}) {}
 
-  cricket::ChannelManager channel_manager_;
+  std::unique_ptr<cricket::ChannelManager> channel_manager_;
   std::vector<RtpHeaderExtensionCapability> extensions_;
   RtpTransceiver transceiver_;
 };