| Index: webrtc/pc/channel_unittest.cc
 | 
| diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc
 | 
| index d6401a593515504ff1f2c31d7b48af69e2db8a72..57e7afb17946c6077a01c10ee72171f4783e3b82 100644
 | 
| --- a/webrtc/pc/channel_unittest.cc
 | 
| +++ b/webrtc/pc/channel_unittest.cc
 | 
| @@ -21,8 +21,9 @@
 | 
|  #include "webrtc/media/base/fakertp.h"
 | 
|  #include "webrtc/media/base/mediachannel.h"
 | 
|  #include "webrtc/media/base/testutils.h"
 | 
| -#include "webrtc/p2p/base/dtlstransportinternal.h"
 | 
| -#include "webrtc/p2p/base/faketransportcontroller.h"
 | 
| +#include "webrtc/p2p/base/fakecandidatepair.h"
 | 
| +#include "webrtc/p2p/base/fakedtlstransport.h"
 | 
| +#include "webrtc/p2p/base/fakepackettransport.h"
 | 
|  #include "webrtc/pc/channel.h"
 | 
|  
 | 
|  using cricket::CA_OFFER;
 | 
| @@ -96,7 +97,10 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      SECURE = 0x4,
 | 
|      SSRC_MUX = 0x8,
 | 
|      DTLS = 0x10,
 | 
| -    GCM_CIPHER = 0x20
 | 
| +    GCM_CIPHER = 0x20,
 | 
| +    // Use BaseChannel with PacketTransportInterface rather than
 | 
| +    // DtlsTransportInternal.
 | 
| +    RAW_PACKET_TRANSPORT = 0x40,
 | 
|    };
 | 
|  
 | 
|    ChannelTest(bool verify_playout,
 | 
| @@ -104,24 +108,15 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|                rtc::ArrayView<const uint8_t> rtcp_data,
 | 
|                NetworkIsWorker network_is_worker)
 | 
|        : verify_playout_(verify_playout),
 | 
| -        media_channel1_(NULL),
 | 
| -        media_channel2_(NULL),
 | 
|          rtp_packet_(rtp_data.data(), rtp_data.size()),
 | 
| -        rtcp_packet_(rtcp_data.data(), rtcp_data.size()),
 | 
| -        media_info_callbacks1_(),
 | 
| -        media_info_callbacks2_() {
 | 
| +        rtcp_packet_(rtcp_data.data(), rtcp_data.size()) {
 | 
|      if (network_is_worker == NetworkIsWorker::Yes) {
 | 
|        network_thread_ = rtc::Thread::Current();
 | 
|      } else {
 | 
|        network_thread_keeper_ = rtc::Thread::Create();
 | 
|        network_thread_keeper_->SetName("Network", nullptr);
 | 
| -      network_thread_keeper_->Start();
 | 
|        network_thread_ = network_thread_keeper_.get();
 | 
|      }
 | 
| -    transport_controller1_.reset(new cricket::FakeTransportController(
 | 
| -        network_thread_, cricket::ICEROLE_CONTROLLING));
 | 
| -    transport_controller2_.reset(new cricket::FakeTransportController(
 | 
| -        network_thread_, cricket::ICEROLE_CONTROLLED));
 | 
|    }
 | 
|  
 | 
|    void CreateChannels(int flags1, int flags2) {
 | 
| @@ -133,28 +128,101 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|                        typename T::MediaChannel* ch2,
 | 
|                        int flags1,
 | 
|                        int flags2) {
 | 
| +    // Network thread is started in CreateChannels, to allow the test to
 | 
| +    // configure a fake clock before any threads are spawned and attempt to
 | 
| +    // access the time.
 | 
| +    if (network_thread_keeper_) {
 | 
| +      network_thread_keeper_->Start();
 | 
| +    }
 | 
|      // Make sure RTCP_MUX_REQUIRED isn't set without RTCP_MUX.
 | 
| -    ASSERT_NE(RTCP_MUX_REQUIRED, flags1 & (RTCP_MUX | RTCP_MUX_REQUIRED));
 | 
| -    ASSERT_NE(RTCP_MUX_REQUIRED, flags2 & (RTCP_MUX | RTCP_MUX_REQUIRED));
 | 
| +    RTC_DCHECK_NE(RTCP_MUX_REQUIRED, flags1 & (RTCP_MUX | RTCP_MUX_REQUIRED));
 | 
| +    RTC_DCHECK_NE(RTCP_MUX_REQUIRED, flags2 & (RTCP_MUX | RTCP_MUX_REQUIRED));
 | 
| +    // Make sure if using raw packet transports, they're used for both
 | 
| +    // channels.
 | 
| +    RTC_DCHECK_EQ(flags1 & RAW_PACKET_TRANSPORT, flags2 & RAW_PACKET_TRANSPORT);
 | 
|      rtc::Thread* worker_thread = rtc::Thread::Current();
 | 
|      media_channel1_ = ch1;
 | 
|      media_channel2_ = ch2;
 | 
| +    rtc::PacketTransportInterface* rtp1 = nullptr;
 | 
| +    rtc::PacketTransportInterface* rtcp1 = nullptr;
 | 
| +    rtc::PacketTransportInterface* rtp2 = nullptr;
 | 
| +    rtc::PacketTransportInterface* rtcp2 = nullptr;
 | 
| +    // Based on flags, create fake DTLS or raw packet transports.
 | 
| +    if (flags1 & RAW_PACKET_TRANSPORT) {
 | 
| +      fake_rtp_packet_transport1_.reset(
 | 
| +          new rtc::FakePacketTransport("channel1_rtp"));
 | 
| +      rtp1 = fake_rtp_packet_transport1_.get();
 | 
| +      if (!(flags1 & RTCP_MUX_REQUIRED)) {
 | 
| +        fake_rtcp_packet_transport1_.reset(
 | 
| +            new rtc::FakePacketTransport("channel1_rtcp"));
 | 
| +        rtcp1 = fake_rtcp_packet_transport1_.get();
 | 
| +      }
 | 
| +    } else {
 | 
| +      // Confirmed to work with KT_RSA and KT_ECDSA.
 | 
| +      fake_rtp_dtls_transport1_.reset(new cricket::FakeDtlsTransport(
 | 
| +          "channel1", cricket::ICE_CANDIDATE_COMPONENT_RTP));
 | 
| +      rtp1 = fake_rtp_dtls_transport1_.get();
 | 
| +      if (!(flags1 & RTCP_MUX_REQUIRED)) {
 | 
| +        fake_rtcp_dtls_transport1_.reset(new cricket::FakeDtlsTransport(
 | 
| +            "channel1", cricket::ICE_CANDIDATE_COMPONENT_RTCP));
 | 
| +        rtcp1 = fake_rtcp_dtls_transport1_.get();
 | 
| +      }
 | 
| +      if (flags1 & DTLS) {
 | 
| +        auto cert1 =
 | 
| +            rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
 | 
| +                rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
 | 
| +        fake_rtp_dtls_transport1_->SetLocalCertificate(cert1);
 | 
| +        if (fake_rtcp_dtls_transport1_) {
 | 
| +          fake_rtcp_dtls_transport1_->SetLocalCertificate(cert1);
 | 
| +        }
 | 
| +      }
 | 
| +    }
 | 
| +    // Based on flags, create fake DTLS or raw packet transports.
 | 
| +    if (flags2 & RAW_PACKET_TRANSPORT) {
 | 
| +      fake_rtp_packet_transport2_.reset(
 | 
| +          new rtc::FakePacketTransport("channel2_rtp"));
 | 
| +      rtp2 = fake_rtp_packet_transport2_.get();
 | 
| +      if (!(flags2 & RTCP_MUX_REQUIRED)) {
 | 
| +        fake_rtcp_packet_transport2_.reset(
 | 
| +            new rtc::FakePacketTransport("channel2_rtcp"));
 | 
| +        rtcp2 = fake_rtcp_packet_transport2_.get();
 | 
| +      }
 | 
| +    } else {
 | 
| +      // Confirmed to work with KT_RSA and KT_ECDSA.
 | 
| +      fake_rtp_dtls_transport2_.reset(new cricket::FakeDtlsTransport(
 | 
| +          "channel2", cricket::ICE_CANDIDATE_COMPONENT_RTP));
 | 
| +      rtp2 = fake_rtp_dtls_transport2_.get();
 | 
| +      if (!(flags2 & RTCP_MUX_REQUIRED)) {
 | 
| +        fake_rtcp_dtls_transport2_.reset(new cricket::FakeDtlsTransport(
 | 
| +            "channel2", cricket::ICE_CANDIDATE_COMPONENT_RTCP));
 | 
| +        rtcp2 = fake_rtcp_dtls_transport2_.get();
 | 
| +      }
 | 
| +      if (flags2 & DTLS) {
 | 
| +        auto cert2 =
 | 
| +            rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
 | 
| +                rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)));
 | 
| +        fake_rtp_dtls_transport2_->SetLocalCertificate(cert2);
 | 
| +        if (fake_rtcp_dtls_transport2_) {
 | 
| +          fake_rtcp_dtls_transport2_->SetLocalCertificate(cert2);
 | 
| +        }
 | 
| +      }
 | 
| +    }
 | 
|      channel1_.reset(
 | 
|          CreateChannel(worker_thread, network_thread_, &media_engine_, ch1,
 | 
| -                      transport_controller1_.get(), flags1));
 | 
| +                      fake_rtp_dtls_transport1_.get(),
 | 
| +                      fake_rtcp_dtls_transport1_.get(), rtp1, rtcp1, flags1));
 | 
|      channel2_.reset(
 | 
|          CreateChannel(worker_thread, network_thread_, &media_engine_, ch2,
 | 
| -                      transport_controller2_.get(), flags2));
 | 
| +                      fake_rtp_dtls_transport2_.get(),
 | 
| +                      fake_rtcp_dtls_transport2_.get(), rtp2, rtcp2, flags2));
 | 
|      channel1_->SignalMediaMonitor.connect(this,
 | 
|                                            &ChannelTest<T>::OnMediaMonitor1);
 | 
|      channel2_->SignalMediaMonitor.connect(this,
 | 
|                                            &ChannelTest<T>::OnMediaMonitor2);
 | 
|      channel1_->SignalRtcpMuxFullyActive.connect(
 | 
| -        transport_controller1_.get(),
 | 
| -        &cricket::FakeTransportController::DestroyRtcpTransport);
 | 
| +        this, &ChannelTest<T>::OnRtcpMuxFullyActive1);
 | 
|      channel2_->SignalRtcpMuxFullyActive.connect(
 | 
| -        transport_controller2_.get(),
 | 
| -        &cricket::FakeTransportController::DestroyRtcpTransport);
 | 
| +        this, &ChannelTest<T>::OnRtcpMuxFullyActive2);
 | 
|      if ((flags1 & DTLS) && (flags2 & DTLS)) {
 | 
|        flags1 = (flags1 & ~SECURE);
 | 
|        flags2 = (flags2 & ~SECURE);
 | 
| @@ -166,19 +234,6 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      CopyContent(local_media_content1_, &remote_media_content1_);
 | 
|      CopyContent(local_media_content2_, &remote_media_content2_);
 | 
|  
 | 
| -    if (flags1 & DTLS) {
 | 
| -      // Confirmed to work with KT_RSA and KT_ECDSA.
 | 
| -      transport_controller1_->SetLocalCertificate(
 | 
| -          rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
 | 
| -              rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT))));
 | 
| -    }
 | 
| -    if (flags2 & DTLS) {
 | 
| -      // Confirmed to work with KT_RSA and KT_ECDSA.
 | 
| -      transport_controller2_->SetLocalCertificate(
 | 
| -          rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
 | 
| -              rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT))));
 | 
| -    }
 | 
| -
 | 
|      // Add stream information (SSRC) to the local content but not to the remote
 | 
|      // content. This means that we per default know the SSRC of what we send but
 | 
|      // not what we receive.
 | 
| @@ -198,11 +253,12 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|        rtc::Thread* network_thread,
 | 
|        cricket::MediaEngineInterface* engine,
 | 
|        typename T::MediaChannel* ch,
 | 
| -      cricket::TransportController* transport_controller,
 | 
| +      cricket::DtlsTransportInternal* fake_rtp_dtls_transport,
 | 
| +      cricket::DtlsTransportInternal* fake_rtcp_dtls_transport,
 | 
| +      rtc::PacketTransportInterface* fake_rtp_packet_transport,
 | 
| +      rtc::PacketTransportInterface* fake_rtcp_packet_transport,
 | 
|        int flags) {
 | 
| -    rtc::Thread* signaling_thread =
 | 
| -        transport_controller ? transport_controller->signaling_thread()
 | 
| -                             : nullptr;
 | 
| +    rtc::Thread* signaling_thread = rtc::Thread::Current();
 | 
|      typename T::Channel* channel = new typename T::Channel(
 | 
|          worker_thread, network_thread, signaling_thread, engine, ch,
 | 
|          cricket::CN_AUDIO, (flags & RTCP_MUX_REQUIRED) != 0,
 | 
| @@ -210,21 +266,41 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      rtc::CryptoOptions crypto_options;
 | 
|      crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0;
 | 
|      channel->SetCryptoOptions(crypto_options);
 | 
| -    cricket::DtlsTransportInternal* rtp_dtls_transport =
 | 
| -        transport_controller->CreateDtlsTransport(
 | 
| -            channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| -    cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
 | 
| -    if (channel->NeedsRtcpTransport()) {
 | 
| -      rtcp_dtls_transport = transport_controller->CreateDtlsTransport(
 | 
| -          channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| +    if (!channel->NeedsRtcpTransport()) {
 | 
| +      fake_rtcp_dtls_transport = nullptr;
 | 
|      }
 | 
| -    if (!channel->Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
 | 
| +    if (!channel->Init_w(fake_rtp_dtls_transport, fake_rtcp_dtls_transport,
 | 
| +                         fake_rtp_packet_transport,
 | 
| +                         fake_rtcp_packet_transport)) {
 | 
|        delete channel;
 | 
|        channel = NULL;
 | 
|      }
 | 
|      return channel;
 | 
|    }
 | 
|  
 | 
| +  void ConnectFakeTransports() {
 | 
| +    network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
 | 
| +      bool asymmetric = false;
 | 
| +      // Depending on test flags, could be using DTLS or raw packet transport.
 | 
| +      if (fake_rtp_dtls_transport1_ && fake_rtp_dtls_transport2_) {
 | 
| +        fake_rtp_dtls_transport1_->SetDestination(
 | 
| +            fake_rtp_dtls_transport2_.get(), asymmetric);
 | 
| +      }
 | 
| +      if (fake_rtcp_dtls_transport1_ && fake_rtcp_dtls_transport2_) {
 | 
| +        fake_rtcp_dtls_transport1_->SetDestination(
 | 
| +            fake_rtcp_dtls_transport2_.get(), asymmetric);
 | 
| +      }
 | 
| +      if (fake_rtp_packet_transport1_ && fake_rtp_packet_transport2_) {
 | 
| +        fake_rtp_packet_transport1_->SetDestination(
 | 
| +            fake_rtp_packet_transport2_.get(), asymmetric);
 | 
| +      }
 | 
| +      if (fake_rtcp_packet_transport1_ && fake_rtcp_packet_transport2_) {
 | 
| +        fake_rtcp_packet_transport1_->SetDestination(
 | 
| +            fake_rtcp_packet_transport2_.get(), asymmetric);
 | 
| +      }
 | 
| +    });
 | 
| +  }
 | 
| +
 | 
|    bool SendInitiate() {
 | 
|      bool result = channel1_->SetLocalContent(&local_media_content1_,
 | 
|                                               CA_OFFER, NULL);
 | 
| @@ -233,8 +309,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|        result = channel2_->SetRemoteContent(&remote_media_content1_,
 | 
|                                             CA_OFFER, NULL);
 | 
|        if (result) {
 | 
| -        transport_controller1_->Connect(transport_controller2_.get());
 | 
| -
 | 
| +        ConnectFakeTransports();
 | 
|          result = channel2_->SetLocalContent(&local_media_content2_,
 | 
|                                              CA_ANSWER, NULL);
 | 
|        }
 | 
| @@ -266,7 +341,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|        channel2_->Enable(true);
 | 
|        result = channel1_->SetRemoteContent(&remote_media_content2_,
 | 
|                                             CA_PRANSWER, NULL);
 | 
| -      transport_controller1_->Connect(transport_controller2_.get());
 | 
| +      ConnectFakeTransports();
 | 
|      }
 | 
|      return result;
 | 
|    }
 | 
| @@ -280,9 +355,20 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      return result;
 | 
|    }
 | 
|  
 | 
| -  bool SendTerminate() {
 | 
| +  bool Terminate() {
 | 
|      channel1_.reset();
 | 
|      channel2_.reset();
 | 
| +    fake_rtp_dtls_transport1_.reset();
 | 
| +    fake_rtcp_dtls_transport1_.reset();
 | 
| +    fake_rtp_dtls_transport2_.reset();
 | 
| +    fake_rtcp_dtls_transport2_.reset();
 | 
| +    fake_rtp_packet_transport1_.reset();
 | 
| +    fake_rtcp_packet_transport1_.reset();
 | 
| +    fake_rtp_packet_transport2_.reset();
 | 
| +    fake_rtcp_packet_transport2_.reset();
 | 
| +    if (network_thread_keeper_) {
 | 
| +      network_thread_keeper_.reset();
 | 
| +    }
 | 
|      return true;
 | 
|    }
 | 
|  
 | 
| @@ -293,24 +379,6 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      return channel1_->RemoveRecvStream(id);
 | 
|    }
 | 
|  
 | 
| -  std::vector<cricket::DtlsTransportInternal*> GetChannels1() {
 | 
| -    return transport_controller1_->channels_for_testing();
 | 
| -  }
 | 
| -
 | 
| -  std::vector<cricket::DtlsTransportInternal*> GetChannels2() {
 | 
| -    return transport_controller2_->channels_for_testing();
 | 
| -  }
 | 
| -
 | 
| -  cricket::FakeDtlsTransport* GetFakeChannel1(int component) {
 | 
| -    return transport_controller1_->GetFakeDtlsTransport_n(
 | 
| -        channel1_->content_name(), component);
 | 
| -  }
 | 
| -
 | 
| -  cricket::FakeDtlsTransport* GetFakeChannel2(int component) {
 | 
| -    return transport_controller2_->GetFakeDtlsTransport_n(
 | 
| -        channel2_->content_name(), component);
 | 
| -  }
 | 
| -
 | 
|    void SendRtp1() {
 | 
|      media_channel1_->SendRtp(rtp_packet_.data(), rtp_packet_.size(),
 | 
|                               rtc::PacketOptions());
 | 
| @@ -405,7 +473,11 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    // Returns true if so.
 | 
|    bool CheckGcmCipher(typename T::Channel* channel, int flags) {
 | 
|      int suite;
 | 
| -    if (!channel->rtp_dtls_transport()->GetSrtpCryptoSuite(&suite)) {
 | 
| +    cricket::FakeDtlsTransport* transport =
 | 
| +        (channel == channel1_.get()) ? fake_rtp_dtls_transport1_.get()
 | 
| +                                     : fake_rtp_dtls_transport2_.get();
 | 
| +    RTC_DCHECK(transport);
 | 
| +    if (!transport->GetSrtpCryptoSuite(&suite)) {
 | 
|        return false;
 | 
|      }
 | 
|  
 | 
| @@ -476,6 +548,12 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      RTC_DCHECK_EQ(channel, channel2_.get());
 | 
|      media_info_callbacks2_++;
 | 
|    }
 | 
| +  void OnRtcpMuxFullyActive1(const std::string&) {
 | 
| +    rtcp_mux_activated_callbacks1_++;
 | 
| +  }
 | 
| +  void OnRtcpMuxFullyActive2(const std::string&) {
 | 
| +    rtcp_mux_activated_callbacks2_++;
 | 
| +  }
 | 
|  
 | 
|    cricket::CandidatePairInterface* last_selected_candidate_pair() {
 | 
|      return last_selected_candidate_pair_;
 | 
| @@ -535,43 +613,37 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    // mux.
 | 
|    void TestSetContentsRtcpMux() {
 | 
|      CreateChannels(0, 0);
 | 
| -    EXPECT_TRUE(channel1_->rtcp_dtls_transport() != NULL);
 | 
| -    EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
 | 
|      typename T::Content content;
 | 
|      CreateContent(0, kPcmuCodec, kH264Codec, &content);
 | 
|      // Both sides agree on mux. Should no longer be a separate RTCP channel.
 | 
|      content.set_rtcp_mux(true);
 | 
|      EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL));
 | 
|      EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL));
 | 
| -    EXPECT_TRUE(channel1_->rtcp_dtls_transport() == NULL);
 | 
|      // Only initiator supports mux. Should still have a separate RTCP channel.
 | 
|      EXPECT_TRUE(channel2_->SetLocalContent(&content, CA_OFFER, NULL));
 | 
|      content.set_rtcp_mux(false);
 | 
|      EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_ANSWER, NULL));
 | 
| -    EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
 | 
|    }
 | 
|  
 | 
|    // Test that SetLocalContent and SetRemoteContent properly set RTCP
 | 
|    // mux when a provisional answer is received.
 | 
|    void TestSetContentsRtcpMuxWithPrAnswer() {
 | 
|      CreateChannels(0, 0);
 | 
| -    EXPECT_TRUE(channel1_->rtcp_dtls_transport() != NULL);
 | 
| -    EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
 | 
|      typename T::Content content;
 | 
|      CreateContent(0, kPcmuCodec, kH264Codec, &content);
 | 
|      content.set_rtcp_mux(true);
 | 
|      EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL));
 | 
|      EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_PRANSWER, NULL));
 | 
| -    EXPECT_TRUE(channel1_->rtcp_dtls_transport() != NULL);
 | 
| +    // Both sides agree on mux. Should signal RTCP mux as fully activated.
 | 
| +    EXPECT_EQ(0, rtcp_mux_activated_callbacks1_);
 | 
|      EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL));
 | 
| -    // Both sides agree on mux. Should no longer be a separate RTCP channel.
 | 
| -    EXPECT_TRUE(channel1_->rtcp_dtls_transport() == NULL);
 | 
| +    EXPECT_EQ(1, rtcp_mux_activated_callbacks1_);
 | 
|      // Only initiator supports mux. Should still have a separate RTCP channel.
 | 
|      EXPECT_TRUE(channel2_->SetLocalContent(&content, CA_OFFER, NULL));
 | 
|      content.set_rtcp_mux(false);
 | 
|      EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_PRANSWER, NULL));
 | 
|      EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_ANSWER, NULL));
 | 
| -    EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
 | 
| +    EXPECT_EQ(0, rtcp_mux_activated_callbacks2_);
 | 
|    }
 | 
|  
 | 
|    // Test that SetRemoteContent properly deals with a content update.
 | 
| @@ -777,7 +849,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|  
 | 
|      EXPECT_TRUE(channel2_->SetRemoteContent(&content1, CA_OFFER, NULL));
 | 
|      EXPECT_EQ(1u, media_channel2_->recv_streams().size());
 | 
| -    transport_controller1_->Connect(transport_controller2_.get());
 | 
| +    ConnectFakeTransports();
 | 
|  
 | 
|      // Channel 2 do not send anything.
 | 
|      typename T::Content content2;
 | 
| @@ -854,7 +926,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|        EXPECT_FALSE(media_channel2_->playout());
 | 
|      }
 | 
|      EXPECT_FALSE(media_channel2_->sending());
 | 
| -    transport_controller1_->Connect(transport_controller2_.get());
 | 
| +    ConnectFakeTransports();
 | 
|      if (verify_playout_) {
 | 
|        EXPECT_TRUE(media_channel1_->playout());
 | 
|      }
 | 
| @@ -902,7 +974,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      EXPECT_TRUE(channel2_->SetRemoteContent(&content1, CA_OFFER, NULL));
 | 
|      EXPECT_TRUE(channel2_->SetLocalContent(&content2, CA_PRANSWER, NULL));
 | 
|      EXPECT_TRUE(channel1_->SetRemoteContent(&content2, CA_PRANSWER, NULL));
 | 
| -    transport_controller1_->Connect(transport_controller2_.get());
 | 
| +    ConnectFakeTransports();
 | 
|  
 | 
|      if (verify_playout_) {
 | 
|        EXPECT_TRUE(media_channel1_->playout());
 | 
| @@ -951,36 +1023,34 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|  
 | 
|      CreateChannels(0, 0);
 | 
|  
 | 
| -    cricket::DtlsTransportInternal* transport_channel1 =
 | 
| -        channel1_->rtp_dtls_transport();
 | 
| -    ASSERT_TRUE(transport_channel1);
 | 
|      typename T::MediaChannel* media_channel1 =
 | 
|          static_cast<typename T::MediaChannel*>(channel1_->media_channel());
 | 
|      ASSERT_TRUE(media_channel1);
 | 
|  
 | 
|      media_channel1->set_num_network_route_changes(0);
 | 
| -    network_thread_->Invoke<void>(RTC_FROM_HERE, [transport_channel1] {
 | 
| +    network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
 | 
|        // The transport channel becomes disconnected.
 | 
| -      transport_channel1->ice_transport()->SignalSelectedCandidatePairChanged(
 | 
| -          transport_channel1->ice_transport(), nullptr, -1, false);
 | 
| +      fake_rtp_dtls_transport1_->ice_transport()
 | 
| +          ->SignalSelectedCandidatePairChanged(
 | 
| +              fake_rtp_dtls_transport1_->ice_transport(), nullptr, -1, false);
 | 
|      });
 | 
|      WaitForThreads();
 | 
|      EXPECT_EQ(1, media_channel1->num_network_route_changes());
 | 
|      EXPECT_FALSE(media_channel1->last_network_route().connected);
 | 
|      media_channel1->set_num_network_route_changes(0);
 | 
|  
 | 
| -    network_thread_->Invoke<void>(RTC_FROM_HERE, [this, transport_channel1,
 | 
| -                                                  media_channel1, kLocalNetId,
 | 
| -                                                  kRemoteNetId, kLastPacketId] {
 | 
| +    network_thread_->Invoke<void>(RTC_FROM_HERE, [this, media_channel1,
 | 
| +                                                  kLocalNetId, kRemoteNetId,
 | 
| +                                                  kLastPacketId] {
 | 
|        // The transport channel becomes connected.
 | 
|        rtc::SocketAddress local_address("192.168.1.1", 1000 /* port number */);
 | 
|        rtc::SocketAddress remote_address("192.168.1.2", 2000 /* port number */);
 | 
| -      std::unique_ptr<cricket::CandidatePairInterface> candidate_pair(
 | 
| -          transport_controller1_->CreateFakeCandidatePair(
 | 
| -              local_address, kLocalNetId, remote_address, kRemoteNetId));
 | 
| -      transport_channel1->ice_transport()->SignalSelectedCandidatePairChanged(
 | 
| -          transport_channel1->ice_transport(), candidate_pair.get(),
 | 
| -          kLastPacketId, true);
 | 
| +      auto candidate_pair = cricket::FakeCandidatePair::Create(
 | 
| +          local_address, kLocalNetId, remote_address, kRemoteNetId);
 | 
| +      fake_rtp_dtls_transport1_->ice_transport()
 | 
| +          ->SignalSelectedCandidatePairChanged(
 | 
| +              fake_rtp_dtls_transport1_->ice_transport(), candidate_pair.get(),
 | 
| +              kLastPacketId, true);
 | 
|      });
 | 
|      WaitForThreads();
 | 
|      EXPECT_EQ(1, media_channel1->num_network_route_changes());
 | 
| @@ -1032,7 +1102,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|                     RTCP_MUX, RTCP_MUX);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_TRUE(SendTerminate());
 | 
| +    EXPECT_TRUE(Terminate());
 | 
|    }
 | 
|  
 | 
|    // Send voice RTP data to the other side and ensure it gets there.
 | 
| @@ -1040,8 +1110,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      CreateChannels(RTCP_MUX | RTCP_MUX_REQUIRED, RTCP_MUX | RTCP_MUX_REQUIRED);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| -    EXPECT_EQ(1U, GetChannels2().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
|      WaitForThreads();
 | 
| @@ -1069,8 +1139,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      CreateChannels(0, 0);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(2U, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_TRUE(channel2_->NeedsRtcpTransport());
 | 
|      SendRtcp1();
 | 
|      SendRtcp2();
 | 
|      WaitForThreads();
 | 
| @@ -1085,8 +1155,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      CreateChannels(RTCP_MUX, 0);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(2U, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_TRUE(channel2_->NeedsRtcpTransport());
 | 
|      SendRtcp1();
 | 
|      SendRtcp2();
 | 
|      WaitForThreads();
 | 
| @@ -1100,10 +1170,12 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    void SendRtcpMuxToRtcpMux() {
 | 
|      CreateChannels(RTCP_MUX, RTCP_MUX);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(1U, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
| +    EXPECT_EQ(0, rtcp_mux_activated_callbacks1_);
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_EQ(1, rtcp_mux_activated_callbacks1_);
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
|      SendRtcp1();
 | 
| @@ -1124,8 +1196,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    void SendRequireRtcpMuxToRtcpMux() {
 | 
|      CreateChannels(RTCP_MUX | RTCP_MUX_REQUIRED, RTCP_MUX);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| -    EXPECT_EQ(1U, GetChannels2().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
| @@ -1147,10 +1219,12 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    void SendRtcpMuxToRequireRtcpMux() {
 | 
|      CreateChannels(RTCP_MUX, RTCP_MUX | RTCP_MUX_REQUIRED);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(1U, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
| +    EXPECT_EQ(0, rtcp_mux_activated_callbacks1_);
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_EQ(1, rtcp_mux_activated_callbacks1_);
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
|      SendRtcp1();
 | 
| @@ -1171,10 +1245,10 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    void SendRequireRtcpMuxToRequireRtcpMux() {
 | 
|      CreateChannels(RTCP_MUX | RTCP_MUX_REQUIRED, RTCP_MUX | RTCP_MUX_REQUIRED);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| -    EXPECT_EQ(1U, GetChannels2().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
|      SendRtcp1();
 | 
| @@ -1195,8 +1269,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    void SendRequireRtcpMuxToNoRtcpMux() {
 | 
|      CreateChannels(RTCP_MUX | RTCP_MUX_REQUIRED, 0);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| -    EXPECT_EQ(2U, GetChannels2().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_TRUE(channel2_->NeedsRtcpTransport());
 | 
|      EXPECT_FALSE(SendAccept());
 | 
|    }
 | 
|  
 | 
| @@ -1204,8 +1278,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    void SendEarlyRtcpMuxToRtcp() {
 | 
|      CreateChannels(RTCP_MUX, 0);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(2U, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_TRUE(channel2_->NeedsRtcpTransport());
 | 
|  
 | 
|      // RTCP can be sent before the call is accepted, if the transport is ready.
 | 
|      // It should not be muxed though, as the remote side doesn't support mux.
 | 
| @@ -1222,7 +1296,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|  
 | 
|      // Complete call setup and ensure everything is still OK.
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
|      SendRtcp1();
 | 
|      SendRtcp2();
 | 
|      WaitForThreads();
 | 
| @@ -1237,8 +1311,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    void SendEarlyRtcpMuxToRtcpMux() {
 | 
|      CreateChannels(RTCP_MUX, RTCP_MUX);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(1U, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
|  
 | 
|      // RTCP can't be sent yet, since the RTCP transport isn't writable, and
 | 
|      // we haven't yet received the accept that says we should mux.
 | 
| @@ -1253,8 +1327,10 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      EXPECT_TRUE(CheckRtcp1());
 | 
|  
 | 
|      // Complete call setup and ensure everything is still OK.
 | 
| +    EXPECT_EQ(0, rtcp_mux_activated_callbacks1_);
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_EQ(1, rtcp_mux_activated_callbacks1_);
 | 
|      SendRtcp1();
 | 
|      SendRtcp2();
 | 
|      WaitForThreads();
 | 
| @@ -1263,10 +1339,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    }
 | 
|  
 | 
|    // Test that we properly send SRTP with RTCP in both directions.
 | 
| -  // You can pass in DTLS and/or RTCP_MUX as flags.
 | 
| +  // You can pass in DTLS, RTCP_MUX, GCM_CIPHER and RAW_PACKET_TRANSPORT as
 | 
| +  // flags.
 | 
|    void SendSrtpToSrtp(int flags1_in = 0, int flags2_in = 0) {
 | 
| -    RTC_CHECK((flags1_in & ~(RTCP_MUX | DTLS | GCM_CIPHER)) == 0);
 | 
| -    RTC_CHECK((flags2_in & ~(RTCP_MUX | DTLS | GCM_CIPHER)) == 0);
 | 
| +    RTC_CHECK((flags1_in &
 | 
| +               ~(RTCP_MUX | DTLS | GCM_CIPHER | RAW_PACKET_TRANSPORT)) == 0);
 | 
| +    RTC_CHECK((flags2_in &
 | 
| +               ~(RTCP_MUX | DTLS | GCM_CIPHER | RAW_PACKET_TRANSPORT)) == 0);
 | 
|  
 | 
|      int flags1 = SECURE | flags1_in;
 | 
|      int flags2 = SECURE | flags2_in;
 | 
| @@ -1342,8 +1421,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|        EXPECT_TRUE(SendProvisionalAnswer());
 | 
|        EXPECT_TRUE(channel1_->secure());
 | 
|        EXPECT_TRUE(channel2_->secure());
 | 
| -      EXPECT_EQ(2U, GetChannels1().size());
 | 
| -      EXPECT_EQ(2U, GetChannels2().size());
 | 
| +      EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +      EXPECT_TRUE(channel2_->NeedsRtcpTransport());
 | 
|        WaitForThreads();  // Wait for 'sending' flag go through network thread.
 | 
|        SendCustomRtcp1(kSsrc1);
 | 
|        SendCustomRtp1(kSsrc1, ++sequence_number1_1);
 | 
| @@ -1359,9 +1438,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|        EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2));
 | 
|  
 | 
|        // Complete call setup and ensure everything is still OK.
 | 
| +      EXPECT_EQ(0, rtcp_mux_activated_callbacks1_);
 | 
| +      EXPECT_EQ(0, rtcp_mux_activated_callbacks2_);
 | 
|        EXPECT_TRUE(SendFinalAnswer());
 | 
| -      EXPECT_EQ(1U, GetChannels1().size());
 | 
| -      EXPECT_EQ(1U, GetChannels2().size());
 | 
| +      EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +      EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
| +      EXPECT_EQ(1, rtcp_mux_activated_callbacks1_);
 | 
| +      EXPECT_EQ(1, rtcp_mux_activated_callbacks2_);
 | 
|        EXPECT_TRUE(channel1_->secure());
 | 
|        EXPECT_TRUE(channel2_->secure());
 | 
|        SendCustomRtcp1(kSsrc1);
 | 
| @@ -1427,8 +1510,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      CreateChannels(RTCP_MUX | RTCP_MUX_REQUIRED, RTCP_MUX | RTCP_MUX_REQUIRED);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(1U, GetChannels1().size());
 | 
| -    EXPECT_EQ(1U, GetChannels2().size());
 | 
| +    EXPECT_FALSE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_FALSE(channel2_->NeedsRtcpTransport());
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
|      WaitForThreads();
 | 
| @@ -1438,8 +1521,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      EXPECT_TRUE(CheckNoRtp2());
 | 
|  
 | 
|      // Lose writability, which should fail.
 | 
| -    network_thread_->Invoke<void>(
 | 
| -        RTC_FROM_HERE, [this] { GetFakeChannel1(1)->SetWritable(false); });
 | 
| +    network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
 | 
| +      fake_rtp_dtls_transport1_->SetWritable(false);
 | 
| +    });
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
|      WaitForThreads();
 | 
| @@ -1447,8 +1531,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      EXPECT_TRUE(CheckNoRtp2());
 | 
|  
 | 
|      // Regain writability
 | 
| -    network_thread_->Invoke<void>(
 | 
| -        RTC_FROM_HERE, [this] { GetFakeChannel1(1)->SetWritable(true); });
 | 
| +    network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
 | 
| +      fake_rtp_dtls_transport1_->SetWritable(true);
 | 
| +    });
 | 
|      EXPECT_TRUE(media_channel1_->sending());
 | 
|      SendRtp1();
 | 
|      SendRtp2();
 | 
| @@ -1459,8 +1544,10 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      EXPECT_TRUE(CheckNoRtp2());
 | 
|  
 | 
|      // Lose writability completely
 | 
| -    network_thread_->Invoke<void>(
 | 
| -        RTC_FROM_HERE, [this] { GetFakeChannel1(1)->SetDestination(nullptr); });
 | 
| +    network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
 | 
| +      bool asymmetric = true;
 | 
| +      fake_rtp_dtls_transport1_->SetDestination(nullptr, asymmetric);
 | 
| +    });
 | 
|      EXPECT_TRUE(media_channel1_->sending());
 | 
|  
 | 
|      // Should fail also.
 | 
| @@ -1473,7 +1560,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|  
 | 
|      // Gain writability back
 | 
|      network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
 | 
| -      GetFakeChannel1(1)->SetDestination(GetFakeChannel2(1));
 | 
| +      bool asymmetric = true;
 | 
| +      fake_rtp_dtls_transport1_->SetDestination(fake_rtp_dtls_transport2_.get(),
 | 
| +                                                asymmetric);
 | 
|      });
 | 
|      EXPECT_TRUE(media_channel1_->sending());
 | 
|      SendRtp1();
 | 
| @@ -1495,18 +1584,16 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      int pl_type2 = pl_types[1];
 | 
|      int flags = SSRC_MUX;
 | 
|      if (secure) flags |= SECURE;
 | 
| -    uint32_t expected_channels = 2U;
 | 
|      if (rtcp_mux) {
 | 
|        flags |= RTCP_MUX;
 | 
| -      expected_channels = 1U;
 | 
|      }
 | 
|      CreateChannels(flags, flags);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(expected_channels, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_EQ(rtcp_mux, !channel2_->NeedsRtcpTransport());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(expected_channels, GetChannels1().size());
 | 
| -    EXPECT_EQ(expected_channels, GetChannels2().size());
 | 
| +    EXPECT_EQ(rtcp_mux, !channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_EQ(rtcp_mux, !channel2_->NeedsRtcpTransport());
 | 
|      EXPECT_TRUE(channel1_->bundle_filter()->FindPayloadType(pl_type1));
 | 
|      EXPECT_TRUE(channel2_->bundle_filter()->FindPayloadType(pl_type1));
 | 
|      EXPECT_FALSE(channel1_->bundle_filter()->FindPayloadType(pl_type2));
 | 
| @@ -1686,8 +1773,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      CreateChannels(0, 0);
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
|      EXPECT_TRUE(SendAccept());
 | 
| -    EXPECT_EQ(2U, GetChannels1().size());
 | 
| -    EXPECT_EQ(2U, GetChannels2().size());
 | 
| +    EXPECT_TRUE(channel1_->NeedsRtcpTransport());
 | 
| +    EXPECT_TRUE(channel2_->NeedsRtcpTransport());
 | 
|  
 | 
|      // Send RTCP1 from a different thread.
 | 
|      ScopedCallThread send_rtcp([this] { SendRtcp1(); });
 | 
| @@ -1733,12 +1820,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      // Using fake clock because this tests that SRTP errors are signaled at
 | 
|      // specific times based on set_signal_silent_time.
 | 
|      rtc::ScopedFakeClock fake_clock;
 | 
| +
 | 
| +    CreateChannels(SECURE, SECURE);
 | 
|      // Some code uses a time of 0 as a special value, so we must start with
 | 
|      // a non-zero time.
 | 
|      // TODO(deadbeef): Fix this.
 | 
|      fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
 | 
|  
 | 
| -    CreateChannels(SECURE, SECURE);
 | 
|      EXPECT_FALSE(channel1_->secure());
 | 
|      EXPECT_FALSE(channel2_->secure());
 | 
|      EXPECT_TRUE(SendInitiate());
 | 
| @@ -1779,22 +1867,21 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      error_handler.mode_ = cricket::SrtpFilter::UNPROTECT;
 | 
|  
 | 
|      network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
 | 
| -      cricket::DtlsTransportInternal* transport_channel =
 | 
| -          channel2_->rtp_dtls_transport();
 | 
| -      transport_channel->SignalReadPacket(
 | 
| -          transport_channel, reinterpret_cast<const char*>(kBadPacket),
 | 
| -          sizeof(kBadPacket), rtc::PacketTime(), 0);
 | 
| +      fake_rtp_dtls_transport2_->SignalReadPacket(
 | 
| +          fake_rtp_dtls_transport2_.get(),
 | 
| +          reinterpret_cast<const char*>(kBadPacket), sizeof(kBadPacket),
 | 
| +          rtc::PacketTime(), 0);
 | 
|      });
 | 
|      EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_handler.error_);
 | 
|      EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, error_handler.mode_);
 | 
| -    // Terminate channels before the fake clock is destroyed.
 | 
| -    EXPECT_TRUE(SendTerminate());
 | 
| +    // Terminate channels/threads before the fake clock is destroyed.
 | 
| +    EXPECT_TRUE(Terminate());
 | 
|    }
 | 
|  
 | 
|    void TestOnReadyToSend() {
 | 
|      CreateChannels(0, 0);
 | 
| -    DtlsTransportInternal* rtp = channel1_->rtp_dtls_transport();
 | 
| -    DtlsTransportInternal* rtcp = channel1_->rtcp_dtls_transport();
 | 
| +    cricket::FakeDtlsTransport* rtp = fake_rtp_dtls_transport1_.get();
 | 
| +    cricket::FakeDtlsTransport* rtcp = fake_rtcp_dtls_transport1_.get();
 | 
|      EXPECT_FALSE(media_channel1_->ready_to_send());
 | 
|  
 | 
|      network_thread_->Invoke<void>(RTC_FROM_HERE,
 | 
| @@ -1840,12 +1927,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|      CreateChannels(0, 0);
 | 
|      typename T::Content content;
 | 
|      CreateContent(0, kPcmuCodec, kH264Codec, &content);
 | 
| -    // Both sides agree on mux. Should no longer be a separate RTCP channel.
 | 
| +    // Both sides agree on mux. Should signal that RTCP mux is fully active.
 | 
|      content.set_rtcp_mux(true);
 | 
|      EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL));
 | 
| +    EXPECT_EQ(0, rtcp_mux_activated_callbacks1_);
 | 
|      EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL));
 | 
| -    EXPECT_TRUE(channel1_->rtcp_dtls_transport() == NULL);
 | 
| -    DtlsTransportInternal* rtp = channel1_->rtp_dtls_transport();
 | 
| +    EXPECT_EQ(1, rtcp_mux_activated_callbacks1_);
 | 
| +    cricket::FakeDtlsTransport* rtp = fake_rtp_dtls_transport1_.get();
 | 
|      EXPECT_FALSE(media_channel1_->ready_to_send());
 | 
|      // In the case of rtcp mux, the SignalReadyToSend() from rtp channel
 | 
|      // should trigger the MediaChannel's OnReadyToSend.
 | 
| @@ -1936,12 +2024,18 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    const bool verify_playout_;
 | 
|    std::unique_ptr<rtc::Thread> network_thread_keeper_;
 | 
|    rtc::Thread* network_thread_;
 | 
| -  std::unique_ptr<cricket::FakeTransportController> transport_controller1_;
 | 
| -  std::unique_ptr<cricket::FakeTransportController> transport_controller2_;
 | 
| +  std::unique_ptr<cricket::FakeDtlsTransport> fake_rtp_dtls_transport1_;
 | 
| +  std::unique_ptr<cricket::FakeDtlsTransport> fake_rtcp_dtls_transport1_;
 | 
| +  std::unique_ptr<cricket::FakeDtlsTransport> fake_rtp_dtls_transport2_;
 | 
| +  std::unique_ptr<cricket::FakeDtlsTransport> fake_rtcp_dtls_transport2_;
 | 
| +  std::unique_ptr<rtc::FakePacketTransport> fake_rtp_packet_transport1_;
 | 
| +  std::unique_ptr<rtc::FakePacketTransport> fake_rtcp_packet_transport1_;
 | 
| +  std::unique_ptr<rtc::FakePacketTransport> fake_rtp_packet_transport2_;
 | 
| +  std::unique_ptr<rtc::FakePacketTransport> fake_rtcp_packet_transport2_;
 | 
|    cricket::FakeMediaEngine media_engine_;
 | 
|    // The media channels are owned by the voice channel objects below.
 | 
| -  typename T::MediaChannel* media_channel1_;
 | 
| -  typename T::MediaChannel* media_channel2_;
 | 
| +  typename T::MediaChannel* media_channel1_ = nullptr;
 | 
| +  typename T::MediaChannel* media_channel2_ = nullptr;
 | 
|    std::unique_ptr<typename T::Channel> channel1_;
 | 
|    std::unique_ptr<typename T::Channel> channel2_;
 | 
|    typename T::Content local_media_content1_;
 | 
| @@ -1951,8 +2045,10 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
 | 
|    // The RTP and RTCP packets to send in the tests.
 | 
|    rtc::Buffer rtp_packet_;
 | 
|    rtc::Buffer rtcp_packet_;
 | 
| -  int media_info_callbacks1_;
 | 
| -  int media_info_callbacks2_;
 | 
| +  int media_info_callbacks1_ = 0;
 | 
| +  int media_info_callbacks2_ = 0;
 | 
| +  int rtcp_mux_activated_callbacks1_ = 0;
 | 
| +  int rtcp_mux_activated_callbacks2_ = 0;
 | 
|    cricket::CandidatePairInterface* last_selected_candidate_pair_;
 | 
|  };
 | 
|  
 | 
| @@ -2014,25 +2110,23 @@ cricket::VideoChannel* ChannelTest<VideoTraits>::CreateChannel(
 | 
|      rtc::Thread* network_thread,
 | 
|      cricket::MediaEngineInterface* engine,
 | 
|      cricket::FakeVideoMediaChannel* ch,
 | 
| -    cricket::TransportController* transport_controller,
 | 
| +    cricket::DtlsTransportInternal* fake_rtp_dtls_transport,
 | 
| +    cricket::DtlsTransportInternal* fake_rtcp_dtls_transport,
 | 
| +    rtc::PacketTransportInterface* fake_rtp_packet_transport,
 | 
| +    rtc::PacketTransportInterface* fake_rtcp_packet_transport,
 | 
|      int flags) {
 | 
| -  rtc::Thread* signaling_thread =
 | 
| -      transport_controller ? transport_controller->signaling_thread() : nullptr;
 | 
| +  rtc::Thread* signaling_thread = rtc::Thread::Current();
 | 
|    cricket::VideoChannel* channel = new cricket::VideoChannel(
 | 
|        worker_thread, network_thread, signaling_thread, ch, cricket::CN_VIDEO,
 | 
|        (flags & RTCP_MUX_REQUIRED) != 0, (flags & SECURE) != 0);
 | 
|    rtc::CryptoOptions crypto_options;
 | 
|    crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0;
 | 
|    channel->SetCryptoOptions(crypto_options);
 | 
| -  cricket::DtlsTransportInternal* rtp_dtls_transport =
 | 
| -      transport_controller->CreateDtlsTransport(
 | 
| -          channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| -  cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
 | 
| -  if (channel->NeedsRtcpTransport()) {
 | 
| -    rtcp_dtls_transport = transport_controller->CreateDtlsTransport(
 | 
| -        channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| -  }
 | 
| -  if (!channel->Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
 | 
| +  if (!channel->NeedsRtcpTransport()) {
 | 
| +    fake_rtcp_dtls_transport = nullptr;
 | 
| +  }
 | 
| +  if (!channel->Init_w(fake_rtp_dtls_transport, fake_rtcp_dtls_transport,
 | 
| +                       fake_rtp_packet_transport, fake_rtcp_packet_transport)) {
 | 
|      delete channel;
 | 
|      channel = NULL;
 | 
|    }
 | 
| @@ -2260,6 +2354,12 @@ TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
 | 
|    Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX);
 | 
|  }
 | 
|  
 | 
| +// Test using the channel with a raw packet interface, as opposed to a DTLS
 | 
| +// transport interface.
 | 
| +TEST_F(VoiceChannelSingleThreadTest, SendSrtpToSrtpWithRawPacketTransport) {
 | 
| +  Base::SendSrtpToSrtp(RAW_PACKET_TRANSPORT, RAW_PACKET_TRANSPORT);
 | 
| +}
 | 
| +
 | 
|  TEST_F(VoiceChannelSingleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
 | 
|    Base::SendEarlyMediaUsingRtcpMuxSrtp();
 | 
|  }
 | 
| @@ -2587,6 +2687,12 @@ TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
 | 
|    Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX);
 | 
|  }
 | 
|  
 | 
| +// Test using the channel with a raw packet interface, as opposed to a DTLS
 | 
| +// transport interface.
 | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendSrtpToSrtpWithRawPacketTransport) {
 | 
| +  Base::SendSrtpToSrtp(RAW_PACKET_TRANSPORT, RAW_PACKET_TRANSPORT);
 | 
| +}
 | 
| +
 | 
|  TEST_F(VoiceChannelDoubleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
 | 
|    Base::SendEarlyMediaUsingRtcpMuxSrtp();
 | 
|  }
 | 
| @@ -2894,6 +3000,12 @@ TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
 | 
|    Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX);
 | 
|  }
 | 
|  
 | 
| +// Test using the channel with a raw packet interface, as opposed to a DTLS
 | 
| +// transport interface.
 | 
| +TEST_F(VideoChannelSingleThreadTest, SendSrtpToSrtpWithRawPacketTransport) {
 | 
| +  Base::SendSrtpToSrtp(RAW_PACKET_TRANSPORT, RAW_PACKET_TRANSPORT);
 | 
| +}
 | 
| +
 | 
|  TEST_F(VideoChannelSingleThreadTest, SendSrtcpMux) {
 | 
|    Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX);
 | 
|  }
 | 
| @@ -3123,6 +3235,12 @@ TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
 | 
|    Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX);
 | 
|  }
 | 
|  
 | 
| +// Test using the channel with a raw packet interface, as opposed to a DTLS
 | 
| +// transport interface.
 | 
| +TEST_F(VideoChannelDoubleThreadTest, SendSrtpToSrtpWithRawPacketTransport) {
 | 
| +  Base::SendSrtpToSrtp(RAW_PACKET_TRANSPORT, RAW_PACKET_TRANSPORT);
 | 
| +}
 | 
| +
 | 
|  TEST_F(VideoChannelDoubleThreadTest, SendSrtcpMux) {
 | 
|    Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX);
 | 
|  }
 | 
| @@ -3230,25 +3348,23 @@ cricket::RtpDataChannel* ChannelTest<DataTraits>::CreateChannel(
 | 
|      rtc::Thread* network_thread,
 | 
|      cricket::MediaEngineInterface* engine,
 | 
|      cricket::FakeDataMediaChannel* ch,
 | 
| -    cricket::TransportController* transport_controller,
 | 
| +    cricket::DtlsTransportInternal* fake_rtp_dtls_transport,
 | 
| +    cricket::DtlsTransportInternal* fake_rtcp_dtls_transport,
 | 
| +    rtc::PacketTransportInterface* fake_rtp_packet_transport,
 | 
| +    rtc::PacketTransportInterface* fake_rtcp_packet_transport,
 | 
|      int flags) {
 | 
| -  rtc::Thread* signaling_thread =
 | 
| -      transport_controller ? transport_controller->signaling_thread() : nullptr;
 | 
| +  rtc::Thread* signaling_thread = rtc::Thread::Current();
 | 
|    cricket::RtpDataChannel* channel = new cricket::RtpDataChannel(
 | 
|        worker_thread, network_thread, signaling_thread, ch, cricket::CN_DATA,
 | 
|        (flags & RTCP_MUX_REQUIRED) != 0, (flags & SECURE) != 0);
 | 
|    rtc::CryptoOptions crypto_options;
 | 
|    crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0;
 | 
|    channel->SetCryptoOptions(crypto_options);
 | 
| -  cricket::DtlsTransportInternal* rtp_dtls_transport =
 | 
| -      transport_controller->CreateDtlsTransport(
 | 
| -          channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| -  cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
 | 
| -  if (channel->NeedsRtcpTransport()) {
 | 
| -    rtcp_dtls_transport = transport_controller->CreateDtlsTransport(
 | 
| -        channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| -  }
 | 
| -  if (!channel->Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
 | 
| +  if (!channel->NeedsRtcpTransport()) {
 | 
| +    fake_rtcp_dtls_transport = nullptr;
 | 
| +  }
 | 
| +  if (!channel->Init_w(fake_rtp_dtls_transport, fake_rtcp_dtls_transport,
 | 
| +                       fake_rtp_packet_transport, fake_rtcp_packet_transport)) {
 | 
|      delete channel;
 | 
|      channel = NULL;
 | 
|    }
 | 
| @@ -3565,7 +3681,9 @@ TEST_F(RtpDataChannelDoubleThreadTest, TestSendData) {
 | 
|  class BaseChannelDeathTest : public testing::Test {
 | 
|   public:
 | 
|    BaseChannelDeathTest()
 | 
| -      :  // RTCP mux not required, SRTP required.
 | 
| +      : fake_rtp_dtls_transport_("foo", cricket::ICE_CANDIDATE_COMPONENT_RTP),
 | 
| +        fake_rtcp_dtls_transport_("foo", cricket::ICE_CANDIDATE_COMPONENT_RTCP),
 | 
| +        // RTCP mux not required, SRTP required.
 | 
|          voice_channel_(
 | 
|              rtc::Thread::Current(),
 | 
|              rtc::Thread::Current(),
 | 
| @@ -3575,66 +3693,89 @@ class BaseChannelDeathTest : public testing::Test {
 | 
|                                                 cricket::AudioOptions()),
 | 
|              cricket::CN_AUDIO,
 | 
|              false,
 | 
| -            true) {
 | 
| -    rtp_transport_ = fake_transport_controller_.CreateDtlsTransport(
 | 
| -        "foo", cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| -    rtcp_transport_ = fake_transport_controller_.CreateDtlsTransport(
 | 
| -        "foo", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| -    EXPECT_TRUE(voice_channel_.Init_w(rtp_transport_, rtcp_transport_));
 | 
| -  }
 | 
| +            true) {}
 | 
|  
 | 
|   protected:
 | 
| -  cricket::FakeTransportController fake_transport_controller_;
 | 
|    cricket::FakeMediaEngine fake_media_engine_;
 | 
| +  cricket::FakeDtlsTransport fake_rtp_dtls_transport_;
 | 
| +  cricket::FakeDtlsTransport fake_rtcp_dtls_transport_;
 | 
|    cricket::VoiceChannel voice_channel_;
 | 
| -  // Will be cleaned up by FakeTransportController, don't need to worry about
 | 
| -  // deleting them in this test.
 | 
| -  cricket::DtlsTransportInternal* rtp_transport_;
 | 
| -  cricket::DtlsTransportInternal* rtcp_transport_;
 | 
|  };
 | 
|  
 | 
| -TEST_F(BaseChannelDeathTest, SetTransportWithNullRtpTransport) {
 | 
| -  cricket::DtlsTransportInternal* new_rtcp_transport =
 | 
| -      fake_transport_controller_.CreateDtlsTransport(
 | 
| -          "bar", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| -  EXPECT_DEATH(voice_channel_.SetTransports(nullptr, new_rtcp_transport), "");
 | 
| +TEST_F(BaseChannelDeathTest, SetTransportsWithNullRtpTransport) {
 | 
| +  ASSERT_TRUE(voice_channel_.Init_w(
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_,
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_));
 | 
| +  cricket::FakeDtlsTransport new_rtcp_transport(
 | 
| +      "bar", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| +  EXPECT_DEATH(voice_channel_.SetTransports(nullptr, &new_rtcp_transport), "");
 | 
|  }
 | 
|  
 | 
| -TEST_F(BaseChannelDeathTest, SetTransportWithMissingRtcpTransport) {
 | 
| -  cricket::DtlsTransportInternal* new_rtp_transport =
 | 
| -      fake_transport_controller_.CreateDtlsTransport(
 | 
| -          "bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| -  EXPECT_DEATH(voice_channel_.SetTransports(new_rtp_transport, nullptr), "");
 | 
| +TEST_F(BaseChannelDeathTest, SetTransportsWithMissingRtcpTransport) {
 | 
| +  ASSERT_TRUE(voice_channel_.Init_w(
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_,
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_));
 | 
| +  cricket::FakeDtlsTransport new_rtp_transport(
 | 
| +      "bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| +  EXPECT_DEATH(voice_channel_.SetTransports(&new_rtp_transport, nullptr), "");
 | 
|  }
 | 
|  
 | 
| -TEST_F(BaseChannelDeathTest, SetTransportWithUnneededRtcpTransport) {
 | 
| +TEST_F(BaseChannelDeathTest, SetTransportsWithUnneededRtcpTransport) {
 | 
| +  ASSERT_TRUE(voice_channel_.Init_w(
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_,
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_));
 | 
|    // Activate RTCP muxing, simulating offer/answer negotiation.
 | 
|    cricket::AudioContentDescription content;
 | 
|    content.set_rtcp_mux(true);
 | 
|    ASSERT_TRUE(voice_channel_.SetLocalContent(&content, CA_OFFER, nullptr));
 | 
|    ASSERT_TRUE(voice_channel_.SetRemoteContent(&content, CA_ANSWER, nullptr));
 | 
| -  cricket::DtlsTransportInternal* new_rtp_transport =
 | 
| -      fake_transport_controller_.CreateDtlsTransport(
 | 
| -          "bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| -  cricket::DtlsTransportInternal* new_rtcp_transport =
 | 
| -      fake_transport_controller_.CreateDtlsTransport(
 | 
| -          "bar", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| +  cricket::FakeDtlsTransport new_rtp_transport(
 | 
| +      "bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| +  cricket::FakeDtlsTransport new_rtcp_transport(
 | 
| +      "bar", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
|    // After muxing is enabled, no RTCP transport should be passed in here.
 | 
|    EXPECT_DEATH(
 | 
| -      voice_channel_.SetTransports(new_rtp_transport, new_rtcp_transport), "");
 | 
| +      voice_channel_.SetTransports(&new_rtp_transport, &new_rtcp_transport),
 | 
| +      "");
 | 
|  }
 | 
|  
 | 
|  // This test will probably go away if/when we move the transport name out of
 | 
|  // the transport classes and into their parent classes.
 | 
| -TEST_F(BaseChannelDeathTest, SetTransportWithMismatchingTransportNames) {
 | 
| -  cricket::DtlsTransportInternal* new_rtp_transport =
 | 
| -      fake_transport_controller_.CreateDtlsTransport(
 | 
| -          "bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| -  cricket::DtlsTransportInternal* new_rtcp_transport =
 | 
| -      fake_transport_controller_.CreateDtlsTransport(
 | 
| -          "baz", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| +TEST_F(BaseChannelDeathTest, SetTransportsWithMismatchingTransportNames) {
 | 
| +  ASSERT_TRUE(voice_channel_.Init_w(
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_,
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_));
 | 
| +  cricket::FakeDtlsTransport new_rtp_transport(
 | 
| +      "bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
 | 
| +  cricket::FakeDtlsTransport new_rtcp_transport(
 | 
| +      "baz", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
 | 
| +  EXPECT_DEATH(
 | 
| +      voice_channel_.SetTransports(&new_rtp_transport, &new_rtcp_transport),
 | 
| +      "");
 | 
| +}
 | 
| +
 | 
| +// Not expected to support going from DtlsTransportInternal to
 | 
| +// PacketTransportInterface.
 | 
| +TEST_F(BaseChannelDeathTest, SetTransportsDtlsToNonDtls) {
 | 
| +  ASSERT_TRUE(voice_channel_.Init_w(
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_,
 | 
| +      &fake_rtp_dtls_transport_, &fake_rtcp_dtls_transport_));
 | 
|    EXPECT_DEATH(
 | 
| -      voice_channel_.SetTransports(new_rtp_transport, new_rtcp_transport), "");
 | 
| +      voice_channel_.SetTransports(static_cast<rtc::PacketTransportInterface*>(
 | 
| +                                       &fake_rtp_dtls_transport_),
 | 
| +                                   static_cast<rtc::PacketTransportInterface*>(
 | 
| +                                       &fake_rtp_dtls_transport_)),
 | 
| +      "");
 | 
| +}
 | 
| +
 | 
| +// Not expected to support going from PacketTransportInterface to
 | 
| +// DtlsTransportInternal.
 | 
| +TEST_F(BaseChannelDeathTest, SetTransportsNonDtlsToDtls) {
 | 
| +  ASSERT_TRUE(voice_channel_.Init_w(nullptr, nullptr, &fake_rtp_dtls_transport_,
 | 
| +                                    &fake_rtcp_dtls_transport_));
 | 
| +  EXPECT_DEATH(voice_channel_.SetTransports(&fake_rtp_dtls_transport_,
 | 
| +                                            &fake_rtp_dtls_transport_),
 | 
| +               "");
 | 
|  }
 | 
|  
 | 
|  #endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
 | 
| 
 |