| Index: webrtc/pc/channel_unittest.cc | 
| diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc | 
| index 6039065e8321b38757834d9ef940d41ae144c113..196d66689097d93bd01d0ccb4fd82cec9dbc1d80 100644 | 
| --- a/webrtc/pc/channel_unittest.cc | 
| +++ b/webrtc/pc/channel_unittest.cc | 
| @@ -10,24 +10,13 @@ | 
|  | 
| #include <memory> | 
|  | 
| -#include "webrtc/base/arraysize.h" | 
| -#include "webrtc/base/criticalsection.h" | 
| -#include "webrtc/base/fileutils.h" | 
| +#include "webrtc/base/array_view.h" | 
| +#include "webrtc/base/buffer.h" | 
| #include "webrtc/base/gunit.h" | 
| -#include "webrtc/base/helpers.h" | 
| #include "webrtc/base/logging.h" | 
| -#include "webrtc/base/pathutils.h" | 
| -#include "webrtc/base/signalthread.h" | 
| -#include "webrtc/base/ssladapter.h" | 
| -#include "webrtc/base/sslidentity.h" | 
| -#include "webrtc/base/window.h" | 
| #include "webrtc/media/base/fakemediaengine.h" | 
| #include "webrtc/media/base/fakertp.h" | 
| -#include "webrtc/media/base/fakescreencapturerfactory.h" | 
| -#include "webrtc/media/base/fakevideocapturer.h" | 
| #include "webrtc/media/base/mediachannel.h" | 
| -#include "webrtc/media/base/rtpdump.h" | 
| -#include "webrtc/media/base/screencastid.h" | 
| #include "webrtc/media/base/testutils.h" | 
| #include "webrtc/p2p/base/faketransportcontroller.h" | 
| #include "webrtc/pc/channel.h" | 
| @@ -46,19 +35,21 @@ using cricket::FakeVoiceMediaChannel; | 
| using cricket::ScreencastId; | 
| using cricket::StreamParams; | 
| using cricket::TransportChannel; | 
| -using rtc::WindowId; | 
| - | 
| -static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 64000, 8000, 1); | 
| -static const cricket::AudioCodec kPcmaCodec(8, "PCMA", 64000, 8000, 1); | 
| -static const cricket::AudioCodec kIsacCodec(103, "ISAC", 40000, 16000, 1); | 
| -static const cricket::VideoCodec kH264Codec(97, "H264", 640, 400, 30); | 
| -static const cricket::VideoCodec kH264SvcCodec(99, "H264-SVC", 320, 200, 15); | 
| -static const cricket::DataCodec kGoogleDataCodec(101, "google-data"); | 
| -static const uint32_t kSsrc1 = 0x1111; | 
| -static const uint32_t kSsrc2 = 0x2222; | 
| -static const uint32_t kSsrc3 = 0x3333; | 
| -static const int kAudioPts[] = {0, 8}; | 
| -static const int kVideoPts[] = {97, 99}; | 
| + | 
| +namespace { | 
| +const cricket::AudioCodec kPcmuCodec(0, "PCMU", 64000, 8000, 1); | 
| +const cricket::AudioCodec kPcmaCodec(8, "PCMA", 64000, 8000, 1); | 
| +const cricket::AudioCodec kIsacCodec(103, "ISAC", 40000, 16000, 1); | 
| +const cricket::VideoCodec kH264Codec(97, "H264", 640, 400, 30); | 
| +const cricket::VideoCodec kH264SvcCodec(99, "H264-SVC", 320, 200, 15); | 
| +const cricket::DataCodec kGoogleDataCodec(101, "google-data"); | 
| +const uint32_t kSsrc1 = 0x1111; | 
| +const uint32_t kSsrc2 = 0x2222; | 
| +const uint32_t kSsrc3 = 0x3333; | 
| +const int kAudioPts[] = {0, 8}; | 
| +const int kVideoPts[] = {97, 99}; | 
| +enum class NetworkIsWorker { Yes, No }; | 
| +}  // namespace | 
|  | 
| template <class ChannelT, | 
| class MediaChannelT, | 
| @@ -76,10 +67,6 @@ class Traits { | 
| typedef OptionsT Options; | 
| }; | 
|  | 
| -// Controls how long we wait for a session to send messages that we | 
| -// expect, in milliseconds.  We put it high to avoid flaky tests. | 
| -static const int kEventTimeout = 5000; | 
| - | 
| class VoiceTraits : public Traits<cricket::VoiceChannel, | 
| cricket::FakeVoiceMediaChannel, | 
| cricket::AudioContentDescription, | 
| @@ -101,12 +88,7 @@ class DataTraits : public Traits<cricket::DataChannel, | 
| cricket::DataMediaInfo, | 
| cricket::DataOptions> {}; | 
|  | 
| -rtc::StreamInterface* Open(const std::string& path) { | 
| -  return rtc::Filesystem::OpenFile( | 
| -      rtc::Pathname(path), "wb"); | 
| -} | 
| - | 
| -// Base class for Voice/VideoChannel tests | 
| +// Base class for Voice/Video/DataChannel tests | 
| template<class T> | 
| class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| public: | 
| @@ -114,40 +96,52 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| DTLS = 0x10 }; | 
|  | 
| ChannelTest(bool verify_playout, | 
| -              const uint8_t* rtp_data, | 
| -              int rtp_len, | 
| -              const uint8_t* rtcp_data, | 
| -              int rtcp_len) | 
| +              rtc::ArrayView<const uint8_t> rtp_data, | 
| +              rtc::ArrayView<const uint8_t> rtcp_data, | 
| +              NetworkIsWorker network_is_worker) | 
| : verify_playout_(verify_playout), | 
| -        transport_controller1_(cricket::ICEROLE_CONTROLLING), | 
| -        transport_controller2_(cricket::ICEROLE_CONTROLLED), | 
| media_channel1_(NULL), | 
| media_channel2_(NULL), | 
| -        rtp_packet_(reinterpret_cast<const char*>(rtp_data), rtp_len), | 
| -        rtcp_packet_(reinterpret_cast<const char*>(rtcp_data), rtcp_len), | 
| +        rtp_packet_(rtp_data.data(), rtp_data.size()), | 
| +        rtcp_packet_(rtcp_data.data(), rtcp_data.size()), | 
| media_info_callbacks1_(), | 
| -        media_info_callbacks2_() {} | 
| +        media_info_callbacks2_() { | 
| +    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) { | 
| CreateChannels(new typename T::MediaChannel(NULL, typename T::Options()), | 
| new typename T::MediaChannel(NULL, typename T::Options()), | 
| -                   flags1, flags2, rtc::Thread::Current()); | 
| +                   flags1, flags2); | 
| } | 
| -  void CreateChannels( | 
| -      typename T::MediaChannel* ch1, typename T::MediaChannel* ch2, | 
| -      int flags1, int flags2, rtc::Thread* thread) { | 
| +  void CreateChannels(typename T::MediaChannel* ch1, | 
| +                      typename T::MediaChannel* ch2, | 
| +                      int flags1, | 
| +                      int flags2) { | 
| +    rtc::Thread* worker_thread = rtc::Thread::Current(); | 
| media_channel1_ = ch1; | 
| media_channel2_ = ch2; | 
| -    channel1_.reset(CreateChannel(thread, &media_engine_, ch1, | 
| -                                  &transport_controller1_, | 
| -                                  (flags1 & RTCP) != 0)); | 
| -    channel2_.reset(CreateChannel(thread, &media_engine_, ch2, | 
| -                                  &transport_controller2_, | 
| -                                  (flags2 & RTCP) != 0)); | 
| -    channel1_->SignalMediaMonitor.connect( | 
| -        this, &ChannelTest<T>::OnMediaMonitor); | 
| -    channel2_->SignalMediaMonitor.connect( | 
| -        this, &ChannelTest<T>::OnMediaMonitor); | 
| +    channel1_.reset( | 
| +        CreateChannel(worker_thread, network_thread_, &media_engine_, ch1, | 
| +                      transport_controller1_.get(), (flags1 & RTCP) != 0)); | 
| +    channel2_.reset( | 
| +        CreateChannel(worker_thread, network_thread_, &media_engine_, ch2, | 
| +                      transport_controller2_.get(), (flags2 & RTCP) != 0)); | 
| +    channel1_->SignalMediaMonitor.connect(this, | 
| +                                          &ChannelTest<T>::OnMediaMonitor1); | 
| +    channel2_->SignalMediaMonitor.connect(this, | 
| +                                          &ChannelTest<T>::OnMediaMonitor2); | 
| if ((flags1 & DTLS) && (flags2 & DTLS)) { | 
| flags1 = (flags1 & ~SECURE); | 
| flags2 = (flags2 & ~SECURE); | 
| @@ -161,13 +155,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
|  | 
| if (flags1 & DTLS) { | 
| // Confirmed to work with KT_RSA and KT_ECDSA. | 
| -      transport_controller1_.SetLocalCertificate( | 
| +      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( | 
| +      transport_controller2_->SetLocalCertificate( | 
| rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( | 
| rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)))); | 
| } | 
| @@ -187,13 +181,15 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| } | 
| } | 
| typename T::Channel* CreateChannel( | 
| -      rtc::Thread* thread, | 
| +      rtc::Thread* worker_thread, | 
| +      rtc::Thread* network_thread, | 
| cricket::MediaEngineInterface* engine, | 
| typename T::MediaChannel* ch, | 
| cricket::TransportController* transport_controller, | 
| bool rtcp) { | 
| -    typename T::Channel* channel = new typename T::Channel( | 
| -        thread, engine, ch, transport_controller, cricket::CN_AUDIO, rtcp); | 
| +    typename T::Channel* channel = | 
| +        new typename T::Channel(worker_thread, network_thread, engine, ch, | 
| +                                transport_controller, cricket::CN_AUDIO, rtcp); | 
| if (!channel->Init()) { | 
| delete channel; | 
| channel = NULL; | 
| @@ -209,7 +205,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_); | 
| +        transport_controller1_->Connect(transport_controller2_.get()); | 
|  | 
| result = channel2_->SetLocalContent(&local_media_content2_, | 
| CA_ANSWER, NULL); | 
| @@ -242,7 +238,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_); | 
| +      transport_controller1_->Connect(transport_controller2_.get()); | 
| } | 
| return result; | 
| } | 
| @@ -269,105 +265,92 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| return channel1_->RemoveRecvStream(id); | 
| } | 
|  | 
| -  // Calling "_w" method here is ok since we only use one thread for this test | 
| cricket::FakeTransport* GetTransport1() { | 
| -    return transport_controller1_.GetTransport_w(channel1_->content_name()); | 
| +    std::string name = channel1_->content_name(); | 
| +    return network_thread_->Invoke<cricket::FakeTransport*>( | 
| +        [this, name] { return transport_controller1_->GetTransport_w(name); }); | 
| } | 
| cricket::FakeTransport* GetTransport2() { | 
| -    return transport_controller2_.GetTransport_w(channel2_->content_name()); | 
| +    std::string name = channel2_->content_name(); | 
| +    return network_thread_->Invoke<cricket::FakeTransport*>( | 
| +        [this, name] { return transport_controller2_->GetTransport_w(name); }); | 
| } | 
|  | 
| -  bool SendRtp1() { | 
| -    return media_channel1_->SendRtp(rtp_packet_.c_str(), | 
| -                                    static_cast<int>(rtp_packet_.size()), | 
| -                                    rtc::PacketOptions()); | 
| +  void SendRtp1() { | 
| +    media_channel1_->SendRtp(rtp_packet_.data(), rtp_packet_.size(), | 
| +                             rtc::PacketOptions()); | 
| } | 
| -  bool SendRtp2() { | 
| -    return media_channel2_->SendRtp(rtp_packet_.c_str(), | 
| -                                    static_cast<int>(rtp_packet_.size()), | 
| -                                    rtc::PacketOptions()); | 
| +  void SendRtp2() { | 
| +    media_channel2_->SendRtp(rtp_packet_.data(), rtp_packet_.size(), | 
| +                             rtc::PacketOptions()); | 
| } | 
| -  bool SendRtcp1() { | 
| -    return media_channel1_->SendRtcp(rtcp_packet_.c_str(), | 
| -                                     static_cast<int>(rtcp_packet_.size())); | 
| +  void SendRtcp1() { | 
| +    media_channel1_->SendRtcp(rtcp_packet_.data(), rtcp_packet_.size()); | 
| } | 
| -  bool SendRtcp2() { | 
| -    return media_channel2_->SendRtcp(rtcp_packet_.c_str(), | 
| -                                     static_cast<int>(rtcp_packet_.size())); | 
| +  void SendRtcp2() { | 
| +    media_channel2_->SendRtcp(rtcp_packet_.data(), rtcp_packet_.size()); | 
| } | 
| // Methods to send custom data. | 
| -  bool SendCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) { | 
| -    std::string data(CreateRtpData(ssrc, sequence_number, pl_type)); | 
| -    return media_channel1_->SendRtp(data.c_str(), static_cast<int>(data.size()), | 
| -                                    rtc::PacketOptions()); | 
| -  } | 
| -  bool SendCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) { | 
| -    std::string data(CreateRtpData(ssrc, sequence_number, pl_type)); | 
| -    return media_channel2_->SendRtp(data.c_str(), static_cast<int>(data.size()), | 
| -                                    rtc::PacketOptions()); | 
| -  } | 
| -  bool SendCustomRtcp1(uint32_t ssrc) { | 
| -    std::string data(CreateRtcpData(ssrc)); | 
| -    return media_channel1_->SendRtcp(data.c_str(), | 
| -                                     static_cast<int>(data.size())); | 
| -  } | 
| -  bool SendCustomRtcp2(uint32_t ssrc) { | 
| -    std::string data(CreateRtcpData(ssrc)); | 
| -    return media_channel2_->SendRtcp(data.c_str(), | 
| -                                     static_cast<int>(data.size())); | 
| +  void SendCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) { | 
| +    rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type); | 
| +    media_channel1_->SendRtp(data.data(), data.size(), rtc::PacketOptions()); | 
| +  } | 
| +  void SendCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) { | 
| +    rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type); | 
| +    media_channel2_->SendRtp(data.data(), data.size(), rtc::PacketOptions()); | 
| +  } | 
| +  void SendCustomRtcp1(uint32_t ssrc) { | 
| +    rtc::Buffer data = CreateRtcpData(ssrc); | 
| +    media_channel1_->SendRtcp(data.data(), data.size()); | 
| } | 
| +  void SendCustomRtcp2(uint32_t ssrc) { | 
| +    rtc::Buffer data = CreateRtcpData(ssrc); | 
| +    media_channel2_->SendRtcp(data.data(), data.size()); | 
| +  } | 
| + | 
| bool CheckRtp1() { | 
| -    return media_channel1_->CheckRtp(rtp_packet_.c_str(), | 
| -                                     static_cast<int>(rtp_packet_.size())); | 
| +    return media_channel1_->CheckRtp(rtp_packet_.data(), rtp_packet_.size()); | 
| } | 
| bool CheckRtp2() { | 
| -    return media_channel2_->CheckRtp(rtp_packet_.c_str(), | 
| -                                     static_cast<int>(rtp_packet_.size())); | 
| +    return media_channel2_->CheckRtp(rtp_packet_.data(), rtp_packet_.size()); | 
| } | 
| bool CheckRtcp1() { | 
| -    return media_channel1_->CheckRtcp(rtcp_packet_.c_str(), | 
| -                                      static_cast<int>(rtcp_packet_.size())); | 
| +    return media_channel1_->CheckRtcp(rtcp_packet_.data(), rtcp_packet_.size()); | 
| } | 
| bool CheckRtcp2() { | 
| -    return media_channel2_->CheckRtcp(rtcp_packet_.c_str(), | 
| -                                      static_cast<int>(rtcp_packet_.size())); | 
| +    return media_channel2_->CheckRtcp(rtcp_packet_.data(), rtcp_packet_.size()); | 
| } | 
| // Methods to check custom data. | 
| bool CheckCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) { | 
| -    std::string data(CreateRtpData(ssrc, sequence_number, pl_type)); | 
| -    return media_channel1_->CheckRtp(data.c_str(), | 
| -                                     static_cast<int>(data.size())); | 
| +    rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type); | 
| +    return media_channel1_->CheckRtp(data.data(), data.size()); | 
| } | 
| bool CheckCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) { | 
| -    std::string data(CreateRtpData(ssrc, sequence_number, pl_type)); | 
| -    return media_channel2_->CheckRtp(data.c_str(), | 
| -                                     static_cast<int>(data.size())); | 
| +    rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type); | 
| +    return media_channel2_->CheckRtp(data.data(), data.size()); | 
| } | 
| bool CheckCustomRtcp1(uint32_t ssrc) { | 
| -    std::string data(CreateRtcpData(ssrc)); | 
| -    return media_channel1_->CheckRtcp(data.c_str(), | 
| -                                      static_cast<int>(data.size())); | 
| +    rtc::Buffer data = CreateRtcpData(ssrc); | 
| +    return media_channel1_->CheckRtcp(data.data(), data.size()); | 
| } | 
| bool CheckCustomRtcp2(uint32_t ssrc) { | 
| -    std::string data(CreateRtcpData(ssrc)); | 
| -    return media_channel2_->CheckRtcp(data.c_str(), | 
| -                                      static_cast<int>(data.size())); | 
| +    rtc::Buffer data = CreateRtcpData(ssrc); | 
| +    return media_channel2_->CheckRtcp(data.data(), data.size()); | 
| } | 
| -  std::string CreateRtpData(uint32_t ssrc, int sequence_number, int pl_type) { | 
| -    std::string data(rtp_packet_); | 
| +  rtc::Buffer CreateRtpData(uint32_t ssrc, int sequence_number, int pl_type) { | 
| +    rtc::Buffer data(rtp_packet_.data(), rtp_packet_.size()); | 
| // Set SSRC in the rtp packet copy. | 
| -    rtc::SetBE32(const_cast<char*>(data.c_str()) + 8, ssrc); | 
| -    rtc::SetBE16(const_cast<char*>(data.c_str()) + 2, sequence_number); | 
| +    rtc::SetBE32(data.data() + 8, ssrc); | 
| +    rtc::SetBE16(data.data() + 2, sequence_number); | 
| if (pl_type >= 0) { | 
| -      rtc::Set8(const_cast<char*>(data.c_str()), 1, | 
| -                static_cast<uint8_t>(pl_type)); | 
| +      rtc::Set8(data.data(), 1, static_cast<uint8_t>(pl_type)); | 
| } | 
| return data; | 
| } | 
| -  std::string CreateRtcpData(uint32_t ssrc) { | 
| -    std::string data(rtcp_packet_); | 
| +  rtc::Buffer CreateRtcpData(uint32_t ssrc) { | 
| +    rtc::Buffer data(rtcp_packet_.data(), rtcp_packet_.size()); | 
| // Set SSRC in the rtcp packet copy. | 
| -    rtc::SetBE32(const_cast<char*>(data.c_str()) + 4, ssrc); | 
| +    rtc::SetBE32(data.data() + 4, ssrc); | 
| return data; | 
| } | 
|  | 
| @@ -408,86 +391,40 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| return sdesc; | 
| } | 
|  | 
| -  class CallThread : public rtc::SignalThread { | 
| -   public: | 
| -    typedef bool (ChannelTest<T>::*Method)(); | 
| -    CallThread(ChannelTest<T>* obj, Method method, bool* result = nullptr) | 
| -        : obj_(obj), | 
| -          method_(method), | 
| -          result_(false), | 
| -          result_ptr_(result) { | 
| -      if (result_ptr_) | 
| -        *result_ptr_ = false; | 
| -    } | 
| - | 
| -    ~CallThread() { | 
| -      if (result_ptr_) { | 
| -        rtc::CritScope cs(&result_lock_); | 
| -        *result_ptr_ = result_; | 
| -      } | 
| -    } | 
| - | 
| -    virtual void DoWork() { | 
| -      SetResult((*obj_.*method_)()); | 
| -    } | 
| - | 
| -    bool result() { | 
| -      rtc::CritScope cs(&result_lock_); | 
| -      return result_; | 
| -    } | 
| - | 
| -   private: | 
| -    void SetResult(const bool& result) { | 
| -      rtc::CritScope cs(&result_lock_); | 
| -      result_ = result; | 
| -    } | 
| - | 
| -    ChannelTest<T>* obj_; | 
| -    Method method_; | 
| -    rtc::CriticalSection result_lock_; | 
| -    bool result_ GUARDED_BY(result_lock_); | 
| -    bool* result_ptr_; | 
| -  }; | 
| - | 
| // Will manage the lifetime of a CallThread, making sure it's | 
| // destroyed before this object goes out of scope. | 
| class ScopedCallThread { | 
| public: | 
| -    using Method = typename CallThread::Method; | 
| - | 
| -    ScopedCallThread(ChannelTest<T>* obj, Method method) | 
| -        : thread_(new CallThread(obj, method)) { | 
| +    template <class FunctorT> | 
| +    ScopedCallThread(const FunctorT& functor) | 
| +        : thread_(rtc::Thread::Create()), | 
| +          task_(new rtc::FunctorMessageHandler<void, FunctorT>(functor)) { | 
| thread_->Start(); | 
| +      thread_->Post(task_.get()); | 
| } | 
|  | 
| -    ~ScopedCallThread() { | 
| -      thread_->Destroy(true); | 
| -    } | 
| +    ~ScopedCallThread() { thread_->Stop(); } | 
|  | 
| -    bool result() const { return thread_->result(); } | 
| +    rtc::Thread* thread() { return thread_.get(); } | 
|  | 
| private: | 
| -    CallThread* thread_; | 
| +    std::unique_ptr<rtc::Thread> thread_; | 
| +    std::unique_ptr<rtc::MessageHandler> task_; | 
| }; | 
|  | 
| -  void CallOnThreadAndWaitForDone(typename CallThread::Method method, | 
| -                                  bool* result) { | 
| -    CallThread* thread = new CallThread(this, method, result); | 
| -    thread->Start(); | 
| -    thread->Destroy(true); | 
| -  } | 
| - | 
| bool CodecMatches(const typename T::Codec& c1, const typename T::Codec& c2) { | 
| return false;  // overridden in specialized classes | 
| } | 
|  | 
| -  void OnMediaMonitor(typename T::Channel* channel, | 
| -                      const typename T::MediaInfo& info) { | 
| -    if (channel == channel1_.get()) { | 
| -      media_info_callbacks1_++; | 
| -    } else if (channel == channel2_.get()) { | 
| -      media_info_callbacks2_++; | 
| -    } | 
| +  void OnMediaMonitor1(typename T::Channel* channel, | 
| +                       const typename T::MediaInfo& info) { | 
| +    RTC_DCHECK_EQ(channel, channel1_.get()); | 
| +    media_info_callbacks1_++; | 
| +  } | 
| +  void OnMediaMonitor2(typename T::Channel* channel, | 
| +                       const typename T::MediaInfo& info) { | 
| +    RTC_DCHECK_EQ(channel, channel2_.get()); | 
| +    media_info_callbacks2_++; | 
| } | 
|  | 
| cricket::CandidatePairInterface* last_selected_candidate_pair() { | 
| @@ -792,7 +729,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_); | 
| +    transport_controller1_->Connect(transport_controller2_.get()); | 
|  | 
| // Channel 2 do not send anything. | 
| typename T::Content content2; | 
| @@ -803,7 +740,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_TRUE(channel2_->Enable(true)); | 
| EXPECT_EQ(0u, media_channel2_->send_streams().size()); | 
|  | 
| -    EXPECT_TRUE(SendCustomRtp1(kSsrc1, 0)); | 
| +    SendCustomRtp1(kSsrc1, 0); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckCustomRtp2(kSsrc1, 0)); | 
|  | 
| // Let channel 2 update the content by sending |stream2| and enable SRTP. | 
| @@ -829,7 +767,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
|  | 
| EXPECT_TRUE(channel1_->secure()); | 
| EXPECT_TRUE(channel2_->secure()); | 
| -    EXPECT_TRUE(SendCustomRtp2(kSsrc2, 0)); | 
| +    SendCustomRtp2(kSsrc2, 0); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckCustomRtp1(kSsrc2, 0)); | 
| } | 
|  | 
| @@ -867,7 +806,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_); | 
| +    transport_controller1_->Connect(transport_controller2_.get()); | 
| if (verify_playout_) { | 
| EXPECT_TRUE(media_channel1_->playout()); | 
| } | 
| @@ -915,7 +854,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_); | 
| +    transport_controller1_->Connect(transport_controller2_.get()); | 
|  | 
| if (verify_playout_) { | 
| EXPECT_TRUE(media_channel1_->playout()); | 
| @@ -958,39 +897,47 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| // Tests that when the transport channel signals a candidate pair change | 
| // event, the media channel will receive a call on the network route change. | 
| void TestNetworkRouteChanges() { | 
| +    constexpr uint16_t kLocalNetId = 1; | 
| +    constexpr uint16_t kRemoteNetId = 2; | 
| +    constexpr int kLastPacketId = 100; | 
| + | 
| CreateChannels(0, 0); | 
|  | 
| cricket::TransportChannel* transport_channel1 = | 
| channel1_->transport_channel(); | 
| -    ASSERT_TRUE(transport_channel1 != nullptr); | 
| +    ASSERT_TRUE(transport_channel1); | 
| typename T::MediaChannel* media_channel1 = | 
| static_cast<typename T::MediaChannel*>(channel1_->media_channel()); | 
| -    ASSERT_TRUE(media_channel1 != nullptr); | 
| - | 
| -    media_channel1_->set_num_network_route_changes(0); | 
| -    // The transport channel becomes disconnected. | 
| -    transport_channel1->SignalSelectedCandidatePairChanged(transport_channel1, | 
| -                                                           nullptr, -1); | 
| -    EXPECT_EQ(1, media_channel1_->num_network_route_changes()); | 
| +    ASSERT_TRUE(media_channel1); | 
| + | 
| +    media_channel1->set_num_network_route_changes(0); | 
| +    network_thread_->Invoke<void>([transport_channel1] { | 
| +      // The transport channel becomes disconnected. | 
| +      transport_channel1->SignalSelectedCandidatePairChanged(transport_channel1, | 
| +                                                             nullptr, -1); | 
| +    }); | 
| +    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); | 
| -    // 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 */); | 
| -    uint16_t local_net_id = 1; | 
| -    uint16_t remote_net_id = 2; | 
| -    int last_packet_id = 100; | 
| -    std::unique_ptr<cricket::CandidatePairInterface> candidate_pair( | 
| -        transport_controller1_.CreateFakeCandidatePair( | 
| -            local_address, local_net_id, remote_address, remote_net_id)); | 
| -    transport_channel1->SignalSelectedCandidatePairChanged( | 
| -        transport_channel1, candidate_pair.get(), last_packet_id); | 
| -    EXPECT_EQ(1, media_channel1_->num_network_route_changes()); | 
| -    rtc::NetworkRoute expected_network_route(local_net_id, remote_net_id, | 
| -                                             last_packet_id); | 
| +    media_channel1->set_num_network_route_changes(0); | 
| + | 
| +    network_thread_->Invoke<void>([this, transport_channel1, 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->SignalSelectedCandidatePairChanged( | 
| +          transport_channel1, candidate_pair.get(), kLastPacketId); | 
| +    }); | 
| +    WaitForThreads(); | 
| +    EXPECT_EQ(1, media_channel1->num_network_route_changes()); | 
| +    rtc::NetworkRoute expected_network_route(kLocalNetId, kRemoteNetId, | 
| +                                             kLastPacketId); | 
| EXPECT_EQ(expected_network_route, media_channel1->last_network_route()); | 
| -    EXPECT_EQ(last_packet_id, | 
| +    EXPECT_EQ(kLastPacketId, | 
| media_channel1->last_network_route().last_sent_packet_id); | 
| } | 
|  | 
| @@ -1029,8 +976,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| } | 
| }; | 
| CreateChannels(new LastWordMediaChannel(), new LastWordMediaChannel(), | 
| -                   RTCP | RTCP_MUX, RTCP | RTCP_MUX, | 
| -                   rtc::Thread::Current()); | 
| +                   RTCP | RTCP_MUX, RTCP | RTCP_MUX); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_TRUE(SendTerminate()); | 
| @@ -1045,8 +991,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1062,8 +1009,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| -    EXPECT_FALSE(SendRtcp1()); | 
| -    EXPECT_FALSE(SendRtcp2()); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| EXPECT_TRUE(CheckNoRtcp2()); | 
| } | 
| @@ -1077,8 +1025,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(2U, GetTransport2()->channels().size()); | 
| -    EXPECT_FALSE(SendRtcp1()); | 
| -    EXPECT_FALSE(SendRtcp2()); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| EXPECT_TRUE(CheckNoRtcp2()); | 
| } | 
| @@ -1092,8 +1041,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(2U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| -    EXPECT_FALSE(SendRtcp1()); | 
| -    EXPECT_FALSE(SendRtcp2()); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| EXPECT_TRUE(CheckNoRtcp2()); | 
| } | 
| @@ -1107,8 +1057,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(2U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(2U, GetTransport2()->channels().size()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtcp1()); | 
| EXPECT_TRUE(CheckRtcp2()); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| @@ -1124,8 +1075,9 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(2U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(2U, GetTransport2()->channels().size()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtcp1()); | 
| EXPECT_TRUE(CheckRtcp2()); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| @@ -1142,10 +1094,11 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1167,10 +1120,11 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| EXPECT_TRUE(SendAccept()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1193,10 +1147,11 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1220,10 +1175,11 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1258,21 +1214,24 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
|  | 
| // 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. | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| +    SendRtcp1(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
| EXPECT_TRUE(CheckRtcp2()); | 
|  | 
| // Send RTCP packet from callee and verify that it is received. | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| EXPECT_TRUE(CheckRtcp1()); | 
|  | 
| // Complete call setup and ensure everything is still OK. | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_EQ(2U, GetTransport1()->channels().size()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtcp2()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| EXPECT_TRUE(CheckRtcp1()); | 
| } | 
|  | 
| @@ -1290,19 +1249,23 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
|  | 
| // 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. | 
| -    EXPECT_FALSE(SendRtcp1()); | 
| +    SendRtcp1(); | 
| +    WaitForThreads(); | 
| +    EXPECT_TRUE(CheckNoRtcp2()); | 
|  | 
| // Send muxed RTCP packet from callee and verify that it is received. | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| EXPECT_TRUE(CheckRtcp1()); | 
|  | 
| // Complete call setup and ensure everything is still OK. | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtcp2()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| EXPECT_TRUE(CheckRtcp1()); | 
| } | 
|  | 
| @@ -1320,17 +1283,19 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_FALSE(channel1_->secure()); | 
| EXPECT_FALSE(channel2_->secure()); | 
| EXPECT_TRUE(SendInitiate()); | 
| -    EXPECT_TRUE_WAIT(channel1_->writable(), kEventTimeout); | 
| -    EXPECT_TRUE_WAIT(channel2_->writable(), kEventTimeout); | 
| +    WaitForThreads(); | 
| +    EXPECT_TRUE(channel1_->writable()); | 
| +    EXPECT_TRUE(channel2_->writable()); | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_TRUE(channel1_->secure()); | 
| EXPECT_TRUE(channel2_->secure()); | 
| EXPECT_EQ(dtls1 && dtls2, channel1_->secure_dtls()); | 
| EXPECT_EQ(dtls1 && dtls2, channel2_->secure_dtls()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1350,10 +1315,11 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_TRUE(SendAccept()); | 
| EXPECT_FALSE(channel1_->secure()); | 
| EXPECT_FALSE(channel2_->secure()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| -    EXPECT_TRUE(SendRtcp1()); | 
| -    EXPECT_TRUE(SendRtcp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    SendRtcp1(); | 
| +    SendRtcp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1379,15 +1345,18 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(2U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(2U, GetTransport2()->channels().size()); | 
| -      EXPECT_TRUE(SendCustomRtcp1(kSsrc1)); | 
| +      WaitForThreads();  // Wait for 'sending' flag go through network thread. | 
| +      SendCustomRtcp1(kSsrc1); | 
| +      SendCustomRtp1(kSsrc1, ++sequence_number1_1); | 
| +      WaitForThreads(); | 
| EXPECT_TRUE(CheckCustomRtcp2(kSsrc1)); | 
| -      EXPECT_TRUE(SendCustomRtp1(kSsrc1, ++sequence_number1_1)); | 
| EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1)); | 
|  | 
| // Send packets from callee and verify that it is received. | 
| -      EXPECT_TRUE(SendCustomRtcp2(kSsrc2)); | 
| +      SendCustomRtcp2(kSsrc2); | 
| +      SendCustomRtp2(kSsrc2, ++sequence_number2_2); | 
| +      WaitForThreads(); | 
| EXPECT_TRUE(CheckCustomRtcp1(kSsrc2)); | 
| -      EXPECT_TRUE(SendCustomRtp2(kSsrc2, ++sequence_number2_2)); | 
| EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2)); | 
|  | 
| // Complete call setup and ensure everything is still OK. | 
| @@ -1396,13 +1365,14 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| EXPECT_TRUE(channel1_->secure()); | 
| EXPECT_TRUE(channel2_->secure()); | 
| -      EXPECT_TRUE(SendCustomRtcp1(kSsrc1)); | 
| +      SendCustomRtcp1(kSsrc1); | 
| +      SendCustomRtp1(kSsrc1, ++sequence_number1_1); | 
| +      SendCustomRtcp2(kSsrc2); | 
| +      SendCustomRtp2(kSsrc2, ++sequence_number2_2); | 
| +      WaitForThreads(); | 
| EXPECT_TRUE(CheckCustomRtcp2(kSsrc1)); | 
| -      EXPECT_TRUE(SendCustomRtp1(kSsrc1, ++sequence_number1_1)); | 
| EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1)); | 
| -      EXPECT_TRUE(SendCustomRtcp2(kSsrc2)); | 
| EXPECT_TRUE(CheckCustomRtcp1(kSsrc2)); | 
| -      EXPECT_TRUE(SendCustomRtp2(kSsrc2, ++sequence_number2_2)); | 
| EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2)); | 
| } | 
|  | 
| @@ -1411,20 +1381,20 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| CreateChannels(RTCP, RTCP); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
| -    ScopedCallThread send_rtp1(this, &ChannelTest<T>::SendRtp1); | 
| -    ScopedCallThread send_rtp2(this, &ChannelTest<T>::SendRtp2); | 
| -    ScopedCallThread send_rtcp1(this, &ChannelTest<T>::SendRtcp1); | 
| -    ScopedCallThread send_rtcp2(this, &ChannelTest<T>::SendRtcp2); | 
| -    EXPECT_TRUE_WAIT(CheckRtp1(), 1000); | 
| -    EXPECT_TRUE_WAIT(CheckRtp2(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtp1.result(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtp2.result(), 1000); | 
| +    ScopedCallThread send_rtp1([this] { SendRtp1(); }); | 
| +    ScopedCallThread send_rtp2([this] { SendRtp2(); }); | 
| +    ScopedCallThread send_rtcp1([this] { SendRtcp1(); }); | 
| +    ScopedCallThread send_rtcp2([this] { SendRtcp2(); }); | 
| +    rtc::Thread* involved_threads[] = {send_rtp1.thread(), send_rtp2.thread(), | 
| +                                       send_rtcp1.thread(), | 
| +                                       send_rtcp2.thread()}; | 
| +    WaitForThreads(involved_threads); | 
| +    EXPECT_TRUE(CheckRtp1()); | 
| +    EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
| -    EXPECT_TRUE_WAIT(CheckRtcp1(), 1000); | 
| -    EXPECT_TRUE_WAIT(CheckRtcp2(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtcp1.result(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtcp2.result(), 1000); | 
| +    EXPECT_TRUE(CheckRtcp1()); | 
| +    EXPECT_TRUE(CheckRtcp2()); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| EXPECT_TRUE(CheckNoRtcp2()); | 
| } | 
| @@ -1434,20 +1404,20 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| CreateChannels(RTCP | SECURE, RTCP | SECURE); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
| -    ScopedCallThread send_rtp1(this, &ChannelTest<T>::SendRtp1); | 
| -    ScopedCallThread send_rtp2(this, &ChannelTest<T>::SendRtp2); | 
| -    ScopedCallThread send_rtcp1(this, &ChannelTest<T>::SendRtcp1); | 
| -    ScopedCallThread send_rtcp2(this, &ChannelTest<T>::SendRtcp2); | 
| -    EXPECT_TRUE_WAIT(CheckRtp1(), 1000); | 
| -    EXPECT_TRUE_WAIT(CheckRtp2(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtp1.result(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtp2.result(), 1000); | 
| +    ScopedCallThread send_rtp1([this] { SendRtp1(); }); | 
| +    ScopedCallThread send_rtp2([this] { SendRtp2(); }); | 
| +    ScopedCallThread send_rtcp1([this] { SendRtcp1(); }); | 
| +    ScopedCallThread send_rtcp2([this] { SendRtcp2(); }); | 
| +    rtc::Thread* involved_threads[] = {send_rtp1.thread(), send_rtp2.thread(), | 
| +                                       send_rtcp1.thread(), | 
| +                                       send_rtcp2.thread()}; | 
| +    WaitForThreads(involved_threads); | 
| +    EXPECT_TRUE(CheckRtp1()); | 
| +    EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
| -    EXPECT_TRUE_WAIT(CheckRtcp1(), 1000); | 
| -    EXPECT_TRUE_WAIT(CheckRtcp2(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtcp1.result(), 1000); | 
| -    EXPECT_TRUE_WAIT(send_rtcp2.result(), 1000); | 
| +    EXPECT_TRUE(CheckRtcp1()); | 
| +    EXPECT_TRUE(CheckRtcp2()); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| EXPECT_TRUE(CheckNoRtcp2()); | 
| } | 
| @@ -1462,45 +1432,54 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| ASSERT_TRUE(GetTransport2()); | 
| EXPECT_EQ(1U, GetTransport1()->channels().size()); | 
| EXPECT_EQ(1U, GetTransport2()->channels().size()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
|  | 
| // Lose writability, which should fail. | 
| -    GetTransport1()->SetWritable(false); | 
| -    EXPECT_FALSE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { GetTransport1()->SetWritable(false); }); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
|  | 
| // Regain writability | 
| -    GetTransport1()->SetWritable(true); | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { GetTransport1()->SetWritable(true); }); | 
| EXPECT_TRUE(media_channel1_->sending()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
|  | 
| // Lose writability completely | 
| -    GetTransport1()->SetDestination(NULL); | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { GetTransport1()->SetDestination(NULL); }); | 
| EXPECT_TRUE(media_channel1_->sending()); | 
|  | 
| // Should fail also. | 
| -    EXPECT_FALSE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
|  | 
| // Gain writability back | 
| -    GetTransport1()->SetDestination(GetTransport2()); | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { GetTransport1()->SetDestination(GetTransport2()); }); | 
| EXPECT_TRUE(media_channel1_->sending()); | 
| -    EXPECT_TRUE(SendRtp1()); | 
| -    EXPECT_TRUE(SendRtp2()); | 
| +    SendRtp1(); | 
| +    SendRtp2(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtp1()); | 
| EXPECT_TRUE(CheckRtp2()); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| @@ -1537,28 +1516,32 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_FALSE(channel2_->bundle_filter()->FindPayloadType(pl_type2)); | 
|  | 
| // Both channels can receive pl_type1 only. | 
| -    EXPECT_TRUE(SendCustomRtp1(kSsrc1, ++sequence_number1_1, pl_type1)); | 
| +    SendCustomRtp1(kSsrc1, ++sequence_number1_1, pl_type1); | 
| +    SendCustomRtp2(kSsrc2, ++sequence_number2_2, pl_type1); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1, pl_type1)); | 
| -    EXPECT_TRUE(SendCustomRtp2(kSsrc2, ++sequence_number2_2, pl_type1)); | 
| EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2, pl_type1)); | 
| EXPECT_TRUE(CheckNoRtp1()); | 
| EXPECT_TRUE(CheckNoRtp2()); | 
|  | 
| // RTCP test | 
| -    EXPECT_TRUE(SendCustomRtp1(kSsrc1, ++sequence_number1_1, pl_type2)); | 
| +    SendCustomRtp1(kSsrc1, ++sequence_number1_1, pl_type2); | 
| +    SendCustomRtp2(kSsrc2, ++sequence_number2_2, pl_type2); | 
| +    WaitForThreads(); | 
| EXPECT_FALSE(CheckCustomRtp2(kSsrc1, sequence_number1_1, pl_type2)); | 
| -    EXPECT_TRUE(SendCustomRtp2(kSsrc2, ++sequence_number2_2, pl_type2)); | 
| EXPECT_FALSE(CheckCustomRtp1(kSsrc2, sequence_number2_2, pl_type2)); | 
|  | 
| -    EXPECT_TRUE(SendCustomRtcp1(kSsrc1)); | 
| -    EXPECT_TRUE(SendCustomRtcp2(kSsrc2)); | 
| +    SendCustomRtcp1(kSsrc1); | 
| +    SendCustomRtcp2(kSsrc2); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckCustomRtcp1(kSsrc2)); | 
| EXPECT_TRUE(CheckNoRtcp1()); | 
| EXPECT_TRUE(CheckCustomRtcp2(kSsrc1)); | 
| EXPECT_TRUE(CheckNoRtcp2()); | 
|  | 
| -    EXPECT_TRUE(SendCustomRtcp1(kSsrc2)); | 
| -    EXPECT_TRUE(SendCustomRtcp2(kSsrc1)); | 
| +    SendCustomRtcp1(kSsrc2); | 
| +    SendCustomRtcp2(kSsrc1); | 
| +    WaitForThreads(); | 
| // Bundle filter shouldn't filter out any RTCP. | 
| EXPECT_TRUE(CheckCustomRtcp1(kSsrc1)); | 
| EXPECT_TRUE(CheckCustomRtcp2(kSsrc2)); | 
| @@ -1704,7 +1687,6 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| } | 
|  | 
| void TestFlushRtcp() { | 
| -    bool send_rtcp1; | 
| CreateChannels(RTCP, RTCP); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
| @@ -1714,14 +1696,16 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_EQ(2U, GetTransport2()->channels().size()); | 
|  | 
| // Send RTCP1 from a different thread. | 
| -    CallOnThreadAndWaitForDone(&ChannelTest<T>::SendRtcp1, &send_rtcp1); | 
| -    EXPECT_TRUE(send_rtcp1); | 
| +    ScopedCallThread send_rtcp([this] { SendRtcp1(); }); | 
| // The sending message is only posted.  channel2_ should be empty. | 
| EXPECT_TRUE(CheckNoRtcp2()); | 
| +    rtc::Thread* wait_for[] = {send_rtcp.thread()}; | 
| +    WaitForThreads(wait_for);  // Ensure rtcp was posted | 
|  | 
| // When channel1_ is deleted, the RTCP packet should be sent out to | 
| // channel2_. | 
| channel1_.reset(); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(CheckRtcp2()); | 
| } | 
|  | 
| @@ -1744,18 +1728,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| // So we need to pass in pl_type so that the packet can pass through | 
| // the bundle filter before it can be processed by the srtp filter. | 
| // The packet is not a valid srtp packet because it is too short. | 
| -    unsigned const char kBadPacket[] = {0x84, | 
| -                                        static_cast<unsigned char>(pl_type), | 
| -                                        0x00, | 
| -                                        0x01, | 
| -                                        0x00, | 
| -                                        0x00, | 
| -                                        0x00, | 
| -                                        0x00, | 
| -                                        0x00, | 
| -                                        0x00, | 
| -                                        0x00, | 
| -                                        0x01}; | 
| +    static unsigned const char kBadPacket[] = { | 
| +        0x84, static_cast<unsigned char>(pl_type), | 
| +        0x00, 0x01, | 
| +        0x00, 0x00, | 
| +        0x00, 0x00, | 
| +        0x00, 0x00, | 
| +        0x00, 0x01}; | 
| CreateChannels(RTCP | SECURE, RTCP | SECURE); | 
| EXPECT_FALSE(channel1_->secure()); | 
| EXPECT_FALSE(channel2_->secure()); | 
| @@ -1768,37 +1747,42 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| &error_handler, &SrtpErrorHandler::OnSrtpError); | 
|  | 
| // Testing failures in sending packets. | 
| -    EXPECT_FALSE(media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket), | 
| -                                          rtc::PacketOptions())); | 
| +    media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket), | 
| +                             rtc::PacketOptions()); | 
| +    WaitForThreads(); | 
| // The first failure will trigger an error. | 
| -    EXPECT_EQ_WAIT(cricket::SrtpFilter::ERROR_FAIL, error_handler.error_, 500); | 
| +    EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_handler.error_); | 
| EXPECT_EQ(cricket::SrtpFilter::PROTECT, error_handler.mode_); | 
| error_handler.error_ = cricket::SrtpFilter::ERROR_NONE; | 
| error_handler.mode_ = cricket::SrtpFilter::UNPROTECT; | 
| // The next 250 ms failures will not trigger an error. | 
| -    EXPECT_FALSE(media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket), | 
| -                                          rtc::PacketOptions())); | 
| +    media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket), | 
| +                             rtc::PacketOptions()); | 
| // Wait for a while to ensure no message comes in. | 
| +    WaitForThreads(); | 
| rtc::Thread::Current()->ProcessMessages(200); | 
| EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_handler.error_); | 
| EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, error_handler.mode_); | 
| // Wait for a little more - the error will be triggered again. | 
| rtc::Thread::Current()->ProcessMessages(200); | 
| -    EXPECT_FALSE(media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket), | 
| -                                          rtc::PacketOptions())); | 
| -    EXPECT_EQ_WAIT(cricket::SrtpFilter::ERROR_FAIL, error_handler.error_, 500); | 
| +    media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket), | 
| +                             rtc::PacketOptions()); | 
| +    WaitForThreads(); | 
| +    EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_handler.error_); | 
| EXPECT_EQ(cricket::SrtpFilter::PROTECT, error_handler.mode_); | 
|  | 
| // Testing failures in receiving packets. | 
| error_handler.error_ = cricket::SrtpFilter::ERROR_NONE; | 
| error_handler.mode_ = cricket::SrtpFilter::UNPROTECT; | 
|  | 
| -    cricket::TransportChannel* transport_channel = | 
| -        channel2_->transport_channel(); | 
| -    transport_channel->SignalReadPacket( | 
| -        transport_channel, reinterpret_cast<const char*>(kBadPacket), | 
| -        sizeof(kBadPacket), rtc::PacketTime(), 0); | 
| -    EXPECT_EQ_WAIT(cricket::SrtpFilter::ERROR_FAIL, error_handler.error_, 500); | 
| +    network_thread_->Invoke<void>([this] { | 
| +      cricket::TransportChannel* transport_channel = | 
| +          channel2_->transport_channel(); | 
| +      transport_channel->SignalReadPacket( | 
| +          transport_channel, 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_); | 
| } | 
|  | 
| @@ -1807,23 +1791,37 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| TransportChannel* rtp = channel1_->transport_channel(); | 
| TransportChannel* rtcp = channel1_->rtcp_transport_channel(); | 
| EXPECT_FALSE(media_channel1_->ready_to_send()); | 
| -    rtp->SignalReadyToSend(rtp); | 
| + | 
| +    network_thread_->Invoke<void>([rtp] { rtp->SignalReadyToSend(rtp); }); | 
| +    WaitForThreads(); | 
| EXPECT_FALSE(media_channel1_->ready_to_send()); | 
| -    rtcp->SignalReadyToSend(rtcp); | 
| + | 
| +    network_thread_->Invoke<void>([rtcp] { rtcp->SignalReadyToSend(rtcp); }); | 
| +    WaitForThreads(); | 
| // MediaChannel::OnReadyToSend only be called when both rtp and rtcp | 
| // channel are ready to send. | 
| EXPECT_TRUE(media_channel1_->ready_to_send()); | 
|  | 
| // rtp channel becomes not ready to send will be propagated to mediachannel | 
| -    channel1_->SetReadyToSend(false, false); | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { channel1_->SetReadyToSend(false, false); }); | 
| +    WaitForThreads(); | 
| EXPECT_FALSE(media_channel1_->ready_to_send()); | 
| -    channel1_->SetReadyToSend(false, true); | 
| + | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { channel1_->SetReadyToSend(false, true); }); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(media_channel1_->ready_to_send()); | 
|  | 
| // rtcp channel becomes not ready to send will be propagated to mediachannel | 
| -    channel1_->SetReadyToSend(true, false); | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { channel1_->SetReadyToSend(true, false); }); | 
| +    WaitForThreads(); | 
| EXPECT_FALSE(media_channel1_->ready_to_send()); | 
| -    channel1_->SetReadyToSend(true, true); | 
| + | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { channel1_->SetReadyToSend(true, true); }); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(media_channel1_->ready_to_send()); | 
| } | 
|  | 
| @@ -1840,9 +1838,13 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| EXPECT_FALSE(media_channel1_->ready_to_send()); | 
| // In the case of rtcp mux, the SignalReadyToSend() from rtp channel | 
| // should trigger the MediaChannel's OnReadyToSend. | 
| -    rtp->SignalReadyToSend(rtp); | 
| +    network_thread_->Invoke<void>([rtp] { rtp->SignalReadyToSend(rtp); }); | 
| +    WaitForThreads(); | 
| EXPECT_TRUE(media_channel1_->ready_to_send()); | 
| -    channel1_->SetReadyToSend(false, false); | 
| + | 
| +    network_thread_->Invoke<void>( | 
| +        [this] { channel1_->SetReadyToSend(false, false); }); | 
| +    WaitForThreads(); | 
| EXPECT_FALSE(media_channel1_->ready_to_send()); | 
| } | 
|  | 
| @@ -1894,11 +1896,34 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| } | 
|  | 
| protected: | 
| +  void WaitForThreads() { WaitForThreads(rtc::ArrayView<rtc::Thread*>()); } | 
| +  static void ProcessThreadQueue(rtc::Thread* thread) { | 
| +    RTC_DCHECK(thread->IsCurrent()); | 
| +    while (!thread->empty()) { | 
| +      thread->ProcessMessages(0); | 
| +    } | 
| +  } | 
| +  void WaitForThreads(rtc::ArrayView<rtc::Thread*> threads) { | 
| +    // |threads| and current thread post packets to network thread. | 
| +    for (rtc::Thread* thread : threads) { | 
| +      thread->Invoke<void>([thread] { ProcessThreadQueue(thread); }); | 
| +    } | 
| +    ProcessThreadQueue(rtc::Thread::Current()); | 
| +    // Network thread move them around and post back to worker = current thread. | 
| +    if (!network_thread_->IsCurrent()) { | 
| +      network_thread_->Invoke<void>( | 
| +          [this] { ProcessThreadQueue(network_thread_); }); | 
| +    } | 
| +    // Worker thread = current Thread process received messages. | 
| +    ProcessThreadQueue(rtc::Thread::Current()); | 
| +  } | 
| // TODO(pbos): Remove playout from all media channels and let renderers mute | 
| // themselves. | 
| const bool verify_playout_; | 
| -  cricket::FakeTransportController transport_controller1_; | 
| -  cricket::FakeTransportController transport_controller2_; | 
| +  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_; | 
| cricket::FakeMediaEngine media_engine_; | 
| // The media channels are owned by the voice channel objects below. | 
| typename T::MediaChannel* media_channel1_; | 
| @@ -1910,8 +1935,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { | 
| typename T::Content remote_media_content1_; | 
| typename T::Content remote_media_content2_; | 
| // The RTP and RTCP packets to send in the tests. | 
| -  std::string rtp_packet_; | 
| -  std::string rtcp_packet_; | 
| +  rtc::Buffer rtp_packet_; | 
| +  rtc::Buffer rtcp_packet_; | 
| int media_info_callbacks1_; | 
| int media_info_callbacks2_; | 
| cricket::CandidatePairInterface* last_selected_candidate_pair_; | 
| @@ -1954,28 +1979,32 @@ void ChannelTest<VoiceTraits>::AddLegacyStreamInContent( | 
| audio->AddLegacyStream(ssrc); | 
| } | 
|  | 
| -class VoiceChannelTest | 
| -    : public ChannelTest<VoiceTraits> { | 
| +class VoiceChannelSingleThreadTest : public ChannelTest<VoiceTraits> { | 
| + public: | 
| +  typedef ChannelTest<VoiceTraits> Base; | 
| +  VoiceChannelSingleThreadTest() | 
| +      : Base(true, kPcmuFrame, kRtcpReport, NetworkIsWorker::Yes) {} | 
| +}; | 
| + | 
| +class VoiceChannelDoubleThreadTest : public ChannelTest<VoiceTraits> { | 
| public: | 
| typedef ChannelTest<VoiceTraits> Base; | 
| -  VoiceChannelTest() | 
| -      : Base(true, | 
| -             kPcmuFrame, | 
| -             sizeof(kPcmuFrame), | 
| -             kRtcpReport, | 
| -             sizeof(kRtcpReport)) {} | 
| +  VoiceChannelDoubleThreadTest() | 
| +      : Base(true, kPcmuFrame, kRtcpReport, NetworkIsWorker::No) {} | 
| }; | 
|  | 
| // override to add NULL parameter | 
| template <> | 
| cricket::VideoChannel* ChannelTest<VideoTraits>::CreateChannel( | 
| -    rtc::Thread* thread, | 
| +    rtc::Thread* worker_thread, | 
| +    rtc::Thread* network_thread, | 
| cricket::MediaEngineInterface* engine, | 
| cricket::FakeVideoMediaChannel* ch, | 
| cricket::TransportController* transport_controller, | 
| bool rtcp) { | 
| -  cricket::VideoChannel* channel = new cricket::VideoChannel( | 
| -      thread, ch, transport_controller, cricket::CN_VIDEO, rtcp); | 
| +  cricket::VideoChannel* channel = | 
| +      new cricket::VideoChannel(worker_thread, network_thread, ch, | 
| +                                transport_controller, cricket::CN_VIDEO, rtcp); | 
| if (!channel->Init()) { | 
| delete channel; | 
| channel = NULL; | 
| @@ -2026,67 +2055,68 @@ void ChannelTest<VideoTraits>::AddLegacyStreamInContent( | 
| video->AddLegacyStream(ssrc); | 
| } | 
|  | 
| -class VideoChannelTest | 
| -    : public ChannelTest<VideoTraits> { | 
| +class VideoChannelSingleThreadTest : public ChannelTest<VideoTraits> { | 
| public: | 
| typedef ChannelTest<VideoTraits> Base; | 
| -  VideoChannelTest() | 
| -      : Base(false, | 
| -             kH264Packet, | 
| -             sizeof(kH264Packet), | 
| -             kRtcpReport, | 
| -             sizeof(kRtcpReport)) {} | 
| +  VideoChannelSingleThreadTest() | 
| +      : Base(false, kH264Packet, kRtcpReport, NetworkIsWorker::Yes) {} | 
| }; | 
|  | 
| +class VideoChannelDoubleThreadTest : public ChannelTest<VideoTraits> { | 
| + public: | 
| +  typedef ChannelTest<VideoTraits> Base; | 
| +  VideoChannelDoubleThreadTest() | 
| +      : Base(false, kH264Packet, kRtcpReport, NetworkIsWorker::No) {} | 
| +}; | 
|  | 
| -// VoiceChannelTest | 
| -TEST_F(VoiceChannelTest, TestInit) { | 
| +// VoiceChannelSingleThreadTest | 
| +TEST_F(VoiceChannelSingleThreadTest, TestInit) { | 
| Base::TestInit(); | 
| EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| EXPECT_TRUE(media_channel1_->dtmf_info_queue().empty()); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSetContents) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSetContents) { | 
| Base::TestSetContents(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSetContentsNullOffer) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSetContentsNullOffer) { | 
| Base::TestSetContentsNullOffer(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSetContentsRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSetContentsRtcpMux) { | 
| Base::TestSetContentsRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSetContentsRtcpMuxWithPrAnswer) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) { | 
| Base::TestSetContentsRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSetRemoteContentUpdate) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSetRemoteContentUpdate) { | 
| Base::TestSetRemoteContentUpdate(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestStreams) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestStreams) { | 
| Base::TestStreams(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestUpdateStreamsInLocalContent) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestUpdateStreamsInLocalContent) { | 
| Base::TestUpdateStreamsInLocalContent(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestUpdateRemoteStreamsInContent) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestUpdateRemoteStreamsInContent) { | 
| Base::TestUpdateStreamsInRemoteContent(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestChangeStreamParamsInContent) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestChangeStreamParamsInContent) { | 
| Base::TestChangeStreamParamsInContent(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestPlayoutAndSendingStates) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestPlayoutAndSendingStates) { | 
| Base::TestPlayoutAndSendingStates(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestMuteStream) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestMuteStream) { | 
| CreateChannels(0, 0); | 
| // Test that we can Mute the default channel even though the sending SSRC | 
| // is unknown. | 
| @@ -2108,123 +2138,123 @@ TEST_F(VoiceChannelTest, TestMuteStream) { | 
| EXPECT_FALSE(media_channel1_->IsStreamMuted(kSsrc1)); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestMediaContentDirection) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestMediaContentDirection) { | 
| Base::TestMediaContentDirection(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestNetworkRouteChanges) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestNetworkRouteChanges) { | 
| Base::TestNetworkRouteChanges(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestCallSetup) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestCallSetup) { | 
| Base::TestCallSetup(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestCallTeardownRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestCallTeardownRtcpMux) { | 
| Base::TestCallTeardownRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRtpToRtp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtp) { | 
| Base::SendRtpToRtp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendNoRtcpToNoRtcp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendNoRtcpToNoRtcp) { | 
| Base::SendNoRtcpToNoRtcp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendNoRtcpToRtcp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendNoRtcpToRtcp) { | 
| Base::SendNoRtcpToRtcp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRtcpToNoRtcp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRtcpToNoRtcp) { | 
| Base::SendRtcpToNoRtcp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRtcpToRtcp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRtcpToRtcp) { | 
| Base::SendRtcpToRtcp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRtcpMuxToRtcp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRtcpMuxToRtcp) { | 
| Base::SendRtcpMuxToRtcp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRtcpMuxToRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRtcpMuxToRtcpMux) { | 
| Base::SendRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRequireRtcpMuxToRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRequireRtcpMuxToRtcpMux) { | 
| Base::SendRequireRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRtcpMuxToRequireRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRtcpMuxToRequireRtcpMux) { | 
| Base::SendRtcpMuxToRequireRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRequireRtcpMuxToRequireRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRequireRtcpMuxToRequireRtcpMux) { | 
| Base::SendRequireRtcpMuxToRequireRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRequireRtcpMuxToNoRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRequireRtcpMuxToNoRtcpMux) { | 
| Base::SendRequireRtcpMuxToNoRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendEarlyRtcpMuxToRtcp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendEarlyRtcpMuxToRtcp) { | 
| Base::SendEarlyRtcpMuxToRtcp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendEarlyRtcpMuxToRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendEarlyRtcpMuxToRtcpMux) { | 
| Base::SendEarlyRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendSrtpToSrtpRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendSrtpToSrtpRtcpMux) { | 
| Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendSrtpToRtp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendSrtpToRtp) { | 
| Base::SendSrtpToSrtp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendSrtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendSrtcpMux) { | 
| Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendDtlsSrtpToSrtp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToSrtp) { | 
| MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| Base::SendSrtpToSrtp(DTLS, 0); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendDtlsSrtpToDtlsSrtp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtp) { | 
| MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| Base::SendSrtpToSrtp(DTLS, DTLS); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { | 
| MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendEarlyMediaUsingRtcpMuxSrtp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) { | 
| Base::SendEarlyMediaUsingRtcpMuxSrtp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendRtpToRtpOnThread) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtpOnThread) { | 
| Base::SendRtpToRtpOnThread(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendSrtpToSrtpOnThread) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendSrtpToSrtpOnThread) { | 
| Base::SendSrtpToSrtpOnThread(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendWithWritabilityLoss) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendWithWritabilityLoss) { | 
| Base::SendWithWritabilityLoss(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestMediaMonitor) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestMediaMonitor) { | 
| Base::TestMediaMonitor(); | 
| } | 
|  | 
| // Test that InsertDtmf properly forwards to the media channel. | 
| -TEST_F(VoiceChannelTest, TestInsertDtmf) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestInsertDtmf) { | 
| CreateChannels(0, 0); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
| @@ -2243,44 +2273,44 @@ TEST_F(VoiceChannelTest, TestInsertDtmf) { | 
| 3, 7, 120)); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSetContentFailure) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSetContentFailure) { | 
| Base::TestSetContentFailure(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSendTwoOffers) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSendTwoOffers) { | 
| Base::TestSendTwoOffers(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestReceiveTwoOffers) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestReceiveTwoOffers) { | 
| Base::TestReceiveTwoOffers(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSendPrAnswer) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSendPrAnswer) { | 
| Base::TestSendPrAnswer(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestReceivePrAnswer) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestReceivePrAnswer) { | 
| Base::TestReceivePrAnswer(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestFlushRtcp) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestFlushRtcp) { | 
| Base::TestFlushRtcp(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestSrtpError) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestSrtpError) { | 
| Base::TestSrtpError(kAudioPts[0]); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestOnReadyToSend) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestOnReadyToSend) { | 
| Base::TestOnReadyToSend(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, TestOnReadyToSendWithRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestOnReadyToSendWithRtcpMux) { | 
| Base::TestOnReadyToSendWithRtcpMux(); | 
| } | 
|  | 
| // Test that we can scale the output volume properly for 1:1 calls. | 
| -TEST_F(VoiceChannelTest, TestScaleVolume1to1Call) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestScaleVolume1to1Call) { | 
| CreateChannels(RTCP, RTCP); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
| @@ -2304,7 +2334,7 @@ TEST_F(VoiceChannelTest, TestScaleVolume1to1Call) { | 
| } | 
|  | 
| // Test that we can scale the output volume properly for multiway calls. | 
| -TEST_F(VoiceChannelTest, TestScaleVolumeMultiwayCall) { | 
| +TEST_F(VoiceChannelSingleThreadTest, TestScaleVolumeMultiwayCall) { | 
| CreateChannels(RTCP, RTCP); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
| @@ -2341,464 +2371,1173 @@ TEST_F(VoiceChannelTest, TestScaleVolumeMultiwayCall) { | 
| EXPECT_DOUBLE_EQ(0.0, volume); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendBundleToBundle) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundle) { | 
| Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, false); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendBundleToBundleSecure) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleSecure) { | 
| Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, true); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendBundleToBundleWithRtcpMux) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleWithRtcpMux) { | 
| Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, false); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, SendBundleToBundleWithRtcpMuxSecure) { | 
| +TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleWithRtcpMuxSecure) { | 
| Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, true); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, DefaultMaxBitrateIsUnlimited) { | 
| +TEST_F(VoiceChannelSingleThreadTest, DefaultMaxBitrateIsUnlimited) { | 
| Base::DefaultMaxBitrateIsUnlimited(); | 
| } | 
|  | 
| -TEST_F(VoiceChannelTest, CanChangeMaxBitrate) { | 
| +TEST_F(VoiceChannelSingleThreadTest, CanChangeMaxBitrate) { | 
| Base::CanChangeMaxBitrate(); | 
| } | 
|  | 
| -// VideoChannelTest | 
| -TEST_F(VideoChannelTest, TestInit) { | 
| +// VoiceChannelDoubleThreadTest | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestInit) { | 
| Base::TestInit(); | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| +  EXPECT_TRUE(media_channel1_->dtmf_info_queue().empty()); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSetContents) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSetContents) { | 
| Base::TestSetContents(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSetContentsNullOffer) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsNullOffer) { | 
| Base::TestSetContentsNullOffer(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSetContentsRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsRtcpMux) { | 
| Base::TestSetContentsRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSetContentsRtcpMuxWithPrAnswer) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) { | 
| Base::TestSetContentsRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSetRemoteContentUpdate) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSetRemoteContentUpdate) { | 
| Base::TestSetRemoteContentUpdate(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestStreams) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestStreams) { | 
| Base::TestStreams(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestUpdateStreamsInLocalContent) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestUpdateStreamsInLocalContent) { | 
| Base::TestUpdateStreamsInLocalContent(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestUpdateRemoteStreamsInContent) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestUpdateRemoteStreamsInContent) { | 
| Base::TestUpdateStreamsInRemoteContent(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestChangeStreamParamsInContent) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestChangeStreamParamsInContent) { | 
| Base::TestChangeStreamParamsInContent(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestPlayoutAndSendingStates) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestPlayoutAndSendingStates) { | 
| Base::TestPlayoutAndSendingStates(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestMuteStream) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestMuteStream) { | 
| CreateChannels(0, 0); | 
| // Test that we can Mute the default channel even though the sending SSRC | 
| // is unknown. | 
| EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| -  EXPECT_TRUE(channel1_->SetVideoSend(0, false, nullptr)); | 
| +  EXPECT_TRUE(channel1_->SetAudioSend(0, false, nullptr, nullptr)); | 
| EXPECT_TRUE(media_channel1_->IsStreamMuted(0)); | 
| -  EXPECT_TRUE(channel1_->SetVideoSend(0, true, nullptr)); | 
| +  EXPECT_TRUE(channel1_->SetAudioSend(0, true, nullptr, nullptr)); | 
| EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| + | 
| // Test that we can not mute an unknown SSRC. | 
| -  EXPECT_FALSE(channel1_->SetVideoSend(kSsrc1, false, nullptr)); | 
| +  EXPECT_FALSE(channel1_->SetAudioSend(kSsrc1, false, nullptr, nullptr)); | 
| + | 
| SendInitiate(); | 
| // After the local session description has been set, we can mute a stream | 
| // with its SSRC. | 
| -  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, false, nullptr)); | 
| +  EXPECT_TRUE(channel1_->SetAudioSend(kSsrc1, false, nullptr, nullptr)); | 
| EXPECT_TRUE(media_channel1_->IsStreamMuted(kSsrc1)); | 
| -  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, true, nullptr)); | 
| +  EXPECT_TRUE(channel1_->SetAudioSend(kSsrc1, true, nullptr, nullptr)); | 
| EXPECT_FALSE(media_channel1_->IsStreamMuted(kSsrc1)); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestMediaContentDirection) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestMediaContentDirection) { | 
| Base::TestMediaContentDirection(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestNetworkRouteChanges) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestNetworkRouteChanges) { | 
| Base::TestNetworkRouteChanges(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestCallSetup) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestCallSetup) { | 
| Base::TestCallSetup(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestCallTeardownRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestCallTeardownRtcpMux) { | 
| Base::TestCallTeardownRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRtpToRtp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtp) { | 
| Base::SendRtpToRtp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendNoRtcpToNoRtcp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendNoRtcpToNoRtcp) { | 
| Base::SendNoRtcpToNoRtcp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendNoRtcpToRtcp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendNoRtcpToRtcp) { | 
| Base::SendNoRtcpToRtcp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRtcpToNoRtcp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRtcpToNoRtcp) { | 
| Base::SendRtcpToNoRtcp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRtcpToRtcp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRtcpToRtcp) { | 
| Base::SendRtcpToRtcp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRtcpMuxToRtcp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRtcpMuxToRtcp) { | 
| Base::SendRtcpMuxToRtcp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRtcpMuxToRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRtcpMuxToRtcpMux) { | 
| Base::SendRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRequireRtcpMuxToRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRequireRtcpMuxToRtcpMux) { | 
| Base::SendRequireRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRtcpMuxToRequireRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRtcpMuxToRequireRtcpMux) { | 
| Base::SendRtcpMuxToRequireRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRequireRtcpMuxToRequireRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRequireRtcpMuxToRequireRtcpMux) { | 
| Base::SendRequireRtcpMuxToRequireRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRequireRtcpMuxToNoRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRequireRtcpMuxToNoRtcpMux) { | 
| Base::SendRequireRtcpMuxToNoRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendEarlyRtcpMuxToRtcp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendEarlyRtcpMuxToRtcp) { | 
| Base::SendEarlyRtcpMuxToRtcp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendEarlyRtcpMuxToRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendEarlyRtcpMuxToRtcpMux) { | 
| Base::SendEarlyRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendSrtpToSrtp) { | 
| -  Base::SendSrtpToSrtp(); | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendSrtpToSrtpRtcpMux) { | 
| +  Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendSrtpToRtp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendSrtpToRtp) { | 
| Base::SendSrtpToSrtp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendDtlsSrtpToSrtp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendSrtcpMux) { | 
| +  Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| +} | 
| + | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToSrtp) { | 
| MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| Base::SendSrtpToSrtp(DTLS, 0); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendDtlsSrtpToDtlsSrtp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtp) { | 
| MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| Base::SendSrtpToSrtp(DTLS, DTLS); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { | 
| MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendSrtcpMux) { | 
| -  Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| -} | 
| - | 
| -TEST_F(VideoChannelTest, SendEarlyMediaUsingRtcpMuxSrtp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) { | 
| Base::SendEarlyMediaUsingRtcpMuxSrtp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendRtpToRtpOnThread) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtpOnThread) { | 
| Base::SendRtpToRtpOnThread(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendSrtpToSrtpOnThread) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendSrtpToSrtpOnThread) { | 
| Base::SendSrtpToSrtpOnThread(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendWithWritabilityLoss) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendWithWritabilityLoss) { | 
| Base::SendWithWritabilityLoss(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestMediaMonitor) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestMediaMonitor) { | 
| Base::TestMediaMonitor(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSetContentFailure) { | 
| +// Test that InsertDtmf properly forwards to the media channel. | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestInsertDtmf) { | 
| +  CreateChannels(0, 0); | 
| +  EXPECT_TRUE(SendInitiate()); | 
| +  EXPECT_TRUE(SendAccept()); | 
| +  EXPECT_EQ(0U, media_channel1_->dtmf_info_queue().size()); | 
| + | 
| +  EXPECT_TRUE(channel1_->InsertDtmf(1, 3, 100)); | 
| +  EXPECT_TRUE(channel1_->InsertDtmf(2, 5, 110)); | 
| +  EXPECT_TRUE(channel1_->InsertDtmf(3, 7, 120)); | 
| + | 
| +  ASSERT_EQ(3U, media_channel1_->dtmf_info_queue().size()); | 
| +  EXPECT_TRUE( | 
| +      CompareDtmfInfo(media_channel1_->dtmf_info_queue()[0], 1, 3, 100)); | 
| +  EXPECT_TRUE( | 
| +      CompareDtmfInfo(media_channel1_->dtmf_info_queue()[1], 2, 5, 110)); | 
| +  EXPECT_TRUE( | 
| +      CompareDtmfInfo(media_channel1_->dtmf_info_queue()[2], 3, 7, 120)); | 
| +} | 
| + | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSetContentFailure) { | 
| Base::TestSetContentFailure(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSendTwoOffers) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSendTwoOffers) { | 
| Base::TestSendTwoOffers(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestReceiveTwoOffers) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestReceiveTwoOffers) { | 
| Base::TestReceiveTwoOffers(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSendPrAnswer) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSendPrAnswer) { | 
| Base::TestSendPrAnswer(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestReceivePrAnswer) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestReceivePrAnswer) { | 
| Base::TestReceivePrAnswer(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestFlushRtcp) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestFlushRtcp) { | 
| Base::TestFlushRtcp(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendBundleToBundle) { | 
| -  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, false); | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestSrtpError) { | 
| +  Base::TestSrtpError(kAudioPts[0]); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendBundleToBundleSecure) { | 
| -  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, true); | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestOnReadyToSend) { | 
| +  Base::TestOnReadyToSend(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendBundleToBundleWithRtcpMux) { | 
| -  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, false); | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestOnReadyToSendWithRtcpMux) { | 
| +  Base::TestOnReadyToSendWithRtcpMux(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, SendBundleToBundleWithRtcpMuxSecure) { | 
| -  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, true); | 
| +// Test that we can scale the output volume properly for 1:1 calls. | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestScaleVolume1to1Call) { | 
| +  CreateChannels(RTCP, RTCP); | 
| +  EXPECT_TRUE(SendInitiate()); | 
| +  EXPECT_TRUE(SendAccept()); | 
| +  double volume; | 
| + | 
| +  // Default is (1.0). | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(0, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.0, volume); | 
| +  // invalid ssrc. | 
| +  EXPECT_FALSE(media_channel1_->GetOutputVolume(3, &volume)); | 
| + | 
| +  // Set scale to (1.5). | 
| +  EXPECT_TRUE(channel1_->SetOutputVolume(0, 1.5)); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(0, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.5, volume); | 
| + | 
| +  // Set scale to (0). | 
| +  EXPECT_TRUE(channel1_->SetOutputVolume(0, 0.0)); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(0, &volume)); | 
| +  EXPECT_DOUBLE_EQ(0.0, volume); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestSrtpError) { | 
| -  Base::TestSrtpError(kVideoPts[0]); | 
| +// Test that we can scale the output volume properly for multiway calls. | 
| +TEST_F(VoiceChannelDoubleThreadTest, TestScaleVolumeMultiwayCall) { | 
| +  CreateChannels(RTCP, RTCP); | 
| +  EXPECT_TRUE(SendInitiate()); | 
| +  EXPECT_TRUE(SendAccept()); | 
| +  EXPECT_TRUE(AddStream1(1)); | 
| +  EXPECT_TRUE(AddStream1(2)); | 
| + | 
| +  double volume; | 
| +  // Default is (1.0). | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(0, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.0, volume); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(1, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.0, volume); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(2, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.0, volume); | 
| +  // invalid ssrc. | 
| +  EXPECT_FALSE(media_channel1_->GetOutputVolume(3, &volume)); | 
| + | 
| +  // Set scale to (1.5) for ssrc = 1. | 
| +  EXPECT_TRUE(channel1_->SetOutputVolume(1, 1.5)); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(1, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.5, volume); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(2, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.0, volume); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(0, &volume)); | 
| +  EXPECT_DOUBLE_EQ(1.0, volume); | 
| + | 
| +  // Set scale to (0) for all ssrcs. | 
| +  EXPECT_TRUE(channel1_->SetOutputVolume(0, 0.0)); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(0, &volume)); | 
| +  EXPECT_DOUBLE_EQ(0.0, volume); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(1, &volume)); | 
| +  EXPECT_DOUBLE_EQ(0.0, volume); | 
| +  EXPECT_TRUE(media_channel1_->GetOutputVolume(2, &volume)); | 
| +  EXPECT_DOUBLE_EQ(0.0, volume); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestOnReadyToSend) { | 
| -  Base::TestOnReadyToSend(); | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundle) { | 
| +  Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, false); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, TestOnReadyToSendWithRtcpMux) { | 
| -  Base::TestOnReadyToSendWithRtcpMux(); | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleSecure) { | 
| +  Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, true); | 
| +} | 
| + | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleWithRtcpMux) { | 
| +  Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, false); | 
| +} | 
| + | 
| +TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleWithRtcpMuxSecure) { | 
| +  Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, true); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, DefaultMaxBitrateIsUnlimited) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, DefaultMaxBitrateIsUnlimited) { | 
| Base::DefaultMaxBitrateIsUnlimited(); | 
| } | 
|  | 
| -TEST_F(VideoChannelTest, CanChangeMaxBitrate) { | 
| +TEST_F(VoiceChannelDoubleThreadTest, CanChangeMaxBitrate) { | 
| Base::CanChangeMaxBitrate(); | 
| } | 
|  | 
| -// DataChannelTest | 
| +// VideoChannelSingleThreadTest | 
| +TEST_F(VideoChannelSingleThreadTest, TestInit) { | 
| +  Base::TestInit(); | 
| +} | 
|  | 
| -class DataChannelTest | 
| -    : public ChannelTest<DataTraits> { | 
| - public: | 
| -  typedef ChannelTest<DataTraits> | 
| -  Base; | 
| -  DataChannelTest() | 
| -      : Base(true, | 
| -             kDataPacket, | 
| -             sizeof(kDataPacket), | 
| -             kRtcpReport, | 
| -             sizeof(kRtcpReport)) {} | 
| -}; | 
| +TEST_F(VideoChannelSingleThreadTest, TestSetContents) { | 
| +  Base::TestSetContents(); | 
| +} | 
|  | 
| -// Override to avoid engine channel parameter. | 
| -template <> | 
| -cricket::DataChannel* ChannelTest<DataTraits>::CreateChannel( | 
| -    rtc::Thread* thread, | 
| -    cricket::MediaEngineInterface* engine, | 
| -    cricket::FakeDataMediaChannel* ch, | 
| -    cricket::TransportController* transport_controller, | 
| -    bool rtcp) { | 
| -  cricket::DataChannel* channel = new cricket::DataChannel( | 
| -      thread, ch, transport_controller, cricket::CN_DATA, rtcp); | 
| -  if (!channel->Init()) { | 
| -    delete channel; | 
| -    channel = NULL; | 
| -  } | 
| -  return channel; | 
| +TEST_F(VideoChannelSingleThreadTest, TestSetContentsNullOffer) { | 
| +  Base::TestSetContentsNullOffer(); | 
| } | 
|  | 
| -template<> | 
| -void ChannelTest<DataTraits>::CreateContent( | 
| -    int flags, | 
| -    const cricket::AudioCodec& audio_codec, | 
| -    const cricket::VideoCodec& video_codec, | 
| -    cricket::DataContentDescription* data) { | 
| -  data->AddCodec(kGoogleDataCodec); | 
| -  data->set_rtcp_mux((flags & RTCP_MUX) != 0); | 
| -  if (flags & SECURE) { | 
| -    data->AddCrypto(cricket::CryptoParams( | 
| -        1, rtc::CS_AES_CM_128_HMAC_SHA1_32, | 
| -        "inline:" + rtc::CreateRandomString(40), std::string())); | 
| -  } | 
| +TEST_F(VideoChannelSingleThreadTest, TestSetContentsRtcpMux) { | 
| +  Base::TestSetContentsRtcpMux(); | 
| } | 
|  | 
| -template<> | 
| -void ChannelTest<DataTraits>::CopyContent( | 
| -    const cricket::DataContentDescription& source, | 
| -    cricket::DataContentDescription* data) { | 
| -  *data = source; | 
| +TEST_F(VideoChannelSingleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) { | 
| +  Base::TestSetContentsRtcpMux(); | 
| } | 
|  | 
| -template<> | 
| -bool ChannelTest<DataTraits>::CodecMatches(const cricket::DataCodec& c1, | 
| -                                           const cricket::DataCodec& c2) { | 
| -  return c1.name == c2.name; | 
| +TEST_F(VideoChannelSingleThreadTest, TestSetRemoteContentUpdate) { | 
| +  Base::TestSetRemoteContentUpdate(); | 
| } | 
|  | 
| -template <> | 
| -void ChannelTest<DataTraits>::AddLegacyStreamInContent( | 
| -    uint32_t ssrc, | 
| -    int flags, | 
| -    cricket::DataContentDescription* data) { | 
| -  data->AddLegacyStream(ssrc); | 
| +TEST_F(VideoChannelSingleThreadTest, TestStreams) { | 
| +  Base::TestStreams(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestUpdateStreamsInLocalContent) { | 
| +  Base::TestUpdateStreamsInLocalContent(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestUpdateRemoteStreamsInContent) { | 
| +  Base::TestUpdateStreamsInRemoteContent(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestChangeStreamParamsInContent) { | 
| +  Base::TestChangeStreamParamsInContent(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestPlayoutAndSendingStates) { | 
| +  Base::TestPlayoutAndSendingStates(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestMuteStream) { | 
| +  CreateChannels(0, 0); | 
| +  // Test that we can Mute the default channel even though the sending SSRC | 
| +  // is unknown. | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(0, false, nullptr)); | 
| +  EXPECT_TRUE(media_channel1_->IsStreamMuted(0)); | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(0, true, nullptr)); | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| +  // Test that we can not mute an unknown SSRC. | 
| +  EXPECT_FALSE(channel1_->SetVideoSend(kSsrc1, false, nullptr)); | 
| +  SendInitiate(); | 
| +  // After the local session description has been set, we can mute a stream | 
| +  // with its SSRC. | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, false, nullptr)); | 
| +  EXPECT_TRUE(media_channel1_->IsStreamMuted(kSsrc1)); | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, true, nullptr)); | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(kSsrc1)); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestMediaContentDirection) { | 
| +  Base::TestMediaContentDirection(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestNetworkRouteChanges) { | 
| +  Base::TestNetworkRouteChanges(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestCallSetup) { | 
| +  Base::TestCallSetup(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestCallTeardownRtcpMux) { | 
| +  Base::TestCallTeardownRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRtpToRtp) { | 
| +  Base::SendRtpToRtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendNoRtcpToNoRtcp) { | 
| +  Base::SendNoRtcpToNoRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendNoRtcpToRtcp) { | 
| +  Base::SendNoRtcpToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRtcpToNoRtcp) { | 
| +  Base::SendRtcpToNoRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRtcpToRtcp) { | 
| +  Base::SendRtcpToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRtcpMuxToRtcp) { | 
| +  Base::SendRtcpMuxToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRtcpMuxToRtcpMux) { | 
| +  Base::SendRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRequireRtcpMuxToRtcpMux) { | 
| +  Base::SendRequireRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRtcpMuxToRequireRtcpMux) { | 
| +  Base::SendRtcpMuxToRequireRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRequireRtcpMuxToRequireRtcpMux) { | 
| +  Base::SendRequireRtcpMuxToRequireRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRequireRtcpMuxToNoRtcpMux) { | 
| +  Base::SendRequireRtcpMuxToNoRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendEarlyRtcpMuxToRtcp) { | 
| +  Base::SendEarlyRtcpMuxToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendEarlyRtcpMuxToRtcpMux) { | 
| +  Base::SendEarlyRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendSrtpToSrtp) { | 
| +  Base::SendSrtpToSrtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendSrtpToRtp) { | 
| +  Base::SendSrtpToSrtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToSrtp) { | 
| +  MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| +  Base::SendSrtpToSrtp(DTLS, 0); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtp) { | 
| +  MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| +  Base::SendSrtpToSrtp(DTLS, DTLS); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { | 
| +  MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| +  Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendSrtcpMux) { | 
| +  Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) { | 
| +  Base::SendEarlyMediaUsingRtcpMuxSrtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendRtpToRtpOnThread) { | 
| +  Base::SendRtpToRtpOnThread(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendSrtpToSrtpOnThread) { | 
| +  Base::SendSrtpToSrtpOnThread(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendWithWritabilityLoss) { | 
| +  Base::SendWithWritabilityLoss(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestMediaMonitor) { | 
| +  Base::TestMediaMonitor(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestSetContentFailure) { | 
| +  Base::TestSetContentFailure(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestSendTwoOffers) { | 
| +  Base::TestSendTwoOffers(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestReceiveTwoOffers) { | 
| +  Base::TestReceiveTwoOffers(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestSendPrAnswer) { | 
| +  Base::TestSendPrAnswer(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestReceivePrAnswer) { | 
| +  Base::TestReceivePrAnswer(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestFlushRtcp) { | 
| +  Base::TestFlushRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendBundleToBundle) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, false); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleSecure) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, true); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleWithRtcpMux) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, false); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleWithRtcpMuxSecure) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, true); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestSrtpError) { | 
| +  Base::TestSrtpError(kVideoPts[0]); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestOnReadyToSend) { | 
| +  Base::TestOnReadyToSend(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, TestOnReadyToSendWithRtcpMux) { | 
| +  Base::TestOnReadyToSendWithRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, DefaultMaxBitrateIsUnlimited) { | 
| +  Base::DefaultMaxBitrateIsUnlimited(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelSingleThreadTest, CanChangeMaxBitrate) { | 
| +  Base::CanChangeMaxBitrate(); | 
| +} | 
| + | 
| +// VideoChannelDoubleThreadTest | 
| +TEST_F(VideoChannelDoubleThreadTest, TestInit) { | 
| +  Base::TestInit(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSetContents) { | 
| +  Base::TestSetContents(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSetContentsNullOffer) { | 
| +  Base::TestSetContentsNullOffer(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSetContentsRtcpMux) { | 
| +  Base::TestSetContentsRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) { | 
| +  Base::TestSetContentsRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSetRemoteContentUpdate) { | 
| +  Base::TestSetRemoteContentUpdate(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestStreams) { | 
| +  Base::TestStreams(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestUpdateStreamsInLocalContent) { | 
| +  Base::TestUpdateStreamsInLocalContent(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestUpdateRemoteStreamsInContent) { | 
| +  Base::TestUpdateStreamsInRemoteContent(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestChangeStreamParamsInContent) { | 
| +  Base::TestChangeStreamParamsInContent(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestPlayoutAndSendingStates) { | 
| +  Base::TestPlayoutAndSendingStates(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestMuteStream) { | 
| +  CreateChannels(0, 0); | 
| +  // Test that we can Mute the default channel even though the sending SSRC | 
| +  // is unknown. | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(0, false, nullptr)); | 
| +  EXPECT_TRUE(media_channel1_->IsStreamMuted(0)); | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(0, true, nullptr)); | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| +  // Test that we can not mute an unknown SSRC. | 
| +  EXPECT_FALSE(channel1_->SetVideoSend(kSsrc1, false, nullptr)); | 
| +  SendInitiate(); | 
| +  // After the local session description has been set, we can mute a stream | 
| +  // with its SSRC. | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, false, nullptr)); | 
| +  EXPECT_TRUE(media_channel1_->IsStreamMuted(kSsrc1)); | 
| +  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, true, nullptr)); | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(kSsrc1)); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestMediaContentDirection) { | 
| +  Base::TestMediaContentDirection(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestNetworkRouteChanges) { | 
| +  Base::TestNetworkRouteChanges(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestCallSetup) { | 
| +  Base::TestCallSetup(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestCallTeardownRtcpMux) { | 
| +  Base::TestCallTeardownRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtp) { | 
| +  Base::SendRtpToRtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendNoRtcpToNoRtcp) { | 
| +  Base::SendNoRtcpToNoRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendNoRtcpToRtcp) { | 
| +  Base::SendNoRtcpToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRtcpToNoRtcp) { | 
| +  Base::SendRtcpToNoRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRtcpToRtcp) { | 
| +  Base::SendRtcpToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRtcpMuxToRtcp) { | 
| +  Base::SendRtcpMuxToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRtcpMuxToRtcpMux) { | 
| +  Base::SendRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRequireRtcpMuxToRtcpMux) { | 
| +  Base::SendRequireRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRtcpMuxToRequireRtcpMux) { | 
| +  Base::SendRtcpMuxToRequireRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRequireRtcpMuxToRequireRtcpMux) { | 
| +  Base::SendRequireRtcpMuxToRequireRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRequireRtcpMuxToNoRtcpMux) { | 
| +  Base::SendRequireRtcpMuxToNoRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendEarlyRtcpMuxToRtcp) { | 
| +  Base::SendEarlyRtcpMuxToRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendEarlyRtcpMuxToRtcpMux) { | 
| +  Base::SendEarlyRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendSrtpToSrtp) { | 
| +  Base::SendSrtpToSrtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendSrtpToRtp) { | 
| +  Base::SendSrtpToSrtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToSrtp) { | 
| +  MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| +  Base::SendSrtpToSrtp(DTLS, 0); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtp) { | 
| +  MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| +  Base::SendSrtpToSrtp(DTLS, DTLS); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { | 
| +  MAYBE_SKIP_TEST(HaveDtlsSrtp); | 
| +  Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendSrtcpMux) { | 
| +  Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) { | 
| +  Base::SendEarlyMediaUsingRtcpMuxSrtp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtpOnThread) { | 
| +  Base::SendRtpToRtpOnThread(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendSrtpToSrtpOnThread) { | 
| +  Base::SendSrtpToSrtpOnThread(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendWithWritabilityLoss) { | 
| +  Base::SendWithWritabilityLoss(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestMediaMonitor) { | 
| +  Base::TestMediaMonitor(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSetContentFailure) { | 
| +  Base::TestSetContentFailure(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSendTwoOffers) { | 
| +  Base::TestSendTwoOffers(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestReceiveTwoOffers) { | 
| +  Base::TestReceiveTwoOffers(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSendPrAnswer) { | 
| +  Base::TestSendPrAnswer(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestReceivePrAnswer) { | 
| +  Base::TestReceivePrAnswer(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestFlushRtcp) { | 
| +  Base::TestFlushRtcp(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundle) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, false); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleSecure) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, true); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleWithRtcpMux) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, false); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleWithRtcpMuxSecure) { | 
| +  Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, true); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestSrtpError) { | 
| +  Base::TestSrtpError(kVideoPts[0]); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestOnReadyToSend) { | 
| +  Base::TestOnReadyToSend(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, TestOnReadyToSendWithRtcpMux) { | 
| +  Base::TestOnReadyToSendWithRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, DefaultMaxBitrateIsUnlimited) { | 
| +  Base::DefaultMaxBitrateIsUnlimited(); | 
| +} | 
| + | 
| +TEST_F(VideoChannelDoubleThreadTest, CanChangeMaxBitrate) { | 
| +  Base::CanChangeMaxBitrate(); | 
| +} | 
| + | 
| +// DataChannelSingleThreadTest | 
| +class DataChannelSingleThreadTest : public ChannelTest<DataTraits> { | 
| + public: | 
| +  typedef ChannelTest<DataTraits> Base; | 
| +  DataChannelSingleThreadTest() | 
| +      : Base(true, kDataPacket, kRtcpReport, NetworkIsWorker::Yes) {} | 
| +}; | 
| + | 
| +// DataChannelDoubleThreadTest | 
| +class DataChannelDoubleThreadTest : public ChannelTest<DataTraits> { | 
| + public: | 
| +  typedef ChannelTest<DataTraits> Base; | 
| +  DataChannelDoubleThreadTest() | 
| +      : Base(true, kDataPacket, kRtcpReport, NetworkIsWorker::No) {} | 
| +}; | 
| + | 
| +// Override to avoid engine channel parameter. | 
| +template <> | 
| +cricket::DataChannel* ChannelTest<DataTraits>::CreateChannel( | 
| +    rtc::Thread* worker_thread, | 
| +    rtc::Thread* network_thread, | 
| +    cricket::MediaEngineInterface* engine, | 
| +    cricket::FakeDataMediaChannel* ch, | 
| +    cricket::TransportController* transport_controller, | 
| +    bool rtcp) { | 
| +  cricket::DataChannel* channel = | 
| +      new cricket::DataChannel(worker_thread, network_thread, ch, | 
| +                               transport_controller, cricket::CN_DATA, rtcp); | 
| +  if (!channel->Init()) { | 
| +    delete channel; | 
| +    channel = NULL; | 
| +  } | 
| +  return channel; | 
| +} | 
| + | 
| +template <> | 
| +void ChannelTest<DataTraits>::CreateContent( | 
| +    int flags, | 
| +    const cricket::AudioCodec& audio_codec, | 
| +    const cricket::VideoCodec& video_codec, | 
| +    cricket::DataContentDescription* data) { | 
| +  data->AddCodec(kGoogleDataCodec); | 
| +  data->set_rtcp_mux((flags & RTCP_MUX) != 0); | 
| +  if (flags & SECURE) { | 
| +    data->AddCrypto(cricket::CryptoParams( | 
| +        1, rtc::CS_AES_CM_128_HMAC_SHA1_32, | 
| +        "inline:" + rtc::CreateRandomString(40), std::string())); | 
| +  } | 
| +} | 
| + | 
| +template <> | 
| +void ChannelTest<DataTraits>::CopyContent( | 
| +    const cricket::DataContentDescription& source, | 
| +    cricket::DataContentDescription* data) { | 
| +  *data = source; | 
| +} | 
| + | 
| +template <> | 
| +bool ChannelTest<DataTraits>::CodecMatches(const cricket::DataCodec& c1, | 
| +                                           const cricket::DataCodec& c2) { | 
| +  return c1.name == c2.name; | 
| +} | 
| + | 
| +template <> | 
| +void ChannelTest<DataTraits>::AddLegacyStreamInContent( | 
| +    uint32_t ssrc, | 
| +    int flags, | 
| +    cricket::DataContentDescription* data) { | 
| +  data->AddLegacyStream(ssrc); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestInit) { | 
| +  Base::TestInit(); | 
| +  EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestSetContents) { | 
| +  Base::TestSetContents(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestSetContentsNullOffer) { | 
| +  Base::TestSetContentsNullOffer(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestSetContentsRtcpMux) { | 
| +  Base::TestSetContentsRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestSetRemoteContentUpdate) { | 
| +  Base::TestSetRemoteContentUpdate(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestStreams) { | 
| +  Base::TestStreams(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestUpdateStreamsInLocalContent) { | 
| +  Base::TestUpdateStreamsInLocalContent(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestUpdateRemoteStreamsInContent) { | 
| +  Base::TestUpdateStreamsInRemoteContent(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestChangeStreamParamsInContent) { | 
| +  Base::TestChangeStreamParamsInContent(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestPlayoutAndSendingStates) { | 
| +  Base::TestPlayoutAndSendingStates(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestMediaContentDirection) { | 
| +  Base::TestMediaContentDirection(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestCallSetup) { | 
| +  Base::TestCallSetup(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestCallTeardownRtcpMux) { | 
| +  Base::TestCallTeardownRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestOnReadyToSend) { | 
| +  Base::TestOnReadyToSend(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestOnReadyToSendWithRtcpMux) { | 
| +  Base::TestOnReadyToSendWithRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendRtpToRtp) { | 
| +  Base::SendRtpToRtp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendNoRtcpToNoRtcp) { | 
| +  Base::SendNoRtcpToNoRtcp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendNoRtcpToRtcp) { | 
| +  Base::SendNoRtcpToRtcp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendRtcpToNoRtcp) { | 
| +  Base::SendRtcpToNoRtcp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendRtcpToRtcp) { | 
| +  Base::SendRtcpToRtcp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendRtcpMuxToRtcp) { | 
| +  Base::SendRtcpMuxToRtcp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendRtcpMuxToRtcpMux) { | 
| +  Base::SendRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendEarlyRtcpMuxToRtcp) { | 
| +  Base::SendEarlyRtcpMuxToRtcp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendEarlyRtcpMuxToRtcpMux) { | 
| +  Base::SendEarlyRtcpMuxToRtcpMux(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendSrtpToSrtp) { | 
| +  Base::SendSrtpToSrtp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendSrtpToRtp) { | 
| +  Base::SendSrtpToSrtp(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendSrtcpMux) { | 
| +  Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendRtpToRtpOnThread) { | 
| +  Base::SendRtpToRtpOnThread(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendSrtpToSrtpOnThread) { | 
| +  Base::SendSrtpToSrtpOnThread(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, SendWithWritabilityLoss) { | 
| +  Base::SendWithWritabilityLoss(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestMediaMonitor) { | 
| +  Base::TestMediaMonitor(); | 
| +} | 
| + | 
| +TEST_F(DataChannelSingleThreadTest, TestSendData) { | 
| +  CreateChannels(0, 0); | 
| +  EXPECT_TRUE(SendInitiate()); | 
| +  EXPECT_TRUE(SendAccept()); | 
| + | 
| +  cricket::SendDataParams params; | 
| +  params.ssrc = 42; | 
| +  unsigned char data[] = {'f', 'o', 'o'}; | 
| +  rtc::CopyOnWriteBuffer payload(data, 3); | 
| +  cricket::SendDataResult result; | 
| +  ASSERT_TRUE(media_channel1_->SendData(params, payload, &result)); | 
| +  EXPECT_EQ(params.ssrc, media_channel1_->last_sent_data_params().ssrc); | 
| +  EXPECT_EQ("foo", media_channel1_->last_sent_data()); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestInit) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestInit) { | 
| Base::TestInit(); | 
| EXPECT_FALSE(media_channel1_->IsStreamMuted(0)); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestSetContents) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestSetContents) { | 
| Base::TestSetContents(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestSetContentsNullOffer) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestSetContentsNullOffer) { | 
| Base::TestSetContentsNullOffer(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestSetContentsRtcpMux) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestSetContentsRtcpMux) { | 
| Base::TestSetContentsRtcpMux(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestSetRemoteContentUpdate) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestSetRemoteContentUpdate) { | 
| Base::TestSetRemoteContentUpdate(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestStreams) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestStreams) { | 
| Base::TestStreams(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestUpdateStreamsInLocalContent) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestUpdateStreamsInLocalContent) { | 
| Base::TestUpdateStreamsInLocalContent(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestUpdateRemoteStreamsInContent) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestUpdateRemoteStreamsInContent) { | 
| Base::TestUpdateStreamsInRemoteContent(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestChangeStreamParamsInContent) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestChangeStreamParamsInContent) { | 
| Base::TestChangeStreamParamsInContent(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestPlayoutAndSendingStates) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestPlayoutAndSendingStates) { | 
| Base::TestPlayoutAndSendingStates(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestMediaContentDirection) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestMediaContentDirection) { | 
| Base::TestMediaContentDirection(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestCallSetup) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestCallSetup) { | 
| Base::TestCallSetup(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestCallTeardownRtcpMux) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestCallTeardownRtcpMux) { | 
| Base::TestCallTeardownRtcpMux(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestOnReadyToSend) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestOnReadyToSend) { | 
| Base::TestOnReadyToSend(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestOnReadyToSendWithRtcpMux) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestOnReadyToSendWithRtcpMux) { | 
| Base::TestOnReadyToSendWithRtcpMux(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendRtpToRtp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendRtpToRtp) { | 
| Base::SendRtpToRtp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendNoRtcpToNoRtcp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendNoRtcpToNoRtcp) { | 
| Base::SendNoRtcpToNoRtcp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendNoRtcpToRtcp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendNoRtcpToRtcp) { | 
| Base::SendNoRtcpToRtcp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendRtcpToNoRtcp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendRtcpToNoRtcp) { | 
| Base::SendRtcpToNoRtcp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendRtcpToRtcp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendRtcpToRtcp) { | 
| Base::SendRtcpToRtcp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendRtcpMuxToRtcp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendRtcpMuxToRtcp) { | 
| Base::SendRtcpMuxToRtcp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendRtcpMuxToRtcpMux) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendRtcpMuxToRtcpMux) { | 
| Base::SendRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendEarlyRtcpMuxToRtcp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendEarlyRtcpMuxToRtcp) { | 
| Base::SendEarlyRtcpMuxToRtcp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendEarlyRtcpMuxToRtcpMux) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendEarlyRtcpMuxToRtcpMux) { | 
| Base::SendEarlyRtcpMuxToRtcpMux(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendSrtpToSrtp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendSrtpToSrtp) { | 
| Base::SendSrtpToSrtp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendSrtpToRtp) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendSrtpToRtp) { | 
| Base::SendSrtpToSrtp(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendSrtcpMux) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendSrtcpMux) { | 
| Base::SendSrtpToSrtp(RTCP_MUX, RTCP_MUX); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendRtpToRtpOnThread) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendRtpToRtpOnThread) { | 
| Base::SendRtpToRtpOnThread(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendSrtpToSrtpOnThread) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendSrtpToSrtpOnThread) { | 
| Base::SendSrtpToSrtpOnThread(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, SendWithWritabilityLoss) { | 
| +TEST_F(DataChannelDoubleThreadTest, SendWithWritabilityLoss) { | 
| Base::SendWithWritabilityLoss(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestMediaMonitor) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestMediaMonitor) { | 
| Base::TestMediaMonitor(); | 
| } | 
|  | 
| -TEST_F(DataChannelTest, TestSendData) { | 
| +TEST_F(DataChannelDoubleThreadTest, TestSendData) { | 
| CreateChannels(0, 0); | 
| EXPECT_TRUE(SendInitiate()); | 
| EXPECT_TRUE(SendAccept()); | 
|  |