blob: c3a41e4d111034d5f5bdcb99ccee3d834bfe54c8 [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
11// Disable for TSan v2, see
12// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
13#if !defined(THREAD_SANITIZER)
14
15#include <stdio.h>
16
17#include <algorithm>
18#include <functional>
19#include <list>
20#include <map>
21#include <memory>
22#include <utility>
23#include <vector>
24
Karl Wiberg1b0eae32017-10-17 14:48:54 +020025#include "api/audio_codecs/builtin_audio_decoder_factory.h"
26#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "api/fakemetricsobserver.h"
28#include "api/mediastreaminterface.h"
29#include "api/peerconnectioninterface.h"
Steve Anton8c0f7a72017-10-03 10:03:10 -070030#include "api/peerconnectionproxy.h"
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010031#include "api/rtpreceiverinterface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "api/test/fakeconstraints.h"
Anders Carlsson67537952018-05-03 11:28:29 +020033#include "api/video_codecs/builtin_video_decoder_factory.h"
34#include "api/video_codecs/builtin_video_encoder_factory.h"
35#include "api/video_codecs/sdp_video_format.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "media/engine/fakewebrtcvideoengine.h"
37#include "p2p/base/p2pconstants.h"
38#include "p2p/base/portinterface.h"
Steve Antonede9ca52017-10-16 13:04:27 -070039#include "p2p/base/teststunserver.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020040#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "p2p/base/testturnserver.h"
42#include "p2p/client/basicportallocator.h"
43#include "pc/dtmfsender.h"
44#include "pc/localaudiosource.h"
45#include "pc/mediasession.h"
46#include "pc/peerconnection.h"
47#include "pc/peerconnectionfactory.h"
Seth Hampson2f0d7022018-02-20 11:54:42 -080048#include "pc/rtpmediautils.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080049#include "pc/sessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020050#include "pc/test/fakeaudiocapturemodule.h"
51#include "pc/test/fakeperiodicvideocapturer.h"
52#include "pc/test/fakertccertificategenerator.h"
53#include "pc/test/fakevideotrackrenderer.h"
54#include "pc/test/mockpeerconnectionobservers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "rtc_base/fakenetwork.h"
Steve Antonede9ca52017-10-16 13:04:27 -070056#include "rtc_base/firewallsocketserver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020057#include "rtc_base/gunit.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "rtc_base/virtualsocketserver.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020059#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070060
61using cricket::ContentInfo;
62using cricket::FakeWebRtcVideoDecoder;
63using cricket::FakeWebRtcVideoDecoderFactory;
64using cricket::FakeWebRtcVideoEncoder;
65using cricket::FakeWebRtcVideoEncoderFactory;
66using cricket::MediaContentDescription;
Steve Antondf527fd2018-04-27 15:52:03 -070067using cricket::StreamParams;
Steve Antonede9ca52017-10-16 13:04:27 -070068using rtc::SocketAddress;
Seth Hampson2f0d7022018-02-20 11:54:42 -080069using ::testing::Combine;
Steve Antonede9ca52017-10-16 13:04:27 -070070using ::testing::ElementsAre;
71using ::testing::Values;
deadbeef1dcb1642017-03-29 21:08:16 -070072using webrtc::DataBuffer;
73using webrtc::DataChannelInterface;
74using webrtc::DtmfSender;
75using webrtc::DtmfSenderInterface;
76using webrtc::DtmfSenderObserverInterface;
77using webrtc::FakeConstraints;
Steve Anton15324772018-01-16 10:26:49 -080078using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-29 21:08:16 -070079using webrtc::MediaConstraintsInterface;
80using webrtc::MediaStreamInterface;
81using webrtc::MediaStreamTrackInterface;
82using webrtc::MockCreateSessionDescriptionObserver;
83using webrtc::MockDataChannelObserver;
84using webrtc::MockSetSessionDescriptionObserver;
85using webrtc::MockStatsObserver;
86using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 10:03:10 -070087using webrtc::PeerConnection;
deadbeef1dcb1642017-03-29 21:08:16 -070088using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-24 18:32:57 -080089using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070090using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 10:03:10 -070091using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 10:26:49 -080092using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 15:18:41 -070093using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-24 18:32:57 -080094using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010095using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 11:54:42 -080096using webrtc::RtpSenderInterface;
97using webrtc::RtpTransceiverDirection;
98using webrtc::RtpTransceiverInit;
99using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-17 17:41:02 -0800100using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 10:27:41 -0800101using webrtc::SdpType;
deadbeef1dcb1642017-03-29 21:08:16 -0700102using webrtc::SessionDescriptionInterface;
103using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 10:26:49 -0800104using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-29 21:08:16 -0700105
106namespace {
107
108static const int kDefaultTimeout = 10000;
109static const int kMaxWaitForStatsMs = 3000;
110static const int kMaxWaitForActivationMs = 5000;
111static const int kMaxWaitForFramesMs = 10000;
112// Default number of audio/video frames to wait for before considering a test
113// successful.
114static const int kDefaultExpectedAudioFrameCount = 3;
115static const int kDefaultExpectedVideoFrameCount = 3;
116
deadbeef1dcb1642017-03-29 21:08:16 -0700117static const char kDataChannelLabel[] = "data_channel";
118
119// SRTP cipher name negotiated by the tests. This must be updated if the
120// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700121static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700122static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
123
Steve Antonede9ca52017-10-16 13:04:27 -0700124static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
125
deadbeef1dcb1642017-03-29 21:08:16 -0700126// Helper function for constructing offer/answer options to initiate an ICE
127// restart.
128PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
129 PeerConnectionInterface::RTCOfferAnswerOptions options;
130 options.ice_restart = true;
131 return options;
132}
133
deadbeefd8ad7882017-04-18 16:01:17 -0700134// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
135// attribute from received SDP, simulating a legacy endpoint.
136void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
137 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800138 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700139 }
140 desc->set_msid_supported(false);
141}
142
Seth Hampson5897a6e2018-04-03 11:16:33 -0700143// Removes all stream information besides the stream ids, simulating an
144// endpoint that only signals a=msid lines to convey stream_ids.
145void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
146 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700147 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700148 std::vector<std::string> stream_ids;
149 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700150 const StreamParams& first_stream =
151 content.media_description()->streams()[0];
152 track_id = first_stream.id;
153 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700154 }
155 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700156 StreamParams new_stream;
157 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700158 new_stream.set_stream_ids(stream_ids);
159 content.media_description()->AddStream(new_stream);
160 }
161}
162
zhihuangf8164932017-05-19 13:09:47 -0700163int FindFirstMediaStatsIndexByKind(
164 const std::string& kind,
165 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
166 media_stats_vec) {
167 for (size_t i = 0; i < media_stats_vec.size(); i++) {
168 if (media_stats_vec[i]->kind.ValueToString() == kind) {
169 return i;
170 }
171 }
172 return -1;
173}
174
deadbeef1dcb1642017-03-29 21:08:16 -0700175class SignalingMessageReceiver {
176 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800177 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700178 virtual void ReceiveIceMessage(const std::string& sdp_mid,
179 int sdp_mline_index,
180 const std::string& msg) = 0;
181
182 protected:
183 SignalingMessageReceiver() {}
184 virtual ~SignalingMessageReceiver() {}
185};
186
187class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
188 public:
189 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
190 : expected_media_type_(media_type) {}
191
192 void OnFirstPacketReceived(cricket::MediaType media_type) override {
193 ASSERT_EQ(expected_media_type_, media_type);
194 first_packet_received_ = true;
195 }
196
197 bool first_packet_received() const { return first_packet_received_; }
198
199 virtual ~MockRtpReceiverObserver() {}
200
201 private:
202 bool first_packet_received_ = false;
203 cricket::MediaType expected_media_type_;
204};
205
206// Helper class that wraps a peer connection, observes it, and can accept
207// signaling messages from another wrapper.
208//
209// Uses a fake network, fake A/V capture, and optionally fake
210// encoders/decoders, though they aren't used by default since they don't
211// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700212// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800213// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700214class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800215 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700216 public:
217 // Different factory methods for convenience.
218 // TODO(deadbeef): Could use the pattern of:
219 //
220 // PeerConnectionWrapper =
221 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
222 //
223 // To reduce some code duplication.
224 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
225 const std::string& debug_name,
226 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
227 rtc::Thread* network_thread,
228 rtc::Thread* worker_thread) {
229 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
230 if (!client->Init(nullptr, nullptr, nullptr, std::move(cert_generator),
231 network_thread, worker_thread)) {
232 delete client;
233 return nullptr;
234 }
235 return client;
236 }
237
deadbeef2f425aa2017-04-14 10:41:32 -0700238 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
239 return peer_connection_factory_.get();
240 }
241
deadbeef1dcb1642017-03-29 21:08:16 -0700242 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
243
244 // If a signaling message receiver is set (via ConnectFakeSignaling), this
245 // will set the whole offer/answer exchange in motion. Just need to wait for
246 // the signaling state to reach "stable".
247 void CreateAndSetAndSignalOffer() {
248 auto offer = CreateOffer();
249 ASSERT_NE(nullptr, offer);
250 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
251 }
252
253 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
254 // when a remote offer is received (via fake signaling) and an answer is
255 // generated. By default, uses default options.
256 void SetOfferAnswerOptions(
257 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
258 offer_answer_options_ = options;
259 }
260
261 // Set a callback to be invoked when SDP is received via the fake signaling
262 // channel, which provides an opportunity to munge (modify) the SDP. This is
263 // used to test SDP being applied that a PeerConnection would normally not
264 // generate, but a non-JSEP endpoint might.
265 void SetReceivedSdpMunger(
266 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100267 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700268 }
269
deadbeefc964d0b2017-04-03 10:03:35 -0700270 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700271 // generated.
272 void SetGeneratedSdpMunger(
273 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100274 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700275 }
276
Seth Hampson2f0d7022018-02-20 11:54:42 -0800277 // Set a callback to be invoked when a remote offer is received via the fake
278 // signaling channel. This provides an opportunity to change the
279 // PeerConnection state before an answer is created and sent to the caller.
280 void SetRemoteOfferHandler(std::function<void()> handler) {
281 remote_offer_handler_ = std::move(handler);
282 }
283
Steve Antonede9ca52017-10-16 13:04:27 -0700284 // Every ICE connection state in order that has been seen by the observer.
285 std::vector<PeerConnectionInterface::IceConnectionState>
286 ice_connection_state_history() const {
287 return ice_connection_state_history_;
288 }
Steve Anton6f25b092017-10-23 09:39:20 -0700289 void clear_ice_connection_state_history() {
290 ice_connection_state_history_.clear();
291 }
Steve Antonede9ca52017-10-16 13:04:27 -0700292
293 // Every ICE gathering state in order that has been seen by the observer.
294 std::vector<PeerConnectionInterface::IceGatheringState>
295 ice_gathering_state_history() const {
296 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700297 }
298
Steve Anton15324772018-01-16 10:26:49 -0800299 void AddAudioVideoTracks() {
300 AddAudioTrack();
301 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700302 }
303
Steve Anton74255ff2018-01-24 18:32:57 -0800304 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
305 return AddTrack(CreateLocalAudioTrack());
306 }
deadbeef1dcb1642017-03-29 21:08:16 -0700307
Steve Anton74255ff2018-01-24 18:32:57 -0800308 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
309 return AddTrack(CreateLocalVideoTrack());
310 }
deadbeef1dcb1642017-03-29 21:08:16 -0700311
312 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
313 FakeConstraints constraints;
314 // Disable highpass filter so that we can get all the test audio frames.
315 constraints.AddMandatory(MediaConstraintsInterface::kHighpassFilter, false);
316 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
317 peer_connection_factory_->CreateAudioSource(&constraints);
318 // TODO(perkj): Test audio source when it is implemented. Currently audio
319 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700320 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700321 source);
322 }
323
324 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
deadbeefb1a15d72017-09-07 14:12:05 -0700325 return CreateLocalVideoTrackInternal(FakeConstraints(),
326 webrtc::kVideoRotation_0);
deadbeef1dcb1642017-03-29 21:08:16 -0700327 }
328
329 rtc::scoped_refptr<webrtc::VideoTrackInterface>
330 CreateLocalVideoTrackWithConstraints(const FakeConstraints& constraints) {
deadbeefb1a15d72017-09-07 14:12:05 -0700331 return CreateLocalVideoTrackInternal(constraints, webrtc::kVideoRotation_0);
deadbeef1dcb1642017-03-29 21:08:16 -0700332 }
333
334 rtc::scoped_refptr<webrtc::VideoTrackInterface>
335 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
deadbeefb1a15d72017-09-07 14:12:05 -0700336 return CreateLocalVideoTrackInternal(FakeConstraints(), rotation);
deadbeef1dcb1642017-03-29 21:08:16 -0700337 }
338
Steve Anton74255ff2018-01-24 18:32:57 -0800339 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
340 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800341 const std::vector<std::string>& stream_ids = {}) {
342 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800343 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800344 return result.MoveValue();
345 }
346
347 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
348 cricket::MediaType media_type) {
349 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
350 for (auto receiver : pc()->GetReceivers()) {
351 if (receiver->media_type() == media_type) {
352 receivers.push_back(receiver);
353 }
354 }
355 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700356 }
357
Seth Hampson2f0d7022018-02-20 11:54:42 -0800358 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
359 cricket::MediaType media_type) {
360 for (auto transceiver : pc()->GetTransceivers()) {
361 if (transceiver->receiver()->media_type() == media_type) {
362 return transceiver;
363 }
364 }
365 return nullptr;
366 }
367
deadbeef1dcb1642017-03-29 21:08:16 -0700368 bool SignalingStateStable() {
369 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
370 }
371
372 void CreateDataChannel() { CreateDataChannel(nullptr); }
373
374 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700375 CreateDataChannel(kDataChannelLabel, init);
376 }
377
378 void CreateDataChannel(const std::string& label,
379 const webrtc::DataChannelInit* init) {
380 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700381 ASSERT_TRUE(data_channel_.get() != nullptr);
382 data_observer_.reset(new MockDataChannelObserver(data_channel_));
383 }
384
385 DataChannelInterface* data_channel() { return data_channel_; }
386 const MockDataChannelObserver* data_observer() const {
387 return data_observer_.get();
388 }
389
390 int audio_frames_received() const {
391 return fake_audio_capture_module_->frames_received();
392 }
393
394 // Takes minimum of video frames received for each track.
395 //
396 // Can be used like:
397 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
398 //
399 // To ensure that all video tracks received at least a certain number of
400 // frames.
401 int min_video_frames_received_per_track() const {
402 int min_frames = INT_MAX;
403 if (video_decoder_factory_enabled_) {
404 const std::vector<FakeWebRtcVideoDecoder*>& decoders =
405 fake_video_decoder_factory_->decoders();
406 if (decoders.empty()) {
407 return 0;
408 }
409 for (FakeWebRtcVideoDecoder* decoder : decoders) {
410 min_frames = std::min(min_frames, decoder->GetNumFramesReceived());
411 }
412 return min_frames;
413 } else {
414 if (fake_video_renderers_.empty()) {
415 return 0;
416 }
417
418 for (const auto& pair : fake_video_renderers_) {
419 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
420 }
421 return min_frames;
422 }
423 }
424
425 // In contrast to the above, sums the video frames received for all tracks.
426 // Can be used to verify that no video frames were received, or that the
427 // counts didn't increase.
428 int total_video_frames_received() const {
429 int total = 0;
430 if (video_decoder_factory_enabled_) {
431 const std::vector<FakeWebRtcVideoDecoder*>& decoders =
432 fake_video_decoder_factory_->decoders();
433 for (const FakeWebRtcVideoDecoder* decoder : decoders) {
434 total += decoder->GetNumFramesReceived();
435 }
436 } else {
437 for (const auto& pair : fake_video_renderers_) {
438 total += pair.second->num_rendered_frames();
439 }
440 for (const auto& renderer : removed_fake_video_renderers_) {
441 total += renderer->num_rendered_frames();
442 }
443 }
444 return total;
445 }
446
447 // Returns a MockStatsObserver in a state after stats gathering finished,
448 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700449 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700450 webrtc::MediaStreamTrackInterface* track) {
451 rtc::scoped_refptr<MockStatsObserver> observer(
452 new rtc::RefCountedObject<MockStatsObserver>());
453 EXPECT_TRUE(peer_connection_->GetStats(
454 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
455 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
456 return observer;
457 }
458
459 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700460 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
461 return OldGetStatsForTrack(nullptr);
462 }
463
464 // Synchronously gets stats and returns them. If it times out, fails the test
465 // and returns null.
466 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
467 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
468 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
469 peer_connection_->GetStats(callback);
470 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
471 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700472 }
473
474 int rendered_width() {
475 EXPECT_FALSE(fake_video_renderers_.empty());
476 return fake_video_renderers_.empty()
477 ? 0
478 : fake_video_renderers_.begin()->second->width();
479 }
480
481 int rendered_height() {
482 EXPECT_FALSE(fake_video_renderers_.empty());
483 return fake_video_renderers_.empty()
484 ? 0
485 : fake_video_renderers_.begin()->second->height();
486 }
487
488 double rendered_aspect_ratio() {
489 if (rendered_height() == 0) {
490 return 0.0;
491 }
492 return static_cast<double>(rendered_width()) / rendered_height();
493 }
494
495 webrtc::VideoRotation rendered_rotation() {
496 EXPECT_FALSE(fake_video_renderers_.empty());
497 return fake_video_renderers_.empty()
498 ? webrtc::kVideoRotation_0
499 : fake_video_renderers_.begin()->second->rotation();
500 }
501
502 int local_rendered_width() {
503 return local_video_renderer_ ? local_video_renderer_->width() : 0;
504 }
505
506 int local_rendered_height() {
507 return local_video_renderer_ ? local_video_renderer_->height() : 0;
508 }
509
510 double local_rendered_aspect_ratio() {
511 if (local_rendered_height() == 0) {
512 return 0.0;
513 }
514 return static_cast<double>(local_rendered_width()) /
515 local_rendered_height();
516 }
517
518 size_t number_of_remote_streams() {
519 if (!pc()) {
520 return 0;
521 }
522 return pc()->remote_streams()->count();
523 }
524
525 StreamCollectionInterface* remote_streams() const {
526 if (!pc()) {
527 ADD_FAILURE();
528 return nullptr;
529 }
530 return pc()->remote_streams();
531 }
532
533 StreamCollectionInterface* local_streams() {
534 if (!pc()) {
535 ADD_FAILURE();
536 return nullptr;
537 }
538 return pc()->local_streams();
539 }
540
541 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
542 return pc()->signaling_state();
543 }
544
545 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
546 return pc()->ice_connection_state();
547 }
548
549 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
550 return pc()->ice_gathering_state();
551 }
552
553 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
554 // GetReceivers. They're updated automatically when a remote offer/answer
555 // from the fake signaling channel is applied, or when
556 // ResetRtpReceiverObservers below is called.
557 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
558 rtp_receiver_observers() {
559 return rtp_receiver_observers_;
560 }
561
562 void ResetRtpReceiverObservers() {
563 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100564 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
565 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700566 std::unique_ptr<MockRtpReceiverObserver> observer(
567 new MockRtpReceiverObserver(receiver->media_type()));
568 receiver->SetObserver(observer.get());
569 rtp_receiver_observers_.push_back(std::move(observer));
570 }
571 }
572
Steve Antonede9ca52017-10-16 13:04:27 -0700573 rtc::FakeNetworkManager* network() const {
574 return fake_network_manager_.get();
575 }
576 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
577
deadbeef1dcb1642017-03-29 21:08:16 -0700578 private:
579 explicit PeerConnectionWrapper(const std::string& debug_name)
580 : debug_name_(debug_name) {}
581
582 bool Init(
583 const MediaConstraintsInterface* constraints,
584 const PeerConnectionFactory::Options* options,
585 const PeerConnectionInterface::RTCConfiguration* config,
586 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
587 rtc::Thread* network_thread,
588 rtc::Thread* worker_thread) {
589 // There's an error in this test code if Init ends up being called twice.
590 RTC_DCHECK(!peer_connection_);
591 RTC_DCHECK(!peer_connection_factory_);
592
593 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700594 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700595
596 std::unique_ptr<cricket::PortAllocator> port_allocator(
597 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700598 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700599 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
600 if (!fake_audio_capture_module_) {
601 return false;
602 }
603 // Note that these factories don't end up getting used unless supported
604 // codecs are added to them.
605 fake_video_decoder_factory_ = new FakeWebRtcVideoDecoderFactory();
606 fake_video_encoder_factory_ = new FakeWebRtcVideoEncoderFactory();
607 rtc::Thread* const signaling_thread = rtc::Thread::Current();
608 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
609 network_thread, worker_thread, signaling_thread,
Anders Carlsson67537952018-05-03 11:28:29 +0200610 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
611 fake_audio_capture_module_),
612 webrtc::CreateBuiltinAudioEncoderFactory(),
613 webrtc::CreateBuiltinAudioDecoderFactory(),
614 std::unique_ptr<FakeWebRtcVideoEncoderFactory>(
615 fake_video_encoder_factory_),
616 std::unique_ptr<FakeWebRtcVideoDecoderFactory>(
617 fake_video_decoder_factory_),
618 nullptr /* audio_mixer */, nullptr /* audio_processing */);
deadbeef1dcb1642017-03-29 21:08:16 -0700619 if (!peer_connection_factory_) {
620 return false;
621 }
622 if (options) {
623 peer_connection_factory_->SetOptions(*options);
624 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800625 if (config) {
626 sdp_semantics_ = config->sdp_semantics;
627 }
deadbeef1dcb1642017-03-29 21:08:16 -0700628 peer_connection_ =
629 CreatePeerConnection(std::move(port_allocator), constraints, config,
630 std::move(cert_generator));
631 return peer_connection_.get() != nullptr;
632 }
633
634 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
635 std::unique_ptr<cricket::PortAllocator> port_allocator,
636 const MediaConstraintsInterface* constraints,
637 const PeerConnectionInterface::RTCConfiguration* config,
638 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) {
639 PeerConnectionInterface::RTCConfiguration modified_config;
640 // If |config| is null, this will result in a default configuration being
641 // used.
642 if (config) {
643 modified_config = *config;
644 }
645 // Disable resolution adaptation; we don't want it interfering with the
646 // test results.
647 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
648 // ratios and not specific resolutions, is this even necessary?
649 modified_config.set_cpu_adaptation(false);
650
651 return peer_connection_factory_->CreatePeerConnection(
652 modified_config, constraints, std::move(port_allocator),
653 std::move(cert_generator), this);
654 }
655
656 void set_signaling_message_receiver(
657 SignalingMessageReceiver* signaling_message_receiver) {
658 signaling_message_receiver_ = signaling_message_receiver;
659 }
660
661 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
662
Steve Antonede9ca52017-10-16 13:04:27 -0700663 void set_signal_ice_candidates(bool signal) {
664 signal_ice_candidates_ = signal;
665 }
666
deadbeef1dcb1642017-03-29 21:08:16 -0700667 void EnableVideoDecoderFactory() {
668 video_decoder_factory_enabled_ = true;
669 fake_video_decoder_factory_->AddSupportedVideoCodecType(
Anders Carlsson67537952018-05-03 11:28:29 +0200670 webrtc::SdpVideoFormat("VP8"));
deadbeef1dcb1642017-03-29 21:08:16 -0700671 }
672
673 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
deadbeef1dcb1642017-03-29 21:08:16 -0700674 const FakeConstraints& constraints,
675 webrtc::VideoRotation rotation) {
676 // Set max frame rate to 10fps to reduce the risk of test flakiness.
677 // TODO(deadbeef): Do something more robust.
678 FakeConstraints source_constraints = constraints;
679 source_constraints.SetMandatoryMaxFrameRate(10);
680
681 cricket::FakeVideoCapturer* fake_capturer =
682 new webrtc::FakePeriodicVideoCapturer();
683 fake_capturer->SetRotation(rotation);
684 video_capturers_.push_back(fake_capturer);
685 rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source =
686 peer_connection_factory_->CreateVideoSource(fake_capturer,
687 &source_constraints);
688 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
deadbeefb1a15d72017-09-07 14:12:05 -0700689 peer_connection_factory_->CreateVideoTrack(rtc::CreateRandomUuid(),
690 source));
deadbeef1dcb1642017-03-29 21:08:16 -0700691 if (!local_video_renderer_) {
692 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
693 }
694 return track;
695 }
696
697 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100698 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800699 std::unique_ptr<SessionDescriptionInterface> desc =
700 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700701 if (received_sdp_munger_) {
702 received_sdp_munger_(desc->description());
703 }
704
705 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
706 // Setting a remote description may have changed the number of receivers,
707 // so reset the receiver observers.
708 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800709 if (remote_offer_handler_) {
710 remote_offer_handler_();
711 }
deadbeef1dcb1642017-03-29 21:08:16 -0700712 auto answer = CreateAnswer();
713 ASSERT_NE(nullptr, answer);
714 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
715 }
716
717 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100718 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800719 std::unique_ptr<SessionDescriptionInterface> desc =
720 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700721 if (received_sdp_munger_) {
722 received_sdp_munger_(desc->description());
723 }
724
725 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
726 // Set the RtpReceiverObserver after receivers are created.
727 ResetRtpReceiverObservers();
728 }
729
730 // Returns null on failure.
731 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
732 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
733 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
734 pc()->CreateOffer(observer, offer_answer_options_);
735 return WaitForDescriptionFromObserver(observer);
736 }
737
738 // Returns null on failure.
739 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
740 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
741 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
742 pc()->CreateAnswer(observer, offer_answer_options_);
743 return WaitForDescriptionFromObserver(observer);
744 }
745
746 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100747 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700748 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
749 if (!observer->result()) {
750 return nullptr;
751 }
752 auto description = observer->MoveDescription();
753 if (generated_sdp_munger_) {
754 generated_sdp_munger_(description->description());
755 }
756 return description;
757 }
758
759 // Setting the local description and sending the SDP message over the fake
760 // signaling channel are combined into the same method because the SDP
761 // message needs to be sent as soon as SetLocalDescription finishes, without
762 // waiting for the observer to be called. This ensures that ICE candidates
763 // don't outrace the description.
764 bool SetLocalDescriptionAndSendSdpMessage(
765 std::unique_ptr<SessionDescriptionInterface> desc) {
766 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
767 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100768 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800769 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700770 std::string sdp;
771 EXPECT_TRUE(desc->ToString(&sdp));
772 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800773 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
774 RemoveUnusedVideoRenderers();
775 }
deadbeef1dcb1642017-03-29 21:08:16 -0700776 // As mentioned above, we need to send the message immediately after
777 // SetLocalDescription.
778 SendSdpMessage(type, sdp);
779 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
780 return true;
781 }
782
783 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
784 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
785 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100786 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700787 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800788 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
789 RemoveUnusedVideoRenderers();
790 }
deadbeef1dcb1642017-03-29 21:08:16 -0700791 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
792 return observer->result();
793 }
794
Seth Hampson2f0d7022018-02-20 11:54:42 -0800795 // This is a work around to remove unused fake_video_renderers from
796 // transceivers that have either stopped or are no longer receiving.
797 void RemoveUnusedVideoRenderers() {
798 auto transceivers = pc()->GetTransceivers();
799 for (auto& transceiver : transceivers) {
800 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
801 continue;
802 }
803 // Remove fake video renderers from any stopped transceivers.
804 if (transceiver->stopped()) {
805 auto it =
806 fake_video_renderers_.find(transceiver->receiver()->track()->id());
807 if (it != fake_video_renderers_.end()) {
808 fake_video_renderers_.erase(it);
809 }
810 }
811 // Remove fake video renderers from any transceivers that are no longer
812 // receiving.
813 if ((transceiver->current_direction() &&
814 !webrtc::RtpTransceiverDirectionHasRecv(
815 *transceiver->current_direction()))) {
816 auto it =
817 fake_video_renderers_.find(transceiver->receiver()->track()->id());
818 if (it != fake_video_renderers_.end()) {
819 fake_video_renderers_.erase(it);
820 }
821 }
822 }
823 }
824
deadbeef1dcb1642017-03-29 21:08:16 -0700825 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
826 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800827 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700828 if (signaling_delay_ms_ == 0) {
829 RelaySdpMessageIfReceiverExists(type, msg);
830 } else {
831 invoker_.AsyncInvokeDelayed<void>(
832 RTC_FROM_HERE, rtc::Thread::Current(),
833 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
834 this, type, msg),
835 signaling_delay_ms_);
836 }
837 }
838
Steve Antona3a92c22017-12-07 10:27:41 -0800839 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700840 if (signaling_message_receiver_) {
841 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
842 }
843 }
844
845 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
846 // default).
847 void SendIceMessage(const std::string& sdp_mid,
848 int sdp_mline_index,
849 const std::string& msg) {
850 if (signaling_delay_ms_ == 0) {
851 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
852 } else {
853 invoker_.AsyncInvokeDelayed<void>(
854 RTC_FROM_HERE, rtc::Thread::Current(),
855 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
856 this, sdp_mid, sdp_mline_index, msg),
857 signaling_delay_ms_);
858 }
859 }
860
861 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
862 int sdp_mline_index,
863 const std::string& msg) {
864 if (signaling_message_receiver_) {
865 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
866 msg);
867 }
868 }
869
870 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800871 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
872 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700873 HandleIncomingOffer(msg);
874 } else {
875 HandleIncomingAnswer(msg);
876 }
877 }
878
879 void ReceiveIceMessage(const std::string& sdp_mid,
880 int sdp_mline_index,
881 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100882 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700883 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
884 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
885 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
886 }
887
888 // PeerConnectionObserver callbacks.
889 void OnSignalingChange(
890 webrtc::PeerConnectionInterface::SignalingState new_state) override {
891 EXPECT_EQ(pc()->signaling_state(), new_state);
892 }
Steve Anton15324772018-01-16 10:26:49 -0800893 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
894 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
895 streams) override {
896 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
897 rtc::scoped_refptr<VideoTrackInterface> video_track(
898 static_cast<VideoTrackInterface*>(receiver->track().get()));
899 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700900 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800901 fake_video_renderers_[video_track->id()] =
902 rtc::MakeUnique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700903 }
904 }
Steve Anton15324772018-01-16 10:26:49 -0800905 void OnRemoveTrack(
906 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
907 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
908 auto it = fake_video_renderers_.find(receiver->track()->id());
909 RTC_DCHECK(it != fake_video_renderers_.end());
910 fake_video_renderers_.erase(it);
911 }
912 }
deadbeef1dcb1642017-03-29 21:08:16 -0700913 void OnRenegotiationNeeded() override {}
914 void OnIceConnectionChange(
915 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
916 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700917 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700918 }
919 void OnIceGatheringChange(
920 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700921 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700922 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700923 }
924 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100925 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700926
927 std::string ice_sdp;
928 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700929 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700930 // Remote party may be deleted.
931 return;
932 }
933 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
934 }
935 void OnDataChannel(
936 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100937 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700938 data_channel_ = data_channel;
939 data_observer_.reset(new MockDataChannelObserver(data_channel));
940 }
941
deadbeef1dcb1642017-03-29 21:08:16 -0700942 std::string debug_name_;
943
944 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
945
946 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
947 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
948 peer_connection_factory_;
949
Steve Antonede9ca52017-10-16 13:04:27 -0700950 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700951 // Needed to keep track of number of frames sent.
952 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
953 // Needed to keep track of number of frames received.
954 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
955 fake_video_renderers_;
956 // Needed to ensure frames aren't received for removed tracks.
957 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
958 removed_fake_video_renderers_;
959 // Needed to keep track of number of frames received when external decoder
960 // used.
961 FakeWebRtcVideoDecoderFactory* fake_video_decoder_factory_ = nullptr;
962 FakeWebRtcVideoEncoderFactory* fake_video_encoder_factory_ = nullptr;
963 bool video_decoder_factory_enabled_ = false;
964
965 // For remote peer communication.
966 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
967 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700968 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-29 21:08:16 -0700969
970 // Store references to the video capturers we've created, so that we can stop
971 // them, if required.
972 std::vector<cricket::FakeVideoCapturer*> video_capturers_;
973 // |local_video_renderer_| attached to the first created local video track.
974 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
975
Seth Hampson2f0d7022018-02-20 11:54:42 -0800976 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -0700977 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
978 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
979 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800980 std::function<void()> remote_offer_handler_;
deadbeef1dcb1642017-03-29 21:08:16 -0700981
982 rtc::scoped_refptr<DataChannelInterface> data_channel_;
983 std::unique_ptr<MockDataChannelObserver> data_observer_;
984
985 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
986
Steve Antonede9ca52017-10-16 13:04:27 -0700987 std::vector<PeerConnectionInterface::IceConnectionState>
988 ice_connection_state_history_;
989 std::vector<PeerConnectionInterface::IceGatheringState>
990 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700991
992 rtc::AsyncInvoker invoker_;
993
Seth Hampson2f0d7022018-02-20 11:54:42 -0800994 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -0700995};
996
Elad Alon99c3fe52017-10-13 16:29:40 +0200997class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
998 public:
999 virtual ~MockRtcEventLogOutput() = default;
1000 MOCK_CONST_METHOD0(IsActive, bool());
1001 MOCK_METHOD1(Write, bool(const std::string&));
1002};
1003
Seth Hampson2f0d7022018-02-20 11:54:42 -08001004// This helper object is used for both specifying how many audio/video frames
1005// are expected to be received for a caller/callee. It provides helper functions
1006// to specify these expectations. The object initially starts in a state of no
1007// expectations.
1008class MediaExpectations {
1009 public:
1010 enum ExpectFrames {
1011 kExpectSomeFrames,
1012 kExpectNoFrames,
1013 kNoExpectation,
1014 };
1015
1016 void ExpectBidirectionalAudioAndVideo() {
1017 ExpectBidirectionalAudio();
1018 ExpectBidirectionalVideo();
1019 }
1020
1021 void ExpectBidirectionalAudio() {
1022 CallerExpectsSomeAudio();
1023 CalleeExpectsSomeAudio();
1024 }
1025
1026 void ExpectNoAudio() {
1027 CallerExpectsNoAudio();
1028 CalleeExpectsNoAudio();
1029 }
1030
1031 void ExpectBidirectionalVideo() {
1032 CallerExpectsSomeVideo();
1033 CalleeExpectsSomeVideo();
1034 }
1035
1036 void ExpectNoVideo() {
1037 CallerExpectsNoVideo();
1038 CalleeExpectsNoVideo();
1039 }
1040
1041 void CallerExpectsSomeAudioAndVideo() {
1042 CallerExpectsSomeAudio();
1043 CallerExpectsSomeVideo();
1044 }
1045
1046 void CalleeExpectsSomeAudioAndVideo() {
1047 CalleeExpectsSomeAudio();
1048 CalleeExpectsSomeVideo();
1049 }
1050
1051 // Caller's audio functions.
1052 void CallerExpectsSomeAudio(
1053 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1054 caller_audio_expectation_ = kExpectSomeFrames;
1055 caller_audio_frames_expected_ = expected_audio_frames;
1056 }
1057
1058 void CallerExpectsNoAudio() {
1059 caller_audio_expectation_ = kExpectNoFrames;
1060 caller_audio_frames_expected_ = 0;
1061 }
1062
1063 // Caller's video functions.
1064 void CallerExpectsSomeVideo(
1065 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1066 caller_video_expectation_ = kExpectSomeFrames;
1067 caller_video_frames_expected_ = expected_video_frames;
1068 }
1069
1070 void CallerExpectsNoVideo() {
1071 caller_video_expectation_ = kExpectNoFrames;
1072 caller_video_frames_expected_ = 0;
1073 }
1074
1075 // Callee's audio functions.
1076 void CalleeExpectsSomeAudio(
1077 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1078 callee_audio_expectation_ = kExpectSomeFrames;
1079 callee_audio_frames_expected_ = expected_audio_frames;
1080 }
1081
1082 void CalleeExpectsNoAudio() {
1083 callee_audio_expectation_ = kExpectNoFrames;
1084 callee_audio_frames_expected_ = 0;
1085 }
1086
1087 // Callee's video functions.
1088 void CalleeExpectsSomeVideo(
1089 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1090 callee_video_expectation_ = kExpectSomeFrames;
1091 callee_video_frames_expected_ = expected_video_frames;
1092 }
1093
1094 void CalleeExpectsNoVideo() {
1095 callee_video_expectation_ = kExpectNoFrames;
1096 callee_video_frames_expected_ = 0;
1097 }
1098
1099 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1100 ExpectFrames caller_video_expectation_ = kNoExpectation;
1101 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1102 ExpectFrames callee_video_expectation_ = kNoExpectation;
1103 int caller_audio_frames_expected_ = 0;
1104 int caller_video_frames_expected_ = 0;
1105 int callee_audio_frames_expected_ = 0;
1106 int callee_video_frames_expected_ = 0;
1107};
1108
deadbeef1dcb1642017-03-29 21:08:16 -07001109// Tests two PeerConnections connecting to each other end-to-end, using a
1110// virtual network, fake A/V capture and fake encoder/decoders. The
1111// PeerConnections share the threads/socket servers, but use separate versions
1112// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001113class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001114 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001115 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1116 : sdp_semantics_(sdp_semantics),
1117 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001118 fss_(new rtc::FirewallSocketServer(ss_.get())),
1119 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-29 21:08:16 -07001120 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001121 network_thread_->SetName("PCNetworkThread", this);
1122 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001123 RTC_CHECK(network_thread_->Start());
1124 RTC_CHECK(worker_thread_->Start());
1125 }
1126
Seth Hampson2f0d7022018-02-20 11:54:42 -08001127 ~PeerConnectionIntegrationBaseTest() {
deadbeef1dcb1642017-03-29 21:08:16 -07001128 if (caller_) {
1129 caller_->set_signaling_message_receiver(nullptr);
1130 }
1131 if (callee_) {
1132 callee_->set_signaling_message_receiver(nullptr);
1133 }
1134 }
1135
1136 bool SignalingStateStable() {
1137 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1138 }
1139
deadbeef71452802017-05-07 17:21:01 -07001140 bool DtlsConnected() {
1141 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1142 // are connected. This is an important distinction. Once we have separate
1143 // ICE and DTLS state, this check needs to use the DTLS state.
1144 return (callee()->ice_connection_state() ==
1145 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1146 callee()->ice_connection_state() ==
1147 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1148 (caller()->ice_connection_state() ==
1149 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1150 caller()->ice_connection_state() ==
1151 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1152 }
1153
Seth Hampson2f0d7022018-02-20 11:54:42 -08001154 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1155 const std::string& debug_name,
1156 const MediaConstraintsInterface* constraints,
1157 const PeerConnectionFactory::Options* options,
1158 const RTCConfiguration* config,
1159 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) {
1160 RTCConfiguration modified_config;
1161 if (config) {
1162 modified_config = *config;
1163 }
Steve Anton3acffc32018-04-12 17:21:03 -07001164 modified_config.sdp_semantics = sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001165 if (!cert_generator) {
1166 cert_generator = rtc::MakeUnique<FakeRTCCertificateGenerator>();
1167 }
1168 std::unique_ptr<PeerConnectionWrapper> client(
1169 new PeerConnectionWrapper(debug_name));
1170 if (!client->Init(constraints, options, &modified_config,
1171 std::move(cert_generator), network_thread_.get(),
1172 worker_thread_.get())) {
1173 return nullptr;
1174 }
1175 return client;
1176 }
1177
deadbeef1dcb1642017-03-29 21:08:16 -07001178 bool CreatePeerConnectionWrappers() {
1179 return CreatePeerConnectionWrappersWithConfig(
1180 PeerConnectionInterface::RTCConfiguration(),
1181 PeerConnectionInterface::RTCConfiguration());
1182 }
1183
Steve Anton3acffc32018-04-12 17:21:03 -07001184 bool CreatePeerConnectionWrappersWithSdpSemantics(
1185 SdpSemantics caller_semantics,
1186 SdpSemantics callee_semantics) {
1187 // Can't specify the sdp_semantics in the passed-in configuration since it
1188 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1189 // stored in sdp_semantics_. So get around this by modifying the instance
1190 // variable before calling CreatePeerConnectionWrapper for the caller and
1191 // callee PeerConnections.
1192 SdpSemantics original_semantics = sdp_semantics_;
1193 sdp_semantics_ = caller_semantics;
1194 caller_ = CreatePeerConnectionWrapper("Caller", nullptr, nullptr, nullptr,
1195 nullptr);
1196 sdp_semantics_ = callee_semantics;
1197 callee_ = CreatePeerConnectionWrapper("Callee", nullptr, nullptr, nullptr,
1198 nullptr);
1199 sdp_semantics_ = original_semantics;
1200 return caller_ && callee_;
1201 }
1202
deadbeef1dcb1642017-03-29 21:08:16 -07001203 bool CreatePeerConnectionWrappersWithConstraints(
1204 MediaConstraintsInterface* caller_constraints,
1205 MediaConstraintsInterface* callee_constraints) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001206 caller_ = CreatePeerConnectionWrapper("Caller", caller_constraints, nullptr,
1207 nullptr, nullptr);
1208 callee_ = CreatePeerConnectionWrapper("Callee", callee_constraints, nullptr,
1209 nullptr, nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001210 return caller_ && callee_;
1211 }
1212
1213 bool CreatePeerConnectionWrappersWithConfig(
1214 const PeerConnectionInterface::RTCConfiguration& caller_config,
1215 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001216 caller_ = CreatePeerConnectionWrapper("Caller", nullptr, nullptr,
1217 &caller_config, nullptr);
1218 callee_ = CreatePeerConnectionWrapper("Callee", nullptr, nullptr,
1219 &callee_config, nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001220 return caller_ && callee_;
1221 }
1222
1223 bool CreatePeerConnectionWrappersWithOptions(
1224 const PeerConnectionFactory::Options& caller_options,
1225 const PeerConnectionFactory::Options& callee_options) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001226 caller_ = CreatePeerConnectionWrapper("Caller", nullptr, &caller_options,
1227 nullptr, nullptr);
1228 callee_ = CreatePeerConnectionWrapper("Callee", nullptr, &callee_options,
1229 nullptr, nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001230 return caller_ && callee_;
1231 }
1232
Seth Hampson2f0d7022018-02-20 11:54:42 -08001233 std::unique_ptr<PeerConnectionWrapper>
1234 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001235 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1236 new FakeRTCCertificateGenerator());
1237 cert_generator->use_alternate_key();
1238
Seth Hampson2f0d7022018-02-20 11:54:42 -08001239 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr, nullptr,
1240 std::move(cert_generator));
deadbeef1dcb1642017-03-29 21:08:16 -07001241 }
1242
1243 // Once called, SDP blobs and ICE candidates will be automatically signaled
1244 // between PeerConnections.
1245 void ConnectFakeSignaling() {
1246 caller_->set_signaling_message_receiver(callee_.get());
1247 callee_->set_signaling_message_receiver(caller_.get());
1248 }
1249
Steve Antonede9ca52017-10-16 13:04:27 -07001250 // Once called, SDP blobs will be automatically signaled between
1251 // PeerConnections. Note that ICE candidates will not be signaled unless they
1252 // are in the exchanged SDP blobs.
1253 void ConnectFakeSignalingForSdpOnly() {
1254 ConnectFakeSignaling();
1255 SetSignalIceCandidates(false);
1256 }
1257
deadbeef1dcb1642017-03-29 21:08:16 -07001258 void SetSignalingDelayMs(int delay_ms) {
1259 caller_->set_signaling_delay_ms(delay_ms);
1260 callee_->set_signaling_delay_ms(delay_ms);
1261 }
1262
Steve Antonede9ca52017-10-16 13:04:27 -07001263 void SetSignalIceCandidates(bool signal) {
1264 caller_->set_signal_ice_candidates(signal);
1265 callee_->set_signal_ice_candidates(signal);
1266 }
1267
deadbeef1dcb1642017-03-29 21:08:16 -07001268 void EnableVideoDecoderFactory() {
1269 caller_->EnableVideoDecoderFactory();
1270 callee_->EnableVideoDecoderFactory();
1271 }
1272
1273 // Messages may get lost on the unreliable DataChannel, so we send multiple
1274 // times to avoid test flakiness.
1275 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1276 const std::string& data,
1277 int retries) {
1278 for (int i = 0; i < retries; ++i) {
1279 dc->Send(DataBuffer(data));
1280 }
1281 }
1282
1283 rtc::Thread* network_thread() { return network_thread_.get(); }
1284
1285 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1286
1287 PeerConnectionWrapper* caller() { return caller_.get(); }
1288
1289 // Set the |caller_| to the |wrapper| passed in and return the
1290 // original |caller_|.
1291 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1292 PeerConnectionWrapper* wrapper) {
1293 PeerConnectionWrapper* old = caller_.release();
1294 caller_.reset(wrapper);
1295 return old;
1296 }
1297
1298 PeerConnectionWrapper* callee() { return callee_.get(); }
1299
1300 // Set the |callee_| to the |wrapper| passed in and return the
1301 // original |callee_|.
1302 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1303 PeerConnectionWrapper* wrapper) {
1304 PeerConnectionWrapper* old = callee_.release();
1305 callee_.reset(wrapper);
1306 return old;
1307 }
1308
Steve Antonede9ca52017-10-16 13:04:27 -07001309 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1310
Seth Hampson2f0d7022018-02-20 11:54:42 -08001311 // Expects the provided number of new frames to be received within
1312 // kMaxWaitForFramesMs. The new expected frames are specified in
1313 // |media_expectations|. Returns false if any of the expectations were
1314 // not met.
1315 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1316 // First initialize the expected frame counts based upon the current
1317 // frame count.
1318 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1319 if (media_expectations.caller_audio_expectation_ ==
1320 MediaExpectations::kExpectSomeFrames) {
1321 total_caller_audio_frames_expected +=
1322 media_expectations.caller_audio_frames_expected_;
1323 }
1324 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001325 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001326 if (media_expectations.caller_video_expectation_ ==
1327 MediaExpectations::kExpectSomeFrames) {
1328 total_caller_video_frames_expected +=
1329 media_expectations.caller_video_frames_expected_;
1330 }
1331 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1332 if (media_expectations.callee_audio_expectation_ ==
1333 MediaExpectations::kExpectSomeFrames) {
1334 total_callee_audio_frames_expected +=
1335 media_expectations.callee_audio_frames_expected_;
1336 }
1337 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001338 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001339 if (media_expectations.callee_video_expectation_ ==
1340 MediaExpectations::kExpectSomeFrames) {
1341 total_callee_video_frames_expected +=
1342 media_expectations.callee_video_frames_expected_;
1343 }
deadbeef1dcb1642017-03-29 21:08:16 -07001344
Seth Hampson2f0d7022018-02-20 11:54:42 -08001345 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001346 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001347 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001348 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001349 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001350 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001351 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001352 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001353 total_callee_video_frames_expected,
1354 kMaxWaitForFramesMs);
1355 bool expectations_correct =
1356 caller()->audio_frames_received() >=
1357 total_caller_audio_frames_expected &&
1358 caller()->min_video_frames_received_per_track() >=
1359 total_caller_video_frames_expected &&
1360 callee()->audio_frames_received() >=
1361 total_callee_audio_frames_expected &&
1362 callee()->min_video_frames_received_per_track() >=
1363 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001364
Seth Hampson2f0d7022018-02-20 11:54:42 -08001365 // After the combined wait, print out a more detailed message upon
1366 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001367 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001368 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001369 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001370 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001371 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001372 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001373 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001374 total_callee_video_frames_expected);
1375
1376 // We want to make sure nothing unexpected was received.
1377 if (media_expectations.caller_audio_expectation_ ==
1378 MediaExpectations::kExpectNoFrames) {
1379 EXPECT_EQ(caller()->audio_frames_received(),
1380 total_caller_audio_frames_expected);
1381 if (caller()->audio_frames_received() !=
1382 total_caller_audio_frames_expected) {
1383 expectations_correct = false;
1384 }
1385 }
1386 if (media_expectations.caller_video_expectation_ ==
1387 MediaExpectations::kExpectNoFrames) {
1388 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1389 total_caller_video_frames_expected);
1390 if (caller()->min_video_frames_received_per_track() !=
1391 total_caller_video_frames_expected) {
1392 expectations_correct = false;
1393 }
1394 }
1395 if (media_expectations.callee_audio_expectation_ ==
1396 MediaExpectations::kExpectNoFrames) {
1397 EXPECT_EQ(callee()->audio_frames_received(),
1398 total_callee_audio_frames_expected);
1399 if (callee()->audio_frames_received() !=
1400 total_callee_audio_frames_expected) {
1401 expectations_correct = false;
1402 }
1403 }
1404 if (media_expectations.callee_video_expectation_ ==
1405 MediaExpectations::kExpectNoFrames) {
1406 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1407 total_callee_video_frames_expected);
1408 if (callee()->min_video_frames_received_per_track() !=
1409 total_callee_video_frames_expected) {
1410 expectations_correct = false;
1411 }
1412 }
1413 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001414 }
1415
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001416 void TestNegotiatedCipherSuite(
1417 const PeerConnectionFactory::Options& caller_options,
1418 const PeerConnectionFactory::Options& callee_options,
1419 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001420 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1421 callee_options));
1422 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
1423 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
1424 caller()->pc()->RegisterUMAObserver(caller_observer);
1425 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001426 caller()->AddAudioVideoTracks();
1427 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001428 caller()->CreateAndSetAndSignalOffer();
1429 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1430 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001431 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001432 EXPECT_EQ(
1433 1, caller_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher,
1434 expected_cipher_suite));
1435 caller()->pc()->RegisterUMAObserver(nullptr);
1436 }
1437
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001438 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1439 bool remote_gcm_enabled,
1440 int expected_cipher_suite) {
1441 PeerConnectionFactory::Options caller_options;
1442 caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
1443 PeerConnectionFactory::Options callee_options;
1444 callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
1445 TestNegotiatedCipherSuite(caller_options, callee_options,
1446 expected_cipher_suite);
1447 }
1448
Seth Hampson2f0d7022018-02-20 11:54:42 -08001449 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001450 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001451
deadbeef1dcb1642017-03-29 21:08:16 -07001452 private:
1453 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001454 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001455 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001456 // |network_thread_| and |worker_thread_| are used by both
1457 // |caller_| and |callee_| so they must be destroyed
1458 // later.
1459 std::unique_ptr<rtc::Thread> network_thread_;
1460 std::unique_ptr<rtc::Thread> worker_thread_;
1461 std::unique_ptr<PeerConnectionWrapper> caller_;
1462 std::unique_ptr<PeerConnectionWrapper> callee_;
1463};
1464
Seth Hampson2f0d7022018-02-20 11:54:42 -08001465class PeerConnectionIntegrationTest
1466 : public PeerConnectionIntegrationBaseTest,
1467 public ::testing::WithParamInterface<SdpSemantics> {
1468 protected:
1469 PeerConnectionIntegrationTest()
1470 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1471};
1472
1473class PeerConnectionIntegrationTestPlanB
1474 : public PeerConnectionIntegrationBaseTest {
1475 protected:
1476 PeerConnectionIntegrationTestPlanB()
1477 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1478};
1479
1480class PeerConnectionIntegrationTestUnifiedPlan
1481 : public PeerConnectionIntegrationBaseTest {
1482 protected:
1483 PeerConnectionIntegrationTestUnifiedPlan()
1484 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1485};
1486
deadbeef1dcb1642017-03-29 21:08:16 -07001487// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1488// includes testing that the callback is invoked if an observer is connected
1489// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001490TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001491 RtpReceiverObserverOnFirstPacketReceived) {
1492 ASSERT_TRUE(CreatePeerConnectionWrappers());
1493 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001494 caller()->AddAudioVideoTracks();
1495 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001496 // Start offer/answer exchange and wait for it to complete.
1497 caller()->CreateAndSetAndSignalOffer();
1498 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1499 // Should be one receiver each for audio/video.
1500 EXPECT_EQ(2, caller()->rtp_receiver_observers().size());
1501 EXPECT_EQ(2, callee()->rtp_receiver_observers().size());
1502 // Wait for all "first packet received" callbacks to be fired.
1503 EXPECT_TRUE_WAIT(
1504 std::all_of(caller()->rtp_receiver_observers().begin(),
1505 caller()->rtp_receiver_observers().end(),
1506 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1507 return o->first_packet_received();
1508 }),
1509 kMaxWaitForFramesMs);
1510 EXPECT_TRUE_WAIT(
1511 std::all_of(callee()->rtp_receiver_observers().begin(),
1512 callee()->rtp_receiver_observers().end(),
1513 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1514 return o->first_packet_received();
1515 }),
1516 kMaxWaitForFramesMs);
1517 // If new observers are set after the first packet was already received, the
1518 // callback should still be invoked.
1519 caller()->ResetRtpReceiverObservers();
1520 callee()->ResetRtpReceiverObservers();
1521 EXPECT_EQ(2, caller()->rtp_receiver_observers().size());
1522 EXPECT_EQ(2, callee()->rtp_receiver_observers().size());
1523 EXPECT_TRUE(
1524 std::all_of(caller()->rtp_receiver_observers().begin(),
1525 caller()->rtp_receiver_observers().end(),
1526 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1527 return o->first_packet_received();
1528 }));
1529 EXPECT_TRUE(
1530 std::all_of(callee()->rtp_receiver_observers().begin(),
1531 callee()->rtp_receiver_observers().end(),
1532 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1533 return o->first_packet_received();
1534 }));
1535}
1536
1537class DummyDtmfObserver : public DtmfSenderObserverInterface {
1538 public:
1539 DummyDtmfObserver() : completed_(false) {}
1540
1541 // Implements DtmfSenderObserverInterface.
1542 void OnToneChange(const std::string& tone) override {
1543 tones_.push_back(tone);
1544 if (tone.empty()) {
1545 completed_ = true;
1546 }
1547 }
1548
1549 const std::vector<std::string>& tones() const { return tones_; }
1550 bool completed() const { return completed_; }
1551
1552 private:
1553 bool completed_;
1554 std::vector<std::string> tones_;
1555};
1556
1557// Assumes |sender| already has an audio track added and the offer/answer
1558// exchange is done.
1559void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1560 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001561 // We should be able to get a DTMF sender from the local sender.
1562 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1563 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1564 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001565 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001566 dtmf_sender->RegisterObserver(&observer);
1567
1568 // Test the DtmfSender object just created.
1569 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1570 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1571
1572 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1573 std::vector<std::string> tones = {"1", "a", ""};
1574 EXPECT_EQ(tones, observer.tones());
1575 dtmf_sender->UnregisterObserver();
1576 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1577}
1578
1579// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1580// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001581TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001582 ASSERT_TRUE(CreatePeerConnectionWrappers());
1583 ConnectFakeSignaling();
1584 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001585 caller()->AddAudioTrack();
1586 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001587 caller()->CreateAndSetAndSignalOffer();
1588 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001589 // DTLS must finish before the DTMF sender can be used reliably.
1590 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001591 TestDtmfFromSenderToReceiver(caller(), callee());
1592 TestDtmfFromSenderToReceiver(callee(), caller());
1593}
1594
1595// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1596// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001597TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001598 ASSERT_TRUE(CreatePeerConnectionWrappers());
1599 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001600 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
1601 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
1602 caller()->pc()->RegisterUMAObserver(caller_observer);
1603
deadbeef1dcb1642017-03-29 21:08:16 -07001604 // Do normal offer/answer and wait for some frames to be received in each
1605 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001606 caller()->AddAudioVideoTracks();
1607 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001608 caller()->CreateAndSetAndSignalOffer();
1609 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001610 MediaExpectations media_expectations;
1611 media_expectations.ExpectBidirectionalAudioAndVideo();
1612 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Harald Alvestrand194939b2018-01-24 16:04:13 +01001613 EXPECT_LE(
1614 1, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1615 webrtc::kEnumCounterKeyProtocolDtls));
1616 EXPECT_EQ(
1617 0, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1618 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001619}
1620
1621// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001622TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001623 PeerConnectionInterface::RTCConfiguration sdes_config;
1624 sdes_config.enable_dtls_srtp.emplace(false);
1625 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1626 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001627 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
1628 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
1629 caller()->pc()->RegisterUMAObserver(caller_observer);
deadbeef1dcb1642017-03-29 21:08:16 -07001630
1631 // Do normal offer/answer and wait for some frames to be received in each
1632 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001633 caller()->AddAudioVideoTracks();
1634 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001635 caller()->CreateAndSetAndSignalOffer();
1636 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001637 MediaExpectations media_expectations;
1638 media_expectations.ExpectBidirectionalAudioAndVideo();
1639 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Harald Alvestrand194939b2018-01-24 16:04:13 +01001640 EXPECT_LE(
1641 1, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1642 webrtc::kEnumCounterKeyProtocolSdes));
1643 EXPECT_EQ(
1644 0, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1645 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001646}
1647
Steve Anton8c0f7a72017-10-03 10:03:10 -07001648// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1649// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001650TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001651 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1652 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1653 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1654 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1655 return pc->GetRemoteAudioSSLCertificate();
1656 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001657 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1658 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1659 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1660 return pc->GetRemoteAudioSSLCertChain();
1661 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001662
1663 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1664 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1665
1666 // Configure each side with a known certificate so they can be compared later.
1667 PeerConnectionInterface::RTCConfiguration caller_config;
1668 caller_config.enable_dtls_srtp.emplace(true);
1669 caller_config.certificates.push_back(caller_cert);
1670 PeerConnectionInterface::RTCConfiguration callee_config;
1671 callee_config.enable_dtls_srtp.emplace(true);
1672 callee_config.certificates.push_back(callee_cert);
1673 ASSERT_TRUE(
1674 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1675 ConnectFakeSignaling();
1676
1677 // When first initialized, there should not be a remote SSL certificate (and
1678 // calling this method should not crash).
1679 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1680 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001681 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1682 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001683
Steve Anton15324772018-01-16 10:26:49 -08001684 caller()->AddAudioTrack();
1685 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001686 caller()->CreateAndSetAndSignalOffer();
1687 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1688 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1689
1690 // Once DTLS has been connected, each side should return the other's SSL
1691 // certificate when calling GetRemoteAudioSSLCertificate.
1692
1693 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1694 ASSERT_TRUE(caller_remote_cert);
1695 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1696 caller_remote_cert->ToPEMString());
1697
1698 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1699 ASSERT_TRUE(callee_remote_cert);
1700 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1701 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001702
1703 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1704 ASSERT_TRUE(caller_remote_cert_chain);
1705 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1706 auto remote_cert = &caller_remote_cert_chain->Get(0);
1707 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1708 remote_cert->ToPEMString());
1709
1710 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1711 ASSERT_TRUE(callee_remote_cert_chain);
1712 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1713 remote_cert = &callee_remote_cert_chain->Get(0);
1714 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1715 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001716}
1717
deadbeef1dcb1642017-03-29 21:08:16 -07001718// This test sets up a call between two parties (using DTLS) and tests that we
1719// can get a video aspect ratio of 16:9.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001720TEST_P(PeerConnectionIntegrationTest, SendAndReceive16To9AspectRatio) {
deadbeef1dcb1642017-03-29 21:08:16 -07001721 ASSERT_TRUE(CreatePeerConnectionWrappers());
1722 ConnectFakeSignaling();
1723
1724 // Add video tracks with 16:9 constraint.
1725 FakeConstraints constraints;
1726 double requested_ratio = 16.0 / 9;
1727 constraints.SetMandatoryMinAspectRatio(requested_ratio);
Steve Anton15324772018-01-16 10:26:49 -08001728 caller()->AddTrack(
1729 caller()->CreateLocalVideoTrackWithConstraints(constraints));
1730 callee()->AddTrack(
1731 callee()->CreateLocalVideoTrackWithConstraints(constraints));
deadbeef1dcb1642017-03-29 21:08:16 -07001732
1733 // Do normal offer/answer and wait for at least one frame to be received in
1734 // each direction.
1735 caller()->CreateAndSetAndSignalOffer();
1736 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1737 callee()->min_video_frames_received_per_track() > 0,
1738 kMaxWaitForFramesMs);
1739
1740 // Check rendered aspect ratio.
1741 EXPECT_EQ(requested_ratio, caller()->local_rendered_aspect_ratio());
1742 EXPECT_EQ(requested_ratio, caller()->rendered_aspect_ratio());
1743 EXPECT_EQ(requested_ratio, callee()->local_rendered_aspect_ratio());
1744 EXPECT_EQ(requested_ratio, callee()->rendered_aspect_ratio());
1745}
1746
1747// This test sets up a call between two parties with a source resolution of
1748// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001749TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001750 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1751 ASSERT_TRUE(CreatePeerConnectionWrappers());
1752 ConnectFakeSignaling();
1753
1754 // Similar to above test, but uses MandatoryMin[Width/Height] constraint
1755 // instead of aspect ratio constraint.
1756 FakeConstraints constraints;
1757 constraints.SetMandatoryMinWidth(1280);
1758 constraints.SetMandatoryMinHeight(720);
Steve Anton15324772018-01-16 10:26:49 -08001759 caller()->AddTrack(
1760 caller()->CreateLocalVideoTrackWithConstraints(constraints));
1761 callee()->AddTrack(
1762 callee()->CreateLocalVideoTrackWithConstraints(constraints));
deadbeef1dcb1642017-03-29 21:08:16 -07001763
1764 // Do normal offer/answer and wait for at least one frame to be received in
1765 // each direction.
1766 caller()->CreateAndSetAndSignalOffer();
1767 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1768 callee()->min_video_frames_received_per_track() > 0,
1769 kMaxWaitForFramesMs);
1770
1771 // Check rendered aspect ratio.
1772 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1773 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1774 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1775 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1776}
1777
1778// This test sets up an one-way call, with media only from caller to
1779// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001780TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001781 ASSERT_TRUE(CreatePeerConnectionWrappers());
1782 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001783 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001784 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001785 MediaExpectations media_expectations;
1786 media_expectations.CalleeExpectsSomeAudioAndVideo();
1787 media_expectations.CallerExpectsNoAudio();
1788 media_expectations.CallerExpectsNoVideo();
1789 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001790}
1791
1792// This test sets up a audio call initially, with the callee rejecting video
1793// initially. Then later the callee decides to upgrade to audio/video, and
1794// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001795TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001796 ASSERT_TRUE(CreatePeerConnectionWrappers());
1797 ConnectFakeSignaling();
1798 // Initially, offer an audio/video stream from the caller, but refuse to
1799 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001800 caller()->AddAudioVideoTracks();
1801 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001802 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1803 PeerConnectionInterface::RTCOfferAnswerOptions options;
1804 options.offer_to_receive_video = 0;
1805 callee()->SetOfferAnswerOptions(options);
1806 } else {
1807 callee()->SetRemoteOfferHandler([this] {
1808 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1809 });
1810 }
deadbeef1dcb1642017-03-29 21:08:16 -07001811 // Do offer/answer and make sure audio is still received end-to-end.
1812 caller()->CreateAndSetAndSignalOffer();
1813 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001814 {
1815 MediaExpectations media_expectations;
1816 media_expectations.ExpectBidirectionalAudio();
1817 media_expectations.ExpectNoVideo();
1818 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1819 }
deadbeef1dcb1642017-03-29 21:08:16 -07001820 // Sanity check that the callee's description has a rejected video section.
1821 ASSERT_NE(nullptr, callee()->pc()->local_description());
1822 const ContentInfo* callee_video_content =
1823 GetFirstVideoContent(callee()->pc()->local_description()->description());
1824 ASSERT_NE(nullptr, callee_video_content);
1825 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001826
deadbeef1dcb1642017-03-29 21:08:16 -07001827 // Now negotiate with video and ensure negotiation succeeds, with video
1828 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001829 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001830 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1831 PeerConnectionInterface::RTCOfferAnswerOptions options;
1832 options.offer_to_receive_video = 1;
1833 callee()->SetOfferAnswerOptions(options);
1834 } else {
1835 callee()->SetRemoteOfferHandler(nullptr);
1836 caller()->SetRemoteOfferHandler([this] {
1837 // The caller creates a new transceiver to receive video on when receiving
1838 // the offer, but by default it is send only.
1839 auto transceivers = caller()->pc()->GetTransceivers();
1840 ASSERT_EQ(3, transceivers.size());
1841 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1842 transceivers[2]->receiver()->media_type());
1843 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1844 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1845 });
1846 }
deadbeef1dcb1642017-03-29 21:08:16 -07001847 callee()->CreateAndSetAndSignalOffer();
1848 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001849 {
1850 // Expect additional audio frames to be received after the upgrade.
1851 MediaExpectations media_expectations;
1852 media_expectations.ExpectBidirectionalAudioAndVideo();
1853 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1854 }
deadbeef1dcb1642017-03-29 21:08:16 -07001855}
1856
deadbeef4389b4d2017-09-07 09:07:36 -07001857// Simpler than the above test; just add an audio track to an established
1858// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001859TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07001860 ASSERT_TRUE(CreatePeerConnectionWrappers());
1861 ConnectFakeSignaling();
1862 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08001863 caller()->AddVideoTrack();
1864 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001865 caller()->CreateAndSetAndSignalOffer();
1866 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1867 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001868 caller()->AddAudioTrack();
1869 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001870 caller()->CreateAndSetAndSignalOffer();
1871 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1872 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001873 MediaExpectations media_expectations;
1874 media_expectations.ExpectBidirectionalAudioAndVideo();
1875 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07001876}
1877
deadbeef1dcb1642017-03-29 21:08:16 -07001878// This test sets up a call that's transferred to a new caller with a different
1879// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001880TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07001881 ASSERT_TRUE(CreatePeerConnectionWrappers());
1882 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001883 caller()->AddAudioVideoTracks();
1884 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001885 caller()->CreateAndSetAndSignalOffer();
1886 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1887
1888 // Keep the original peer around which will still send packets to the
1889 // receiving client. These SRTP packets will be dropped.
1890 std::unique_ptr<PeerConnectionWrapper> original_peer(
1891 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001892 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001893 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1894 // directly above.
1895 original_peer->pc()->Close();
1896
1897 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001898 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001899 caller()->CreateAndSetAndSignalOffer();
1900 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1901 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001902 MediaExpectations media_expectations;
1903 media_expectations.ExpectBidirectionalAudioAndVideo();
1904 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001905}
1906
1907// This test sets up a call that's transferred to a new callee with a different
1908// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001909TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07001910 ASSERT_TRUE(CreatePeerConnectionWrappers());
1911 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001912 caller()->AddAudioVideoTracks();
1913 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001914 caller()->CreateAndSetAndSignalOffer();
1915 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1916
1917 // Keep the original peer around which will still send packets to the
1918 // receiving client. These SRTP packets will be dropped.
1919 std::unique_ptr<PeerConnectionWrapper> original_peer(
1920 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001921 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001922 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1923 // directly above.
1924 original_peer->pc()->Close();
1925
1926 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001927 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001928 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
1929 caller()->CreateAndSetAndSignalOffer();
1930 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1931 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001932 MediaExpectations media_expectations;
1933 media_expectations.ExpectBidirectionalAudioAndVideo();
1934 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001935}
1936
1937// This test sets up a non-bundled call and negotiates bundling at the same
1938// time as starting an ICE restart. When bundling is in effect in the restart,
1939// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001940TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07001941 ASSERT_TRUE(CreatePeerConnectionWrappers());
1942 ConnectFakeSignaling();
1943
Steve Anton15324772018-01-16 10:26:49 -08001944 caller()->AddAudioVideoTracks();
1945 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001946 // Remove the bundle group from the SDP received by the callee.
1947 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
1948 desc->RemoveGroupByName("BUNDLE");
1949 });
1950 caller()->CreateAndSetAndSignalOffer();
1951 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001952 {
1953 MediaExpectations media_expectations;
1954 media_expectations.ExpectBidirectionalAudioAndVideo();
1955 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1956 }
deadbeef1dcb1642017-03-29 21:08:16 -07001957 // Now stop removing the BUNDLE group, and trigger an ICE restart.
1958 callee()->SetReceivedSdpMunger(nullptr);
1959 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
1960 caller()->CreateAndSetAndSignalOffer();
1961 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1962
1963 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001964 {
1965 MediaExpectations media_expectations;
1966 media_expectations.ExpectBidirectionalAudioAndVideo();
1967 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1968 }
deadbeef1dcb1642017-03-29 21:08:16 -07001969}
1970
1971// Test CVO (Coordination of Video Orientation). If a video source is rotated
1972// and both peers support the CVO RTP header extension, the actual video frames
1973// don't need to be encoded in different resolutions, since the rotation is
1974// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001975TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07001976 ASSERT_TRUE(CreatePeerConnectionWrappers());
1977 ConnectFakeSignaling();
1978 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08001979 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07001980 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08001981 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07001982 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
1983
1984 // Wait for video frames to be received by both sides.
1985 caller()->CreateAndSetAndSignalOffer();
1986 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1987 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1988 callee()->min_video_frames_received_per_track() > 0,
1989 kMaxWaitForFramesMs);
1990
1991 // Ensure that the aspect ratio is unmodified.
1992 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
1993 // not just assumed.
1994 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
1995 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
1996 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
1997 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
1998 // Ensure that the CVO bits were surfaced to the renderer.
1999 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2000 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2001}
2002
2003// Test that when the CVO extension isn't supported, video is rotated the
2004// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002005TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002006 ASSERT_TRUE(CreatePeerConnectionWrappers());
2007 ConnectFakeSignaling();
2008 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002009 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002010 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002011 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002012 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2013
2014 // Remove the CVO extension from the offered SDP.
2015 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2016 cricket::VideoContentDescription* video =
2017 GetFirstVideoContentDescription(desc);
2018 video->ClearRtpHeaderExtensions();
2019 });
2020 // Wait for video frames to be received by both sides.
2021 caller()->CreateAndSetAndSignalOffer();
2022 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2023 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2024 callee()->min_video_frames_received_per_track() > 0,
2025 kMaxWaitForFramesMs);
2026
2027 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2028 // rotation.
2029 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2030 // not just assumed.
2031 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2032 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2033 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2034 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2035 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2036 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2037 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2038}
2039
deadbeef1dcb1642017-03-29 21:08:16 -07002040// Test that if the answerer rejects the audio m= section, no audio is sent or
2041// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002042TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002043 ASSERT_TRUE(CreatePeerConnectionWrappers());
2044 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002045 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002046 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2047 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2048 // it will reject the audio m= section completely.
2049 PeerConnectionInterface::RTCOfferAnswerOptions options;
2050 options.offer_to_receive_audio = 0;
2051 callee()->SetOfferAnswerOptions(options);
2052 } else {
2053 // Stopping the audio RtpTransceiver will cause the media section to be
2054 // rejected in the answer.
2055 callee()->SetRemoteOfferHandler([this] {
2056 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2057 });
2058 }
Steve Anton15324772018-01-16 10:26:49 -08002059 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002060 // Do offer/answer and wait for successful end-to-end video frames.
2061 caller()->CreateAndSetAndSignalOffer();
2062 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002063 MediaExpectations media_expectations;
2064 media_expectations.ExpectBidirectionalVideo();
2065 media_expectations.ExpectNoAudio();
2066 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2067
deadbeef1dcb1642017-03-29 21:08:16 -07002068 // Sanity check that the callee's description has a rejected audio section.
2069 ASSERT_NE(nullptr, callee()->pc()->local_description());
2070 const ContentInfo* callee_audio_content =
2071 GetFirstAudioContent(callee()->pc()->local_description()->description());
2072 ASSERT_NE(nullptr, callee_audio_content);
2073 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002074 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2075 // The caller's transceiver should have stopped after receiving the answer.
2076 EXPECT_TRUE(caller()
2077 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2078 ->stopped());
2079 }
deadbeef1dcb1642017-03-29 21:08:16 -07002080}
2081
2082// Test that if the answerer rejects the video m= section, no video is sent or
2083// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002084TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002085 ASSERT_TRUE(CreatePeerConnectionWrappers());
2086 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002087 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002088 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2089 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2090 // it will reject the video m= section completely.
2091 PeerConnectionInterface::RTCOfferAnswerOptions options;
2092 options.offer_to_receive_video = 0;
2093 callee()->SetOfferAnswerOptions(options);
2094 } else {
2095 // Stopping the video RtpTransceiver will cause the media section to be
2096 // rejected in the answer.
2097 callee()->SetRemoteOfferHandler([this] {
2098 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2099 });
2100 }
Steve Anton15324772018-01-16 10:26:49 -08002101 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002102 // Do offer/answer and wait for successful end-to-end audio frames.
2103 caller()->CreateAndSetAndSignalOffer();
2104 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002105 MediaExpectations media_expectations;
2106 media_expectations.ExpectBidirectionalAudio();
2107 media_expectations.ExpectNoVideo();
2108 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2109
deadbeef1dcb1642017-03-29 21:08:16 -07002110 // Sanity check that the callee's description has a rejected video section.
2111 ASSERT_NE(nullptr, callee()->pc()->local_description());
2112 const ContentInfo* callee_video_content =
2113 GetFirstVideoContent(callee()->pc()->local_description()->description());
2114 ASSERT_NE(nullptr, callee_video_content);
2115 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002116 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2117 // The caller's transceiver should have stopped after receiving the answer.
2118 EXPECT_TRUE(caller()
2119 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2120 ->stopped());
2121 }
deadbeef1dcb1642017-03-29 21:08:16 -07002122}
2123
2124// Test that if the answerer rejects both audio and video m= sections, nothing
2125// bad happens.
2126// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2127// test anything but the fact that negotiation succeeds, which doesn't mean
2128// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002129TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002130 ASSERT_TRUE(CreatePeerConnectionWrappers());
2131 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002132 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002133 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2134 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2135 // will reject both audio and video m= sections.
2136 PeerConnectionInterface::RTCOfferAnswerOptions options;
2137 options.offer_to_receive_audio = 0;
2138 options.offer_to_receive_video = 0;
2139 callee()->SetOfferAnswerOptions(options);
2140 } else {
2141 callee()->SetRemoteOfferHandler([this] {
2142 // Stopping all transceivers will cause all media sections to be rejected.
2143 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2144 transceiver->Stop();
2145 }
2146 });
2147 }
deadbeef1dcb1642017-03-29 21:08:16 -07002148 // Do offer/answer and wait for stable signaling state.
2149 caller()->CreateAndSetAndSignalOffer();
2150 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002151
deadbeef1dcb1642017-03-29 21:08:16 -07002152 // Sanity check that the callee's description has rejected m= sections.
2153 ASSERT_NE(nullptr, callee()->pc()->local_description());
2154 const ContentInfo* callee_audio_content =
2155 GetFirstAudioContent(callee()->pc()->local_description()->description());
2156 ASSERT_NE(nullptr, callee_audio_content);
2157 EXPECT_TRUE(callee_audio_content->rejected);
2158 const ContentInfo* callee_video_content =
2159 GetFirstVideoContent(callee()->pc()->local_description()->description());
2160 ASSERT_NE(nullptr, callee_video_content);
2161 EXPECT_TRUE(callee_video_content->rejected);
2162}
2163
2164// This test sets up an audio and video call between two parties. After the
2165// call runs for a while, the caller sends an updated offer with video being
2166// rejected. Once the re-negotiation is done, the video flow should stop and
2167// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002168TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002169 ASSERT_TRUE(CreatePeerConnectionWrappers());
2170 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002171 caller()->AddAudioVideoTracks();
2172 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002173 caller()->CreateAndSetAndSignalOffer();
2174 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002175 {
2176 MediaExpectations media_expectations;
2177 media_expectations.ExpectBidirectionalAudioAndVideo();
2178 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2179 }
deadbeef1dcb1642017-03-29 21:08:16 -07002180 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002181 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2182 caller()->SetGeneratedSdpMunger(
2183 [](cricket::SessionDescription* description) {
2184 for (cricket::ContentInfo& content : description->contents()) {
2185 if (cricket::IsVideoContent(&content)) {
2186 content.rejected = true;
2187 }
2188 }
2189 });
2190 } else {
2191 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2192 }
deadbeef1dcb1642017-03-29 21:08:16 -07002193 caller()->CreateAndSetAndSignalOffer();
2194 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2195
2196 // Sanity check that the caller's description has a rejected video section.
2197 ASSERT_NE(nullptr, caller()->pc()->local_description());
2198 const ContentInfo* caller_video_content =
2199 GetFirstVideoContent(caller()->pc()->local_description()->description());
2200 ASSERT_NE(nullptr, caller_video_content);
2201 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002202 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002203 {
2204 MediaExpectations media_expectations;
2205 media_expectations.ExpectBidirectionalAudio();
2206 media_expectations.ExpectNoVideo();
2207 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2208 }
deadbeef1dcb1642017-03-29 21:08:16 -07002209}
2210
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002211// Do one offer/answer with audio, another that disables it (rejecting the m=
2212// section), and another that re-enables it. Regression test for:
2213// bugs.webrtc.org/6023
2214TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2215 ASSERT_TRUE(CreatePeerConnectionWrappers());
2216 ConnectFakeSignaling();
2217
2218 // Add audio track, do normal offer/answer.
2219 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2220 caller()->CreateLocalAudioTrack();
2221 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2222 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2223 caller()->CreateAndSetAndSignalOffer();
2224 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2225
2226 // Remove audio track, and set offer_to_receive_audio to false to cause the
2227 // m= section to be completely disabled, not just "recvonly".
2228 caller()->pc()->RemoveTrack(sender);
2229 PeerConnectionInterface::RTCOfferAnswerOptions options;
2230 options.offer_to_receive_audio = 0;
2231 caller()->SetOfferAnswerOptions(options);
2232 caller()->CreateAndSetAndSignalOffer();
2233 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2234
2235 // Add the audio track again, expecting negotiation to succeed and frames to
2236 // flow.
2237 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2238 options.offer_to_receive_audio = 1;
2239 caller()->SetOfferAnswerOptions(options);
2240 caller()->CreateAndSetAndSignalOffer();
2241 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2242
2243 MediaExpectations media_expectations;
2244 media_expectations.CalleeExpectsSomeAudio();
2245 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2246}
2247
deadbeef1dcb1642017-03-29 21:08:16 -07002248// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2249// is needed to support legacy endpoints.
2250// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2251// add a test for an end-to-end test without MID signaling either (basically,
2252// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002253TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002254 ASSERT_TRUE(CreatePeerConnectionWrappers());
2255 ConnectFakeSignaling();
2256 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002257 caller()->AddAudioVideoTracks();
2258 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002259 // Remove SSRCs and MSIDs from the received offer SDP.
2260 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002261 caller()->CreateAndSetAndSignalOffer();
2262 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002263 MediaExpectations media_expectations;
2264 media_expectations.ExpectBidirectionalAudioAndVideo();
2265 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002266}
2267
Seth Hampson5897a6e2018-04-03 11:16:33 -07002268// Basic end-to-end test, without SSRC signaling. This means that the track
2269// was created properly and frames are delivered when the MSIDs are communicated
2270// with a=msid lines and no a=ssrc lines.
2271TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2272 EndToEndCallWithoutSsrcSignaling) {
2273 const char kStreamId[] = "streamId";
2274 ASSERT_TRUE(CreatePeerConnectionWrappers());
2275 ConnectFakeSignaling();
2276 // Add just audio tracks.
2277 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2278 callee()->AddAudioTrack();
2279
2280 // Remove SSRCs from the received offer SDP.
2281 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2282 caller()->CreateAndSetAndSignalOffer();
2283 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2284 MediaExpectations media_expectations;
2285 media_expectations.ExpectBidirectionalAudio();
2286 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2287}
2288
Steve Antondf527fd2018-04-27 15:52:03 -07002289// Tests that video flows between multiple video tracks when SSRCs are not
2290// signaled. This exercises the MID RTP header extension which is needed to
2291// demux the incoming video tracks.
2292TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2293 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2294 ASSERT_TRUE(CreatePeerConnectionWrappers());
2295 ConnectFakeSignaling();
2296 caller()->AddVideoTrack();
2297 caller()->AddVideoTrack();
2298 callee()->AddVideoTrack();
2299 callee()->AddVideoTrack();
2300
2301 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2302 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2303 caller()->CreateAndSetAndSignalOffer();
2304 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2305 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2306 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2307
2308 // Expect video to be received in both directions on both tracks.
2309 MediaExpectations media_expectations;
2310 media_expectations.ExpectBidirectionalVideo();
2311 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2312}
2313
deadbeef1dcb1642017-03-29 21:08:16 -07002314// Test that if two video tracks are sent (from caller to callee, in this test),
2315// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002316TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002317 ASSERT_TRUE(CreatePeerConnectionWrappers());
2318 ConnectFakeSignaling();
2319 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002320 caller()->AddAudioVideoTracks();
2321 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002322 caller()->CreateAndSetAndSignalOffer();
2323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002324 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002325
2326 MediaExpectations media_expectations;
2327 media_expectations.CalleeExpectsSomeAudioAndVideo();
2328 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002329}
2330
2331static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2332 bool first = true;
2333 for (cricket::ContentInfo& content : desc->contents()) {
2334 if (first) {
2335 first = false;
2336 continue;
2337 }
2338 content.bundle_only = true;
2339 }
2340 first = true;
2341 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2342 if (first) {
2343 first = false;
2344 continue;
2345 }
2346 transport.description.ice_ufrag.clear();
2347 transport.description.ice_pwd.clear();
2348 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2349 transport.description.identity_fingerprint.reset(nullptr);
2350 }
2351}
2352
2353// Test that if applying a true "max bundle" offer, which uses ports of 0,
2354// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2355// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2356// successfully and media flows.
2357// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2358// TODO(deadbeef): Won't need this test once we start generating actual
2359// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002360TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002361 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2362 ASSERT_TRUE(CreatePeerConnectionWrappers());
2363 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002364 caller()->AddAudioVideoTracks();
2365 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002366 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2367 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2368 // but the first m= section.
2369 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2370 caller()->CreateAndSetAndSignalOffer();
2371 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002372 MediaExpectations media_expectations;
2373 media_expectations.ExpectBidirectionalAudioAndVideo();
2374 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002375}
2376
2377// Test that we can receive the audio output level from a remote audio track.
2378// TODO(deadbeef): Use a fake audio source and verify that the output level is
2379// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002380TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002381 ASSERT_TRUE(CreatePeerConnectionWrappers());
2382 ConnectFakeSignaling();
2383 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002384 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002385 caller()->CreateAndSetAndSignalOffer();
2386 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2387
2388 // Get the audio output level stats. Note that the level is not available
2389 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002390 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002391 kMaxWaitForFramesMs);
2392}
2393
2394// Test that an audio input level is reported.
2395// TODO(deadbeef): Use a fake audio source and verify that the input level is
2396// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002397TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002398 ASSERT_TRUE(CreatePeerConnectionWrappers());
2399 ConnectFakeSignaling();
2400 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002401 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002402 caller()->CreateAndSetAndSignalOffer();
2403 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2404
2405 // Get the audio input level stats. The level should be available very
2406 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002407 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002408 kMaxWaitForStatsMs);
2409}
2410
2411// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002412TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002413 ASSERT_TRUE(CreatePeerConnectionWrappers());
2414 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002415 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002416 // Do offer/answer, wait for the callee to receive some frames.
2417 caller()->CreateAndSetAndSignalOffer();
2418 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002419
2420 MediaExpectations media_expectations;
2421 media_expectations.CalleeExpectsSomeAudioAndVideo();
2422 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002423
2424 // Get a handle to the remote tracks created, so they can be used as GetStats
2425 // filters.
Steve Anton15324772018-01-16 10:26:49 -08002426 for (auto receiver : callee()->pc()->GetReceivers()) {
2427 // We received frames, so we definitely should have nonzero "received bytes"
2428 // stats at this point.
2429 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2430 0);
2431 }
deadbeef1dcb1642017-03-29 21:08:16 -07002432}
2433
2434// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002435TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002436 ASSERT_TRUE(CreatePeerConnectionWrappers());
2437 ConnectFakeSignaling();
2438 auto audio_track = caller()->CreateLocalAudioTrack();
2439 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002440 caller()->AddTrack(audio_track);
2441 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002442 // Do offer/answer, wait for the callee to receive some frames.
2443 caller()->CreateAndSetAndSignalOffer();
2444 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002445 MediaExpectations media_expectations;
2446 media_expectations.CalleeExpectsSomeAudioAndVideo();
2447 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002448
2449 // The callee received frames, so we definitely should have nonzero "sent
2450 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002451 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2452 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2453}
2454
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002455// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002456TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002457 ASSERT_TRUE(CreatePeerConnectionWrappers());
2458 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002459 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002460
Steve Anton15324772018-01-16 10:26:49 -08002461 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002462
2463 // Do offer/answer, wait for the callee to receive some frames.
2464 caller()->CreateAndSetAndSignalOffer();
2465 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2466
2467 // Get the remote audio track created on the receiver, so they can be used as
2468 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002469 auto receivers = callee()->pc()->GetReceivers();
2470 ASSERT_EQ(1u, receivers.size());
2471 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002472
2473 // Get the audio output level stats. Note that the level is not available
2474 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002475 EXPECT_TRUE_WAIT(
2476 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2477 0,
2478 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002479}
2480
deadbeefd8ad7882017-04-18 16:01:17 -07002481// Test that we can get stats (using the new stats implemnetation) for
2482// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2483// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002484TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002485 GetStatsForUnsignaledStreamWithNewStatsApi) {
2486 ASSERT_TRUE(CreatePeerConnectionWrappers());
2487 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002488 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002489 // Remove SSRCs and MSIDs from the received offer SDP.
2490 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2491 caller()->CreateAndSetAndSignalOffer();
2492 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002493 MediaExpectations media_expectations;
2494 media_expectations.CalleeExpectsSomeAudio(1);
2495 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002496
2497 // We received a frame, so we should have nonzero "bytes received" stats for
2498 // the unsignaled stream, if stats are working for it.
2499 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2500 callee()->NewGetStats();
2501 ASSERT_NE(nullptr, report);
2502 auto inbound_stream_stats =
2503 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2504 ASSERT_EQ(1U, inbound_stream_stats.size());
2505 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2506 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002507 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2508}
2509
2510// Test that we can successfully get the media related stats (audio level
2511// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002512TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002513 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2514 ASSERT_TRUE(CreatePeerConnectionWrappers());
2515 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002516 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002517 // Remove SSRCs and MSIDs from the received offer SDP.
2518 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2519 caller()->CreateAndSetAndSignalOffer();
2520 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002521 MediaExpectations media_expectations;
2522 media_expectations.CalleeExpectsSomeAudio(1);
2523 media_expectations.CalleeExpectsSomeVideo(1);
2524 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002525
2526 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2527 callee()->NewGetStats();
2528 ASSERT_NE(nullptr, report);
2529
2530 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2531 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2532 ASSERT_GE(audio_index, 0);
2533 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002534}
2535
deadbeef4e2deab2017-09-20 13:56:21 -07002536// Helper for test below.
2537void ModifySsrcs(cricket::SessionDescription* desc) {
2538 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002539 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002540 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002541 for (uint32_t& ssrc : stream.ssrcs) {
2542 ssrc = rtc::CreateRandomId();
2543 }
2544 }
2545 }
2546}
2547
2548// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2549// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2550// This should result in two "RTCInboundRTPStreamStats", but only one
2551// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2552// being reset to 0 once the SSRC change occurs.
2553//
2554// Regression test for this bug:
2555// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2556//
2557// The bug causes the track stats to only represent one of the two streams:
2558// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2559// that the track stat counters would reset to 0 when the new stream is
2560// received, and a 50% chance that they'll stop updating (while
2561// "concealed_samples" continues increasing, due to silence being generated for
2562// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002563TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002564 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002565 ASSERT_TRUE(CreatePeerConnectionWrappers());
2566 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002567 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002568 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2569 // that doesn't signal SSRCs (from the callee's perspective).
2570 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2571 caller()->CreateAndSetAndSignalOffer();
2572 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2573 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002574 {
2575 MediaExpectations media_expectations;
2576 media_expectations.CalleeExpectsSomeAudio(50);
2577 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2578 }
deadbeef4e2deab2017-09-20 13:56:21 -07002579 // Some audio frames were received, so we should have nonzero "samples
2580 // received" for the track.
2581 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2582 callee()->NewGetStats();
2583 ASSERT_NE(nullptr, report);
2584 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2585 ASSERT_EQ(1U, track_stats.size());
2586 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2587 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2588 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2589
2590 // Create a new offer and munge it to cause the caller to use a new SSRC.
2591 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2592 caller()->CreateAndSetAndSignalOffer();
2593 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2594 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2595 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002596 {
2597 MediaExpectations media_expectations;
2598 media_expectations.CalleeExpectsSomeAudio(25);
2599 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2600 }
deadbeef4e2deab2017-09-20 13:56:21 -07002601
2602 report = callee()->NewGetStats();
2603 ASSERT_NE(nullptr, report);
2604 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2605 ASSERT_EQ(1U, track_stats.size());
2606 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2607 // The "total samples received" stat should only be greater than it was
2608 // before.
2609 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2610 // Right now, the new SSRC will cause the counters to reset to 0.
2611 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2612
2613 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002614 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002615 // good sign that we're seeing stats from the old stream that's no longer
2616 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002617 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002618 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2619 EXPECT_LT(*track_stats[0]->concealed_samples,
2620 *track_stats[0]->total_samples_received *
2621 kAcceptableConcealedSamplesPercentage);
2622
2623 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2624 // sanity check that the SSRC really changed.
2625 // TODO(deadbeef): This isn't working right now, because we're not returning
2626 // *any* stats for the inactive stream. Uncomment when the bug is completely
2627 // fixed.
2628 // auto inbound_stream_stats =
2629 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2630 // ASSERT_EQ(2U, inbound_stream_stats.size());
2631}
2632
deadbeef1dcb1642017-03-29 21:08:16 -07002633// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002634TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002635 PeerConnectionFactory::Options dtls_10_options;
2636 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2637 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2638 dtls_10_options));
2639 ConnectFakeSignaling();
2640 // Do normal offer/answer and wait for some frames to be received in each
2641 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002642 caller()->AddAudioVideoTracks();
2643 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002644 caller()->CreateAndSetAndSignalOffer();
2645 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002646 MediaExpectations media_expectations;
2647 media_expectations.ExpectBidirectionalAudioAndVideo();
2648 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002649}
2650
2651// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002652TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002653 PeerConnectionFactory::Options dtls_10_options;
2654 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2655 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2656 dtls_10_options));
2657 ConnectFakeSignaling();
2658 // Register UMA observer before signaling begins.
2659 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
2660 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
2661 caller()->pc()->RegisterUMAObserver(caller_observer);
Steve Anton15324772018-01-16 10:26:49 -08002662 caller()->AddAudioVideoTracks();
2663 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002664 caller()->CreateAndSetAndSignalOffer();
2665 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2666 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002667 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002668 kDefaultTimeout);
2669 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002670 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002671 EXPECT_EQ(1,
2672 caller_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher,
2673 kDefaultSrtpCryptoSuite));
2674}
2675
2676// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002677TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002678 PeerConnectionFactory::Options dtls_12_options;
2679 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2680 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2681 dtls_12_options));
2682 ConnectFakeSignaling();
2683 // Register UMA observer before signaling begins.
2684 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
2685 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
2686 caller()->pc()->RegisterUMAObserver(caller_observer);
Steve Anton15324772018-01-16 10:26:49 -08002687 caller()->AddAudioVideoTracks();
2688 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002689 caller()->CreateAndSetAndSignalOffer();
2690 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2691 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002692 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002693 kDefaultTimeout);
2694 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002695 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002696 EXPECT_EQ(1,
2697 caller_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher,
2698 kDefaultSrtpCryptoSuite));
2699}
2700
2701// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2702// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002703TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002704 PeerConnectionFactory::Options caller_options;
2705 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2706 PeerConnectionFactory::Options callee_options;
2707 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2708 ASSERT_TRUE(
2709 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2710 ConnectFakeSignaling();
2711 // Do normal offer/answer and wait for some frames to be received in each
2712 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002713 caller()->AddAudioVideoTracks();
2714 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002715 caller()->CreateAndSetAndSignalOffer();
2716 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002717 MediaExpectations media_expectations;
2718 media_expectations.ExpectBidirectionalAudioAndVideo();
2719 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002720}
2721
2722// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2723// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002724TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07002725 PeerConnectionFactory::Options caller_options;
2726 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2727 PeerConnectionFactory::Options callee_options;
2728 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2729 ASSERT_TRUE(
2730 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2731 ConnectFakeSignaling();
2732 // Do normal offer/answer and wait for some frames to be received in each
2733 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002734 caller()->AddAudioVideoTracks();
2735 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002736 caller()->CreateAndSetAndSignalOffer();
2737 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002738 MediaExpectations media_expectations;
2739 media_expectations.ExpectBidirectionalAudioAndVideo();
2740 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002741}
2742
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002743// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2744// works as expected; the cipher should only be used if enabled by both sides.
2745TEST_P(PeerConnectionIntegrationTest,
2746 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2747 PeerConnectionFactory::Options caller_options;
2748 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2749 PeerConnectionFactory::Options callee_options;
2750 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2751 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2752 TestNegotiatedCipherSuite(caller_options, callee_options,
2753 expected_cipher_suite);
2754}
2755
2756TEST_P(PeerConnectionIntegrationTest,
2757 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2758 PeerConnectionFactory::Options caller_options;
2759 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2760 PeerConnectionFactory::Options callee_options;
2761 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2762 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2763 TestNegotiatedCipherSuite(caller_options, callee_options,
2764 expected_cipher_suite);
2765}
2766
2767TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2768 PeerConnectionFactory::Options caller_options;
2769 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2770 PeerConnectionFactory::Options callee_options;
2771 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2772 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2773 TestNegotiatedCipherSuite(caller_options, callee_options,
2774 expected_cipher_suite);
2775}
2776
deadbeef1dcb1642017-03-29 21:08:16 -07002777// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002778TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002779 bool local_gcm_enabled = false;
2780 bool remote_gcm_enabled = false;
2781 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2782 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2783 expected_cipher_suite);
2784}
2785
2786// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002787TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002788 bool local_gcm_enabled = true;
2789 bool remote_gcm_enabled = true;
2790 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2791 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2792 expected_cipher_suite);
2793}
2794
2795// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002796TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002797 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2798 bool local_gcm_enabled = true;
2799 bool remote_gcm_enabled = false;
2800 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2801 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2802 expected_cipher_suite);
2803}
2804
2805// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002806TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002807 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2808 bool local_gcm_enabled = false;
2809 bool remote_gcm_enabled = true;
2810 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2811 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2812 expected_cipher_suite);
2813}
2814
deadbeef7914b8c2017-04-21 03:23:33 -07002815// Verify that media can be transmitted end-to-end when GCM crypto suites are
2816// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2817// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2818// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002819TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07002820 PeerConnectionFactory::Options gcm_options;
2821 gcm_options.crypto_options.enable_gcm_crypto_suites = true;
2822 ASSERT_TRUE(
2823 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2824 ConnectFakeSignaling();
2825 // Do normal offer/answer and wait for some frames to be received in each
2826 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002827 caller()->AddAudioVideoTracks();
2828 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07002829 caller()->CreateAndSetAndSignalOffer();
2830 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002831 MediaExpectations media_expectations;
2832 media_expectations.ExpectBidirectionalAudioAndVideo();
2833 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07002834}
2835
deadbeef1dcb1642017-03-29 21:08:16 -07002836// This test sets up a call between two parties with audio, video and an RTP
2837// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002838TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07002839 FakeConstraints setup_constraints;
2840 setup_constraints.SetAllowRtpDataChannels();
2841 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2842 &setup_constraints));
2843 ConnectFakeSignaling();
2844 // Expect that data channel created on caller side will show up for callee as
2845 // well.
2846 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002847 caller()->AddAudioVideoTracks();
2848 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002849 caller()->CreateAndSetAndSignalOffer();
2850 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2851 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002852 MediaExpectations media_expectations;
2853 media_expectations.ExpectBidirectionalAudioAndVideo();
2854 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002855 ASSERT_NE(nullptr, caller()->data_channel());
2856 ASSERT_NE(nullptr, callee()->data_channel());
2857 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2858 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2859
2860 // Ensure data can be sent in both directions.
2861 std::string data = "hello world";
2862 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2863 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2864 kDefaultTimeout);
2865 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2866 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2867 kDefaultTimeout);
2868}
2869
2870// Ensure that an RTP data channel is signaled as closed for the caller when
2871// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002872TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002873 RtpDataChannelSignaledClosedInCalleeOffer) {
2874 // Same procedure as above test.
2875 FakeConstraints setup_constraints;
2876 setup_constraints.SetAllowRtpDataChannels();
2877 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2878 &setup_constraints));
2879 ConnectFakeSignaling();
2880 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002881 caller()->AddAudioVideoTracks();
2882 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002883 caller()->CreateAndSetAndSignalOffer();
2884 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2885 ASSERT_NE(nullptr, caller()->data_channel());
2886 ASSERT_NE(nullptr, callee()->data_channel());
2887 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2888 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2889
2890 // Close the data channel on the callee, and do an updated offer/answer.
2891 callee()->data_channel()->Close();
2892 callee()->CreateAndSetAndSignalOffer();
2893 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2894 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2895 EXPECT_FALSE(callee()->data_observer()->IsOpen());
2896}
2897
2898// Tests that data is buffered in an RTP data channel until an observer is
2899// registered for it.
2900//
2901// NOTE: RTP data channels can receive data before the underlying
2902// transport has detected that a channel is writable and thus data can be
2903// received before the data channel state changes to open. That is hard to test
2904// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002905TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002906 DataBufferedUntilRtpDataChannelObserverRegistered) {
2907 // Use fake clock and simulated network delay so that we predictably can wait
2908 // until an SCTP message has been delivered without "sleep()"ing.
2909 rtc::ScopedFakeClock fake_clock;
2910 // Some things use a time of "0" as a special value, so we need to start out
2911 // the fake clock at a nonzero time.
2912 // TODO(deadbeef): Fix this.
2913 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
2914 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
2915 virtual_socket_server()->UpdateDelayDistribution();
2916
2917 FakeConstraints constraints;
2918 constraints.SetAllowRtpDataChannels();
2919 ASSERT_TRUE(
2920 CreatePeerConnectionWrappersWithConstraints(&constraints, &constraints));
2921 ConnectFakeSignaling();
2922 caller()->CreateDataChannel();
2923 caller()->CreateAndSetAndSignalOffer();
2924 ASSERT_TRUE(caller()->data_channel() != nullptr);
2925 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
2926 kDefaultTimeout, fake_clock);
2927 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
2928 kDefaultTimeout, fake_clock);
2929 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
2930 callee()->data_channel()->state(), kDefaultTimeout,
2931 fake_clock);
2932
2933 // Unregister the observer which is normally automatically registered.
2934 callee()->data_channel()->UnregisterObserver();
2935 // Send data and advance fake clock until it should have been received.
2936 std::string data = "hello world";
2937 caller()->data_channel()->Send(DataBuffer(data));
2938 SIMULATED_WAIT(false, 50, fake_clock);
2939
2940 // Attach data channel and expect data to be received immediately. Note that
2941 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
2942 // further, but data can be received even if the callback is asynchronous.
2943 MockDataChannelObserver new_observer(callee()->data_channel());
2944 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
2945 fake_clock);
2946}
2947
2948// This test sets up a call between two parties with audio, video and but only
2949// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002950TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07002951 FakeConstraints setup_constraints_1;
2952 setup_constraints_1.SetAllowRtpDataChannels();
2953 // Must disable DTLS to make negotiation succeed.
2954 setup_constraints_1.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
2955 false);
2956 FakeConstraints setup_constraints_2;
2957 setup_constraints_2.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
2958 false);
2959 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(
2960 &setup_constraints_1, &setup_constraints_2));
2961 ConnectFakeSignaling();
2962 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002963 caller()->AddAudioVideoTracks();
2964 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002965 caller()->CreateAndSetAndSignalOffer();
2966 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2967 // The caller should still have a data channel, but it should be closed, and
2968 // one should ever have been created for the callee.
2969 EXPECT_TRUE(caller()->data_channel() != nullptr);
2970 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2971 EXPECT_EQ(nullptr, callee()->data_channel());
2972}
2973
2974// This test sets up a call between two parties with audio, and video. When
2975// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002976TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002977 FakeConstraints setup_constraints;
2978 setup_constraints.SetAllowRtpDataChannels();
2979 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2980 &setup_constraints));
2981 ConnectFakeSignaling();
2982 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08002983 caller()->AddAudioVideoTracks();
2984 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002985 caller()->CreateAndSetAndSignalOffer();
2986 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2987 // Create data channel and do new offer and answer.
2988 caller()->CreateDataChannel();
2989 caller()->CreateAndSetAndSignalOffer();
2990 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2991 ASSERT_NE(nullptr, caller()->data_channel());
2992 ASSERT_NE(nullptr, callee()->data_channel());
2993 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2994 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2995 // Ensure data can be sent in both directions.
2996 std::string data = "hello world";
2997 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2998 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2999 kDefaultTimeout);
3000 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3001 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3002 kDefaultTimeout);
3003}
3004
3005#ifdef HAVE_SCTP
3006
3007// This test sets up a call between two parties with audio, video and an SCTP
3008// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003009TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003010 ASSERT_TRUE(CreatePeerConnectionWrappers());
3011 ConnectFakeSignaling();
3012 // Expect that data channel created on caller side will show up for callee as
3013 // well.
3014 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003015 caller()->AddAudioVideoTracks();
3016 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003017 caller()->CreateAndSetAndSignalOffer();
3018 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3019 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003020 MediaExpectations media_expectations;
3021 media_expectations.ExpectBidirectionalAudioAndVideo();
3022 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003023 // Caller data channel should already exist (it created one). Callee data
3024 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3025 ASSERT_NE(nullptr, caller()->data_channel());
3026 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3027 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3028 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3029
3030 // Ensure data can be sent in both directions.
3031 std::string data = "hello world";
3032 caller()->data_channel()->Send(DataBuffer(data));
3033 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3034 kDefaultTimeout);
3035 callee()->data_channel()->Send(DataBuffer(data));
3036 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3037 kDefaultTimeout);
3038}
3039
3040// Ensure that when the callee closes an SCTP data channel, the closing
3041// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003042TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003043 // Same procedure as above test.
3044 ASSERT_TRUE(CreatePeerConnectionWrappers());
3045 ConnectFakeSignaling();
3046 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003047 caller()->AddAudioVideoTracks();
3048 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003049 caller()->CreateAndSetAndSignalOffer();
3050 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3051 ASSERT_NE(nullptr, caller()->data_channel());
3052 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3053 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3054 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3055
3056 // Close the data channel on the callee side, and wait for it to reach the
3057 // "closed" state on both sides.
3058 callee()->data_channel()->Close();
3059 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3060 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3061}
3062
Seth Hampson2f0d7022018-02-20 11:54:42 -08003063TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003064 ASSERT_TRUE(CreatePeerConnectionWrappers());
3065 ConnectFakeSignaling();
3066 webrtc::DataChannelInit init;
3067 init.id = 53;
3068 init.maxRetransmits = 52;
3069 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003070 caller()->AddAudioVideoTracks();
3071 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003072 caller()->CreateAndSetAndSignalOffer();
3073 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003074 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3075 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 11:41:54 -07003076 EXPECT_EQ(init.id, callee()->data_channel()->id());
3077 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3078 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3079 EXPECT_FALSE(callee()->data_channel()->negotiated());
3080}
3081
deadbeef1dcb1642017-03-29 21:08:16 -07003082// Test usrsctp's ability to process unordered data stream, where data actually
3083// arrives out of order using simulated delays. Previously there have been some
3084// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003085TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003086 // Introduce random network delays.
3087 // Otherwise it's not a true "unordered" test.
3088 virtual_socket_server()->set_delay_mean(20);
3089 virtual_socket_server()->set_delay_stddev(5);
3090 virtual_socket_server()->UpdateDelayDistribution();
3091 // Normal procedure, but with unordered data channel config.
3092 ASSERT_TRUE(CreatePeerConnectionWrappers());
3093 ConnectFakeSignaling();
3094 webrtc::DataChannelInit init;
3095 init.ordered = false;
3096 caller()->CreateDataChannel(&init);
3097 caller()->CreateAndSetAndSignalOffer();
3098 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3099 ASSERT_NE(nullptr, caller()->data_channel());
3100 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3101 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3102 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3103
3104 static constexpr int kNumMessages = 100;
3105 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3106 static constexpr size_t kMaxMessageSize = 4096;
3107 // Create and send random messages.
3108 std::vector<std::string> sent_messages;
3109 for (int i = 0; i < kNumMessages; ++i) {
3110 size_t length =
3111 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3112 std::string message;
3113 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3114 caller()->data_channel()->Send(DataBuffer(message));
3115 callee()->data_channel()->Send(DataBuffer(message));
3116 sent_messages.push_back(message);
3117 }
3118
3119 // Wait for all messages to be received.
3120 EXPECT_EQ_WAIT(kNumMessages,
3121 caller()->data_observer()->received_message_count(),
3122 kDefaultTimeout);
3123 EXPECT_EQ_WAIT(kNumMessages,
3124 callee()->data_observer()->received_message_count(),
3125 kDefaultTimeout);
3126
3127 // Sort and compare to make sure none of the messages were corrupted.
3128 std::vector<std::string> caller_received_messages =
3129 caller()->data_observer()->messages();
3130 std::vector<std::string> callee_received_messages =
3131 callee()->data_observer()->messages();
3132 std::sort(sent_messages.begin(), sent_messages.end());
3133 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3134 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3135 EXPECT_EQ(sent_messages, caller_received_messages);
3136 EXPECT_EQ(sent_messages, callee_received_messages);
3137}
3138
3139// This test sets up a call between two parties with audio, and video. When
3140// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003141TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003142 ASSERT_TRUE(CreatePeerConnectionWrappers());
3143 ConnectFakeSignaling();
3144 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003145 caller()->AddAudioVideoTracks();
3146 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003147 caller()->CreateAndSetAndSignalOffer();
3148 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3149 // Create data channel and do new offer and answer.
3150 caller()->CreateDataChannel();
3151 caller()->CreateAndSetAndSignalOffer();
3152 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3153 // Caller data channel should already exist (it created one). Callee data
3154 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3155 ASSERT_NE(nullptr, caller()->data_channel());
3156 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3157 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3158 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3159 // Ensure data can be sent in both directions.
3160 std::string data = "hello world";
3161 caller()->data_channel()->Send(DataBuffer(data));
3162 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3163 kDefaultTimeout);
3164 callee()->data_channel()->Send(DataBuffer(data));
3165 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3166 kDefaultTimeout);
3167}
3168
deadbeef7914b8c2017-04-21 03:23:33 -07003169// Set up a connection initially just using SCTP data channels, later upgrading
3170// to audio/video, ensuring frames are received end-to-end. Effectively the
3171// inverse of the test above.
3172// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003173TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003174 ASSERT_TRUE(CreatePeerConnectionWrappers());
3175 ConnectFakeSignaling();
3176 // Do initial offer/answer with just data channel.
3177 caller()->CreateDataChannel();
3178 caller()->CreateAndSetAndSignalOffer();
3179 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3180 // Wait until data can be sent over the data channel.
3181 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3182 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3183 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3184
3185 // Do subsequent offer/answer with two-way audio and video. Audio and video
3186 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003187 caller()->AddAudioVideoTracks();
3188 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003189 caller()->CreateAndSetAndSignalOffer();
3190 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003191 MediaExpectations media_expectations;
3192 media_expectations.ExpectBidirectionalAudioAndVideo();
3193 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003194}
3195
deadbeef8b7e9ad2017-05-25 09:38:55 -07003196static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 09:38:55 -07003197 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 15:14:30 -08003198 GetFirstDataContentDescription(desc);
3199 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003200 dcd_offer->set_use_sctpmap(false);
3201 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3202}
3203
3204// Test that the data channel works when a spec-compliant SCTP m= section is
3205// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3206// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003207TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003208 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3209 ASSERT_TRUE(CreatePeerConnectionWrappers());
3210 ConnectFakeSignaling();
3211 caller()->CreateDataChannel();
3212 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3213 caller()->CreateAndSetAndSignalOffer();
3214 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3215 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3216 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3217 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3218
3219 // Ensure data can be sent in both directions.
3220 std::string data = "hello world";
3221 caller()->data_channel()->Send(DataBuffer(data));
3222 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3223 kDefaultTimeout);
3224 callee()->data_channel()->Send(DataBuffer(data));
3225 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3226 kDefaultTimeout);
3227}
3228
deadbeef1dcb1642017-03-29 21:08:16 -07003229#endif // HAVE_SCTP
3230
3231// Test that the ICE connection and gathering states eventually reach
3232// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003233TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003234 ASSERT_TRUE(CreatePeerConnectionWrappers());
3235 ConnectFakeSignaling();
3236 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003237 caller()->AddAudioVideoTracks();
3238 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003239 caller()->CreateAndSetAndSignalOffer();
3240 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3241 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3242 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3243 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3244 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3245 // After the best candidate pair is selected and all candidates are signaled,
3246 // the ICE connection state should reach "complete".
3247 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3248 // answerer/"callee" by default) only reaches "connected". When this is
3249 // fixed, this test should be updated.
3250 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3251 caller()->ice_connection_state(), kDefaultTimeout);
3252 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3253 callee()->ice_connection_state(), kDefaultTimeout);
3254}
3255
Steve Antonede9ca52017-10-16 13:04:27 -07003256// Test that firewalling the ICE connection causes the clients to identify the
3257// disconnected state and then removing the firewall causes them to reconnect.
3258class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003259 : public PeerConnectionIntegrationBaseTest,
3260 public ::testing::WithParamInterface<
3261 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003262 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003263 PeerConnectionIntegrationIceStatesTest()
3264 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3265 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003266 }
3267
3268 void StartStunServer(const SocketAddress& server_address) {
3269 stun_server_.reset(
3270 cricket::TestStunServer::Create(network_thread(), server_address));
3271 }
3272
3273 bool TestIPv6() {
3274 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3275 }
3276
3277 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 16:57:45 -07003278 network_thread()->Invoke<void>(
3279 RTC_FROM_HERE,
3280 rtc::Bind(&cricket::PortAllocator::set_flags,
3281 caller()->port_allocator(), port_allocator_flags_));
3282 network_thread()->Invoke<void>(
3283 RTC_FROM_HERE,
3284 rtc::Bind(&cricket::PortAllocator::set_flags,
3285 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 13:04:27 -07003286 }
3287
3288 std::vector<SocketAddress> CallerAddresses() {
3289 std::vector<SocketAddress> addresses;
3290 addresses.push_back(SocketAddress("1.1.1.1", 0));
3291 if (TestIPv6()) {
3292 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3293 }
3294 return addresses;
3295 }
3296
3297 std::vector<SocketAddress> CalleeAddresses() {
3298 std::vector<SocketAddress> addresses;
3299 addresses.push_back(SocketAddress("2.2.2.2", 0));
3300 if (TestIPv6()) {
3301 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3302 }
3303 return addresses;
3304 }
3305
3306 void SetUpNetworkInterfaces() {
3307 // Remove the default interfaces added by the test infrastructure.
3308 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3309 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3310
3311 // Add network addresses for test.
3312 for (const auto& caller_address : CallerAddresses()) {
3313 caller()->network()->AddInterface(caller_address);
3314 }
3315 for (const auto& callee_address : CalleeAddresses()) {
3316 callee()->network()->AddInterface(callee_address);
3317 }
3318 }
3319
3320 private:
3321 uint32_t port_allocator_flags_;
3322 std::unique_ptr<cricket::TestStunServer> stun_server_;
3323};
3324
3325// Tests that the PeerConnection goes through all the ICE gathering/connection
3326// states over the duration of the call. This includes Disconnected and Failed
3327// states, induced by putting a firewall between the peers and waiting for them
3328// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003329TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3330 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3331 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3332 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 13:04:27 -07003333
3334 const SocketAddress kStunServerAddress =
3335 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3336 StartStunServer(kStunServerAddress);
3337
3338 PeerConnectionInterface::RTCConfiguration config;
3339 PeerConnectionInterface::IceServer ice_stun_server;
3340 ice_stun_server.urls.push_back(
3341 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3342 kStunServerAddress.PortAsString());
3343 config.servers.push_back(ice_stun_server);
3344
3345 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3346 ConnectFakeSignaling();
3347 SetPortAllocatorFlags();
3348 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003349 caller()->AddAudioVideoTracks();
3350 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003351
3352 // Initial state before anything happens.
3353 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3354 caller()->ice_gathering_state());
3355 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3356 caller()->ice_connection_state());
3357
3358 // Start the call by creating the offer, setting it as the local description,
3359 // then sending it to the peer who will respond with an answer. This happens
3360 // asynchronously so that we can watch the states as it runs in the
3361 // background.
3362 caller()->CreateAndSetAndSignalOffer();
3363
Steve Anton83119dd2017-11-10 16:19:52 -08003364 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3365 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003366
3367 // Verify that the observer was notified of the intermediate transitions.
3368 EXPECT_THAT(caller()->ice_connection_state_history(),
3369 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3370 PeerConnectionInterface::kIceConnectionConnected,
3371 PeerConnectionInterface::kIceConnectionCompleted));
3372 EXPECT_THAT(caller()->ice_gathering_state_history(),
3373 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3374 PeerConnectionInterface::kIceGatheringComplete));
3375
3376 // Block connections to/from the caller and wait for ICE to become
3377 // disconnected.
3378 for (const auto& caller_address : CallerAddresses()) {
3379 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3380 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003381 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-10 16:19:52 -08003382 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3383 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003384
3385 // Let ICE re-establish by removing the firewall rules.
3386 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01003387 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-10 16:19:52 -08003388 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3389 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003390
3391 // According to RFC7675, if there is no response within 30 seconds then the
3392 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08003393 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07003394 constexpr int kConsentTimeout = 30000;
3395 for (const auto& caller_address : CallerAddresses()) {
3396 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3397 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003398 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-10 16:19:52 -08003399 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3400 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003401}
3402
3403// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3404// and that the statistics in the metric observers are updated correctly.
3405TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3406 ASSERT_TRUE(CreatePeerConnectionWrappers());
3407 ConnectFakeSignaling();
3408 SetPortAllocatorFlags();
3409 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003410 caller()->AddAudioVideoTracks();
3411 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003412
3413 rtc::scoped_refptr<webrtc::FakeMetricsObserver> metrics_observer(
3414 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>());
3415 caller()->pc()->RegisterUMAObserver(metrics_observer.get());
3416
3417 caller()->CreateAndSetAndSignalOffer();
3418
3419 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3420
3421 const int num_best_ipv4 = metrics_observer->GetEnumCounter(
3422 webrtc::kEnumCounterAddressFamily, webrtc::kBestConnections_IPv4);
3423 const int num_best_ipv6 = metrics_observer->GetEnumCounter(
3424 webrtc::kEnumCounterAddressFamily, webrtc::kBestConnections_IPv6);
3425 if (TestIPv6()) {
3426 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3427 // connection.
3428 EXPECT_EQ(0u, num_best_ipv4);
3429 EXPECT_EQ(1u, num_best_ipv6);
3430 } else {
3431 EXPECT_EQ(1u, num_best_ipv4);
3432 EXPECT_EQ(0u, num_best_ipv6);
3433 }
3434
3435 EXPECT_EQ(0u, metrics_observer->GetEnumCounter(
3436 webrtc::kEnumCounterIceCandidatePairTypeUdp,
3437 webrtc::kIceCandidatePairHostHost));
3438 EXPECT_EQ(1u, metrics_observer->GetEnumCounter(
3439 webrtc::kEnumCounterIceCandidatePairTypeUdp,
3440 webrtc::kIceCandidatePairHostPublicHostPublic));
3441}
3442
3443constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3444 cricket::PORTALLOCATOR_DISABLE_STUN |
3445 cricket::PORTALLOCATOR_DISABLE_RELAY;
3446constexpr uint32_t kFlagsIPv6NoStun =
3447 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3448 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3449constexpr uint32_t kFlagsIPv4Stun =
3450 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3451
Seth Hampson2f0d7022018-02-20 11:54:42 -08003452INSTANTIATE_TEST_CASE_P(
3453 PeerConnectionIntegrationTest,
3454 PeerConnectionIntegrationIceStatesTest,
3455 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3456 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3457 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3458 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07003459
deadbeef1dcb1642017-03-29 21:08:16 -07003460// This test sets up a call between two parties with audio and video.
3461// During the call, the caller restarts ICE and the test verifies that
3462// new ICE candidates are generated and audio and video still can flow, and the
3463// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003464TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07003465 ASSERT_TRUE(CreatePeerConnectionWrappers());
3466 ConnectFakeSignaling();
3467 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08003468 caller()->AddAudioVideoTracks();
3469 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003470 caller()->CreateAndSetAndSignalOffer();
3471 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3472 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3473 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3474 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3475 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3476
3477 // To verify that the ICE restart actually occurs, get
3478 // ufrag/password/candidates before and after restart.
3479 // Create an SDP string of the first audio candidate for both clients.
3480 const webrtc::IceCandidateCollection* audio_candidates_caller =
3481 caller()->pc()->local_description()->candidates(0);
3482 const webrtc::IceCandidateCollection* audio_candidates_callee =
3483 callee()->pc()->local_description()->candidates(0);
3484 ASSERT_GT(audio_candidates_caller->count(), 0u);
3485 ASSERT_GT(audio_candidates_callee->count(), 0u);
3486 std::string caller_candidate_pre_restart;
3487 ASSERT_TRUE(
3488 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3489 std::string callee_candidate_pre_restart;
3490 ASSERT_TRUE(
3491 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3492 const cricket::SessionDescription* desc =
3493 caller()->pc()->local_description()->description();
3494 std::string caller_ufrag_pre_restart =
3495 desc->transport_infos()[0].description.ice_ufrag;
3496 desc = callee()->pc()->local_description()->description();
3497 std::string callee_ufrag_pre_restart =
3498 desc->transport_infos()[0].description.ice_ufrag;
3499
3500 // Have the caller initiate an ICE restart.
3501 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3502 caller()->CreateAndSetAndSignalOffer();
3503 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3504 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3505 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3506 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3507 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3508
3509 // Grab the ufrags/candidates again.
3510 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3511 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3512 ASSERT_GT(audio_candidates_caller->count(), 0u);
3513 ASSERT_GT(audio_candidates_callee->count(), 0u);
3514 std::string caller_candidate_post_restart;
3515 ASSERT_TRUE(
3516 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3517 std::string callee_candidate_post_restart;
3518 ASSERT_TRUE(
3519 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3520 desc = caller()->pc()->local_description()->description();
3521 std::string caller_ufrag_post_restart =
3522 desc->transport_infos()[0].description.ice_ufrag;
3523 desc = callee()->pc()->local_description()->description();
3524 std::string callee_ufrag_post_restart =
3525 desc->transport_infos()[0].description.ice_ufrag;
3526 // Sanity check that an ICE restart was actually negotiated in SDP.
3527 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3528 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3529 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3530 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3531
3532 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003533 MediaExpectations media_expectations;
3534 media_expectations.ExpectBidirectionalAudioAndVideo();
3535 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003536}
3537
3538// Verify that audio/video can be received end-to-end when ICE renomination is
3539// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003540TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07003541 PeerConnectionInterface::RTCConfiguration config;
3542 config.enable_ice_renomination = true;
3543 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3544 ConnectFakeSignaling();
3545 // Do normal offer/answer and wait for some frames to be received in each
3546 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003547 caller()->AddAudioVideoTracks();
3548 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003549 caller()->CreateAndSetAndSignalOffer();
3550 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3551 // Sanity check that ICE renomination was actually negotiated.
3552 const cricket::SessionDescription* desc =
3553 caller()->pc()->local_description()->description();
3554 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003555 ASSERT_NE(
3556 info.description.transport_options.end(),
3557 std::find(info.description.transport_options.begin(),
3558 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003559 }
3560 desc = callee()->pc()->local_description()->description();
3561 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003562 ASSERT_NE(
3563 info.description.transport_options.end(),
3564 std::find(info.description.transport_options.begin(),
3565 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003566 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08003567 MediaExpectations media_expectations;
3568 media_expectations.ExpectBidirectionalAudioAndVideo();
3569 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003570}
3571
Steve Anton6f25b092017-10-23 09:39:20 -07003572// With a max bundle policy and RTCP muxing, adding a new media description to
3573// the connection should not affect ICE at all because the new media will use
3574// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003575TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003576 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07003577 PeerConnectionInterface::RTCConfiguration config;
3578 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3579 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3580 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3581 config, PeerConnectionInterface::RTCConfiguration()));
3582 ConnectFakeSignaling();
3583
Steve Anton15324772018-01-16 10:26:49 -08003584 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003585 caller()->CreateAndSetAndSignalOffer();
3586 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07003587 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3588 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07003589
3590 caller()->clear_ice_connection_state_history();
3591
Steve Anton15324772018-01-16 10:26:49 -08003592 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003593 caller()->CreateAndSetAndSignalOffer();
3594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3595
3596 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3597}
3598
deadbeef1dcb1642017-03-29 21:08:16 -07003599// This test sets up a call between two parties with audio and video. It then
3600// renegotiates setting the video m-line to "port 0", then later renegotiates
3601// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003602TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003603 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3604 ASSERT_TRUE(CreatePeerConnectionWrappers());
3605 ConnectFakeSignaling();
3606
3607 // Do initial negotiation, only sending media from the caller. Will result in
3608 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08003609 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003610 caller()->CreateAndSetAndSignalOffer();
3611 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3612
3613 // Negotiate again, disabling the video "m=" section (the callee will set the
3614 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003615 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3616 PeerConnectionInterface::RTCOfferAnswerOptions options;
3617 options.offer_to_receive_video = 0;
3618 callee()->SetOfferAnswerOptions(options);
3619 } else {
3620 callee()->SetRemoteOfferHandler([this] {
3621 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3622 });
3623 }
deadbeef1dcb1642017-03-29 21:08:16 -07003624 caller()->CreateAndSetAndSignalOffer();
3625 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3626 // Sanity check that video "m=" section was actually rejected.
3627 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3628 callee()->pc()->local_description()->description());
3629 ASSERT_NE(nullptr, answer_video_content);
3630 ASSERT_TRUE(answer_video_content->rejected);
3631
3632 // Enable video and do negotiation again, making sure video is received
3633 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003634 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3635 PeerConnectionInterface::RTCOfferAnswerOptions options;
3636 options.offer_to_receive_video = 1;
3637 callee()->SetOfferAnswerOptions(options);
3638 } else {
3639 // The caller's transceiver is stopped, so we need to add another track.
3640 auto caller_transceiver =
3641 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3642 EXPECT_TRUE(caller_transceiver->stopped());
3643 caller()->AddVideoTrack();
3644 }
3645 callee()->AddVideoTrack();
3646 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07003647 caller()->CreateAndSetAndSignalOffer();
3648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003649
deadbeef1dcb1642017-03-29 21:08:16 -07003650 // Verify the caller receives frames from the newly added stream, and the
3651 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003652 MediaExpectations media_expectations;
3653 media_expectations.CalleeExpectsSomeAudio();
3654 media_expectations.ExpectBidirectionalVideo();
3655 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003656}
3657
3658// This test sets up a Jsep call between two parties with external
3659// VideoDecoderFactory.
3660// TODO(holmer): Disabled due to sometimes crashing on buildbots.
3661// See issue webrtc/2378.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003662TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003663 DISABLED_EndToEndCallWithVideoDecoderFactory) {
3664 ASSERT_TRUE(CreatePeerConnectionWrappers());
3665 EnableVideoDecoderFactory();
3666 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003667 caller()->AddAudioVideoTracks();
3668 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003669 caller()->CreateAndSetAndSignalOffer();
3670 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003671 MediaExpectations media_expectations;
3672 media_expectations.ExpectBidirectionalAudioAndVideo();
3673 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003674}
3675
3676// This tests that if we negotiate after calling CreateSender but before we
3677// have a track, then set a track later, frames from the newly-set track are
3678// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003679TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07003680 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3681 ASSERT_TRUE(CreatePeerConnectionWrappers());
3682 ConnectFakeSignaling();
3683 auto caller_audio_sender =
3684 caller()->pc()->CreateSender("audio", "caller_stream");
3685 auto caller_video_sender =
3686 caller()->pc()->CreateSender("video", "caller_stream");
3687 auto callee_audio_sender =
3688 callee()->pc()->CreateSender("audio", "callee_stream");
3689 auto callee_video_sender =
3690 callee()->pc()->CreateSender("video", "callee_stream");
3691 caller()->CreateAndSetAndSignalOffer();
3692 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3693 // Wait for ICE to complete, without any tracks being set.
3694 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3695 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3696 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3697 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3698 // Now set the tracks, and expect frames to immediately start flowing.
3699 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3700 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3701 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3702 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08003703 MediaExpectations media_expectations;
3704 media_expectations.ExpectBidirectionalAudioAndVideo();
3705 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3706}
3707
3708// This tests that if we negotiate after calling AddTransceiver but before we
3709// have a track, then set a track later, frames from the newly-set tracks are
3710// received end-to-end.
3711TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3712 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3713 ASSERT_TRUE(CreatePeerConnectionWrappers());
3714 ConnectFakeSignaling();
3715 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3716 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3717 auto caller_audio_sender = audio_result.MoveValue()->sender();
3718 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3719 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3720 auto caller_video_sender = video_result.MoveValue()->sender();
3721 callee()->SetRemoteOfferHandler([this] {
3722 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3723 callee()->pc()->GetTransceivers()[0]->SetDirection(
3724 RtpTransceiverDirection::kSendRecv);
3725 callee()->pc()->GetTransceivers()[1]->SetDirection(
3726 RtpTransceiverDirection::kSendRecv);
3727 });
3728 caller()->CreateAndSetAndSignalOffer();
3729 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3730 // Wait for ICE to complete, without any tracks being set.
3731 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3732 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3733 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3734 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3735 // Now set the tracks, and expect frames to immediately start flowing.
3736 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3737 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3738 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3739 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3740 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3741 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3742 MediaExpectations media_expectations;
3743 media_expectations.ExpectBidirectionalAudioAndVideo();
3744 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003745}
3746
3747// This test verifies that a remote video track can be added via AddStream,
3748// and sent end-to-end. For this particular test, it's simply echoed back
3749// from the caller to the callee, rather than being forwarded to a third
3750// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003751TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07003752 ASSERT_TRUE(CreatePeerConnectionWrappers());
3753 ConnectFakeSignaling();
3754 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08003755 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003756 caller()->CreateAndSetAndSignalOffer();
3757 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3758 ASSERT_EQ(1, callee()->remote_streams()->count());
3759
3760 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3761 // time).
3762 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3763 callee()->CreateAndSetAndSignalOffer();
3764 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3765
Seth Hampson2f0d7022018-02-20 11:54:42 -08003766 MediaExpectations media_expectations;
3767 media_expectations.ExpectBidirectionalVideo();
3768 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003769}
3770
3771// Test that we achieve the expected end-to-end connection time, using a
3772// fake clock and simulated latency on the media and signaling paths.
3773// We use a TURN<->TURN connection because this is usually the quickest to
3774// set up initially, especially when we're confident the connection will work
3775// and can start sending media before we get a STUN response.
3776//
3777// With various optimizations enabled, here are the network delays we expect to
3778// be on the critical path:
3779// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3780// signaling answer (with DTLS fingerprint).
3781// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3782// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3783// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003784TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07003785 rtc::ScopedFakeClock fake_clock;
3786 // Some things use a time of "0" as a special value, so we need to start out
3787 // the fake clock at a nonzero time.
3788 // TODO(deadbeef): Fix this.
3789 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
3790
3791 static constexpr int media_hop_delay_ms = 50;
3792 static constexpr int signaling_trip_delay_ms = 500;
3793 // For explanation of these values, see comment above.
3794 static constexpr int required_media_hops = 9;
3795 static constexpr int required_signaling_trips = 2;
3796 // For internal delays (such as posting an event asychronously).
3797 static constexpr int allowed_internal_delay_ms = 20;
3798 static constexpr int total_connection_time_ms =
3799 media_hop_delay_ms * required_media_hops +
3800 signaling_trip_delay_ms * required_signaling_trips +
3801 allowed_internal_delay_ms;
3802
3803 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3804 3478};
3805 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3806 0};
3807 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3808 3478};
3809 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3810 0};
3811 cricket::TestTurnServer turn_server_1(network_thread(),
3812 turn_server_1_internal_address,
3813 turn_server_1_external_address);
3814 cricket::TestTurnServer turn_server_2(network_thread(),
3815 turn_server_2_internal_address,
3816 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003817
deadbeef1dcb1642017-03-29 21:08:16 -07003818 // Bypass permission check on received packets so media can be sent before
3819 // the candidate is signaled.
3820 turn_server_1.set_enable_permission_checks(false);
3821 turn_server_2.set_enable_permission_checks(false);
3822
3823 PeerConnectionInterface::RTCConfiguration client_1_config;
3824 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3825 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3826 ice_server_1.username = "test";
3827 ice_server_1.password = "test";
3828 client_1_config.servers.push_back(ice_server_1);
3829 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3830 client_1_config.presume_writable_when_fully_relayed = true;
3831
3832 PeerConnectionInterface::RTCConfiguration client_2_config;
3833 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3834 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3835 ice_server_2.username = "test";
3836 ice_server_2.password = "test";
3837 client_2_config.servers.push_back(ice_server_2);
3838 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3839 client_2_config.presume_writable_when_fully_relayed = true;
3840
3841 ASSERT_TRUE(
3842 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3843 // Set up the simulated delays.
3844 SetSignalingDelayMs(signaling_trip_delay_ms);
3845 ConnectFakeSignaling();
3846 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
3847 virtual_socket_server()->UpdateDelayDistribution();
3848
3849 // Set "offer to receive audio/video" without adding any tracks, so we just
3850 // set up ICE/DTLS with no media.
3851 PeerConnectionInterface::RTCOfferAnswerOptions options;
3852 options.offer_to_receive_audio = 1;
3853 options.offer_to_receive_video = 1;
3854 caller()->SetOfferAnswerOptions(options);
3855 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07003856 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
3857 fake_clock);
deadbeef1dcb1642017-03-29 21:08:16 -07003858 // Need to free the clients here since they're using things we created on
3859 // the stack.
3860 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
3861 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
3862}
3863
Jonas Orelandbdcee282017-10-10 14:01:40 +02003864// Verify that a TurnCustomizer passed in through RTCConfiguration
3865// is actually used by the underlying TURN candidate pair.
3866// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003867TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02003868 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3869 3478};
3870 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3871 0};
3872 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3873 3478};
3874 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3875 0};
3876 cricket::TestTurnServer turn_server_1(network_thread(),
3877 turn_server_1_internal_address,
3878 turn_server_1_external_address);
3879 cricket::TestTurnServer turn_server_2(network_thread(),
3880 turn_server_2_internal_address,
3881 turn_server_2_external_address);
3882
3883 PeerConnectionInterface::RTCConfiguration client_1_config;
3884 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3885 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3886 ice_server_1.username = "test";
3887 ice_server_1.password = "test";
3888 client_1_config.servers.push_back(ice_server_1);
3889 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3890 auto customizer1 = rtc::MakeUnique<cricket::TestTurnCustomizer>();
3891 client_1_config.turn_customizer = customizer1.get();
3892
3893 PeerConnectionInterface::RTCConfiguration client_2_config;
3894 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3895 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3896 ice_server_2.username = "test";
3897 ice_server_2.password = "test";
3898 client_2_config.servers.push_back(ice_server_2);
3899 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3900 auto customizer2 = rtc::MakeUnique<cricket::TestTurnCustomizer>();
3901 client_2_config.turn_customizer = customizer2.get();
3902
3903 ASSERT_TRUE(
3904 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3905 ConnectFakeSignaling();
3906
3907 // Set "offer to receive audio/video" without adding any tracks, so we just
3908 // set up ICE/DTLS with no media.
3909 PeerConnectionInterface::RTCOfferAnswerOptions options;
3910 options.offer_to_receive_audio = 1;
3911 options.offer_to_receive_video = 1;
3912 caller()->SetOfferAnswerOptions(options);
3913 caller()->CreateAndSetAndSignalOffer();
3914 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3915
3916 EXPECT_GT(customizer1->allow_channel_data_cnt_, 0u);
3917 EXPECT_GT(customizer1->modify_cnt_, 0u);
3918
3919 EXPECT_GT(customizer2->allow_channel_data_cnt_, 0u);
3920 EXPECT_GT(customizer2->modify_cnt_, 0u);
3921
3922 // Need to free the clients here since they're using things we created on
3923 // the stack.
3924 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
3925 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
3926}
3927
deadbeefc964d0b2017-04-03 10:03:35 -07003928// Test that audio and video flow end-to-end when codec names don't use the
3929// expected casing, given that they're supposed to be case insensitive. To test
3930// this, all but one codec is removed from each media description, and its
3931// casing is changed.
3932//
3933// In the past, this has regressed and caused crashes/black video, due to the
3934// fact that code at some layers was doing case-insensitive comparisons and
3935// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003936TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07003937 ASSERT_TRUE(CreatePeerConnectionWrappers());
3938 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003939 caller()->AddAudioVideoTracks();
3940 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07003941
3942 // Remove all but one audio/video codec (opus and VP8), and change the
3943 // casing of the caller's generated offer.
3944 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
3945 cricket::AudioContentDescription* audio =
3946 GetFirstAudioContentDescription(description);
3947 ASSERT_NE(nullptr, audio);
3948 auto audio_codecs = audio->codecs();
3949 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
3950 [](const cricket::AudioCodec& codec) {
3951 return codec.name != "opus";
3952 }),
3953 audio_codecs.end());
3954 ASSERT_EQ(1u, audio_codecs.size());
3955 audio_codecs[0].name = "OpUs";
3956 audio->set_codecs(audio_codecs);
3957
3958 cricket::VideoContentDescription* video =
3959 GetFirstVideoContentDescription(description);
3960 ASSERT_NE(nullptr, video);
3961 auto video_codecs = video->codecs();
3962 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
3963 [](const cricket::VideoCodec& codec) {
3964 return codec.name != "VP8";
3965 }),
3966 video_codecs.end());
3967 ASSERT_EQ(1u, video_codecs.size());
3968 video_codecs[0].name = "vP8";
3969 video->set_codecs(video_codecs);
3970 });
3971
3972 caller()->CreateAndSetAndSignalOffer();
3973 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3974
3975 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003976 MediaExpectations media_expectations;
3977 media_expectations.ExpectBidirectionalAudioAndVideo();
3978 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07003979}
3980
Seth Hampson2f0d7022018-02-20 11:54:42 -08003981TEST_P(PeerConnectionIntegrationTest, GetSources) {
hbos8d609f62017-04-10 07:39:05 -07003982 ASSERT_TRUE(CreatePeerConnectionWrappers());
3983 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08003984 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07003985 caller()->CreateAndSetAndSignalOffer();
3986 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07003987 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003988 MediaExpectations media_expectations;
3989 media_expectations.CalleeExpectsSomeAudio(1);
3990 ASSERT_TRUE(ExpectNewFrames(media_expectations));
hbos8d609f62017-04-10 07:39:05 -07003991 ASSERT_GT(callee()->pc()->GetReceivers().size(), 0u);
3992 auto receiver = callee()->pc()->GetReceivers()[0];
3993 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
3994
3995 auto contributing_sources = receiver->GetSources();
3996 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
3997 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
3998 contributing_sources[0].source_id());
3999}
4000
deadbeef2f425aa2017-04-14 10:41:32 -07004001// Test that if a track is removed and added again with a different stream ID,
4002// the new stream ID is successfully communicated in SDP and media continues to
4003// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004004// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4005// it will not reuse a transceiver that has already been sending. After creating
4006// a new transceiver it tries to create an offer with two senders of the same
4007// track ids and it fails.
4008TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004009 ASSERT_TRUE(CreatePeerConnectionWrappers());
4010 ConnectFakeSignaling();
4011
4012 rtc::scoped_refptr<MediaStreamInterface> stream_1 =
4013 caller()->pc_factory()->CreateLocalMediaStream("stream_1");
4014 rtc::scoped_refptr<MediaStreamInterface> stream_2 =
4015 caller()->pc_factory()->CreateLocalMediaStream("stream_2");
4016
4017 // Add track using stream 1, do offer/answer.
4018 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4019 caller()->CreateLocalAudioTrack();
4020 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
4021 caller()->pc()->AddTrack(track, {stream_1.get()});
4022 caller()->CreateAndSetAndSignalOffer();
4023 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004024 {
4025 MediaExpectations media_expectations;
4026 media_expectations.CalleeExpectsSomeAudio(1);
4027 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4028 }
deadbeef2f425aa2017-04-14 10:41:32 -07004029 // Remove the sender, and create a new one with the new stream.
4030 caller()->pc()->RemoveTrack(sender);
4031 sender = caller()->pc()->AddTrack(track, {stream_2.get()});
4032 caller()->CreateAndSetAndSignalOffer();
4033 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4034 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004035 {
4036 MediaExpectations media_expectations;
4037 media_expectations.CalleeExpectsSomeAudio();
4038 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4039 }
deadbeef2f425aa2017-04-14 10:41:32 -07004040}
4041
Seth Hampson2f0d7022018-02-20 11:54:42 -08004042TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004043 ASSERT_TRUE(CreatePeerConnectionWrappers());
4044 ConnectFakeSignaling();
4045
4046 auto output = rtc::MakeUnique<testing::NiceMock<MockRtcEventLogOutput>>();
4047 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4048 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4049 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004050 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4051 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004052
Steve Anton15324772018-01-16 10:26:49 -08004053 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004054 caller()->CreateAndSetAndSignalOffer();
4055 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4056}
4057
Steve Antonede9ca52017-10-16 13:04:27 -07004058// Test that if candidates are only signaled by applying full session
4059// descriptions (instead of using AddIceCandidate), the peers can connect to
4060// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004061TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004062 ASSERT_TRUE(CreatePeerConnectionWrappers());
4063 // Each side will signal the session descriptions but not candidates.
4064 ConnectFakeSignalingForSdpOnly();
4065
4066 // Add audio video track and exchange the initial offer/answer with media
4067 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004068 caller()->AddAudioVideoTracks();
4069 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004070 caller()->CreateAndSetAndSignalOffer();
4071
4072 // Wait for all candidates to be gathered on both the caller and callee.
4073 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4074 caller()->ice_gathering_state(), kDefaultTimeout);
4075 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4076 callee()->ice_gathering_state(), kDefaultTimeout);
4077
4078 // The candidates will now be included in the session description, so
4079 // signaling them will start the ICE connection.
4080 caller()->CreateAndSetAndSignalOffer();
4081 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4082
4083 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004084 MediaExpectations media_expectations;
4085 media_expectations.ExpectBidirectionalAudioAndVideo();
4086 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004087}
4088
henrika5f6bf242017-11-01 11:06:56 +01004089// Test that SetAudioPlayout can be used to disable audio playout from the
4090// start, then later enable it. This may be useful, for example, if the caller
4091// needs to play a local ringtone until some event occurs, after which it
4092// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004093TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004094 ASSERT_TRUE(CreatePeerConnectionWrappers());
4095 ConnectFakeSignaling();
4096
4097 // Set up audio-only call where audio playout is disabled on caller's side.
4098 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004099 caller()->AddAudioTrack();
4100 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004101 caller()->CreateAndSetAndSignalOffer();
4102 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4103
4104 // Pump messages for a second.
4105 WAIT(false, 1000);
4106 // Since audio playout is disabled, the caller shouldn't have received
4107 // anything (at the playout level, at least).
4108 EXPECT_EQ(0, caller()->audio_frames_received());
4109 // As a sanity check, make sure the callee (for which playout isn't disabled)
4110 // did still see frames on its audio level.
4111 ASSERT_GT(callee()->audio_frames_received(), 0);
4112
4113 // Enable playout again, and ensure audio starts flowing.
4114 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004115 MediaExpectations media_expectations;
4116 media_expectations.ExpectBidirectionalAudio();
4117 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004118}
4119
4120double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4121 auto report = pc->NewGetStats();
4122 auto track_stats_list =
4123 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4124 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4125 for (const auto* track_stats : track_stats_list) {
4126 if (track_stats->remote_source.is_defined() &&
4127 *track_stats->remote_source) {
4128 remote_track_stats = track_stats;
4129 break;
4130 }
4131 }
4132
4133 if (!remote_track_stats->total_audio_energy.is_defined()) {
4134 return 0.0;
4135 }
4136 return *remote_track_stats->total_audio_energy;
4137}
4138
4139// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4140// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004141TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004142 DisableAudioPlayoutStillGeneratesAudioStats) {
4143 ASSERT_TRUE(CreatePeerConnectionWrappers());
4144 ConnectFakeSignaling();
4145
4146 // Set up audio-only call where playout is disabled but audio-processing is
4147 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004148 caller()->AddAudioTrack();
4149 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004150 caller()->pc()->SetAudioPlayout(false);
4151
4152 caller()->CreateAndSetAndSignalOffer();
4153 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4154
4155 // Wait for the callee to receive audio stats.
4156 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4157}
4158
henrika4f167df2017-11-01 14:45:55 +01004159// Test that SetAudioRecording can be used to disable audio recording from the
4160// start, then later enable it. This may be useful, for example, if the caller
4161// wants to ensure that no audio resources are active before a certain state
4162// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004163TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01004164 ASSERT_TRUE(CreatePeerConnectionWrappers());
4165 ConnectFakeSignaling();
4166
4167 // Set up audio-only call where audio recording is disabled on caller's side.
4168 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08004169 caller()->AddAudioTrack();
4170 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01004171 caller()->CreateAndSetAndSignalOffer();
4172 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4173
4174 // Pump messages for a second.
4175 WAIT(false, 1000);
4176 // Since caller has disabled audio recording, the callee shouldn't have
4177 // received anything.
4178 EXPECT_EQ(0, callee()->audio_frames_received());
4179 // As a sanity check, make sure the caller did still see frames on its
4180 // audio level since audio recording is enabled on the calle side.
4181 ASSERT_GT(caller()->audio_frames_received(), 0);
4182
4183 // Enable audio recording again, and ensure audio starts flowing.
4184 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004185 MediaExpectations media_expectations;
4186 media_expectations.ExpectBidirectionalAudio();
4187 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01004188}
4189
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004190// Test that after closing PeerConnections, they stop sending any packets (ICE,
4191// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004192TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004193 // Set up audio/video/data, wait for some frames to be received.
4194 ASSERT_TRUE(CreatePeerConnectionWrappers());
4195 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004196 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004197#ifdef HAVE_SCTP
4198 caller()->CreateDataChannel();
4199#endif
4200 caller()->CreateAndSetAndSignalOffer();
4201 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004202 MediaExpectations media_expectations;
4203 media_expectations.CalleeExpectsSomeAudioAndVideo();
4204 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004205 // Close PeerConnections.
4206 caller()->pc()->Close();
4207 callee()->pc()->Close();
4208 // Pump messages for a second, and ensure no new packets end up sent.
4209 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4210 WAIT(false, 1000);
4211 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4212 EXPECT_EQ(sent_packets_a, sent_packets_b);
4213}
4214
Steve Anton7eca0932018-03-30 15:18:41 -07004215// Test that transport stats are generated by the RTCStatsCollector for a
4216// connection that only involves data channels. This is a regression test for
4217// crbug.com/826972.
4218#ifdef HAVE_SCTP
4219TEST_P(PeerConnectionIntegrationTest,
4220 TransportStatsReportedForDataChannelOnlyConnection) {
4221 ASSERT_TRUE(CreatePeerConnectionWrappers());
4222 ConnectFakeSignaling();
4223 caller()->CreateDataChannel();
4224
4225 caller()->CreateAndSetAndSignalOffer();
4226 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4227 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4228
4229 auto caller_report = caller()->NewGetStats();
4230 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4231 auto callee_report = callee()->NewGetStats();
4232 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4233}
4234#endif // HAVE_SCTP
4235
Seth Hampson2f0d7022018-02-20 11:54:42 -08004236INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4237 PeerConnectionIntegrationTest,
4238 Values(SdpSemantics::kPlanB,
4239 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08004240
Steve Anton74255ff2018-01-24 18:32:57 -08004241// Tests that verify interoperability between Plan B and Unified Plan
4242// PeerConnections.
4243class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004244 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08004245 public ::testing::WithParamInterface<
4246 std::tuple<SdpSemantics, SdpSemantics>> {
4247 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004248 // Setting the SdpSemantics for the base test to kDefault does not matter
4249 // because we specify not to use the test semantics when creating
4250 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08004251 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07004252 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08004253 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08004254 callee_semantics_(std::get<1>(GetParam())) {}
4255
4256 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07004257 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4258 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08004259 }
4260
4261 const SdpSemantics caller_semantics_;
4262 const SdpSemantics callee_semantics_;
4263};
4264
4265TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4266 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4267 ConnectFakeSignaling();
4268
4269 caller()->CreateAndSetAndSignalOffer();
4270 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4271}
4272
4273TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4274 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4275 ConnectFakeSignaling();
4276 auto audio_sender = caller()->AddAudioTrack();
4277
4278 caller()->CreateAndSetAndSignalOffer();
4279 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4280
4281 // Verify that one audio receiver has been created on the remote and that it
4282 // has the same track ID as the sending track.
4283 auto receivers = callee()->pc()->GetReceivers();
4284 ASSERT_EQ(1u, receivers.size());
4285 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4286 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4287
Seth Hampson2f0d7022018-02-20 11:54:42 -08004288 MediaExpectations media_expectations;
4289 media_expectations.CalleeExpectsSomeAudio();
4290 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004291}
4292
4293TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4294 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4295 ConnectFakeSignaling();
4296 auto video_sender = caller()->AddVideoTrack();
4297 auto audio_sender = caller()->AddAudioTrack();
4298
4299 caller()->CreateAndSetAndSignalOffer();
4300 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4301
4302 // Verify that one audio and one video receiver have been created on the
4303 // remote and that they have the same track IDs as the sending tracks.
4304 auto audio_receivers =
4305 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4306 ASSERT_EQ(1u, audio_receivers.size());
4307 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4308 auto video_receivers =
4309 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4310 ASSERT_EQ(1u, video_receivers.size());
4311 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4312
Seth Hampson2f0d7022018-02-20 11:54:42 -08004313 MediaExpectations media_expectations;
4314 media_expectations.CalleeExpectsSomeAudioAndVideo();
4315 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004316}
4317
4318TEST_P(PeerConnectionIntegrationInteropTest,
4319 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4320 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4321 ConnectFakeSignaling();
4322 caller()->AddAudioVideoTracks();
4323 callee()->AddAudioVideoTracks();
4324
4325 caller()->CreateAndSetAndSignalOffer();
4326 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4327
Seth Hampson2f0d7022018-02-20 11:54:42 -08004328 MediaExpectations media_expectations;
4329 media_expectations.ExpectBidirectionalAudioAndVideo();
4330 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004331}
4332
4333TEST_P(PeerConnectionIntegrationInteropTest,
4334 ReverseRolesOneAudioLocalToOneVideoRemote) {
4335 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4336 ConnectFakeSignaling();
4337 caller()->AddAudioTrack();
4338 callee()->AddVideoTrack();
4339
4340 caller()->CreateAndSetAndSignalOffer();
4341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4342
4343 // Verify that only the audio track has been negotiated.
4344 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4345 // Might also check that the callee's NegotiationNeeded flag is set.
4346
4347 // Reverse roles.
4348 callee()->CreateAndSetAndSignalOffer();
4349 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4350
Seth Hampson2f0d7022018-02-20 11:54:42 -08004351 MediaExpectations media_expectations;
4352 media_expectations.CallerExpectsSomeVideo();
4353 media_expectations.CalleeExpectsSomeAudio();
4354 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004355}
4356
Steve Antonba42e992018-04-09 14:10:01 -07004357INSTANTIATE_TEST_CASE_P(
4358 PeerConnectionIntegrationTest,
4359 PeerConnectionIntegrationInteropTest,
4360 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4361 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4362
4363// Test that if the Unified Plan side offers two video tracks then the Plan B
4364// side will only see the first one and ignore the second.
4365TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07004366 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4367 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08004368 ConnectFakeSignaling();
4369 auto first_sender = caller()->AddVideoTrack();
4370 caller()->AddVideoTrack();
4371
4372 caller()->CreateAndSetAndSignalOffer();
4373 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4374
4375 // Verify that there is only one receiver and it corresponds to the first
4376 // added track.
4377 auto receivers = callee()->pc()->GetReceivers();
4378 ASSERT_EQ(1u, receivers.size());
4379 EXPECT_TRUE(receivers[0]->track()->enabled());
4380 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4381
Seth Hampson2f0d7022018-02-20 11:54:42 -08004382 MediaExpectations media_expectations;
4383 media_expectations.CalleeExpectsSomeVideo();
4384 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004385}
4386
deadbeef1dcb1642017-03-29 21:08:16 -07004387} // namespace
4388
4389#endif // if !defined(THREAD_SANITIZER)