blob: 3bf9556403474846d52f03e9d5aa434a94e6f340 [file] [log] [blame]
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00001/*
kjellander65c7f672016-02-12 00:05:01 -08002 * Copyright 2009 The WebRTC project authors. All Rights Reserved.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 *
kjellander65c7f672016-02-12 00:05:01 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070011#include "pc/channel.h"
12
Harald Alvestrandc24a2182022-02-23 13:44:59 +000013#include <stddef.h>
14
Yves Gerey3e707812018-11-28 16:47:49 +010015#include <cstdint>
Harald Alvestrandc24a2182022-02-23 13:44:59 +000016#include <string>
17#include <type_traits>
kwiberg31022942016-03-11 14:18:21 -080018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "api/array_view.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "api/audio_options.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/rtp_parameters.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "media/base/codec.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "media/base/fake_media_engine.h"
24#include "media/base/fake_rtp.h"
25#include "media/base/media_channel.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000026#include "media/base/media_constants.h"
27#include "media/base/rid_description.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "p2p/base/candidate_pair_interface.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000029#include "p2p/base/dtls_transport_internal.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "p2p/base/fake_dtls_transport.h"
31#include "p2p/base/fake_packet_transport.h"
32#include "p2p/base/ice_transport_internal.h"
33#include "p2p/base/p2p_constants.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000034#include "p2p/base/packet_transport_internal.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "pc/dtls_srtp_transport.h"
36#include "pc/jsep_transport.h"
37#include "pc/rtp_transport.h"
Yves Gerey3e707812018-11-28 16:47:49 +010038#include "rtc_base/arraysize.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020039#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "rtc_base/byte_order.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "rtc_base/checks.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000042#include "rtc_base/location.h"
Steve Anton10542f22019-01-11 09:11:00 -080043#include "rtc_base/rtc_certificate.h"
44#include "rtc_base/ssl_identity.h"
Tommic9625f02021-05-06 22:03:19 +020045#include "rtc_base/task_utils/pending_task_safety_flag.h"
46#include "rtc_base/task_utils/to_queued_task.h"
Mirta Dvornicic479a3c02019-06-04 15:38:50 +020047#include "test/gmock.h"
Yves Gerey3e707812018-11-28 16:47:49 +010048#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049
zhihuangb2cdd932017-01-19 16:54:25 -080050using cricket::DtlsTransportInternal;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051using cricket::FakeVoiceMediaChannel;
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080052using cricket::RidDescription;
53using cricket::RidDirection;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054using cricket::StreamParams;
Steve Anton4e70a722017-11-28 14:57:10 -080055using webrtc::RtpTransceiverDirection;
Steve Anton3828c062017-12-06 10:34:51 -080056using webrtc::SdpType;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057
Danil Chapovalov33b01f22016-05-11 19:55:27 +020058namespace {
59const cricket::AudioCodec kPcmuCodec(0, "PCMU", 64000, 8000, 1);
60const cricket::AudioCodec kPcmaCodec(8, "PCMA", 64000, 8000, 1);
61const cricket::AudioCodec kIsacCodec(103, "ISAC", 40000, 16000, 1);
perkj26752742016-10-24 01:21:16 -070062const cricket::VideoCodec kH264Codec(97, "H264");
63const cricket::VideoCodec kH264SvcCodec(99, "H264-SVC");
Danil Chapovalov33b01f22016-05-11 19:55:27 +020064const uint32_t kSsrc1 = 0x1111;
65const uint32_t kSsrc2 = 0x2222;
Zhi Huang365381f2018-04-13 16:44:34 -070066const uint32_t kSsrc3 = 0x3333;
67const uint32_t kSsrc4 = 0x4444;
Danil Chapovalov33b01f22016-05-11 19:55:27 +020068const int kAudioPts[] = {0, 8};
69const int kVideoPts[] = {97, 99};
70enum class NetworkIsWorker { Yes, No };
Niels Möller02284852018-01-17 10:22:47 +010071
Danil Chapovalov33b01f22016-05-11 19:55:27 +020072} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073
deadbeefcbecd352015-09-23 11:50:27 -070074template <class ChannelT,
75 class MediaChannelT,
76 class ContentT,
77 class CodecT,
78 class MediaInfoT,
79 class OptionsT>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080class Traits {
81 public:
82 typedef ChannelT Channel;
83 typedef MediaChannelT MediaChannel;
84 typedef ContentT Content;
85 typedef CodecT Codec;
86 typedef MediaInfoT MediaInfo;
Fredrik Solenbergb071a192015-09-17 16:42:56 +020087 typedef OptionsT Options;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088};
89
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090class VoiceTraits : public Traits<cricket::VoiceChannel,
91 cricket::FakeVoiceMediaChannel,
92 cricket::AudioContentDescription,
93 cricket::AudioCodec,
Fredrik Solenbergb071a192015-09-17 16:42:56 +020094 cricket::VoiceMediaInfo,
deadbeefcbecd352015-09-23 11:50:27 -070095 cricket::AudioOptions> {};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096
97class VideoTraits : public Traits<cricket::VideoChannel,
98 cricket::FakeVideoMediaChannel,
99 cricket::VideoContentDescription,
100 cricket::VideoCodec,
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200101 cricket::VideoMediaInfo,
deadbeefcbecd352015-09-23 11:50:27 -0700102 cricket::VideoOptions> {};
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000103
Harald Alvestrand48171ec2021-04-20 15:06:03 +0000104// Base class for Voice/Video tests
Yves Gerey665174f2018-06-19 15:03:05 +0200105template <class T>
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200106class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000107 public:
deadbeefac22f702017-01-12 21:59:29 -0800108 enum Flags {
109 RTCP_MUX = 0x1,
deadbeefac22f702017-01-12 21:59:29 -0800110 SSRC_MUX = 0x8,
111 DTLS = 0x10,
deadbeef5bd5ca32017-02-10 11:31:50 -0800112 // Use BaseChannel with PacketTransportInternal rather than
deadbeeff5346592017-01-24 21:51:21 -0800113 // DtlsTransportInternal.
deadbeef7914b8c2017-04-21 03:23:33 -0700114 RAW_PACKET_TRANSPORT = 0x20,
deadbeefac22f702017-01-12 21:59:29 -0800115 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116
Peter Boström34fbfff2015-09-24 19:20:30 +0200117 ChannelTest(bool verify_playout,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200118 rtc::ArrayView<const uint8_t> rtp_data,
119 rtc::ArrayView<const uint8_t> rtcp_data,
120 NetworkIsWorker network_is_worker)
Peter Boström34fbfff2015-09-24 19:20:30 +0200121 : verify_playout_(verify_playout),
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200122 rtp_packet_(rtp_data.data(), rtp_data.size()),
deadbeeff5346592017-01-24 21:51:21 -0800123 rtcp_packet_(rtcp_data.data(), rtcp_data.size()) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200124 if (network_is_worker == NetworkIsWorker::Yes) {
125 network_thread_ = rtc::Thread::Current();
126 } else {
127 network_thread_keeper_ = rtc::Thread::Create();
128 network_thread_keeper_->SetName("Network", nullptr);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200129 network_thread_ = network_thread_keeper_.get();
130 }
Tommic9625f02021-05-06 22:03:19 +0200131 RTC_DCHECK(network_thread_);
132 }
133
134 ~ChannelTest() {
135 if (network_thread_) {
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100136 network_thread_->Invoke<void>(RTC_FROM_HERE, [this]() {
137 network_thread_safety_->SetNotAlive();
138 DeinitChannels();
139 });
Tommic9625f02021-05-06 22:03:19 +0200140 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200141 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000142
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143 void CreateChannels(int flags1, int flags2) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200144 CreateChannels(std::make_unique<typename T::MediaChannel>(
Tommic9625f02021-05-06 22:03:19 +0200145 nullptr, typename T::Options(), network_thread_),
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200146 std::make_unique<typename T::MediaChannel>(
Tommic9625f02021-05-06 22:03:19 +0200147 nullptr, typename T::Options(), network_thread_),
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200148 flags1, flags2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000149 }
Steve Anton8699a322017-11-06 15:53:33 -0800150 void CreateChannels(std::unique_ptr<typename T::MediaChannel> ch1,
151 std::unique_ptr<typename T::MediaChannel> ch2,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200152 int flags1,
153 int flags2) {
Tommic9625f02021-05-06 22:03:19 +0200154 RTC_DCHECK(!channel1_);
155 RTC_DCHECK(!channel2_);
156
deadbeeff5346592017-01-24 21:51:21 -0800157 // Network thread is started in CreateChannels, to allow the test to
158 // configure a fake clock before any threads are spawned and attempt to
159 // access the time.
160 if (network_thread_keeper_) {
161 network_thread_keeper_->Start();
162 }
Zhi Huange830e682018-03-30 10:48:35 -0700163
deadbeeff5346592017-01-24 21:51:21 -0800164 // Make sure if using raw packet transports, they're used for both
165 // channels.
166 RTC_DCHECK_EQ(flags1 & RAW_PACKET_TRANSPORT, flags2 & RAW_PACKET_TRANSPORT);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200167 rtc::Thread* worker_thread = rtc::Thread::Current();
deadbeeff5346592017-01-24 21:51:21 -0800168 // Based on flags, create fake DTLS or raw packet transports.
169 if (flags1 & RAW_PACKET_TRANSPORT) {
170 fake_rtp_packet_transport1_.reset(
171 new rtc::FakePacketTransport("channel1_rtp"));
Zhi Huange830e682018-03-30 10:48:35 -0700172 if (!(flags1 & RTCP_MUX)) {
deadbeeff5346592017-01-24 21:51:21 -0800173 fake_rtcp_packet_transport1_.reset(
174 new rtc::FakePacketTransport("channel1_rtcp"));
deadbeeff5346592017-01-24 21:51:21 -0800175 }
176 } else {
177 // Confirmed to work with KT_RSA and KT_ECDSA.
178 fake_rtp_dtls_transport1_.reset(new cricket::FakeDtlsTransport(
Niels Möller92430882021-03-18 10:03:19 +0100179 "channel1", cricket::ICE_CANDIDATE_COMPONENT_RTP, network_thread_));
Zhi Huange830e682018-03-30 10:48:35 -0700180 if (!(flags1 & RTCP_MUX)) {
deadbeeff5346592017-01-24 21:51:21 -0800181 fake_rtcp_dtls_transport1_.reset(new cricket::FakeDtlsTransport(
Niels Möller92430882021-03-18 10:03:19 +0100182 "channel1", cricket::ICE_CANDIDATE_COMPONENT_RTCP,
183 network_thread_));
deadbeeff5346592017-01-24 21:51:21 -0800184 }
185 if (flags1 & DTLS) {
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100186 auto cert1 = rtc::RTCCertificate::Create(
187 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
deadbeeff5346592017-01-24 21:51:21 -0800188 fake_rtp_dtls_transport1_->SetLocalCertificate(cert1);
189 if (fake_rtcp_dtls_transport1_) {
190 fake_rtcp_dtls_transport1_->SetLocalCertificate(cert1);
191 }
192 }
193 }
194 // Based on flags, create fake DTLS or raw packet transports.
195 if (flags2 & RAW_PACKET_TRANSPORT) {
196 fake_rtp_packet_transport2_.reset(
197 new rtc::FakePacketTransport("channel2_rtp"));
Zhi Huange830e682018-03-30 10:48:35 -0700198 if (!(flags2 & RTCP_MUX)) {
deadbeeff5346592017-01-24 21:51:21 -0800199 fake_rtcp_packet_transport2_.reset(
200 new rtc::FakePacketTransport("channel2_rtcp"));
deadbeeff5346592017-01-24 21:51:21 -0800201 }
202 } else {
203 // Confirmed to work with KT_RSA and KT_ECDSA.
204 fake_rtp_dtls_transport2_.reset(new cricket::FakeDtlsTransport(
Niels Möller92430882021-03-18 10:03:19 +0100205 "channel2", cricket::ICE_CANDIDATE_COMPONENT_RTP, network_thread_));
Zhi Huange830e682018-03-30 10:48:35 -0700206 if (!(flags2 & RTCP_MUX)) {
deadbeeff5346592017-01-24 21:51:21 -0800207 fake_rtcp_dtls_transport2_.reset(new cricket::FakeDtlsTransport(
Niels Möller92430882021-03-18 10:03:19 +0100208 "channel2", cricket::ICE_CANDIDATE_COMPONENT_RTCP,
209 network_thread_));
deadbeeff5346592017-01-24 21:51:21 -0800210 }
211 if (flags2 & DTLS) {
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100212 auto cert2 = rtc::RTCCertificate::Create(
213 rtc::SSLIdentity::Create("session2", rtc::KT_DEFAULT));
deadbeeff5346592017-01-24 21:51:21 -0800214 fake_rtp_dtls_transport2_->SetLocalCertificate(cert2);
215 if (fake_rtcp_dtls_transport2_) {
216 fake_rtcp_dtls_transport2_->SetLocalCertificate(cert2);
217 }
218 }
219 }
Zhi Huange830e682018-03-30 10:48:35 -0700220 rtp_transport1_ = CreateRtpTransportBasedOnFlags(
221 fake_rtp_packet_transport1_.get(), fake_rtcp_packet_transport1_.get(),
222 fake_rtp_dtls_transport1_.get(), fake_rtcp_dtls_transport1_.get(),
223 flags1);
224 rtp_transport2_ = CreateRtpTransportBasedOnFlags(
225 fake_rtp_packet_transport2_.get(), fake_rtcp_packet_transport2_.get(),
226 fake_rtp_dtls_transport2_.get(), fake_rtcp_dtls_transport2_.get(),
227 flags2);
228
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800229 channel1_ = CreateChannel(worker_thread, network_thread_, std::move(ch1),
230 rtp_transport1_.get(), flags1);
231 channel2_ = CreateChannel(worker_thread, network_thread_, std::move(ch2),
232 rtp_transport2_.get(), flags2);
Yves Gerey665174f2018-06-19 15:03:05 +0200233 CreateContent(flags1, kPcmuCodec, kH264Codec, &local_media_content1_);
234 CreateContent(flags2, kPcmuCodec, kH264Codec, &local_media_content2_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 CopyContent(local_media_content1_, &remote_media_content1_);
236 CopyContent(local_media_content2_, &remote_media_content2_);
237
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 // Add stream information (SSRC) to the local content but not to the remote
239 // content. This means that we per default know the SSRC of what we send but
240 // not what we receive.
241 AddLegacyStreamInContent(kSsrc1, flags1, &local_media_content1_);
242 AddLegacyStreamInContent(kSsrc2, flags2, &local_media_content2_);
243
244 // If SSRC_MUX is used we also need to know the SSRC of the incoming stream.
245 if (flags1 & SSRC_MUX) {
246 AddLegacyStreamInContent(kSsrc1, flags1, &remote_media_content1_);
247 }
248 if (flags2 & SSRC_MUX) {
249 AddLegacyStreamInContent(kSsrc2, flags2, &remote_media_content2_);
250 }
251 }
Steve Anton8699a322017-11-06 15:53:33 -0800252 std::unique_ptr<typename T::Channel> CreateChannel(
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200253 rtc::Thread* worker_thread,
254 rtc::Thread* network_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800255 std::unique_ptr<typename T::MediaChannel> ch,
Zhi Huange830e682018-03-30 10:48:35 -0700256 webrtc::RtpTransportInternal* rtp_transport,
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +0200257 int flags);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258
Zhi Huange830e682018-03-30 10:48:35 -0700259 std::unique_ptr<webrtc::RtpTransportInternal> CreateRtpTransportBasedOnFlags(
260 rtc::PacketTransportInternal* rtp_packet_transport,
261 rtc::PacketTransportInternal* rtcp_packet_transport,
262 DtlsTransportInternal* rtp_dtls_transport,
263 DtlsTransportInternal* rtcp_dtls_transport,
264 int flags) {
265 if (flags & RTCP_MUX) {
266 rtcp_packet_transport = nullptr;
267 rtcp_dtls_transport = nullptr;
268 }
269
270 if (flags & DTLS) {
271 return CreateDtlsSrtpTransport(rtp_dtls_transport, rtcp_dtls_transport);
272 } else {
273 if (flags & RAW_PACKET_TRANSPORT) {
274 return CreateUnencryptedTransport(rtp_packet_transport,
275 rtcp_packet_transport);
276 } else {
277 return CreateUnencryptedTransport(rtp_dtls_transport,
278 rtcp_dtls_transport);
279 }
280 }
281 }
282
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100283 // Unininitializes the channels on the network thread.
284 void DeinitChannels() {
285 if (!channel1_ && !channel2_)
286 return;
287 network_thread_->Invoke<void>(RTC_FROM_HERE, [this]() {
288 if (channel1_) {
289 RTC_DCHECK_RUN_ON(channel1_->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100290 channel1_->SetRtpTransport(nullptr);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100291 }
292 if (channel2_) {
293 RTC_DCHECK_RUN_ON(channel2_->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +0100294 channel2_->SetRtpTransport(nullptr);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100295 }
296 });
297 }
298
Zhi Huange830e682018-03-30 10:48:35 -0700299 std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedTransport(
300 rtc::PacketTransportInternal* rtp_packet_transport,
301 rtc::PacketTransportInternal* rtcp_packet_transport) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200302 auto rtp_transport = std::make_unique<webrtc::RtpTransport>(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200303 rtcp_packet_transport == nullptr);
Zhi Huange830e682018-03-30 10:48:35 -0700304
Niels Möller92430882021-03-18 10:03:19 +0100305 network_thread_->Invoke<void>(
306 RTC_FROM_HERE,
307 [&rtp_transport, rtp_packet_transport, rtcp_packet_transport] {
308 rtp_transport->SetRtpPacketTransport(rtp_packet_transport);
309 if (rtcp_packet_transport) {
310 rtp_transport->SetRtcpPacketTransport(rtcp_packet_transport);
311 }
312 });
Zhi Huange830e682018-03-30 10:48:35 -0700313 return rtp_transport;
314 }
315
316 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
317 cricket::DtlsTransportInternal* rtp_dtls_transport,
318 cricket::DtlsTransportInternal* rtcp_dtls_transport) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200319 auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
Zhi Huang365381f2018-04-13 16:44:34 -0700320 rtcp_dtls_transport == nullptr);
Zhi Huange830e682018-03-30 10:48:35 -0700321
Niels Möller92430882021-03-18 10:03:19 +0100322 network_thread_->Invoke<void>(
323 RTC_FROM_HERE,
324 [&dtls_srtp_transport, rtp_dtls_transport, rtcp_dtls_transport] {
325 dtls_srtp_transport->SetDtlsTransports(rtp_dtls_transport,
326 rtcp_dtls_transport);
327 });
Zhi Huange830e682018-03-30 10:48:35 -0700328 return dtls_srtp_transport;
329 }
330
deadbeeff5346592017-01-24 21:51:21 -0800331 void ConnectFakeTransports() {
332 network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
333 bool asymmetric = false;
334 // Depending on test flags, could be using DTLS or raw packet transport.
335 if (fake_rtp_dtls_transport1_ && fake_rtp_dtls_transport2_) {
336 fake_rtp_dtls_transport1_->SetDestination(
337 fake_rtp_dtls_transport2_.get(), asymmetric);
338 }
339 if (fake_rtcp_dtls_transport1_ && fake_rtcp_dtls_transport2_) {
340 fake_rtcp_dtls_transport1_->SetDestination(
341 fake_rtcp_dtls_transport2_.get(), asymmetric);
342 }
343 if (fake_rtp_packet_transport1_ && fake_rtp_packet_transport2_) {
344 fake_rtp_packet_transport1_->SetDestination(
345 fake_rtp_packet_transport2_.get(), asymmetric);
346 }
347 if (fake_rtcp_packet_transport1_ && fake_rtcp_packet_transport2_) {
348 fake_rtcp_packet_transport1_->SetDestination(
349 fake_rtcp_packet_transport2_.get(), asymmetric);
350 }
351 });
Taylor Brandstetter2ab9b282021-02-01 14:39:07 -0800352 // The transport becoming writable will asynchronously update the send state
353 // on the worker thread; since this test uses the main thread as the worker
354 // thread, we must process the message queue for this to occur.
355 WaitForThreads();
deadbeeff5346592017-01-24 21:51:21 -0800356 }
357
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358 bool SendInitiate() {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000359 std::string err;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000360 bool result = channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000361 SdpType::kOffer, err);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000362 if (result) {
363 channel1_->Enable(true);
Tommi1959f8f2021-04-26 10:20:19 +0200364 FlushCurrentThread();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000365 result = channel2_->SetRemoteContent(&remote_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000366 SdpType::kOffer, err);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000367 if (result) {
deadbeeff5346592017-01-24 21:51:21 -0800368 ConnectFakeTransports();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000369 result = channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000370 SdpType::kAnswer, err);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000371 }
372 }
373 return result;
374 }
375
376 bool SendAccept() {
377 channel2_->Enable(true);
Tommi1959f8f2021-04-26 10:20:19 +0200378 FlushCurrentThread();
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000379 std::string err;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000380 return channel1_->SetRemoteContent(&remote_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000381 SdpType::kAnswer, err);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382 }
383
384 bool SendOffer() {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000385 std::string err;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000386 bool result = channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000387 SdpType::kOffer, err);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000388 if (result) {
389 channel1_->Enable(true);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000390 result = channel2_->SetRemoteContent(&remote_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000391 SdpType::kOffer, err);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000392 }
393 return result;
394 }
395
396 bool SendProvisionalAnswer() {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000397 std::string err;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000398 bool result = channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000399 SdpType::kPrAnswer, err);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000400 if (result) {
401 channel2_->Enable(true);
402 result = channel1_->SetRemoteContent(&remote_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000403 SdpType::kPrAnswer, err);
deadbeeff5346592017-01-24 21:51:21 -0800404 ConnectFakeTransports();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000405 }
406 return result;
407 }
408
409 bool SendFinalAnswer() {
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000410 std::string err;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000411 bool result = channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000412 SdpType::kAnswer, err);
413 if (result) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000414 result = channel1_->SetRemoteContent(&remote_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000415 SdpType::kAnswer, err);
416 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000417 return result;
418 }
419
Tommic9625f02021-05-06 22:03:19 +0200420 void SendRtp(typename T::MediaChannel* media_channel, rtc::Buffer data) {
421 network_thread_->PostTask(webrtc::ToQueuedTask(
422 network_thread_safety_, [media_channel, data = std::move(data)]() {
423 media_channel->SendRtp(data.data(), data.size(),
424 rtc::PacketOptions());
425 }));
426 }
427
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200428 void SendRtp1() {
Tommic9625f02021-05-06 22:03:19 +0200429 SendRtp1(rtc::Buffer(rtp_packet_.data(), rtp_packet_.size()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000430 }
Tommic9625f02021-05-06 22:03:19 +0200431
432 void SendRtp1(rtc::Buffer data) {
433 SendRtp(media_channel1(), std::move(data));
434 }
435
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200436 void SendRtp2() {
Tommic9625f02021-05-06 22:03:19 +0200437 SendRtp2(rtc::Buffer(rtp_packet_.data(), rtp_packet_.size()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000438 }
Tommic9625f02021-05-06 22:03:19 +0200439
440 void SendRtp2(rtc::Buffer data) {
441 SendRtp(media_channel2(), std::move(data));
442 }
443
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444 // Methods to send custom data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200445 void SendCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Tommic9625f02021-05-06 22:03:19 +0200446 SendRtp1(CreateRtpData(ssrc, sequence_number, pl_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000447 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200448 void SendCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Tommic9625f02021-05-06 22:03:19 +0200449 SendRtp2(CreateRtpData(ssrc, sequence_number, pl_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200451
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000452 bool CheckRtp1() {
Tommic9625f02021-05-06 22:03:19 +0200453 return media_channel1()->CheckRtp(rtp_packet_.data(), rtp_packet_.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000454 }
455 bool CheckRtp2() {
Tommic9625f02021-05-06 22:03:19 +0200456 return media_channel2()->CheckRtp(rtp_packet_.data(), rtp_packet_.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000457 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000458 // Methods to check custom data.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200459 bool CheckCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200460 rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
Tommic9625f02021-05-06 22:03:19 +0200461 return media_channel1()->CheckRtp(data.data(), data.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000462 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200463 bool CheckCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200464 rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
Tommic9625f02021-05-06 22:03:19 +0200465 return media_channel2()->CheckRtp(data.data(), data.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000466 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200467 rtc::Buffer CreateRtpData(uint32_t ssrc, int sequence_number, int pl_type) {
468 rtc::Buffer data(rtp_packet_.data(), rtp_packet_.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000469 // Set SSRC in the rtp packet copy.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200470 rtc::SetBE32(data.data() + 8, ssrc);
471 rtc::SetBE16(data.data() + 2, sequence_number);
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +0000472 if (pl_type >= 0) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200473 rtc::Set8(data.data(), 1, static_cast<uint8_t>(pl_type));
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +0000474 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000475 return data;
476 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000477
Tommic9625f02021-05-06 22:03:19 +0200478 bool CheckNoRtp1() { return media_channel1()->CheckNoRtp(); }
479 bool CheckNoRtp2() { return media_channel2()->CheckNoRtp(); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000480
481 void CreateContent(int flags,
482 const cricket::AudioCodec& audio_codec,
483 const cricket::VideoCodec& video_codec,
484 typename T::Content* content) {
485 // overridden in specialized classes
486 }
487 void CopyContent(const typename T::Content& source,
488 typename T::Content* content) {
489 // overridden in specialized classes
490 }
491
Steve Anton18ee1d52017-09-11 11:32:35 -0700492 // Creates a MediaContent with one stream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000493 // kPcmuCodec is used as audio codec and kH264Codec is used as video codec.
Steve Anton18ee1d52017-09-11 11:32:35 -0700494 typename T::Content* CreateMediaContentWithStream(uint32_t ssrc) {
495 typename T::Content* content = new typename T::Content();
Zhi Huange830e682018-03-30 10:48:35 -0700496 CreateContent(0, kPcmuCodec, kH264Codec, content);
Steve Anton18ee1d52017-09-11 11:32:35 -0700497 AddLegacyStreamInContent(ssrc, 0, content);
498 return content;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000499 }
500
ossu292d6582016-03-17 02:31:13 -0700501 // Will manage the lifetime of a CallThread, making sure it's
502 // destroyed before this object goes out of scope.
503 class ScopedCallThread {
504 public:
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200505 template <class FunctorT>
Artem Titovd8bd7502019-01-09 21:10:00 +0100506 explicit ScopedCallThread(FunctorT&& functor)
Danil Chapovalovb877e712019-11-29 15:19:27 +0100507 : thread_(rtc::Thread::Create()) {
ossu292d6582016-03-17 02:31:13 -0700508 thread_->Start();
Henrik Boström2deee4b2022-01-20 11:58:05 +0100509 thread_->PostTask(std::forward<FunctorT>(functor));
ossu292d6582016-03-17 02:31:13 -0700510 }
511
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200512 ~ScopedCallThread() { thread_->Stop(); }
ossu292d6582016-03-17 02:31:13 -0700513
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200514 rtc::Thread* thread() { return thread_.get(); }
ossu292d6582016-03-17 02:31:13 -0700515
516 private:
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200517 std::unique_ptr<rtc::Thread> thread_;
ossu292d6582016-03-17 02:31:13 -0700518 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000519
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 bool CodecMatches(const typename T::Codec& c1, const typename T::Codec& c2) {
521 return false; // overridden in specialized classes
522 }
523
Honghai Zhangcc411c02016-03-29 17:27:21 -0700524 cricket::CandidatePairInterface* last_selected_candidate_pair() {
525 return last_selected_candidate_pair_;
526 }
527
Peter Boström0c4e06b2015-10-07 12:23:21 +0200528 void AddLegacyStreamInContent(uint32_t ssrc,
529 int flags,
530 typename T::Content* content) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000531 // Base implementation.
532 }
533
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200534 // Utility method that calls BaseChannel::srtp_active() on the network thread
Artem Titov880fa812021-07-30 22:30:23 +0200535 // and returns the result. The `srtp_active()` state is maintained on the
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200536 // network thread, which callers need to factor in.
537 bool IsSrtpActive(std::unique_ptr<typename T::Channel>& channel) {
538 RTC_DCHECK(channel.get());
539 return network_thread_->Invoke<bool>(
540 RTC_FROM_HERE, [&] { return channel->srtp_active(); });
541 }
542
543 // Returns true iff the transport is set for a channel and rtcp_mux_enabled()
544 // returns true.
545 bool IsRtcpMuxEnabled(std::unique_ptr<typename T::Channel>& channel) {
546 RTC_DCHECK(channel.get());
547 return network_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
548 return channel->rtp_transport() &&
549 channel->rtp_transport()->rtcp_mux_enabled();
550 });
551 }
552
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000553 // Tests that can be used by derived classes.
554
555 // Basic sanity check.
556 void TestInit() {
557 CreateChannels(0, 0);
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200558 EXPECT_FALSE(IsSrtpActive(channel1_));
Tommic9625f02021-05-06 22:03:19 +0200559 EXPECT_FALSE(media_channel1()->sending());
Peter Boström34fbfff2015-09-24 19:20:30 +0200560 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200561 EXPECT_FALSE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200562 }
Tommic9625f02021-05-06 22:03:19 +0200563 EXPECT_TRUE(media_channel1()->codecs().empty());
564 EXPECT_TRUE(media_channel1()->recv_streams().empty());
565 EXPECT_TRUE(media_channel1()->rtp_packets().empty());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000566 }
567
568 // Test that SetLocalContent and SetRemoteContent properly configure
569 // the codecs.
570 void TestSetContents() {
571 CreateChannels(0, 0);
572 typename T::Content content;
573 CreateContent(0, kPcmuCodec, kH264Codec, &content);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000574 std::string err;
575 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +0200576 EXPECT_EQ(0U, media_channel1()->codecs().size());
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000577 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +0200578 ASSERT_EQ(1U, media_channel1()->codecs().size());
Yves Gerey665174f2018-06-19 15:03:05 +0200579 EXPECT_TRUE(
Tommic9625f02021-05-06 22:03:19 +0200580 CodecMatches(content.codecs()[0], media_channel1()->codecs()[0]));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000581 }
582
Johannes Kron9190b822018-10-29 11:22:05 +0100583 // Test that SetLocalContent and SetRemoteContent properly configure
584 // extmap-allow-mixed.
585 void TestSetContentsExtmapAllowMixedCaller(bool offer, bool answer) {
586 // For a caller, SetLocalContent() is called first with an offer and next
587 // SetRemoteContent() is called with the answer.
588 CreateChannels(0, 0);
589 typename T::Content content;
590 CreateContent(0, kPcmuCodec, kH264Codec, &content);
591 auto offer_enum = offer ? (T::Content::kSession) : (T::Content::kNo);
592 auto answer_enum = answer ? (T::Content::kSession) : (T::Content::kNo);
593 content.set_extmap_allow_mixed_enum(offer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000594 std::string err;
595 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
Johannes Kron9190b822018-10-29 11:22:05 +0100596 content.set_extmap_allow_mixed_enum(answer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000597 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +0200598 EXPECT_EQ(answer, media_channel1()->ExtmapAllowMixed());
Johannes Kron9190b822018-10-29 11:22:05 +0100599 }
600 void TestSetContentsExtmapAllowMixedCallee(bool offer, bool answer) {
601 // For a callee, SetRemoteContent() is called first with an offer and next
602 // SetLocalContent() is called with the answer.
603 CreateChannels(0, 0);
604 typename T::Content content;
605 CreateContent(0, kPcmuCodec, kH264Codec, &content);
606 auto offer_enum = offer ? (T::Content::kSession) : (T::Content::kNo);
607 auto answer_enum = answer ? (T::Content::kSession) : (T::Content::kNo);
608 content.set_extmap_allow_mixed_enum(offer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000609 std::string err;
610 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kOffer, err));
Johannes Kron9190b822018-10-29 11:22:05 +0100611 content.set_extmap_allow_mixed_enum(answer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000612 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +0200613 EXPECT_EQ(answer, media_channel1()->ExtmapAllowMixed());
Johannes Kron9190b822018-10-29 11:22:05 +0100614 }
615
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000616 // Test that SetLocalContent and SetRemoteContent properly deals
617 // with an empty offer.
618 void TestSetContentsNullOffer() {
619 CreateChannels(0, 0);
620 typename T::Content content;
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000621 std::string err;
622 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623 CreateContent(0, kPcmuCodec, kH264Codec, &content);
Tommic9625f02021-05-06 22:03:19 +0200624 EXPECT_EQ(0U, media_channel1()->codecs().size());
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000625 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +0200626 ASSERT_EQ(1U, media_channel1()->codecs().size());
Yves Gerey665174f2018-06-19 15:03:05 +0200627 EXPECT_TRUE(
Tommic9625f02021-05-06 22:03:19 +0200628 CodecMatches(content.codecs()[0], media_channel1()->codecs()[0]));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629 }
630
631 // Test that SetLocalContent and SetRemoteContent properly set RTCP
632 // mux.
633 void TestSetContentsRtcpMux() {
deadbeefac22f702017-01-12 21:59:29 -0800634 CreateChannels(0, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635 typename T::Content content;
636 CreateContent(0, kPcmuCodec, kH264Codec, &content);
637 // Both sides agree on mux. Should no longer be a separate RTCP channel.
638 content.set_rtcp_mux(true);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000639 std::string err;
640 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
641 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000642 // Only initiator supports mux. Should still have a separate RTCP channel.
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000643 EXPECT_TRUE(channel2_->SetLocalContent(&content, SdpType::kOffer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000644 content.set_rtcp_mux(false);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000645 EXPECT_TRUE(channel2_->SetRemoteContent(&content, SdpType::kAnswer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000646 }
647
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648 // Test that SetLocalContent and SetRemoteContent properly
649 // handles adding and removing StreamParams when the action is a full
Steve Anton3828c062017-12-06 10:34:51 -0800650 // SdpType::kOffer / SdpType::kAnswer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651 void TestChangeStreamParamsInContent() {
652 cricket::StreamParams stream1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000653 stream1.id = "stream1";
654 stream1.ssrcs.push_back(kSsrc1);
655 stream1.cname = "stream1_cname";
656
657 cricket::StreamParams stream2;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658 stream2.id = "stream2";
659 stream2.ssrcs.push_back(kSsrc2);
660 stream2.cname = "stream2_cname";
661
Artem Titov880fa812021-07-30 22:30:23 +0200662 // Setup a call where channel 1 send `stream1` to channel 2.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000663 CreateChannels(0, 0);
664 typename T::Content content1;
665 CreateContent(0, kPcmuCodec, kH264Codec, &content1);
666 content1.AddStream(stream1);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000667 std::string err;
668 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
Tommi1959f8f2021-04-26 10:20:19 +0200669 channel1_->Enable(true);
Tommic9625f02021-05-06 22:03:19 +0200670 EXPECT_EQ(1u, media_channel1()->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000671
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000672 EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +0200673 EXPECT_EQ(1u, media_channel2()->recv_streams().size());
deadbeeff5346592017-01-24 21:51:21 -0800674 ConnectFakeTransports();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675
676 // Channel 2 do not send anything.
677 typename T::Content content2;
678 CreateContent(0, kPcmuCodec, kH264Codec, &content2);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000679 EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +0200680 EXPECT_EQ(0u, media_channel1()->recv_streams().size());
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000681 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, err));
Tommi1959f8f2021-04-26 10:20:19 +0200682 channel2_->Enable(true);
Tommic9625f02021-05-06 22:03:19 +0200683 EXPECT_EQ(0u, media_channel2()->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000684
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200685 SendCustomRtp1(kSsrc1, 0);
686 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000687 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, 0));
688
Artem Titov880fa812021-07-30 22:30:23 +0200689 // Let channel 2 update the content by sending `stream2` and enable SRTP.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000690 typename T::Content content3;
Zhi Huange830e682018-03-30 10:48:35 -0700691 CreateContent(0, kPcmuCodec, kH264Codec, &content3);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692 content3.AddStream(stream2);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000693 EXPECT_TRUE(channel2_->SetLocalContent(&content3, SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +0200694 ASSERT_EQ(1u, media_channel2()->send_streams().size());
695 EXPECT_EQ(stream2, media_channel2()->send_streams()[0]);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000696
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000697 EXPECT_TRUE(channel1_->SetRemoteContent(&content3, SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +0200698 ASSERT_EQ(1u, media_channel1()->recv_streams().size());
699 EXPECT_EQ(stream2, media_channel1()->recv_streams()[0]);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000700
701 // Channel 1 replies but stop sending stream1.
702 typename T::Content content4;
Zhi Huange830e682018-03-30 10:48:35 -0700703 CreateContent(0, kPcmuCodec, kH264Codec, &content4);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000704 EXPECT_TRUE(channel1_->SetLocalContent(&content4, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +0200705 EXPECT_EQ(0u, media_channel1()->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000706
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000707 EXPECT_TRUE(channel2_->SetRemoteContent(&content4, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +0200708 EXPECT_EQ(0u, media_channel2()->recv_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200710 SendCustomRtp2(kSsrc2, 0);
711 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, 0));
713 }
714
715 // Test that we only start playout and sending at the right times.
716 void TestPlayoutAndSendingStates() {
717 CreateChannels(0, 0);
Peter Boström34fbfff2015-09-24 19:20:30 +0200718 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200719 EXPECT_FALSE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200720 }
Tommic9625f02021-05-06 22:03:19 +0200721 EXPECT_FALSE(media_channel1()->sending());
Peter Boström34fbfff2015-09-24 19:20:30 +0200722 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200723 EXPECT_FALSE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200724 }
Tommic9625f02021-05-06 22:03:19 +0200725 EXPECT_FALSE(media_channel2()->sending());
Tommi1959f8f2021-04-26 10:20:19 +0200726 channel1_->Enable(true);
727 FlushCurrentThread();
Peter Boström34fbfff2015-09-24 19:20:30 +0200728 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200729 EXPECT_FALSE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200730 }
Tommic9625f02021-05-06 22:03:19 +0200731 EXPECT_FALSE(media_channel1()->sending());
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000732 std::string err;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000733 EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000734 SdpType::kOffer, err));
Peter Boström34fbfff2015-09-24 19:20:30 +0200735 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200736 EXPECT_TRUE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200737 }
Tommic9625f02021-05-06 22:03:19 +0200738 EXPECT_FALSE(media_channel1()->sending());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000739 EXPECT_TRUE(channel2_->SetRemoteContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000740 SdpType::kOffer, err));
Peter Boström34fbfff2015-09-24 19:20:30 +0200741 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200742 EXPECT_FALSE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200743 }
Tommic9625f02021-05-06 22:03:19 +0200744 EXPECT_FALSE(media_channel2()->sending());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000745 EXPECT_TRUE(channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000746 SdpType::kAnswer, err));
Peter Boström34fbfff2015-09-24 19:20:30 +0200747 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200748 EXPECT_FALSE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200749 }
Tommic9625f02021-05-06 22:03:19 +0200750 EXPECT_FALSE(media_channel2()->sending());
deadbeeff5346592017-01-24 21:51:21 -0800751 ConnectFakeTransports();
Peter Boström34fbfff2015-09-24 19:20:30 +0200752 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200753 EXPECT_TRUE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200754 }
Tommic9625f02021-05-06 22:03:19 +0200755 EXPECT_FALSE(media_channel1()->sending());
Peter Boström34fbfff2015-09-24 19:20:30 +0200756 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200757 EXPECT_FALSE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200758 }
Tommic9625f02021-05-06 22:03:19 +0200759 EXPECT_FALSE(media_channel2()->sending());
Tommi1959f8f2021-04-26 10:20:19 +0200760 channel2_->Enable(true);
761 FlushCurrentThread();
Peter Boström34fbfff2015-09-24 19:20:30 +0200762 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200763 EXPECT_TRUE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200764 }
Tommic9625f02021-05-06 22:03:19 +0200765 EXPECT_TRUE(media_channel2()->sending());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000766 EXPECT_TRUE(channel1_->SetRemoteContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000767 SdpType::kAnswer, err));
Peter Boström34fbfff2015-09-24 19:20:30 +0200768 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200769 EXPECT_TRUE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200770 }
Tommic9625f02021-05-06 22:03:19 +0200771 EXPECT_TRUE(media_channel1()->sending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772 }
773
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000774 // Test that changing the MediaContentDirection in the local and remote
775 // session description start playout and sending at the right time.
776 void TestMediaContentDirection() {
777 CreateChannels(0, 0);
778 typename T::Content content1;
779 CreateContent(0, kPcmuCodec, kH264Codec, &content1);
780 typename T::Content content2;
781 CreateContent(0, kPcmuCodec, kH264Codec, &content2);
Artem Titov880fa812021-07-30 22:30:23 +0200782 // Set `content2` to be InActive.
Steve Anton4e70a722017-11-28 14:57:10 -0800783 content2.set_direction(RtpTransceiverDirection::kInactive);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784
Tommi1959f8f2021-04-26 10:20:19 +0200785 channel1_->Enable(true);
786 channel2_->Enable(true);
787 FlushCurrentThread();
Peter Boström34fbfff2015-09-24 19:20:30 +0200788 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200789 EXPECT_FALSE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200790 }
Tommic9625f02021-05-06 22:03:19 +0200791 EXPECT_FALSE(media_channel1()->sending());
Peter Boström34fbfff2015-09-24 19:20:30 +0200792 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200793 EXPECT_FALSE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200794 }
Tommic9625f02021-05-06 22:03:19 +0200795 EXPECT_FALSE(media_channel2()->sending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000797 std::string err;
798 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
799 EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, err));
800 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kPrAnswer, err));
Steve Anton3828c062017-12-06 10:34:51 -0800801 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000802 channel1_->SetRemoteContent(&content2, SdpType::kPrAnswer, err));
deadbeeff5346592017-01-24 21:51:21 -0800803 ConnectFakeTransports();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804
Peter Boström34fbfff2015-09-24 19:20:30 +0200805 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200806 EXPECT_TRUE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200807 }
Tommic9625f02021-05-06 22:03:19 +0200808 EXPECT_FALSE(media_channel1()->sending()); // remote InActive
Peter Boström34fbfff2015-09-24 19:20:30 +0200809 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200810 EXPECT_FALSE(media_channel2()->playout()); // local InActive
Peter Boström34fbfff2015-09-24 19:20:30 +0200811 }
Tommic9625f02021-05-06 22:03:19 +0200812 EXPECT_FALSE(media_channel2()->sending()); // local InActive
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813
Artem Titov880fa812021-07-30 22:30:23 +0200814 // Update `content2` to be RecvOnly.
Steve Anton4e70a722017-11-28 14:57:10 -0800815 content2.set_direction(RtpTransceiverDirection::kRecvOnly);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000816 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kPrAnswer, err));
Steve Anton3828c062017-12-06 10:34:51 -0800817 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000818 channel1_->SetRemoteContent(&content2, SdpType::kPrAnswer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819
Peter Boström34fbfff2015-09-24 19:20:30 +0200820 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200821 EXPECT_TRUE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200822 }
Tommic9625f02021-05-06 22:03:19 +0200823 EXPECT_TRUE(media_channel1()->sending());
Peter Boström34fbfff2015-09-24 19:20:30 +0200824 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200825 EXPECT_TRUE(media_channel2()->playout()); // local RecvOnly
Peter Boström34fbfff2015-09-24 19:20:30 +0200826 }
Tommic9625f02021-05-06 22:03:19 +0200827 EXPECT_FALSE(media_channel2()->sending()); // local RecvOnly
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828
Artem Titov880fa812021-07-30 22:30:23 +0200829 // Update `content2` to be SendRecv.
Steve Anton4e70a722017-11-28 14:57:10 -0800830 content2.set_direction(RtpTransceiverDirection::kSendRecv);
Tomas Gunnarssond908d742022-01-05 10:44:26 +0000831 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, err));
832 EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000833
Peter Boström34fbfff2015-09-24 19:20:30 +0200834 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200835 EXPECT_TRUE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200836 }
Tommic9625f02021-05-06 22:03:19 +0200837 EXPECT_TRUE(media_channel1()->sending());
Peter Boström34fbfff2015-09-24 19:20:30 +0200838 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200839 EXPECT_TRUE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200840 }
Tommic9625f02021-05-06 22:03:19 +0200841 EXPECT_TRUE(media_channel2()->sending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000842 }
843
Honghai Zhangcc411c02016-03-29 17:27:21 -0700844 // Tests that when the transport channel signals a candidate pair change
845 // event, the media channel will receive a call on the network route change.
846 void TestNetworkRouteChanges() {
eladalon05b07bb2017-08-24 07:40:16 -0700847 static constexpr uint16_t kLocalNetId = 1;
848 static constexpr uint16_t kRemoteNetId = 2;
849 static constexpr int kLastPacketId = 100;
Zhi Huang942bc2e2017-11-13 13:26:07 -0800850 // Ipv4(20) + UDP(8).
851 static constexpr int kTransportOverheadPerPacket = 28;
Zhi Huangcf6e24a2018-02-21 10:40:07 -0800852 static constexpr int kSrtpOverheadPerPacket = 10;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200853
Zhi Huangcf6e24a2018-02-21 10:40:07 -0800854 CreateChannels(DTLS, DTLS);
855 SendInitiate();
Honghai Zhangcc411c02016-03-29 17:27:21 -0700856
Honghai Zhangcc411c02016-03-29 17:27:21 -0700857 typename T::MediaChannel* media_channel1 =
858 static_cast<typename T::MediaChannel*>(channel1_->media_channel());
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200859 ASSERT_TRUE(media_channel1);
Honghai Zhangcc411c02016-03-29 17:27:21 -0700860
Zhi Huang942bc2e2017-11-13 13:26:07 -0800861 // Need to wait for the threads before calling
Artem Titov880fa812021-07-30 22:30:23 +0200862 // `set_num_network_route_changes` because the network route would be set
Zhi Huang942bc2e2017-11-13 13:26:07 -0800863 // when creating the channel.
864 WaitForThreads();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200865 media_channel1->set_num_network_route_changes(0);
deadbeeff5346592017-01-24 21:51:21 -0800866 network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800867 rtc::NetworkRoute network_route;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200868 // The transport channel becomes disconnected.
Zhi Huang942bc2e2017-11-13 13:26:07 -0800869 fake_rtp_dtls_transport1_->ice_transport()->SignalNetworkRouteChanged(
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200870 absl::optional<rtc::NetworkRoute>(network_route));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200871 });
872 WaitForThreads();
873 EXPECT_EQ(1, media_channel1->num_network_route_changes());
Honghai Zhangcc411c02016-03-29 17:27:21 -0700874 EXPECT_FALSE(media_channel1->last_network_route().connected);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200875 media_channel1->set_num_network_route_changes(0);
Honghai Zhangcc411c02016-03-29 17:27:21 -0700876
eladalon05b07bb2017-08-24 07:40:16 -0700877 network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800878 rtc::NetworkRoute network_route;
879 network_route.connected = true;
Jonas Oreland71fda362020-03-20 16:11:56 +0100880 network_route.local =
881 rtc::RouteEndpoint::CreateWithNetworkId(kLocalNetId);
882 network_route.remote =
883 rtc::RouteEndpoint::CreateWithNetworkId(kRemoteNetId);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800884 network_route.last_sent_packet_id = kLastPacketId;
885 network_route.packet_overhead = kTransportOverheadPerPacket;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200886 // The transport channel becomes connected.
Zhi Huang942bc2e2017-11-13 13:26:07 -0800887 fake_rtp_dtls_transport1_->ice_transport()->SignalNetworkRouteChanged(
888
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200889 absl::optional<rtc::NetworkRoute>(network_route));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200890 });
891 WaitForThreads();
892 EXPECT_EQ(1, media_channel1->num_network_route_changes());
Sebastian Janssonaf2adda2018-12-04 11:16:19 +0100893 EXPECT_TRUE(media_channel1->last_network_route().connected);
894 EXPECT_EQ(kLocalNetId,
Jonas Oreland71fda362020-03-20 16:11:56 +0100895 media_channel1->last_network_route().local.network_id());
Sebastian Janssonaf2adda2018-12-04 11:16:19 +0100896 EXPECT_EQ(kRemoteNetId,
Jonas Oreland71fda362020-03-20 16:11:56 +0100897 media_channel1->last_network_route().remote.network_id());
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200898 EXPECT_EQ(kLastPacketId,
Honghai Zhang52dce732016-03-31 12:37:31 -0700899 media_channel1->last_network_route().last_sent_packet_id);
Zhi Huangcf6e24a2018-02-21 10:40:07 -0800900 EXPECT_EQ(kTransportOverheadPerPacket + kSrtpOverheadPerPacket,
michaelt79e05882016-11-08 02:50:09 -0800901 media_channel1->transport_overhead_per_packet());
Honghai Zhangcc411c02016-03-29 17:27:21 -0700902 }
903
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904 // Test setting up a call.
905 void TestCallSetup() {
906 CreateChannels(0, 0);
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200907 EXPECT_FALSE(IsSrtpActive(channel1_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908 EXPECT_TRUE(SendInitiate());
Peter Boström34fbfff2015-09-24 19:20:30 +0200909 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200910 EXPECT_TRUE(media_channel1()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200911 }
Tommic9625f02021-05-06 22:03:19 +0200912 EXPECT_FALSE(media_channel1()->sending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200914 EXPECT_FALSE(IsSrtpActive(channel1_));
Tommic9625f02021-05-06 22:03:19 +0200915 EXPECT_TRUE(media_channel1()->sending());
916 EXPECT_EQ(1U, media_channel1()->codecs().size());
Peter Boström34fbfff2015-09-24 19:20:30 +0200917 if (verify_playout_) {
Tommic9625f02021-05-06 22:03:19 +0200918 EXPECT_TRUE(media_channel2()->playout());
Peter Boström34fbfff2015-09-24 19:20:30 +0200919 }
Tommic9625f02021-05-06 22:03:19 +0200920 EXPECT_TRUE(media_channel2()->sending());
921 EXPECT_EQ(1U, media_channel2()->codecs().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000922 }
923
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924 // Send voice RTP data to the other side and ensure it gets there.
925 void SendRtpToRtp() {
Zhi Huange830e682018-03-30 10:48:35 -0700926 CreateChannels(RTCP_MUX, RTCP_MUX);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927 EXPECT_TRUE(SendInitiate());
928 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200929 EXPECT_TRUE(IsRtcpMuxEnabled(channel1_));
930 EXPECT_TRUE(IsRtcpMuxEnabled(channel2_));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200931 SendRtp1();
932 SendRtp2();
933 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934 EXPECT_TRUE(CheckRtp1());
935 EXPECT_TRUE(CheckRtp2());
936 EXPECT_TRUE(CheckNoRtp1());
937 EXPECT_TRUE(CheckNoRtp2());
938 }
939
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200940 void TestDeinit() {
deadbeefac22f702017-01-12 21:59:29 -0800941 CreateChannels(0, 0);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200942 EXPECT_TRUE(SendInitiate());
943 EXPECT_TRUE(SendAccept());
944 SendRtp1();
945 SendRtp2();
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +0100946
947 DeinitChannels();
948
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200949 // Do not wait, destroy channels.
950 channel1_.reset(nullptr);
951 channel2_.reset(nullptr);
952 }
953
Zhi Huange830e682018-03-30 10:48:35 -0700954 void SendDtlsSrtpToDtlsSrtp(int flags1, int flags2) {
955 CreateChannels(flags1 | DTLS, flags2 | DTLS);
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200956 EXPECT_FALSE(IsSrtpActive(channel1_));
957 EXPECT_FALSE(IsSrtpActive(channel2_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958 EXPECT_TRUE(SendInitiate());
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200959 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200961 EXPECT_TRUE(IsSrtpActive(channel1_));
962 EXPECT_TRUE(IsSrtpActive(channel2_));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200963 SendRtp1();
964 SendRtp2();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200965 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966 EXPECT_TRUE(CheckRtp1());
967 EXPECT_TRUE(CheckRtp2());
968 EXPECT_TRUE(CheckNoRtp1());
969 EXPECT_TRUE(CheckNoRtp2());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000970 }
971
972 // Test that we can send and receive early media when a provisional answer is
973 // sent and received. The test uses SRTP, RTCP mux and SSRC mux.
974 void SendEarlyMediaUsingRtcpMuxSrtp() {
Yves Gerey665174f2018-06-19 15:03:05 +0200975 int sequence_number1_1 = 0, sequence_number2_2 = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976
Yves Gerey665174f2018-06-19 15:03:05 +0200977 CreateChannels(SSRC_MUX | RTCP_MUX | DTLS, SSRC_MUX | RTCP_MUX | DTLS);
978 EXPECT_TRUE(SendOffer());
979 EXPECT_TRUE(SendProvisionalAnswer());
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200980 EXPECT_TRUE(IsSrtpActive(channel1_));
981 EXPECT_TRUE(IsSrtpActive(channel2_));
982 EXPECT_TRUE(IsRtcpMuxEnabled(channel1_));
983 EXPECT_TRUE(IsRtcpMuxEnabled(channel2_));
Yves Gerey665174f2018-06-19 15:03:05 +0200984 WaitForThreads(); // Wait for 'sending' flag go through network thread.
Yves Gerey665174f2018-06-19 15:03:05 +0200985 SendCustomRtp1(kSsrc1, ++sequence_number1_1);
986 WaitForThreads();
Yves Gerey665174f2018-06-19 15:03:05 +0200987 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988
Yves Gerey665174f2018-06-19 15:03:05 +0200989 // Send packets from callee and verify that it is received.
Yves Gerey665174f2018-06-19 15:03:05 +0200990 SendCustomRtp2(kSsrc2, ++sequence_number2_2);
991 WaitForThreads();
Yves Gerey665174f2018-06-19 15:03:05 +0200992 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000993
Yves Gerey665174f2018-06-19 15:03:05 +0200994 // Complete call setup and ensure everything is still OK.
995 EXPECT_TRUE(SendFinalAnswer());
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +0200996 EXPECT_TRUE(IsSrtpActive(channel1_));
997 EXPECT_TRUE(IsSrtpActive(channel2_));
Yves Gerey665174f2018-06-19 15:03:05 +0200998 SendCustomRtp1(kSsrc1, ++sequence_number1_1);
Yves Gerey665174f2018-06-19 15:03:05 +0200999 SendCustomRtp2(kSsrc2, ++sequence_number2_2);
1000 WaitForThreads();
Yves Gerey665174f2018-06-19 15:03:05 +02001001 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1));
Yves Gerey665174f2018-06-19 15:03:05 +02001002 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001003 }
1004
1005 // Test that we properly send RTP without SRTP from a thread.
1006 void SendRtpToRtpOnThread() {
deadbeefac22f702017-01-12 21:59:29 -08001007 CreateChannels(0, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001008 EXPECT_TRUE(SendInitiate());
1009 EXPECT_TRUE(SendAccept());
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001010 ScopedCallThread send_rtp1([this] { SendRtp1(); });
1011 ScopedCallThread send_rtp2([this] { SendRtp2(); });
Bjorn A Mellemd0704ce2019-10-10 10:49:53 -07001012 rtc::Thread* involved_threads[] = {send_rtp1.thread(), send_rtp2.thread()};
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001013 WaitForThreads(involved_threads);
1014 EXPECT_TRUE(CheckRtp1());
1015 EXPECT_TRUE(CheckRtp2());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016 EXPECT_TRUE(CheckNoRtp1());
1017 EXPECT_TRUE(CheckNoRtp2());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001018 }
1019
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020 // Test that the mediachannel retains its sending state after the transport
1021 // becomes non-writable.
1022 void SendWithWritabilityLoss() {
Zhi Huange830e682018-03-30 10:48:35 -07001023 CreateChannels(RTCP_MUX, RTCP_MUX);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 EXPECT_TRUE(SendInitiate());
1025 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 11:26:47 +02001026 EXPECT_TRUE(IsRtcpMuxEnabled(channel1_));
1027 EXPECT_TRUE(IsRtcpMuxEnabled(channel2_));
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001028 SendRtp1();
1029 SendRtp2();
1030 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001031 EXPECT_TRUE(CheckRtp1());
1032 EXPECT_TRUE(CheckRtp2());
1033 EXPECT_TRUE(CheckNoRtp1());
1034 EXPECT_TRUE(CheckNoRtp2());
1035
wu@webrtc.org97077a32013-10-25 21:18:33 +00001036 // Lose writability, which should fail.
deadbeeff5346592017-01-24 21:51:21 -08001037 network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
1038 fake_rtp_dtls_transport1_->SetWritable(false);
1039 });
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001040 SendRtp1();
1041 SendRtp2();
1042 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001043 EXPECT_TRUE(CheckRtp1());
1044 EXPECT_TRUE(CheckNoRtp2());
1045
1046 // Regain writability
deadbeeff5346592017-01-24 21:51:21 -08001047 network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
1048 fake_rtp_dtls_transport1_->SetWritable(true);
1049 });
Tommic9625f02021-05-06 22:03:19 +02001050 EXPECT_TRUE(media_channel1()->sending());
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001051 SendRtp1();
1052 SendRtp2();
1053 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001054 EXPECT_TRUE(CheckRtp1());
1055 EXPECT_TRUE(CheckRtp2());
1056 EXPECT_TRUE(CheckNoRtp1());
1057 EXPECT_TRUE(CheckNoRtp2());
1058
1059 // Lose writability completely
deadbeeff5346592017-01-24 21:51:21 -08001060 network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
1061 bool asymmetric = true;
1062 fake_rtp_dtls_transport1_->SetDestination(nullptr, asymmetric);
1063 });
Tommic9625f02021-05-06 22:03:19 +02001064 EXPECT_TRUE(media_channel1()->sending());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001065
wu@webrtc.org97077a32013-10-25 21:18:33 +00001066 // Should fail also.
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001067 SendRtp1();
1068 SendRtp2();
1069 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001070 EXPECT_TRUE(CheckRtp1());
1071 EXPECT_TRUE(CheckNoRtp2());
zhihuangb2cdd932017-01-19 16:54:25 -08001072 EXPECT_TRUE(CheckNoRtp1());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001073
1074 // Gain writability back
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001075 network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
deadbeeff5346592017-01-24 21:51:21 -08001076 bool asymmetric = true;
1077 fake_rtp_dtls_transport1_->SetDestination(fake_rtp_dtls_transport2_.get(),
1078 asymmetric);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001079 });
Tommic9625f02021-05-06 22:03:19 +02001080 EXPECT_TRUE(media_channel1()->sending());
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001081 SendRtp1();
1082 SendRtp2();
1083 WaitForThreads();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001084 EXPECT_TRUE(CheckRtp1());
1085 EXPECT_TRUE(CheckRtp2());
1086 EXPECT_TRUE(CheckNoRtp1());
1087 EXPECT_TRUE(CheckNoRtp2());
1088 }
1089
Yves Gerey665174f2018-06-19 15:03:05 +02001090 void SendBundleToBundle(const int* pl_types,
1091 int len,
1092 bool rtcp_mux,
1093 bool secure) {
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001094 ASSERT_EQ(2, len);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001095 int sequence_number1_1 = 0, sequence_number2_2 = 0;
Artem Titov880fa812021-07-30 22:30:23 +02001096 // Only pl_type1 was added to the bundle filter for both `channel1_`
1097 // and `channel2_`.
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001098 int pl_type1 = pl_types[0];
1099 int pl_type2 = pl_types[1];
deadbeefac22f702017-01-12 21:59:29 -08001100 int flags = SSRC_MUX;
Zhi Huange830e682018-03-30 10:48:35 -07001101 if (secure)
1102 flags |= DTLS;
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001103 if (rtcp_mux) {
1104 flags |= RTCP_MUX;
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001105 }
1106 CreateChannels(flags, flags);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001107 EXPECT_TRUE(SendInitiate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001108 EXPECT_TRUE(SendAccept());
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001109
1110 // Both channels can receive pl_type1 only.
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001111 SendCustomRtp1(kSsrc1, ++sequence_number1_1, pl_type1);
1112 SendCustomRtp2(kSsrc2, ++sequence_number2_2, pl_type1);
1113 WaitForThreads();
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001114 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1, pl_type1));
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001115 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2, pl_type1));
1116 EXPECT_TRUE(CheckNoRtp1());
1117 EXPECT_TRUE(CheckNoRtp2());
1118
Zhi Huang365381f2018-04-13 16:44:34 -07001119 SendCustomRtp1(kSsrc3, ++sequence_number1_1, pl_type2);
1120 SendCustomRtp2(kSsrc4, ++sequence_number2_2, pl_type2);
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001121 WaitForThreads();
Zhi Huang365381f2018-04-13 16:44:34 -07001122 EXPECT_FALSE(CheckCustomRtp2(kSsrc3, sequence_number1_1, pl_type2));
1123 EXPECT_FALSE(CheckCustomRtp1(kSsrc4, sequence_number2_2, pl_type2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001124 }
1125
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001126 void TestSetContentFailure() {
1127 CreateChannels(0, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001128
Peter Thatchera6d24442015-07-09 21:26:36 -07001129 std::string err;
Steve Anton18ee1d52017-09-11 11:32:35 -07001130 std::unique_ptr<typename T::Content> content(
1131 CreateMediaContentWithStream(1));
1132
Tommic9625f02021-05-06 22:03:19 +02001133 media_channel1()->set_fail_set_recv_codecs(true);
Steve Anton18ee1d52017-09-11 11:32:35 -07001134 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001135 channel1_->SetLocalContent(content.get(), SdpType::kOffer, err));
Steve Anton18ee1d52017-09-11 11:32:35 -07001136 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001137 channel1_->SetLocalContent(content.get(), SdpType::kAnswer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001138
Tommic9625f02021-05-06 22:03:19 +02001139 media_channel1()->set_fail_set_send_codecs(true);
Steve Anton18ee1d52017-09-11 11:32:35 -07001140 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001141 channel1_->SetRemoteContent(content.get(), SdpType::kOffer, err));
Steve Anton18ee1d52017-09-11 11:32:35 -07001142
Tommic9625f02021-05-06 22:03:19 +02001143 media_channel1()->set_fail_set_send_codecs(true);
Steve Anton18ee1d52017-09-11 11:32:35 -07001144 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001145 channel1_->SetRemoteContent(content.get(), SdpType::kAnswer, err));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001146 }
1147
1148 void TestSendTwoOffers() {
1149 CreateChannels(0, 0);
1150
Peter Thatchera6d24442015-07-09 21:26:36 -07001151 std::string err;
Steve Anton18ee1d52017-09-11 11:32:35 -07001152 std::unique_ptr<typename T::Content> content1(
1153 CreateMediaContentWithStream(1));
1154 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001155 channel1_->SetLocalContent(content1.get(), SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02001156 EXPECT_TRUE(media_channel1()->HasSendStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001157
Steve Anton18ee1d52017-09-11 11:32:35 -07001158 std::unique_ptr<typename T::Content> content2(
1159 CreateMediaContentWithStream(2));
1160 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001161 channel1_->SetLocalContent(content2.get(), SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02001162 EXPECT_FALSE(media_channel1()->HasSendStream(1));
1163 EXPECT_TRUE(media_channel1()->HasSendStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001164 }
1165
1166 void TestReceiveTwoOffers() {
1167 CreateChannels(0, 0);
1168
Peter Thatchera6d24442015-07-09 21:26:36 -07001169 std::string err;
Steve Anton18ee1d52017-09-11 11:32:35 -07001170 std::unique_ptr<typename T::Content> content1(
1171 CreateMediaContentWithStream(1));
1172 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001173 channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02001174 EXPECT_TRUE(media_channel1()->HasRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001175
Steve Anton18ee1d52017-09-11 11:32:35 -07001176 std::unique_ptr<typename T::Content> content2(
1177 CreateMediaContentWithStream(2));
1178 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001179 channel1_->SetRemoteContent(content2.get(), SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02001180 EXPECT_FALSE(media_channel1()->HasRecvStream(1));
1181 EXPECT_TRUE(media_channel1()->HasRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001182 }
1183
1184 void TestSendPrAnswer() {
1185 CreateChannels(0, 0);
1186
Peter Thatchera6d24442015-07-09 21:26:36 -07001187 std::string err;
1188 // Receive offer
Steve Anton18ee1d52017-09-11 11:32:35 -07001189 std::unique_ptr<typename T::Content> content1(
1190 CreateMediaContentWithStream(1));
1191 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001192 channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02001193 EXPECT_TRUE(media_channel1()->HasRecvStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001194
Peter Thatchera6d24442015-07-09 21:26:36 -07001195 // Send PR answer
Steve Anton18ee1d52017-09-11 11:32:35 -07001196 std::unique_ptr<typename T::Content> content2(
1197 CreateMediaContentWithStream(2));
1198 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001199 channel1_->SetLocalContent(content2.get(), SdpType::kPrAnswer, err));
Tommic9625f02021-05-06 22:03:19 +02001200 EXPECT_TRUE(media_channel1()->HasRecvStream(1));
1201 EXPECT_TRUE(media_channel1()->HasSendStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001202
Peter Thatchera6d24442015-07-09 21:26:36 -07001203 // Send answer
Steve Anton18ee1d52017-09-11 11:32:35 -07001204 std::unique_ptr<typename T::Content> content3(
1205 CreateMediaContentWithStream(3));
1206 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001207 channel1_->SetLocalContent(content3.get(), SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +02001208 EXPECT_TRUE(media_channel1()->HasRecvStream(1));
1209 EXPECT_FALSE(media_channel1()->HasSendStream(2));
1210 EXPECT_TRUE(media_channel1()->HasSendStream(3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001211 }
1212
1213 void TestReceivePrAnswer() {
1214 CreateChannels(0, 0);
1215
Peter Thatchera6d24442015-07-09 21:26:36 -07001216 std::string err;
1217 // Send offer
Steve Anton18ee1d52017-09-11 11:32:35 -07001218 std::unique_ptr<typename T::Content> content1(
1219 CreateMediaContentWithStream(1));
1220 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001221 channel1_->SetLocalContent(content1.get(), SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02001222 EXPECT_TRUE(media_channel1()->HasSendStream(1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001223
Peter Thatchera6d24442015-07-09 21:26:36 -07001224 // Receive PR answer
Steve Anton18ee1d52017-09-11 11:32:35 -07001225 std::unique_ptr<typename T::Content> content2(
1226 CreateMediaContentWithStream(2));
Steve Anton3828c062017-12-06 10:34:51 -08001227 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001228 channel1_->SetRemoteContent(content2.get(), SdpType::kPrAnswer, err));
Tommic9625f02021-05-06 22:03:19 +02001229 EXPECT_TRUE(media_channel1()->HasSendStream(1));
1230 EXPECT_TRUE(media_channel1()->HasRecvStream(2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001231
Peter Thatchera6d24442015-07-09 21:26:36 -07001232 // Receive answer
Steve Anton18ee1d52017-09-11 11:32:35 -07001233 std::unique_ptr<typename T::Content> content3(
1234 CreateMediaContentWithStream(3));
1235 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001236 channel1_->SetRemoteContent(content3.get(), SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +02001237 EXPECT_TRUE(media_channel1()->HasSendStream(1));
1238 EXPECT_FALSE(media_channel1()->HasRecvStream(2));
1239 EXPECT_TRUE(media_channel1()->HasRecvStream(3));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001240 }
1241
zstein56162b92017-04-24 16:54:35 -07001242 void TestOnTransportReadyToSend() {
deadbeefac22f702017-01-12 21:59:29 -08001243 CreateChannels(0, 0);
Tommic9625f02021-05-06 22:03:19 +02001244 EXPECT_FALSE(media_channel1()->ready_to_send());
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001245
Tomas Gunnarssonad325862021-02-03 16:23:40 +01001246 network_thread_->PostTask(
Henrik Boström2deee4b2022-01-20 11:58:05 +01001247 [this] { channel1_->OnTransportReadyToSend(true); });
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001248 WaitForThreads();
Tommic9625f02021-05-06 22:03:19 +02001249 EXPECT_TRUE(media_channel1()->ready_to_send());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001250
Tomas Gunnarssonad325862021-02-03 16:23:40 +01001251 network_thread_->PostTask(
Henrik Boström2deee4b2022-01-20 11:58:05 +01001252 [this] { channel1_->OnTransportReadyToSend(false); });
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001253 WaitForThreads();
Tommic9625f02021-05-06 22:03:19 +02001254 EXPECT_FALSE(media_channel1()->ready_to_send());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001255 }
1256
skvladdc1c62c2016-03-16 19:07:43 -07001257 bool SetRemoteContentWithBitrateLimit(int remote_limit) {
1258 typename T::Content content;
1259 CreateContent(0, kPcmuCodec, kH264Codec, &content);
1260 content.set_bandwidth(remote_limit);
Steve Anton3828c062017-12-06 10:34:51 -08001261 return channel1_->SetRemoteContent(&content, SdpType::kOffer, NULL);
skvladdc1c62c2016-03-16 19:07:43 -07001262 }
1263
Danil Chapovalov66cadcc2018-06-19 16:47:43 +02001264 webrtc::RtpParameters BitrateLimitedParameters(absl::optional<int> limit) {
skvladdc1c62c2016-03-16 19:07:43 -07001265 webrtc::RtpParameters parameters;
1266 webrtc::RtpEncodingParameters encoding;
Mirko Bonadei05cf6be2019-01-31 21:38:12 +01001267 encoding.max_bitrate_bps = limit;
skvladdc1c62c2016-03-16 19:07:43 -07001268 parameters.encodings.push_back(encoding);
1269 return parameters;
1270 }
1271
1272 void VerifyMaxBitrate(const webrtc::RtpParameters& parameters,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +02001273 absl::optional<int> expected_bitrate) {
skvladdc1c62c2016-03-16 19:07:43 -07001274 EXPECT_EQ(1UL, parameters.encodings.size());
1275 EXPECT_EQ(expected_bitrate, parameters.encodings[0].max_bitrate_bps);
1276 }
1277
1278 void DefaultMaxBitrateIsUnlimited() {
1279 CreateChannels(0, 0);
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001280 std::string err;
Steve Anton3828c062017-12-06 10:34:51 -08001281 EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001282 SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02001283 EXPECT_EQ(media_channel1()->max_bps(), -1);
1284 VerifyMaxBitrate(media_channel1()->GetRtpSendParameters(kSsrc1),
Danil Chapovalov66cadcc2018-06-19 16:47:43 +02001285 absl::nullopt);
skvladdc1c62c2016-03-16 19:07:43 -07001286 }
1287
Zhi Huange830e682018-03-30 10:48:35 -07001288 // Test that when a channel gets new RtpTransport with a call to
Artem Titov880fa812021-07-30 22:30:23 +02001289 // `SetRtpTransport`, the socket options from the old RtpTransport is merged
Zhi Huange830e682018-03-30 10:48:35 -07001290 // with the options on the new one.
1291
Steve Anton8a63f782017-10-23 13:08:53 -07001292 // For example, audio and video may use separate socket options, but initially
1293 // be unbundled, then later become bundled. When this happens, their preferred
1294 // socket options should be merged to the underlying transport they share.
1295 void SocketOptionsMergedOnSetTransport() {
1296 constexpr int kSndBufSize = 4000;
1297 constexpr int kRcvBufSize = 8000;
1298
Zhi Huange830e682018-03-30 10:48:35 -07001299 CreateChannels(DTLS, DTLS);
Steve Anton8a63f782017-10-23 13:08:53 -07001300
Zhi Huange830e682018-03-30 10:48:35 -07001301 new_rtp_transport_ = CreateDtlsSrtpTransport(
Bjorn A Mellem3a1b9272019-05-24 16:13:08 -07001302 fake_rtp_dtls_transport2_.get(), fake_rtcp_dtls_transport2_.get());
Steve Anton8a63f782017-10-23 13:08:53 -07001303
Niels Möller92430882021-03-18 10:03:19 +01001304 bool rcv_success, send_success;
1305 int rcv_buf, send_buf;
1306 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Tommic9625f02021-05-06 22:03:19 +02001307 channel1_->SetOption(cricket::BaseChannel::ST_RTP,
1308 rtc::Socket::Option::OPT_SNDBUF, kSndBufSize);
1309 channel2_->SetOption(cricket::BaseChannel::ST_RTP,
1310 rtc::Socket::Option::OPT_RCVBUF, kRcvBufSize);
Tomas Gunnarssond9a51b02021-04-02 17:42:02 +02001311 channel1_->SetRtpTransport(new_rtp_transport_.get());
Niels Möller92430882021-03-18 10:03:19 +01001312 send_success = fake_rtp_dtls_transport2_->GetOption(
1313 rtc::Socket::Option::OPT_SNDBUF, &send_buf);
1314 rcv_success = fake_rtp_dtls_transport2_->GetOption(
1315 rtc::Socket::Option::OPT_RCVBUF, &rcv_buf);
1316 });
1317
1318 ASSERT_TRUE(send_success);
1319 EXPECT_EQ(kSndBufSize, send_buf);
1320 ASSERT_TRUE(rcv_success);
1321 EXPECT_EQ(kRcvBufSize, rcv_buf);
Steve Anton8a63f782017-10-23 13:08:53 -07001322 }
1323
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001324 void CreateSimulcastContent(const std::vector<std::string>& rids,
1325 typename T::Content* content) {
1326 std::vector<RidDescription> rid_descriptions;
Courtney Edwards134c6992020-03-03 11:36:35 +01001327 for (const std::string& name : rids) {
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001328 rid_descriptions.push_back(RidDescription(name, RidDirection::kSend));
1329 }
1330
1331 StreamParams stream;
1332 stream.set_rids(rid_descriptions);
1333 CreateContent(0, kPcmuCodec, kH264Codec, content);
1334 // This is for unified plan, so there can be only one StreamParams.
1335 content->mutable_streams().clear();
1336 content->AddStream(stream);
1337 }
1338
1339 void VerifySimulcastStreamParams(const StreamParams& expected,
1340 const typename T::Channel* channel) {
1341 const std::vector<StreamParams>& streams = channel->local_streams();
1342 ASSERT_EQ(1u, streams.size());
1343 const StreamParams& result = streams[0];
1344 EXPECT_EQ(expected.rids(), result.rids());
1345 EXPECT_TRUE(result.has_ssrcs());
1346 EXPECT_EQ(expected.rids().size() * 2, result.ssrcs.size());
1347 std::vector<uint32_t> primary_ssrcs;
1348 result.GetPrimarySsrcs(&primary_ssrcs);
1349 EXPECT_EQ(expected.rids().size(), primary_ssrcs.size());
1350 }
1351
1352 void TestUpdateLocalStreamsWithSimulcast() {
1353 CreateChannels(0, 0);
1354 typename T::Content content1, content2, content3;
1355 CreateSimulcastContent({"f", "h", "q"}, &content1);
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001356 std::string err;
1357 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001358 VerifySimulcastStreamParams(content1.streams()[0], channel1_.get());
1359 StreamParams stream1 = channel1_->local_streams()[0];
1360
1361 // Create a similar offer. SetLocalContent should not remove and add.
1362 CreateSimulcastContent({"f", "h", "q"}, &content2);
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001363 EXPECT_TRUE(channel1_->SetLocalContent(&content2, SdpType::kOffer, err));
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001364 VerifySimulcastStreamParams(content2.streams()[0], channel1_.get());
1365 StreamParams stream2 = channel1_->local_streams()[0];
1366 // Check that the streams are identical (SSRCs didn't change).
1367 EXPECT_EQ(stream1, stream2);
1368
1369 // Create third offer that has same RIDs in different order.
1370 CreateSimulcastContent({"f", "q", "h"}, &content3);
Tomas Gunnarssond908d742022-01-05 10:44:26 +00001371 EXPECT_TRUE(channel1_->SetLocalContent(&content3, SdpType::kOffer, err));
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001372 VerifySimulcastStreamParams(content3.streams()[0], channel1_.get());
1373 }
1374
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001375 protected:
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001376 void WaitForThreads() { WaitForThreads(rtc::ArrayView<rtc::Thread*>()); }
1377 static void ProcessThreadQueue(rtc::Thread* thread) {
1378 RTC_DCHECK(thread->IsCurrent());
1379 while (!thread->empty()) {
1380 thread->ProcessMessages(0);
1381 }
1382 }
Tommi1959f8f2021-04-26 10:20:19 +02001383 static void FlushCurrentThread() {
1384 rtc::Thread::Current()->ProcessMessages(0);
1385 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001386 void WaitForThreads(rtc::ArrayView<rtc::Thread*> threads) {
Artem Titov880fa812021-07-30 22:30:23 +02001387 // `threads` and current thread post packets to network thread.
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001388 for (rtc::Thread* thread : threads) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001389 thread->Invoke<void>(RTC_FROM_HERE,
1390 [thread] { ProcessThreadQueue(thread); });
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001391 }
1392 ProcessThreadQueue(rtc::Thread::Current());
1393 // Network thread move them around and post back to worker = current thread.
1394 if (!network_thread_->IsCurrent()) {
1395 network_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001396 RTC_FROM_HERE, [this] { ProcessThreadQueue(network_thread_); });
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001397 }
1398 // Worker thread = current Thread process received messages.
1399 ProcessThreadQueue(rtc::Thread::Current());
1400 }
Tommic9625f02021-05-06 22:03:19 +02001401
1402 typename T::MediaChannel* media_channel1() {
1403 RTC_DCHECK(channel1_);
1404 RTC_DCHECK(channel1_->media_channel());
1405 return static_cast<typename T::MediaChannel*>(channel1_->media_channel());
1406 }
1407
1408 typename T::MediaChannel* media_channel2() {
1409 RTC_DCHECK(channel2_);
1410 RTC_DCHECK(channel2_->media_channel());
1411 return static_cast<typename T::MediaChannel*>(channel2_->media_channel());
1412 }
1413
Peter Boström34fbfff2015-09-24 19:20:30 +02001414 // TODO(pbos): Remove playout from all media channels and let renderers mute
1415 // themselves.
1416 const bool verify_playout_;
Tommic9625f02021-05-06 22:03:19 +02001417 rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> network_thread_safety_ =
1418 webrtc::PendingTaskSafetyFlag::CreateDetached();
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001419 std::unique_ptr<rtc::Thread> network_thread_keeper_;
1420 rtc::Thread* network_thread_;
deadbeeff5346592017-01-24 21:51:21 -08001421 std::unique_ptr<cricket::FakeDtlsTransport> fake_rtp_dtls_transport1_;
1422 std::unique_ptr<cricket::FakeDtlsTransport> fake_rtcp_dtls_transport1_;
1423 std::unique_ptr<cricket::FakeDtlsTransport> fake_rtp_dtls_transport2_;
1424 std::unique_ptr<cricket::FakeDtlsTransport> fake_rtcp_dtls_transport2_;
1425 std::unique_ptr<rtc::FakePacketTransport> fake_rtp_packet_transport1_;
1426 std::unique_ptr<rtc::FakePacketTransport> fake_rtcp_packet_transport1_;
1427 std::unique_ptr<rtc::FakePacketTransport> fake_rtp_packet_transport2_;
1428 std::unique_ptr<rtc::FakePacketTransport> fake_rtcp_packet_transport2_;
Zhi Huange830e682018-03-30 10:48:35 -07001429 std::unique_ptr<webrtc::RtpTransportInternal> rtp_transport1_;
1430 std::unique_ptr<webrtc::RtpTransportInternal> rtp_transport2_;
1431 std::unique_ptr<webrtc::RtpTransportInternal> new_rtp_transport_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001432 cricket::FakeMediaEngine media_engine_;
kwiberg31022942016-03-11 14:18:21 -08001433 std::unique_ptr<typename T::Channel> channel1_;
1434 std::unique_ptr<typename T::Channel> channel2_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435 typename T::Content local_media_content1_;
1436 typename T::Content local_media_content2_;
1437 typename T::Content remote_media_content1_;
1438 typename T::Content remote_media_content2_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001439 // The RTP and RTCP packets to send in the tests.
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001440 rtc::Buffer rtp_packet_;
1441 rtc::Buffer rtcp_packet_;
Honghai Zhangcc411c02016-03-29 17:27:21 -07001442 cricket::CandidatePairInterface* last_selected_candidate_pair_;
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001443 rtc::UniqueRandomIdGenerator ssrc_generator_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001444};
1445
Yves Gerey665174f2018-06-19 15:03:05 +02001446template <>
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +02001447std::unique_ptr<cricket::VoiceChannel> ChannelTest<VoiceTraits>::CreateChannel(
1448 rtc::Thread* worker_thread,
1449 rtc::Thread* network_thread,
1450 std::unique_ptr<cricket::FakeVoiceMediaChannel> ch,
1451 webrtc::RtpTransportInternal* rtp_transport,
1452 int flags) {
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +02001453 rtc::Thread* signaling_thread = rtc::Thread::Current();
1454 auto channel = std::make_unique<cricket::VoiceChannel>(
1455 worker_thread, network_thread, signaling_thread, std::move(ch),
1456 cricket::CN_AUDIO, (flags & DTLS) != 0, webrtc::CryptoOptions(),
1457 &ssrc_generator_);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +01001458 network_thread->Invoke<void>(RTC_FROM_HERE, [&]() {
1459 RTC_DCHECK_RUN_ON(channel->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +01001460 channel->SetRtpTransport(rtp_transport);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +01001461 });
Sebastian Jansson1b83a9e2019-09-18 18:22:12 +02001462 return channel;
1463}
1464
1465template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001466void ChannelTest<VoiceTraits>::CreateContent(
1467 int flags,
1468 const cricket::AudioCodec& audio_codec,
1469 const cricket::VideoCodec& video_codec,
1470 cricket::AudioContentDescription* audio) {
1471 audio->AddCodec(audio_codec);
1472 audio->set_rtcp_mux((flags & RTCP_MUX) != 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473}
1474
Yves Gerey665174f2018-06-19 15:03:05 +02001475template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001476void ChannelTest<VoiceTraits>::CopyContent(
1477 const cricket::AudioContentDescription& source,
1478 cricket::AudioContentDescription* audio) {
1479 *audio = source;
1480}
1481
Yves Gerey665174f2018-06-19 15:03:05 +02001482template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001483bool ChannelTest<VoiceTraits>::CodecMatches(const cricket::AudioCodec& c1,
1484 const cricket::AudioCodec& c2) {
1485 return c1.name == c2.name && c1.clockrate == c2.clockrate &&
Yves Gerey665174f2018-06-19 15:03:05 +02001486 c1.bitrate == c2.bitrate && c1.channels == c2.channels;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001487}
1488
Peter Boström0c4e06b2015-10-07 12:23:21 +02001489template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001490void ChannelTest<VoiceTraits>::AddLegacyStreamInContent(
Peter Boström0c4e06b2015-10-07 12:23:21 +02001491 uint32_t ssrc,
1492 int flags,
1493 cricket::AudioContentDescription* audio) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494 audio->AddLegacyStream(ssrc);
1495}
1496
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001497class VoiceChannelSingleThreadTest : public ChannelTest<VoiceTraits> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001498 public:
solenberg1dd98f32015-09-10 01:57:14 -07001499 typedef ChannelTest<VoiceTraits> Base;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001500 VoiceChannelSingleThreadTest()
1501 : Base(true, kPcmuFrame, kRtcpReport, NetworkIsWorker::Yes) {}
1502};
1503
1504class VoiceChannelDoubleThreadTest : public ChannelTest<VoiceTraits> {
1505 public:
1506 typedef ChannelTest<VoiceTraits> Base;
1507 VoiceChannelDoubleThreadTest()
1508 : Base(true, kPcmuFrame, kRtcpReport, NetworkIsWorker::No) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001509};
1510
jbauch5869f502017-06-29 12:31:36 -07001511class VoiceChannelWithEncryptedRtpHeaderExtensionsSingleThreadTest
Yves Gerey665174f2018-06-19 15:03:05 +02001512 : public ChannelTest<VoiceTraits> {
jbauch5869f502017-06-29 12:31:36 -07001513 public:
1514 typedef ChannelTest<VoiceTraits> Base;
1515 VoiceChannelWithEncryptedRtpHeaderExtensionsSingleThreadTest()
Yves Gerey665174f2018-06-19 15:03:05 +02001516 : Base(true,
1517 kPcmuFrameWithExtensions,
1518 kRtcpReport,
1519 NetworkIsWorker::Yes) {}
jbauch5869f502017-06-29 12:31:36 -07001520};
1521
1522class VoiceChannelWithEncryptedRtpHeaderExtensionsDoubleThreadTest
Yves Gerey665174f2018-06-19 15:03:05 +02001523 : public ChannelTest<VoiceTraits> {
jbauch5869f502017-06-29 12:31:36 -07001524 public:
1525 typedef ChannelTest<VoiceTraits> Base;
1526 VoiceChannelWithEncryptedRtpHeaderExtensionsDoubleThreadTest()
Yves Gerey665174f2018-06-19 15:03:05 +02001527 : Base(true, kPcmuFrameWithExtensions, kRtcpReport, NetworkIsWorker::No) {
1528 }
jbauch5869f502017-06-29 12:31:36 -07001529};
1530
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001531// override to add NULL parameter
deadbeefcbecd352015-09-23 11:50:27 -07001532template <>
Steve Anton8699a322017-11-06 15:53:33 -08001533std::unique_ptr<cricket::VideoChannel> ChannelTest<VideoTraits>::CreateChannel(
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001534 rtc::Thread* worker_thread,
1535 rtc::Thread* network_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001536 std::unique_ptr<cricket::FakeVideoMediaChannel> ch,
Zhi Huange830e682018-03-30 10:48:35 -07001537 webrtc::RtpTransportInternal* rtp_transport,
jbauchcb560652016-08-04 05:20:32 -07001538 int flags) {
deadbeeff5346592017-01-24 21:51:21 -08001539 rtc::Thread* signaling_thread = rtc::Thread::Current();
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001540 auto channel = std::make_unique<cricket::VideoChannel>(
Steve Anton8699a322017-11-06 15:53:33 -08001541 worker_thread, network_thread, signaling_thread, std::move(ch),
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08001542 cricket::CN_VIDEO, (flags & DTLS) != 0, webrtc::CryptoOptions(),
1543 &ssrc_generator_);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +01001544 network_thread->Invoke<void>(RTC_FROM_HERE, [&]() {
1545 RTC_DCHECK_RUN_ON(channel->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 11:36:23 +01001546 channel->SetRtpTransport(rtp_transport);
Tomas Gunnarsson1933d3b2022-01-17 11:25:21 +01001547 });
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548 return channel;
1549}
1550
Yves Gerey665174f2018-06-19 15:03:05 +02001551template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552void ChannelTest<VideoTraits>::CreateContent(
1553 int flags,
1554 const cricket::AudioCodec& audio_codec,
1555 const cricket::VideoCodec& video_codec,
1556 cricket::VideoContentDescription* video) {
1557 video->AddCodec(video_codec);
1558 video->set_rtcp_mux((flags & RTCP_MUX) != 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559}
1560
Yves Gerey665174f2018-06-19 15:03:05 +02001561template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562void ChannelTest<VideoTraits>::CopyContent(
1563 const cricket::VideoContentDescription& source,
1564 cricket::VideoContentDescription* video) {
1565 *video = source;
1566}
1567
Yves Gerey665174f2018-06-19 15:03:05 +02001568template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569bool ChannelTest<VideoTraits>::CodecMatches(const cricket::VideoCodec& c1,
1570 const cricket::VideoCodec& c2) {
perkj26752742016-10-24 01:21:16 -07001571 return c1.name == c2.name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572}
1573
Peter Boström0c4e06b2015-10-07 12:23:21 +02001574template <>
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575void ChannelTest<VideoTraits>::AddLegacyStreamInContent(
Peter Boström0c4e06b2015-10-07 12:23:21 +02001576 uint32_t ssrc,
1577 int flags,
1578 cricket::VideoContentDescription* video) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579 video->AddLegacyStream(ssrc);
1580}
1581
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001582class VideoChannelSingleThreadTest : public ChannelTest<VideoTraits> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583 public:
solenberg1dd98f32015-09-10 01:57:14 -07001584 typedef ChannelTest<VideoTraits> Base;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001585 VideoChannelSingleThreadTest()
1586 : Base(false, kH264Packet, kRtcpReport, NetworkIsWorker::Yes) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587};
1588
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001589class VideoChannelDoubleThreadTest : public ChannelTest<VideoTraits> {
1590 public:
1591 typedef ChannelTest<VideoTraits> Base;
1592 VideoChannelDoubleThreadTest()
1593 : Base(false, kH264Packet, kRtcpReport, NetworkIsWorker::No) {}
1594};
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595
Kári Tristan Helgason8b35df72017-09-25 14:46:43 +02001596TEST_F(VoiceChannelSingleThreadTest, TestInit) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597 Base::TestInit();
Tommic9625f02021-05-06 22:03:19 +02001598 EXPECT_FALSE(media_channel1()->IsStreamMuted(0));
1599 EXPECT_TRUE(media_channel1()->dtmf_info_queue().empty());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001600}
1601
Danil Chapovalovdae07ba2016-05-14 01:43:50 +02001602TEST_F(VoiceChannelSingleThreadTest, TestDeinit) {
1603 Base::TestDeinit();
1604}
1605
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001606TEST_F(VoiceChannelSingleThreadTest, TestSetContents) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001607 Base::TestSetContents();
1608}
1609
Johannes Kron9190b822018-10-29 11:22:05 +01001610TEST_F(VoiceChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
1611 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
1612}
1613
1614TEST_F(VoiceChannelSingleThreadTest,
1615 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
1616 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
1617}
1618
1619TEST_F(VoiceChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
1620 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
1621}
1622
1623TEST_F(VoiceChannelSingleThreadTest,
1624 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
1625 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
1626}
1627
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001628TEST_F(VoiceChannelSingleThreadTest, TestSetContentsNullOffer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001629 Base::TestSetContentsNullOffer();
1630}
1631
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001632TEST_F(VoiceChannelSingleThreadTest, TestSetContentsRtcpMux) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001633 Base::TestSetContentsRtcpMux();
1634}
1635
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001636TEST_F(VoiceChannelSingleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001637 Base::TestSetContentsRtcpMux();
1638}
1639
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001640TEST_F(VoiceChannelSingleThreadTest, TestChangeStreamParamsInContent) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001641 Base::TestChangeStreamParamsInContent();
1642}
1643
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001644TEST_F(VoiceChannelSingleThreadTest, TestPlayoutAndSendingStates) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001645 Base::TestPlayoutAndSendingStates();
1646}
1647
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001648TEST_F(VoiceChannelSingleThreadTest, TestMediaContentDirection) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001649 Base::TestMediaContentDirection();
1650}
1651
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001652TEST_F(VoiceChannelSingleThreadTest, TestNetworkRouteChanges) {
Honghai Zhangcc411c02016-03-29 17:27:21 -07001653 Base::TestNetworkRouteChanges();
1654}
1655
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001656TEST_F(VoiceChannelSingleThreadTest, TestCallSetup) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001657 Base::TestCallSetup();
1658}
1659
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001660TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001661 Base::SendRtpToRtp();
1662}
1663
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001664TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 10:48:35 -07001665 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666}
1667
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001668TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 10:48:35 -07001669 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
deadbeeff5346592017-01-24 21:51:21 -08001670}
1671
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001672TEST_F(VoiceChannelSingleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001673 Base::SendEarlyMediaUsingRtcpMuxSrtp();
1674}
1675
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001676TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtpOnThread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001677 Base::SendRtpToRtpOnThread();
1678}
1679
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001680TEST_F(VoiceChannelSingleThreadTest, SendWithWritabilityLoss) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681 Base::SendWithWritabilityLoss();
1682}
1683
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001684TEST_F(VoiceChannelSingleThreadTest, TestSetContentFailure) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685 Base::TestSetContentFailure();
1686}
1687
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001688TEST_F(VoiceChannelSingleThreadTest, TestSendTwoOffers) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689 Base::TestSendTwoOffers();
1690}
1691
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001692TEST_F(VoiceChannelSingleThreadTest, TestReceiveTwoOffers) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001693 Base::TestReceiveTwoOffers();
1694}
1695
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001696TEST_F(VoiceChannelSingleThreadTest, TestSendPrAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001697 Base::TestSendPrAnswer();
1698}
1699
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001700TEST_F(VoiceChannelSingleThreadTest, TestReceivePrAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001701 Base::TestReceivePrAnswer();
1702}
1703
zstein56162b92017-04-24 16:54:35 -07001704TEST_F(VoiceChannelSingleThreadTest, TestOnTransportReadyToSend) {
1705 Base::TestOnTransportReadyToSend();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001706}
1707
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001708TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundle) {
tfarina5237aaf2015-11-10 23:44:30 -08001709 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001710}
1711
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001712TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleSecure) {
tfarina5237aaf2015-11-10 23:44:30 -08001713 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, true);
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001714}
1715
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001716TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleWithRtcpMux) {
tfarina5237aaf2015-11-10 23:44:30 -08001717 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, false);
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001718}
1719
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001720TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
tfarina5237aaf2015-11-10 23:44:30 -08001721 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001722}
1723
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001724TEST_F(VoiceChannelSingleThreadTest, DefaultMaxBitrateIsUnlimited) {
skvlade0d46372016-04-07 22:59:22 -07001725 Base::DefaultMaxBitrateIsUnlimited();
skvladdc1c62c2016-03-16 19:07:43 -07001726}
1727
Steve Anton8a63f782017-10-23 13:08:53 -07001728TEST_F(VoiceChannelSingleThreadTest, SocketOptionsMergedOnSetTransport) {
1729 Base::SocketOptionsMergedOnSetTransport();
1730}
1731
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001732// VoiceChannelDoubleThreadTest
1733TEST_F(VoiceChannelDoubleThreadTest, TestInit) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734 Base::TestInit();
Tommic9625f02021-05-06 22:03:19 +02001735 EXPECT_FALSE(media_channel1()->IsStreamMuted(0));
1736 EXPECT_TRUE(media_channel1()->dtmf_info_queue().empty());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001737}
1738
Danil Chapovalovdae07ba2016-05-14 01:43:50 +02001739TEST_F(VoiceChannelDoubleThreadTest, TestDeinit) {
1740 Base::TestDeinit();
1741}
1742
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001743TEST_F(VoiceChannelDoubleThreadTest, TestSetContents) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001744 Base::TestSetContents();
1745}
1746
Johannes Kron9190b822018-10-29 11:22:05 +01001747TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
1748 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
1749}
1750
1751TEST_F(VoiceChannelDoubleThreadTest,
1752 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
1753 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
1754}
1755
1756TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
1757 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
1758}
1759
1760TEST_F(VoiceChannelDoubleThreadTest,
1761 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
1762 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
1763}
1764
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001765TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsNullOffer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766 Base::TestSetContentsNullOffer();
1767}
1768
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001769TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsRtcpMux) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770 Base::TestSetContentsRtcpMux();
1771}
1772
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001773TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774 Base::TestSetContentsRtcpMux();
1775}
1776
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001777TEST_F(VoiceChannelDoubleThreadTest, TestChangeStreamParamsInContent) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778 Base::TestChangeStreamParamsInContent();
1779}
1780
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001781TEST_F(VoiceChannelDoubleThreadTest, TestPlayoutAndSendingStates) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001782 Base::TestPlayoutAndSendingStates();
1783}
1784
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001785TEST_F(VoiceChannelDoubleThreadTest, TestMediaContentDirection) {
1786 Base::TestMediaContentDirection();
1787}
1788
1789TEST_F(VoiceChannelDoubleThreadTest, TestNetworkRouteChanges) {
1790 Base::TestNetworkRouteChanges();
1791}
1792
1793TEST_F(VoiceChannelDoubleThreadTest, TestCallSetup) {
1794 Base::TestCallSetup();
1795}
1796
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001797TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtp) {
1798 Base::SendRtpToRtp();
1799}
1800
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001801TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 10:48:35 -07001802 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001803}
1804
1805TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 10:48:35 -07001806 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
deadbeeff5346592017-01-24 21:51:21 -08001807}
1808
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001809TEST_F(VoiceChannelDoubleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
1810 Base::SendEarlyMediaUsingRtcpMuxSrtp();
1811}
1812
1813TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtpOnThread) {
1814 Base::SendRtpToRtpOnThread();
1815}
1816
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001817TEST_F(VoiceChannelDoubleThreadTest, SendWithWritabilityLoss) {
1818 Base::SendWithWritabilityLoss();
1819}
1820
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001821TEST_F(VoiceChannelDoubleThreadTest, TestSetContentFailure) {
1822 Base::TestSetContentFailure();
1823}
1824
1825TEST_F(VoiceChannelDoubleThreadTest, TestSendTwoOffers) {
1826 Base::TestSendTwoOffers();
1827}
1828
1829TEST_F(VoiceChannelDoubleThreadTest, TestReceiveTwoOffers) {
1830 Base::TestReceiveTwoOffers();
1831}
1832
1833TEST_F(VoiceChannelDoubleThreadTest, TestSendPrAnswer) {
1834 Base::TestSendPrAnswer();
1835}
1836
1837TEST_F(VoiceChannelDoubleThreadTest, TestReceivePrAnswer) {
1838 Base::TestReceivePrAnswer();
1839}
1840
zstein56162b92017-04-24 16:54:35 -07001841TEST_F(VoiceChannelDoubleThreadTest, TestOnTransportReadyToSend) {
1842 Base::TestOnTransportReadyToSend();
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001843}
1844
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001845TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundle) {
1846 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, false);
1847}
1848
1849TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleSecure) {
1850 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), false, true);
1851}
1852
1853TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleWithRtcpMux) {
1854 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, false);
1855}
1856
1857TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
1858 Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, true);
1859}
1860
1861TEST_F(VoiceChannelDoubleThreadTest, DefaultMaxBitrateIsUnlimited) {
1862 Base::DefaultMaxBitrateIsUnlimited();
1863}
1864
Steve Anton8a63f782017-10-23 13:08:53 -07001865TEST_F(VoiceChannelDoubleThreadTest, SocketOptionsMergedOnSetTransport) {
1866 Base::SocketOptionsMergedOnSetTransport();
1867}
1868
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001869// VideoChannelSingleThreadTest
1870TEST_F(VideoChannelSingleThreadTest, TestInit) {
1871 Base::TestInit();
1872}
1873
Danil Chapovalovdae07ba2016-05-14 01:43:50 +02001874TEST_F(VideoChannelSingleThreadTest, TestDeinit) {
1875 Base::TestDeinit();
1876}
1877
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001878TEST_F(VideoChannelSingleThreadTest, TestSetContents) {
1879 Base::TestSetContents();
1880}
1881
Johannes Kron9190b822018-10-29 11:22:05 +01001882TEST_F(VideoChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
1883 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
1884}
1885
1886TEST_F(VideoChannelSingleThreadTest,
1887 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
1888 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
1889}
1890
1891TEST_F(VideoChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
1892 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
1893}
1894
1895TEST_F(VideoChannelSingleThreadTest,
1896 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
1897 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
1898}
1899
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001900TEST_F(VideoChannelSingleThreadTest, TestSetContentsNullOffer) {
1901 Base::TestSetContentsNullOffer();
1902}
1903
1904TEST_F(VideoChannelSingleThreadTest, TestSetContentsRtcpMux) {
1905 Base::TestSetContentsRtcpMux();
1906}
1907
1908TEST_F(VideoChannelSingleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
1909 Base::TestSetContentsRtcpMux();
1910}
1911
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001912TEST_F(VideoChannelSingleThreadTest, TestChangeStreamParamsInContent) {
1913 Base::TestChangeStreamParamsInContent();
1914}
1915
1916TEST_F(VideoChannelSingleThreadTest, TestPlayoutAndSendingStates) {
1917 Base::TestPlayoutAndSendingStates();
1918}
1919
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001920TEST_F(VideoChannelSingleThreadTest, TestMediaContentDirection) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001921 Base::TestMediaContentDirection();
1922}
1923
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001924TEST_F(VideoChannelSingleThreadTest, TestNetworkRouteChanges) {
Honghai Zhangcc411c02016-03-29 17:27:21 -07001925 Base::TestNetworkRouteChanges();
1926}
1927
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001928TEST_F(VideoChannelSingleThreadTest, TestCallSetup) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929 Base::TestCallSetup();
1930}
1931
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001932TEST_F(VideoChannelSingleThreadTest, SendRtpToRtp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001933 Base::SendRtpToRtp();
1934}
1935
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001936TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 10:48:35 -07001937 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001938}
1939
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001940TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 10:48:35 -07001941 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001942}
1943
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001944TEST_F(VideoChannelSingleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001945 Base::SendEarlyMediaUsingRtcpMuxSrtp();
1946}
1947
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001948TEST_F(VideoChannelSingleThreadTest, SendRtpToRtpOnThread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001949 Base::SendRtpToRtpOnThread();
1950}
1951
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001952TEST_F(VideoChannelSingleThreadTest, SendWithWritabilityLoss) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001953 Base::SendWithWritabilityLoss();
1954}
1955
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001956TEST_F(VideoChannelSingleThreadTest, TestSetContentFailure) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001957 Base::TestSetContentFailure();
1958}
1959
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001960TEST_F(VideoChannelSingleThreadTest, TestSendTwoOffers) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001961 Base::TestSendTwoOffers();
1962}
1963
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001964TEST_F(VideoChannelSingleThreadTest, TestReceiveTwoOffers) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001965 Base::TestReceiveTwoOffers();
1966}
1967
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001968TEST_F(VideoChannelSingleThreadTest, TestSendPrAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001969 Base::TestSendPrAnswer();
1970}
1971
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001972TEST_F(VideoChannelSingleThreadTest, TestReceivePrAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001973 Base::TestReceivePrAnswer();
1974}
1975
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001976TEST_F(VideoChannelSingleThreadTest, SendBundleToBundle) {
tfarina5237aaf2015-11-10 23:44:30 -08001977 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001978}
1979
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001980TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleSecure) {
tfarina5237aaf2015-11-10 23:44:30 -08001981 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, true);
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001982}
1983
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001984TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleWithRtcpMux) {
tfarina5237aaf2015-11-10 23:44:30 -08001985 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, false);
buildbot@webrtc.org5ee0f052014-05-05 20:18:08 +00001986}
1987
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001988TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
tfarina5237aaf2015-11-10 23:44:30 -08001989 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001990}
1991
zstein56162b92017-04-24 16:54:35 -07001992TEST_F(VideoChannelSingleThreadTest, TestOnTransportReadyToSend) {
1993 Base::TestOnTransportReadyToSend();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001994}
1995
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001996TEST_F(VideoChannelSingleThreadTest, DefaultMaxBitrateIsUnlimited) {
skvladdc1c62c2016-03-16 19:07:43 -07001997 Base::DefaultMaxBitrateIsUnlimited();
1998}
1999
Steve Anton8a63f782017-10-23 13:08:53 -07002000TEST_F(VideoChannelSingleThreadTest, SocketOptionsMergedOnSetTransport) {
2001 Base::SocketOptionsMergedOnSetTransport();
2002}
2003
Amit Hilbuchbcd39d42019-01-25 17:13:56 -08002004TEST_F(VideoChannelSingleThreadTest, UpdateLocalStreamsWithSimulcast) {
2005 Base::TestUpdateLocalStreamsWithSimulcast();
2006}
2007
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002008TEST_F(VideoChannelSingleThreadTest, TestSetLocalOfferWithPacketization) {
2009 const cricket::VideoCodec kVp8Codec(97, "VP8");
2010 cricket::VideoCodec vp9_codec(98, "VP9");
2011 vp9_codec.packetization = cricket::kPacketizationParamRaw;
2012 cricket::VideoContentDescription video;
2013 video.set_codecs({kVp8Codec, vp9_codec});
2014
2015 CreateChannels(0, 0);
2016
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002017 std::string err;
2018 EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, err));
Tommic9625f02021-05-06 22:03:19 +02002019 EXPECT_THAT(media_channel1()->send_codecs(), testing::IsEmpty());
2020 ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2));
2021 EXPECT_TRUE(media_channel1()->recv_codecs()[0].Matches(kVp8Codec));
2022 EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
2023 EXPECT_TRUE(media_channel1()->recv_codecs()[1].Matches(vp9_codec));
2024 EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization,
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002025 cricket::kPacketizationParamRaw);
2026}
2027
2028TEST_F(VideoChannelSingleThreadTest, TestSetRemoteOfferWithPacketization) {
2029 const cricket::VideoCodec kVp8Codec(97, "VP8");
2030 cricket::VideoCodec vp9_codec(98, "VP9");
2031 vp9_codec.packetization = cricket::kPacketizationParamRaw;
2032 cricket::VideoContentDescription video;
2033 video.set_codecs({kVp8Codec, vp9_codec});
2034
2035 CreateChannels(0, 0);
2036
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002037 std::string err;
2038 EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kOffer, err));
2039 EXPECT_TRUE(err.empty());
Tommic9625f02021-05-06 22:03:19 +02002040 EXPECT_THAT(media_channel1()->recv_codecs(), testing::IsEmpty());
2041 ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2));
2042 EXPECT_TRUE(media_channel1()->send_codecs()[0].Matches(kVp8Codec));
2043 EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
2044 EXPECT_TRUE(media_channel1()->send_codecs()[1].Matches(vp9_codec));
2045 EXPECT_EQ(media_channel1()->send_codecs()[1].packetization,
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002046 cricket::kPacketizationParamRaw);
2047}
2048
2049TEST_F(VideoChannelSingleThreadTest, TestSetAnswerWithPacketization) {
2050 const cricket::VideoCodec kVp8Codec(97, "VP8");
2051 cricket::VideoCodec vp9_codec(98, "VP9");
2052 vp9_codec.packetization = cricket::kPacketizationParamRaw;
2053 cricket::VideoContentDescription video;
2054 video.set_codecs({kVp8Codec, vp9_codec});
2055
2056 CreateChannels(0, 0);
2057
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002058 std::string err;
2059 EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, err));
2060 EXPECT_TRUE(err.empty());
2061 EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kAnswer, err));
2062 EXPECT_TRUE(err.empty());
Tommic9625f02021-05-06 22:03:19 +02002063 ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2));
2064 EXPECT_TRUE(media_channel1()->recv_codecs()[0].Matches(kVp8Codec));
2065 EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
2066 EXPECT_TRUE(media_channel1()->recv_codecs()[1].Matches(vp9_codec));
2067 EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization,
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002068 cricket::kPacketizationParamRaw);
Tommic9625f02021-05-06 22:03:19 +02002069 EXPECT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2));
2070 EXPECT_TRUE(media_channel1()->send_codecs()[0].Matches(kVp8Codec));
2071 EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
2072 EXPECT_TRUE(media_channel1()->send_codecs()[1].Matches(vp9_codec));
2073 EXPECT_EQ(media_channel1()->send_codecs()[1].packetization,
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002074 cricket::kPacketizationParamRaw);
2075}
2076
2077TEST_F(VideoChannelSingleThreadTest, TestSetLocalAnswerWithoutPacketization) {
2078 const cricket::VideoCodec kLocalCodec(98, "VP8");
2079 cricket::VideoCodec remote_codec(99, "VP8");
2080 remote_codec.packetization = cricket::kPacketizationParamRaw;
2081 cricket::VideoContentDescription local_video;
2082 local_video.set_codecs({kLocalCodec});
2083 cricket::VideoContentDescription remote_video;
2084 remote_video.set_codecs({remote_codec});
2085
2086 CreateChannels(0, 0);
2087
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002088 std::string err;
2089 EXPECT_TRUE(channel1_->SetRemoteContent(&remote_video, SdpType::kOffer, err));
2090 EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +02002091 ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1));
2092 EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
2093 ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1));
2094 EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002095}
2096
2097TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) {
2098 cricket::VideoCodec local_codec(98, "VP8");
2099 local_codec.packetization = cricket::kPacketizationParamRaw;
2100 const cricket::VideoCodec kRemoteCodec(99, "VP8");
2101 cricket::VideoContentDescription local_video;
2102 local_video.set_codecs({local_codec});
2103 cricket::VideoContentDescription remote_video;
2104 remote_video.set_codecs({kRemoteCodec});
2105
2106 CreateChannels(0, 0);
2107
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002108 std::string err;
2109 EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kOffer, err));
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002110 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002111 channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, err));
Tommic9625f02021-05-06 22:03:19 +02002112 ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1));
2113 EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
2114 ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1));
2115 EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002116}
2117
2118TEST_F(VideoChannelSingleThreadTest,
2119 TestSetRemoteAnswerWithInvalidPacketization) {
2120 cricket::VideoCodec local_codec(98, "VP8");
2121 local_codec.packetization = cricket::kPacketizationParamRaw;
2122 cricket::VideoCodec remote_codec(99, "VP8");
2123 remote_codec.packetization = "unknownpacketizationattributevalue";
2124 cricket::VideoContentDescription local_video;
2125 local_video.set_codecs({local_codec});
2126 cricket::VideoContentDescription remote_video;
2127 remote_video.set_codecs({remote_codec});
2128
2129 CreateChannels(0, 0);
2130
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002131 std::string err;
2132 EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kOffer, err));
2133 EXPECT_TRUE(err.empty());
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002134 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002135 channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, err));
2136 EXPECT_FALSE(err.empty());
Tommic9625f02021-05-06 22:03:19 +02002137 ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1));
2138 EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization,
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002139 cricket::kPacketizationParamRaw);
Tommic9625f02021-05-06 22:03:19 +02002140 EXPECT_THAT(media_channel1()->send_codecs(), testing::IsEmpty());
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002141}
2142
2143TEST_F(VideoChannelSingleThreadTest,
2144 TestSetLocalAnswerWithInvalidPacketization) {
2145 cricket::VideoCodec local_codec(98, "VP8");
2146 local_codec.packetization = cricket::kPacketizationParamRaw;
2147 const cricket::VideoCodec kRemoteCodec(99, "VP8");
2148 cricket::VideoContentDescription local_video;
2149 local_video.set_codecs({local_codec});
2150 cricket::VideoContentDescription remote_video;
2151 remote_video.set_codecs({kRemoteCodec});
2152
2153 CreateChannels(0, 0);
2154
Tomas Gunnarssond908d742022-01-05 10:44:26 +00002155 std::string err;
2156 EXPECT_TRUE(channel1_->SetRemoteContent(&remote_video, SdpType::kOffer, err));
2157 EXPECT_TRUE(err.empty());
2158 EXPECT_FALSE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, err));
2159 EXPECT_FALSE(err.empty());
Tommic9625f02021-05-06 22:03:19 +02002160 EXPECT_THAT(media_channel1()->recv_codecs(), testing::IsEmpty());
2161 ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1));
2162 EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02002163}
2164
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002165// VideoChannelDoubleThreadTest
2166TEST_F(VideoChannelDoubleThreadTest, TestInit) {
2167 Base::TestInit();
2168}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169
Danil Chapovalovdae07ba2016-05-14 01:43:50 +02002170TEST_F(VideoChannelDoubleThreadTest, TestDeinit) {
2171 Base::TestDeinit();
2172}
2173
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002174TEST_F(VideoChannelDoubleThreadTest, TestSetContents) {
2175 Base::TestSetContents();
2176}
2177
Johannes Kron9190b822018-10-29 11:22:05 +01002178TEST_F(VideoChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
2179 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
2180}
2181
2182TEST_F(VideoChannelDoubleThreadTest,
2183 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
2184 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
2185}
2186
2187TEST_F(VideoChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
2188 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
2189}
2190
2191TEST_F(VideoChannelDoubleThreadTest,
2192 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
2193 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
2194}
2195
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002196TEST_F(VideoChannelDoubleThreadTest, TestSetContentsNullOffer) {
2197 Base::TestSetContentsNullOffer();
2198}
2199
2200TEST_F(VideoChannelDoubleThreadTest, TestSetContentsRtcpMux) {
2201 Base::TestSetContentsRtcpMux();
2202}
2203
2204TEST_F(VideoChannelDoubleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
2205 Base::TestSetContentsRtcpMux();
2206}
2207
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002208TEST_F(VideoChannelDoubleThreadTest, TestChangeStreamParamsInContent) {
2209 Base::TestChangeStreamParamsInContent();
2210}
2211
2212TEST_F(VideoChannelDoubleThreadTest, TestPlayoutAndSendingStates) {
2213 Base::TestPlayoutAndSendingStates();
2214}
2215
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002216TEST_F(VideoChannelDoubleThreadTest, TestMediaContentDirection) {
2217 Base::TestMediaContentDirection();
2218}
2219
2220TEST_F(VideoChannelDoubleThreadTest, TestNetworkRouteChanges) {
2221 Base::TestNetworkRouteChanges();
2222}
2223
2224TEST_F(VideoChannelDoubleThreadTest, TestCallSetup) {
2225 Base::TestCallSetup();
2226}
2227
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002228TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtp) {
2229 Base::SendRtpToRtp();
2230}
2231
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002232TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 10:48:35 -07002233 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002234}
2235
2236TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 10:48:35 -07002237 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002238}
2239
2240TEST_F(VideoChannelDoubleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
2241 Base::SendEarlyMediaUsingRtcpMuxSrtp();
2242}
2243
2244TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtpOnThread) {
2245 Base::SendRtpToRtpOnThread();
2246}
2247
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002248TEST_F(VideoChannelDoubleThreadTest, SendWithWritabilityLoss) {
2249 Base::SendWithWritabilityLoss();
2250}
2251
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002252TEST_F(VideoChannelDoubleThreadTest, TestSetContentFailure) {
2253 Base::TestSetContentFailure();
2254}
2255
2256TEST_F(VideoChannelDoubleThreadTest, TestSendTwoOffers) {
2257 Base::TestSendTwoOffers();
2258}
2259
2260TEST_F(VideoChannelDoubleThreadTest, TestReceiveTwoOffers) {
2261 Base::TestReceiveTwoOffers();
2262}
2263
2264TEST_F(VideoChannelDoubleThreadTest, TestSendPrAnswer) {
2265 Base::TestSendPrAnswer();
2266}
2267
2268TEST_F(VideoChannelDoubleThreadTest, TestReceivePrAnswer) {
2269 Base::TestReceivePrAnswer();
2270}
2271
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002272TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundle) {
2273 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, false);
2274}
2275
2276TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleSecure) {
2277 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), false, true);
2278}
2279
2280TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleWithRtcpMux) {
2281 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, false);
2282}
2283
2284TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
2285 Base::SendBundleToBundle(kVideoPts, arraysize(kVideoPts), true, true);
2286}
2287
zstein56162b92017-04-24 16:54:35 -07002288TEST_F(VideoChannelDoubleThreadTest, TestOnTransportReadyToSend) {
2289 Base::TestOnTransportReadyToSend();
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002290}
2291
Danil Chapovalov33b01f22016-05-11 19:55:27 +02002292TEST_F(VideoChannelDoubleThreadTest, DefaultMaxBitrateIsUnlimited) {
2293 Base::DefaultMaxBitrateIsUnlimited();
2294}
2295
Steve Anton8a63f782017-10-23 13:08:53 -07002296TEST_F(VideoChannelDoubleThreadTest, SocketOptionsMergedOnSetTransport) {
2297 Base::SocketOptionsMergedOnSetTransport();
2298}
2299
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002301// TODO(pthatcher): TestSetReceiver?