blob: 186da00b9669435f0d749061b90b307b8ce9ac00 [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// Disable for TSan v2, see
12// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
13#if !defined(THREAD_SANITIZER)
14
15#include <stdio.h>
16
17#include <algorithm>
18#include <functional>
19#include <list>
20#include <map>
21#include <memory>
22#include <utility>
23#include <vector>
24
Karl Wiberg1b0eae32017-10-17 14:48:54 +020025#include "api/audio_codecs/builtin_audio_decoder_factory.h"
26#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "api/fakemetricsobserver.h"
28#include "api/mediastreaminterface.h"
29#include "api/peerconnectioninterface.h"
Steve Anton8c0f7a72017-10-03 10:03:10 -070030#include "api/peerconnectionproxy.h"
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010031#include "api/rtpreceiverinterface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "api/test/fakeconstraints.h"
Anders Carlsson67537952018-05-03 11:28:29 +020033#include "api/video_codecs/builtin_video_decoder_factory.h"
34#include "api/video_codecs/builtin_video_encoder_factory.h"
35#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070036#include "call/call.h"
37#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
38#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020039#include "media/engine/fakewebrtcvideoengine.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070040#include "media/engine/webrtcmediaengine.h"
41#include "modules/audio_processing/include/audio_processing.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020042#include "p2p/base/p2pconstants.h"
43#include "p2p/base/portinterface.h"
Steve Antonede9ca52017-10-16 13:04:27 -070044#include "p2p/base/teststunserver.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020045#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020046#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 11:54:42 -080053#include "pc/rtpmediautils.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080054#include "pc/sessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "pc/test/fakeaudiocapturemodule.h"
Niels Möller0f405822018-05-17 09:16:41 +020056#include "pc/test/fakeperiodicvideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020057#include "pc/test/fakertccertificategenerator.h"
58#include "pc/test/fakevideotrackrenderer.h"
59#include "pc/test/mockpeerconnectionobservers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020060#include "rtc_base/fakenetwork.h"
Steve Antonede9ca52017-10-16 13:04:27 -070061#include "rtc_base/firewallsocketserver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020062#include "rtc_base/gunit.h"
Benjamin Wrightd6f86e82018-05-08 13:12:25 -070063#include "rtc_base/testcertificateverifier.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020064#include "rtc_base/virtualsocketserver.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020065#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070066
67using cricket::ContentInfo;
68using cricket::FakeWebRtcVideoDecoder;
69using cricket::FakeWebRtcVideoDecoderFactory;
70using cricket::FakeWebRtcVideoEncoder;
71using cricket::FakeWebRtcVideoEncoderFactory;
72using cricket::MediaContentDescription;
Steve Antondf527fd2018-04-27 15:52:03 -070073using cricket::StreamParams;
Steve Antonede9ca52017-10-16 13:04:27 -070074using rtc::SocketAddress;
Seth Hampson2f0d7022018-02-20 11:54:42 -080075using ::testing::Combine;
Steve Antonede9ca52017-10-16 13:04:27 -070076using ::testing::ElementsAre;
77using ::testing::Values;
deadbeef1dcb1642017-03-29 21:08:16 -070078using webrtc::DataBuffer;
79using webrtc::DataChannelInterface;
80using webrtc::DtmfSender;
81using webrtc::DtmfSenderInterface;
82using webrtc::DtmfSenderObserverInterface;
83using webrtc::FakeConstraints;
Steve Anton15324772018-01-16 10:26:49 -080084using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-29 21:08:16 -070085using webrtc::MediaConstraintsInterface;
86using webrtc::MediaStreamInterface;
87using webrtc::MediaStreamTrackInterface;
88using webrtc::MockCreateSessionDescriptionObserver;
89using webrtc::MockDataChannelObserver;
90using webrtc::MockSetSessionDescriptionObserver;
91using webrtc::MockStatsObserver;
92using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 10:03:10 -070093using webrtc::PeerConnection;
deadbeef1dcb1642017-03-29 21:08:16 -070094using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-24 18:32:57 -080095using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070096using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 10:03:10 -070097using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 10:26:49 -080098using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 15:18:41 -070099using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-24 18:32:57 -0800100using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100101using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800102using webrtc::RtpSenderInterface;
103using webrtc::RtpTransceiverDirection;
104using webrtc::RtpTransceiverInit;
105using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-17 17:41:02 -0800106using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 10:27:41 -0800107using webrtc::SdpType;
deadbeef1dcb1642017-03-29 21:08:16 -0700108using webrtc::SessionDescriptionInterface;
109using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 10:26:49 -0800110using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-29 21:08:16 -0700111
112namespace {
113
114static const int kDefaultTimeout = 10000;
115static const int kMaxWaitForStatsMs = 3000;
116static const int kMaxWaitForActivationMs = 5000;
117static const int kMaxWaitForFramesMs = 10000;
118// Default number of audio/video frames to wait for before considering a test
119// successful.
120static const int kDefaultExpectedAudioFrameCount = 3;
121static const int kDefaultExpectedVideoFrameCount = 3;
122
deadbeef1dcb1642017-03-29 21:08:16 -0700123static const char kDataChannelLabel[] = "data_channel";
124
125// SRTP cipher name negotiated by the tests. This must be updated if the
126// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700127static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700128static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
129
Steve Antonede9ca52017-10-16 13:04:27 -0700130static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
131
deadbeef1dcb1642017-03-29 21:08:16 -0700132// Helper function for constructing offer/answer options to initiate an ICE
133// restart.
134PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
135 PeerConnectionInterface::RTCOfferAnswerOptions options;
136 options.ice_restart = true;
137 return options;
138}
139
deadbeefd8ad7882017-04-18 16:01:17 -0700140// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
141// attribute from received SDP, simulating a legacy endpoint.
142void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
143 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800144 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700145 }
146 desc->set_msid_supported(false);
147}
148
Seth Hampson5897a6e2018-04-03 11:16:33 -0700149// Removes all stream information besides the stream ids, simulating an
150// endpoint that only signals a=msid lines to convey stream_ids.
151void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
152 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700153 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700154 std::vector<std::string> stream_ids;
155 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700156 const StreamParams& first_stream =
157 content.media_description()->streams()[0];
158 track_id = first_stream.id;
159 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700160 }
161 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700162 StreamParams new_stream;
163 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700164 new_stream.set_stream_ids(stream_ids);
165 content.media_description()->AddStream(new_stream);
166 }
167}
168
zhihuangf8164932017-05-19 13:09:47 -0700169int FindFirstMediaStatsIndexByKind(
170 const std::string& kind,
171 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
172 media_stats_vec) {
173 for (size_t i = 0; i < media_stats_vec.size(); i++) {
174 if (media_stats_vec[i]->kind.ValueToString() == kind) {
175 return i;
176 }
177 }
178 return -1;
179}
180
Harald Alvestrand8ebba742018-05-31 14:00:34 +0200181int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
182 int signature = 0;
183 for (const auto it : events) {
184 signature |= static_cast<int>(it);
185 }
186 return signature;
187}
188
deadbeef1dcb1642017-03-29 21:08:16 -0700189class SignalingMessageReceiver {
190 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800191 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700192 virtual void ReceiveIceMessage(const std::string& sdp_mid,
193 int sdp_mline_index,
194 const std::string& msg) = 0;
195
196 protected:
197 SignalingMessageReceiver() {}
198 virtual ~SignalingMessageReceiver() {}
199};
200
201class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
202 public:
203 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
204 : expected_media_type_(media_type) {}
205
206 void OnFirstPacketReceived(cricket::MediaType media_type) override {
207 ASSERT_EQ(expected_media_type_, media_type);
208 first_packet_received_ = true;
209 }
210
211 bool first_packet_received() const { return first_packet_received_; }
212
213 virtual ~MockRtpReceiverObserver() {}
214
215 private:
216 bool first_packet_received_ = false;
217 cricket::MediaType expected_media_type_;
218};
219
220// Helper class that wraps a peer connection, observes it, and can accept
221// signaling messages from another wrapper.
222//
223// Uses a fake network, fake A/V capture, and optionally fake
224// encoders/decoders, though they aren't used by default since they don't
225// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700226// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800227// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700228class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800229 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700230 public:
231 // Different factory methods for convenience.
232 // TODO(deadbeef): Could use the pattern of:
233 //
234 // PeerConnectionWrapper =
235 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
236 //
237 // To reduce some code duplication.
238 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
239 const std::string& debug_name,
240 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
241 rtc::Thread* network_thread,
242 rtc::Thread* worker_thread) {
243 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700244 webrtc::PeerConnectionDependencies dependencies(nullptr);
245 dependencies.cert_generator = std::move(cert_generator);
246 if (!client->Init(nullptr, nullptr, nullptr, std::move(dependencies),
Qingsi Wang7685e862018-06-11 20:15:46 -0700247 network_thread, worker_thread, nullptr)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700248 delete client;
249 return nullptr;
250 }
251 return client;
252 }
253
deadbeef2f425aa2017-04-14 10:41:32 -0700254 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
255 return peer_connection_factory_.get();
256 }
257
deadbeef1dcb1642017-03-29 21:08:16 -0700258 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
259
260 // If a signaling message receiver is set (via ConnectFakeSignaling), this
261 // will set the whole offer/answer exchange in motion. Just need to wait for
262 // the signaling state to reach "stable".
263 void CreateAndSetAndSignalOffer() {
264 auto offer = CreateOffer();
265 ASSERT_NE(nullptr, offer);
266 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
267 }
268
269 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
270 // when a remote offer is received (via fake signaling) and an answer is
271 // generated. By default, uses default options.
272 void SetOfferAnswerOptions(
273 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
274 offer_answer_options_ = options;
275 }
276
277 // Set a callback to be invoked when SDP is received via the fake signaling
278 // channel, which provides an opportunity to munge (modify) the SDP. This is
279 // used to test SDP being applied that a PeerConnection would normally not
280 // generate, but a non-JSEP endpoint might.
281 void SetReceivedSdpMunger(
282 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100283 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700284 }
285
deadbeefc964d0b2017-04-03 10:03:35 -0700286 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700287 // generated.
288 void SetGeneratedSdpMunger(
289 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100290 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700291 }
292
Seth Hampson2f0d7022018-02-20 11:54:42 -0800293 // Set a callback to be invoked when a remote offer is received via the fake
294 // signaling channel. This provides an opportunity to change the
295 // PeerConnection state before an answer is created and sent to the caller.
296 void SetRemoteOfferHandler(std::function<void()> handler) {
297 remote_offer_handler_ = std::move(handler);
298 }
299
Steve Antonede9ca52017-10-16 13:04:27 -0700300 // Every ICE connection state in order that has been seen by the observer.
301 std::vector<PeerConnectionInterface::IceConnectionState>
302 ice_connection_state_history() const {
303 return ice_connection_state_history_;
304 }
Steve Anton6f25b092017-10-23 09:39:20 -0700305 void clear_ice_connection_state_history() {
306 ice_connection_state_history_.clear();
307 }
Steve Antonede9ca52017-10-16 13:04:27 -0700308
309 // Every ICE gathering state in order that has been seen by the observer.
310 std::vector<PeerConnectionInterface::IceGatheringState>
311 ice_gathering_state_history() const {
312 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700313 }
314
Steve Anton15324772018-01-16 10:26:49 -0800315 void AddAudioVideoTracks() {
316 AddAudioTrack();
317 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700318 }
319
Steve Anton74255ff2018-01-24 18:32:57 -0800320 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
321 return AddTrack(CreateLocalAudioTrack());
322 }
deadbeef1dcb1642017-03-29 21:08:16 -0700323
Steve Anton74255ff2018-01-24 18:32:57 -0800324 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
325 return AddTrack(CreateLocalVideoTrack());
326 }
deadbeef1dcb1642017-03-29 21:08:16 -0700327
328 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200329 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700330 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200331 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700332 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200333 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700334 // TODO(perkj): Test audio source when it is implemented. Currently audio
335 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700336 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700337 source);
338 }
339
340 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Niels Möller5c7efe72018-05-11 10:34:46 +0200341 return CreateLocalVideoTrackInternal(
342 webrtc::FakePeriodicVideoSource::Config());
deadbeef1dcb1642017-03-29 21:08:16 -0700343 }
344
345 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200346 CreateLocalVideoTrackWithConfig(
347 webrtc::FakePeriodicVideoSource::Config config) {
348 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700349 }
350
351 rtc::scoped_refptr<webrtc::VideoTrackInterface>
352 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200353 webrtc::FakePeriodicVideoSource::Config config;
354 config.rotation = rotation;
355 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700356 }
357
Steve Anton74255ff2018-01-24 18:32:57 -0800358 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
359 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800360 const std::vector<std::string>& stream_ids = {}) {
361 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800362 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800363 return result.MoveValue();
364 }
365
366 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
367 cricket::MediaType media_type) {
368 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
369 for (auto receiver : pc()->GetReceivers()) {
370 if (receiver->media_type() == media_type) {
371 receivers.push_back(receiver);
372 }
373 }
374 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700375 }
376
Seth Hampson2f0d7022018-02-20 11:54:42 -0800377 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
378 cricket::MediaType media_type) {
379 for (auto transceiver : pc()->GetTransceivers()) {
380 if (transceiver->receiver()->media_type() == media_type) {
381 return transceiver;
382 }
383 }
384 return nullptr;
385 }
386
deadbeef1dcb1642017-03-29 21:08:16 -0700387 bool SignalingStateStable() {
388 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
389 }
390
391 void CreateDataChannel() { CreateDataChannel(nullptr); }
392
393 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700394 CreateDataChannel(kDataChannelLabel, init);
395 }
396
397 void CreateDataChannel(const std::string& label,
398 const webrtc::DataChannelInit* init) {
399 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700400 ASSERT_TRUE(data_channel_.get() != nullptr);
401 data_observer_.reset(new MockDataChannelObserver(data_channel_));
402 }
403
404 DataChannelInterface* data_channel() { return data_channel_; }
405 const MockDataChannelObserver* data_observer() const {
406 return data_observer_.get();
407 }
408
409 int audio_frames_received() const {
410 return fake_audio_capture_module_->frames_received();
411 }
412
413 // Takes minimum of video frames received for each track.
414 //
415 // Can be used like:
416 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
417 //
418 // To ensure that all video tracks received at least a certain number of
419 // frames.
420 int min_video_frames_received_per_track() const {
421 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200422 if (fake_video_renderers_.empty()) {
423 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700424 }
deadbeef1dcb1642017-03-29 21:08:16 -0700425
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200426 for (const auto& pair : fake_video_renderers_) {
427 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700428 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200429 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700430 }
431
432 // Returns a MockStatsObserver in a state after stats gathering finished,
433 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700434 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700435 webrtc::MediaStreamTrackInterface* track) {
436 rtc::scoped_refptr<MockStatsObserver> observer(
437 new rtc::RefCountedObject<MockStatsObserver>());
438 EXPECT_TRUE(peer_connection_->GetStats(
439 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
440 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
441 return observer;
442 }
443
444 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700445 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
446 return OldGetStatsForTrack(nullptr);
447 }
448
449 // Synchronously gets stats and returns them. If it times out, fails the test
450 // and returns null.
451 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
452 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
453 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
454 peer_connection_->GetStats(callback);
455 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
456 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700457 }
458
459 int rendered_width() {
460 EXPECT_FALSE(fake_video_renderers_.empty());
461 return fake_video_renderers_.empty()
462 ? 0
463 : fake_video_renderers_.begin()->second->width();
464 }
465
466 int rendered_height() {
467 EXPECT_FALSE(fake_video_renderers_.empty());
468 return fake_video_renderers_.empty()
469 ? 0
470 : fake_video_renderers_.begin()->second->height();
471 }
472
473 double rendered_aspect_ratio() {
474 if (rendered_height() == 0) {
475 return 0.0;
476 }
477 return static_cast<double>(rendered_width()) / rendered_height();
478 }
479
480 webrtc::VideoRotation rendered_rotation() {
481 EXPECT_FALSE(fake_video_renderers_.empty());
482 return fake_video_renderers_.empty()
483 ? webrtc::kVideoRotation_0
484 : fake_video_renderers_.begin()->second->rotation();
485 }
486
487 int local_rendered_width() {
488 return local_video_renderer_ ? local_video_renderer_->width() : 0;
489 }
490
491 int local_rendered_height() {
492 return local_video_renderer_ ? local_video_renderer_->height() : 0;
493 }
494
495 double local_rendered_aspect_ratio() {
496 if (local_rendered_height() == 0) {
497 return 0.0;
498 }
499 return static_cast<double>(local_rendered_width()) /
500 local_rendered_height();
501 }
502
503 size_t number_of_remote_streams() {
504 if (!pc()) {
505 return 0;
506 }
507 return pc()->remote_streams()->count();
508 }
509
510 StreamCollectionInterface* remote_streams() const {
511 if (!pc()) {
512 ADD_FAILURE();
513 return nullptr;
514 }
515 return pc()->remote_streams();
516 }
517
518 StreamCollectionInterface* local_streams() {
519 if (!pc()) {
520 ADD_FAILURE();
521 return nullptr;
522 }
523 return pc()->local_streams();
524 }
525
526 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
527 return pc()->signaling_state();
528 }
529
530 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
531 return pc()->ice_connection_state();
532 }
533
534 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
535 return pc()->ice_gathering_state();
536 }
537
538 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
539 // GetReceivers. They're updated automatically when a remote offer/answer
540 // from the fake signaling channel is applied, or when
541 // ResetRtpReceiverObservers below is called.
542 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
543 rtp_receiver_observers() {
544 return rtp_receiver_observers_;
545 }
546
547 void ResetRtpReceiverObservers() {
548 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100549 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
550 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700551 std::unique_ptr<MockRtpReceiverObserver> observer(
552 new MockRtpReceiverObserver(receiver->media_type()));
553 receiver->SetObserver(observer.get());
554 rtp_receiver_observers_.push_back(std::move(observer));
555 }
556 }
557
Steve Antonede9ca52017-10-16 13:04:27 -0700558 rtc::FakeNetworkManager* network() const {
559 return fake_network_manager_.get();
560 }
561 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
562
Qingsi Wang7685e862018-06-11 20:15:46 -0700563 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
564 return event_log_factory_;
565 }
566
deadbeef1dcb1642017-03-29 21:08:16 -0700567 private:
568 explicit PeerConnectionWrapper(const std::string& debug_name)
569 : debug_name_(debug_name) {}
570
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700571 bool Init(const MediaConstraintsInterface* constraints,
572 const PeerConnectionFactory::Options* options,
573 const PeerConnectionInterface::RTCConfiguration* config,
574 webrtc::PeerConnectionDependencies dependencies,
575 rtc::Thread* network_thread,
Qingsi Wang7685e862018-06-11 20:15:46 -0700576 rtc::Thread* worker_thread,
577 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700578 // There's an error in this test code if Init ends up being called twice.
579 RTC_DCHECK(!peer_connection_);
580 RTC_DCHECK(!peer_connection_factory_);
581
582 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700583 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700584
585 std::unique_ptr<cricket::PortAllocator> port_allocator(
586 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700587 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700588 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
589 if (!fake_audio_capture_module_) {
590 return false;
591 }
deadbeef1dcb1642017-03-29 21:08:16 -0700592 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700593
594 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
595 pc_factory_dependencies.network_thread = network_thread;
596 pc_factory_dependencies.worker_thread = worker_thread;
597 pc_factory_dependencies.signaling_thread = signaling_thread;
598 pc_factory_dependencies.media_engine =
599 cricket::WebRtcMediaEngineFactory::Create(
600 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
601 fake_audio_capture_module_),
602 webrtc::CreateBuiltinAudioEncoderFactory(),
603 webrtc::CreateBuiltinAudioDecoderFactory(),
604 webrtc::CreateBuiltinVideoEncoderFactory(),
605 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
606 webrtc::AudioProcessingBuilder().Create());
607 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
608 if (event_log_factory) {
609 event_log_factory_ = event_log_factory.get();
610 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
611 } else {
612 pc_factory_dependencies.event_log_factory =
613 webrtc::CreateRtcEventLogFactory();
614 }
615 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
616 std::move(pc_factory_dependencies));
617
deadbeef1dcb1642017-03-29 21:08:16 -0700618 if (!peer_connection_factory_) {
619 return false;
620 }
621 if (options) {
622 peer_connection_factory_->SetOptions(*options);
623 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800624 if (config) {
625 sdp_semantics_ = config->sdp_semantics;
626 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700627
628 dependencies.allocator = std::move(port_allocator);
deadbeef1dcb1642017-03-29 21:08:16 -0700629 peer_connection_ =
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700630 CreatePeerConnection(constraints, config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700631 return peer_connection_.get() != nullptr;
632 }
633
634 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700635 const MediaConstraintsInterface* constraints,
636 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700637 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700638 PeerConnectionInterface::RTCConfiguration modified_config;
639 // If |config| is null, this will result in a default configuration being
640 // used.
641 if (config) {
642 modified_config = *config;
643 }
644 // Disable resolution adaptation; we don't want it interfering with the
645 // test results.
646 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
647 // ratios and not specific resolutions, is this even necessary?
648 modified_config.set_cpu_adaptation(false);
649
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700650 // Use the legacy interface.
651 if (constraints != nullptr) {
652 return peer_connection_factory_->CreatePeerConnection(
653 modified_config, constraints, std::move(dependencies.allocator),
654 std::move(dependencies.cert_generator), this);
655 }
656 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700657 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700658 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700659 }
660
661 void set_signaling_message_receiver(
662 SignalingMessageReceiver* signaling_message_receiver) {
663 signaling_message_receiver_ = signaling_message_receiver;
664 }
665
666 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
667
Steve Antonede9ca52017-10-16 13:04:27 -0700668 void set_signal_ice_candidates(bool signal) {
669 signal_ice_candidates_ = signal;
670 }
671
deadbeef1dcb1642017-03-29 21:08:16 -0700672 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200673 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700674 // Set max frame rate to 10fps to reduce the risk of test flakiness.
675 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200676 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700677
Niels Möller5c7efe72018-05-11 10:34:46 +0200678 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200679 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
680 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700681 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200682 peer_connection_factory_->CreateVideoTrack(
683 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700684 if (!local_video_renderer_) {
685 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
686 }
687 return track;
688 }
689
690 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100691 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800692 std::unique_ptr<SessionDescriptionInterface> desc =
693 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700694 if (received_sdp_munger_) {
695 received_sdp_munger_(desc->description());
696 }
697
698 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
699 // Setting a remote description may have changed the number of receivers,
700 // so reset the receiver observers.
701 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800702 if (remote_offer_handler_) {
703 remote_offer_handler_();
704 }
deadbeef1dcb1642017-03-29 21:08:16 -0700705 auto answer = CreateAnswer();
706 ASSERT_NE(nullptr, answer);
707 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
708 }
709
710 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100711 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800712 std::unique_ptr<SessionDescriptionInterface> desc =
713 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700714 if (received_sdp_munger_) {
715 received_sdp_munger_(desc->description());
716 }
717
718 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
719 // Set the RtpReceiverObserver after receivers are created.
720 ResetRtpReceiverObservers();
721 }
722
723 // Returns null on failure.
724 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
725 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
726 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
727 pc()->CreateOffer(observer, offer_answer_options_);
728 return WaitForDescriptionFromObserver(observer);
729 }
730
731 // Returns null on failure.
732 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
733 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
734 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
735 pc()->CreateAnswer(observer, offer_answer_options_);
736 return WaitForDescriptionFromObserver(observer);
737 }
738
739 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100740 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700741 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
742 if (!observer->result()) {
743 return nullptr;
744 }
745 auto description = observer->MoveDescription();
746 if (generated_sdp_munger_) {
747 generated_sdp_munger_(description->description());
748 }
749 return description;
750 }
751
752 // Setting the local description and sending the SDP message over the fake
753 // signaling channel are combined into the same method because the SDP
754 // message needs to be sent as soon as SetLocalDescription finishes, without
755 // waiting for the observer to be called. This ensures that ICE candidates
756 // don't outrace the description.
757 bool SetLocalDescriptionAndSendSdpMessage(
758 std::unique_ptr<SessionDescriptionInterface> desc) {
759 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
760 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100761 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800762 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700763 std::string sdp;
764 EXPECT_TRUE(desc->ToString(&sdp));
765 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800766 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
767 RemoveUnusedVideoRenderers();
768 }
deadbeef1dcb1642017-03-29 21:08:16 -0700769 // As mentioned above, we need to send the message immediately after
770 // SetLocalDescription.
771 SendSdpMessage(type, sdp);
772 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
773 return true;
774 }
775
776 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
777 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
778 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100779 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700780 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800781 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
782 RemoveUnusedVideoRenderers();
783 }
deadbeef1dcb1642017-03-29 21:08:16 -0700784 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
785 return observer->result();
786 }
787
Seth Hampson2f0d7022018-02-20 11:54:42 -0800788 // This is a work around to remove unused fake_video_renderers from
789 // transceivers that have either stopped or are no longer receiving.
790 void RemoveUnusedVideoRenderers() {
791 auto transceivers = pc()->GetTransceivers();
792 for (auto& transceiver : transceivers) {
793 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
794 continue;
795 }
796 // Remove fake video renderers from any stopped transceivers.
797 if (transceiver->stopped()) {
798 auto it =
799 fake_video_renderers_.find(transceiver->receiver()->track()->id());
800 if (it != fake_video_renderers_.end()) {
801 fake_video_renderers_.erase(it);
802 }
803 }
804 // Remove fake video renderers from any transceivers that are no longer
805 // receiving.
806 if ((transceiver->current_direction() &&
807 !webrtc::RtpTransceiverDirectionHasRecv(
808 *transceiver->current_direction()))) {
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 }
816 }
817
deadbeef1dcb1642017-03-29 21:08:16 -0700818 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
819 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800820 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700821 if (signaling_delay_ms_ == 0) {
822 RelaySdpMessageIfReceiverExists(type, msg);
823 } else {
824 invoker_.AsyncInvokeDelayed<void>(
825 RTC_FROM_HERE, rtc::Thread::Current(),
826 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
827 this, type, msg),
828 signaling_delay_ms_);
829 }
830 }
831
Steve Antona3a92c22017-12-07 10:27:41 -0800832 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700833 if (signaling_message_receiver_) {
834 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
835 }
836 }
837
838 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
839 // default).
840 void SendIceMessage(const std::string& sdp_mid,
841 int sdp_mline_index,
842 const std::string& msg) {
843 if (signaling_delay_ms_ == 0) {
844 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
845 } else {
846 invoker_.AsyncInvokeDelayed<void>(
847 RTC_FROM_HERE, rtc::Thread::Current(),
848 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
849 this, sdp_mid, sdp_mline_index, msg),
850 signaling_delay_ms_);
851 }
852 }
853
854 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
855 int sdp_mline_index,
856 const std::string& msg) {
857 if (signaling_message_receiver_) {
858 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
859 msg);
860 }
861 }
862
863 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800864 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
865 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700866 HandleIncomingOffer(msg);
867 } else {
868 HandleIncomingAnswer(msg);
869 }
870 }
871
872 void ReceiveIceMessage(const std::string& sdp_mid,
873 int sdp_mline_index,
874 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100875 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700876 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
877 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
878 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
879 }
880
881 // PeerConnectionObserver callbacks.
882 void OnSignalingChange(
883 webrtc::PeerConnectionInterface::SignalingState new_state) override {
884 EXPECT_EQ(pc()->signaling_state(), new_state);
885 }
Steve Anton15324772018-01-16 10:26:49 -0800886 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
887 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
888 streams) override {
889 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
890 rtc::scoped_refptr<VideoTrackInterface> video_track(
891 static_cast<VideoTrackInterface*>(receiver->track().get()));
892 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700893 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800894 fake_video_renderers_[video_track->id()] =
895 rtc::MakeUnique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700896 }
897 }
Steve Anton15324772018-01-16 10:26:49 -0800898 void OnRemoveTrack(
899 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
900 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
901 auto it = fake_video_renderers_.find(receiver->track()->id());
902 RTC_DCHECK(it != fake_video_renderers_.end());
903 fake_video_renderers_.erase(it);
904 }
905 }
deadbeef1dcb1642017-03-29 21:08:16 -0700906 void OnRenegotiationNeeded() override {}
907 void OnIceConnectionChange(
908 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
909 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700910 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700911 }
912 void OnIceGatheringChange(
913 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700914 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700915 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700916 }
917 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100918 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700919
920 std::string ice_sdp;
921 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700922 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700923 // Remote party may be deleted.
924 return;
925 }
926 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
927 }
928 void OnDataChannel(
929 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100930 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700931 data_channel_ = data_channel;
932 data_observer_.reset(new MockDataChannelObserver(data_channel));
933 }
934
deadbeef1dcb1642017-03-29 21:08:16 -0700935 std::string debug_name_;
936
937 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
938
939 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
940 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
941 peer_connection_factory_;
942
Steve Antonede9ca52017-10-16 13:04:27 -0700943 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700944 // Needed to keep track of number of frames sent.
945 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
946 // Needed to keep track of number of frames received.
947 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
948 fake_video_renderers_;
949 // Needed to ensure frames aren't received for removed tracks.
950 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
951 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -0700952
953 // For remote peer communication.
954 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
955 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700956 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-29 21:08:16 -0700957
Niels Möller5c7efe72018-05-11 10:34:46 +0200958 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -0700959 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +0200960 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
961 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -0700962 // |local_video_renderer_| attached to the first created local video track.
963 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
964
Seth Hampson2f0d7022018-02-20 11:54:42 -0800965 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -0700966 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
967 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
968 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800969 std::function<void()> remote_offer_handler_;
deadbeef1dcb1642017-03-29 21:08:16 -0700970
971 rtc::scoped_refptr<DataChannelInterface> data_channel_;
972 std::unique_ptr<MockDataChannelObserver> data_observer_;
973
974 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
975
Steve Antonede9ca52017-10-16 13:04:27 -0700976 std::vector<PeerConnectionInterface::IceConnectionState>
977 ice_connection_state_history_;
978 std::vector<PeerConnectionInterface::IceGatheringState>
979 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700980
Qingsi Wang7685e862018-06-11 20:15:46 -0700981 webrtc::FakeRtcEventLogFactory* event_log_factory_;
982
deadbeef1dcb1642017-03-29 21:08:16 -0700983 rtc::AsyncInvoker invoker_;
984
Seth Hampson2f0d7022018-02-20 11:54:42 -0800985 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -0700986};
987
Elad Alon99c3fe52017-10-13 16:29:40 +0200988class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
989 public:
990 virtual ~MockRtcEventLogOutput() = default;
991 MOCK_CONST_METHOD0(IsActive, bool());
992 MOCK_METHOD1(Write, bool(const std::string&));
993};
994
Seth Hampson2f0d7022018-02-20 11:54:42 -0800995// This helper object is used for both specifying how many audio/video frames
996// are expected to be received for a caller/callee. It provides helper functions
997// to specify these expectations. The object initially starts in a state of no
998// expectations.
999class MediaExpectations {
1000 public:
1001 enum ExpectFrames {
1002 kExpectSomeFrames,
1003 kExpectNoFrames,
1004 kNoExpectation,
1005 };
1006
1007 void ExpectBidirectionalAudioAndVideo() {
1008 ExpectBidirectionalAudio();
1009 ExpectBidirectionalVideo();
1010 }
1011
1012 void ExpectBidirectionalAudio() {
1013 CallerExpectsSomeAudio();
1014 CalleeExpectsSomeAudio();
1015 }
1016
1017 void ExpectNoAudio() {
1018 CallerExpectsNoAudio();
1019 CalleeExpectsNoAudio();
1020 }
1021
1022 void ExpectBidirectionalVideo() {
1023 CallerExpectsSomeVideo();
1024 CalleeExpectsSomeVideo();
1025 }
1026
1027 void ExpectNoVideo() {
1028 CallerExpectsNoVideo();
1029 CalleeExpectsNoVideo();
1030 }
1031
1032 void CallerExpectsSomeAudioAndVideo() {
1033 CallerExpectsSomeAudio();
1034 CallerExpectsSomeVideo();
1035 }
1036
1037 void CalleeExpectsSomeAudioAndVideo() {
1038 CalleeExpectsSomeAudio();
1039 CalleeExpectsSomeVideo();
1040 }
1041
1042 // Caller's audio functions.
1043 void CallerExpectsSomeAudio(
1044 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1045 caller_audio_expectation_ = kExpectSomeFrames;
1046 caller_audio_frames_expected_ = expected_audio_frames;
1047 }
1048
1049 void CallerExpectsNoAudio() {
1050 caller_audio_expectation_ = kExpectNoFrames;
1051 caller_audio_frames_expected_ = 0;
1052 }
1053
1054 // Caller's video functions.
1055 void CallerExpectsSomeVideo(
1056 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1057 caller_video_expectation_ = kExpectSomeFrames;
1058 caller_video_frames_expected_ = expected_video_frames;
1059 }
1060
1061 void CallerExpectsNoVideo() {
1062 caller_video_expectation_ = kExpectNoFrames;
1063 caller_video_frames_expected_ = 0;
1064 }
1065
1066 // Callee's audio functions.
1067 void CalleeExpectsSomeAudio(
1068 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1069 callee_audio_expectation_ = kExpectSomeFrames;
1070 callee_audio_frames_expected_ = expected_audio_frames;
1071 }
1072
1073 void CalleeExpectsNoAudio() {
1074 callee_audio_expectation_ = kExpectNoFrames;
1075 callee_audio_frames_expected_ = 0;
1076 }
1077
1078 // Callee's video functions.
1079 void CalleeExpectsSomeVideo(
1080 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1081 callee_video_expectation_ = kExpectSomeFrames;
1082 callee_video_frames_expected_ = expected_video_frames;
1083 }
1084
1085 void CalleeExpectsNoVideo() {
1086 callee_video_expectation_ = kExpectNoFrames;
1087 callee_video_frames_expected_ = 0;
1088 }
1089
1090 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1091 ExpectFrames caller_video_expectation_ = kNoExpectation;
1092 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1093 ExpectFrames callee_video_expectation_ = kNoExpectation;
1094 int caller_audio_frames_expected_ = 0;
1095 int caller_video_frames_expected_ = 0;
1096 int callee_audio_frames_expected_ = 0;
1097 int callee_video_frames_expected_ = 0;
1098};
1099
deadbeef1dcb1642017-03-29 21:08:16 -07001100// Tests two PeerConnections connecting to each other end-to-end, using a
1101// virtual network, fake A/V capture and fake encoder/decoders. The
1102// PeerConnections share the threads/socket servers, but use separate versions
1103// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001104class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001105 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001106 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1107 : sdp_semantics_(sdp_semantics),
1108 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001109 fss_(new rtc::FirewallSocketServer(ss_.get())),
1110 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-29 21:08:16 -07001111 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001112 network_thread_->SetName("PCNetworkThread", this);
1113 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001114 RTC_CHECK(network_thread_->Start());
1115 RTC_CHECK(worker_thread_->Start());
1116 }
1117
Seth Hampson2f0d7022018-02-20 11:54:42 -08001118 ~PeerConnectionIntegrationBaseTest() {
deadbeef1dcb1642017-03-29 21:08:16 -07001119 if (caller_) {
1120 caller_->set_signaling_message_receiver(nullptr);
1121 }
1122 if (callee_) {
1123 callee_->set_signaling_message_receiver(nullptr);
1124 }
1125 }
1126
1127 bool SignalingStateStable() {
1128 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1129 }
1130
deadbeef71452802017-05-07 17:21:01 -07001131 bool DtlsConnected() {
1132 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1133 // are connected. This is an important distinction. Once we have separate
1134 // ICE and DTLS state, this check needs to use the DTLS state.
1135 return (callee()->ice_connection_state() ==
1136 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1137 callee()->ice_connection_state() ==
1138 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1139 (caller()->ice_connection_state() ==
1140 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1141 caller()->ice_connection_state() ==
1142 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1143 }
1144
Qingsi Wang7685e862018-06-11 20:15:46 -07001145 // When |event_log_factory| is null, the default implementation of the event
1146 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001147 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1148 const std::string& debug_name,
1149 const MediaConstraintsInterface* constraints,
1150 const PeerConnectionFactory::Options* options,
1151 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001152 webrtc::PeerConnectionDependencies dependencies,
1153 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001154 RTCConfiguration modified_config;
1155 if (config) {
1156 modified_config = *config;
1157 }
Steve Anton3acffc32018-04-12 17:21:03 -07001158 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001159 if (!dependencies.cert_generator) {
1160 dependencies.cert_generator =
1161 rtc::MakeUnique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001162 }
1163 std::unique_ptr<PeerConnectionWrapper> client(
1164 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001165
Seth Hampson2f0d7022018-02-20 11:54:42 -08001166 if (!client->Init(constraints, options, &modified_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001167 std::move(dependencies), network_thread_.get(),
Qingsi Wang7685e862018-06-11 20:15:46 -07001168 worker_thread_.get(), std::move(event_log_factory))) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001169 return nullptr;
1170 }
1171 return client;
1172 }
1173
Qingsi Wang7685e862018-06-11 20:15:46 -07001174 std::unique_ptr<PeerConnectionWrapper>
1175 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1176 const std::string& debug_name,
1177 const MediaConstraintsInterface* constraints,
1178 const PeerConnectionFactory::Options* options,
1179 const RTCConfiguration* config,
1180 webrtc::PeerConnectionDependencies dependencies) {
1181 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1182 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
1183 return CreatePeerConnectionWrapper(debug_name, constraints, options, config,
1184 std::move(dependencies),
1185 std::move(event_log_factory));
1186 }
1187
deadbeef1dcb1642017-03-29 21:08:16 -07001188 bool CreatePeerConnectionWrappers() {
1189 return CreatePeerConnectionWrappersWithConfig(
1190 PeerConnectionInterface::RTCConfiguration(),
1191 PeerConnectionInterface::RTCConfiguration());
1192 }
1193
Steve Anton3acffc32018-04-12 17:21:03 -07001194 bool CreatePeerConnectionWrappersWithSdpSemantics(
1195 SdpSemantics caller_semantics,
1196 SdpSemantics callee_semantics) {
1197 // Can't specify the sdp_semantics in the passed-in configuration since it
1198 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1199 // stored in sdp_semantics_. So get around this by modifying the instance
1200 // variable before calling CreatePeerConnectionWrapper for the caller and
1201 // callee PeerConnections.
1202 SdpSemantics original_semantics = sdp_semantics_;
1203 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001204 caller_ = CreatePeerConnectionWrapper(
1205 "Caller", nullptr, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001206 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001207 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001208 callee_ = CreatePeerConnectionWrapper(
1209 "Callee", nullptr, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001210 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001211 sdp_semantics_ = original_semantics;
1212 return caller_ && callee_;
1213 }
1214
deadbeef1dcb1642017-03-29 21:08:16 -07001215 bool CreatePeerConnectionWrappersWithConstraints(
1216 MediaConstraintsInterface* caller_constraints,
1217 MediaConstraintsInterface* callee_constraints) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001218 caller_ = CreatePeerConnectionWrapper(
1219 "Caller", caller_constraints, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001220 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001221 callee_ = CreatePeerConnectionWrapper(
1222 "Callee", callee_constraints, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001223 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001224
deadbeef1dcb1642017-03-29 21:08:16 -07001225 return caller_ && callee_;
1226 }
1227
1228 bool CreatePeerConnectionWrappersWithConfig(
1229 const PeerConnectionInterface::RTCConfiguration& caller_config,
1230 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001231 caller_ = CreatePeerConnectionWrapper(
1232 "Caller", nullptr, nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001233 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001234 callee_ = CreatePeerConnectionWrapper(
1235 "Callee", nullptr, nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001236 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001237 return caller_ && callee_;
1238 }
1239
1240 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1241 const PeerConnectionInterface::RTCConfiguration& caller_config,
1242 webrtc::PeerConnectionDependencies caller_dependencies,
1243 const PeerConnectionInterface::RTCConfiguration& callee_config,
1244 webrtc::PeerConnectionDependencies callee_dependencies) {
1245 caller_ =
1246 CreatePeerConnectionWrapper("Caller", nullptr, nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001247 std::move(caller_dependencies), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001248 callee_ =
1249 CreatePeerConnectionWrapper("Callee", nullptr, nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001250 std::move(callee_dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001251 return caller_ && callee_;
1252 }
1253
1254 bool CreatePeerConnectionWrappersWithOptions(
1255 const PeerConnectionFactory::Options& caller_options,
1256 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001257 caller_ = CreatePeerConnectionWrapper(
1258 "Caller", nullptr, &caller_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001259 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001260 callee_ = CreatePeerConnectionWrapper(
1261 "Callee", nullptr, &callee_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001262 webrtc::PeerConnectionDependencies(nullptr), nullptr);
1263 return caller_ && callee_;
1264 }
1265
1266 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1267 PeerConnectionInterface::RTCConfiguration default_config;
1268 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
1269 "Caller", nullptr, nullptr, &default_config,
1270 webrtc::PeerConnectionDependencies(nullptr));
1271 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
1272 "Callee", nullptr, nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001273 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001274 return caller_ && callee_;
1275 }
1276
Seth Hampson2f0d7022018-02-20 11:54:42 -08001277 std::unique_ptr<PeerConnectionWrapper>
1278 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001279 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1280 new FakeRTCCertificateGenerator());
1281 cert_generator->use_alternate_key();
1282
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001283 webrtc::PeerConnectionDependencies dependencies(nullptr);
1284 dependencies.cert_generator = std::move(cert_generator);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001285 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001286 std::move(dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001287 }
1288
1289 // Once called, SDP blobs and ICE candidates will be automatically signaled
1290 // between PeerConnections.
1291 void ConnectFakeSignaling() {
1292 caller_->set_signaling_message_receiver(callee_.get());
1293 callee_->set_signaling_message_receiver(caller_.get());
1294 }
1295
Steve Antonede9ca52017-10-16 13:04:27 -07001296 // Once called, SDP blobs will be automatically signaled between
1297 // PeerConnections. Note that ICE candidates will not be signaled unless they
1298 // are in the exchanged SDP blobs.
1299 void ConnectFakeSignalingForSdpOnly() {
1300 ConnectFakeSignaling();
1301 SetSignalIceCandidates(false);
1302 }
1303
deadbeef1dcb1642017-03-29 21:08:16 -07001304 void SetSignalingDelayMs(int delay_ms) {
1305 caller_->set_signaling_delay_ms(delay_ms);
1306 callee_->set_signaling_delay_ms(delay_ms);
1307 }
1308
Steve Antonede9ca52017-10-16 13:04:27 -07001309 void SetSignalIceCandidates(bool signal) {
1310 caller_->set_signal_ice_candidates(signal);
1311 callee_->set_signal_ice_candidates(signal);
1312 }
1313
deadbeef1dcb1642017-03-29 21:08:16 -07001314 // Messages may get lost on the unreliable DataChannel, so we send multiple
1315 // times to avoid test flakiness.
1316 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1317 const std::string& data,
1318 int retries) {
1319 for (int i = 0; i < retries; ++i) {
1320 dc->Send(DataBuffer(data));
1321 }
1322 }
1323
1324 rtc::Thread* network_thread() { return network_thread_.get(); }
1325
1326 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1327
1328 PeerConnectionWrapper* caller() { return caller_.get(); }
1329
1330 // Set the |caller_| to the |wrapper| passed in and return the
1331 // original |caller_|.
1332 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1333 PeerConnectionWrapper* wrapper) {
1334 PeerConnectionWrapper* old = caller_.release();
1335 caller_.reset(wrapper);
1336 return old;
1337 }
1338
1339 PeerConnectionWrapper* callee() { return callee_.get(); }
1340
1341 // Set the |callee_| to the |wrapper| passed in and return the
1342 // original |callee_|.
1343 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1344 PeerConnectionWrapper* wrapper) {
1345 PeerConnectionWrapper* old = callee_.release();
1346 callee_.reset(wrapper);
1347 return old;
1348 }
1349
Steve Antonede9ca52017-10-16 13:04:27 -07001350 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1351
Seth Hampson2f0d7022018-02-20 11:54:42 -08001352 // Expects the provided number of new frames to be received within
1353 // kMaxWaitForFramesMs. The new expected frames are specified in
1354 // |media_expectations|. Returns false if any of the expectations were
1355 // not met.
1356 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1357 // First initialize the expected frame counts based upon the current
1358 // frame count.
1359 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1360 if (media_expectations.caller_audio_expectation_ ==
1361 MediaExpectations::kExpectSomeFrames) {
1362 total_caller_audio_frames_expected +=
1363 media_expectations.caller_audio_frames_expected_;
1364 }
1365 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001366 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001367 if (media_expectations.caller_video_expectation_ ==
1368 MediaExpectations::kExpectSomeFrames) {
1369 total_caller_video_frames_expected +=
1370 media_expectations.caller_video_frames_expected_;
1371 }
1372 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1373 if (media_expectations.callee_audio_expectation_ ==
1374 MediaExpectations::kExpectSomeFrames) {
1375 total_callee_audio_frames_expected +=
1376 media_expectations.callee_audio_frames_expected_;
1377 }
1378 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001379 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001380 if (media_expectations.callee_video_expectation_ ==
1381 MediaExpectations::kExpectSomeFrames) {
1382 total_callee_video_frames_expected +=
1383 media_expectations.callee_video_frames_expected_;
1384 }
deadbeef1dcb1642017-03-29 21:08:16 -07001385
Seth Hampson2f0d7022018-02-20 11:54:42 -08001386 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001387 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001388 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001389 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001390 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001391 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001392 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001393 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001394 total_callee_video_frames_expected,
1395 kMaxWaitForFramesMs);
1396 bool expectations_correct =
1397 caller()->audio_frames_received() >=
1398 total_caller_audio_frames_expected &&
1399 caller()->min_video_frames_received_per_track() >=
1400 total_caller_video_frames_expected &&
1401 callee()->audio_frames_received() >=
1402 total_callee_audio_frames_expected &&
1403 callee()->min_video_frames_received_per_track() >=
1404 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001405
Seth Hampson2f0d7022018-02-20 11:54:42 -08001406 // After the combined wait, print out a more detailed message upon
1407 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001408 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001409 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001410 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001411 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001412 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001413 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001414 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001415 total_callee_video_frames_expected);
1416
1417 // We want to make sure nothing unexpected was received.
1418 if (media_expectations.caller_audio_expectation_ ==
1419 MediaExpectations::kExpectNoFrames) {
1420 EXPECT_EQ(caller()->audio_frames_received(),
1421 total_caller_audio_frames_expected);
1422 if (caller()->audio_frames_received() !=
1423 total_caller_audio_frames_expected) {
1424 expectations_correct = false;
1425 }
1426 }
1427 if (media_expectations.caller_video_expectation_ ==
1428 MediaExpectations::kExpectNoFrames) {
1429 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1430 total_caller_video_frames_expected);
1431 if (caller()->min_video_frames_received_per_track() !=
1432 total_caller_video_frames_expected) {
1433 expectations_correct = false;
1434 }
1435 }
1436 if (media_expectations.callee_audio_expectation_ ==
1437 MediaExpectations::kExpectNoFrames) {
1438 EXPECT_EQ(callee()->audio_frames_received(),
1439 total_callee_audio_frames_expected);
1440 if (callee()->audio_frames_received() !=
1441 total_callee_audio_frames_expected) {
1442 expectations_correct = false;
1443 }
1444 }
1445 if (media_expectations.callee_video_expectation_ ==
1446 MediaExpectations::kExpectNoFrames) {
1447 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1448 total_callee_video_frames_expected);
1449 if (callee()->min_video_frames_received_per_track() !=
1450 total_callee_video_frames_expected) {
1451 expectations_correct = false;
1452 }
1453 }
1454 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001455 }
1456
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001457 void TestNegotiatedCipherSuite(
1458 const PeerConnectionFactory::Options& caller_options,
1459 const PeerConnectionFactory::Options& callee_options,
1460 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001461 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1462 callee_options));
1463 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
1464 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
1465 caller()->pc()->RegisterUMAObserver(caller_observer);
1466 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001467 caller()->AddAudioVideoTracks();
1468 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001469 caller()->CreateAndSetAndSignalOffer();
1470 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1471 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001472 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001473 EXPECT_EQ(
1474 1, caller_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher,
1475 expected_cipher_suite));
1476 caller()->pc()->RegisterUMAObserver(nullptr);
1477 }
1478
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001479 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1480 bool remote_gcm_enabled,
1481 int expected_cipher_suite) {
1482 PeerConnectionFactory::Options caller_options;
1483 caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
1484 PeerConnectionFactory::Options callee_options;
1485 callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
1486 TestNegotiatedCipherSuite(caller_options, callee_options,
1487 expected_cipher_suite);
1488 }
1489
Seth Hampson2f0d7022018-02-20 11:54:42 -08001490 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001491 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001492
deadbeef1dcb1642017-03-29 21:08:16 -07001493 private:
1494 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001495 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001496 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001497 // |network_thread_| and |worker_thread_| are used by both
1498 // |caller_| and |callee_| so they must be destroyed
1499 // later.
1500 std::unique_ptr<rtc::Thread> network_thread_;
1501 std::unique_ptr<rtc::Thread> worker_thread_;
1502 std::unique_ptr<PeerConnectionWrapper> caller_;
1503 std::unique_ptr<PeerConnectionWrapper> callee_;
1504};
1505
Seth Hampson2f0d7022018-02-20 11:54:42 -08001506class PeerConnectionIntegrationTest
1507 : public PeerConnectionIntegrationBaseTest,
1508 public ::testing::WithParamInterface<SdpSemantics> {
1509 protected:
1510 PeerConnectionIntegrationTest()
1511 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1512};
1513
1514class PeerConnectionIntegrationTestPlanB
1515 : public PeerConnectionIntegrationBaseTest {
1516 protected:
1517 PeerConnectionIntegrationTestPlanB()
1518 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1519};
1520
1521class PeerConnectionIntegrationTestUnifiedPlan
1522 : public PeerConnectionIntegrationBaseTest {
1523 protected:
1524 PeerConnectionIntegrationTestUnifiedPlan()
1525 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1526};
1527
deadbeef1dcb1642017-03-29 21:08:16 -07001528// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1529// includes testing that the callback is invoked if an observer is connected
1530// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001531TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001532 RtpReceiverObserverOnFirstPacketReceived) {
1533 ASSERT_TRUE(CreatePeerConnectionWrappers());
1534 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001535 caller()->AddAudioVideoTracks();
1536 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001537 // Start offer/answer exchange and wait for it to complete.
1538 caller()->CreateAndSetAndSignalOffer();
1539 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1540 // Should be one receiver each for audio/video.
1541 EXPECT_EQ(2, caller()->rtp_receiver_observers().size());
1542 EXPECT_EQ(2, callee()->rtp_receiver_observers().size());
1543 // Wait for all "first packet received" callbacks to be fired.
1544 EXPECT_TRUE_WAIT(
1545 std::all_of(caller()->rtp_receiver_observers().begin(),
1546 caller()->rtp_receiver_observers().end(),
1547 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1548 return o->first_packet_received();
1549 }),
1550 kMaxWaitForFramesMs);
1551 EXPECT_TRUE_WAIT(
1552 std::all_of(callee()->rtp_receiver_observers().begin(),
1553 callee()->rtp_receiver_observers().end(),
1554 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1555 return o->first_packet_received();
1556 }),
1557 kMaxWaitForFramesMs);
1558 // If new observers are set after the first packet was already received, the
1559 // callback should still be invoked.
1560 caller()->ResetRtpReceiverObservers();
1561 callee()->ResetRtpReceiverObservers();
1562 EXPECT_EQ(2, caller()->rtp_receiver_observers().size());
1563 EXPECT_EQ(2, callee()->rtp_receiver_observers().size());
1564 EXPECT_TRUE(
1565 std::all_of(caller()->rtp_receiver_observers().begin(),
1566 caller()->rtp_receiver_observers().end(),
1567 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1568 return o->first_packet_received();
1569 }));
1570 EXPECT_TRUE(
1571 std::all_of(callee()->rtp_receiver_observers().begin(),
1572 callee()->rtp_receiver_observers().end(),
1573 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1574 return o->first_packet_received();
1575 }));
1576}
1577
1578class DummyDtmfObserver : public DtmfSenderObserverInterface {
1579 public:
1580 DummyDtmfObserver() : completed_(false) {}
1581
1582 // Implements DtmfSenderObserverInterface.
1583 void OnToneChange(const std::string& tone) override {
1584 tones_.push_back(tone);
1585 if (tone.empty()) {
1586 completed_ = true;
1587 }
1588 }
1589
1590 const std::vector<std::string>& tones() const { return tones_; }
1591 bool completed() const { return completed_; }
1592
1593 private:
1594 bool completed_;
1595 std::vector<std::string> tones_;
1596};
1597
1598// Assumes |sender| already has an audio track added and the offer/answer
1599// exchange is done.
1600void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1601 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001602 // We should be able to get a DTMF sender from the local sender.
1603 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1604 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1605 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001606 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001607 dtmf_sender->RegisterObserver(&observer);
1608
1609 // Test the DtmfSender object just created.
1610 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1611 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1612
1613 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1614 std::vector<std::string> tones = {"1", "a", ""};
1615 EXPECT_EQ(tones, observer.tones());
1616 dtmf_sender->UnregisterObserver();
1617 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1618}
1619
1620// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1621// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001622TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001623 ASSERT_TRUE(CreatePeerConnectionWrappers());
1624 ConnectFakeSignaling();
1625 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001626 caller()->AddAudioTrack();
1627 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001628 caller()->CreateAndSetAndSignalOffer();
1629 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001630 // DTLS must finish before the DTMF sender can be used reliably.
1631 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001632 TestDtmfFromSenderToReceiver(caller(), callee());
1633 TestDtmfFromSenderToReceiver(callee(), caller());
1634}
1635
1636// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1637// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001638TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001639 ASSERT_TRUE(CreatePeerConnectionWrappers());
1640 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001641 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
1642 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
1643 caller()->pc()->RegisterUMAObserver(caller_observer);
1644
deadbeef1dcb1642017-03-29 21:08:16 -07001645 // Do normal offer/answer and wait for some frames to be received in each
1646 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001647 caller()->AddAudioVideoTracks();
1648 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001649 caller()->CreateAndSetAndSignalOffer();
1650 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001651 MediaExpectations media_expectations;
1652 media_expectations.ExpectBidirectionalAudioAndVideo();
1653 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Harald Alvestrand194939b2018-01-24 16:04:13 +01001654 EXPECT_LE(
1655 1, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1656 webrtc::kEnumCounterKeyProtocolDtls));
1657 EXPECT_EQ(
1658 0, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1659 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001660}
1661
1662// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001663TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001664 PeerConnectionInterface::RTCConfiguration sdes_config;
1665 sdes_config.enable_dtls_srtp.emplace(false);
1666 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1667 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001668 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
1669 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
1670 caller()->pc()->RegisterUMAObserver(caller_observer);
deadbeef1dcb1642017-03-29 21:08:16 -07001671
1672 // Do normal offer/answer and wait for some frames to be received in each
1673 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001674 caller()->AddAudioVideoTracks();
1675 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001676 caller()->CreateAndSetAndSignalOffer();
1677 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001678 MediaExpectations media_expectations;
1679 media_expectations.ExpectBidirectionalAudioAndVideo();
1680 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Harald Alvestrand194939b2018-01-24 16:04:13 +01001681 EXPECT_LE(
1682 1, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1683 webrtc::kEnumCounterKeyProtocolSdes));
1684 EXPECT_EQ(
1685 0, caller_observer->GetEnumCounter(webrtc::kEnumCounterKeyProtocol,
1686 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001687}
1688
Steve Anton8c0f7a72017-10-03 10:03:10 -07001689// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1690// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001691TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001692 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1693 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1694 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1695 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1696 return pc->GetRemoteAudioSSLCertificate();
1697 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001698 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1699 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1700 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1701 return pc->GetRemoteAudioSSLCertChain();
1702 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001703
1704 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1705 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1706
1707 // Configure each side with a known certificate so they can be compared later.
1708 PeerConnectionInterface::RTCConfiguration caller_config;
1709 caller_config.enable_dtls_srtp.emplace(true);
1710 caller_config.certificates.push_back(caller_cert);
1711 PeerConnectionInterface::RTCConfiguration callee_config;
1712 callee_config.enable_dtls_srtp.emplace(true);
1713 callee_config.certificates.push_back(callee_cert);
1714 ASSERT_TRUE(
1715 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1716 ConnectFakeSignaling();
1717
1718 // When first initialized, there should not be a remote SSL certificate (and
1719 // calling this method should not crash).
1720 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1721 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001722 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1723 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001724
Steve Anton15324772018-01-16 10:26:49 -08001725 caller()->AddAudioTrack();
1726 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001727 caller()->CreateAndSetAndSignalOffer();
1728 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1729 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1730
1731 // Once DTLS has been connected, each side should return the other's SSL
1732 // certificate when calling GetRemoteAudioSSLCertificate.
1733
1734 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1735 ASSERT_TRUE(caller_remote_cert);
1736 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1737 caller_remote_cert->ToPEMString());
1738
1739 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1740 ASSERT_TRUE(callee_remote_cert);
1741 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1742 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001743
1744 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1745 ASSERT_TRUE(caller_remote_cert_chain);
1746 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1747 auto remote_cert = &caller_remote_cert_chain->Get(0);
1748 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1749 remote_cert->ToPEMString());
1750
1751 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1752 ASSERT_TRUE(callee_remote_cert_chain);
1753 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1754 remote_cert = &callee_remote_cert_chain->Get(0);
1755 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1756 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001757}
1758
deadbeef1dcb1642017-03-29 21:08:16 -07001759// This test sets up a call between two parties with a source resolution of
1760// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001761TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001762 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1763 ASSERT_TRUE(CreatePeerConnectionWrappers());
1764 ConnectFakeSignaling();
1765
Niels Möller5c7efe72018-05-11 10:34:46 +02001766 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1767 webrtc::FakePeriodicVideoSource::Config config;
1768 config.width = 1280;
1769 config.height = 720;
1770 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1771 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07001772
1773 // Do normal offer/answer and wait for at least one frame to be received in
1774 // each direction.
1775 caller()->CreateAndSetAndSignalOffer();
1776 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1777 callee()->min_video_frames_received_per_track() > 0,
1778 kMaxWaitForFramesMs);
1779
1780 // Check rendered aspect ratio.
1781 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1782 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1783 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1784 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1785}
1786
1787// This test sets up an one-way call, with media only from caller to
1788// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001789TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001790 ASSERT_TRUE(CreatePeerConnectionWrappers());
1791 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001792 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001793 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001794 MediaExpectations media_expectations;
1795 media_expectations.CalleeExpectsSomeAudioAndVideo();
1796 media_expectations.CallerExpectsNoAudio();
1797 media_expectations.CallerExpectsNoVideo();
1798 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001799}
1800
1801// This test sets up a audio call initially, with the callee rejecting video
1802// initially. Then later the callee decides to upgrade to audio/video, and
1803// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001804TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001805 ASSERT_TRUE(CreatePeerConnectionWrappers());
1806 ConnectFakeSignaling();
1807 // Initially, offer an audio/video stream from the caller, but refuse to
1808 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001809 caller()->AddAudioVideoTracks();
1810 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001811 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1812 PeerConnectionInterface::RTCOfferAnswerOptions options;
1813 options.offer_to_receive_video = 0;
1814 callee()->SetOfferAnswerOptions(options);
1815 } else {
1816 callee()->SetRemoteOfferHandler([this] {
1817 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1818 });
1819 }
deadbeef1dcb1642017-03-29 21:08:16 -07001820 // Do offer/answer and make sure audio is still received end-to-end.
1821 caller()->CreateAndSetAndSignalOffer();
1822 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001823 {
1824 MediaExpectations media_expectations;
1825 media_expectations.ExpectBidirectionalAudio();
1826 media_expectations.ExpectNoVideo();
1827 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1828 }
deadbeef1dcb1642017-03-29 21:08:16 -07001829 // Sanity check that the callee's description has a rejected video section.
1830 ASSERT_NE(nullptr, callee()->pc()->local_description());
1831 const ContentInfo* callee_video_content =
1832 GetFirstVideoContent(callee()->pc()->local_description()->description());
1833 ASSERT_NE(nullptr, callee_video_content);
1834 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001835
deadbeef1dcb1642017-03-29 21:08:16 -07001836 // Now negotiate with video and ensure negotiation succeeds, with video
1837 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001838 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001839 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1840 PeerConnectionInterface::RTCOfferAnswerOptions options;
1841 options.offer_to_receive_video = 1;
1842 callee()->SetOfferAnswerOptions(options);
1843 } else {
1844 callee()->SetRemoteOfferHandler(nullptr);
1845 caller()->SetRemoteOfferHandler([this] {
1846 // The caller creates a new transceiver to receive video on when receiving
1847 // the offer, but by default it is send only.
1848 auto transceivers = caller()->pc()->GetTransceivers();
1849 ASSERT_EQ(3, transceivers.size());
1850 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1851 transceivers[2]->receiver()->media_type());
1852 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1853 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1854 });
1855 }
deadbeef1dcb1642017-03-29 21:08:16 -07001856 callee()->CreateAndSetAndSignalOffer();
1857 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001858 {
1859 // Expect additional audio frames to be received after the upgrade.
1860 MediaExpectations media_expectations;
1861 media_expectations.ExpectBidirectionalAudioAndVideo();
1862 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1863 }
deadbeef1dcb1642017-03-29 21:08:16 -07001864}
1865
deadbeef4389b4d2017-09-07 09:07:36 -07001866// Simpler than the above test; just add an audio track to an established
1867// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001868TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07001869 ASSERT_TRUE(CreatePeerConnectionWrappers());
1870 ConnectFakeSignaling();
1871 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08001872 caller()->AddVideoTrack();
1873 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001874 caller()->CreateAndSetAndSignalOffer();
1875 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1876 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001877 caller()->AddAudioTrack();
1878 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001879 caller()->CreateAndSetAndSignalOffer();
1880 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1881 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001882 MediaExpectations media_expectations;
1883 media_expectations.ExpectBidirectionalAudioAndVideo();
1884 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07001885}
1886
deadbeef1dcb1642017-03-29 21:08:16 -07001887// This test sets up a call that's transferred to a new caller with a different
1888// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001889TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07001890 ASSERT_TRUE(CreatePeerConnectionWrappers());
1891 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001892 caller()->AddAudioVideoTracks();
1893 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001894 caller()->CreateAndSetAndSignalOffer();
1895 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1896
1897 // Keep the original peer around which will still send packets to the
1898 // receiving client. These SRTP packets will be dropped.
1899 std::unique_ptr<PeerConnectionWrapper> original_peer(
1900 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001901 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001902 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1903 // directly above.
1904 original_peer->pc()->Close();
1905
1906 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001907 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001908 caller()->CreateAndSetAndSignalOffer();
1909 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1910 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001911 MediaExpectations media_expectations;
1912 media_expectations.ExpectBidirectionalAudioAndVideo();
1913 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001914}
1915
1916// This test sets up a call that's transferred to a new callee with a different
1917// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001918TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07001919 ASSERT_TRUE(CreatePeerConnectionWrappers());
1920 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001921 caller()->AddAudioVideoTracks();
1922 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001923 caller()->CreateAndSetAndSignalOffer();
1924 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1925
1926 // Keep the original peer around which will still send packets to the
1927 // receiving client. These SRTP packets will be dropped.
1928 std::unique_ptr<PeerConnectionWrapper> original_peer(
1929 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001930 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001931 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1932 // directly above.
1933 original_peer->pc()->Close();
1934
1935 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001936 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001937 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
1938 caller()->CreateAndSetAndSignalOffer();
1939 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1940 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001941 MediaExpectations media_expectations;
1942 media_expectations.ExpectBidirectionalAudioAndVideo();
1943 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001944}
1945
1946// This test sets up a non-bundled call and negotiates bundling at the same
1947// time as starting an ICE restart. When bundling is in effect in the restart,
1948// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001949TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07001950 ASSERT_TRUE(CreatePeerConnectionWrappers());
1951 ConnectFakeSignaling();
1952
Steve Anton15324772018-01-16 10:26:49 -08001953 caller()->AddAudioVideoTracks();
1954 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001955 // Remove the bundle group from the SDP received by the callee.
1956 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
1957 desc->RemoveGroupByName("BUNDLE");
1958 });
1959 caller()->CreateAndSetAndSignalOffer();
1960 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001961 {
1962 MediaExpectations media_expectations;
1963 media_expectations.ExpectBidirectionalAudioAndVideo();
1964 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1965 }
deadbeef1dcb1642017-03-29 21:08:16 -07001966 // Now stop removing the BUNDLE group, and trigger an ICE restart.
1967 callee()->SetReceivedSdpMunger(nullptr);
1968 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
1969 caller()->CreateAndSetAndSignalOffer();
1970 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1971
1972 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001973 {
1974 MediaExpectations media_expectations;
1975 media_expectations.ExpectBidirectionalAudioAndVideo();
1976 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1977 }
deadbeef1dcb1642017-03-29 21:08:16 -07001978}
1979
1980// Test CVO (Coordination of Video Orientation). If a video source is rotated
1981// and both peers support the CVO RTP header extension, the actual video frames
1982// don't need to be encoded in different resolutions, since the rotation is
1983// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001984TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07001985 ASSERT_TRUE(CreatePeerConnectionWrappers());
1986 ConnectFakeSignaling();
1987 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08001988 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07001989 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08001990 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07001991 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
1992
1993 // Wait for video frames to be received by both sides.
1994 caller()->CreateAndSetAndSignalOffer();
1995 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1996 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1997 callee()->min_video_frames_received_per_track() > 0,
1998 kMaxWaitForFramesMs);
1999
2000 // Ensure that the aspect ratio is unmodified.
2001 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2002 // not just assumed.
2003 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2004 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2005 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2006 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2007 // Ensure that the CVO bits were surfaced to the renderer.
2008 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2009 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2010}
2011
2012// Test that when the CVO extension isn't supported, video is rotated the
2013// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002014TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002015 ASSERT_TRUE(CreatePeerConnectionWrappers());
2016 ConnectFakeSignaling();
2017 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002018 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002019 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002020 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002021 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2022
2023 // Remove the CVO extension from the offered SDP.
2024 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2025 cricket::VideoContentDescription* video =
2026 GetFirstVideoContentDescription(desc);
2027 video->ClearRtpHeaderExtensions();
2028 });
2029 // Wait for video frames to be received by both sides.
2030 caller()->CreateAndSetAndSignalOffer();
2031 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2032 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2033 callee()->min_video_frames_received_per_track() > 0,
2034 kMaxWaitForFramesMs);
2035
2036 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2037 // rotation.
2038 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2039 // not just assumed.
2040 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2041 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2042 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2043 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2044 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2045 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2046 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2047}
2048
deadbeef1dcb1642017-03-29 21:08:16 -07002049// Test that if the answerer rejects the audio m= section, no audio is sent or
2050// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002051TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002052 ASSERT_TRUE(CreatePeerConnectionWrappers());
2053 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002054 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002055 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2056 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2057 // it will reject the audio m= section completely.
2058 PeerConnectionInterface::RTCOfferAnswerOptions options;
2059 options.offer_to_receive_audio = 0;
2060 callee()->SetOfferAnswerOptions(options);
2061 } else {
2062 // Stopping the audio RtpTransceiver will cause the media section to be
2063 // rejected in the answer.
2064 callee()->SetRemoteOfferHandler([this] {
2065 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2066 });
2067 }
Steve Anton15324772018-01-16 10:26:49 -08002068 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002069 // Do offer/answer and wait for successful end-to-end video frames.
2070 caller()->CreateAndSetAndSignalOffer();
2071 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002072 MediaExpectations media_expectations;
2073 media_expectations.ExpectBidirectionalVideo();
2074 media_expectations.ExpectNoAudio();
2075 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2076
deadbeef1dcb1642017-03-29 21:08:16 -07002077 // Sanity check that the callee's description has a rejected audio section.
2078 ASSERT_NE(nullptr, callee()->pc()->local_description());
2079 const ContentInfo* callee_audio_content =
2080 GetFirstAudioContent(callee()->pc()->local_description()->description());
2081 ASSERT_NE(nullptr, callee_audio_content);
2082 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002083 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2084 // The caller's transceiver should have stopped after receiving the answer.
2085 EXPECT_TRUE(caller()
2086 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2087 ->stopped());
2088 }
deadbeef1dcb1642017-03-29 21:08:16 -07002089}
2090
2091// Test that if the answerer rejects the video m= section, no video is sent or
2092// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002093TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002094 ASSERT_TRUE(CreatePeerConnectionWrappers());
2095 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002096 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002097 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2098 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2099 // it will reject the video m= section completely.
2100 PeerConnectionInterface::RTCOfferAnswerOptions options;
2101 options.offer_to_receive_video = 0;
2102 callee()->SetOfferAnswerOptions(options);
2103 } else {
2104 // Stopping the video RtpTransceiver will cause the media section to be
2105 // rejected in the answer.
2106 callee()->SetRemoteOfferHandler([this] {
2107 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2108 });
2109 }
Steve Anton15324772018-01-16 10:26:49 -08002110 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002111 // Do offer/answer and wait for successful end-to-end audio frames.
2112 caller()->CreateAndSetAndSignalOffer();
2113 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002114 MediaExpectations media_expectations;
2115 media_expectations.ExpectBidirectionalAudio();
2116 media_expectations.ExpectNoVideo();
2117 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2118
deadbeef1dcb1642017-03-29 21:08:16 -07002119 // Sanity check that the callee's description has a rejected video section.
2120 ASSERT_NE(nullptr, callee()->pc()->local_description());
2121 const ContentInfo* callee_video_content =
2122 GetFirstVideoContent(callee()->pc()->local_description()->description());
2123 ASSERT_NE(nullptr, callee_video_content);
2124 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002125 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2126 // The caller's transceiver should have stopped after receiving the answer.
2127 EXPECT_TRUE(caller()
2128 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2129 ->stopped());
2130 }
deadbeef1dcb1642017-03-29 21:08:16 -07002131}
2132
2133// Test that if the answerer rejects both audio and video m= sections, nothing
2134// bad happens.
2135// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2136// test anything but the fact that negotiation succeeds, which doesn't mean
2137// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002138TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002139 ASSERT_TRUE(CreatePeerConnectionWrappers());
2140 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002141 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002142 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2143 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2144 // will reject both audio and video m= sections.
2145 PeerConnectionInterface::RTCOfferAnswerOptions options;
2146 options.offer_to_receive_audio = 0;
2147 options.offer_to_receive_video = 0;
2148 callee()->SetOfferAnswerOptions(options);
2149 } else {
2150 callee()->SetRemoteOfferHandler([this] {
2151 // Stopping all transceivers will cause all media sections to be rejected.
2152 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2153 transceiver->Stop();
2154 }
2155 });
2156 }
deadbeef1dcb1642017-03-29 21:08:16 -07002157 // Do offer/answer and wait for stable signaling state.
2158 caller()->CreateAndSetAndSignalOffer();
2159 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002160
deadbeef1dcb1642017-03-29 21:08:16 -07002161 // Sanity check that the callee's description has rejected m= sections.
2162 ASSERT_NE(nullptr, callee()->pc()->local_description());
2163 const ContentInfo* callee_audio_content =
2164 GetFirstAudioContent(callee()->pc()->local_description()->description());
2165 ASSERT_NE(nullptr, callee_audio_content);
2166 EXPECT_TRUE(callee_audio_content->rejected);
2167 const ContentInfo* callee_video_content =
2168 GetFirstVideoContent(callee()->pc()->local_description()->description());
2169 ASSERT_NE(nullptr, callee_video_content);
2170 EXPECT_TRUE(callee_video_content->rejected);
2171}
2172
2173// This test sets up an audio and video call between two parties. After the
2174// call runs for a while, the caller sends an updated offer with video being
2175// rejected. Once the re-negotiation is done, the video flow should stop and
2176// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002177TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002178 ASSERT_TRUE(CreatePeerConnectionWrappers());
2179 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002180 caller()->AddAudioVideoTracks();
2181 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002182 caller()->CreateAndSetAndSignalOffer();
2183 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002184 {
2185 MediaExpectations media_expectations;
2186 media_expectations.ExpectBidirectionalAudioAndVideo();
2187 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2188 }
deadbeef1dcb1642017-03-29 21:08:16 -07002189 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002190 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2191 caller()->SetGeneratedSdpMunger(
2192 [](cricket::SessionDescription* description) {
2193 for (cricket::ContentInfo& content : description->contents()) {
2194 if (cricket::IsVideoContent(&content)) {
2195 content.rejected = true;
2196 }
2197 }
2198 });
2199 } else {
2200 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2201 }
deadbeef1dcb1642017-03-29 21:08:16 -07002202 caller()->CreateAndSetAndSignalOffer();
2203 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2204
2205 // Sanity check that the caller's description has a rejected video section.
2206 ASSERT_NE(nullptr, caller()->pc()->local_description());
2207 const ContentInfo* caller_video_content =
2208 GetFirstVideoContent(caller()->pc()->local_description()->description());
2209 ASSERT_NE(nullptr, caller_video_content);
2210 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002211 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002212 {
2213 MediaExpectations media_expectations;
2214 media_expectations.ExpectBidirectionalAudio();
2215 media_expectations.ExpectNoVideo();
2216 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2217 }
deadbeef1dcb1642017-03-29 21:08:16 -07002218}
2219
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002220// Do one offer/answer with audio, another that disables it (rejecting the m=
2221// section), and another that re-enables it. Regression test for:
2222// bugs.webrtc.org/6023
2223TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2224 ASSERT_TRUE(CreatePeerConnectionWrappers());
2225 ConnectFakeSignaling();
2226
2227 // Add audio track, do normal offer/answer.
2228 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2229 caller()->CreateLocalAudioTrack();
2230 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2231 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2232 caller()->CreateAndSetAndSignalOffer();
2233 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2234
2235 // Remove audio track, and set offer_to_receive_audio to false to cause the
2236 // m= section to be completely disabled, not just "recvonly".
2237 caller()->pc()->RemoveTrack(sender);
2238 PeerConnectionInterface::RTCOfferAnswerOptions options;
2239 options.offer_to_receive_audio = 0;
2240 caller()->SetOfferAnswerOptions(options);
2241 caller()->CreateAndSetAndSignalOffer();
2242 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2243
2244 // Add the audio track again, expecting negotiation to succeed and frames to
2245 // flow.
2246 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2247 options.offer_to_receive_audio = 1;
2248 caller()->SetOfferAnswerOptions(options);
2249 caller()->CreateAndSetAndSignalOffer();
2250 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2251
2252 MediaExpectations media_expectations;
2253 media_expectations.CalleeExpectsSomeAudio();
2254 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2255}
2256
deadbeef1dcb1642017-03-29 21:08:16 -07002257// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2258// is needed to support legacy endpoints.
2259// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2260// add a test for an end-to-end test without MID signaling either (basically,
2261// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002262TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002263 ASSERT_TRUE(CreatePeerConnectionWrappers());
2264 ConnectFakeSignaling();
2265 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002266 caller()->AddAudioVideoTracks();
2267 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002268 // Remove SSRCs and MSIDs from the received offer SDP.
2269 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002270 caller()->CreateAndSetAndSignalOffer();
2271 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002272 MediaExpectations media_expectations;
2273 media_expectations.ExpectBidirectionalAudioAndVideo();
2274 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002275}
2276
Seth Hampson5897a6e2018-04-03 11:16:33 -07002277// Basic end-to-end test, without SSRC signaling. This means that the track
2278// was created properly and frames are delivered when the MSIDs are communicated
2279// with a=msid lines and no a=ssrc lines.
2280TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2281 EndToEndCallWithoutSsrcSignaling) {
2282 const char kStreamId[] = "streamId";
2283 ASSERT_TRUE(CreatePeerConnectionWrappers());
2284 ConnectFakeSignaling();
2285 // Add just audio tracks.
2286 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2287 callee()->AddAudioTrack();
2288
2289 // Remove SSRCs from the received offer SDP.
2290 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2291 caller()->CreateAndSetAndSignalOffer();
2292 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2293 MediaExpectations media_expectations;
2294 media_expectations.ExpectBidirectionalAudio();
2295 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2296}
2297
Steve Antondf527fd2018-04-27 15:52:03 -07002298// Tests that video flows between multiple video tracks when SSRCs are not
2299// signaled. This exercises the MID RTP header extension which is needed to
2300// demux the incoming video tracks.
2301TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2302 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2303 ASSERT_TRUE(CreatePeerConnectionWrappers());
2304 ConnectFakeSignaling();
2305 caller()->AddVideoTrack();
2306 caller()->AddVideoTrack();
2307 callee()->AddVideoTrack();
2308 callee()->AddVideoTrack();
2309
2310 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2311 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2312 caller()->CreateAndSetAndSignalOffer();
2313 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2314 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2315 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2316
2317 // Expect video to be received in both directions on both tracks.
2318 MediaExpectations media_expectations;
2319 media_expectations.ExpectBidirectionalVideo();
2320 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2321}
2322
deadbeef1dcb1642017-03-29 21:08:16 -07002323// Test that if two video tracks are sent (from caller to callee, in this test),
2324// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002325TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002326 ASSERT_TRUE(CreatePeerConnectionWrappers());
2327 ConnectFakeSignaling();
2328 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002329 caller()->AddAudioVideoTracks();
2330 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002331 caller()->CreateAndSetAndSignalOffer();
2332 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002333 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002334
2335 MediaExpectations media_expectations;
2336 media_expectations.CalleeExpectsSomeAudioAndVideo();
2337 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002338}
2339
2340static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2341 bool first = true;
2342 for (cricket::ContentInfo& content : desc->contents()) {
2343 if (first) {
2344 first = false;
2345 continue;
2346 }
2347 content.bundle_only = true;
2348 }
2349 first = true;
2350 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2351 if (first) {
2352 first = false;
2353 continue;
2354 }
2355 transport.description.ice_ufrag.clear();
2356 transport.description.ice_pwd.clear();
2357 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2358 transport.description.identity_fingerprint.reset(nullptr);
2359 }
2360}
2361
2362// Test that if applying a true "max bundle" offer, which uses ports of 0,
2363// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2364// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2365// successfully and media flows.
2366// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2367// TODO(deadbeef): Won't need this test once we start generating actual
2368// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002369TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002370 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2371 ASSERT_TRUE(CreatePeerConnectionWrappers());
2372 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002373 caller()->AddAudioVideoTracks();
2374 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002375 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2376 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2377 // but the first m= section.
2378 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2379 caller()->CreateAndSetAndSignalOffer();
2380 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002381 MediaExpectations media_expectations;
2382 media_expectations.ExpectBidirectionalAudioAndVideo();
2383 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002384}
2385
2386// Test that we can receive the audio output level from a remote audio track.
2387// TODO(deadbeef): Use a fake audio source and verify that the output level is
2388// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002389TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002390 ASSERT_TRUE(CreatePeerConnectionWrappers());
2391 ConnectFakeSignaling();
2392 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002393 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002394 caller()->CreateAndSetAndSignalOffer();
2395 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2396
2397 // Get the audio output level stats. Note that the level is not available
2398 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002399 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002400 kMaxWaitForFramesMs);
2401}
2402
2403// Test that an audio input level is reported.
2404// TODO(deadbeef): Use a fake audio source and verify that the input level is
2405// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002406TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002407 ASSERT_TRUE(CreatePeerConnectionWrappers());
2408 ConnectFakeSignaling();
2409 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002410 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002411 caller()->CreateAndSetAndSignalOffer();
2412 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2413
2414 // Get the audio input level stats. The level should be available very
2415 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002416 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002417 kMaxWaitForStatsMs);
2418}
2419
2420// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002421TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002422 ASSERT_TRUE(CreatePeerConnectionWrappers());
2423 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002424 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002425 // Do offer/answer, wait for the callee to receive some frames.
2426 caller()->CreateAndSetAndSignalOffer();
2427 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002428
2429 MediaExpectations media_expectations;
2430 media_expectations.CalleeExpectsSomeAudioAndVideo();
2431 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002432
2433 // Get a handle to the remote tracks created, so they can be used as GetStats
2434 // filters.
Steve Anton15324772018-01-16 10:26:49 -08002435 for (auto receiver : callee()->pc()->GetReceivers()) {
2436 // We received frames, so we definitely should have nonzero "received bytes"
2437 // stats at this point.
2438 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2439 0);
2440 }
deadbeef1dcb1642017-03-29 21:08:16 -07002441}
2442
2443// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002444TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002445 ASSERT_TRUE(CreatePeerConnectionWrappers());
2446 ConnectFakeSignaling();
2447 auto audio_track = caller()->CreateLocalAudioTrack();
2448 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002449 caller()->AddTrack(audio_track);
2450 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002451 // Do offer/answer, wait for the callee to receive some frames.
2452 caller()->CreateAndSetAndSignalOffer();
2453 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002454 MediaExpectations media_expectations;
2455 media_expectations.CalleeExpectsSomeAudioAndVideo();
2456 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002457
2458 // The callee received frames, so we definitely should have nonzero "sent
2459 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002460 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2461 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2462}
2463
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002464// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002465TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002466 ASSERT_TRUE(CreatePeerConnectionWrappers());
2467 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002468 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002469
Steve Anton15324772018-01-16 10:26:49 -08002470 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002471
2472 // Do offer/answer, wait for the callee to receive some frames.
2473 caller()->CreateAndSetAndSignalOffer();
2474 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2475
2476 // Get the remote audio track created on the receiver, so they can be used as
2477 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002478 auto receivers = callee()->pc()->GetReceivers();
2479 ASSERT_EQ(1u, receivers.size());
2480 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002481
2482 // Get the audio output level stats. Note that the level is not available
2483 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002484 EXPECT_TRUE_WAIT(
2485 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2486 0,
2487 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002488}
2489
deadbeefd8ad7882017-04-18 16:01:17 -07002490// Test that we can get stats (using the new stats implemnetation) for
2491// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2492// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002493TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002494 GetStatsForUnsignaledStreamWithNewStatsApi) {
2495 ASSERT_TRUE(CreatePeerConnectionWrappers());
2496 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002497 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002498 // Remove SSRCs and MSIDs from the received offer SDP.
2499 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2500 caller()->CreateAndSetAndSignalOffer();
2501 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002502 MediaExpectations media_expectations;
2503 media_expectations.CalleeExpectsSomeAudio(1);
2504 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002505
2506 // We received a frame, so we should have nonzero "bytes received" stats for
2507 // the unsignaled stream, if stats are working for it.
2508 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2509 callee()->NewGetStats();
2510 ASSERT_NE(nullptr, report);
2511 auto inbound_stream_stats =
2512 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2513 ASSERT_EQ(1U, inbound_stream_stats.size());
2514 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2515 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002516 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2517}
2518
2519// Test that we can successfully get the media related stats (audio level
2520// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002521TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002522 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2523 ASSERT_TRUE(CreatePeerConnectionWrappers());
2524 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002525 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002526 // Remove SSRCs and MSIDs from the received offer SDP.
2527 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2528 caller()->CreateAndSetAndSignalOffer();
2529 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002530 MediaExpectations media_expectations;
2531 media_expectations.CalleeExpectsSomeAudio(1);
2532 media_expectations.CalleeExpectsSomeVideo(1);
2533 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002534
2535 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2536 callee()->NewGetStats();
2537 ASSERT_NE(nullptr, report);
2538
2539 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2540 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2541 ASSERT_GE(audio_index, 0);
2542 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002543}
2544
deadbeef4e2deab2017-09-20 13:56:21 -07002545// Helper for test below.
2546void ModifySsrcs(cricket::SessionDescription* desc) {
2547 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002548 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002549 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002550 for (uint32_t& ssrc : stream.ssrcs) {
2551 ssrc = rtc::CreateRandomId();
2552 }
2553 }
2554 }
2555}
2556
2557// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2558// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2559// This should result in two "RTCInboundRTPStreamStats", but only one
2560// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2561// being reset to 0 once the SSRC change occurs.
2562//
2563// Regression test for this bug:
2564// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2565//
2566// The bug causes the track stats to only represent one of the two streams:
2567// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2568// that the track stat counters would reset to 0 when the new stream is
2569// received, and a 50% chance that they'll stop updating (while
2570// "concealed_samples" continues increasing, due to silence being generated for
2571// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002572TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002573 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002574 ASSERT_TRUE(CreatePeerConnectionWrappers());
2575 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002576 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002577 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2578 // that doesn't signal SSRCs (from the callee's perspective).
2579 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2580 caller()->CreateAndSetAndSignalOffer();
2581 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2582 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002583 {
2584 MediaExpectations media_expectations;
2585 media_expectations.CalleeExpectsSomeAudio(50);
2586 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2587 }
deadbeef4e2deab2017-09-20 13:56:21 -07002588 // Some audio frames were received, so we should have nonzero "samples
2589 // received" for the track.
2590 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2591 callee()->NewGetStats();
2592 ASSERT_NE(nullptr, report);
2593 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2594 ASSERT_EQ(1U, track_stats.size());
2595 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2596 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2597 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2598
2599 // Create a new offer and munge it to cause the caller to use a new SSRC.
2600 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2601 caller()->CreateAndSetAndSignalOffer();
2602 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2603 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2604 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002605 {
2606 MediaExpectations media_expectations;
2607 media_expectations.CalleeExpectsSomeAudio(25);
2608 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2609 }
deadbeef4e2deab2017-09-20 13:56:21 -07002610
2611 report = callee()->NewGetStats();
2612 ASSERT_NE(nullptr, report);
2613 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2614 ASSERT_EQ(1U, track_stats.size());
2615 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2616 // The "total samples received" stat should only be greater than it was
2617 // before.
2618 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2619 // Right now, the new SSRC will cause the counters to reset to 0.
2620 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2621
2622 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002623 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002624 // good sign that we're seeing stats from the old stream that's no longer
2625 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002626 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002627 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2628 EXPECT_LT(*track_stats[0]->concealed_samples,
2629 *track_stats[0]->total_samples_received *
2630 kAcceptableConcealedSamplesPercentage);
2631
2632 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2633 // sanity check that the SSRC really changed.
2634 // TODO(deadbeef): This isn't working right now, because we're not returning
2635 // *any* stats for the inactive stream. Uncomment when the bug is completely
2636 // fixed.
2637 // auto inbound_stream_stats =
2638 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2639 // ASSERT_EQ(2U, inbound_stream_stats.size());
2640}
2641
deadbeef1dcb1642017-03-29 21:08:16 -07002642// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002643TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002644 PeerConnectionFactory::Options dtls_10_options;
2645 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2646 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2647 dtls_10_options));
2648 ConnectFakeSignaling();
2649 // Do normal offer/answer and wait for some frames to be received in each
2650 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002651 caller()->AddAudioVideoTracks();
2652 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002653 caller()->CreateAndSetAndSignalOffer();
2654 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002655 MediaExpectations media_expectations;
2656 media_expectations.ExpectBidirectionalAudioAndVideo();
2657 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002658}
2659
2660// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002661TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002662 PeerConnectionFactory::Options dtls_10_options;
2663 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2664 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2665 dtls_10_options));
2666 ConnectFakeSignaling();
2667 // Register UMA observer before signaling begins.
2668 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
2669 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
2670 caller()->pc()->RegisterUMAObserver(caller_observer);
Steve Anton15324772018-01-16 10:26:49 -08002671 caller()->AddAudioVideoTracks();
2672 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002673 caller()->CreateAndSetAndSignalOffer();
2674 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2675 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002676 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002677 kDefaultTimeout);
2678 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002679 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002680 EXPECT_EQ(1,
2681 caller_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher,
2682 kDefaultSrtpCryptoSuite));
2683}
2684
2685// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002686TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002687 PeerConnectionFactory::Options dtls_12_options;
2688 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2689 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2690 dtls_12_options));
2691 ConnectFakeSignaling();
2692 // Register UMA observer before signaling begins.
2693 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
2694 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
2695 caller()->pc()->RegisterUMAObserver(caller_observer);
Steve Anton15324772018-01-16 10:26:49 -08002696 caller()->AddAudioVideoTracks();
2697 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002698 caller()->CreateAndSetAndSignalOffer();
2699 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2700 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002701 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002702 kDefaultTimeout);
2703 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002704 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002705 EXPECT_EQ(1,
2706 caller_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher,
2707 kDefaultSrtpCryptoSuite));
2708}
2709
2710// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2711// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002712TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002713 PeerConnectionFactory::Options caller_options;
2714 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2715 PeerConnectionFactory::Options callee_options;
2716 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2717 ASSERT_TRUE(
2718 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2719 ConnectFakeSignaling();
2720 // Do normal offer/answer and wait for some frames to be received in each
2721 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002722 caller()->AddAudioVideoTracks();
2723 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002724 caller()->CreateAndSetAndSignalOffer();
2725 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002726 MediaExpectations media_expectations;
2727 media_expectations.ExpectBidirectionalAudioAndVideo();
2728 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002729}
2730
2731// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2732// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002733TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07002734 PeerConnectionFactory::Options caller_options;
2735 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2736 PeerConnectionFactory::Options callee_options;
2737 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2738 ASSERT_TRUE(
2739 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2740 ConnectFakeSignaling();
2741 // Do normal offer/answer and wait for some frames to be received in each
2742 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002743 caller()->AddAudioVideoTracks();
2744 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002745 caller()->CreateAndSetAndSignalOffer();
2746 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002747 MediaExpectations media_expectations;
2748 media_expectations.ExpectBidirectionalAudioAndVideo();
2749 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002750}
2751
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002752// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2753// works as expected; the cipher should only be used if enabled by both sides.
2754TEST_P(PeerConnectionIntegrationTest,
2755 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2756 PeerConnectionFactory::Options caller_options;
2757 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2758 PeerConnectionFactory::Options callee_options;
2759 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2760 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2761 TestNegotiatedCipherSuite(caller_options, callee_options,
2762 expected_cipher_suite);
2763}
2764
2765TEST_P(PeerConnectionIntegrationTest,
2766 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2767 PeerConnectionFactory::Options caller_options;
2768 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2769 PeerConnectionFactory::Options callee_options;
2770 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2771 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2772 TestNegotiatedCipherSuite(caller_options, callee_options,
2773 expected_cipher_suite);
2774}
2775
2776TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2777 PeerConnectionFactory::Options caller_options;
2778 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2779 PeerConnectionFactory::Options callee_options;
2780 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2781 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2782 TestNegotiatedCipherSuite(caller_options, callee_options,
2783 expected_cipher_suite);
2784}
2785
deadbeef1dcb1642017-03-29 21:08:16 -07002786// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002787TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002788 bool local_gcm_enabled = false;
2789 bool remote_gcm_enabled = false;
2790 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2791 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2792 expected_cipher_suite);
2793}
2794
2795// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002796TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002797 bool local_gcm_enabled = true;
2798 bool remote_gcm_enabled = true;
2799 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2800 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2801 expected_cipher_suite);
2802}
2803
2804// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002805TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002806 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2807 bool local_gcm_enabled = true;
2808 bool remote_gcm_enabled = false;
2809 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2810 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2811 expected_cipher_suite);
2812}
2813
2814// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002815TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002816 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2817 bool local_gcm_enabled = false;
2818 bool remote_gcm_enabled = true;
2819 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2820 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2821 expected_cipher_suite);
2822}
2823
deadbeef7914b8c2017-04-21 03:23:33 -07002824// Verify that media can be transmitted end-to-end when GCM crypto suites are
2825// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2826// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2827// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002828TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07002829 PeerConnectionFactory::Options gcm_options;
2830 gcm_options.crypto_options.enable_gcm_crypto_suites = true;
2831 ASSERT_TRUE(
2832 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2833 ConnectFakeSignaling();
2834 // Do normal offer/answer and wait for some frames to be received in each
2835 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002836 caller()->AddAudioVideoTracks();
2837 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07002838 caller()->CreateAndSetAndSignalOffer();
2839 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002840 MediaExpectations media_expectations;
2841 media_expectations.ExpectBidirectionalAudioAndVideo();
2842 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07002843}
2844
deadbeef1dcb1642017-03-29 21:08:16 -07002845// This test sets up a call between two parties with audio, video and an RTP
2846// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002847TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07002848 FakeConstraints setup_constraints;
2849 setup_constraints.SetAllowRtpDataChannels();
2850 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2851 &setup_constraints));
2852 ConnectFakeSignaling();
2853 // Expect that data channel created on caller side will show up for callee as
2854 // well.
2855 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002856 caller()->AddAudioVideoTracks();
2857 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002858 caller()->CreateAndSetAndSignalOffer();
2859 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2860 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002861 MediaExpectations media_expectations;
2862 media_expectations.ExpectBidirectionalAudioAndVideo();
2863 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002864 ASSERT_NE(nullptr, caller()->data_channel());
2865 ASSERT_NE(nullptr, callee()->data_channel());
2866 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2867 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2868
2869 // Ensure data can be sent in both directions.
2870 std::string data = "hello world";
2871 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2872 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2873 kDefaultTimeout);
2874 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2875 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2876 kDefaultTimeout);
2877}
2878
2879// Ensure that an RTP data channel is signaled as closed for the caller when
2880// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002881TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002882 RtpDataChannelSignaledClosedInCalleeOffer) {
2883 // Same procedure as above test.
2884 FakeConstraints setup_constraints;
2885 setup_constraints.SetAllowRtpDataChannels();
2886 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2887 &setup_constraints));
2888 ConnectFakeSignaling();
2889 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002890 caller()->AddAudioVideoTracks();
2891 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002892 caller()->CreateAndSetAndSignalOffer();
2893 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2894 ASSERT_NE(nullptr, caller()->data_channel());
2895 ASSERT_NE(nullptr, callee()->data_channel());
2896 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2897 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2898
2899 // Close the data channel on the callee, and do an updated offer/answer.
2900 callee()->data_channel()->Close();
2901 callee()->CreateAndSetAndSignalOffer();
2902 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2903 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2904 EXPECT_FALSE(callee()->data_observer()->IsOpen());
2905}
2906
2907// Tests that data is buffered in an RTP data channel until an observer is
2908// registered for it.
2909//
2910// NOTE: RTP data channels can receive data before the underlying
2911// transport has detected that a channel is writable and thus data can be
2912// received before the data channel state changes to open. That is hard to test
2913// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002914TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002915 DataBufferedUntilRtpDataChannelObserverRegistered) {
2916 // Use fake clock and simulated network delay so that we predictably can wait
2917 // until an SCTP message has been delivered without "sleep()"ing.
2918 rtc::ScopedFakeClock fake_clock;
2919 // Some things use a time of "0" as a special value, so we need to start out
2920 // the fake clock at a nonzero time.
2921 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02002922 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07002923 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
2924 virtual_socket_server()->UpdateDelayDistribution();
2925
2926 FakeConstraints constraints;
2927 constraints.SetAllowRtpDataChannels();
2928 ASSERT_TRUE(
2929 CreatePeerConnectionWrappersWithConstraints(&constraints, &constraints));
2930 ConnectFakeSignaling();
2931 caller()->CreateDataChannel();
2932 caller()->CreateAndSetAndSignalOffer();
2933 ASSERT_TRUE(caller()->data_channel() != nullptr);
2934 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
2935 kDefaultTimeout, fake_clock);
2936 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
2937 kDefaultTimeout, fake_clock);
2938 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
2939 callee()->data_channel()->state(), kDefaultTimeout,
2940 fake_clock);
2941
2942 // Unregister the observer which is normally automatically registered.
2943 callee()->data_channel()->UnregisterObserver();
2944 // Send data and advance fake clock until it should have been received.
2945 std::string data = "hello world";
2946 caller()->data_channel()->Send(DataBuffer(data));
2947 SIMULATED_WAIT(false, 50, fake_clock);
2948
2949 // Attach data channel and expect data to be received immediately. Note that
2950 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
2951 // further, but data can be received even if the callback is asynchronous.
2952 MockDataChannelObserver new_observer(callee()->data_channel());
2953 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
2954 fake_clock);
2955}
2956
2957// This test sets up a call between two parties with audio, video and but only
2958// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002959TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07002960 FakeConstraints setup_constraints_1;
2961 setup_constraints_1.SetAllowRtpDataChannels();
2962 // Must disable DTLS to make negotiation succeed.
2963 setup_constraints_1.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
2964 false);
2965 FakeConstraints setup_constraints_2;
2966 setup_constraints_2.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
2967 false);
2968 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(
2969 &setup_constraints_1, &setup_constraints_2));
2970 ConnectFakeSignaling();
2971 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002972 caller()->AddAudioVideoTracks();
2973 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002974 caller()->CreateAndSetAndSignalOffer();
2975 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2976 // The caller should still have a data channel, but it should be closed, and
2977 // one should ever have been created for the callee.
2978 EXPECT_TRUE(caller()->data_channel() != nullptr);
2979 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2980 EXPECT_EQ(nullptr, callee()->data_channel());
2981}
2982
2983// This test sets up a call between two parties with audio, and video. When
2984// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002985TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002986 FakeConstraints setup_constraints;
2987 setup_constraints.SetAllowRtpDataChannels();
2988 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2989 &setup_constraints));
2990 ConnectFakeSignaling();
2991 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08002992 caller()->AddAudioVideoTracks();
2993 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002994 caller()->CreateAndSetAndSignalOffer();
2995 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2996 // Create data channel and do new offer and answer.
2997 caller()->CreateDataChannel();
2998 caller()->CreateAndSetAndSignalOffer();
2999 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3000 ASSERT_NE(nullptr, caller()->data_channel());
3001 ASSERT_NE(nullptr, callee()->data_channel());
3002 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3003 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3004 // Ensure data can be sent in both directions.
3005 std::string data = "hello world";
3006 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3007 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3008 kDefaultTimeout);
3009 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3010 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3011 kDefaultTimeout);
3012}
3013
3014#ifdef HAVE_SCTP
3015
3016// This test sets up a call between two parties with audio, video and an SCTP
3017// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003018TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003019 ASSERT_TRUE(CreatePeerConnectionWrappers());
3020 ConnectFakeSignaling();
3021 // Expect that data channel created on caller side will show up for callee as
3022 // well.
3023 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003024 caller()->AddAudioVideoTracks();
3025 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003026 caller()->CreateAndSetAndSignalOffer();
3027 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3028 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003029 MediaExpectations media_expectations;
3030 media_expectations.ExpectBidirectionalAudioAndVideo();
3031 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003032 // Caller data channel should already exist (it created one). Callee data
3033 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3034 ASSERT_NE(nullptr, caller()->data_channel());
3035 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3036 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3037 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3038
3039 // Ensure data can be sent in both directions.
3040 std::string data = "hello world";
3041 caller()->data_channel()->Send(DataBuffer(data));
3042 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3043 kDefaultTimeout);
3044 callee()->data_channel()->Send(DataBuffer(data));
3045 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3046 kDefaultTimeout);
3047}
3048
3049// Ensure that when the callee closes an SCTP data channel, the closing
3050// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003051TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003052 // Same procedure as above test.
3053 ASSERT_TRUE(CreatePeerConnectionWrappers());
3054 ConnectFakeSignaling();
3055 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003056 caller()->AddAudioVideoTracks();
3057 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003058 caller()->CreateAndSetAndSignalOffer();
3059 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3060 ASSERT_NE(nullptr, caller()->data_channel());
3061 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3062 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3063 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3064
3065 // Close the data channel on the callee side, and wait for it to reach the
3066 // "closed" state on both sides.
3067 callee()->data_channel()->Close();
3068 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3069 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3070}
3071
Seth Hampson2f0d7022018-02-20 11:54:42 -08003072TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003073 ASSERT_TRUE(CreatePeerConnectionWrappers());
3074 ConnectFakeSignaling();
3075 webrtc::DataChannelInit init;
3076 init.id = 53;
3077 init.maxRetransmits = 52;
3078 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003079 caller()->AddAudioVideoTracks();
3080 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003081 caller()->CreateAndSetAndSignalOffer();
3082 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003083 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3084 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 11:41:54 -07003085 EXPECT_EQ(init.id, callee()->data_channel()->id());
3086 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3087 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3088 EXPECT_FALSE(callee()->data_channel()->negotiated());
3089}
3090
deadbeef1dcb1642017-03-29 21:08:16 -07003091// Test usrsctp's ability to process unordered data stream, where data actually
3092// arrives out of order using simulated delays. Previously there have been some
3093// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003094TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003095 // Introduce random network delays.
3096 // Otherwise it's not a true "unordered" test.
3097 virtual_socket_server()->set_delay_mean(20);
3098 virtual_socket_server()->set_delay_stddev(5);
3099 virtual_socket_server()->UpdateDelayDistribution();
3100 // Normal procedure, but with unordered data channel config.
3101 ASSERT_TRUE(CreatePeerConnectionWrappers());
3102 ConnectFakeSignaling();
3103 webrtc::DataChannelInit init;
3104 init.ordered = false;
3105 caller()->CreateDataChannel(&init);
3106 caller()->CreateAndSetAndSignalOffer();
3107 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3108 ASSERT_NE(nullptr, caller()->data_channel());
3109 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3110 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3111 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3112
3113 static constexpr int kNumMessages = 100;
3114 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3115 static constexpr size_t kMaxMessageSize = 4096;
3116 // Create and send random messages.
3117 std::vector<std::string> sent_messages;
3118 for (int i = 0; i < kNumMessages; ++i) {
3119 size_t length =
3120 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3121 std::string message;
3122 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3123 caller()->data_channel()->Send(DataBuffer(message));
3124 callee()->data_channel()->Send(DataBuffer(message));
3125 sent_messages.push_back(message);
3126 }
3127
3128 // Wait for all messages to be received.
3129 EXPECT_EQ_WAIT(kNumMessages,
3130 caller()->data_observer()->received_message_count(),
3131 kDefaultTimeout);
3132 EXPECT_EQ_WAIT(kNumMessages,
3133 callee()->data_observer()->received_message_count(),
3134 kDefaultTimeout);
3135
3136 // Sort and compare to make sure none of the messages were corrupted.
3137 std::vector<std::string> caller_received_messages =
3138 caller()->data_observer()->messages();
3139 std::vector<std::string> callee_received_messages =
3140 callee()->data_observer()->messages();
3141 std::sort(sent_messages.begin(), sent_messages.end());
3142 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3143 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3144 EXPECT_EQ(sent_messages, caller_received_messages);
3145 EXPECT_EQ(sent_messages, callee_received_messages);
3146}
3147
3148// This test sets up a call between two parties with audio, and video. When
3149// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003150TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003151 ASSERT_TRUE(CreatePeerConnectionWrappers());
3152 ConnectFakeSignaling();
3153 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003154 caller()->AddAudioVideoTracks();
3155 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003156 caller()->CreateAndSetAndSignalOffer();
3157 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3158 // Create data channel and do new offer and answer.
3159 caller()->CreateDataChannel();
3160 caller()->CreateAndSetAndSignalOffer();
3161 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3162 // Caller data channel should already exist (it created one). Callee data
3163 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3164 ASSERT_NE(nullptr, caller()->data_channel());
3165 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3166 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3167 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3168 // Ensure data can be sent in both directions.
3169 std::string data = "hello world";
3170 caller()->data_channel()->Send(DataBuffer(data));
3171 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3172 kDefaultTimeout);
3173 callee()->data_channel()->Send(DataBuffer(data));
3174 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3175 kDefaultTimeout);
3176}
3177
deadbeef7914b8c2017-04-21 03:23:33 -07003178// Set up a connection initially just using SCTP data channels, later upgrading
3179// to audio/video, ensuring frames are received end-to-end. Effectively the
3180// inverse of the test above.
3181// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003182TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003183 ASSERT_TRUE(CreatePeerConnectionWrappers());
3184 ConnectFakeSignaling();
3185 // Do initial offer/answer with just data channel.
3186 caller()->CreateDataChannel();
3187 caller()->CreateAndSetAndSignalOffer();
3188 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3189 // Wait until data can be sent over the data channel.
3190 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3191 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3192 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3193
3194 // Do subsequent offer/answer with two-way audio and video. Audio and video
3195 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003196 caller()->AddAudioVideoTracks();
3197 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003198 caller()->CreateAndSetAndSignalOffer();
3199 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003200 MediaExpectations media_expectations;
3201 media_expectations.ExpectBidirectionalAudioAndVideo();
3202 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003203}
3204
deadbeef8b7e9ad2017-05-25 09:38:55 -07003205static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 09:38:55 -07003206 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 15:14:30 -08003207 GetFirstDataContentDescription(desc);
3208 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003209 dcd_offer->set_use_sctpmap(false);
3210 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3211}
3212
3213// Test that the data channel works when a spec-compliant SCTP m= section is
3214// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3215// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003216TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003217 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3218 ASSERT_TRUE(CreatePeerConnectionWrappers());
3219 ConnectFakeSignaling();
3220 caller()->CreateDataChannel();
3221 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3222 caller()->CreateAndSetAndSignalOffer();
3223 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3224 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3225 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3226 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3227
3228 // Ensure data can be sent in both directions.
3229 std::string data = "hello world";
3230 caller()->data_channel()->Send(DataBuffer(data));
3231 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3232 kDefaultTimeout);
3233 callee()->data_channel()->Send(DataBuffer(data));
3234 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3235 kDefaultTimeout);
3236}
3237
deadbeef1dcb1642017-03-29 21:08:16 -07003238#endif // HAVE_SCTP
3239
3240// Test that the ICE connection and gathering states eventually reach
3241// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003242TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003243 ASSERT_TRUE(CreatePeerConnectionWrappers());
3244 ConnectFakeSignaling();
3245 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003246 caller()->AddAudioVideoTracks();
3247 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003248 caller()->CreateAndSetAndSignalOffer();
3249 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3250 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3251 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3252 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3253 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3254 // After the best candidate pair is selected and all candidates are signaled,
3255 // the ICE connection state should reach "complete".
3256 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3257 // answerer/"callee" by default) only reaches "connected". When this is
3258 // fixed, this test should be updated.
3259 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3260 caller()->ice_connection_state(), kDefaultTimeout);
3261 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3262 callee()->ice_connection_state(), kDefaultTimeout);
3263}
3264
Steve Antonede9ca52017-10-16 13:04:27 -07003265// Test that firewalling the ICE connection causes the clients to identify the
3266// disconnected state and then removing the firewall causes them to reconnect.
3267class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003268 : public PeerConnectionIntegrationBaseTest,
3269 public ::testing::WithParamInterface<
3270 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003271 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003272 PeerConnectionIntegrationIceStatesTest()
3273 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3274 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003275 }
3276
3277 void StartStunServer(const SocketAddress& server_address) {
3278 stun_server_.reset(
3279 cricket::TestStunServer::Create(network_thread(), server_address));
3280 }
3281
3282 bool TestIPv6() {
3283 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3284 }
3285
3286 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 16:57:45 -07003287 network_thread()->Invoke<void>(
3288 RTC_FROM_HERE,
3289 rtc::Bind(&cricket::PortAllocator::set_flags,
3290 caller()->port_allocator(), port_allocator_flags_));
3291 network_thread()->Invoke<void>(
3292 RTC_FROM_HERE,
3293 rtc::Bind(&cricket::PortAllocator::set_flags,
3294 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 13:04:27 -07003295 }
3296
3297 std::vector<SocketAddress> CallerAddresses() {
3298 std::vector<SocketAddress> addresses;
3299 addresses.push_back(SocketAddress("1.1.1.1", 0));
3300 if (TestIPv6()) {
3301 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3302 }
3303 return addresses;
3304 }
3305
3306 std::vector<SocketAddress> CalleeAddresses() {
3307 std::vector<SocketAddress> addresses;
3308 addresses.push_back(SocketAddress("2.2.2.2", 0));
3309 if (TestIPv6()) {
3310 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3311 }
3312 return addresses;
3313 }
3314
3315 void SetUpNetworkInterfaces() {
3316 // Remove the default interfaces added by the test infrastructure.
3317 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3318 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3319
3320 // Add network addresses for test.
3321 for (const auto& caller_address : CallerAddresses()) {
3322 caller()->network()->AddInterface(caller_address);
3323 }
3324 for (const auto& callee_address : CalleeAddresses()) {
3325 callee()->network()->AddInterface(callee_address);
3326 }
3327 }
3328
3329 private:
3330 uint32_t port_allocator_flags_;
3331 std::unique_ptr<cricket::TestStunServer> stun_server_;
3332};
3333
3334// Tests that the PeerConnection goes through all the ICE gathering/connection
3335// states over the duration of the call. This includes Disconnected and Failed
3336// states, induced by putting a firewall between the peers and waiting for them
3337// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003338TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3339 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3340 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3341 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 13:04:27 -07003342
3343 const SocketAddress kStunServerAddress =
3344 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3345 StartStunServer(kStunServerAddress);
3346
3347 PeerConnectionInterface::RTCConfiguration config;
3348 PeerConnectionInterface::IceServer ice_stun_server;
3349 ice_stun_server.urls.push_back(
3350 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3351 kStunServerAddress.PortAsString());
3352 config.servers.push_back(ice_stun_server);
3353
3354 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3355 ConnectFakeSignaling();
3356 SetPortAllocatorFlags();
3357 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003358 caller()->AddAudioVideoTracks();
3359 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003360
3361 // Initial state before anything happens.
3362 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3363 caller()->ice_gathering_state());
3364 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3365 caller()->ice_connection_state());
3366
3367 // Start the call by creating the offer, setting it as the local description,
3368 // then sending it to the peer who will respond with an answer. This happens
3369 // asynchronously so that we can watch the states as it runs in the
3370 // background.
3371 caller()->CreateAndSetAndSignalOffer();
3372
Steve Anton83119dd2017-11-10 16:19:52 -08003373 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3374 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003375
3376 // Verify that the observer was notified of the intermediate transitions.
3377 EXPECT_THAT(caller()->ice_connection_state_history(),
3378 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3379 PeerConnectionInterface::kIceConnectionConnected,
3380 PeerConnectionInterface::kIceConnectionCompleted));
3381 EXPECT_THAT(caller()->ice_gathering_state_history(),
3382 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3383 PeerConnectionInterface::kIceGatheringComplete));
3384
3385 // Block connections to/from the caller and wait for ICE to become
3386 // disconnected.
3387 for (const auto& caller_address : CallerAddresses()) {
3388 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3389 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003390 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-10 16:19:52 -08003391 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3392 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003393
3394 // Let ICE re-establish by removing the firewall rules.
3395 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01003396 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-10 16:19:52 -08003397 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3398 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003399
3400 // According to RFC7675, if there is no response within 30 seconds then the
3401 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08003402 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07003403 constexpr int kConsentTimeout = 30000;
3404 for (const auto& caller_address : CallerAddresses()) {
3405 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3406 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003407 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-10 16:19:52 -08003408 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3409 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003410}
3411
3412// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3413// and that the statistics in the metric observers are updated correctly.
3414TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3415 ASSERT_TRUE(CreatePeerConnectionWrappers());
3416 ConnectFakeSignaling();
3417 SetPortAllocatorFlags();
3418 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003419 caller()->AddAudioVideoTracks();
3420 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003421
3422 rtc::scoped_refptr<webrtc::FakeMetricsObserver> metrics_observer(
3423 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>());
3424 caller()->pc()->RegisterUMAObserver(metrics_observer.get());
3425
3426 caller()->CreateAndSetAndSignalOffer();
3427
3428 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3429
3430 const int num_best_ipv4 = metrics_observer->GetEnumCounter(
3431 webrtc::kEnumCounterAddressFamily, webrtc::kBestConnections_IPv4);
3432 const int num_best_ipv6 = metrics_observer->GetEnumCounter(
3433 webrtc::kEnumCounterAddressFamily, webrtc::kBestConnections_IPv6);
3434 if (TestIPv6()) {
3435 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3436 // connection.
3437 EXPECT_EQ(0u, num_best_ipv4);
3438 EXPECT_EQ(1u, num_best_ipv6);
3439 } else {
3440 EXPECT_EQ(1u, num_best_ipv4);
3441 EXPECT_EQ(0u, num_best_ipv6);
3442 }
3443
3444 EXPECT_EQ(0u, metrics_observer->GetEnumCounter(
3445 webrtc::kEnumCounterIceCandidatePairTypeUdp,
3446 webrtc::kIceCandidatePairHostHost));
3447 EXPECT_EQ(1u, metrics_observer->GetEnumCounter(
3448 webrtc::kEnumCounterIceCandidatePairTypeUdp,
3449 webrtc::kIceCandidatePairHostPublicHostPublic));
3450}
3451
3452constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3453 cricket::PORTALLOCATOR_DISABLE_STUN |
3454 cricket::PORTALLOCATOR_DISABLE_RELAY;
3455constexpr uint32_t kFlagsIPv6NoStun =
3456 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3457 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3458constexpr uint32_t kFlagsIPv4Stun =
3459 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3460
Seth Hampson2f0d7022018-02-20 11:54:42 -08003461INSTANTIATE_TEST_CASE_P(
3462 PeerConnectionIntegrationTest,
3463 PeerConnectionIntegrationIceStatesTest,
3464 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3465 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3466 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3467 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07003468
deadbeef1dcb1642017-03-29 21:08:16 -07003469// This test sets up a call between two parties with audio and video.
3470// During the call, the caller restarts ICE and the test verifies that
3471// new ICE candidates are generated and audio and video still can flow, and the
3472// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003473TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07003474 ASSERT_TRUE(CreatePeerConnectionWrappers());
3475 ConnectFakeSignaling();
3476 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08003477 caller()->AddAudioVideoTracks();
3478 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003479 caller()->CreateAndSetAndSignalOffer();
3480 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3481 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3482 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3483 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3484 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3485
3486 // To verify that the ICE restart actually occurs, get
3487 // ufrag/password/candidates before and after restart.
3488 // Create an SDP string of the first audio candidate for both clients.
3489 const webrtc::IceCandidateCollection* audio_candidates_caller =
3490 caller()->pc()->local_description()->candidates(0);
3491 const webrtc::IceCandidateCollection* audio_candidates_callee =
3492 callee()->pc()->local_description()->candidates(0);
3493 ASSERT_GT(audio_candidates_caller->count(), 0u);
3494 ASSERT_GT(audio_candidates_callee->count(), 0u);
3495 std::string caller_candidate_pre_restart;
3496 ASSERT_TRUE(
3497 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3498 std::string callee_candidate_pre_restart;
3499 ASSERT_TRUE(
3500 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3501 const cricket::SessionDescription* desc =
3502 caller()->pc()->local_description()->description();
3503 std::string caller_ufrag_pre_restart =
3504 desc->transport_infos()[0].description.ice_ufrag;
3505 desc = callee()->pc()->local_description()->description();
3506 std::string callee_ufrag_pre_restart =
3507 desc->transport_infos()[0].description.ice_ufrag;
3508
3509 // Have the caller initiate an ICE restart.
3510 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3511 caller()->CreateAndSetAndSignalOffer();
3512 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3513 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3514 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3515 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3516 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3517
3518 // Grab the ufrags/candidates again.
3519 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3520 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3521 ASSERT_GT(audio_candidates_caller->count(), 0u);
3522 ASSERT_GT(audio_candidates_callee->count(), 0u);
3523 std::string caller_candidate_post_restart;
3524 ASSERT_TRUE(
3525 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3526 std::string callee_candidate_post_restart;
3527 ASSERT_TRUE(
3528 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3529 desc = caller()->pc()->local_description()->description();
3530 std::string caller_ufrag_post_restart =
3531 desc->transport_infos()[0].description.ice_ufrag;
3532 desc = callee()->pc()->local_description()->description();
3533 std::string callee_ufrag_post_restart =
3534 desc->transport_infos()[0].description.ice_ufrag;
3535 // Sanity check that an ICE restart was actually negotiated in SDP.
3536 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3537 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3538 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3539 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3540
3541 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003542 MediaExpectations media_expectations;
3543 media_expectations.ExpectBidirectionalAudioAndVideo();
3544 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003545}
3546
3547// Verify that audio/video can be received end-to-end when ICE renomination is
3548// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003549TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07003550 PeerConnectionInterface::RTCConfiguration config;
3551 config.enable_ice_renomination = true;
3552 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3553 ConnectFakeSignaling();
3554 // Do normal offer/answer and wait for some frames to be received in each
3555 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003556 caller()->AddAudioVideoTracks();
3557 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003558 caller()->CreateAndSetAndSignalOffer();
3559 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3560 // Sanity check that ICE renomination was actually negotiated.
3561 const cricket::SessionDescription* desc =
3562 caller()->pc()->local_description()->description();
3563 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003564 ASSERT_NE(
3565 info.description.transport_options.end(),
3566 std::find(info.description.transport_options.begin(),
3567 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003568 }
3569 desc = callee()->pc()->local_description()->description();
3570 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003571 ASSERT_NE(
3572 info.description.transport_options.end(),
3573 std::find(info.description.transport_options.begin(),
3574 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003575 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08003576 MediaExpectations media_expectations;
3577 media_expectations.ExpectBidirectionalAudioAndVideo();
3578 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003579}
3580
Steve Anton6f25b092017-10-23 09:39:20 -07003581// With a max bundle policy and RTCP muxing, adding a new media description to
3582// the connection should not affect ICE at all because the new media will use
3583// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003584TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003585 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07003586 PeerConnectionInterface::RTCConfiguration config;
3587 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3588 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3589 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3590 config, PeerConnectionInterface::RTCConfiguration()));
3591 ConnectFakeSignaling();
3592
Steve Anton15324772018-01-16 10:26:49 -08003593 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003594 caller()->CreateAndSetAndSignalOffer();
3595 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07003596 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3597 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07003598
3599 caller()->clear_ice_connection_state_history();
3600
Steve Anton15324772018-01-16 10:26:49 -08003601 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003602 caller()->CreateAndSetAndSignalOffer();
3603 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3604
3605 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3606}
3607
deadbeef1dcb1642017-03-29 21:08:16 -07003608// This test sets up a call between two parties with audio and video. It then
3609// renegotiates setting the video m-line to "port 0", then later renegotiates
3610// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003611TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003612 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3613 ASSERT_TRUE(CreatePeerConnectionWrappers());
3614 ConnectFakeSignaling();
3615
3616 // Do initial negotiation, only sending media from the caller. Will result in
3617 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08003618 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003619 caller()->CreateAndSetAndSignalOffer();
3620 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3621
3622 // Negotiate again, disabling the video "m=" section (the callee will set the
3623 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003624 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3625 PeerConnectionInterface::RTCOfferAnswerOptions options;
3626 options.offer_to_receive_video = 0;
3627 callee()->SetOfferAnswerOptions(options);
3628 } else {
3629 callee()->SetRemoteOfferHandler([this] {
3630 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3631 });
3632 }
deadbeef1dcb1642017-03-29 21:08:16 -07003633 caller()->CreateAndSetAndSignalOffer();
3634 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3635 // Sanity check that video "m=" section was actually rejected.
3636 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3637 callee()->pc()->local_description()->description());
3638 ASSERT_NE(nullptr, answer_video_content);
3639 ASSERT_TRUE(answer_video_content->rejected);
3640
3641 // Enable video and do negotiation again, making sure video is received
3642 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003643 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3644 PeerConnectionInterface::RTCOfferAnswerOptions options;
3645 options.offer_to_receive_video = 1;
3646 callee()->SetOfferAnswerOptions(options);
3647 } else {
3648 // The caller's transceiver is stopped, so we need to add another track.
3649 auto caller_transceiver =
3650 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3651 EXPECT_TRUE(caller_transceiver->stopped());
3652 caller()->AddVideoTrack();
3653 }
3654 callee()->AddVideoTrack();
3655 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07003656 caller()->CreateAndSetAndSignalOffer();
3657 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003658
deadbeef1dcb1642017-03-29 21:08:16 -07003659 // Verify the caller receives frames from the newly added stream, and the
3660 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003661 MediaExpectations media_expectations;
3662 media_expectations.CalleeExpectsSomeAudio();
3663 media_expectations.ExpectBidirectionalVideo();
3664 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003665}
3666
deadbeef1dcb1642017-03-29 21:08:16 -07003667// This tests that if we negotiate after calling CreateSender but before we
3668// have a track, then set a track later, frames from the newly-set track are
3669// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003670TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07003671 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3672 ASSERT_TRUE(CreatePeerConnectionWrappers());
3673 ConnectFakeSignaling();
3674 auto caller_audio_sender =
3675 caller()->pc()->CreateSender("audio", "caller_stream");
3676 auto caller_video_sender =
3677 caller()->pc()->CreateSender("video", "caller_stream");
3678 auto callee_audio_sender =
3679 callee()->pc()->CreateSender("audio", "callee_stream");
3680 auto callee_video_sender =
3681 callee()->pc()->CreateSender("video", "callee_stream");
3682 caller()->CreateAndSetAndSignalOffer();
3683 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3684 // Wait for ICE to complete, without any tracks being set.
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 // Now set the tracks, and expect frames to immediately start flowing.
3690 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3691 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3692 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3693 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08003694 MediaExpectations media_expectations;
3695 media_expectations.ExpectBidirectionalAudioAndVideo();
3696 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3697}
3698
3699// This tests that if we negotiate after calling AddTransceiver but before we
3700// have a track, then set a track later, frames from the newly-set tracks are
3701// received end-to-end.
3702TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3703 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3704 ASSERT_TRUE(CreatePeerConnectionWrappers());
3705 ConnectFakeSignaling();
3706 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3707 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3708 auto caller_audio_sender = audio_result.MoveValue()->sender();
3709 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3710 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3711 auto caller_video_sender = video_result.MoveValue()->sender();
3712 callee()->SetRemoteOfferHandler([this] {
3713 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3714 callee()->pc()->GetTransceivers()[0]->SetDirection(
3715 RtpTransceiverDirection::kSendRecv);
3716 callee()->pc()->GetTransceivers()[1]->SetDirection(
3717 RtpTransceiverDirection::kSendRecv);
3718 });
3719 caller()->CreateAndSetAndSignalOffer();
3720 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3721 // Wait for ICE to complete, without any tracks being set.
3722 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3723 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3724 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3725 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3726 // Now set the tracks, and expect frames to immediately start flowing.
3727 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3728 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3729 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3730 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3731 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3732 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3733 MediaExpectations media_expectations;
3734 media_expectations.ExpectBidirectionalAudioAndVideo();
3735 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003736}
3737
3738// This test verifies that a remote video track can be added via AddStream,
3739// and sent end-to-end. For this particular test, it's simply echoed back
3740// from the caller to the callee, rather than being forwarded to a third
3741// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003742TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07003743 ASSERT_TRUE(CreatePeerConnectionWrappers());
3744 ConnectFakeSignaling();
3745 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08003746 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003747 caller()->CreateAndSetAndSignalOffer();
3748 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3749 ASSERT_EQ(1, callee()->remote_streams()->count());
3750
3751 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3752 // time).
3753 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3754 callee()->CreateAndSetAndSignalOffer();
3755 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3756
Seth Hampson2f0d7022018-02-20 11:54:42 -08003757 MediaExpectations media_expectations;
3758 media_expectations.ExpectBidirectionalVideo();
3759 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003760}
3761
3762// Test that we achieve the expected end-to-end connection time, using a
3763// fake clock and simulated latency on the media and signaling paths.
3764// We use a TURN<->TURN connection because this is usually the quickest to
3765// set up initially, especially when we're confident the connection will work
3766// and can start sending media before we get a STUN response.
3767//
3768// With various optimizations enabled, here are the network delays we expect to
3769// be on the critical path:
3770// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3771// signaling answer (with DTLS fingerprint).
3772// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3773// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3774// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003775TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07003776 rtc::ScopedFakeClock fake_clock;
3777 // Some things use a time of "0" as a special value, so we need to start out
3778 // the fake clock at a nonzero time.
3779 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003780 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003781
3782 static constexpr int media_hop_delay_ms = 50;
3783 static constexpr int signaling_trip_delay_ms = 500;
3784 // For explanation of these values, see comment above.
3785 static constexpr int required_media_hops = 9;
3786 static constexpr int required_signaling_trips = 2;
3787 // For internal delays (such as posting an event asychronously).
3788 static constexpr int allowed_internal_delay_ms = 20;
3789 static constexpr int total_connection_time_ms =
3790 media_hop_delay_ms * required_media_hops +
3791 signaling_trip_delay_ms * required_signaling_trips +
3792 allowed_internal_delay_ms;
3793
3794 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3795 3478};
3796 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3797 0};
3798 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3799 3478};
3800 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3801 0};
3802 cricket::TestTurnServer turn_server_1(network_thread(),
3803 turn_server_1_internal_address,
3804 turn_server_1_external_address);
3805 cricket::TestTurnServer turn_server_2(network_thread(),
3806 turn_server_2_internal_address,
3807 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003808
deadbeef1dcb1642017-03-29 21:08:16 -07003809 // Bypass permission check on received packets so media can be sent before
3810 // the candidate is signaled.
3811 turn_server_1.set_enable_permission_checks(false);
3812 turn_server_2.set_enable_permission_checks(false);
3813
3814 PeerConnectionInterface::RTCConfiguration client_1_config;
3815 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3816 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3817 ice_server_1.username = "test";
3818 ice_server_1.password = "test";
3819 client_1_config.servers.push_back(ice_server_1);
3820 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3821 client_1_config.presume_writable_when_fully_relayed = true;
3822
3823 PeerConnectionInterface::RTCConfiguration client_2_config;
3824 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3825 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3826 ice_server_2.username = "test";
3827 ice_server_2.password = "test";
3828 client_2_config.servers.push_back(ice_server_2);
3829 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3830 client_2_config.presume_writable_when_fully_relayed = true;
3831
3832 ASSERT_TRUE(
3833 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3834 // Set up the simulated delays.
3835 SetSignalingDelayMs(signaling_trip_delay_ms);
3836 ConnectFakeSignaling();
3837 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
3838 virtual_socket_server()->UpdateDelayDistribution();
3839
3840 // Set "offer to receive audio/video" without adding any tracks, so we just
3841 // set up ICE/DTLS with no media.
3842 PeerConnectionInterface::RTCOfferAnswerOptions options;
3843 options.offer_to_receive_audio = 1;
3844 options.offer_to_receive_video = 1;
3845 caller()->SetOfferAnswerOptions(options);
3846 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07003847 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
3848 fake_clock);
deadbeef1dcb1642017-03-29 21:08:16 -07003849 // Need to free the clients here since they're using things we created on
3850 // the stack.
3851 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
3852 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
3853}
3854
Jonas Orelandbdcee282017-10-10 14:01:40 +02003855// Verify that a TurnCustomizer passed in through RTCConfiguration
3856// is actually used by the underlying TURN candidate pair.
3857// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003858TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02003859 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3860 3478};
3861 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3862 0};
3863 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3864 3478};
3865 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3866 0};
3867 cricket::TestTurnServer turn_server_1(network_thread(),
3868 turn_server_1_internal_address,
3869 turn_server_1_external_address);
3870 cricket::TestTurnServer turn_server_2(network_thread(),
3871 turn_server_2_internal_address,
3872 turn_server_2_external_address);
3873
3874 PeerConnectionInterface::RTCConfiguration client_1_config;
3875 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3876 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3877 ice_server_1.username = "test";
3878 ice_server_1.password = "test";
3879 client_1_config.servers.push_back(ice_server_1);
3880 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3881 auto customizer1 = rtc::MakeUnique<cricket::TestTurnCustomizer>();
3882 client_1_config.turn_customizer = customizer1.get();
3883
3884 PeerConnectionInterface::RTCConfiguration client_2_config;
3885 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3886 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3887 ice_server_2.username = "test";
3888 ice_server_2.password = "test";
3889 client_2_config.servers.push_back(ice_server_2);
3890 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3891 auto customizer2 = rtc::MakeUnique<cricket::TestTurnCustomizer>();
3892 client_2_config.turn_customizer = customizer2.get();
3893
3894 ASSERT_TRUE(
3895 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3896 ConnectFakeSignaling();
3897
3898 // Set "offer to receive audio/video" without adding any tracks, so we just
3899 // set up ICE/DTLS with no media.
3900 PeerConnectionInterface::RTCOfferAnswerOptions options;
3901 options.offer_to_receive_audio = 1;
3902 options.offer_to_receive_video = 1;
3903 caller()->SetOfferAnswerOptions(options);
3904 caller()->CreateAndSetAndSignalOffer();
3905 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3906
3907 EXPECT_GT(customizer1->allow_channel_data_cnt_, 0u);
3908 EXPECT_GT(customizer1->modify_cnt_, 0u);
3909
3910 EXPECT_GT(customizer2->allow_channel_data_cnt_, 0u);
3911 EXPECT_GT(customizer2->modify_cnt_, 0u);
3912
3913 // Need to free the clients here since they're using things we created on
3914 // the stack.
3915 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
3916 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
3917}
3918
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07003919// Verifies that you can use TCP instead of UDP to connect to a TURN server and
3920// send media between the caller and the callee.
3921TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
3922 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3923 3478};
3924 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3925
3926 // Enable TCP for the fake turn server.
3927 cricket::TestTurnServer turn_server(
3928 network_thread(), turn_server_internal_address,
3929 turn_server_external_address, cricket::PROTO_TCP);
3930
3931 webrtc::PeerConnectionInterface::IceServer ice_server;
3932 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
3933 ice_server.username = "test";
3934 ice_server.password = "test";
3935
3936 PeerConnectionInterface::RTCConfiguration client_1_config;
3937 client_1_config.servers.push_back(ice_server);
3938 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3939
3940 PeerConnectionInterface::RTCConfiguration client_2_config;
3941 client_2_config.servers.push_back(ice_server);
3942 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3943
3944 ASSERT_TRUE(
3945 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3946
3947 // Do normal offer/answer and wait for ICE to complete.
3948 ConnectFakeSignaling();
3949 caller()->AddAudioVideoTracks();
3950 callee()->AddAudioVideoTracks();
3951 caller()->CreateAndSetAndSignalOffer();
3952 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3953 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3954 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3955
3956 MediaExpectations media_expectations;
3957 media_expectations.ExpectBidirectionalAudioAndVideo();
3958 EXPECT_TRUE(ExpectNewFrames(media_expectations));
3959}
3960
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07003961// Verify that a SSLCertificateVerifier passed in through
3962// PeerConnectionDependencies is actually used by the underlying SSL
3963// implementation to determine whether a certificate presented by the TURN
3964// server is accepted by the client. Note that openssladapter_unittest.cc
3965// contains more detailed, lower-level tests.
3966TEST_P(PeerConnectionIntegrationTest,
3967 SSLCertificateVerifierUsedForTurnConnections) {
3968 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3969 3478};
3970 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3971
3972 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
3973 // that host name verification passes on the fake certificate.
3974 cricket::TestTurnServer turn_server(
3975 network_thread(), turn_server_internal_address,
3976 turn_server_external_address, cricket::PROTO_TLS,
3977 /*ignore_bad_certs=*/true, "88.88.88.0");
3978
3979 webrtc::PeerConnectionInterface::IceServer ice_server;
3980 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
3981 ice_server.username = "test";
3982 ice_server.password = "test";
3983
3984 PeerConnectionInterface::RTCConfiguration client_1_config;
3985 client_1_config.servers.push_back(ice_server);
3986 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3987
3988 PeerConnectionInterface::RTCConfiguration client_2_config;
3989 client_2_config.servers.push_back(ice_server);
3990 // Setting the type to kRelay forces the connection to go through a TURN
3991 // server.
3992 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3993
3994 // Get a copy to the pointer so we can verify calls later.
3995 rtc::TestCertificateVerifier* client_1_cert_verifier =
3996 new rtc::TestCertificateVerifier();
3997 client_1_cert_verifier->verify_certificate_ = true;
3998 rtc::TestCertificateVerifier* client_2_cert_verifier =
3999 new rtc::TestCertificateVerifier();
4000 client_2_cert_verifier->verify_certificate_ = true;
4001
4002 // Create the dependencies with the test certificate verifier.
4003 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4004 client_1_deps.tls_cert_verifier =
4005 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4006 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4007 client_2_deps.tls_cert_verifier =
4008 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4009
4010 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4011 client_1_config, std::move(client_1_deps), client_2_config,
4012 std::move(client_2_deps)));
4013 ConnectFakeSignaling();
4014
4015 // Set "offer to receive audio/video" without adding any tracks, so we just
4016 // set up ICE/DTLS with no media.
4017 PeerConnectionInterface::RTCOfferAnswerOptions options;
4018 options.offer_to_receive_audio = 1;
4019 options.offer_to_receive_video = 1;
4020 caller()->SetOfferAnswerOptions(options);
4021 caller()->CreateAndSetAndSignalOffer();
4022 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4023
4024 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4025 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
4026
4027 // Need to free the clients here since they're using things we created on
4028 // the stack.
4029 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
4030 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
4031}
4032
4033TEST_P(PeerConnectionIntegrationTest,
4034 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4035 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4036 3478};
4037 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4038
4039 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4040 // that host name verification passes on the fake certificate.
4041 cricket::TestTurnServer turn_server(
4042 network_thread(), turn_server_internal_address,
4043 turn_server_external_address, cricket::PROTO_TLS,
4044 /*ignore_bad_certs=*/true, "88.88.88.0");
4045
4046 webrtc::PeerConnectionInterface::IceServer ice_server;
4047 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4048 ice_server.username = "test";
4049 ice_server.password = "test";
4050
4051 PeerConnectionInterface::RTCConfiguration client_1_config;
4052 client_1_config.servers.push_back(ice_server);
4053 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4054
4055 PeerConnectionInterface::RTCConfiguration client_2_config;
4056 client_2_config.servers.push_back(ice_server);
4057 // Setting the type to kRelay forces the connection to go through a TURN
4058 // server.
4059 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4060
4061 // Get a copy to the pointer so we can verify calls later.
4062 rtc::TestCertificateVerifier* client_1_cert_verifier =
4063 new rtc::TestCertificateVerifier();
4064 client_1_cert_verifier->verify_certificate_ = false;
4065 rtc::TestCertificateVerifier* client_2_cert_verifier =
4066 new rtc::TestCertificateVerifier();
4067 client_2_cert_verifier->verify_certificate_ = false;
4068
4069 // Create the dependencies with the test certificate verifier.
4070 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4071 client_1_deps.tls_cert_verifier =
4072 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4073 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4074 client_2_deps.tls_cert_verifier =
4075 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4076
4077 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4078 client_1_config, std::move(client_1_deps), client_2_config,
4079 std::move(client_2_deps)));
4080 ConnectFakeSignaling();
4081
4082 // Set "offer to receive audio/video" without adding any tracks, so we just
4083 // set up ICE/DTLS with no media.
4084 PeerConnectionInterface::RTCOfferAnswerOptions options;
4085 options.offer_to_receive_audio = 1;
4086 options.offer_to_receive_video = 1;
4087 caller()->SetOfferAnswerOptions(options);
4088 caller()->CreateAndSetAndSignalOffer();
4089 bool wait_res = true;
4090 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4091 // properly, should be able to just wait for a state of "failed" instead of
4092 // waiting a fixed 10 seconds.
4093 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4094 ASSERT_FALSE(wait_res);
4095
4096 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4097 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
4098
4099 // Need to free the clients here since they're using things we created on
4100 // the stack.
4101 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
4102 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
4103}
4104
deadbeefc964d0b2017-04-03 10:03:35 -07004105// Test that audio and video flow end-to-end when codec names don't use the
4106// expected casing, given that they're supposed to be case insensitive. To test
4107// this, all but one codec is removed from each media description, and its
4108// casing is changed.
4109//
4110// In the past, this has regressed and caused crashes/black video, due to the
4111// fact that code at some layers was doing case-insensitive comparisons and
4112// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004113TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004114 ASSERT_TRUE(CreatePeerConnectionWrappers());
4115 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004116 caller()->AddAudioVideoTracks();
4117 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004118
4119 // Remove all but one audio/video codec (opus and VP8), and change the
4120 // casing of the caller's generated offer.
4121 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4122 cricket::AudioContentDescription* audio =
4123 GetFirstAudioContentDescription(description);
4124 ASSERT_NE(nullptr, audio);
4125 auto audio_codecs = audio->codecs();
4126 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4127 [](const cricket::AudioCodec& codec) {
4128 return codec.name != "opus";
4129 }),
4130 audio_codecs.end());
4131 ASSERT_EQ(1u, audio_codecs.size());
4132 audio_codecs[0].name = "OpUs";
4133 audio->set_codecs(audio_codecs);
4134
4135 cricket::VideoContentDescription* video =
4136 GetFirstVideoContentDescription(description);
4137 ASSERT_NE(nullptr, video);
4138 auto video_codecs = video->codecs();
4139 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4140 [](const cricket::VideoCodec& codec) {
4141 return codec.name != "VP8";
4142 }),
4143 video_codecs.end());
4144 ASSERT_EQ(1u, video_codecs.size());
4145 video_codecs[0].name = "vP8";
4146 video->set_codecs(video_codecs);
4147 });
4148
4149 caller()->CreateAndSetAndSignalOffer();
4150 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4151
4152 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004153 MediaExpectations media_expectations;
4154 media_expectations.ExpectBidirectionalAudioAndVideo();
4155 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004156}
4157
Seth Hampson2f0d7022018-02-20 11:54:42 -08004158TEST_P(PeerConnectionIntegrationTest, GetSources) {
hbos8d609f62017-04-10 07:39:05 -07004159 ASSERT_TRUE(CreatePeerConnectionWrappers());
4160 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004161 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004162 caller()->CreateAndSetAndSignalOffer();
4163 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004164 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004165 MediaExpectations media_expectations;
4166 media_expectations.CalleeExpectsSomeAudio(1);
4167 ASSERT_TRUE(ExpectNewFrames(media_expectations));
hbos8d609f62017-04-10 07:39:05 -07004168 ASSERT_GT(callee()->pc()->GetReceivers().size(), 0u);
4169 auto receiver = callee()->pc()->GetReceivers()[0];
4170 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
4171
4172 auto contributing_sources = receiver->GetSources();
4173 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4174 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4175 contributing_sources[0].source_id());
4176}
4177
deadbeef2f425aa2017-04-14 10:41:32 -07004178// Test that if a track is removed and added again with a different stream ID,
4179// the new stream ID is successfully communicated in SDP and media continues to
4180// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004181// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4182// it will not reuse a transceiver that has already been sending. After creating
4183// a new transceiver it tries to create an offer with two senders of the same
4184// track ids and it fails.
4185TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004186 ASSERT_TRUE(CreatePeerConnectionWrappers());
4187 ConnectFakeSignaling();
4188
4189 rtc::scoped_refptr<MediaStreamInterface> stream_1 =
4190 caller()->pc_factory()->CreateLocalMediaStream("stream_1");
4191 rtc::scoped_refptr<MediaStreamInterface> stream_2 =
4192 caller()->pc_factory()->CreateLocalMediaStream("stream_2");
4193
4194 // Add track using stream 1, do offer/answer.
4195 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4196 caller()->CreateLocalAudioTrack();
4197 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
4198 caller()->pc()->AddTrack(track, {stream_1.get()});
4199 caller()->CreateAndSetAndSignalOffer();
4200 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004201 {
4202 MediaExpectations media_expectations;
4203 media_expectations.CalleeExpectsSomeAudio(1);
4204 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4205 }
deadbeef2f425aa2017-04-14 10:41:32 -07004206 // Remove the sender, and create a new one with the new stream.
4207 caller()->pc()->RemoveTrack(sender);
4208 sender = caller()->pc()->AddTrack(track, {stream_2.get()});
4209 caller()->CreateAndSetAndSignalOffer();
4210 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4211 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004212 {
4213 MediaExpectations media_expectations;
4214 media_expectations.CalleeExpectsSomeAudio();
4215 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4216 }
deadbeef2f425aa2017-04-14 10:41:32 -07004217}
4218
Seth Hampson2f0d7022018-02-20 11:54:42 -08004219TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004220 ASSERT_TRUE(CreatePeerConnectionWrappers());
4221 ConnectFakeSignaling();
4222
4223 auto output = rtc::MakeUnique<testing::NiceMock<MockRtcEventLogOutput>>();
4224 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4225 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4226 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004227 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4228 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004229
Steve Anton15324772018-01-16 10:26:49 -08004230 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004231 caller()->CreateAndSetAndSignalOffer();
4232 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4233}
4234
Steve Antonede9ca52017-10-16 13:04:27 -07004235// Test that if candidates are only signaled by applying full session
4236// descriptions (instead of using AddIceCandidate), the peers can connect to
4237// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004238TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004239 ASSERT_TRUE(CreatePeerConnectionWrappers());
4240 // Each side will signal the session descriptions but not candidates.
4241 ConnectFakeSignalingForSdpOnly();
4242
4243 // Add audio video track and exchange the initial offer/answer with media
4244 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004245 caller()->AddAudioVideoTracks();
4246 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004247 caller()->CreateAndSetAndSignalOffer();
4248
4249 // Wait for all candidates to be gathered on both the caller and callee.
4250 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4251 caller()->ice_gathering_state(), kDefaultTimeout);
4252 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4253 callee()->ice_gathering_state(), kDefaultTimeout);
4254
4255 // The candidates will now be included in the session description, so
4256 // signaling them will start the ICE connection.
4257 caller()->CreateAndSetAndSignalOffer();
4258 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4259
4260 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004261 MediaExpectations media_expectations;
4262 media_expectations.ExpectBidirectionalAudioAndVideo();
4263 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004264}
4265
henrika5f6bf242017-11-01 11:06:56 +01004266// Test that SetAudioPlayout can be used to disable audio playout from the
4267// start, then later enable it. This may be useful, for example, if the caller
4268// needs to play a local ringtone until some event occurs, after which it
4269// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004270TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004271 ASSERT_TRUE(CreatePeerConnectionWrappers());
4272 ConnectFakeSignaling();
4273
4274 // Set up audio-only call where audio playout is disabled on caller's side.
4275 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004276 caller()->AddAudioTrack();
4277 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004278 caller()->CreateAndSetAndSignalOffer();
4279 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4280
4281 // Pump messages for a second.
4282 WAIT(false, 1000);
4283 // Since audio playout is disabled, the caller shouldn't have received
4284 // anything (at the playout level, at least).
4285 EXPECT_EQ(0, caller()->audio_frames_received());
4286 // As a sanity check, make sure the callee (for which playout isn't disabled)
4287 // did still see frames on its audio level.
4288 ASSERT_GT(callee()->audio_frames_received(), 0);
4289
4290 // Enable playout again, and ensure audio starts flowing.
4291 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004292 MediaExpectations media_expectations;
4293 media_expectations.ExpectBidirectionalAudio();
4294 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004295}
4296
4297double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4298 auto report = pc->NewGetStats();
4299 auto track_stats_list =
4300 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4301 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4302 for (const auto* track_stats : track_stats_list) {
4303 if (track_stats->remote_source.is_defined() &&
4304 *track_stats->remote_source) {
4305 remote_track_stats = track_stats;
4306 break;
4307 }
4308 }
4309
4310 if (!remote_track_stats->total_audio_energy.is_defined()) {
4311 return 0.0;
4312 }
4313 return *remote_track_stats->total_audio_energy;
4314}
4315
4316// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4317// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004318TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004319 DisableAudioPlayoutStillGeneratesAudioStats) {
4320 ASSERT_TRUE(CreatePeerConnectionWrappers());
4321 ConnectFakeSignaling();
4322
4323 // Set up audio-only call where playout is disabled but audio-processing is
4324 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004325 caller()->AddAudioTrack();
4326 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004327 caller()->pc()->SetAudioPlayout(false);
4328
4329 caller()->CreateAndSetAndSignalOffer();
4330 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4331
4332 // Wait for the callee to receive audio stats.
4333 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4334}
4335
henrika4f167df2017-11-01 14:45:55 +01004336// Test that SetAudioRecording can be used to disable audio recording from the
4337// start, then later enable it. This may be useful, for example, if the caller
4338// wants to ensure that no audio resources are active before a certain state
4339// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004340TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01004341 ASSERT_TRUE(CreatePeerConnectionWrappers());
4342 ConnectFakeSignaling();
4343
4344 // Set up audio-only call where audio recording is disabled on caller's side.
4345 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08004346 caller()->AddAudioTrack();
4347 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01004348 caller()->CreateAndSetAndSignalOffer();
4349 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4350
4351 // Pump messages for a second.
4352 WAIT(false, 1000);
4353 // Since caller has disabled audio recording, the callee shouldn't have
4354 // received anything.
4355 EXPECT_EQ(0, callee()->audio_frames_received());
4356 // As a sanity check, make sure the caller did still see frames on its
4357 // audio level since audio recording is enabled on the calle side.
4358 ASSERT_GT(caller()->audio_frames_received(), 0);
4359
4360 // Enable audio recording again, and ensure audio starts flowing.
4361 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004362 MediaExpectations media_expectations;
4363 media_expectations.ExpectBidirectionalAudio();
4364 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01004365}
4366
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004367// Test that after closing PeerConnections, they stop sending any packets (ICE,
4368// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004369TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004370 // Set up audio/video/data, wait for some frames to be received.
4371 ASSERT_TRUE(CreatePeerConnectionWrappers());
4372 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004373 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004374#ifdef HAVE_SCTP
4375 caller()->CreateDataChannel();
4376#endif
4377 caller()->CreateAndSetAndSignalOffer();
4378 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004379 MediaExpectations media_expectations;
4380 media_expectations.CalleeExpectsSomeAudioAndVideo();
4381 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004382 // Close PeerConnections.
4383 caller()->pc()->Close();
4384 callee()->pc()->Close();
4385 // Pump messages for a second, and ensure no new packets end up sent.
4386 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4387 WAIT(false, 1000);
4388 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4389 EXPECT_EQ(sent_packets_a, sent_packets_b);
4390}
4391
Steve Anton7eca0932018-03-30 15:18:41 -07004392// Test that transport stats are generated by the RTCStatsCollector for a
4393// connection that only involves data channels. This is a regression test for
4394// crbug.com/826972.
4395#ifdef HAVE_SCTP
4396TEST_P(PeerConnectionIntegrationTest,
4397 TransportStatsReportedForDataChannelOnlyConnection) {
4398 ASSERT_TRUE(CreatePeerConnectionWrappers());
4399 ConnectFakeSignaling();
4400 caller()->CreateDataChannel();
4401
4402 caller()->CreateAndSetAndSignalOffer();
4403 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4404 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4405
4406 auto caller_report = caller()->NewGetStats();
4407 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4408 auto callee_report = callee()->NewGetStats();
4409 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4410}
4411#endif // HAVE_SCTP
4412
Qingsi Wang7685e862018-06-11 20:15:46 -07004413TEST_P(PeerConnectionIntegrationTest,
4414 IceEventsGeneratedAndLoggedInRtcEventLog) {
4415 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4416 ConnectFakeSignaling();
4417 PeerConnectionInterface::RTCOfferAnswerOptions options;
4418 options.offer_to_receive_audio = 1;
4419 caller()->SetOfferAnswerOptions(options);
4420 caller()->CreateAndSetAndSignalOffer();
4421 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4422 ASSERT_NE(nullptr, caller()->event_log_factory());
4423 ASSERT_NE(nullptr, callee()->event_log_factory());
4424 webrtc::FakeRtcEventLog* caller_event_log =
4425 static_cast<webrtc::FakeRtcEventLog*>(
4426 caller()->event_log_factory()->last_log_created());
4427 webrtc::FakeRtcEventLog* callee_event_log =
4428 static_cast<webrtc::FakeRtcEventLog*>(
4429 callee()->event_log_factory()->last_log_created());
4430 ASSERT_NE(nullptr, caller_event_log);
4431 ASSERT_NE(nullptr, callee_event_log);
4432 int caller_ice_config_count = caller_event_log->GetEventCount(
4433 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4434 int caller_ice_event_count = caller_event_log->GetEventCount(
4435 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4436 int callee_ice_config_count = callee_event_log->GetEventCount(
4437 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4438 int callee_ice_event_count = callee_event_log->GetEventCount(
4439 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4440 EXPECT_LT(0, caller_ice_config_count);
4441 EXPECT_LT(0, caller_ice_event_count);
4442 EXPECT_LT(0, callee_ice_config_count);
4443 EXPECT_LT(0, callee_ice_event_count);
4444}
4445
Seth Hampson2f0d7022018-02-20 11:54:42 -08004446INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4447 PeerConnectionIntegrationTest,
4448 Values(SdpSemantics::kPlanB,
4449 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08004450
Steve Anton74255ff2018-01-24 18:32:57 -08004451// Tests that verify interoperability between Plan B and Unified Plan
4452// PeerConnections.
4453class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004454 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08004455 public ::testing::WithParamInterface<
4456 std::tuple<SdpSemantics, SdpSemantics>> {
4457 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004458 // Setting the SdpSemantics for the base test to kDefault does not matter
4459 // because we specify not to use the test semantics when creating
4460 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08004461 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07004462 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08004463 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08004464 callee_semantics_(std::get<1>(GetParam())) {}
4465
4466 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07004467 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4468 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08004469 }
4470
4471 const SdpSemantics caller_semantics_;
4472 const SdpSemantics callee_semantics_;
4473};
4474
4475TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4476 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4477 ConnectFakeSignaling();
4478
4479 caller()->CreateAndSetAndSignalOffer();
4480 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4481}
4482
4483TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4484 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4485 ConnectFakeSignaling();
4486 auto audio_sender = caller()->AddAudioTrack();
4487
4488 caller()->CreateAndSetAndSignalOffer();
4489 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4490
4491 // Verify that one audio receiver has been created on the remote and that it
4492 // has the same track ID as the sending track.
4493 auto receivers = callee()->pc()->GetReceivers();
4494 ASSERT_EQ(1u, receivers.size());
4495 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4496 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4497
Seth Hampson2f0d7022018-02-20 11:54:42 -08004498 MediaExpectations media_expectations;
4499 media_expectations.CalleeExpectsSomeAudio();
4500 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004501}
4502
4503TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4504 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4505 ConnectFakeSignaling();
4506 auto video_sender = caller()->AddVideoTrack();
4507 auto audio_sender = caller()->AddAudioTrack();
4508
4509 caller()->CreateAndSetAndSignalOffer();
4510 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4511
4512 // Verify that one audio and one video receiver have been created on the
4513 // remote and that they have the same track IDs as the sending tracks.
4514 auto audio_receivers =
4515 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4516 ASSERT_EQ(1u, audio_receivers.size());
4517 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4518 auto video_receivers =
4519 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4520 ASSERT_EQ(1u, video_receivers.size());
4521 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4522
Seth Hampson2f0d7022018-02-20 11:54:42 -08004523 MediaExpectations media_expectations;
4524 media_expectations.CalleeExpectsSomeAudioAndVideo();
4525 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004526}
4527
4528TEST_P(PeerConnectionIntegrationInteropTest,
4529 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4530 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4531 ConnectFakeSignaling();
4532 caller()->AddAudioVideoTracks();
4533 callee()->AddAudioVideoTracks();
4534
4535 caller()->CreateAndSetAndSignalOffer();
4536 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4537
Seth Hampson2f0d7022018-02-20 11:54:42 -08004538 MediaExpectations media_expectations;
4539 media_expectations.ExpectBidirectionalAudioAndVideo();
4540 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004541}
4542
4543TEST_P(PeerConnectionIntegrationInteropTest,
4544 ReverseRolesOneAudioLocalToOneVideoRemote) {
4545 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4546 ConnectFakeSignaling();
4547 caller()->AddAudioTrack();
4548 callee()->AddVideoTrack();
4549
4550 caller()->CreateAndSetAndSignalOffer();
4551 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4552
4553 // Verify that only the audio track has been negotiated.
4554 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4555 // Might also check that the callee's NegotiationNeeded flag is set.
4556
4557 // Reverse roles.
4558 callee()->CreateAndSetAndSignalOffer();
4559 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4560
Seth Hampson2f0d7022018-02-20 11:54:42 -08004561 MediaExpectations media_expectations;
4562 media_expectations.CallerExpectsSomeVideo();
4563 media_expectations.CalleeExpectsSomeAudio();
4564 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004565}
4566
Harald Alvestrand8ebba742018-05-31 14:00:34 +02004567// Test getting the usage fingerprint for a simple test case.
4568TEST_P(PeerConnectionIntegrationTest, UsageFingerprintHistogram) {
4569 ASSERT_TRUE(CreatePeerConnectionWrappers());
4570 ConnectFakeSignaling();
4571 // Register UMA observer before signaling begins.
4572 rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
4573 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
4574 caller()->pc()->RegisterUMAObserver(caller_observer);
4575 rtc::scoped_refptr<webrtc::FakeMetricsObserver> callee_observer =
4576 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
4577 callee()->pc()->RegisterUMAObserver(callee_observer);
4578 caller()->AddAudioTrack();
4579 caller()->AddVideoTrack();
4580 caller()->CreateAndSetAndSignalOffer();
4581 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4582 caller()->pc()->Close();
4583 callee()->pc()->Close();
4584 int expected_fingerprint = MakeUsageFingerprint(
4585 {PeerConnection::UsageEvent::AUDIO_ADDED,
4586 PeerConnection::UsageEvent::VIDEO_ADDED,
4587 PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
4588 PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
4589 PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
4590 PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
4591 PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
4592 PeerConnection::UsageEvent::CLOSE_CALLED});
4593 EXPECT_TRUE(caller_observer->ExpectOnlySingleEnumCount(
4594 webrtc::kEnumCounterUsagePattern, expected_fingerprint));
4595 EXPECT_TRUE(callee_observer->ExpectOnlySingleEnumCount(
4596 webrtc::kEnumCounterUsagePattern, expected_fingerprint));
4597}
4598
Steve Antonba42e992018-04-09 14:10:01 -07004599INSTANTIATE_TEST_CASE_P(
4600 PeerConnectionIntegrationTest,
4601 PeerConnectionIntegrationInteropTest,
4602 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4603 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4604
4605// Test that if the Unified Plan side offers two video tracks then the Plan B
4606// side will only see the first one and ignore the second.
4607TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07004608 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4609 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08004610 ConnectFakeSignaling();
4611 auto first_sender = caller()->AddVideoTrack();
4612 caller()->AddVideoTrack();
4613
4614 caller()->CreateAndSetAndSignalOffer();
4615 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4616
4617 // Verify that there is only one receiver and it corresponds to the first
4618 // added track.
4619 auto receivers = callee()->pc()->GetReceivers();
4620 ASSERT_EQ(1u, receivers.size());
4621 EXPECT_TRUE(receivers[0]->track()->enabled());
4622 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4623
Seth Hampson2f0d7022018-02-20 11:54:42 -08004624 MediaExpectations media_expectations;
4625 media_expectations.CalleeExpectsSomeVideo();
4626 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004627}
4628
deadbeef1dcb1642017-03-29 21:08:16 -07004629} // namespace
4630
4631#endif // if !defined(THREAD_SANITIZER)