blob: 236a8bb97dcba09dd1849e21bf266f6103183cce [file] [log] [blame]
deadbeef1dcb1642017-03-30 04:08:161/*
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 12:48:5425#include "api/audio_codecs/builtin_audio_decoder_factory.h"
26#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3127#include "api/mediastreaminterface.h"
28#include "api/peerconnectioninterface.h"
Steve Anton8c0f7a72017-10-03 17:03:1029#include "api/peerconnectionproxy.h"
Mirko Bonadeic61ce0d2017-11-21 16:04:2030#include "api/rtpreceiverinterface.h"
Yves Gerey2e00abc2018-10-05 13:39:2431#include "api/umametrics.h"
Anders Carlsson67537952018-05-03 09:28:2932#include "api/video_codecs/builtin_video_decoder_factory.h"
33#include "api/video_codecs/builtin_video_encoder_factory.h"
34#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-12 03:15:4635#include "call/call.h"
36#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
37#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3138#include "media/engine/fakewebrtcvideoengine.h"
Qingsi Wang7685e862018-06-12 03:15:4639#include "media/engine/webrtcmediaengine.h"
40#include "modules/audio_processing/include/audio_processing.h"
Zach Stein6fcdc2f2018-08-23 23:25:5541#include "p2p/base/mockasyncresolver.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3142#include "p2p/base/p2pconstants.h"
43#include "p2p/base/portinterface.h"
Steve Antonede9ca52017-10-16 20:04:2744#include "p2p/base/teststunserver.h"
Jonas Orelandbdcee282017-10-10 12:01:4045#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3146#include "p2p/base/testturnserver.h"
47#include "p2p/client/basicportallocator.h"
48#include "pc/dtmfsender.h"
49#include "pc/localaudiosource.h"
50#include "pc/mediasession.h"
51#include "pc/peerconnection.h"
52#include "pc/peerconnectionfactory.h"
Seth Hampson2f0d7022018-02-20 19:54:4253#include "pc/rtpmediautils.h"
Steve Anton4ab68ee2017-12-19 22:26:1154#include "pc/sessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3155#include "pc/test/fakeaudiocapturemodule.h"
Niels Möller0f405822018-05-17 07:16:4156#include "pc/test/fakeperiodicvideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3157#include "pc/test/fakertccertificategenerator.h"
58#include "pc/test/fakevideotrackrenderer.h"
59#include "pc/test/mockpeerconnectionobservers.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3160#include "rtc_base/fakenetwork.h"
Steve Antonede9ca52017-10-16 20:04:2761#include "rtc_base/firewallsocketserver.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3162#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 10:53:2363#include "rtc_base/numerics/safe_conversions.h"
Benjamin Wrightd6f86e82018-05-08 20:12:2564#include "rtc_base/testcertificateverifier.h"
Johannes Kron965e7942018-09-13 13:36:2065#include "rtc_base/timeutils.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3166#include "rtc_base/virtualsocketserver.h"
Mirko Bonadei17f48782018-09-28 06:51:1067#include "system_wrappers/include/metrics.h"
Elad Alon99c3fe52017-10-13 14:29:4068#include "test/gmock.h"
deadbeef1dcb1642017-03-30 04:08:1669
70using cricket::ContentInfo;
71using cricket::FakeWebRtcVideoDecoder;
72using cricket::FakeWebRtcVideoDecoderFactory;
73using cricket::FakeWebRtcVideoEncoder;
74using cricket::FakeWebRtcVideoEncoderFactory;
75using cricket::MediaContentDescription;
Steve Antondf527fd2018-04-27 22:52:0376using cricket::StreamParams;
Steve Antonede9ca52017-10-16 20:04:2777using rtc::SocketAddress;
Seth Hampson2f0d7022018-02-20 19:54:4278using ::testing::Combine;
Steve Antonede9ca52017-10-16 20:04:2779using ::testing::ElementsAre;
Zach Stein6fcdc2f2018-08-23 23:25:5580using ::testing::Return;
81using ::testing::SetArgPointee;
Steve Antonede9ca52017-10-16 20:04:2782using ::testing::Values;
Zach Stein6fcdc2f2018-08-23 23:25:5583using ::testing::_;
deadbeef1dcb1642017-03-30 04:08:1684using webrtc::DataBuffer;
85using webrtc::DataChannelInterface;
86using webrtc::DtmfSender;
87using webrtc::DtmfSenderInterface;
88using webrtc::DtmfSenderObserverInterface;
Steve Anton15324772018-01-16 18:26:4989using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-30 04:08:1690using webrtc::MediaStreamInterface;
91using webrtc::MediaStreamTrackInterface;
92using webrtc::MockCreateSessionDescriptionObserver;
93using webrtc::MockDataChannelObserver;
94using webrtc::MockSetSessionDescriptionObserver;
95using webrtc::MockStatsObserver;
96using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 17:03:1097using webrtc::PeerConnection;
deadbeef1dcb1642017-03-30 04:08:1698using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-25 02:32:5799using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-30 04:08:16100using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 17:03:10101using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 18:26:49102using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 22:18:41103using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-25 02:32:57104using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 16:04:20105using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 19:54:42106using webrtc::RtpSenderInterface;
107using webrtc::RtpTransceiverDirection;
108using webrtc::RtpTransceiverInit;
109using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-18 01:41:02110using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 18:27:41111using webrtc::SdpType;
deadbeef1dcb1642017-03-30 04:08:16112using webrtc::SessionDescriptionInterface;
113using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 18:26:49114using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-30 04:08:16115
116namespace {
117
118static const int kDefaultTimeout = 10000;
119static const int kMaxWaitForStatsMs = 3000;
120static const int kMaxWaitForActivationMs = 5000;
121static const int kMaxWaitForFramesMs = 10000;
122// Default number of audio/video frames to wait for before considering a test
123// successful.
124static const int kDefaultExpectedAudioFrameCount = 3;
125static const int kDefaultExpectedVideoFrameCount = 3;
126
deadbeef1dcb1642017-03-30 04:08:16127static const char kDataChannelLabel[] = "data_channel";
128
129// SRTP cipher name negotiated by the tests. This must be updated if the
130// default changes.
Taylor Brandstetterfd350d72018-04-03 23:29:26131static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-30 04:08:16132static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
133
Steve Antonede9ca52017-10-16 20:04:27134static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
135
deadbeef1dcb1642017-03-30 04:08:16136// Helper function for constructing offer/answer options to initiate an ICE
137// restart.
138PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
139 PeerConnectionInterface::RTCOfferAnswerOptions options;
140 options.ice_restart = true;
141 return options;
142}
143
deadbeefd8ad7882017-04-18 23:01:17144// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
145// attribute from received SDP, simulating a legacy endpoint.
146void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
147 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 23:14:30148 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 23:01:17149 }
150 desc->set_msid_supported(false);
151}
152
Seth Hampson5897a6e2018-04-03 18:16:33153// Removes all stream information besides the stream ids, simulating an
154// endpoint that only signals a=msid lines to convey stream_ids.
155void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
156 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 22:52:03157 std::string track_id;
Seth Hampson5897a6e2018-04-03 18:16:33158 std::vector<std::string> stream_ids;
159 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 22:52:03160 const StreamParams& first_stream =
161 content.media_description()->streams()[0];
162 track_id = first_stream.id;
163 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 18:16:33164 }
165 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 22:52:03166 StreamParams new_stream;
167 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 18:16:33168 new_stream.set_stream_ids(stream_ids);
169 content.media_description()->AddStream(new_stream);
170 }
171}
172
zhihuangf8164932017-05-19 20:09:47173int FindFirstMediaStatsIndexByKind(
174 const std::string& kind,
175 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
176 media_stats_vec) {
177 for (size_t i = 0; i < media_stats_vec.size(); i++) {
178 if (media_stats_vec[i]->kind.ValueToString() == kind) {
179 return i;
180 }
181 }
182 return -1;
183}
184
deadbeef1dcb1642017-03-30 04:08:16185class SignalingMessageReceiver {
186 public:
Steve Antona3a92c22017-12-07 18:27:41187 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-30 04:08:16188 virtual void ReceiveIceMessage(const std::string& sdp_mid,
189 int sdp_mline_index,
190 const std::string& msg) = 0;
191
192 protected:
193 SignalingMessageReceiver() {}
194 virtual ~SignalingMessageReceiver() {}
195};
196
197class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
198 public:
199 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
200 : expected_media_type_(media_type) {}
201
202 void OnFirstPacketReceived(cricket::MediaType media_type) override {
203 ASSERT_EQ(expected_media_type_, media_type);
204 first_packet_received_ = true;
205 }
206
207 bool first_packet_received() const { return first_packet_received_; }
208
209 virtual ~MockRtpReceiverObserver() {}
210
211 private:
212 bool first_packet_received_ = false;
213 cricket::MediaType expected_media_type_;
214};
215
Zach Stein6fcdc2f2018-08-23 23:25:55216// Used by PeerConnectionWrapper::OnIceCandidate to allow a test to modify an
217// ICE candidate before it is signaled.
218class IceCandidateReplacerInterface {
219 public:
220 virtual ~IceCandidateReplacerInterface() = default;
221 // Return nullptr to drop the candidate (it won't be signaled to the other
222 // side).
223 virtual std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
224 const webrtc::IceCandidateInterface*) = 0;
225};
226
deadbeef1dcb1642017-03-30 04:08:16227// Helper class that wraps a peer connection, observes it, and can accept
228// signaling messages from another wrapper.
229//
230// Uses a fake network, fake A/V capture, and optionally fake
231// encoders/decoders, though they aren't used by default since they don't
232// advertise support of any codecs.
Steve Anton94286cb2017-09-26 23:20:19233// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 19:54:42234// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-30 04:08:16235class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 18:26:49236 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-30 04:08:16237 public:
238 // Different factory methods for convenience.
239 // TODO(deadbeef): Could use the pattern of:
240 //
241 // PeerConnectionWrapper =
242 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
243 //
244 // To reduce some code duplication.
245 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
246 const std::string& debug_name,
247 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
248 rtc::Thread* network_thread,
249 rtc::Thread* worker_thread) {
250 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 20:12:25251 webrtc::PeerConnectionDependencies dependencies(nullptr);
252 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 10:32:18253 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
254 worker_thread, nullptr)) {
deadbeef1dcb1642017-03-30 04:08:16255 delete client;
256 return nullptr;
257 }
258 return client;
259 }
260
deadbeef2f425aa2017-04-14 17:41:32261 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
262 return peer_connection_factory_.get();
263 }
264
deadbeef1dcb1642017-03-30 04:08:16265 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
266
267 // If a signaling message receiver is set (via ConnectFakeSignaling), this
268 // will set the whole offer/answer exchange in motion. Just need to wait for
269 // the signaling state to reach "stable".
270 void CreateAndSetAndSignalOffer() {
271 auto offer = CreateOffer();
272 ASSERT_NE(nullptr, offer);
273 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
274 }
275
276 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
277 // when a remote offer is received (via fake signaling) and an answer is
278 // generated. By default, uses default options.
279 void SetOfferAnswerOptions(
280 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
281 offer_answer_options_ = options;
282 }
283
284 // Set a callback to be invoked when SDP is received via the fake signaling
285 // channel, which provides an opportunity to munge (modify) the SDP. This is
286 // used to test SDP being applied that a PeerConnection would normally not
287 // generate, but a non-JSEP endpoint might.
288 void SetReceivedSdpMunger(
289 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 16:04:20290 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-30 04:08:16291 }
292
deadbeefc964d0b2017-04-03 17:03:35293 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-30 04:08:16294 // generated.
295 void SetGeneratedSdpMunger(
296 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 16:04:20297 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-30 04:08:16298 }
299
Seth Hampson2f0d7022018-02-20 19:54:42300 // Set a callback to be invoked when a remote offer is received via the fake
301 // signaling channel. This provides an opportunity to change the
302 // PeerConnection state before an answer is created and sent to the caller.
303 void SetRemoteOfferHandler(std::function<void()> handler) {
304 remote_offer_handler_ = std::move(handler);
305 }
306
Zach Stein6fcdc2f2018-08-23 23:25:55307 void SetLocalIceCandidateReplacer(
308 std::unique_ptr<IceCandidateReplacerInterface> replacer) {
309 local_ice_candidate_replacer_ = std::move(replacer);
310 }
311
Steve Antonede9ca52017-10-16 20:04:27312 // Every ICE connection state in order that has been seen by the observer.
313 std::vector<PeerConnectionInterface::IceConnectionState>
314 ice_connection_state_history() const {
315 return ice_connection_state_history_;
316 }
Steve Anton6f25b092017-10-23 16:39:20317 void clear_ice_connection_state_history() {
318 ice_connection_state_history_.clear();
319 }
Steve Antonede9ca52017-10-16 20:04:27320
Jonas Olsson635474e2018-10-18 13:58:17321 // Every PeerConnection state in order that has been seen by the observer.
322 std::vector<PeerConnectionInterface::PeerConnectionState>
323 peer_connection_state_history() const {
324 return peer_connection_state_history_;
325 }
326
Steve Antonede9ca52017-10-16 20:04:27327 // Every ICE gathering state in order that has been seen by the observer.
328 std::vector<PeerConnectionInterface::IceGatheringState>
329 ice_gathering_state_history() const {
330 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-30 04:08:16331 }
332
Steve Anton15324772018-01-16 18:26:49333 void AddAudioVideoTracks() {
334 AddAudioTrack();
335 AddVideoTrack();
deadbeef1dcb1642017-03-30 04:08:16336 }
337
Steve Anton74255ff2018-01-25 02:32:57338 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
339 return AddTrack(CreateLocalAudioTrack());
340 }
deadbeef1dcb1642017-03-30 04:08:16341
Steve Anton74255ff2018-01-25 02:32:57342 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
343 return AddTrack(CreateLocalVideoTrack());
344 }
deadbeef1dcb1642017-03-30 04:08:16345
346 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 09:23:35347 cricket::AudioOptions options;
deadbeef1dcb1642017-03-30 04:08:16348 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 09:23:35349 options.highpass_filter = false;
deadbeef1dcb1642017-03-30 04:08:16350 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 09:23:35351 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-30 04:08:16352 // TODO(perkj): Test audio source when it is implemented. Currently audio
353 // always use the default input.
deadbeefb1a15d72017-09-07 21:12:05354 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-30 04:08:16355 source);
356 }
357
358 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Johannes Kron965e7942018-09-13 13:36:20359 webrtc::FakePeriodicVideoSource::Config config;
360 config.timestamp_offset_ms = rtc::TimeMillis();
361 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-30 04:08:16362 }
363
364 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 08:34:46365 CreateLocalVideoTrackWithConfig(
366 webrtc::FakePeriodicVideoSource::Config config) {
367 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-30 04:08:16368 }
369
370 rtc::scoped_refptr<webrtc::VideoTrackInterface>
371 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 08:34:46372 webrtc::FakePeriodicVideoSource::Config config;
373 config.rotation = rotation;
Johannes Kron965e7942018-09-13 13:36:20374 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 08:34:46375 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-30 04:08:16376 }
377
Steve Anton74255ff2018-01-25 02:32:57378 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
379 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10380 const std::vector<std::string>& stream_ids = {}) {
381 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 18:26:49382 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-25 02:32:57383 return result.MoveValue();
384 }
385
386 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
387 cricket::MediaType media_type) {
388 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
389 for (auto receiver : pc()->GetReceivers()) {
390 if (receiver->media_type() == media_type) {
391 receivers.push_back(receiver);
392 }
393 }
394 return receivers;
deadbeef1dcb1642017-03-30 04:08:16395 }
396
Seth Hampson2f0d7022018-02-20 19:54:42397 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
398 cricket::MediaType media_type) {
399 for (auto transceiver : pc()->GetTransceivers()) {
400 if (transceiver->receiver()->media_type() == media_type) {
401 return transceiver;
402 }
403 }
404 return nullptr;
405 }
406
deadbeef1dcb1642017-03-30 04:08:16407 bool SignalingStateStable() {
408 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
409 }
410
411 void CreateDataChannel() { CreateDataChannel(nullptr); }
412
413 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 18:41:54414 CreateDataChannel(kDataChannelLabel, init);
415 }
416
417 void CreateDataChannel(const std::string& label,
418 const webrtc::DataChannelInit* init) {
419 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-30 04:08:16420 ASSERT_TRUE(data_channel_.get() != nullptr);
421 data_observer_.reset(new MockDataChannelObserver(data_channel_));
422 }
423
424 DataChannelInterface* data_channel() { return data_channel_; }
425 const MockDataChannelObserver* data_observer() const {
426 return data_observer_.get();
427 }
428
429 int audio_frames_received() const {
430 return fake_audio_capture_module_->frames_received();
431 }
432
433 // Takes minimum of video frames received for each track.
434 //
435 // Can be used like:
436 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
437 //
438 // To ensure that all video tracks received at least a certain number of
439 // frames.
440 int min_video_frames_received_per_track() const {
441 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 07:48:06442 if (fake_video_renderers_.empty()) {
443 return 0;
deadbeef1dcb1642017-03-30 04:08:16444 }
deadbeef1dcb1642017-03-30 04:08:16445
Anders Carlsson5f2bb622018-05-14 07:48:06446 for (const auto& pair : fake_video_renderers_) {
447 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-30 04:08:16448 }
Anders Carlsson5f2bb622018-05-14 07:48:06449 return min_frames;
deadbeef1dcb1642017-03-30 04:08:16450 }
451
452 // Returns a MockStatsObserver in a state after stats gathering finished,
453 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 23:01:17454 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-30 04:08:16455 webrtc::MediaStreamTrackInterface* track) {
456 rtc::scoped_refptr<MockStatsObserver> observer(
457 new rtc::RefCountedObject<MockStatsObserver>());
458 EXPECT_TRUE(peer_connection_->GetStats(
459 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
460 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
461 return observer;
462 }
463
464 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 23:01:17465 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
466 return OldGetStatsForTrack(nullptr);
467 }
468
469 // Synchronously gets stats and returns them. If it times out, fails the test
470 // and returns null.
471 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
472 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
473 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
474 peer_connection_->GetStats(callback);
475 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
476 return callback->report();
deadbeef1dcb1642017-03-30 04:08:16477 }
478
479 int rendered_width() {
480 EXPECT_FALSE(fake_video_renderers_.empty());
481 return fake_video_renderers_.empty()
482 ? 0
483 : fake_video_renderers_.begin()->second->width();
484 }
485
486 int rendered_height() {
487 EXPECT_FALSE(fake_video_renderers_.empty());
488 return fake_video_renderers_.empty()
489 ? 0
490 : fake_video_renderers_.begin()->second->height();
491 }
492
493 double rendered_aspect_ratio() {
494 if (rendered_height() == 0) {
495 return 0.0;
496 }
497 return static_cast<double>(rendered_width()) / rendered_height();
498 }
499
500 webrtc::VideoRotation rendered_rotation() {
501 EXPECT_FALSE(fake_video_renderers_.empty());
502 return fake_video_renderers_.empty()
503 ? webrtc::kVideoRotation_0
504 : fake_video_renderers_.begin()->second->rotation();
505 }
506
507 int local_rendered_width() {
508 return local_video_renderer_ ? local_video_renderer_->width() : 0;
509 }
510
511 int local_rendered_height() {
512 return local_video_renderer_ ? local_video_renderer_->height() : 0;
513 }
514
515 double local_rendered_aspect_ratio() {
516 if (local_rendered_height() == 0) {
517 return 0.0;
518 }
519 return static_cast<double>(local_rendered_width()) /
520 local_rendered_height();
521 }
522
523 size_t number_of_remote_streams() {
524 if (!pc()) {
525 return 0;
526 }
527 return pc()->remote_streams()->count();
528 }
529
530 StreamCollectionInterface* remote_streams() const {
531 if (!pc()) {
532 ADD_FAILURE();
533 return nullptr;
534 }
535 return pc()->remote_streams();
536 }
537
538 StreamCollectionInterface* local_streams() {
539 if (!pc()) {
540 ADD_FAILURE();
541 return nullptr;
542 }
543 return pc()->local_streams();
544 }
545
546 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
547 return pc()->signaling_state();
548 }
549
550 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
551 return pc()->ice_connection_state();
552 }
553
554 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
555 return pc()->ice_gathering_state();
556 }
557
558 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
559 // GetReceivers. They're updated automatically when a remote offer/answer
560 // from the fake signaling channel is applied, or when
561 // ResetRtpReceiverObservers below is called.
562 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
563 rtp_receiver_observers() {
564 return rtp_receiver_observers_;
565 }
566
567 void ResetRtpReceiverObservers() {
568 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 16:04:20569 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
570 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-30 04:08:16571 std::unique_ptr<MockRtpReceiverObserver> observer(
572 new MockRtpReceiverObserver(receiver->media_type()));
573 receiver->SetObserver(observer.get());
574 rtp_receiver_observers_.push_back(std::move(observer));
575 }
576 }
577
Steve Antonede9ca52017-10-16 20:04:27578 rtc::FakeNetworkManager* network() const {
579 return fake_network_manager_.get();
580 }
581 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
582
Qingsi Wang7685e862018-06-12 03:15:46583 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
584 return event_log_factory_;
585 }
586
deadbeef1dcb1642017-03-30 04:08:16587 private:
588 explicit PeerConnectionWrapper(const std::string& debug_name)
589 : debug_name_(debug_name) {}
590
Niels Möllerf06f9232018-08-07 10:32:18591 bool Init(const PeerConnectionFactory::Options* options,
Benjamin Wrightd6f86e82018-05-08 20:12:25592 const PeerConnectionInterface::RTCConfiguration* config,
593 webrtc::PeerConnectionDependencies dependencies,
594 rtc::Thread* network_thread,
Qingsi Wang7685e862018-06-12 03:15:46595 rtc::Thread* worker_thread,
596 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
deadbeef1dcb1642017-03-30 04:08:16597 // There's an error in this test code if Init ends up being called twice.
598 RTC_DCHECK(!peer_connection_);
599 RTC_DCHECK(!peer_connection_factory_);
600
601 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 20:04:27602 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-30 04:08:16603
604 std::unique_ptr<cricket::PortAllocator> port_allocator(
605 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 20:04:27606 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-30 04:08:16607 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
608 if (!fake_audio_capture_module_) {
609 return false;
610 }
deadbeef1dcb1642017-03-30 04:08:16611 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-12 03:15:46612
613 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
614 pc_factory_dependencies.network_thread = network_thread;
615 pc_factory_dependencies.worker_thread = worker_thread;
616 pc_factory_dependencies.signaling_thread = signaling_thread;
617 pc_factory_dependencies.media_engine =
618 cricket::WebRtcMediaEngineFactory::Create(
619 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
620 fake_audio_capture_module_),
621 webrtc::CreateBuiltinAudioEncoderFactory(),
622 webrtc::CreateBuiltinAudioDecoderFactory(),
623 webrtc::CreateBuiltinVideoEncoderFactory(),
Qingsi Wang59844ce2018-11-01 04:45:53624 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
Qingsi Wang7685e862018-06-12 03:15:46625 webrtc::AudioProcessingBuilder().Create());
626 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
627 if (event_log_factory) {
628 event_log_factory_ = event_log_factory.get();
629 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
630 } else {
631 pc_factory_dependencies.event_log_factory =
632 webrtc::CreateRtcEventLogFactory();
633 }
634 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
635 std::move(pc_factory_dependencies));
636
deadbeef1dcb1642017-03-30 04:08:16637 if (!peer_connection_factory_) {
638 return false;
639 }
640 if (options) {
641 peer_connection_factory_->SetOptions(*options);
642 }
Seth Hampson2f0d7022018-02-20 19:54:42643 if (config) {
644 sdp_semantics_ = config->sdp_semantics;
645 }
Benjamin Wrightd6f86e82018-05-08 20:12:25646
647 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 10:32:18648 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-30 04:08:16649 return peer_connection_.get() != nullptr;
650 }
651
652 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-30 04:08:16653 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 20:12:25654 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-30 04:08:16655 PeerConnectionInterface::RTCConfiguration modified_config;
656 // If |config| is null, this will result in a default configuration being
657 // used.
658 if (config) {
659 modified_config = *config;
660 }
661 // Disable resolution adaptation; we don't want it interfering with the
662 // test results.
663 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
664 // ratios and not specific resolutions, is this even necessary?
665 modified_config.set_cpu_adaptation(false);
666
Benjamin Wrightd6f86e82018-05-08 20:12:25667 dependencies.observer = this;
deadbeef1dcb1642017-03-30 04:08:16668 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 20:12:25669 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-30 04:08:16670 }
671
672 void set_signaling_message_receiver(
673 SignalingMessageReceiver* signaling_message_receiver) {
674 signaling_message_receiver_ = signaling_message_receiver;
675 }
676
677 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
678
Steve Antonede9ca52017-10-16 20:04:27679 void set_signal_ice_candidates(bool signal) {
680 signal_ice_candidates_ = signal;
681 }
682
deadbeef1dcb1642017-03-30 04:08:16683 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 08:34:46684 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-30 04:08:16685 // Set max frame rate to 10fps to reduce the risk of test flakiness.
686 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 08:34:46687 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-30 04:08:16688
Niels Möller5c7efe72018-05-11 08:34:46689 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 07:16:41690 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
691 config, false /* remote */));
deadbeef1dcb1642017-03-30 04:08:16692 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 08:34:46693 peer_connection_factory_->CreateVideoTrack(
694 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-30 04:08:16695 if (!local_video_renderer_) {
696 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
697 }
698 return track;
699 }
700
701 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 10:09:25702 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 18:27:41703 std::unique_ptr<SessionDescriptionInterface> desc =
704 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-30 04:08:16705 if (received_sdp_munger_) {
706 received_sdp_munger_(desc->description());
707 }
708
709 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
710 // Setting a remote description may have changed the number of receivers,
711 // so reset the receiver observers.
712 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 19:54:42713 if (remote_offer_handler_) {
714 remote_offer_handler_();
715 }
deadbeef1dcb1642017-03-30 04:08:16716 auto answer = CreateAnswer();
717 ASSERT_NE(nullptr, answer);
718 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
719 }
720
721 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 10:09:25722 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 18:27:41723 std::unique_ptr<SessionDescriptionInterface> desc =
724 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-30 04:08:16725 if (received_sdp_munger_) {
726 received_sdp_munger_(desc->description());
727 }
728
729 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
730 // Set the RtpReceiverObserver after receivers are created.
731 ResetRtpReceiverObservers();
732 }
733
734 // Returns null on failure.
735 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
736 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
737 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
738 pc()->CreateOffer(observer, offer_answer_options_);
739 return WaitForDescriptionFromObserver(observer);
740 }
741
742 // Returns null on failure.
743 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
744 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
745 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
746 pc()->CreateAnswer(observer, offer_answer_options_);
747 return WaitForDescriptionFromObserver(observer);
748 }
749
750 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 16:04:20751 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-30 04:08:16752 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
753 if (!observer->result()) {
754 return nullptr;
755 }
756 auto description = observer->MoveDescription();
757 if (generated_sdp_munger_) {
758 generated_sdp_munger_(description->description());
759 }
760 return description;
761 }
762
763 // Setting the local description and sending the SDP message over the fake
764 // signaling channel are combined into the same method because the SDP
765 // message needs to be sent as soon as SetLocalDescription finishes, without
766 // waiting for the observer to be called. This ensures that ICE candidates
767 // don't outrace the description.
768 bool SetLocalDescriptionAndSendSdpMessage(
769 std::unique_ptr<SessionDescriptionInterface> desc) {
770 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
771 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 10:09:25772 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 18:27:41773 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-30 04:08:16774 std::string sdp;
775 EXPECT_TRUE(desc->ToString(&sdp));
776 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 19:54:42777 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
778 RemoveUnusedVideoRenderers();
779 }
deadbeef1dcb1642017-03-30 04:08:16780 // As mentioned above, we need to send the message immediately after
781 // SetLocalDescription.
782 SendSdpMessage(type, sdp);
783 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
784 return true;
785 }
786
787 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
788 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
789 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 10:09:25790 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-30 04:08:16791 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 19:54:42792 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
793 RemoveUnusedVideoRenderers();
794 }
deadbeef1dcb1642017-03-30 04:08:16795 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
796 return observer->result();
797 }
798
Seth Hampson2f0d7022018-02-20 19:54:42799 // This is a work around to remove unused fake_video_renderers from
800 // transceivers that have either stopped or are no longer receiving.
801 void RemoveUnusedVideoRenderers() {
802 auto transceivers = pc()->GetTransceivers();
803 for (auto& transceiver : transceivers) {
804 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
805 continue;
806 }
807 // Remove fake video renderers from any stopped transceivers.
808 if (transceiver->stopped()) {
809 auto it =
810 fake_video_renderers_.find(transceiver->receiver()->track()->id());
811 if (it != fake_video_renderers_.end()) {
812 fake_video_renderers_.erase(it);
813 }
814 }
815 // Remove fake video renderers from any transceivers that are no longer
816 // receiving.
817 if ((transceiver->current_direction() &&
818 !webrtc::RtpTransceiverDirectionHasRecv(
819 *transceiver->current_direction()))) {
820 auto it =
821 fake_video_renderers_.find(transceiver->receiver()->track()->id());
822 if (it != fake_video_renderers_.end()) {
823 fake_video_renderers_.erase(it);
824 }
825 }
826 }
827 }
828
deadbeef1dcb1642017-03-30 04:08:16829 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
830 // default).
Steve Antona3a92c22017-12-07 18:27:41831 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-30 04:08:16832 if (signaling_delay_ms_ == 0) {
833 RelaySdpMessageIfReceiverExists(type, msg);
834 } else {
835 invoker_.AsyncInvokeDelayed<void>(
836 RTC_FROM_HERE, rtc::Thread::Current(),
837 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
838 this, type, msg),
839 signaling_delay_ms_);
840 }
841 }
842
Steve Antona3a92c22017-12-07 18:27:41843 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-30 04:08:16844 if (signaling_message_receiver_) {
845 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
846 }
847 }
848
849 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
850 // default).
851 void SendIceMessage(const std::string& sdp_mid,
852 int sdp_mline_index,
853 const std::string& msg) {
854 if (signaling_delay_ms_ == 0) {
855 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
856 } else {
857 invoker_.AsyncInvokeDelayed<void>(
858 RTC_FROM_HERE, rtc::Thread::Current(),
859 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
860 this, sdp_mid, sdp_mline_index, msg),
861 signaling_delay_ms_);
862 }
863 }
864
865 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
866 int sdp_mline_index,
867 const std::string& msg) {
868 if (signaling_message_receiver_) {
869 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
870 msg);
871 }
872 }
873
874 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 18:27:41875 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
876 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-30 04:08:16877 HandleIncomingOffer(msg);
878 } else {
879 HandleIncomingAnswer(msg);
880 }
881 }
882
883 void ReceiveIceMessage(const std::string& sdp_mid,
884 int sdp_mline_index,
885 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 10:09:25886 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-30 04:08:16887 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
888 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
889 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
890 }
891
892 // PeerConnectionObserver callbacks.
893 void OnSignalingChange(
894 webrtc::PeerConnectionInterface::SignalingState new_state) override {
895 EXPECT_EQ(pc()->signaling_state(), new_state);
896 }
Steve Anton15324772018-01-16 18:26:49897 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
898 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
899 streams) override {
900 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
901 rtc::scoped_refptr<VideoTrackInterface> video_track(
902 static_cast<VideoTrackInterface*>(receiver->track().get()));
903 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-30 04:08:16904 fake_video_renderers_.end());
Steve Anton15324772018-01-16 18:26:49905 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 09:40:33906 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-30 04:08:16907 }
908 }
Steve Anton15324772018-01-16 18:26:49909 void OnRemoveTrack(
910 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
911 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
912 auto it = fake_video_renderers_.find(receiver->track()->id());
913 RTC_DCHECK(it != fake_video_renderers_.end());
914 fake_video_renderers_.erase(it);
915 }
916 }
deadbeef1dcb1642017-03-30 04:08:16917 void OnRenegotiationNeeded() override {}
918 void OnIceConnectionChange(
919 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
920 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 20:04:27921 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-30 04:08:16922 }
Jonas Olsson635474e2018-10-18 13:58:17923 void OnConnectionChange(
924 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override {
925 peer_connection_state_history_.push_back(new_state);
926 }
927
deadbeef1dcb1642017-03-30 04:08:16928 void OnIceGatheringChange(
929 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-30 04:08:16930 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 20:04:27931 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-30 04:08:16932 }
Zach Stein6fcdc2f2018-08-23 23:25:55933 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceIceCandidate(
934 const webrtc::IceCandidateInterface* candidate) {
935 std::string candidate_string;
936 candidate->ToString(&candidate_string);
937
938 auto owned_candidate =
939 local_ice_candidate_replacer_->ReplaceCandidate(candidate);
940 if (!owned_candidate) {
941 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer dropped \""
942 << candidate_string << "\"";
943 return nullptr;
944 }
945 std::string owned_candidate_string;
946 owned_candidate->ToString(&owned_candidate_string);
947 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer changed \""
948 << candidate_string << "\" to \"" << owned_candidate_string
949 << "\"";
950 return owned_candidate;
951 }
deadbeef1dcb1642017-03-30 04:08:16952 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 10:09:25953 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-30 04:08:16954
Zach Stein6fcdc2f2018-08-23 23:25:55955 const webrtc::IceCandidateInterface* new_candidate = candidate;
956 std::unique_ptr<webrtc::IceCandidateInterface> owned_candidate;
957 if (local_ice_candidate_replacer_) {
958 owned_candidate = ReplaceIceCandidate(candidate);
959 if (!owned_candidate) {
960 return; // The candidate was dropped.
961 }
962 new_candidate = owned_candidate.get();
963 }
964
deadbeef1dcb1642017-03-30 04:08:16965 std::string ice_sdp;
Zach Stein6fcdc2f2018-08-23 23:25:55966 EXPECT_TRUE(new_candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 20:04:27967 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-30 04:08:16968 // Remote party may be deleted.
969 return;
970 }
Zach Stein6fcdc2f2018-08-23 23:25:55971 SendIceMessage(new_candidate->sdp_mid(), new_candidate->sdp_mline_index(),
972 ice_sdp);
deadbeef1dcb1642017-03-30 04:08:16973 }
974 void OnDataChannel(
975 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 10:09:25976 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-30 04:08:16977 data_channel_ = data_channel;
978 data_observer_.reset(new MockDataChannelObserver(data_channel));
979 }
980
deadbeef1dcb1642017-03-30 04:08:16981 std::string debug_name_;
982
983 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
984
985 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
986 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
987 peer_connection_factory_;
988
Steve Antonede9ca52017-10-16 20:04:27989 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-30 04:08:16990 // Needed to keep track of number of frames sent.
991 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
992 // Needed to keep track of number of frames received.
993 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
994 fake_video_renderers_;
995 // Needed to ensure frames aren't received for removed tracks.
996 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
997 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-30 04:08:16998
999 // For remote peer communication.
1000 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
1001 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 20:04:271002 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-30 04:08:161003
Niels Möller5c7efe72018-05-11 08:34:461004 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-30 04:08:161005 // them, if required.
Niels Möller5c7efe72018-05-11 08:34:461006 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
1007 video_track_sources_;
deadbeef1dcb1642017-03-30 04:08:161008 // |local_video_renderer_| attached to the first created local video track.
1009 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
1010
Seth Hampson2f0d7022018-02-20 19:54:421011 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-30 04:08:161012 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1013 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1014 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 19:54:421015 std::function<void()> remote_offer_handler_;
Zach Stein6fcdc2f2018-08-23 23:25:551016 std::unique_ptr<IceCandidateReplacerInterface> local_ice_candidate_replacer_;
deadbeef1dcb1642017-03-30 04:08:161017 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1018 std::unique_ptr<MockDataChannelObserver> data_observer_;
1019
1020 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1021
Steve Antonede9ca52017-10-16 20:04:271022 std::vector<PeerConnectionInterface::IceConnectionState>
1023 ice_connection_state_history_;
Jonas Olsson635474e2018-10-18 13:58:171024 std::vector<PeerConnectionInterface::PeerConnectionState>
1025 peer_connection_state_history_;
Steve Antonede9ca52017-10-16 20:04:271026 std::vector<PeerConnectionInterface::IceGatheringState>
1027 ice_gathering_state_history_;
deadbeef1dcb1642017-03-30 04:08:161028
Qingsi Wang7685e862018-06-12 03:15:461029 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1030
deadbeef1dcb1642017-03-30 04:08:161031 rtc::AsyncInvoker invoker_;
1032
Seth Hampson2f0d7022018-02-20 19:54:421033 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-30 04:08:161034};
1035
Elad Alon99c3fe52017-10-13 14:29:401036class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1037 public:
1038 virtual ~MockRtcEventLogOutput() = default;
1039 MOCK_CONST_METHOD0(IsActive, bool());
1040 MOCK_METHOD1(Write, bool(const std::string&));
1041};
1042
Seth Hampson2f0d7022018-02-20 19:54:421043// This helper object is used for both specifying how many audio/video frames
1044// are expected to be received for a caller/callee. It provides helper functions
1045// to specify these expectations. The object initially starts in a state of no
1046// expectations.
1047class MediaExpectations {
1048 public:
1049 enum ExpectFrames {
1050 kExpectSomeFrames,
1051 kExpectNoFrames,
1052 kNoExpectation,
1053 };
1054
1055 void ExpectBidirectionalAudioAndVideo() {
1056 ExpectBidirectionalAudio();
1057 ExpectBidirectionalVideo();
1058 }
1059
1060 void ExpectBidirectionalAudio() {
1061 CallerExpectsSomeAudio();
1062 CalleeExpectsSomeAudio();
1063 }
1064
1065 void ExpectNoAudio() {
1066 CallerExpectsNoAudio();
1067 CalleeExpectsNoAudio();
1068 }
1069
1070 void ExpectBidirectionalVideo() {
1071 CallerExpectsSomeVideo();
1072 CalleeExpectsSomeVideo();
1073 }
1074
1075 void ExpectNoVideo() {
1076 CallerExpectsNoVideo();
1077 CalleeExpectsNoVideo();
1078 }
1079
1080 void CallerExpectsSomeAudioAndVideo() {
1081 CallerExpectsSomeAudio();
1082 CallerExpectsSomeVideo();
1083 }
1084
1085 void CalleeExpectsSomeAudioAndVideo() {
1086 CalleeExpectsSomeAudio();
1087 CalleeExpectsSomeVideo();
1088 }
1089
1090 // Caller's audio functions.
1091 void CallerExpectsSomeAudio(
1092 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1093 caller_audio_expectation_ = kExpectSomeFrames;
1094 caller_audio_frames_expected_ = expected_audio_frames;
1095 }
1096
1097 void CallerExpectsNoAudio() {
1098 caller_audio_expectation_ = kExpectNoFrames;
1099 caller_audio_frames_expected_ = 0;
1100 }
1101
1102 // Caller's video functions.
1103 void CallerExpectsSomeVideo(
1104 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1105 caller_video_expectation_ = kExpectSomeFrames;
1106 caller_video_frames_expected_ = expected_video_frames;
1107 }
1108
1109 void CallerExpectsNoVideo() {
1110 caller_video_expectation_ = kExpectNoFrames;
1111 caller_video_frames_expected_ = 0;
1112 }
1113
1114 // Callee's audio functions.
1115 void CalleeExpectsSomeAudio(
1116 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1117 callee_audio_expectation_ = kExpectSomeFrames;
1118 callee_audio_frames_expected_ = expected_audio_frames;
1119 }
1120
1121 void CalleeExpectsNoAudio() {
1122 callee_audio_expectation_ = kExpectNoFrames;
1123 callee_audio_frames_expected_ = 0;
1124 }
1125
1126 // Callee's video functions.
1127 void CalleeExpectsSomeVideo(
1128 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1129 callee_video_expectation_ = kExpectSomeFrames;
1130 callee_video_frames_expected_ = expected_video_frames;
1131 }
1132
1133 void CalleeExpectsNoVideo() {
1134 callee_video_expectation_ = kExpectNoFrames;
1135 callee_video_frames_expected_ = 0;
1136 }
1137
1138 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1139 ExpectFrames caller_video_expectation_ = kNoExpectation;
1140 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1141 ExpectFrames callee_video_expectation_ = kNoExpectation;
1142 int caller_audio_frames_expected_ = 0;
1143 int caller_video_frames_expected_ = 0;
1144 int callee_audio_frames_expected_ = 0;
1145 int callee_video_frames_expected_ = 0;
1146};
1147
deadbeef1dcb1642017-03-30 04:08:161148// Tests two PeerConnections connecting to each other end-to-end, using a
1149// virtual network, fake A/V capture and fake encoder/decoders. The
1150// PeerConnections share the threads/socket servers, but use separate versions
1151// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 19:54:421152class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-30 04:08:161153 public:
Seth Hampson2f0d7022018-02-20 19:54:421154 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1155 : sdp_semantics_(sdp_semantics),
1156 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 20:04:271157 fss_(new rtc::FirewallSocketServer(ss_.get())),
1158 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-30 04:08:161159 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 14:21:481160 network_thread_->SetName("PCNetworkThread", this);
1161 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-30 04:08:161162 RTC_CHECK(network_thread_->Start());
1163 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 19:54:531164 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-30 04:08:161165 }
1166
Seth Hampson2f0d7022018-02-20 19:54:421167 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 14:41:321168 // The PeerConnections should deleted before the TurnCustomizers.
1169 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1170 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1171 // that the TurnCustomizer outlives the life of the PeerConnection or else
1172 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-30 04:08:161173 if (caller_) {
1174 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 14:41:321175 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-30 04:08:161176 }
1177 if (callee_) {
1178 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 14:41:321179 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-30 04:08:161180 }
Seth Hampsonaed71642018-06-11 14:41:321181
1182 // If turn servers were created for the test they need to be destroyed on
1183 // the network thread.
1184 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1185 turn_servers_.clear();
1186 turn_customizers_.clear();
1187 });
deadbeef1dcb1642017-03-30 04:08:161188 }
1189
1190 bool SignalingStateStable() {
1191 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1192 }
1193
deadbeef71452802017-05-08 00:21:011194 bool DtlsConnected() {
1195 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1196 // are connected. This is an important distinction. Once we have separate
1197 // ICE and DTLS state, this check needs to use the DTLS state.
1198 return (callee()->ice_connection_state() ==
1199 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1200 callee()->ice_connection_state() ==
1201 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1202 (caller()->ice_connection_state() ==
1203 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1204 caller()->ice_connection_state() ==
1205 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1206 }
1207
Qingsi Wang7685e862018-06-12 03:15:461208 // When |event_log_factory| is null, the default implementation of the event
1209 // log factory will be used.
Seth Hampson2f0d7022018-02-20 19:54:421210 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1211 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 19:54:421212 const PeerConnectionFactory::Options* options,
1213 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-12 03:15:461214 webrtc::PeerConnectionDependencies dependencies,
1215 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
Seth Hampson2f0d7022018-02-20 19:54:421216 RTCConfiguration modified_config;
1217 if (config) {
1218 modified_config = *config;
1219 }
Steve Anton3acffc32018-04-13 00:21:031220 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 20:12:251221 if (!dependencies.cert_generator) {
1222 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 09:40:331223 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 19:54:421224 }
1225 std::unique_ptr<PeerConnectionWrapper> client(
1226 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 20:12:251227
Niels Möllerf06f9232018-08-07 10:32:181228 if (!client->Init(options, &modified_config, std::move(dependencies),
1229 network_thread_.get(), worker_thread_.get(),
1230 std::move(event_log_factory))) {
Seth Hampson2f0d7022018-02-20 19:54:421231 return nullptr;
1232 }
1233 return client;
1234 }
1235
Qingsi Wang7685e862018-06-12 03:15:461236 std::unique_ptr<PeerConnectionWrapper>
1237 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1238 const std::string& debug_name,
Qingsi Wang7685e862018-06-12 03:15:461239 const PeerConnectionFactory::Options* options,
1240 const RTCConfiguration* config,
1241 webrtc::PeerConnectionDependencies dependencies) {
1242 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1243 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möllerf06f9232018-08-07 10:32:181244 return CreatePeerConnectionWrapper(debug_name, options, config,
Qingsi Wang7685e862018-06-12 03:15:461245 std::move(dependencies),
1246 std::move(event_log_factory));
1247 }
1248
deadbeef1dcb1642017-03-30 04:08:161249 bool CreatePeerConnectionWrappers() {
1250 return CreatePeerConnectionWrappersWithConfig(
1251 PeerConnectionInterface::RTCConfiguration(),
1252 PeerConnectionInterface::RTCConfiguration());
1253 }
1254
Steve Anton3acffc32018-04-13 00:21:031255 bool CreatePeerConnectionWrappersWithSdpSemantics(
1256 SdpSemantics caller_semantics,
1257 SdpSemantics callee_semantics) {
1258 // Can't specify the sdp_semantics in the passed-in configuration since it
1259 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1260 // stored in sdp_semantics_. So get around this by modifying the instance
1261 // variable before calling CreatePeerConnectionWrapper for the caller and
1262 // callee PeerConnections.
1263 SdpSemantics original_semantics = sdp_semantics_;
1264 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 20:12:251265 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181266 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1267 nullptr);
Steve Anton3acffc32018-04-13 00:21:031268 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 20:12:251269 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181270 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1271 nullptr);
Steve Anton3acffc32018-04-13 00:21:031272 sdp_semantics_ = original_semantics;
1273 return caller_ && callee_;
1274 }
1275
deadbeef1dcb1642017-03-30 04:08:161276 bool CreatePeerConnectionWrappersWithConfig(
1277 const PeerConnectionInterface::RTCConfiguration& caller_config,
1278 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 20:12:251279 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181280 "Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-12 03:15:461281 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251282 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181283 "Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-12 03:15:461284 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251285 return caller_ && callee_;
1286 }
1287
1288 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1289 const PeerConnectionInterface::RTCConfiguration& caller_config,
1290 webrtc::PeerConnectionDependencies caller_dependencies,
1291 const PeerConnectionInterface::RTCConfiguration& callee_config,
1292 webrtc::PeerConnectionDependencies callee_dependencies) {
1293 caller_ =
Niels Möllerf06f9232018-08-07 10:32:181294 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-12 03:15:461295 std::move(caller_dependencies), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251296 callee_ =
Niels Möllerf06f9232018-08-07 10:32:181297 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-12 03:15:461298 std::move(callee_dependencies), nullptr);
deadbeef1dcb1642017-03-30 04:08:161299 return caller_ && callee_;
1300 }
1301
1302 bool CreatePeerConnectionWrappersWithOptions(
1303 const PeerConnectionFactory::Options& caller_options,
1304 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 20:12:251305 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181306 "Caller", &caller_options, nullptr,
Qingsi Wang7685e862018-06-12 03:15:461307 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251308 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181309 "Callee", &callee_options, nullptr,
Qingsi Wang7685e862018-06-12 03:15:461310 webrtc::PeerConnectionDependencies(nullptr), nullptr);
1311 return caller_ && callee_;
1312 }
1313
1314 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1315 PeerConnectionInterface::RTCConfiguration default_config;
1316 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 10:32:181317 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-12 03:15:461318 webrtc::PeerConnectionDependencies(nullptr));
1319 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 10:32:181320 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 20:12:251321 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-30 04:08:161322 return caller_ && callee_;
1323 }
1324
Seth Hampson2f0d7022018-02-20 19:54:421325 std::unique_ptr<PeerConnectionWrapper>
1326 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-30 04:08:161327 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1328 new FakeRTCCertificateGenerator());
1329 cert_generator->use_alternate_key();
1330
Benjamin Wrightd6f86e82018-05-08 20:12:251331 webrtc::PeerConnectionDependencies dependencies(nullptr);
1332 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 10:32:181333 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
Qingsi Wang7685e862018-06-12 03:15:461334 std::move(dependencies), nullptr);
deadbeef1dcb1642017-03-30 04:08:161335 }
1336
Seth Hampsonaed71642018-06-11 14:41:321337 cricket::TestTurnServer* CreateTurnServer(
1338 rtc::SocketAddress internal_address,
1339 rtc::SocketAddress external_address,
1340 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1341 const std::string& common_name = "test turn server") {
1342 rtc::Thread* thread = network_thread();
1343 std::unique_ptr<cricket::TestTurnServer> turn_server =
1344 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1345 RTC_FROM_HERE,
1346 [thread, internal_address, external_address, type, common_name] {
Karl Wiberg918f50c2018-07-05 09:40:331347 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 14:41:321348 thread, internal_address, external_address, type,
1349 /*ignore_bad_certs=*/true, common_name);
1350 });
1351 turn_servers_.push_back(std::move(turn_server));
1352 // Interactions with the turn server should be done on the network thread.
1353 return turn_servers_.back().get();
1354 }
1355
1356 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1357 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1358 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1359 RTC_FROM_HERE,
Karl Wiberg918f50c2018-07-05 09:40:331360 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 14:41:321361 turn_customizers_.push_back(std::move(turn_customizer));
1362 // Interactions with the turn customizer should be done on the network
1363 // thread.
1364 return turn_customizers_.back().get();
1365 }
1366
1367 // Checks that the function counters for a TestTurnCustomizer are greater than
1368 // 0.
1369 void ExpectTurnCustomizerCountersIncremented(
1370 cricket::TestTurnCustomizer* turn_customizer) {
1371 unsigned int allow_channel_data_counter =
1372 network_thread()->Invoke<unsigned int>(
1373 RTC_FROM_HERE, [turn_customizer] {
1374 return turn_customizer->allow_channel_data_cnt_;
1375 });
1376 EXPECT_GT(allow_channel_data_counter, 0u);
1377 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1378 RTC_FROM_HERE,
1379 [turn_customizer] { return turn_customizer->modify_cnt_; });
1380 EXPECT_GT(modify_counter, 0u);
1381 }
1382
deadbeef1dcb1642017-03-30 04:08:161383 // Once called, SDP blobs and ICE candidates will be automatically signaled
1384 // between PeerConnections.
1385 void ConnectFakeSignaling() {
1386 caller_->set_signaling_message_receiver(callee_.get());
1387 callee_->set_signaling_message_receiver(caller_.get());
1388 }
1389
Steve Antonede9ca52017-10-16 20:04:271390 // Once called, SDP blobs will be automatically signaled between
1391 // PeerConnections. Note that ICE candidates will not be signaled unless they
1392 // are in the exchanged SDP blobs.
1393 void ConnectFakeSignalingForSdpOnly() {
1394 ConnectFakeSignaling();
1395 SetSignalIceCandidates(false);
1396 }
1397
deadbeef1dcb1642017-03-30 04:08:161398 void SetSignalingDelayMs(int delay_ms) {
1399 caller_->set_signaling_delay_ms(delay_ms);
1400 callee_->set_signaling_delay_ms(delay_ms);
1401 }
1402
Steve Antonede9ca52017-10-16 20:04:271403 void SetSignalIceCandidates(bool signal) {
1404 caller_->set_signal_ice_candidates(signal);
1405 callee_->set_signal_ice_candidates(signal);
1406 }
1407
deadbeef1dcb1642017-03-30 04:08:161408 // Messages may get lost on the unreliable DataChannel, so we send multiple
1409 // times to avoid test flakiness.
1410 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1411 const std::string& data,
1412 int retries) {
1413 for (int i = 0; i < retries; ++i) {
1414 dc->Send(DataBuffer(data));
1415 }
1416 }
1417
1418 rtc::Thread* network_thread() { return network_thread_.get(); }
1419
1420 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1421
1422 PeerConnectionWrapper* caller() { return caller_.get(); }
1423
1424 // Set the |caller_| to the |wrapper| passed in and return the
1425 // original |caller_|.
1426 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1427 PeerConnectionWrapper* wrapper) {
1428 PeerConnectionWrapper* old = caller_.release();
1429 caller_.reset(wrapper);
1430 return old;
1431 }
1432
1433 PeerConnectionWrapper* callee() { return callee_.get(); }
1434
1435 // Set the |callee_| to the |wrapper| passed in and return the
1436 // original |callee_|.
1437 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1438 PeerConnectionWrapper* wrapper) {
1439 PeerConnectionWrapper* old = callee_.release();
1440 callee_.reset(wrapper);
1441 return old;
1442 }
1443
Steve Antonede9ca52017-10-16 20:04:271444 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1445
Seth Hampson2f0d7022018-02-20 19:54:421446 // Expects the provided number of new frames to be received within
1447 // kMaxWaitForFramesMs. The new expected frames are specified in
1448 // |media_expectations|. Returns false if any of the expectations were
1449 // not met.
1450 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1451 // First initialize the expected frame counts based upon the current
1452 // frame count.
1453 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1454 if (media_expectations.caller_audio_expectation_ ==
1455 MediaExpectations::kExpectSomeFrames) {
1456 total_caller_audio_frames_expected +=
1457 media_expectations.caller_audio_frames_expected_;
1458 }
1459 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-30 04:08:161460 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 19:54:421461 if (media_expectations.caller_video_expectation_ ==
1462 MediaExpectations::kExpectSomeFrames) {
1463 total_caller_video_frames_expected +=
1464 media_expectations.caller_video_frames_expected_;
1465 }
1466 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1467 if (media_expectations.callee_audio_expectation_ ==
1468 MediaExpectations::kExpectSomeFrames) {
1469 total_callee_audio_frames_expected +=
1470 media_expectations.callee_audio_frames_expected_;
1471 }
1472 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-30 04:08:161473 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 19:54:421474 if (media_expectations.callee_video_expectation_ ==
1475 MediaExpectations::kExpectSomeFrames) {
1476 total_callee_video_frames_expected +=
1477 media_expectations.callee_video_frames_expected_;
1478 }
deadbeef1dcb1642017-03-30 04:08:161479
Seth Hampson2f0d7022018-02-20 19:54:421480 // Wait for the expected frames.
deadbeef1dcb1642017-03-30 04:08:161481 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 19:54:421482 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-30 04:08:161483 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 19:54:421484 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-30 04:08:161485 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 19:54:421486 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-30 04:08:161487 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 19:54:421488 total_callee_video_frames_expected,
1489 kMaxWaitForFramesMs);
1490 bool expectations_correct =
1491 caller()->audio_frames_received() >=
1492 total_caller_audio_frames_expected &&
1493 caller()->min_video_frames_received_per_track() >=
1494 total_caller_video_frames_expected &&
1495 callee()->audio_frames_received() >=
1496 total_callee_audio_frames_expected &&
1497 callee()->min_video_frames_received_per_track() >=
1498 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-30 04:08:161499
Seth Hampson2f0d7022018-02-20 19:54:421500 // After the combined wait, print out a more detailed message upon
1501 // failure.
deadbeef1dcb1642017-03-30 04:08:161502 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 19:54:421503 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-30 04:08:161504 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 19:54:421505 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-30 04:08:161506 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 19:54:421507 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-30 04:08:161508 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 19:54:421509 total_callee_video_frames_expected);
1510
1511 // We want to make sure nothing unexpected was received.
1512 if (media_expectations.caller_audio_expectation_ ==
1513 MediaExpectations::kExpectNoFrames) {
1514 EXPECT_EQ(caller()->audio_frames_received(),
1515 total_caller_audio_frames_expected);
1516 if (caller()->audio_frames_received() !=
1517 total_caller_audio_frames_expected) {
1518 expectations_correct = false;
1519 }
1520 }
1521 if (media_expectations.caller_video_expectation_ ==
1522 MediaExpectations::kExpectNoFrames) {
1523 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1524 total_caller_video_frames_expected);
1525 if (caller()->min_video_frames_received_per_track() !=
1526 total_caller_video_frames_expected) {
1527 expectations_correct = false;
1528 }
1529 }
1530 if (media_expectations.callee_audio_expectation_ ==
1531 MediaExpectations::kExpectNoFrames) {
1532 EXPECT_EQ(callee()->audio_frames_received(),
1533 total_callee_audio_frames_expected);
1534 if (callee()->audio_frames_received() !=
1535 total_callee_audio_frames_expected) {
1536 expectations_correct = false;
1537 }
1538 }
1539 if (media_expectations.callee_video_expectation_ ==
1540 MediaExpectations::kExpectNoFrames) {
1541 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1542 total_callee_video_frames_expected);
1543 if (callee()->min_video_frames_received_per_track() !=
1544 total_callee_video_frames_expected) {
1545 expectations_correct = false;
1546 }
1547 }
1548 return expectations_correct;
deadbeef1dcb1642017-03-30 04:08:161549 }
1550
Taylor Brandstetter5e55fe82018-03-23 18:50:161551 void TestNegotiatedCipherSuite(
1552 const PeerConnectionFactory::Options& caller_options,
1553 const PeerConnectionFactory::Options& callee_options,
1554 int expected_cipher_suite) {
deadbeef1dcb1642017-03-30 04:08:161555 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1556 callee_options));
deadbeef1dcb1642017-03-30 04:08:161557 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491558 caller()->AddAudioVideoTracks();
1559 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161560 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 19:54:531561 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:161562 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 23:01:171563 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 19:54:531564 // TODO(bugs.webrtc.org/9456): Fix it.
1565 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1566 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1567 expected_cipher_suite));
deadbeef1dcb1642017-03-30 04:08:161568 }
1569
Taylor Brandstetter5e55fe82018-03-23 18:50:161570 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1571 bool remote_gcm_enabled,
1572 int expected_cipher_suite) {
1573 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 22:33:171574 caller_options.crypto_options.srtp.enable_gcm_crypto_suites =
1575 local_gcm_enabled;
Taylor Brandstetter5e55fe82018-03-23 18:50:161576 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 22:33:171577 callee_options.crypto_options.srtp.enable_gcm_crypto_suites =
1578 remote_gcm_enabled;
Taylor Brandstetter5e55fe82018-03-23 18:50:161579 TestNegotiatedCipherSuite(caller_options, callee_options,
1580 expected_cipher_suite);
1581 }
1582
Seth Hampson2f0d7022018-02-20 19:54:421583 protected:
Steve Anton3acffc32018-04-13 00:21:031584 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 19:54:421585
deadbeef1dcb1642017-03-30 04:08:161586 private:
1587 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-30 04:08:161588 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 20:04:271589 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-30 04:08:161590 // |network_thread_| and |worker_thread_| are used by both
1591 // |caller_| and |callee_| so they must be destroyed
1592 // later.
1593 std::unique_ptr<rtc::Thread> network_thread_;
1594 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 14:41:321595 // The turn servers and turn customizers should be accessed & deleted on the
1596 // network thread to avoid a race with the socket read/write that occurs
1597 // on the network thread.
1598 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1599 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-30 04:08:161600 std::unique_ptr<PeerConnectionWrapper> caller_;
1601 std::unique_ptr<PeerConnectionWrapper> callee_;
1602};
1603
Seth Hampson2f0d7022018-02-20 19:54:421604class PeerConnectionIntegrationTest
1605 : public PeerConnectionIntegrationBaseTest,
1606 public ::testing::WithParamInterface<SdpSemantics> {
1607 protected:
1608 PeerConnectionIntegrationTest()
1609 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1610};
1611
1612class PeerConnectionIntegrationTestPlanB
1613 : public PeerConnectionIntegrationBaseTest {
1614 protected:
1615 PeerConnectionIntegrationTestPlanB()
1616 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1617};
1618
1619class PeerConnectionIntegrationTestUnifiedPlan
1620 : public PeerConnectionIntegrationBaseTest {
1621 protected:
1622 PeerConnectionIntegrationTestUnifiedPlan()
1623 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1624};
1625
deadbeef1dcb1642017-03-30 04:08:161626// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1627// includes testing that the callback is invoked if an observer is connected
1628// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 19:54:421629TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:161630 RtpReceiverObserverOnFirstPacketReceived) {
1631 ASSERT_TRUE(CreatePeerConnectionWrappers());
1632 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491633 caller()->AddAudioVideoTracks();
1634 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161635 // Start offer/answer exchange and wait for it to complete.
1636 caller()->CreateAndSetAndSignalOffer();
1637 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1638 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 10:53:231639 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1640 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-30 04:08:161641 // Wait for all "first packet received" callbacks to be fired.
1642 EXPECT_TRUE_WAIT(
1643 std::all_of(caller()->rtp_receiver_observers().begin(),
1644 caller()->rtp_receiver_observers().end(),
1645 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1646 return o->first_packet_received();
1647 }),
1648 kMaxWaitForFramesMs);
1649 EXPECT_TRUE_WAIT(
1650 std::all_of(callee()->rtp_receiver_observers().begin(),
1651 callee()->rtp_receiver_observers().end(),
1652 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1653 return o->first_packet_received();
1654 }),
1655 kMaxWaitForFramesMs);
1656 // If new observers are set after the first packet was already received, the
1657 // callback should still be invoked.
1658 caller()->ResetRtpReceiverObservers();
1659 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 10:53:231660 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1661 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-30 04:08:161662 EXPECT_TRUE(
1663 std::all_of(caller()->rtp_receiver_observers().begin(),
1664 caller()->rtp_receiver_observers().end(),
1665 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1666 return o->first_packet_received();
1667 }));
1668 EXPECT_TRUE(
1669 std::all_of(callee()->rtp_receiver_observers().begin(),
1670 callee()->rtp_receiver_observers().end(),
1671 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1672 return o->first_packet_received();
1673 }));
1674}
1675
1676class DummyDtmfObserver : public DtmfSenderObserverInterface {
1677 public:
1678 DummyDtmfObserver() : completed_(false) {}
1679
1680 // Implements DtmfSenderObserverInterface.
1681 void OnToneChange(const std::string& tone) override {
1682 tones_.push_back(tone);
1683 if (tone.empty()) {
1684 completed_ = true;
1685 }
1686 }
1687
1688 const std::vector<std::string>& tones() const { return tones_; }
1689 bool completed() const { return completed_; }
1690
1691 private:
1692 bool completed_;
1693 std::vector<std::string> tones_;
1694};
1695
1696// Assumes |sender| already has an audio track added and the offer/answer
1697// exchange is done.
1698void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1699 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 18:26:491700 // We should be able to get a DTMF sender from the local sender.
1701 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1702 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1703 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-30 04:08:161704 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-30 04:08:161705 dtmf_sender->RegisterObserver(&observer);
1706
1707 // Test the DtmfSender object just created.
1708 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1709 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1710
1711 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1712 std::vector<std::string> tones = {"1", "a", ""};
1713 EXPECT_EQ(tones, observer.tones());
1714 dtmf_sender->UnregisterObserver();
1715 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1716}
1717
1718// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1719// direction).
Seth Hampson2f0d7022018-02-20 19:54:421720TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-30 04:08:161721 ASSERT_TRUE(CreatePeerConnectionWrappers());
1722 ConnectFakeSignaling();
1723 // Only need audio for DTMF.
Steve Anton15324772018-01-16 18:26:491724 caller()->AddAudioTrack();
1725 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-30 04:08:161726 caller()->CreateAndSetAndSignalOffer();
1727 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-08 00:21:011728 // DTLS must finish before the DTMF sender can be used reliably.
1729 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:161730 TestDtmfFromSenderToReceiver(caller(), callee());
1731 TestDtmfFromSenderToReceiver(callee(), caller());
1732}
1733
1734// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1735// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 19:54:421736TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-30 04:08:161737 ASSERT_TRUE(CreatePeerConnectionWrappers());
1738 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 15:04:131739
deadbeef1dcb1642017-03-30 04:08:161740 // Do normal offer/answer and wait for some frames to be received in each
1741 // direction.
Steve Anton15324772018-01-16 18:26:491742 caller()->AddAudioVideoTracks();
1743 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161744 caller()->CreateAndSetAndSignalOffer();
1745 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421746 MediaExpectations media_expectations;
1747 media_expectations.ExpectBidirectionalAudioAndVideo();
1748 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 19:54:531749 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1750 webrtc::kEnumCounterKeyProtocolDtls));
1751 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1752 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-30 04:08:161753}
1754
1755// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 19:54:421756TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-30 04:08:161757 PeerConnectionInterface::RTCConfiguration sdes_config;
1758 sdes_config.enable_dtls_srtp.emplace(false);
1759 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1760 ConnectFakeSignaling();
1761
1762 // Do normal offer/answer and wait for some frames to be received in each
1763 // direction.
Steve Anton15324772018-01-16 18:26:491764 caller()->AddAudioVideoTracks();
1765 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161766 caller()->CreateAndSetAndSignalOffer();
1767 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421768 MediaExpectations media_expectations;
1769 media_expectations.ExpectBidirectionalAudioAndVideo();
1770 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 19:54:531771 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1772 webrtc::kEnumCounterKeyProtocolSdes));
1773 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1774 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-30 04:08:161775}
1776
Steve Anton8c0f7a72017-10-03 17:03:101777// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1778// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 19:54:421779TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 17:03:101780 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1781 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1782 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1783 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1784 return pc->GetRemoteAudioSSLCertificate();
1785 };
Zhi Huang70b820f2018-01-27 22:16:151786 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1787 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1788 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1789 return pc->GetRemoteAudioSSLCertChain();
1790 };
Steve Anton8c0f7a72017-10-03 17:03:101791
1792 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1793 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1794
1795 // Configure each side with a known certificate so they can be compared later.
1796 PeerConnectionInterface::RTCConfiguration caller_config;
1797 caller_config.enable_dtls_srtp.emplace(true);
1798 caller_config.certificates.push_back(caller_cert);
1799 PeerConnectionInterface::RTCConfiguration callee_config;
1800 callee_config.enable_dtls_srtp.emplace(true);
1801 callee_config.certificates.push_back(callee_cert);
1802 ASSERT_TRUE(
1803 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1804 ConnectFakeSignaling();
1805
1806 // When first initialized, there should not be a remote SSL certificate (and
1807 // calling this method should not crash).
1808 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1809 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 22:16:151810 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1811 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 17:03:101812
Steve Anton15324772018-01-16 18:26:491813 caller()->AddAudioTrack();
1814 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 17:03:101815 caller()->CreateAndSetAndSignalOffer();
1816 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1817 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1818
1819 // Once DTLS has been connected, each side should return the other's SSL
1820 // certificate when calling GetRemoteAudioSSLCertificate.
1821
1822 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1823 ASSERT_TRUE(caller_remote_cert);
Benjamin Wright6c6c9df2018-10-25 08:16:261824 EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(),
Steve Anton8c0f7a72017-10-03 17:03:101825 caller_remote_cert->ToPEMString());
1826
1827 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1828 ASSERT_TRUE(callee_remote_cert);
Benjamin Wright6c6c9df2018-10-25 08:16:261829 EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(),
Steve Anton8c0f7a72017-10-03 17:03:101830 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 22:16:151831
1832 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1833 ASSERT_TRUE(caller_remote_cert_chain);
1834 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1835 auto remote_cert = &caller_remote_cert_chain->Get(0);
Benjamin Wright6c6c9df2018-10-25 08:16:261836 EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(),
Zhi Huang70b820f2018-01-27 22:16:151837 remote_cert->ToPEMString());
1838
1839 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1840 ASSERT_TRUE(callee_remote_cert_chain);
1841 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1842 remote_cert = &callee_remote_cert_chain->Get(0);
Benjamin Wright6c6c9df2018-10-25 08:16:261843 EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(),
Zhi Huang70b820f2018-01-27 22:16:151844 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 17:03:101845}
1846
deadbeef1dcb1642017-03-30 04:08:161847// This test sets up a call between two parties with a source resolution of
1848// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 19:54:421849TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:161850 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1851 ASSERT_TRUE(CreatePeerConnectionWrappers());
1852 ConnectFakeSignaling();
1853
Niels Möller5c7efe72018-05-11 08:34:461854 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1855 webrtc::FakePeriodicVideoSource::Config config;
1856 config.width = 1280;
1857 config.height = 720;
Johannes Kron965e7942018-09-13 13:36:201858 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 08:34:461859 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1860 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-30 04:08:161861
1862 // Do normal offer/answer and wait for at least one frame to be received in
1863 // each direction.
1864 caller()->CreateAndSetAndSignalOffer();
1865 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1866 callee()->min_video_frames_received_per_track() > 0,
1867 kMaxWaitForFramesMs);
1868
1869 // Check rendered aspect ratio.
1870 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1871 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1872 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1873 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1874}
1875
1876// This test sets up an one-way call, with media only from caller to
1877// callee.
Seth Hampson2f0d7022018-02-20 19:54:421878TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-30 04:08:161879 ASSERT_TRUE(CreatePeerConnectionWrappers());
1880 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491881 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161882 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 19:54:421883 MediaExpectations media_expectations;
1884 media_expectations.CalleeExpectsSomeAudioAndVideo();
1885 media_expectations.CallerExpectsNoAudio();
1886 media_expectations.CallerExpectsNoVideo();
1887 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:161888}
1889
1890// This test sets up a audio call initially, with the callee rejecting video
1891// initially. Then later the callee decides to upgrade to audio/video, and
1892// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 19:54:421893TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-30 04:08:161894 ASSERT_TRUE(CreatePeerConnectionWrappers());
1895 ConnectFakeSignaling();
1896 // Initially, offer an audio/video stream from the caller, but refuse to
1897 // send/receive video on the callee side.
Steve Anton15324772018-01-16 18:26:491898 caller()->AddAudioVideoTracks();
1899 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 19:54:421900 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1901 PeerConnectionInterface::RTCOfferAnswerOptions options;
1902 options.offer_to_receive_video = 0;
1903 callee()->SetOfferAnswerOptions(options);
1904 } else {
1905 callee()->SetRemoteOfferHandler([this] {
1906 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1907 });
1908 }
deadbeef1dcb1642017-03-30 04:08:161909 // Do offer/answer and make sure audio is still received end-to-end.
1910 caller()->CreateAndSetAndSignalOffer();
1911 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421912 {
1913 MediaExpectations media_expectations;
1914 media_expectations.ExpectBidirectionalAudio();
1915 media_expectations.ExpectNoVideo();
1916 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1917 }
deadbeef1dcb1642017-03-30 04:08:161918 // Sanity check that the callee's description has a rejected video section.
1919 ASSERT_NE(nullptr, callee()->pc()->local_description());
1920 const ContentInfo* callee_video_content =
1921 GetFirstVideoContent(callee()->pc()->local_description()->description());
1922 ASSERT_NE(nullptr, callee_video_content);
1923 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 19:54:421924
deadbeef1dcb1642017-03-30 04:08:161925 // Now negotiate with video and ensure negotiation succeeds, with video
1926 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 18:26:491927 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 19:54:421928 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1929 PeerConnectionInterface::RTCOfferAnswerOptions options;
1930 options.offer_to_receive_video = 1;
1931 callee()->SetOfferAnswerOptions(options);
1932 } else {
1933 callee()->SetRemoteOfferHandler(nullptr);
1934 caller()->SetRemoteOfferHandler([this] {
1935 // The caller creates a new transceiver to receive video on when receiving
1936 // the offer, but by default it is send only.
1937 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 10:53:231938 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 19:54:421939 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1940 transceivers[2]->receiver()->media_type());
1941 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1942 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1943 });
1944 }
deadbeef1dcb1642017-03-30 04:08:161945 callee()->CreateAndSetAndSignalOffer();
1946 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421947 {
1948 // Expect additional audio frames to be received after the upgrade.
1949 MediaExpectations media_expectations;
1950 media_expectations.ExpectBidirectionalAudioAndVideo();
1951 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1952 }
deadbeef1dcb1642017-03-30 04:08:161953}
1954
deadbeef4389b4d2017-09-07 16:07:361955// Simpler than the above test; just add an audio track to an established
1956// video-only connection.
Seth Hampson2f0d7022018-02-20 19:54:421957TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 16:07:361958 ASSERT_TRUE(CreatePeerConnectionWrappers());
1959 ConnectFakeSignaling();
1960 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 18:26:491961 caller()->AddVideoTrack();
1962 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 16:07:361963 caller()->CreateAndSetAndSignalOffer();
1964 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1965 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 18:26:491966 caller()->AddAudioTrack();
1967 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 16:07:361968 caller()->CreateAndSetAndSignalOffer();
1969 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1970 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:421971 MediaExpectations media_expectations;
1972 media_expectations.ExpectBidirectionalAudioAndVideo();
1973 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 16:07:361974}
1975
deadbeef1dcb1642017-03-30 04:08:161976// This test sets up a call that's transferred to a new caller with a different
1977// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 19:54:421978TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-30 04:08:161979 ASSERT_TRUE(CreatePeerConnectionWrappers());
1980 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491981 caller()->AddAudioVideoTracks();
1982 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161983 caller()->CreateAndSetAndSignalOffer();
1984 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1985
1986 // Keep the original peer around which will still send packets to the
1987 // receiving client. These SRTP packets will be dropped.
1988 std::unique_ptr<PeerConnectionWrapper> original_peer(
1989 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 19:54:421990 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-30 04:08:161991 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1992 // directly above.
1993 original_peer->pc()->Close();
1994
1995 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491996 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161997 caller()->CreateAndSetAndSignalOffer();
1998 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1999 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:422000 MediaExpectations media_expectations;
2001 media_expectations.ExpectBidirectionalAudioAndVideo();
2002 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162003}
2004
2005// This test sets up a call that's transferred to a new callee with a different
2006// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 19:54:422007TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-30 04:08:162008 ASSERT_TRUE(CreatePeerConnectionWrappers());
2009 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492010 caller()->AddAudioVideoTracks();
2011 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162012 caller()->CreateAndSetAndSignalOffer();
2013 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2014
2015 // Keep the original peer around which will still send packets to the
2016 // receiving client. These SRTP packets will be dropped.
2017 std::unique_ptr<PeerConnectionWrapper> original_peer(
2018 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 19:54:422019 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-30 04:08:162020 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2021 // directly above.
2022 original_peer->pc()->Close();
2023
2024 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492025 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162026 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2027 caller()->CreateAndSetAndSignalOffer();
2028 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2029 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:422030 MediaExpectations media_expectations;
2031 media_expectations.ExpectBidirectionalAudioAndVideo();
2032 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162033}
2034
2035// This test sets up a non-bundled call and negotiates bundling at the same
2036// time as starting an ICE restart. When bundling is in effect in the restart,
2037// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 19:54:422038TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-30 04:08:162039 ASSERT_TRUE(CreatePeerConnectionWrappers());
2040 ConnectFakeSignaling();
2041
Steve Anton15324772018-01-16 18:26:492042 caller()->AddAudioVideoTracks();
2043 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162044 // Remove the bundle group from the SDP received by the callee.
2045 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2046 desc->RemoveGroupByName("BUNDLE");
2047 });
2048 caller()->CreateAndSetAndSignalOffer();
2049 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422050 {
2051 MediaExpectations media_expectations;
2052 media_expectations.ExpectBidirectionalAudioAndVideo();
2053 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2054 }
deadbeef1dcb1642017-03-30 04:08:162055 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2056 callee()->SetReceivedSdpMunger(nullptr);
2057 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2058 caller()->CreateAndSetAndSignalOffer();
2059 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2060
2061 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 19:54:422062 {
2063 MediaExpectations media_expectations;
2064 media_expectations.ExpectBidirectionalAudioAndVideo();
2065 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2066 }
deadbeef1dcb1642017-03-30 04:08:162067}
2068
2069// Test CVO (Coordination of Video Orientation). If a video source is rotated
2070// and both peers support the CVO RTP header extension, the actual video frames
2071// don't need to be encoded in different resolutions, since the rotation is
2072// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 19:54:422073TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-30 04:08:162074 ASSERT_TRUE(CreatePeerConnectionWrappers());
2075 ConnectFakeSignaling();
2076 // Add rotated video tracks.
Steve Anton15324772018-01-16 18:26:492077 caller()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162078 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 18:26:492079 callee()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162080 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2081
2082 // Wait for video frames to be received by both sides.
2083 caller()->CreateAndSetAndSignalOffer();
2084 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2085 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2086 callee()->min_video_frames_received_per_track() > 0,
2087 kMaxWaitForFramesMs);
2088
2089 // Ensure that the aspect ratio is unmodified.
2090 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2091 // not just assumed.
2092 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2093 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2094 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2095 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2096 // Ensure that the CVO bits were surfaced to the renderer.
2097 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2098 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2099}
2100
2101// Test that when the CVO extension isn't supported, video is rotated the
2102// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 19:54:422103TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-30 04:08:162104 ASSERT_TRUE(CreatePeerConnectionWrappers());
2105 ConnectFakeSignaling();
2106 // Add rotated video tracks.
Steve Anton15324772018-01-16 18:26:492107 caller()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162108 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 18:26:492109 callee()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162110 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2111
2112 // Remove the CVO extension from the offered SDP.
2113 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2114 cricket::VideoContentDescription* video =
2115 GetFirstVideoContentDescription(desc);
2116 video->ClearRtpHeaderExtensions();
2117 });
2118 // Wait for video frames to be received by both sides.
2119 caller()->CreateAndSetAndSignalOffer();
2120 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2121 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2122 callee()->min_video_frames_received_per_track() > 0,
2123 kMaxWaitForFramesMs);
2124
2125 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2126 // rotation.
2127 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2128 // not just assumed.
2129 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2130 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2131 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2132 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2133 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2134 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2135 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2136}
2137
deadbeef1dcb1642017-03-30 04:08:162138// Test that if the answerer rejects the audio m= section, no audio is sent or
2139// received, but video still can be.
Seth Hampson2f0d7022018-02-20 19:54:422140TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-30 04:08:162141 ASSERT_TRUE(CreatePeerConnectionWrappers());
2142 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492143 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 19:54:422144 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2145 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2146 // it will reject the audio m= section completely.
2147 PeerConnectionInterface::RTCOfferAnswerOptions options;
2148 options.offer_to_receive_audio = 0;
2149 callee()->SetOfferAnswerOptions(options);
2150 } else {
2151 // Stopping the audio RtpTransceiver will cause the media section to be
2152 // rejected in the answer.
2153 callee()->SetRemoteOfferHandler([this] {
2154 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2155 });
2156 }
Steve Anton15324772018-01-16 18:26:492157 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-30 04:08:162158 // Do offer/answer and wait for successful end-to-end video frames.
2159 caller()->CreateAndSetAndSignalOffer();
2160 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422161 MediaExpectations media_expectations;
2162 media_expectations.ExpectBidirectionalVideo();
2163 media_expectations.ExpectNoAudio();
2164 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2165
deadbeef1dcb1642017-03-30 04:08:162166 // Sanity check that the callee's description has a rejected audio section.
2167 ASSERT_NE(nullptr, callee()->pc()->local_description());
2168 const ContentInfo* callee_audio_content =
2169 GetFirstAudioContent(callee()->pc()->local_description()->description());
2170 ASSERT_NE(nullptr, callee_audio_content);
2171 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 19:54:422172 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2173 // The caller's transceiver should have stopped after receiving the answer.
2174 EXPECT_TRUE(caller()
2175 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2176 ->stopped());
2177 }
deadbeef1dcb1642017-03-30 04:08:162178}
2179
2180// Test that if the answerer rejects the video m= section, no video is sent or
2181// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 19:54:422182TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-30 04:08:162183 ASSERT_TRUE(CreatePeerConnectionWrappers());
2184 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492185 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 19:54:422186 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2187 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2188 // it will reject the video m= section completely.
2189 PeerConnectionInterface::RTCOfferAnswerOptions options;
2190 options.offer_to_receive_video = 0;
2191 callee()->SetOfferAnswerOptions(options);
2192 } else {
2193 // Stopping the video RtpTransceiver will cause the media section to be
2194 // rejected in the answer.
2195 callee()->SetRemoteOfferHandler([this] {
2196 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2197 });
2198 }
Steve Anton15324772018-01-16 18:26:492199 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-30 04:08:162200 // Do offer/answer and wait for successful end-to-end audio frames.
2201 caller()->CreateAndSetAndSignalOffer();
2202 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422203 MediaExpectations media_expectations;
2204 media_expectations.ExpectBidirectionalAudio();
2205 media_expectations.ExpectNoVideo();
2206 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2207
deadbeef1dcb1642017-03-30 04:08:162208 // Sanity check that the callee's description has a rejected video section.
2209 ASSERT_NE(nullptr, callee()->pc()->local_description());
2210 const ContentInfo* callee_video_content =
2211 GetFirstVideoContent(callee()->pc()->local_description()->description());
2212 ASSERT_NE(nullptr, callee_video_content);
2213 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 19:54:422214 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2215 // The caller's transceiver should have stopped after receiving the answer.
2216 EXPECT_TRUE(caller()
2217 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2218 ->stopped());
2219 }
deadbeef1dcb1642017-03-30 04:08:162220}
2221
2222// Test that if the answerer rejects both audio and video m= sections, nothing
2223// bad happens.
2224// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2225// test anything but the fact that negotiation succeeds, which doesn't mean
2226// much.
Seth Hampson2f0d7022018-02-20 19:54:422227TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-30 04:08:162228 ASSERT_TRUE(CreatePeerConnectionWrappers());
2229 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492230 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 19:54:422231 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2232 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2233 // will reject both audio and video m= sections.
2234 PeerConnectionInterface::RTCOfferAnswerOptions options;
2235 options.offer_to_receive_audio = 0;
2236 options.offer_to_receive_video = 0;
2237 callee()->SetOfferAnswerOptions(options);
2238 } else {
2239 callee()->SetRemoteOfferHandler([this] {
2240 // Stopping all transceivers will cause all media sections to be rejected.
2241 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2242 transceiver->Stop();
2243 }
2244 });
2245 }
deadbeef1dcb1642017-03-30 04:08:162246 // Do offer/answer and wait for stable signaling state.
2247 caller()->CreateAndSetAndSignalOffer();
2248 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422249
deadbeef1dcb1642017-03-30 04:08:162250 // Sanity check that the callee's description has rejected m= sections.
2251 ASSERT_NE(nullptr, callee()->pc()->local_description());
2252 const ContentInfo* callee_audio_content =
2253 GetFirstAudioContent(callee()->pc()->local_description()->description());
2254 ASSERT_NE(nullptr, callee_audio_content);
2255 EXPECT_TRUE(callee_audio_content->rejected);
2256 const ContentInfo* callee_video_content =
2257 GetFirstVideoContent(callee()->pc()->local_description()->description());
2258 ASSERT_NE(nullptr, callee_video_content);
2259 EXPECT_TRUE(callee_video_content->rejected);
2260}
2261
2262// This test sets up an audio and video call between two parties. After the
2263// call runs for a while, the caller sends an updated offer with video being
2264// rejected. Once the re-negotiation is done, the video flow should stop and
2265// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 19:54:422266TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-30 04:08:162267 ASSERT_TRUE(CreatePeerConnectionWrappers());
2268 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492269 caller()->AddAudioVideoTracks();
2270 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162271 caller()->CreateAndSetAndSignalOffer();
2272 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422273 {
2274 MediaExpectations media_expectations;
2275 media_expectations.ExpectBidirectionalAudioAndVideo();
2276 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2277 }
deadbeef1dcb1642017-03-30 04:08:162278 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 19:54:422279 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2280 caller()->SetGeneratedSdpMunger(
2281 [](cricket::SessionDescription* description) {
2282 for (cricket::ContentInfo& content : description->contents()) {
2283 if (cricket::IsVideoContent(&content)) {
2284 content.rejected = true;
2285 }
2286 }
2287 });
2288 } else {
2289 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2290 }
deadbeef1dcb1642017-03-30 04:08:162291 caller()->CreateAndSetAndSignalOffer();
2292 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2293
2294 // Sanity check that the caller's description has a rejected video section.
2295 ASSERT_NE(nullptr, caller()->pc()->local_description());
2296 const ContentInfo* caller_video_content =
2297 GetFirstVideoContent(caller()->pc()->local_description()->description());
2298 ASSERT_NE(nullptr, caller_video_content);
2299 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-30 04:08:162300 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 19:54:422301 {
2302 MediaExpectations media_expectations;
2303 media_expectations.ExpectBidirectionalAudio();
2304 media_expectations.ExpectNoVideo();
2305 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2306 }
deadbeef1dcb1642017-03-30 04:08:162307}
2308
Taylor Brandstetter60c8dc82018-04-11 22:20:272309// Do one offer/answer with audio, another that disables it (rejecting the m=
2310// section), and another that re-enables it. Regression test for:
2311// bugs.webrtc.org/6023
2312TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2313 ASSERT_TRUE(CreatePeerConnectionWrappers());
2314 ConnectFakeSignaling();
2315
2316 // Add audio track, do normal offer/answer.
2317 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2318 caller()->CreateLocalAudioTrack();
2319 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2320 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2321 caller()->CreateAndSetAndSignalOffer();
2322 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2323
2324 // Remove audio track, and set offer_to_receive_audio to false to cause the
2325 // m= section to be completely disabled, not just "recvonly".
2326 caller()->pc()->RemoveTrack(sender);
2327 PeerConnectionInterface::RTCOfferAnswerOptions options;
2328 options.offer_to_receive_audio = 0;
2329 caller()->SetOfferAnswerOptions(options);
2330 caller()->CreateAndSetAndSignalOffer();
2331 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2332
2333 // Add the audio track again, expecting negotiation to succeed and frames to
2334 // flow.
2335 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2336 options.offer_to_receive_audio = 1;
2337 caller()->SetOfferAnswerOptions(options);
2338 caller()->CreateAndSetAndSignalOffer();
2339 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2340
2341 MediaExpectations media_expectations;
2342 media_expectations.CalleeExpectsSomeAudio();
2343 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2344}
2345
deadbeef1dcb1642017-03-30 04:08:162346// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2347// is needed to support legacy endpoints.
2348// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2349// add a test for an end-to-end test without MID signaling either (basically,
2350// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 19:54:422351TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-30 04:08:162352 ASSERT_TRUE(CreatePeerConnectionWrappers());
2353 ConnectFakeSignaling();
2354 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 18:26:492355 caller()->AddAudioVideoTracks();
2356 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 23:01:172357 // Remove SSRCs and MSIDs from the received offer SDP.
2358 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-30 04:08:162359 caller()->CreateAndSetAndSignalOffer();
2360 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422361 MediaExpectations media_expectations;
2362 media_expectations.ExpectBidirectionalAudioAndVideo();
2363 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162364}
2365
Seth Hampson5897a6e2018-04-03 18:16:332366// Basic end-to-end test, without SSRC signaling. This means that the track
2367// was created properly and frames are delivered when the MSIDs are communicated
2368// with a=msid lines and no a=ssrc lines.
2369TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2370 EndToEndCallWithoutSsrcSignaling) {
2371 const char kStreamId[] = "streamId";
2372 ASSERT_TRUE(CreatePeerConnectionWrappers());
2373 ConnectFakeSignaling();
2374 // Add just audio tracks.
2375 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2376 callee()->AddAudioTrack();
2377
2378 // Remove SSRCs from the received offer SDP.
2379 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2380 caller()->CreateAndSetAndSignalOffer();
2381 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2382 MediaExpectations media_expectations;
2383 media_expectations.ExpectBidirectionalAudio();
2384 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2385}
2386
Steve Antondf527fd2018-04-27 22:52:032387// Tests that video flows between multiple video tracks when SSRCs are not
2388// signaled. This exercises the MID RTP header extension which is needed to
2389// demux the incoming video tracks.
2390TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2391 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2392 ASSERT_TRUE(CreatePeerConnectionWrappers());
2393 ConnectFakeSignaling();
2394 caller()->AddVideoTrack();
2395 caller()->AddVideoTrack();
2396 callee()->AddVideoTrack();
2397 callee()->AddVideoTrack();
2398
2399 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2400 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2401 caller()->CreateAndSetAndSignalOffer();
2402 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2403 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2404 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2405
2406 // Expect video to be received in both directions on both tracks.
2407 MediaExpectations media_expectations;
2408 media_expectations.ExpectBidirectionalVideo();
2409 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2410}
2411
deadbeef1dcb1642017-03-30 04:08:162412// Test that if two video tracks are sent (from caller to callee, in this test),
2413// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:422414TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-30 04:08:162415 ASSERT_TRUE(CreatePeerConnectionWrappers());
2416 ConnectFakeSignaling();
2417 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 18:26:492418 caller()->AddAudioVideoTracks();
2419 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-30 04:08:162420 caller()->CreateAndSetAndSignalOffer();
2421 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 18:26:492422 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 19:54:422423
2424 MediaExpectations media_expectations;
2425 media_expectations.CalleeExpectsSomeAudioAndVideo();
2426 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162427}
2428
2429static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2430 bool first = true;
2431 for (cricket::ContentInfo& content : desc->contents()) {
2432 if (first) {
2433 first = false;
2434 continue;
2435 }
2436 content.bundle_only = true;
2437 }
2438 first = true;
2439 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2440 if (first) {
2441 first = false;
2442 continue;
2443 }
2444 transport.description.ice_ufrag.clear();
2445 transport.description.ice_pwd.clear();
2446 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2447 transport.description.identity_fingerprint.reset(nullptr);
2448 }
2449}
2450
2451// Test that if applying a true "max bundle" offer, which uses ports of 0,
2452// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2453// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2454// successfully and media flows.
2455// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2456// TODO(deadbeef): Won't need this test once we start generating actual
2457// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 19:54:422458TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162459 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2460 ASSERT_TRUE(CreatePeerConnectionWrappers());
2461 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492462 caller()->AddAudioVideoTracks();
2463 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162464 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2465 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2466 // but the first m= section.
2467 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2468 caller()->CreateAndSetAndSignalOffer();
2469 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422470 MediaExpectations media_expectations;
2471 media_expectations.ExpectBidirectionalAudioAndVideo();
2472 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162473}
2474
2475// Test that we can receive the audio output level from a remote audio track.
2476// TODO(deadbeef): Use a fake audio source and verify that the output level is
2477// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 19:54:422478TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162479 ASSERT_TRUE(CreatePeerConnectionWrappers());
2480 ConnectFakeSignaling();
2481 // Just add an audio track.
Steve Anton15324772018-01-16 18:26:492482 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-30 04:08:162483 caller()->CreateAndSetAndSignalOffer();
2484 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2485
2486 // Get the audio output level stats. Note that the level is not available
2487 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 23:01:172488 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-30 04:08:162489 kMaxWaitForFramesMs);
2490}
2491
2492// Test that an audio input level is reported.
2493// TODO(deadbeef): Use a fake audio source and verify that the input level is
2494// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 19:54:422495TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162496 ASSERT_TRUE(CreatePeerConnectionWrappers());
2497 ConnectFakeSignaling();
2498 // Just add an audio track.
Steve Anton15324772018-01-16 18:26:492499 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-30 04:08:162500 caller()->CreateAndSetAndSignalOffer();
2501 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2502
2503 // Get the audio input level stats. The level should be available very
2504 // soon after the test starts.
deadbeefd8ad7882017-04-18 23:01:172505 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-30 04:08:162506 kMaxWaitForStatsMs);
2507}
2508
2509// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 19:54:422510TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162511 ASSERT_TRUE(CreatePeerConnectionWrappers());
2512 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492513 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162514 // Do offer/answer, wait for the callee to receive some frames.
2515 caller()->CreateAndSetAndSignalOffer();
2516 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422517
2518 MediaExpectations media_expectations;
2519 media_expectations.CalleeExpectsSomeAudioAndVideo();
2520 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162521
2522 // Get a handle to the remote tracks created, so they can be used as GetStats
2523 // filters.
Steve Anton15324772018-01-16 18:26:492524 for (auto receiver : callee()->pc()->GetReceivers()) {
2525 // We received frames, so we definitely should have nonzero "received bytes"
2526 // stats at this point.
2527 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2528 0);
2529 }
deadbeef1dcb1642017-03-30 04:08:162530}
2531
2532// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 19:54:422533TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162534 ASSERT_TRUE(CreatePeerConnectionWrappers());
2535 ConnectFakeSignaling();
2536 auto audio_track = caller()->CreateLocalAudioTrack();
2537 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 18:26:492538 caller()->AddTrack(audio_track);
2539 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-30 04:08:162540 // Do offer/answer, wait for the callee to receive some frames.
2541 caller()->CreateAndSetAndSignalOffer();
2542 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422543 MediaExpectations media_expectations;
2544 media_expectations.CalleeExpectsSomeAudioAndVideo();
2545 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162546
2547 // The callee received frames, so we definitely should have nonzero "sent
2548 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 23:01:172549 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2550 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2551}
2552
Fredrik Solenberg73276ad2017-09-14 12:46:472553// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 19:54:422554TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 12:46:472555 ASSERT_TRUE(CreatePeerConnectionWrappers());
2556 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492557 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 12:46:472558
Steve Anton15324772018-01-16 18:26:492559 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 12:46:472560
2561 // Do offer/answer, wait for the callee to receive some frames.
2562 caller()->CreateAndSetAndSignalOffer();
2563 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2564
2565 // Get the remote audio track created on the receiver, so they can be used as
2566 // GetStats filters.
Steve Antonfc853712018-03-01 21:48:582567 auto receivers = callee()->pc()->GetReceivers();
2568 ASSERT_EQ(1u, receivers.size());
2569 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 12:46:472570
2571 // Get the audio output level stats. Note that the level is not available
2572 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 17:48:352573 EXPECT_TRUE_WAIT(
2574 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2575 0,
2576 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 12:46:472577}
2578
deadbeefd8ad7882017-04-18 23:01:172579// Test that we can get stats (using the new stats implemnetation) for
2580// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2581// SDP.
Seth Hampson2f0d7022018-02-20 19:54:422582TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 23:01:172583 GetStatsForUnsignaledStreamWithNewStatsApi) {
2584 ASSERT_TRUE(CreatePeerConnectionWrappers());
2585 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492586 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 23:01:172587 // Remove SSRCs and MSIDs from the received offer SDP.
2588 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2589 caller()->CreateAndSetAndSignalOffer();
2590 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422591 MediaExpectations media_expectations;
2592 media_expectations.CalleeExpectsSomeAudio(1);
2593 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 23:01:172594
2595 // We received a frame, so we should have nonzero "bytes received" stats for
2596 // the unsignaled stream, if stats are working for it.
2597 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2598 callee()->NewGetStats();
2599 ASSERT_NE(nullptr, report);
2600 auto inbound_stream_stats =
2601 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2602 ASSERT_EQ(1U, inbound_stream_stats.size());
2603 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2604 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 20:09:472605 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2606}
2607
Taylor Brandstettera4653442018-06-19 16:44:262608// Same as above but for the legacy stats implementation.
2609TEST_P(PeerConnectionIntegrationTest,
2610 GetStatsForUnsignaledStreamWithOldStatsApi) {
2611 ASSERT_TRUE(CreatePeerConnectionWrappers());
2612 ConnectFakeSignaling();
2613 caller()->AddAudioTrack();
2614 // Remove SSRCs and MSIDs from the received offer SDP.
2615 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2616 caller()->CreateAndSetAndSignalOffer();
2617 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2618
2619 // Note that, since the old stats implementation associates SSRCs with tracks
2620 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2621 // associated track ID. So we can't use the track "selector" argument.
2622 //
2623 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2624 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 10:53:232625 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 16:44:262626 kDefaultTimeout);
2627}
2628
zhihuangf8164932017-05-19 20:09:472629// Test that we can successfully get the media related stats (audio level
2630// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 19:54:422631TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 20:09:472632 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2633 ASSERT_TRUE(CreatePeerConnectionWrappers());
2634 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492635 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 20:09:472636 // Remove SSRCs and MSIDs from the received offer SDP.
2637 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2638 caller()->CreateAndSetAndSignalOffer();
2639 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422640 MediaExpectations media_expectations;
2641 media_expectations.CalleeExpectsSomeAudio(1);
2642 media_expectations.CalleeExpectsSomeVideo(1);
2643 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 20:09:472644
2645 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2646 callee()->NewGetStats();
2647 ASSERT_NE(nullptr, report);
2648
2649 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2650 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2651 ASSERT_GE(audio_index, 0);
2652 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-30 04:08:162653}
2654
deadbeef4e2deab2017-09-20 20:56:212655// Helper for test below.
2656void ModifySsrcs(cricket::SessionDescription* desc) {
2657 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 22:52:032658 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 23:14:302659 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 20:56:212660 for (uint32_t& ssrc : stream.ssrcs) {
2661 ssrc = rtc::CreateRandomId();
2662 }
2663 }
2664 }
2665}
2666
2667// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2668// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2669// This should result in two "RTCInboundRTPStreamStats", but only one
2670// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2671// being reset to 0 once the SSRC change occurs.
2672//
2673// Regression test for this bug:
2674// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2675//
2676// The bug causes the track stats to only represent one of the two streams:
2677// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2678// that the track stat counters would reset to 0 when the new stream is
2679// received, and a 50% chance that they'll stop updating (while
2680// "concealed_samples" continues increasing, due to silence being generated for
2681// the inactive stream).
Seth Hampson2f0d7022018-02-20 19:54:422682TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-11 00:19:522683 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 20:56:212684 ASSERT_TRUE(CreatePeerConnectionWrappers());
2685 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492686 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 20:56:212687 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2688 // that doesn't signal SSRCs (from the callee's perspective).
2689 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2690 caller()->CreateAndSetAndSignalOffer();
2691 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2692 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 19:54:422693 {
2694 MediaExpectations media_expectations;
2695 media_expectations.CalleeExpectsSomeAudio(50);
2696 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2697 }
deadbeef4e2deab2017-09-20 20:56:212698 // Some audio frames were received, so we should have nonzero "samples
2699 // received" for the track.
2700 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2701 callee()->NewGetStats();
2702 ASSERT_NE(nullptr, report);
2703 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2704 ASSERT_EQ(1U, track_stats.size());
2705 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2706 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2707 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2708
2709 // Create a new offer and munge it to cause the caller to use a new SSRC.
2710 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2711 caller()->CreateAndSetAndSignalOffer();
2712 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2713 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2714 // SSRC.
Seth Hampson2f0d7022018-02-20 19:54:422715 {
2716 MediaExpectations media_expectations;
2717 media_expectations.CalleeExpectsSomeAudio(25);
2718 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2719 }
deadbeef4e2deab2017-09-20 20:56:212720
2721 report = callee()->NewGetStats();
2722 ASSERT_NE(nullptr, report);
2723 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2724 ASSERT_EQ(1U, track_stats.size());
2725 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2726 // The "total samples received" stat should only be greater than it was
2727 // before.
2728 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2729 // Right now, the new SSRC will cause the counters to reset to 0.
2730 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2731
2732 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-11 00:19:522733 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 20:56:212734 // good sign that we're seeing stats from the old stream that's no longer
2735 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-11 00:19:522736 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 20:56:212737 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2738 EXPECT_LT(*track_stats[0]->concealed_samples,
2739 *track_stats[0]->total_samples_received *
2740 kAcceptableConcealedSamplesPercentage);
2741
2742 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2743 // sanity check that the SSRC really changed.
2744 // TODO(deadbeef): This isn't working right now, because we're not returning
2745 // *any* stats for the inactive stream. Uncomment when the bug is completely
2746 // fixed.
2747 // auto inbound_stream_stats =
2748 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2749 // ASSERT_EQ(2U, inbound_stream_stats.size());
2750}
2751
deadbeef1dcb1642017-03-30 04:08:162752// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 19:54:422753TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-30 04:08:162754 PeerConnectionFactory::Options dtls_10_options;
2755 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2756 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2757 dtls_10_options));
2758 ConnectFakeSignaling();
2759 // Do normal offer/answer and wait for some frames to be received in each
2760 // direction.
Steve Anton15324772018-01-16 18:26:492761 caller()->AddAudioVideoTracks();
2762 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162763 caller()->CreateAndSetAndSignalOffer();
2764 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422765 MediaExpectations media_expectations;
2766 media_expectations.ExpectBidirectionalAudioAndVideo();
2767 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162768}
2769
2770// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:422771TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-30 04:08:162772 PeerConnectionFactory::Options dtls_10_options;
2773 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2774 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2775 dtls_10_options));
2776 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492777 caller()->AddAudioVideoTracks();
2778 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162779 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 19:54:532780 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:162781 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 23:01:172782 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-30 04:08:162783 kDefaultTimeout);
2784 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 23:01:172785 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 19:54:532786 // TODO(bugs.webrtc.org/9456): Fix it.
2787 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2788 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2789 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-30 04:08:162790}
2791
2792// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:422793TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-30 04:08:162794 PeerConnectionFactory::Options dtls_12_options;
2795 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2796 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2797 dtls_12_options));
2798 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492799 caller()->AddAudioVideoTracks();
2800 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162801 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 19:54:532802 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:162803 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 23:01:172804 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-30 04:08:162805 kDefaultTimeout);
2806 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 23:01:172807 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 19:54:532808 // TODO(bugs.webrtc.org/9456): Fix it.
2809 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2810 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2811 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-30 04:08:162812}
2813
2814// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2815// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 19:54:422816TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-30 04:08:162817 PeerConnectionFactory::Options caller_options;
2818 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2819 PeerConnectionFactory::Options callee_options;
2820 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2821 ASSERT_TRUE(
2822 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2823 ConnectFakeSignaling();
2824 // Do normal offer/answer and wait for some frames to be received in each
2825 // direction.
Steve Anton15324772018-01-16 18:26:492826 caller()->AddAudioVideoTracks();
2827 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162828 caller()->CreateAndSetAndSignalOffer();
2829 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422830 MediaExpectations media_expectations;
2831 media_expectations.ExpectBidirectionalAudioAndVideo();
2832 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162833}
2834
2835// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2836// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 19:54:422837TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-30 04:08:162838 PeerConnectionFactory::Options caller_options;
2839 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2840 PeerConnectionFactory::Options callee_options;
2841 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2842 ASSERT_TRUE(
2843 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2844 ConnectFakeSignaling();
2845 // Do normal offer/answer and wait for some frames to be received in each
2846 // direction.
Steve Anton15324772018-01-16 18:26:492847 caller()->AddAudioVideoTracks();
2848 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162849 caller()->CreateAndSetAndSignalOffer();
2850 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422851 MediaExpectations media_expectations;
2852 media_expectations.ExpectBidirectionalAudioAndVideo();
2853 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162854}
2855
Taylor Brandstetter5e55fe82018-03-23 18:50:162856// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2857// works as expected; the cipher should only be used if enabled by both sides.
2858TEST_P(PeerConnectionIntegrationTest,
2859 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2860 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 22:33:172861 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 18:50:162862 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 22:33:172863 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
2864 false;
Taylor Brandstetter5e55fe82018-03-23 18:50:162865 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2866 TestNegotiatedCipherSuite(caller_options, callee_options,
2867 expected_cipher_suite);
2868}
2869
2870TEST_P(PeerConnectionIntegrationTest,
2871 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2872 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 22:33:172873 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
2874 false;
Taylor Brandstetter5e55fe82018-03-23 18:50:162875 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 22:33:172876 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 18:50:162877 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2878 TestNegotiatedCipherSuite(caller_options, callee_options,
2879 expected_cipher_suite);
2880}
2881
2882TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2883 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 22:33:172884 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 18:50:162885 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 22:33:172886 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 18:50:162887 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2888 TestNegotiatedCipherSuite(caller_options, callee_options,
2889 expected_cipher_suite);
2890}
2891
deadbeef1dcb1642017-03-30 04:08:162892// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 19:54:422893TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-30 04:08:162894 bool local_gcm_enabled = false;
2895 bool remote_gcm_enabled = false;
2896 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2897 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2898 expected_cipher_suite);
2899}
2900
2901// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 19:54:422902TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-30 04:08:162903 bool local_gcm_enabled = true;
2904 bool remote_gcm_enabled = true;
2905 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2906 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2907 expected_cipher_suite);
2908}
2909
2910// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 19:54:422911TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162912 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2913 bool local_gcm_enabled = true;
2914 bool remote_gcm_enabled = false;
2915 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2916 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2917 expected_cipher_suite);
2918}
2919
2920// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 19:54:422921TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162922 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2923 bool local_gcm_enabled = false;
2924 bool remote_gcm_enabled = true;
2925 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2926 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2927 expected_cipher_suite);
2928}
2929
deadbeef7914b8c2017-04-21 10:23:332930// Verify that media can be transmitted end-to-end when GCM crypto suites are
2931// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2932// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2933// works with it.
Seth Hampson2f0d7022018-02-20 19:54:422934TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 10:23:332935 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 22:33:172936 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
deadbeef7914b8c2017-04-21 10:23:332937 ASSERT_TRUE(
2938 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2939 ConnectFakeSignaling();
2940 // Do normal offer/answer and wait for some frames to be received in each
2941 // direction.
Steve Anton15324772018-01-16 18:26:492942 caller()->AddAudioVideoTracks();
2943 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 10:23:332944 caller()->CreateAndSetAndSignalOffer();
2945 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422946 MediaExpectations media_expectations;
2947 media_expectations.ExpectBidirectionalAudioAndVideo();
2948 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 10:23:332949}
2950
deadbeef1dcb1642017-03-30 04:08:162951// This test sets up a call between two parties with audio, video and an RTP
2952// data channel.
Seth Hampson2f0d7022018-02-20 19:54:422953TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 10:32:182954 PeerConnectionInterface::RTCConfiguration rtc_config;
2955 rtc_config.enable_rtp_data_channel = true;
2956 rtc_config.enable_dtls_srtp = false;
2957 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:162958 ConnectFakeSignaling();
2959 // Expect that data channel created on caller side will show up for callee as
2960 // well.
2961 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:492962 caller()->AddAudioVideoTracks();
2963 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162964 caller()->CreateAndSetAndSignalOffer();
2965 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2966 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 19:54:422967 MediaExpectations media_expectations;
2968 media_expectations.ExpectBidirectionalAudioAndVideo();
2969 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162970 ASSERT_NE(nullptr, caller()->data_channel());
2971 ASSERT_NE(nullptr, callee()->data_channel());
2972 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2973 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2974
2975 // Ensure data can be sent in both directions.
2976 std::string data = "hello world";
2977 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2978 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2979 kDefaultTimeout);
2980 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2981 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2982 kDefaultTimeout);
2983}
2984
2985// Ensure that an RTP data channel is signaled as closed for the caller when
2986// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 19:54:422987TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162988 RtpDataChannelSignaledClosedInCalleeOffer) {
2989 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 10:32:182990 PeerConnectionInterface::RTCConfiguration rtc_config;
2991 rtc_config.enable_rtp_data_channel = true;
2992 rtc_config.enable_dtls_srtp = false;
2993 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:162994 ConnectFakeSignaling();
2995 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:492996 caller()->AddAudioVideoTracks();
2997 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162998 caller()->CreateAndSetAndSignalOffer();
2999 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3000 ASSERT_NE(nullptr, caller()->data_channel());
3001 ASSERT_NE(nullptr, callee()->data_channel());
3002 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3003 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3004
3005 // Close the data channel on the callee, and do an updated offer/answer.
3006 callee()->data_channel()->Close();
3007 callee()->CreateAndSetAndSignalOffer();
3008 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3009 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3010 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3011}
3012
3013// Tests that data is buffered in an RTP data channel until an observer is
3014// registered for it.
3015//
3016// NOTE: RTP data channels can receive data before the underlying
3017// transport has detected that a channel is writable and thus data can be
3018// received before the data channel state changes to open. That is hard to test
3019// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 19:54:423020TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:163021 DataBufferedUntilRtpDataChannelObserverRegistered) {
3022 // Use fake clock and simulated network delay so that we predictably can wait
3023 // until an SCTP message has been delivered without "sleep()"ing.
3024 rtc::ScopedFakeClock fake_clock;
3025 // Some things use a time of "0" as a special value, so we need to start out
3026 // the fake clock at a nonzero time.
3027 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 12:52:223028 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-30 04:08:163029 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3030 virtual_socket_server()->UpdateDelayDistribution();
3031
Niels Möllerf06f9232018-08-07 10:32:183032 PeerConnectionInterface::RTCConfiguration rtc_config;
3033 rtc_config.enable_rtp_data_channel = true;
3034 rtc_config.enable_dtls_srtp = false;
3035 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:163036 ConnectFakeSignaling();
3037 caller()->CreateDataChannel();
3038 caller()->CreateAndSetAndSignalOffer();
3039 ASSERT_TRUE(caller()->data_channel() != nullptr);
3040 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
3041 kDefaultTimeout, fake_clock);
3042 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
3043 kDefaultTimeout, fake_clock);
3044 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3045 callee()->data_channel()->state(), kDefaultTimeout,
3046 fake_clock);
3047
3048 // Unregister the observer which is normally automatically registered.
3049 callee()->data_channel()->UnregisterObserver();
3050 // Send data and advance fake clock until it should have been received.
3051 std::string data = "hello world";
3052 caller()->data_channel()->Send(DataBuffer(data));
3053 SIMULATED_WAIT(false, 50, fake_clock);
3054
3055 // Attach data channel and expect data to be received immediately. Note that
3056 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3057 // further, but data can be received even if the callback is asynchronous.
3058 MockDataChannelObserver new_observer(callee()->data_channel());
3059 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
3060 fake_clock);
Seth Hampson1d4a76d2018-06-19 21:31:413061 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3062 // If this is not done a DCHECK can be hit in ports.cc, because a large
3063 // negative number is calculated for the rtt due to the global clock changing.
3064 caller()->pc()->Close();
3065 callee()->pc()->Close();
deadbeef1dcb1642017-03-30 04:08:163066}
3067
3068// This test sets up a call between two parties with audio, video and but only
3069// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 19:54:423070TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 10:32:183071 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3072 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-30 04:08:163073 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 10:32:183074 rtc_config_1.enable_dtls_srtp = false;
3075 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3076 rtc_config_2.enable_dtls_srtp = false;
3077 rtc_config_2.enable_dtls_srtp = false;
3078 ASSERT_TRUE(
3079 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-30 04:08:163080 ConnectFakeSignaling();
3081 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:493082 caller()->AddAudioVideoTracks();
3083 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163084 caller()->CreateAndSetAndSignalOffer();
3085 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3086 // The caller should still have a data channel, but it should be closed, and
3087 // one should ever have been created for the callee.
3088 EXPECT_TRUE(caller()->data_channel() != nullptr);
3089 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3090 EXPECT_EQ(nullptr, callee()->data_channel());
3091}
3092
3093// This test sets up a call between two parties with audio, and video. When
3094// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:423095TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 10:32:183096 PeerConnectionInterface::RTCConfiguration rtc_config;
3097 rtc_config.enable_rtp_data_channel = true;
3098 rtc_config.enable_dtls_srtp = false;
3099 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:163100 ConnectFakeSignaling();
3101 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 18:26:493102 caller()->AddAudioVideoTracks();
3103 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163104 caller()->CreateAndSetAndSignalOffer();
3105 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3106 // Create data channel and do new offer and answer.
3107 caller()->CreateDataChannel();
3108 caller()->CreateAndSetAndSignalOffer();
3109 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3110 ASSERT_NE(nullptr, caller()->data_channel());
3111 ASSERT_NE(nullptr, callee()->data_channel());
3112 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3113 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3114 // Ensure data can be sent in both directions.
3115 std::string data = "hello world";
3116 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3117 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3118 kDefaultTimeout);
3119 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3120 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3121 kDefaultTimeout);
3122}
3123
3124#ifdef HAVE_SCTP
3125
3126// This test sets up a call between two parties with audio, video and an SCTP
3127// data channel.
Seth Hampson2f0d7022018-02-20 19:54:423128TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-30 04:08:163129 ASSERT_TRUE(CreatePeerConnectionWrappers());
3130 ConnectFakeSignaling();
3131 // Expect that data channel created on caller side will show up for callee as
3132 // well.
3133 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:493134 caller()->AddAudioVideoTracks();
3135 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163136 caller()->CreateAndSetAndSignalOffer();
3137 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3138 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 19:54:423139 MediaExpectations media_expectations;
3140 media_expectations.ExpectBidirectionalAudioAndVideo();
3141 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163142 // Caller data channel should already exist (it created one). Callee data
3143 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3144 ASSERT_NE(nullptr, caller()->data_channel());
3145 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3146 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3147 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3148
3149 // Ensure data can be sent in both directions.
3150 std::string data = "hello world";
3151 caller()->data_channel()->Send(DataBuffer(data));
3152 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3153 kDefaultTimeout);
3154 callee()->data_channel()->Send(DataBuffer(data));
3155 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3156 kDefaultTimeout);
3157}
3158
3159// Ensure that when the callee closes an SCTP data channel, the closing
3160// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 19:54:423161TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-30 04:08:163162 // Same procedure as above test.
3163 ASSERT_TRUE(CreatePeerConnectionWrappers());
3164 ConnectFakeSignaling();
3165 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:493166 caller()->AddAudioVideoTracks();
3167 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163168 caller()->CreateAndSetAndSignalOffer();
3169 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3170 ASSERT_NE(nullptr, caller()->data_channel());
3171 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3172 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3173 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3174
3175 // Close the data channel on the callee side, and wait for it to reach the
3176 // "closed" state on both sides.
3177 callee()->data_channel()->Close();
3178 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3179 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3180}
3181
Seth Hampson2f0d7022018-02-20 19:54:423182TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 18:41:543183 ASSERT_TRUE(CreatePeerConnectionWrappers());
3184 ConnectFakeSignaling();
3185 webrtc::DataChannelInit init;
3186 init.id = 53;
3187 init.maxRetransmits = 52;
3188 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 18:26:493189 caller()->AddAudioVideoTracks();
3190 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 18:41:543191 caller()->CreateAndSetAndSignalOffer();
3192 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 20:04:123193 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3194 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 18:41:543195 EXPECT_EQ(init.id, callee()->data_channel()->id());
3196 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3197 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3198 EXPECT_FALSE(callee()->data_channel()->negotiated());
3199}
3200
deadbeef1dcb1642017-03-30 04:08:163201// Test usrsctp's ability to process unordered data stream, where data actually
3202// arrives out of order using simulated delays. Previously there have been some
3203// bugs in this area.
Seth Hampson2f0d7022018-02-20 19:54:423204TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-30 04:08:163205 // Introduce random network delays.
3206 // Otherwise it's not a true "unordered" test.
3207 virtual_socket_server()->set_delay_mean(20);
3208 virtual_socket_server()->set_delay_stddev(5);
3209 virtual_socket_server()->UpdateDelayDistribution();
3210 // Normal procedure, but with unordered data channel config.
3211 ASSERT_TRUE(CreatePeerConnectionWrappers());
3212 ConnectFakeSignaling();
3213 webrtc::DataChannelInit init;
3214 init.ordered = false;
3215 caller()->CreateDataChannel(&init);
3216 caller()->CreateAndSetAndSignalOffer();
3217 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3218 ASSERT_NE(nullptr, caller()->data_channel());
3219 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3220 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3221 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3222
3223 static constexpr int kNumMessages = 100;
3224 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3225 static constexpr size_t kMaxMessageSize = 4096;
3226 // Create and send random messages.
3227 std::vector<std::string> sent_messages;
3228 for (int i = 0; i < kNumMessages; ++i) {
3229 size_t length =
3230 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3231 std::string message;
3232 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3233 caller()->data_channel()->Send(DataBuffer(message));
3234 callee()->data_channel()->Send(DataBuffer(message));
3235 sent_messages.push_back(message);
3236 }
3237
3238 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 10:53:233239 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-30 04:08:163240 caller()->data_observer()->received_message_count(),
3241 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 10:53:233242 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-30 04:08:163243 callee()->data_observer()->received_message_count(),
3244 kDefaultTimeout);
3245
3246 // Sort and compare to make sure none of the messages were corrupted.
3247 std::vector<std::string> caller_received_messages =
3248 caller()->data_observer()->messages();
3249 std::vector<std::string> callee_received_messages =
3250 callee()->data_observer()->messages();
3251 std::sort(sent_messages.begin(), sent_messages.end());
3252 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3253 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3254 EXPECT_EQ(sent_messages, caller_received_messages);
3255 EXPECT_EQ(sent_messages, callee_received_messages);
3256}
3257
3258// This test sets up a call between two parties with audio, and video. When
3259// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:423260TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-30 04:08:163261 ASSERT_TRUE(CreatePeerConnectionWrappers());
3262 ConnectFakeSignaling();
3263 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 18:26:493264 caller()->AddAudioVideoTracks();
3265 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163266 caller()->CreateAndSetAndSignalOffer();
3267 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3268 // Create data channel and do new offer and answer.
3269 caller()->CreateDataChannel();
3270 caller()->CreateAndSetAndSignalOffer();
3271 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3272 // Caller data channel should already exist (it created one). Callee data
3273 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3274 ASSERT_NE(nullptr, caller()->data_channel());
3275 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3276 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3277 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3278 // Ensure data can be sent in both directions.
3279 std::string data = "hello world";
3280 caller()->data_channel()->Send(DataBuffer(data));
3281 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3282 kDefaultTimeout);
3283 callee()->data_channel()->Send(DataBuffer(data));
3284 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3285 kDefaultTimeout);
3286}
3287
deadbeef7914b8c2017-04-21 10:23:333288// Set up a connection initially just using SCTP data channels, later upgrading
3289// to audio/video, ensuring frames are received end-to-end. Effectively the
3290// inverse of the test above.
3291// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 19:54:423292TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 10:23:333293 ASSERT_TRUE(CreatePeerConnectionWrappers());
3294 ConnectFakeSignaling();
3295 // Do initial offer/answer with just data channel.
3296 caller()->CreateDataChannel();
3297 caller()->CreateAndSetAndSignalOffer();
3298 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3299 // Wait until data can be sent over the data channel.
3300 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3301 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3302 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3303
3304 // Do subsequent offer/answer with two-way audio and video. Audio and video
3305 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 18:26:493306 caller()->AddAudioVideoTracks();
3307 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 10:23:333308 caller()->CreateAndSetAndSignalOffer();
3309 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:423310 MediaExpectations media_expectations;
3311 media_expectations.ExpectBidirectionalAudioAndVideo();
3312 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 10:23:333313}
3314
deadbeef8b7e9ad2017-05-25 16:38:553315static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 16:38:553316 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 23:14:303317 GetFirstDataContentDescription(desc);
3318 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 16:38:553319 dcd_offer->set_use_sctpmap(false);
3320 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3321}
3322
3323// Test that the data channel works when a spec-compliant SCTP m= section is
3324// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3325// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 19:54:423326TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 16:38:553327 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3328 ASSERT_TRUE(CreatePeerConnectionWrappers());
3329 ConnectFakeSignaling();
3330 caller()->CreateDataChannel();
3331 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3332 caller()->CreateAndSetAndSignalOffer();
3333 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3334 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3335 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3336 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3337
3338 // Ensure data can be sent in both directions.
3339 std::string data = "hello world";
3340 caller()->data_channel()->Send(DataBuffer(data));
3341 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3342 kDefaultTimeout);
3343 callee()->data_channel()->Send(DataBuffer(data));
3344 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3345 kDefaultTimeout);
3346}
3347
deadbeef1dcb1642017-03-30 04:08:163348#endif // HAVE_SCTP
3349
3350// Test that the ICE connection and gathering states eventually reach
3351// "complete".
Seth Hampson2f0d7022018-02-20 19:54:423352TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-30 04:08:163353 ASSERT_TRUE(CreatePeerConnectionWrappers());
3354 ConnectFakeSignaling();
3355 // Do normal offer/answer.
Steve Anton15324772018-01-16 18:26:493356 caller()->AddAudioVideoTracks();
3357 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163358 caller()->CreateAndSetAndSignalOffer();
3359 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3360 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3361 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3362 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3363 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3364 // After the best candidate pair is selected and all candidates are signaled,
3365 // the ICE connection state should reach "complete".
3366 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3367 // answerer/"callee" by default) only reaches "connected". When this is
3368 // fixed, this test should be updated.
3369 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3370 caller()->ice_connection_state(), kDefaultTimeout);
3371 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3372 callee()->ice_connection_state(), kDefaultTimeout);
3373}
3374
Zach Stein6fcdc2f2018-08-23 23:25:553375// Replaces the first candidate with a static address and configures a
3376// MockAsyncResolver to return the replaced address the first time the static
3377// address is resolved. Candidates past the first will not be signaled.
3378class ReplaceFirstCandidateAddressDropOthers final
3379 : public IceCandidateReplacerInterface {
3380 public:
3381 ReplaceFirstCandidateAddressDropOthers(
3382 const SocketAddress& new_address,
3383 rtc::MockAsyncResolver* mock_async_resolver)
3384 : mock_async_resolver_(mock_async_resolver), new_address_(new_address) {
3385 RTC_DCHECK(mock_async_resolver);
3386 }
3387
3388 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3389 const webrtc::IceCandidateInterface* candidate) override {
3390 if (replaced_candidate_) {
3391 return nullptr;
3392 }
3393
3394 replaced_candidate_ = true;
3395 cricket::Candidate new_candidate(candidate->candidate());
3396 new_candidate.set_address(new_address_);
3397 EXPECT_CALL(*mock_async_resolver_, GetResolvedAddress(_, _))
3398 .WillOnce(DoAll(SetArgPointee<1>(candidate->candidate().address()),
3399 Return(true)));
3400 EXPECT_CALL(*mock_async_resolver_, Destroy(_));
3401 return webrtc::CreateIceCandidate(
3402 candidate->sdp_mid(), candidate->sdp_mline_index(), new_candidate);
3403 }
3404
3405 private:
3406 rtc::MockAsyncResolver* mock_async_resolver_;
3407 SocketAddress new_address_;
3408 bool replaced_candidate_ = false;
3409};
3410
3411// Drops all candidates before they are signaled.
3412class DropAllCandidates final : public IceCandidateReplacerInterface {
3413 public:
3414 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3415 const webrtc::IceCandidateInterface*) override {
3416 return nullptr;
3417 }
3418};
3419
3420// Replace the first caller ICE candidate IP with a fake hostname and drop the
3421// other candidates. Drop all candidates on the callee side (to avoid a prflx
3422// connection). Use a mock resolver to resolve the hostname back to the original
3423// IP on the callee side and check that the ice connection connects.
3424TEST_P(PeerConnectionIntegrationTest,
3425 IceStatesReachCompletionWithRemoteHostname) {
3426 webrtc::MockAsyncResolverFactory* callee_mock_async_resolver_factory;
3427 {
3428 auto resolver_factory =
3429 absl::make_unique<webrtc::MockAsyncResolverFactory>();
3430 callee_mock_async_resolver_factory = resolver_factory.get();
3431 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3432 callee_deps.async_resolver_factory = std::move(resolver_factory);
3433
3434 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3435 RTCConfiguration(), webrtc::PeerConnectionDependencies(nullptr),
3436 RTCConfiguration(), std::move(callee_deps)));
3437 }
3438
3439 rtc::MockAsyncResolver mock_async_resolver;
3440
3441 // This also verifies that the injected AsyncResolverFactory is used by
3442 // P2PTransportChannel.
3443 EXPECT_CALL(*callee_mock_async_resolver_factory, Create())
3444 .WillOnce(Return(&mock_async_resolver));
3445 caller()->SetLocalIceCandidateReplacer(
3446 absl::make_unique<ReplaceFirstCandidateAddressDropOthers>(
3447 SocketAddress("a.b", 10000), &mock_async_resolver));
3448 callee()->SetLocalIceCandidateReplacer(
3449 absl::make_unique<DropAllCandidates>());
3450
3451 ConnectFakeSignaling();
3452 caller()->AddAudioVideoTracks();
3453 callee()->AddAudioVideoTracks();
3454 caller()->CreateAndSetAndSignalOffer();
3455 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3456 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3457 caller()->ice_connection_state(), kDefaultTimeout);
3458 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3459 callee()->ice_connection_state(), kDefaultTimeout);
3460}
3461
Steve Antonede9ca52017-10-16 20:04:273462// Test that firewalling the ICE connection causes the clients to identify the
3463// disconnected state and then removing the firewall causes them to reconnect.
3464class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 19:54:423465 : public PeerConnectionIntegrationBaseTest,
3466 public ::testing::WithParamInterface<
3467 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 20:04:273468 protected:
Seth Hampson2f0d7022018-02-20 19:54:423469 PeerConnectionIntegrationIceStatesTest()
3470 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3471 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 20:04:273472 }
3473
3474 void StartStunServer(const SocketAddress& server_address) {
3475 stun_server_.reset(
3476 cricket::TestStunServer::Create(network_thread(), server_address));
3477 }
3478
3479 bool TestIPv6() {
3480 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3481 }
3482
3483 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 23:57:453484 network_thread()->Invoke<void>(
3485 RTC_FROM_HERE,
3486 rtc::Bind(&cricket::PortAllocator::set_flags,
3487 caller()->port_allocator(), port_allocator_flags_));
3488 network_thread()->Invoke<void>(
3489 RTC_FROM_HERE,
3490 rtc::Bind(&cricket::PortAllocator::set_flags,
3491 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 20:04:273492 }
3493
3494 std::vector<SocketAddress> CallerAddresses() {
3495 std::vector<SocketAddress> addresses;
3496 addresses.push_back(SocketAddress("1.1.1.1", 0));
3497 if (TestIPv6()) {
3498 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3499 }
3500 return addresses;
3501 }
3502
3503 std::vector<SocketAddress> CalleeAddresses() {
3504 std::vector<SocketAddress> addresses;
3505 addresses.push_back(SocketAddress("2.2.2.2", 0));
3506 if (TestIPv6()) {
3507 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3508 }
3509 return addresses;
3510 }
3511
3512 void SetUpNetworkInterfaces() {
3513 // Remove the default interfaces added by the test infrastructure.
3514 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3515 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3516
3517 // Add network addresses for test.
3518 for (const auto& caller_address : CallerAddresses()) {
3519 caller()->network()->AddInterface(caller_address);
3520 }
3521 for (const auto& callee_address : CalleeAddresses()) {
3522 callee()->network()->AddInterface(callee_address);
3523 }
3524 }
3525
3526 private:
3527 uint32_t port_allocator_flags_;
3528 std::unique_ptr<cricket::TestStunServer> stun_server_;
3529};
3530
3531// Tests that the PeerConnection goes through all the ICE gathering/connection
3532// states over the duration of the call. This includes Disconnected and Failed
3533// states, induced by putting a firewall between the peers and waiting for them
3534// to time out.
Steve Anton83119dd2017-11-11 00:19:523535TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3536 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3537 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3538 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 20:04:273539
3540 const SocketAddress kStunServerAddress =
3541 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3542 StartStunServer(kStunServerAddress);
3543
3544 PeerConnectionInterface::RTCConfiguration config;
3545 PeerConnectionInterface::IceServer ice_stun_server;
3546 ice_stun_server.urls.push_back(
3547 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3548 kStunServerAddress.PortAsString());
3549 config.servers.push_back(ice_stun_server);
3550
3551 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3552 ConnectFakeSignaling();
3553 SetPortAllocatorFlags();
3554 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 18:26:493555 caller()->AddAudioVideoTracks();
3556 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 20:04:273557
3558 // Initial state before anything happens.
3559 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3560 caller()->ice_gathering_state());
3561 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3562 caller()->ice_connection_state());
3563
3564 // Start the call by creating the offer, setting it as the local description,
3565 // then sending it to the peer who will respond with an answer. This happens
3566 // asynchronously so that we can watch the states as it runs in the
3567 // background.
3568 caller()->CreateAndSetAndSignalOffer();
3569
Steve Anton83119dd2017-11-11 00:19:523570 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3571 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 20:04:273572
3573 // Verify that the observer was notified of the intermediate transitions.
3574 EXPECT_THAT(caller()->ice_connection_state_history(),
3575 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3576 PeerConnectionInterface::kIceConnectionConnected,
3577 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 13:58:173578 // After the ice transport transitions from checking to connected we revert
3579 // back to new as the standard requires, as at that point the DTLS transport
3580 // is in the "new" state while no transports are "connecting", "checking",
3581 // "failed" or disconnected. This is pretty unintuitive, and we might want to
3582 // amend the spec to handle this case more gracefully.
3583 EXPECT_THAT(
3584 caller()->peer_connection_state_history(),
3585 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
3586 PeerConnectionInterface::PeerConnectionState::kNew,
3587 PeerConnectionInterface::PeerConnectionState::kConnecting,
3588 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 20:04:273589 EXPECT_THAT(caller()->ice_gathering_state_history(),
3590 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3591 PeerConnectionInterface::kIceGatheringComplete));
3592
3593 // Block connections to/from the caller and wait for ICE to become
3594 // disconnected.
3595 for (const auto& caller_address : CallerAddresses()) {
3596 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3597 }
Mirko Bonadei675513b2017-11-09 10:09:253598 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-11 00:19:523599 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3600 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 20:04:273601
3602 // Let ICE re-establish by removing the firewall rules.
3603 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 10:09:253604 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-11 00:19:523605 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3606 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 20:04:273607
3608 // According to RFC7675, if there is no response within 30 seconds then the
3609 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-11 00:19:523610 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 20:04:273611 constexpr int kConsentTimeout = 30000;
3612 for (const auto& caller_address : CallerAddresses()) {
3613 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3614 }
Mirko Bonadei675513b2017-11-09 10:09:253615 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-11 00:19:523616 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3617 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 20:04:273618}
3619
3620// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3621// and that the statistics in the metric observers are updated correctly.
3622TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3623 ASSERT_TRUE(CreatePeerConnectionWrappers());
3624 ConnectFakeSignaling();
3625 SetPortAllocatorFlags();
3626 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 18:26:493627 caller()->AddAudioVideoTracks();
3628 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 20:04:273629 caller()->CreateAndSetAndSignalOffer();
3630
3631 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3632
Qingsi Wang7fc821d2018-07-12 19:54:533633 // TODO(bugs.webrtc.org/9456): Fix it.
3634 const int num_best_ipv4 = webrtc::metrics::NumEvents(
3635 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
3636 const int num_best_ipv6 = webrtc::metrics::NumEvents(
3637 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 20:04:273638 if (TestIPv6()) {
3639 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3640 // connection.
Mirko Bonadeie12c1fe2018-07-03 10:53:233641 EXPECT_EQ(0, num_best_ipv4);
3642 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 20:04:273643 } else {
Mirko Bonadeie12c1fe2018-07-03 10:53:233644 EXPECT_EQ(1, num_best_ipv4);
3645 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 20:04:273646 }
3647
Qingsi Wang7fc821d2018-07-12 19:54:533648 EXPECT_EQ(0, webrtc::metrics::NumEvents(
3649 "WebRTC.PeerConnection.CandidatePairType_UDP",
3650 webrtc::kIceCandidatePairHostHost));
3651 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3652 "WebRTC.PeerConnection.CandidatePairType_UDP",
3653 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 20:04:273654}
3655
3656constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3657 cricket::PORTALLOCATOR_DISABLE_STUN |
3658 cricket::PORTALLOCATOR_DISABLE_RELAY;
3659constexpr uint32_t kFlagsIPv6NoStun =
3660 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3661 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3662constexpr uint32_t kFlagsIPv4Stun =
3663 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3664
Seth Hampson2f0d7022018-02-20 19:54:423665INSTANTIATE_TEST_CASE_P(
3666 PeerConnectionIntegrationTest,
3667 PeerConnectionIntegrationIceStatesTest,
3668 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3669 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3670 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3671 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 20:04:273672
deadbeef1dcb1642017-03-30 04:08:163673// This test sets up a call between two parties with audio and video.
3674// During the call, the caller restarts ICE and the test verifies that
3675// new ICE candidates are generated and audio and video still can flow, and the
3676// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 19:54:423677TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-30 04:08:163678 ASSERT_TRUE(CreatePeerConnectionWrappers());
3679 ConnectFakeSignaling();
3680 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 18:26:493681 caller()->AddAudioVideoTracks();
3682 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163683 caller()->CreateAndSetAndSignalOffer();
3684 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3685 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3686 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3687 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3688 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3689
3690 // To verify that the ICE restart actually occurs, get
3691 // ufrag/password/candidates before and after restart.
3692 // Create an SDP string of the first audio candidate for both clients.
3693 const webrtc::IceCandidateCollection* audio_candidates_caller =
3694 caller()->pc()->local_description()->candidates(0);
3695 const webrtc::IceCandidateCollection* audio_candidates_callee =
3696 callee()->pc()->local_description()->candidates(0);
3697 ASSERT_GT(audio_candidates_caller->count(), 0u);
3698 ASSERT_GT(audio_candidates_callee->count(), 0u);
3699 std::string caller_candidate_pre_restart;
3700 ASSERT_TRUE(
3701 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3702 std::string callee_candidate_pre_restart;
3703 ASSERT_TRUE(
3704 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3705 const cricket::SessionDescription* desc =
3706 caller()->pc()->local_description()->description();
3707 std::string caller_ufrag_pre_restart =
3708 desc->transport_infos()[0].description.ice_ufrag;
3709 desc = callee()->pc()->local_description()->description();
3710 std::string callee_ufrag_pre_restart =
3711 desc->transport_infos()[0].description.ice_ufrag;
3712
3713 // Have the caller initiate an ICE restart.
3714 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3715 caller()->CreateAndSetAndSignalOffer();
3716 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3717 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3718 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3719 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3720 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3721
3722 // Grab the ufrags/candidates again.
3723 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3724 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3725 ASSERT_GT(audio_candidates_caller->count(), 0u);
3726 ASSERT_GT(audio_candidates_callee->count(), 0u);
3727 std::string caller_candidate_post_restart;
3728 ASSERT_TRUE(
3729 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3730 std::string callee_candidate_post_restart;
3731 ASSERT_TRUE(
3732 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3733 desc = caller()->pc()->local_description()->description();
3734 std::string caller_ufrag_post_restart =
3735 desc->transport_infos()[0].description.ice_ufrag;
3736 desc = callee()->pc()->local_description()->description();
3737 std::string callee_ufrag_post_restart =
3738 desc->transport_infos()[0].description.ice_ufrag;
3739 // Sanity check that an ICE restart was actually negotiated in SDP.
3740 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3741 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3742 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3743 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3744
3745 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 19:54:423746 MediaExpectations media_expectations;
3747 media_expectations.ExpectBidirectionalAudioAndVideo();
3748 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163749}
3750
3751// Verify that audio/video can be received end-to-end when ICE renomination is
3752// enabled.
Seth Hampson2f0d7022018-02-20 19:54:423753TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-30 04:08:163754 PeerConnectionInterface::RTCConfiguration config;
3755 config.enable_ice_renomination = true;
3756 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3757 ConnectFakeSignaling();
3758 // Do normal offer/answer and wait for some frames to be received in each
3759 // direction.
Steve Anton15324772018-01-16 18:26:493760 caller()->AddAudioVideoTracks();
3761 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163762 caller()->CreateAndSetAndSignalOffer();
3763 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3764 // Sanity check that ICE renomination was actually negotiated.
3765 const cricket::SessionDescription* desc =
3766 caller()->pc()->local_description()->description();
3767 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 09:41:293768 ASSERT_NE(
3769 info.description.transport_options.end(),
3770 std::find(info.description.transport_options.begin(),
3771 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-30 04:08:163772 }
3773 desc = callee()->pc()->local_description()->description();
3774 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 09:41:293775 ASSERT_NE(
3776 info.description.transport_options.end(),
3777 std::find(info.description.transport_options.begin(),
3778 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-30 04:08:163779 }
Seth Hampson2f0d7022018-02-20 19:54:423780 MediaExpectations media_expectations;
3781 media_expectations.ExpectBidirectionalAudioAndVideo();
3782 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163783}
3784
Steve Anton6f25b092017-10-23 16:39:203785// With a max bundle policy and RTCP muxing, adding a new media description to
3786// the connection should not affect ICE at all because the new media will use
3787// the existing connection.
Seth Hampson2f0d7022018-02-20 19:54:423788TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-11 00:19:523789 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 16:39:203790 PeerConnectionInterface::RTCConfiguration config;
3791 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3792 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3793 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3794 config, PeerConnectionInterface::RTCConfiguration()));
3795 ConnectFakeSignaling();
3796
Steve Anton15324772018-01-16 18:26:493797 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 16:39:203798 caller()->CreateAndSetAndSignalOffer();
3799 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 19:24:503800 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3801 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 16:39:203802
3803 caller()->clear_ice_connection_state_history();
3804
Steve Anton15324772018-01-16 18:26:493805 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 16:39:203806 caller()->CreateAndSetAndSignalOffer();
3807 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3808
3809 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3810}
3811
deadbeef1dcb1642017-03-30 04:08:163812// This test sets up a call between two parties with audio and video. It then
3813// renegotiates setting the video m-line to "port 0", then later renegotiates
3814// again, enabling video.
Seth Hampson2f0d7022018-02-20 19:54:423815TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:163816 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3817 ASSERT_TRUE(CreatePeerConnectionWrappers());
3818 ConnectFakeSignaling();
3819
3820 // Do initial negotiation, only sending media from the caller. Will result in
3821 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 18:26:493822 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163823 caller()->CreateAndSetAndSignalOffer();
3824 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3825
3826 // Negotiate again, disabling the video "m=" section (the callee will set the
3827 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 19:54:423828 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3829 PeerConnectionInterface::RTCOfferAnswerOptions options;
3830 options.offer_to_receive_video = 0;
3831 callee()->SetOfferAnswerOptions(options);
3832 } else {
3833 callee()->SetRemoteOfferHandler([this] {
3834 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3835 });
3836 }
deadbeef1dcb1642017-03-30 04:08:163837 caller()->CreateAndSetAndSignalOffer();
3838 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3839 // Sanity check that video "m=" section was actually rejected.
3840 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3841 callee()->pc()->local_description()->description());
3842 ASSERT_NE(nullptr, answer_video_content);
3843 ASSERT_TRUE(answer_video_content->rejected);
3844
3845 // Enable video and do negotiation again, making sure video is received
3846 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 19:54:423847 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3848 PeerConnectionInterface::RTCOfferAnswerOptions options;
3849 options.offer_to_receive_video = 1;
3850 callee()->SetOfferAnswerOptions(options);
3851 } else {
3852 // The caller's transceiver is stopped, so we need to add another track.
3853 auto caller_transceiver =
3854 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3855 EXPECT_TRUE(caller_transceiver->stopped());
3856 caller()->AddVideoTrack();
3857 }
3858 callee()->AddVideoTrack();
3859 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-30 04:08:163860 caller()->CreateAndSetAndSignalOffer();
3861 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:423862
deadbeef1dcb1642017-03-30 04:08:163863 // Verify the caller receives frames from the newly added stream, and the
3864 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 19:54:423865 MediaExpectations media_expectations;
3866 media_expectations.CalleeExpectsSomeAudio();
3867 media_expectations.ExpectBidirectionalVideo();
3868 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163869}
3870
deadbeef1dcb1642017-03-30 04:08:163871// This tests that if we negotiate after calling CreateSender but before we
3872// have a track, then set a track later, frames from the newly-set track are
3873// received end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:423874TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-30 04:08:163875 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3876 ASSERT_TRUE(CreatePeerConnectionWrappers());
3877 ConnectFakeSignaling();
3878 auto caller_audio_sender =
3879 caller()->pc()->CreateSender("audio", "caller_stream");
3880 auto caller_video_sender =
3881 caller()->pc()->CreateSender("video", "caller_stream");
3882 auto callee_audio_sender =
3883 callee()->pc()->CreateSender("audio", "callee_stream");
3884 auto callee_video_sender =
3885 callee()->pc()->CreateSender("video", "callee_stream");
3886 caller()->CreateAndSetAndSignalOffer();
3887 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3888 // Wait for ICE to complete, without any tracks being set.
3889 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3890 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3891 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3892 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3893 // Now set the tracks, and expect frames to immediately start flowing.
3894 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3895 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3896 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3897 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 19:54:423898 MediaExpectations media_expectations;
3899 media_expectations.ExpectBidirectionalAudioAndVideo();
3900 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3901}
3902
3903// This tests that if we negotiate after calling AddTransceiver but before we
3904// have a track, then set a track later, frames from the newly-set tracks are
3905// received end-to-end.
3906TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3907 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3908 ASSERT_TRUE(CreatePeerConnectionWrappers());
3909 ConnectFakeSignaling();
3910 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3911 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3912 auto caller_audio_sender = audio_result.MoveValue()->sender();
3913 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3914 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3915 auto caller_video_sender = video_result.MoveValue()->sender();
3916 callee()->SetRemoteOfferHandler([this] {
3917 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3918 callee()->pc()->GetTransceivers()[0]->SetDirection(
3919 RtpTransceiverDirection::kSendRecv);
3920 callee()->pc()->GetTransceivers()[1]->SetDirection(
3921 RtpTransceiverDirection::kSendRecv);
3922 });
3923 caller()->CreateAndSetAndSignalOffer();
3924 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3925 // Wait for ICE to complete, without any tracks being set.
3926 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3927 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3928 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3929 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3930 // Now set the tracks, and expect frames to immediately start flowing.
3931 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3932 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3933 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3934 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3935 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3936 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3937 MediaExpectations media_expectations;
3938 media_expectations.ExpectBidirectionalAudioAndVideo();
3939 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163940}
3941
3942// This test verifies that a remote video track can be added via AddStream,
3943// and sent end-to-end. For this particular test, it's simply echoed back
3944// from the caller to the callee, rather than being forwarded to a third
3945// PeerConnection.
Seth Hampson2f0d7022018-02-20 19:54:423946TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-30 04:08:163947 ASSERT_TRUE(CreatePeerConnectionWrappers());
3948 ConnectFakeSignaling();
3949 // Just send a video track from the caller.
Steve Anton15324772018-01-16 18:26:493950 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-30 04:08:163951 caller()->CreateAndSetAndSignalOffer();
3952 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 10:53:233953 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-30 04:08:163954
3955 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3956 // time).
3957 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3958 callee()->CreateAndSetAndSignalOffer();
3959 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3960
Seth Hampson2f0d7022018-02-20 19:54:423961 MediaExpectations media_expectations;
3962 media_expectations.ExpectBidirectionalVideo();
3963 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163964}
3965
3966// Test that we achieve the expected end-to-end connection time, using a
3967// fake clock and simulated latency on the media and signaling paths.
3968// We use a TURN<->TURN connection because this is usually the quickest to
3969// set up initially, especially when we're confident the connection will work
3970// and can start sending media before we get a STUN response.
3971//
3972// With various optimizations enabled, here are the network delays we expect to
3973// be on the critical path:
3974// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3975// signaling answer (with DTLS fingerprint).
3976// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3977// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3978// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 19:54:423979TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-30 04:08:163980 rtc::ScopedFakeClock fake_clock;
3981 // Some things use a time of "0" as a special value, so we need to start out
3982 // the fake clock at a nonzero time.
3983 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 12:52:223984 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-30 04:08:163985
3986 static constexpr int media_hop_delay_ms = 50;
3987 static constexpr int signaling_trip_delay_ms = 500;
3988 // For explanation of these values, see comment above.
3989 static constexpr int required_media_hops = 9;
3990 static constexpr int required_signaling_trips = 2;
3991 // For internal delays (such as posting an event asychronously).
3992 static constexpr int allowed_internal_delay_ms = 20;
3993 static constexpr int total_connection_time_ms =
3994 media_hop_delay_ms * required_media_hops +
3995 signaling_trip_delay_ms * required_signaling_trips +
3996 allowed_internal_delay_ms;
3997
3998 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3999 3478};
4000 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4001 0};
4002 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4003 3478};
4004 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4005 0};
Seth Hampsonaed71642018-06-11 14:41:324006 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4007 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 12:01:404008
Seth Hampsonaed71642018-06-11 14:41:324009 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4010 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-30 04:08:164011 // Bypass permission check on received packets so media can be sent before
4012 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 14:41:324013 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4014 turn_server_1->set_enable_permission_checks(false);
4015 });
4016 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4017 turn_server_2->set_enable_permission_checks(false);
4018 });
deadbeef1dcb1642017-03-30 04:08:164019
4020 PeerConnectionInterface::RTCConfiguration client_1_config;
4021 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4022 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4023 ice_server_1.username = "test";
4024 ice_server_1.password = "test";
4025 client_1_config.servers.push_back(ice_server_1);
4026 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4027 client_1_config.presume_writable_when_fully_relayed = true;
4028
4029 PeerConnectionInterface::RTCConfiguration client_2_config;
4030 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4031 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4032 ice_server_2.username = "test";
4033 ice_server_2.password = "test";
4034 client_2_config.servers.push_back(ice_server_2);
4035 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4036 client_2_config.presume_writable_when_fully_relayed = true;
4037
4038 ASSERT_TRUE(
4039 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4040 // Set up the simulated delays.
4041 SetSignalingDelayMs(signaling_trip_delay_ms);
4042 ConnectFakeSignaling();
4043 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4044 virtual_socket_server()->UpdateDelayDistribution();
4045
4046 // Set "offer to receive audio/video" without adding any tracks, so we just
4047 // set up ICE/DTLS with no media.
4048 PeerConnectionInterface::RTCOfferAnswerOptions options;
4049 options.offer_to_receive_audio = 1;
4050 options.offer_to_receive_video = 1;
4051 caller()->SetOfferAnswerOptions(options);
4052 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-08 00:21:014053 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
4054 fake_clock);
Seth Hampson1d4a76d2018-06-19 21:31:414055 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4056 // If this is not done a DCHECK can be hit in ports.cc, because a large
4057 // negative number is calculated for the rtt due to the global clock changing.
4058 caller()->pc()->Close();
4059 callee()->pc()->Close();
deadbeef1dcb1642017-03-30 04:08:164060}
4061
Jonas Orelandbdcee282017-10-10 12:01:404062// Verify that a TurnCustomizer passed in through RTCConfiguration
4063// is actually used by the underlying TURN candidate pair.
4064// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 19:54:424065TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 12:01:404066 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4067 3478};
4068 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4069 0};
4070 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4071 3478};
4072 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4073 0};
Seth Hampsonaed71642018-06-11 14:41:324074 CreateTurnServer(turn_server_1_internal_address,
4075 turn_server_1_external_address);
4076 CreateTurnServer(turn_server_2_internal_address,
4077 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 12:01:404078
4079 PeerConnectionInterface::RTCConfiguration client_1_config;
4080 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4081 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4082 ice_server_1.username = "test";
4083 ice_server_1.password = "test";
4084 client_1_config.servers.push_back(ice_server_1);
4085 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 14:41:324086 auto* customizer1 = CreateTurnCustomizer();
4087 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 12:01:404088
4089 PeerConnectionInterface::RTCConfiguration client_2_config;
4090 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4091 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4092 ice_server_2.username = "test";
4093 ice_server_2.password = "test";
4094 client_2_config.servers.push_back(ice_server_2);
4095 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 14:41:324096 auto* customizer2 = CreateTurnCustomizer();
4097 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 12:01:404098
4099 ASSERT_TRUE(
4100 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4101 ConnectFakeSignaling();
4102
4103 // Set "offer to receive audio/video" without adding any tracks, so we just
4104 // set up ICE/DTLS with no media.
4105 PeerConnectionInterface::RTCOfferAnswerOptions options;
4106 options.offer_to_receive_audio = 1;
4107 options.offer_to_receive_video = 1;
4108 caller()->SetOfferAnswerOptions(options);
4109 caller()->CreateAndSetAndSignalOffer();
4110 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4111
Seth Hampsonaed71642018-06-11 14:41:324112 ExpectTurnCustomizerCountersIncremented(customizer1);
4113 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 12:01:404114}
4115
Benjamin Wright2d5f3cb2018-05-22 21:46:064116// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4117// send media between the caller and the callee.
4118TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4119 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4120 3478};
4121 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4122
4123 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 14:41:324124 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4125 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 21:46:064126
4127 webrtc::PeerConnectionInterface::IceServer ice_server;
4128 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4129 ice_server.username = "test";
4130 ice_server.password = "test";
4131
4132 PeerConnectionInterface::RTCConfiguration client_1_config;
4133 client_1_config.servers.push_back(ice_server);
4134 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4135
4136 PeerConnectionInterface::RTCConfiguration client_2_config;
4137 client_2_config.servers.push_back(ice_server);
4138 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4139
4140 ASSERT_TRUE(
4141 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4142
4143 // Do normal offer/answer and wait for ICE to complete.
4144 ConnectFakeSignaling();
4145 caller()->AddAudioVideoTracks();
4146 callee()->AddAudioVideoTracks();
4147 caller()->CreateAndSetAndSignalOffer();
4148 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4149 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4150 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4151
4152 MediaExpectations media_expectations;
4153 media_expectations.ExpectBidirectionalAudioAndVideo();
4154 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4155}
4156
Benjamin Wrightd6f86e82018-05-08 20:12:254157// Verify that a SSLCertificateVerifier passed in through
4158// PeerConnectionDependencies is actually used by the underlying SSL
4159// implementation to determine whether a certificate presented by the TURN
4160// server is accepted by the client. Note that openssladapter_unittest.cc
4161// contains more detailed, lower-level tests.
4162TEST_P(PeerConnectionIntegrationTest,
4163 SSLCertificateVerifierUsedForTurnConnections) {
4164 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4165 3478};
4166 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4167
4168 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4169 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 14:41:324170 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4171 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 20:12:254172
4173 webrtc::PeerConnectionInterface::IceServer ice_server;
4174 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4175 ice_server.username = "test";
4176 ice_server.password = "test";
4177
4178 PeerConnectionInterface::RTCConfiguration client_1_config;
4179 client_1_config.servers.push_back(ice_server);
4180 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4181
4182 PeerConnectionInterface::RTCConfiguration client_2_config;
4183 client_2_config.servers.push_back(ice_server);
4184 // Setting the type to kRelay forces the connection to go through a TURN
4185 // server.
4186 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4187
4188 // Get a copy to the pointer so we can verify calls later.
4189 rtc::TestCertificateVerifier* client_1_cert_verifier =
4190 new rtc::TestCertificateVerifier();
4191 client_1_cert_verifier->verify_certificate_ = true;
4192 rtc::TestCertificateVerifier* client_2_cert_verifier =
4193 new rtc::TestCertificateVerifier();
4194 client_2_cert_verifier->verify_certificate_ = true;
4195
4196 // Create the dependencies with the test certificate verifier.
4197 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4198 client_1_deps.tls_cert_verifier =
4199 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4200 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4201 client_2_deps.tls_cert_verifier =
4202 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4203
4204 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4205 client_1_config, std::move(client_1_deps), client_2_config,
4206 std::move(client_2_deps)));
4207 ConnectFakeSignaling();
4208
4209 // Set "offer to receive audio/video" without adding any tracks, so we just
4210 // set up ICE/DTLS with no media.
4211 PeerConnectionInterface::RTCOfferAnswerOptions options;
4212 options.offer_to_receive_audio = 1;
4213 options.offer_to_receive_video = 1;
4214 caller()->SetOfferAnswerOptions(options);
4215 caller()->CreateAndSetAndSignalOffer();
4216 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4217
4218 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4219 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 20:12:254220}
4221
4222TEST_P(PeerConnectionIntegrationTest,
4223 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4224 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4225 3478};
4226 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4227
4228 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4229 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 14:41:324230 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4231 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 20:12:254232
4233 webrtc::PeerConnectionInterface::IceServer ice_server;
4234 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4235 ice_server.username = "test";
4236 ice_server.password = "test";
4237
4238 PeerConnectionInterface::RTCConfiguration client_1_config;
4239 client_1_config.servers.push_back(ice_server);
4240 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4241
4242 PeerConnectionInterface::RTCConfiguration client_2_config;
4243 client_2_config.servers.push_back(ice_server);
4244 // Setting the type to kRelay forces the connection to go through a TURN
4245 // server.
4246 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4247
4248 // Get a copy to the pointer so we can verify calls later.
4249 rtc::TestCertificateVerifier* client_1_cert_verifier =
4250 new rtc::TestCertificateVerifier();
4251 client_1_cert_verifier->verify_certificate_ = false;
4252 rtc::TestCertificateVerifier* client_2_cert_verifier =
4253 new rtc::TestCertificateVerifier();
4254 client_2_cert_verifier->verify_certificate_ = false;
4255
4256 // Create the dependencies with the test certificate verifier.
4257 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4258 client_1_deps.tls_cert_verifier =
4259 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4260 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4261 client_2_deps.tls_cert_verifier =
4262 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4263
4264 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4265 client_1_config, std::move(client_1_deps), client_2_config,
4266 std::move(client_2_deps)));
4267 ConnectFakeSignaling();
4268
4269 // Set "offer to receive audio/video" without adding any tracks, so we just
4270 // set up ICE/DTLS with no media.
4271 PeerConnectionInterface::RTCOfferAnswerOptions options;
4272 options.offer_to_receive_audio = 1;
4273 options.offer_to_receive_video = 1;
4274 caller()->SetOfferAnswerOptions(options);
4275 caller()->CreateAndSetAndSignalOffer();
4276 bool wait_res = true;
4277 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4278 // properly, should be able to just wait for a state of "failed" instead of
4279 // waiting a fixed 10 seconds.
4280 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4281 ASSERT_FALSE(wait_res);
4282
4283 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4284 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 20:12:254285}
4286
deadbeefc964d0b2017-04-03 17:03:354287// Test that audio and video flow end-to-end when codec names don't use the
4288// expected casing, given that they're supposed to be case insensitive. To test
4289// this, all but one codec is removed from each media description, and its
4290// casing is changed.
4291//
4292// In the past, this has regressed and caused crashes/black video, due to the
4293// fact that code at some layers was doing case-insensitive comparisons and
4294// code at other layers was not.
Seth Hampson2f0d7022018-02-20 19:54:424295TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 17:03:354296 ASSERT_TRUE(CreatePeerConnectionWrappers());
4297 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:494298 caller()->AddAudioVideoTracks();
4299 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 17:03:354300
4301 // Remove all but one audio/video codec (opus and VP8), and change the
4302 // casing of the caller's generated offer.
4303 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4304 cricket::AudioContentDescription* audio =
4305 GetFirstAudioContentDescription(description);
4306 ASSERT_NE(nullptr, audio);
4307 auto audio_codecs = audio->codecs();
4308 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4309 [](const cricket::AudioCodec& codec) {
4310 return codec.name != "opus";
4311 }),
4312 audio_codecs.end());
4313 ASSERT_EQ(1u, audio_codecs.size());
4314 audio_codecs[0].name = "OpUs";
4315 audio->set_codecs(audio_codecs);
4316
4317 cricket::VideoContentDescription* video =
4318 GetFirstVideoContentDescription(description);
4319 ASSERT_NE(nullptr, video);
4320 auto video_codecs = video->codecs();
4321 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4322 [](const cricket::VideoCodec& codec) {
4323 return codec.name != "VP8";
4324 }),
4325 video_codecs.end());
4326 ASSERT_EQ(1u, video_codecs.size());
4327 video_codecs[0].name = "vP8";
4328 video->set_codecs(video_codecs);
4329 });
4330
4331 caller()->CreateAndSetAndSignalOffer();
4332 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4333
4334 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:424335 MediaExpectations media_expectations;
4336 media_expectations.ExpectBidirectionalAudioAndVideo();
4337 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 17:03:354338}
4339
Jonas Oreland49ac5952018-09-26 14:04:324340TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 14:39:054341 ASSERT_TRUE(CreatePeerConnectionWrappers());
4342 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:494343 caller()->AddAudioTrack();
hbos8d609f62017-04-10 14:39:054344 caller()->CreateAndSetAndSignalOffer();
4345 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 23:01:174346 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 19:54:424347 MediaExpectations media_expectations;
4348 media_expectations.CalleeExpectsSomeAudio(1);
4349 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 14:04:324350 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 14:39:054351 auto receiver = callee()->pc()->GetReceivers()[0];
4352 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 14:04:324353 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 14:39:054354 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4355 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 14:04:324356 sources[0].source_id());
4357 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
4358}
4359
4360TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
4361 ASSERT_TRUE(CreatePeerConnectionWrappers());
4362 ConnectFakeSignaling();
4363 caller()->AddVideoTrack();
4364 caller()->CreateAndSetAndSignalOffer();
4365 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4366 // Wait for one video frame to be received by the callee.
4367 MediaExpectations media_expectations;
4368 media_expectations.CalleeExpectsSomeVideo(1);
4369 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4370 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
4371 auto receiver = callee()->pc()->GetReceivers()[0];
4372 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
4373 auto sources = receiver->GetSources();
4374 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4375 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4376 sources[0].source_id());
4377 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 14:39:054378}
4379
deadbeef2f425aa2017-04-14 17:41:324380// Test that if a track is removed and added again with a different stream ID,
4381// the new stream ID is successfully communicated in SDP and media continues to
4382// flow end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:424383// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4384// it will not reuse a transceiver that has already been sending. After creating
4385// a new transceiver it tries to create an offer with two senders of the same
4386// track ids and it fails.
4387TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 17:41:324388 ASSERT_TRUE(CreatePeerConnectionWrappers());
4389 ConnectFakeSignaling();
4390
deadbeef2f425aa2017-04-14 17:41:324391 // Add track using stream 1, do offer/answer.
4392 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4393 caller()->CreateLocalAudioTrack();
4394 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 18:13:444395 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 17:41:324396 caller()->CreateAndSetAndSignalOffer();
4397 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:424398 {
4399 MediaExpectations media_expectations;
4400 media_expectations.CalleeExpectsSomeAudio(1);
4401 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4402 }
deadbeef2f425aa2017-04-14 17:41:324403 // Remove the sender, and create a new one with the new stream.
4404 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 18:13:444405 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 17:41:324406 caller()->CreateAndSetAndSignalOffer();
4407 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4408 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 19:54:424409 {
4410 MediaExpectations media_expectations;
4411 media_expectations.CalleeExpectsSomeAudio();
4412 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4413 }
deadbeef2f425aa2017-04-14 17:41:324414}
4415
Seth Hampson2f0d7022018-02-20 19:54:424416TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 14:29:404417 ASSERT_TRUE(CreatePeerConnectionWrappers());
4418 ConnectFakeSignaling();
4419
Karl Wiberg918f50c2018-07-05 09:40:334420 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Elad Alon99c3fe52017-10-13 14:29:404421 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4422 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4423 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 16:38:144424 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4425 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 14:29:404426
Steve Anton15324772018-01-16 18:26:494427 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 14:29:404428 caller()->CreateAndSetAndSignalOffer();
4429 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4430}
4431
Steve Antonede9ca52017-10-16 20:04:274432// Test that if candidates are only signaled by applying full session
4433// descriptions (instead of using AddIceCandidate), the peers can connect to
4434// each other and exchange media.
Seth Hampson2f0d7022018-02-20 19:54:424435TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 20:04:274436 ASSERT_TRUE(CreatePeerConnectionWrappers());
4437 // Each side will signal the session descriptions but not candidates.
4438 ConnectFakeSignalingForSdpOnly();
4439
4440 // Add audio video track and exchange the initial offer/answer with media
4441 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 18:26:494442 caller()->AddAudioVideoTracks();
4443 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 20:04:274444 caller()->CreateAndSetAndSignalOffer();
4445
4446 // Wait for all candidates to be gathered on both the caller and callee.
4447 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4448 caller()->ice_gathering_state(), kDefaultTimeout);
4449 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4450 callee()->ice_gathering_state(), kDefaultTimeout);
4451
4452 // The candidates will now be included in the session description, so
4453 // signaling them will start the ICE connection.
4454 caller()->CreateAndSetAndSignalOffer();
4455 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4456
4457 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 19:54:424458 MediaExpectations media_expectations;
4459 media_expectations.ExpectBidirectionalAudioAndVideo();
4460 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 20:04:274461}
4462
henrika5f6bf242017-11-01 10:06:564463// Test that SetAudioPlayout can be used to disable audio playout from the
4464// start, then later enable it. This may be useful, for example, if the caller
4465// needs to play a local ringtone until some event occurs, after which it
4466// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 19:54:424467TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 10:06:564468 ASSERT_TRUE(CreatePeerConnectionWrappers());
4469 ConnectFakeSignaling();
4470
4471 // Set up audio-only call where audio playout is disabled on caller's side.
4472 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 18:26:494473 caller()->AddAudioTrack();
4474 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 10:06:564475 caller()->CreateAndSetAndSignalOffer();
4476 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4477
4478 // Pump messages for a second.
4479 WAIT(false, 1000);
4480 // Since audio playout is disabled, the caller shouldn't have received
4481 // anything (at the playout level, at least).
4482 EXPECT_EQ(0, caller()->audio_frames_received());
4483 // As a sanity check, make sure the callee (for which playout isn't disabled)
4484 // did still see frames on its audio level.
4485 ASSERT_GT(callee()->audio_frames_received(), 0);
4486
4487 // Enable playout again, and ensure audio starts flowing.
4488 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 19:54:424489 MediaExpectations media_expectations;
4490 media_expectations.ExpectBidirectionalAudio();
4491 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 10:06:564492}
4493
4494double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4495 auto report = pc->NewGetStats();
4496 auto track_stats_list =
4497 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4498 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4499 for (const auto* track_stats : track_stats_list) {
4500 if (track_stats->remote_source.is_defined() &&
4501 *track_stats->remote_source) {
4502 remote_track_stats = track_stats;
4503 break;
4504 }
4505 }
4506
4507 if (!remote_track_stats->total_audio_energy.is_defined()) {
4508 return 0.0;
4509 }
4510 return *remote_track_stats->total_audio_energy;
4511}
4512
4513// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4514// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 19:54:424515TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 10:06:564516 DisableAudioPlayoutStillGeneratesAudioStats) {
4517 ASSERT_TRUE(CreatePeerConnectionWrappers());
4518 ConnectFakeSignaling();
4519
4520 // Set up audio-only call where playout is disabled but audio-processing is
4521 // still active.
Steve Anton15324772018-01-16 18:26:494522 caller()->AddAudioTrack();
4523 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 10:06:564524 caller()->pc()->SetAudioPlayout(false);
4525
4526 caller()->CreateAndSetAndSignalOffer();
4527 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4528
4529 // Wait for the callee to receive audio stats.
4530 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4531}
4532
henrika4f167df2017-11-01 13:45:554533// Test that SetAudioRecording can be used to disable audio recording from the
4534// start, then later enable it. This may be useful, for example, if the caller
4535// wants to ensure that no audio resources are active before a certain state
4536// is reached.
Seth Hampson2f0d7022018-02-20 19:54:424537TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 13:45:554538 ASSERT_TRUE(CreatePeerConnectionWrappers());
4539 ConnectFakeSignaling();
4540
4541 // Set up audio-only call where audio recording is disabled on caller's side.
4542 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 18:26:494543 caller()->AddAudioTrack();
4544 callee()->AddAudioTrack();
henrika4f167df2017-11-01 13:45:554545 caller()->CreateAndSetAndSignalOffer();
4546 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4547
4548 // Pump messages for a second.
4549 WAIT(false, 1000);
4550 // Since caller has disabled audio recording, the callee shouldn't have
4551 // received anything.
4552 EXPECT_EQ(0, callee()->audio_frames_received());
4553 // As a sanity check, make sure the caller did still see frames on its
4554 // audio level since audio recording is enabled on the calle side.
4555 ASSERT_GT(caller()->audio_frames_received(), 0);
4556
4557 // Enable audio recording again, and ensure audio starts flowing.
4558 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 19:54:424559 MediaExpectations media_expectations;
4560 media_expectations.ExpectBidirectionalAudio();
4561 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 13:45:554562}
4563
Taylor Brandstetter389a97c2018-01-04 00:26:064564// Test that after closing PeerConnections, they stop sending any packets (ICE,
4565// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 19:54:424566TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-04 00:26:064567 // Set up audio/video/data, wait for some frames to be received.
4568 ASSERT_TRUE(CreatePeerConnectionWrappers());
4569 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:494570 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-04 00:26:064571#ifdef HAVE_SCTP
4572 caller()->CreateDataChannel();
4573#endif
4574 caller()->CreateAndSetAndSignalOffer();
4575 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:424576 MediaExpectations media_expectations;
4577 media_expectations.CalleeExpectsSomeAudioAndVideo();
4578 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-04 00:26:064579 // Close PeerConnections.
4580 caller()->pc()->Close();
4581 callee()->pc()->Close();
4582 // Pump messages for a second, and ensure no new packets end up sent.
4583 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4584 WAIT(false, 1000);
4585 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4586 EXPECT_EQ(sent_packets_a, sent_packets_b);
4587}
4588
Steve Anton7eca0932018-03-30 22:18:414589// Test that transport stats are generated by the RTCStatsCollector for a
4590// connection that only involves data channels. This is a regression test for
4591// crbug.com/826972.
4592#ifdef HAVE_SCTP
4593TEST_P(PeerConnectionIntegrationTest,
4594 TransportStatsReportedForDataChannelOnlyConnection) {
4595 ASSERT_TRUE(CreatePeerConnectionWrappers());
4596 ConnectFakeSignaling();
4597 caller()->CreateDataChannel();
4598
4599 caller()->CreateAndSetAndSignalOffer();
4600 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4601 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4602
4603 auto caller_report = caller()->NewGetStats();
4604 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4605 auto callee_report = callee()->NewGetStats();
4606 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4607}
4608#endif // HAVE_SCTP
4609
Qingsi Wang7685e862018-06-12 03:15:464610TEST_P(PeerConnectionIntegrationTest,
4611 IceEventsGeneratedAndLoggedInRtcEventLog) {
4612 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4613 ConnectFakeSignaling();
4614 PeerConnectionInterface::RTCOfferAnswerOptions options;
4615 options.offer_to_receive_audio = 1;
4616 caller()->SetOfferAnswerOptions(options);
4617 caller()->CreateAndSetAndSignalOffer();
4618 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4619 ASSERT_NE(nullptr, caller()->event_log_factory());
4620 ASSERT_NE(nullptr, callee()->event_log_factory());
4621 webrtc::FakeRtcEventLog* caller_event_log =
4622 static_cast<webrtc::FakeRtcEventLog*>(
4623 caller()->event_log_factory()->last_log_created());
4624 webrtc::FakeRtcEventLog* callee_event_log =
4625 static_cast<webrtc::FakeRtcEventLog*>(
4626 callee()->event_log_factory()->last_log_created());
4627 ASSERT_NE(nullptr, caller_event_log);
4628 ASSERT_NE(nullptr, callee_event_log);
4629 int caller_ice_config_count = caller_event_log->GetEventCount(
4630 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4631 int caller_ice_event_count = caller_event_log->GetEventCount(
4632 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4633 int callee_ice_config_count = callee_event_log->GetEventCount(
4634 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4635 int callee_ice_event_count = callee_event_log->GetEventCount(
4636 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4637 EXPECT_LT(0, caller_ice_config_count);
4638 EXPECT_LT(0, caller_ice_event_count);
4639 EXPECT_LT(0, callee_ice_config_count);
4640 EXPECT_LT(0, callee_ice_event_count);
4641}
4642
Seth Hampson2f0d7022018-02-20 19:54:424643INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4644 PeerConnectionIntegrationTest,
4645 Values(SdpSemantics::kPlanB,
4646 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-18 01:41:024647
Steve Anton74255ff2018-01-25 02:32:574648// Tests that verify interoperability between Plan B and Unified Plan
4649// PeerConnections.
4650class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 19:54:424651 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-25 02:32:574652 public ::testing::WithParamInterface<
4653 std::tuple<SdpSemantics, SdpSemantics>> {
4654 protected:
Seth Hampson2f0d7022018-02-20 19:54:424655 // Setting the SdpSemantics for the base test to kDefault does not matter
4656 // because we specify not to use the test semantics when creating
4657 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-25 02:32:574658 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-13 00:21:034659 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 19:54:424660 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-25 02:32:574661 callee_semantics_(std::get<1>(GetParam())) {}
4662
4663 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-13 00:21:034664 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4665 callee_semantics_);
Steve Anton74255ff2018-01-25 02:32:574666 }
4667
4668 const SdpSemantics caller_semantics_;
4669 const SdpSemantics callee_semantics_;
4670};
4671
4672TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4673 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4674 ConnectFakeSignaling();
4675
4676 caller()->CreateAndSetAndSignalOffer();
4677 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4678}
4679
4680TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4681 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4682 ConnectFakeSignaling();
4683 auto audio_sender = caller()->AddAudioTrack();
4684
4685 caller()->CreateAndSetAndSignalOffer();
4686 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4687
4688 // Verify that one audio receiver has been created on the remote and that it
4689 // has the same track ID as the sending track.
4690 auto receivers = callee()->pc()->GetReceivers();
4691 ASSERT_EQ(1u, receivers.size());
4692 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4693 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4694
Seth Hampson2f0d7022018-02-20 19:54:424695 MediaExpectations media_expectations;
4696 media_expectations.CalleeExpectsSomeAudio();
4697 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574698}
4699
4700TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4701 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4702 ConnectFakeSignaling();
4703 auto video_sender = caller()->AddVideoTrack();
4704 auto audio_sender = caller()->AddAudioTrack();
4705
4706 caller()->CreateAndSetAndSignalOffer();
4707 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4708
4709 // Verify that one audio and one video receiver have been created on the
4710 // remote and that they have the same track IDs as the sending tracks.
4711 auto audio_receivers =
4712 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4713 ASSERT_EQ(1u, audio_receivers.size());
4714 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4715 auto video_receivers =
4716 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4717 ASSERT_EQ(1u, video_receivers.size());
4718 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4719
Seth Hampson2f0d7022018-02-20 19:54:424720 MediaExpectations media_expectations;
4721 media_expectations.CalleeExpectsSomeAudioAndVideo();
4722 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574723}
4724
4725TEST_P(PeerConnectionIntegrationInteropTest,
4726 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4727 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4728 ConnectFakeSignaling();
4729 caller()->AddAudioVideoTracks();
4730 callee()->AddAudioVideoTracks();
4731
4732 caller()->CreateAndSetAndSignalOffer();
4733 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4734
Seth Hampson2f0d7022018-02-20 19:54:424735 MediaExpectations media_expectations;
4736 media_expectations.ExpectBidirectionalAudioAndVideo();
4737 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574738}
4739
4740TEST_P(PeerConnectionIntegrationInteropTest,
4741 ReverseRolesOneAudioLocalToOneVideoRemote) {
4742 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4743 ConnectFakeSignaling();
4744 caller()->AddAudioTrack();
4745 callee()->AddVideoTrack();
4746
4747 caller()->CreateAndSetAndSignalOffer();
4748 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4749
4750 // Verify that only the audio track has been negotiated.
4751 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4752 // Might also check that the callee's NegotiationNeeded flag is set.
4753
4754 // Reverse roles.
4755 callee()->CreateAndSetAndSignalOffer();
4756 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4757
Seth Hampson2f0d7022018-02-20 19:54:424758 MediaExpectations media_expectations;
4759 media_expectations.CallerExpectsSomeVideo();
4760 media_expectations.CalleeExpectsSomeAudio();
4761 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574762}
4763
Steve Antonba42e992018-04-09 21:10:014764INSTANTIATE_TEST_CASE_P(
4765 PeerConnectionIntegrationTest,
4766 PeerConnectionIntegrationInteropTest,
4767 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4768 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4769
4770// Test that if the Unified Plan side offers two video tracks then the Plan B
4771// side will only see the first one and ignore the second.
4772TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-13 00:21:034773 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4774 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-25 02:32:574775 ConnectFakeSignaling();
4776 auto first_sender = caller()->AddVideoTrack();
4777 caller()->AddVideoTrack();
4778
4779 caller()->CreateAndSetAndSignalOffer();
4780 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4781
4782 // Verify that there is only one receiver and it corresponds to the first
4783 // added track.
4784 auto receivers = callee()->pc()->GetReceivers();
4785 ASSERT_EQ(1u, receivers.size());
4786 EXPECT_TRUE(receivers[0]->track()->enabled());
4787 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4788
Seth Hampson2f0d7022018-02-20 19:54:424789 MediaExpectations media_expectations;
4790 media_expectations.CalleeExpectsSomeVideo();
4791 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574792}
4793
deadbeef1dcb1642017-03-30 04:08:164794} // namespace
4795
4796#endif // if !defined(THREAD_SANITIZER)