blob: cc97e4ef7d2f471d7e7905a6dcc6ef2002ace7e8 [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/mediastreaminterface.h"
28#include "api/peerconnectioninterface.h"
Steve Anton8c0f7a72017-10-03 10:03:10 -070029#include "api/peerconnectionproxy.h"
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010030#include "api/rtpreceiverinterface.h"
Anders Carlsson67537952018-05-03 11:28:29 +020031#include "api/video_codecs/builtin_video_decoder_factory.h"
32#include "api/video_codecs/builtin_video_encoder_factory.h"
33#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070034#include "call/call.h"
35#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
36#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "media/engine/fakewebrtcvideoengine.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070038#include "media/engine/webrtcmediaengine.h"
39#include "modules/audio_processing/include/audio_processing.h"
Zach Stein6fcdc2f2018-08-23 16:25:55 -070040#include "p2p/base/mockasyncresolver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "p2p/base/p2pconstants.h"
42#include "p2p/base/portinterface.h"
Steve Antonede9ca52017-10-16 13:04:27 -070043#include "p2p/base/teststunserver.h"
Jonas Orelandbdcee282017-10-10 14:01:40 +020044#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020045#include "p2p/base/testturnserver.h"
46#include "p2p/client/basicportallocator.h"
47#include "pc/dtmfsender.h"
48#include "pc/localaudiosource.h"
49#include "pc/mediasession.h"
50#include "pc/peerconnection.h"
51#include "pc/peerconnectionfactory.h"
Seth Hampson2f0d7022018-02-20 11:54:42 -080052#include "pc/rtpmediautils.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080053#include "pc/sessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020054#include "pc/test/fakeaudiocapturemodule.h"
Niels Möller0f405822018-05-17 09:16:41 +020055#include "pc/test/fakeperiodicvideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020056#include "pc/test/fakertccertificategenerator.h"
57#include "pc/test/fakevideotrackrenderer.h"
58#include "pc/test/mockpeerconnectionobservers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020059#include "rtc_base/fakenetwork.h"
Steve Antonede9ca52017-10-16 13:04:27 -070060#include "rtc_base/firewallsocketserver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020061#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020062#include "rtc_base/numerics/safe_conversions.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"
Qingsi Wang7fc821d2018-07-12 12:54:53 -070065#include "system_wrappers/include/metrics_default.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020066#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070067
68using cricket::ContentInfo;
69using cricket::FakeWebRtcVideoDecoder;
70using cricket::FakeWebRtcVideoDecoderFactory;
71using cricket::FakeWebRtcVideoEncoder;
72using cricket::FakeWebRtcVideoEncoderFactory;
73using cricket::MediaContentDescription;
Steve Antondf527fd2018-04-27 15:52:03 -070074using cricket::StreamParams;
Steve Antonede9ca52017-10-16 13:04:27 -070075using rtc::SocketAddress;
Seth Hampson2f0d7022018-02-20 11:54:42 -080076using ::testing::Combine;
Steve Antonede9ca52017-10-16 13:04:27 -070077using ::testing::ElementsAre;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070078using ::testing::Return;
79using ::testing::SetArgPointee;
Steve Antonede9ca52017-10-16 13:04:27 -070080using ::testing::Values;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070081using ::testing::_;
deadbeef1dcb1642017-03-29 21:08:16 -070082using webrtc::DataBuffer;
83using webrtc::DataChannelInterface;
84using webrtc::DtmfSender;
85using webrtc::DtmfSenderInterface;
86using webrtc::DtmfSenderObserverInterface;
Steve Anton15324772018-01-16 10:26:49 -080087using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-29 21:08:16 -070088using webrtc::MediaConstraintsInterface;
89using webrtc::MediaStreamInterface;
90using webrtc::MediaStreamTrackInterface;
91using webrtc::MockCreateSessionDescriptionObserver;
92using webrtc::MockDataChannelObserver;
93using webrtc::MockSetSessionDescriptionObserver;
94using webrtc::MockStatsObserver;
95using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 10:03:10 -070096using webrtc::PeerConnection;
deadbeef1dcb1642017-03-29 21:08:16 -070097using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-24 18:32:57 -080098using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070099using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 10:03:10 -0700100using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 10:26:49 -0800101using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 15:18:41 -0700102using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-24 18:32:57 -0800103using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100104using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800105using webrtc::RtpSenderInterface;
106using webrtc::RtpTransceiverDirection;
107using webrtc::RtpTransceiverInit;
108using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-17 17:41:02 -0800109using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 10:27:41 -0800110using webrtc::SdpType;
deadbeef1dcb1642017-03-29 21:08:16 -0700111using webrtc::SessionDescriptionInterface;
112using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 10:26:49 -0800113using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-29 21:08:16 -0700114
115namespace {
116
117static const int kDefaultTimeout = 10000;
118static const int kMaxWaitForStatsMs = 3000;
119static const int kMaxWaitForActivationMs = 5000;
120static const int kMaxWaitForFramesMs = 10000;
121// Default number of audio/video frames to wait for before considering a test
122// successful.
123static const int kDefaultExpectedAudioFrameCount = 3;
124static const int kDefaultExpectedVideoFrameCount = 3;
125
deadbeef1dcb1642017-03-29 21:08:16 -0700126static const char kDataChannelLabel[] = "data_channel";
127
128// SRTP cipher name negotiated by the tests. This must be updated if the
129// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700130static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700131static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
132
Steve Antonede9ca52017-10-16 13:04:27 -0700133static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
134
deadbeef1dcb1642017-03-29 21:08:16 -0700135// Helper function for constructing offer/answer options to initiate an ICE
136// restart.
137PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
138 PeerConnectionInterface::RTCOfferAnswerOptions options;
139 options.ice_restart = true;
140 return options;
141}
142
deadbeefd8ad7882017-04-18 16:01:17 -0700143// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
144// attribute from received SDP, simulating a legacy endpoint.
145void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
146 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800147 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700148 }
149 desc->set_msid_supported(false);
150}
151
Seth Hampson5897a6e2018-04-03 11:16:33 -0700152// Removes all stream information besides the stream ids, simulating an
153// endpoint that only signals a=msid lines to convey stream_ids.
154void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
155 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700156 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700157 std::vector<std::string> stream_ids;
158 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700159 const StreamParams& first_stream =
160 content.media_description()->streams()[0];
161 track_id = first_stream.id;
162 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700163 }
164 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700165 StreamParams new_stream;
166 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700167 new_stream.set_stream_ids(stream_ids);
168 content.media_description()->AddStream(new_stream);
169 }
170}
171
zhihuangf8164932017-05-19 13:09:47 -0700172int FindFirstMediaStatsIndexByKind(
173 const std::string& kind,
174 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
175 media_stats_vec) {
176 for (size_t i = 0; i < media_stats_vec.size(); i++) {
177 if (media_stats_vec[i]->kind.ValueToString() == kind) {
178 return i;
179 }
180 }
181 return -1;
182}
183
deadbeef1dcb1642017-03-29 21:08:16 -0700184class SignalingMessageReceiver {
185 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800186 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700187 virtual void ReceiveIceMessage(const std::string& sdp_mid,
188 int sdp_mline_index,
189 const std::string& msg) = 0;
190
191 protected:
192 SignalingMessageReceiver() {}
193 virtual ~SignalingMessageReceiver() {}
194};
195
196class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
197 public:
198 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
199 : expected_media_type_(media_type) {}
200
201 void OnFirstPacketReceived(cricket::MediaType media_type) override {
202 ASSERT_EQ(expected_media_type_, media_type);
203 first_packet_received_ = true;
204 }
205
206 bool first_packet_received() const { return first_packet_received_; }
207
208 virtual ~MockRtpReceiverObserver() {}
209
210 private:
211 bool first_packet_received_ = false;
212 cricket::MediaType expected_media_type_;
213};
214
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700215// Used by PeerConnectionWrapper::OnIceCandidate to allow a test to modify an
216// ICE candidate before it is signaled.
217class IceCandidateReplacerInterface {
218 public:
219 virtual ~IceCandidateReplacerInterface() = default;
220 // Return nullptr to drop the candidate (it won't be signaled to the other
221 // side).
222 virtual std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
223 const webrtc::IceCandidateInterface*) = 0;
224};
225
deadbeef1dcb1642017-03-29 21:08:16 -0700226// Helper class that wraps a peer connection, observes it, and can accept
227// signaling messages from another wrapper.
228//
229// Uses a fake network, fake A/V capture, and optionally fake
230// encoders/decoders, though they aren't used by default since they don't
231// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700232// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800233// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700234class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800235 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700236 public:
237 // Different factory methods for convenience.
238 // TODO(deadbeef): Could use the pattern of:
239 //
240 // PeerConnectionWrapper =
241 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
242 //
243 // To reduce some code duplication.
244 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
245 const std::string& debug_name,
246 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
247 rtc::Thread* network_thread,
248 rtc::Thread* worker_thread) {
249 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700250 webrtc::PeerConnectionDependencies dependencies(nullptr);
251 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200252 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
253 worker_thread, nullptr)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700254 delete client;
255 return nullptr;
256 }
257 return client;
258 }
259
deadbeef2f425aa2017-04-14 10:41:32 -0700260 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
261 return peer_connection_factory_.get();
262 }
263
deadbeef1dcb1642017-03-29 21:08:16 -0700264 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
265
266 // If a signaling message receiver is set (via ConnectFakeSignaling), this
267 // will set the whole offer/answer exchange in motion. Just need to wait for
268 // the signaling state to reach "stable".
269 void CreateAndSetAndSignalOffer() {
270 auto offer = CreateOffer();
271 ASSERT_NE(nullptr, offer);
272 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
273 }
274
275 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
276 // when a remote offer is received (via fake signaling) and an answer is
277 // generated. By default, uses default options.
278 void SetOfferAnswerOptions(
279 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
280 offer_answer_options_ = options;
281 }
282
283 // Set a callback to be invoked when SDP is received via the fake signaling
284 // channel, which provides an opportunity to munge (modify) the SDP. This is
285 // used to test SDP being applied that a PeerConnection would normally not
286 // generate, but a non-JSEP endpoint might.
287 void SetReceivedSdpMunger(
288 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100289 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700290 }
291
deadbeefc964d0b2017-04-03 10:03:35 -0700292 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700293 // generated.
294 void SetGeneratedSdpMunger(
295 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100296 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700297 }
298
Seth Hampson2f0d7022018-02-20 11:54:42 -0800299 // Set a callback to be invoked when a remote offer is received via the fake
300 // signaling channel. This provides an opportunity to change the
301 // PeerConnection state before an answer is created and sent to the caller.
302 void SetRemoteOfferHandler(std::function<void()> handler) {
303 remote_offer_handler_ = std::move(handler);
304 }
305
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700306 void SetLocalIceCandidateReplacer(
307 std::unique_ptr<IceCandidateReplacerInterface> replacer) {
308 local_ice_candidate_replacer_ = std::move(replacer);
309 }
310
Steve Antonede9ca52017-10-16 13:04:27 -0700311 // Every ICE connection state in order that has been seen by the observer.
312 std::vector<PeerConnectionInterface::IceConnectionState>
313 ice_connection_state_history() const {
314 return ice_connection_state_history_;
315 }
Steve Anton6f25b092017-10-23 09:39:20 -0700316 void clear_ice_connection_state_history() {
317 ice_connection_state_history_.clear();
318 }
Steve Antonede9ca52017-10-16 13:04:27 -0700319
320 // Every ICE gathering state in order that has been seen by the observer.
321 std::vector<PeerConnectionInterface::IceGatheringState>
322 ice_gathering_state_history() const {
323 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700324 }
325
Steve Anton15324772018-01-16 10:26:49 -0800326 void AddAudioVideoTracks() {
327 AddAudioTrack();
328 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700329 }
330
Steve Anton74255ff2018-01-24 18:32:57 -0800331 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
332 return AddTrack(CreateLocalAudioTrack());
333 }
deadbeef1dcb1642017-03-29 21:08:16 -0700334
Steve Anton74255ff2018-01-24 18:32:57 -0800335 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
336 return AddTrack(CreateLocalVideoTrack());
337 }
deadbeef1dcb1642017-03-29 21:08:16 -0700338
339 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200340 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700341 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200342 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700343 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200344 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700345 // TODO(perkj): Test audio source when it is implemented. Currently audio
346 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700347 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700348 source);
349 }
350
351 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Niels Möller5c7efe72018-05-11 10:34:46 +0200352 return CreateLocalVideoTrackInternal(
353 webrtc::FakePeriodicVideoSource::Config());
deadbeef1dcb1642017-03-29 21:08:16 -0700354 }
355
356 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200357 CreateLocalVideoTrackWithConfig(
358 webrtc::FakePeriodicVideoSource::Config config) {
359 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700360 }
361
362 rtc::scoped_refptr<webrtc::VideoTrackInterface>
363 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200364 webrtc::FakePeriodicVideoSource::Config config;
365 config.rotation = rotation;
366 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700367 }
368
Steve Anton74255ff2018-01-24 18:32:57 -0800369 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
370 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800371 const std::vector<std::string>& stream_ids = {}) {
372 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800373 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800374 return result.MoveValue();
375 }
376
377 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
378 cricket::MediaType media_type) {
379 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
380 for (auto receiver : pc()->GetReceivers()) {
381 if (receiver->media_type() == media_type) {
382 receivers.push_back(receiver);
383 }
384 }
385 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700386 }
387
Seth Hampson2f0d7022018-02-20 11:54:42 -0800388 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
389 cricket::MediaType media_type) {
390 for (auto transceiver : pc()->GetTransceivers()) {
391 if (transceiver->receiver()->media_type() == media_type) {
392 return transceiver;
393 }
394 }
395 return nullptr;
396 }
397
deadbeef1dcb1642017-03-29 21:08:16 -0700398 bool SignalingStateStable() {
399 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
400 }
401
402 void CreateDataChannel() { CreateDataChannel(nullptr); }
403
404 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700405 CreateDataChannel(kDataChannelLabel, init);
406 }
407
408 void CreateDataChannel(const std::string& label,
409 const webrtc::DataChannelInit* init) {
410 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700411 ASSERT_TRUE(data_channel_.get() != nullptr);
412 data_observer_.reset(new MockDataChannelObserver(data_channel_));
413 }
414
415 DataChannelInterface* data_channel() { return data_channel_; }
416 const MockDataChannelObserver* data_observer() const {
417 return data_observer_.get();
418 }
419
420 int audio_frames_received() const {
421 return fake_audio_capture_module_->frames_received();
422 }
423
424 // Takes minimum of video frames received for each track.
425 //
426 // Can be used like:
427 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
428 //
429 // To ensure that all video tracks received at least a certain number of
430 // frames.
431 int min_video_frames_received_per_track() const {
432 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200433 if (fake_video_renderers_.empty()) {
434 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700435 }
deadbeef1dcb1642017-03-29 21:08:16 -0700436
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200437 for (const auto& pair : fake_video_renderers_) {
438 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700439 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200440 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700441 }
442
443 // Returns a MockStatsObserver in a state after stats gathering finished,
444 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700445 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700446 webrtc::MediaStreamTrackInterface* track) {
447 rtc::scoped_refptr<MockStatsObserver> observer(
448 new rtc::RefCountedObject<MockStatsObserver>());
449 EXPECT_TRUE(peer_connection_->GetStats(
450 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
451 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
452 return observer;
453 }
454
455 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700456 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
457 return OldGetStatsForTrack(nullptr);
458 }
459
460 // Synchronously gets stats and returns them. If it times out, fails the test
461 // and returns null.
462 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
463 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
464 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
465 peer_connection_->GetStats(callback);
466 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
467 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700468 }
469
470 int rendered_width() {
471 EXPECT_FALSE(fake_video_renderers_.empty());
472 return fake_video_renderers_.empty()
473 ? 0
474 : fake_video_renderers_.begin()->second->width();
475 }
476
477 int rendered_height() {
478 EXPECT_FALSE(fake_video_renderers_.empty());
479 return fake_video_renderers_.empty()
480 ? 0
481 : fake_video_renderers_.begin()->second->height();
482 }
483
484 double rendered_aspect_ratio() {
485 if (rendered_height() == 0) {
486 return 0.0;
487 }
488 return static_cast<double>(rendered_width()) / rendered_height();
489 }
490
491 webrtc::VideoRotation rendered_rotation() {
492 EXPECT_FALSE(fake_video_renderers_.empty());
493 return fake_video_renderers_.empty()
494 ? webrtc::kVideoRotation_0
495 : fake_video_renderers_.begin()->second->rotation();
496 }
497
498 int local_rendered_width() {
499 return local_video_renderer_ ? local_video_renderer_->width() : 0;
500 }
501
502 int local_rendered_height() {
503 return local_video_renderer_ ? local_video_renderer_->height() : 0;
504 }
505
506 double local_rendered_aspect_ratio() {
507 if (local_rendered_height() == 0) {
508 return 0.0;
509 }
510 return static_cast<double>(local_rendered_width()) /
511 local_rendered_height();
512 }
513
514 size_t number_of_remote_streams() {
515 if (!pc()) {
516 return 0;
517 }
518 return pc()->remote_streams()->count();
519 }
520
521 StreamCollectionInterface* remote_streams() const {
522 if (!pc()) {
523 ADD_FAILURE();
524 return nullptr;
525 }
526 return pc()->remote_streams();
527 }
528
529 StreamCollectionInterface* local_streams() {
530 if (!pc()) {
531 ADD_FAILURE();
532 return nullptr;
533 }
534 return pc()->local_streams();
535 }
536
537 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
538 return pc()->signaling_state();
539 }
540
541 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
542 return pc()->ice_connection_state();
543 }
544
545 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
546 return pc()->ice_gathering_state();
547 }
548
549 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
550 // GetReceivers. They're updated automatically when a remote offer/answer
551 // from the fake signaling channel is applied, or when
552 // ResetRtpReceiverObservers below is called.
553 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
554 rtp_receiver_observers() {
555 return rtp_receiver_observers_;
556 }
557
558 void ResetRtpReceiverObservers() {
559 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100560 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
561 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700562 std::unique_ptr<MockRtpReceiverObserver> observer(
563 new MockRtpReceiverObserver(receiver->media_type()));
564 receiver->SetObserver(observer.get());
565 rtp_receiver_observers_.push_back(std::move(observer));
566 }
567 }
568
Steve Antonede9ca52017-10-16 13:04:27 -0700569 rtc::FakeNetworkManager* network() const {
570 return fake_network_manager_.get();
571 }
572 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
573
Qingsi Wang7685e862018-06-11 20:15:46 -0700574 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
575 return event_log_factory_;
576 }
577
deadbeef1dcb1642017-03-29 21:08:16 -0700578 private:
579 explicit PeerConnectionWrapper(const std::string& debug_name)
580 : debug_name_(debug_name) {}
581
Niels Möllerf06f9232018-08-07 12:32:18 +0200582 bool Init(const PeerConnectionFactory::Options* options,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700583 const PeerConnectionInterface::RTCConfiguration* config,
584 webrtc::PeerConnectionDependencies dependencies,
585 rtc::Thread* network_thread,
Qingsi Wang7685e862018-06-11 20:15:46 -0700586 rtc::Thread* worker_thread,
587 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700588 // There's an error in this test code if Init ends up being called twice.
589 RTC_DCHECK(!peer_connection_);
590 RTC_DCHECK(!peer_connection_factory_);
591
592 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700593 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700594
595 std::unique_ptr<cricket::PortAllocator> port_allocator(
596 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700597 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700598 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
599 if (!fake_audio_capture_module_) {
600 return false;
601 }
deadbeef1dcb1642017-03-29 21:08:16 -0700602 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700603
604 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
605 pc_factory_dependencies.network_thread = network_thread;
606 pc_factory_dependencies.worker_thread = worker_thread;
607 pc_factory_dependencies.signaling_thread = signaling_thread;
608 pc_factory_dependencies.media_engine =
609 cricket::WebRtcMediaEngineFactory::Create(
610 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
611 fake_audio_capture_module_),
612 webrtc::CreateBuiltinAudioEncoderFactory(),
613 webrtc::CreateBuiltinAudioDecoderFactory(),
614 webrtc::CreateBuiltinVideoEncoderFactory(),
615 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
616 webrtc::AudioProcessingBuilder().Create());
617 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
618 if (event_log_factory) {
619 event_log_factory_ = event_log_factory.get();
620 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
621 } else {
622 pc_factory_dependencies.event_log_factory =
623 webrtc::CreateRtcEventLogFactory();
624 }
625 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
626 std::move(pc_factory_dependencies));
627
deadbeef1dcb1642017-03-29 21:08:16 -0700628 if (!peer_connection_factory_) {
629 return false;
630 }
631 if (options) {
632 peer_connection_factory_->SetOptions(*options);
633 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800634 if (config) {
635 sdp_semantics_ = config->sdp_semantics;
636 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700637
638 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200639 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700640 return peer_connection_.get() != nullptr;
641 }
642
643 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700644 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700645 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700646 PeerConnectionInterface::RTCConfiguration modified_config;
647 // If |config| is null, this will result in a default configuration being
648 // used.
649 if (config) {
650 modified_config = *config;
651 }
652 // Disable resolution adaptation; we don't want it interfering with the
653 // test results.
654 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
655 // ratios and not specific resolutions, is this even necessary?
656 modified_config.set_cpu_adaptation(false);
657
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700658 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700659 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700660 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700661 }
662
663 void set_signaling_message_receiver(
664 SignalingMessageReceiver* signaling_message_receiver) {
665 signaling_message_receiver_ = signaling_message_receiver;
666 }
667
668 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
669
Steve Antonede9ca52017-10-16 13:04:27 -0700670 void set_signal_ice_candidates(bool signal) {
671 signal_ice_candidates_ = signal;
672 }
673
deadbeef1dcb1642017-03-29 21:08:16 -0700674 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200675 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700676 // Set max frame rate to 10fps to reduce the risk of test flakiness.
677 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200678 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700679
Niels Möller5c7efe72018-05-11 10:34:46 +0200680 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200681 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
682 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700683 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200684 peer_connection_factory_->CreateVideoTrack(
685 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700686 if (!local_video_renderer_) {
687 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
688 }
689 return track;
690 }
691
692 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100693 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800694 std::unique_ptr<SessionDescriptionInterface> desc =
695 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700696 if (received_sdp_munger_) {
697 received_sdp_munger_(desc->description());
698 }
699
700 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
701 // Setting a remote description may have changed the number of receivers,
702 // so reset the receiver observers.
703 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800704 if (remote_offer_handler_) {
705 remote_offer_handler_();
706 }
deadbeef1dcb1642017-03-29 21:08:16 -0700707 auto answer = CreateAnswer();
708 ASSERT_NE(nullptr, answer);
709 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
710 }
711
712 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100713 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800714 std::unique_ptr<SessionDescriptionInterface> desc =
715 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700716 if (received_sdp_munger_) {
717 received_sdp_munger_(desc->description());
718 }
719
720 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
721 // Set the RtpReceiverObserver after receivers are created.
722 ResetRtpReceiverObservers();
723 }
724
725 // Returns null on failure.
726 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
727 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
728 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
729 pc()->CreateOffer(observer, offer_answer_options_);
730 return WaitForDescriptionFromObserver(observer);
731 }
732
733 // Returns null on failure.
734 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
735 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
736 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
737 pc()->CreateAnswer(observer, offer_answer_options_);
738 return WaitForDescriptionFromObserver(observer);
739 }
740
741 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100742 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700743 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
744 if (!observer->result()) {
745 return nullptr;
746 }
747 auto description = observer->MoveDescription();
748 if (generated_sdp_munger_) {
749 generated_sdp_munger_(description->description());
750 }
751 return description;
752 }
753
754 // Setting the local description and sending the SDP message over the fake
755 // signaling channel are combined into the same method because the SDP
756 // message needs to be sent as soon as SetLocalDescription finishes, without
757 // waiting for the observer to be called. This ensures that ICE candidates
758 // don't outrace the description.
759 bool SetLocalDescriptionAndSendSdpMessage(
760 std::unique_ptr<SessionDescriptionInterface> desc) {
761 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
762 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100763 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800764 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700765 std::string sdp;
766 EXPECT_TRUE(desc->ToString(&sdp));
767 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800768 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
769 RemoveUnusedVideoRenderers();
770 }
deadbeef1dcb1642017-03-29 21:08:16 -0700771 // As mentioned above, we need to send the message immediately after
772 // SetLocalDescription.
773 SendSdpMessage(type, sdp);
774 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
775 return true;
776 }
777
778 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
779 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
780 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100781 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700782 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800783 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
784 RemoveUnusedVideoRenderers();
785 }
deadbeef1dcb1642017-03-29 21:08:16 -0700786 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
787 return observer->result();
788 }
789
Seth Hampson2f0d7022018-02-20 11:54:42 -0800790 // This is a work around to remove unused fake_video_renderers from
791 // transceivers that have either stopped or are no longer receiving.
792 void RemoveUnusedVideoRenderers() {
793 auto transceivers = pc()->GetTransceivers();
794 for (auto& transceiver : transceivers) {
795 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
796 continue;
797 }
798 // Remove fake video renderers from any stopped transceivers.
799 if (transceiver->stopped()) {
800 auto it =
801 fake_video_renderers_.find(transceiver->receiver()->track()->id());
802 if (it != fake_video_renderers_.end()) {
803 fake_video_renderers_.erase(it);
804 }
805 }
806 // Remove fake video renderers from any transceivers that are no longer
807 // receiving.
808 if ((transceiver->current_direction() &&
809 !webrtc::RtpTransceiverDirectionHasRecv(
810 *transceiver->current_direction()))) {
811 auto it =
812 fake_video_renderers_.find(transceiver->receiver()->track()->id());
813 if (it != fake_video_renderers_.end()) {
814 fake_video_renderers_.erase(it);
815 }
816 }
817 }
818 }
819
deadbeef1dcb1642017-03-29 21:08:16 -0700820 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
821 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800822 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700823 if (signaling_delay_ms_ == 0) {
824 RelaySdpMessageIfReceiverExists(type, msg);
825 } else {
826 invoker_.AsyncInvokeDelayed<void>(
827 RTC_FROM_HERE, rtc::Thread::Current(),
828 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
829 this, type, msg),
830 signaling_delay_ms_);
831 }
832 }
833
Steve Antona3a92c22017-12-07 10:27:41 -0800834 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700835 if (signaling_message_receiver_) {
836 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
837 }
838 }
839
840 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
841 // default).
842 void SendIceMessage(const std::string& sdp_mid,
843 int sdp_mline_index,
844 const std::string& msg) {
845 if (signaling_delay_ms_ == 0) {
846 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
847 } else {
848 invoker_.AsyncInvokeDelayed<void>(
849 RTC_FROM_HERE, rtc::Thread::Current(),
850 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
851 this, sdp_mid, sdp_mline_index, msg),
852 signaling_delay_ms_);
853 }
854 }
855
856 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
857 int sdp_mline_index,
858 const std::string& msg) {
859 if (signaling_message_receiver_) {
860 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
861 msg);
862 }
863 }
864
865 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800866 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
867 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700868 HandleIncomingOffer(msg);
869 } else {
870 HandleIncomingAnswer(msg);
871 }
872 }
873
874 void ReceiveIceMessage(const std::string& sdp_mid,
875 int sdp_mline_index,
876 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100877 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700878 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
879 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
880 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
881 }
882
883 // PeerConnectionObserver callbacks.
884 void OnSignalingChange(
885 webrtc::PeerConnectionInterface::SignalingState new_state) override {
886 EXPECT_EQ(pc()->signaling_state(), new_state);
887 }
Steve Anton15324772018-01-16 10:26:49 -0800888 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
889 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
890 streams) override {
891 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
892 rtc::scoped_refptr<VideoTrackInterface> video_track(
893 static_cast<VideoTrackInterface*>(receiver->track().get()));
894 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700895 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800896 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 11:40:33 +0200897 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700898 }
899 }
Steve Anton15324772018-01-16 10:26:49 -0800900 void OnRemoveTrack(
901 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
902 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
903 auto it = fake_video_renderers_.find(receiver->track()->id());
904 RTC_DCHECK(it != fake_video_renderers_.end());
905 fake_video_renderers_.erase(it);
906 }
907 }
deadbeef1dcb1642017-03-29 21:08:16 -0700908 void OnRenegotiationNeeded() override {}
909 void OnIceConnectionChange(
910 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
911 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700912 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700913 }
914 void OnIceGatheringChange(
915 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700916 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700917 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700918 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700919 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceIceCandidate(
920 const webrtc::IceCandidateInterface* candidate) {
921 std::string candidate_string;
922 candidate->ToString(&candidate_string);
923
924 auto owned_candidate =
925 local_ice_candidate_replacer_->ReplaceCandidate(candidate);
926 if (!owned_candidate) {
927 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer dropped \""
928 << candidate_string << "\"";
929 return nullptr;
930 }
931 std::string owned_candidate_string;
932 owned_candidate->ToString(&owned_candidate_string);
933 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer changed \""
934 << candidate_string << "\" to \"" << owned_candidate_string
935 << "\"";
936 return owned_candidate;
937 }
deadbeef1dcb1642017-03-29 21:08:16 -0700938 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100939 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700940
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700941 const webrtc::IceCandidateInterface* new_candidate = candidate;
942 std::unique_ptr<webrtc::IceCandidateInterface> owned_candidate;
943 if (local_ice_candidate_replacer_) {
944 owned_candidate = ReplaceIceCandidate(candidate);
945 if (!owned_candidate) {
946 return; // The candidate was dropped.
947 }
948 new_candidate = owned_candidate.get();
949 }
950
deadbeef1dcb1642017-03-29 21:08:16 -0700951 std::string ice_sdp;
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700952 EXPECT_TRUE(new_candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700953 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700954 // Remote party may be deleted.
955 return;
956 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700957 SendIceMessage(new_candidate->sdp_mid(), new_candidate->sdp_mline_index(),
958 ice_sdp);
deadbeef1dcb1642017-03-29 21:08:16 -0700959 }
960 void OnDataChannel(
961 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100962 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700963 data_channel_ = data_channel;
964 data_observer_.reset(new MockDataChannelObserver(data_channel));
965 }
966
deadbeef1dcb1642017-03-29 21:08:16 -0700967 std::string debug_name_;
968
969 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
970
971 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
972 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
973 peer_connection_factory_;
974
Steve Antonede9ca52017-10-16 13:04:27 -0700975 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700976 // Needed to keep track of number of frames sent.
977 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
978 // Needed to keep track of number of frames received.
979 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
980 fake_video_renderers_;
981 // Needed to ensure frames aren't received for removed tracks.
982 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
983 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -0700984
985 // For remote peer communication.
986 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
987 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700988 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-29 21:08:16 -0700989
Niels Möller5c7efe72018-05-11 10:34:46 +0200990 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -0700991 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +0200992 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
993 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -0700994 // |local_video_renderer_| attached to the first created local video track.
995 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
996
Seth Hampson2f0d7022018-02-20 11:54:42 -0800997 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -0700998 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
999 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1000 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001001 std::function<void()> remote_offer_handler_;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001002 std::unique_ptr<IceCandidateReplacerInterface> local_ice_candidate_replacer_;
deadbeef1dcb1642017-03-29 21:08:16 -07001003 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1004 std::unique_ptr<MockDataChannelObserver> data_observer_;
1005
1006 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1007
Steve Antonede9ca52017-10-16 13:04:27 -07001008 std::vector<PeerConnectionInterface::IceConnectionState>
1009 ice_connection_state_history_;
1010 std::vector<PeerConnectionInterface::IceGatheringState>
1011 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -07001012
Qingsi Wang7685e862018-06-11 20:15:46 -07001013 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1014
deadbeef1dcb1642017-03-29 21:08:16 -07001015 rtc::AsyncInvoker invoker_;
1016
Seth Hampson2f0d7022018-02-20 11:54:42 -08001017 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -07001018};
1019
Elad Alon99c3fe52017-10-13 16:29:40 +02001020class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1021 public:
1022 virtual ~MockRtcEventLogOutput() = default;
1023 MOCK_CONST_METHOD0(IsActive, bool());
1024 MOCK_METHOD1(Write, bool(const std::string&));
1025};
1026
Seth Hampson2f0d7022018-02-20 11:54:42 -08001027// This helper object is used for both specifying how many audio/video frames
1028// are expected to be received for a caller/callee. It provides helper functions
1029// to specify these expectations. The object initially starts in a state of no
1030// expectations.
1031class MediaExpectations {
1032 public:
1033 enum ExpectFrames {
1034 kExpectSomeFrames,
1035 kExpectNoFrames,
1036 kNoExpectation,
1037 };
1038
1039 void ExpectBidirectionalAudioAndVideo() {
1040 ExpectBidirectionalAudio();
1041 ExpectBidirectionalVideo();
1042 }
1043
1044 void ExpectBidirectionalAudio() {
1045 CallerExpectsSomeAudio();
1046 CalleeExpectsSomeAudio();
1047 }
1048
1049 void ExpectNoAudio() {
1050 CallerExpectsNoAudio();
1051 CalleeExpectsNoAudio();
1052 }
1053
1054 void ExpectBidirectionalVideo() {
1055 CallerExpectsSomeVideo();
1056 CalleeExpectsSomeVideo();
1057 }
1058
1059 void ExpectNoVideo() {
1060 CallerExpectsNoVideo();
1061 CalleeExpectsNoVideo();
1062 }
1063
1064 void CallerExpectsSomeAudioAndVideo() {
1065 CallerExpectsSomeAudio();
1066 CallerExpectsSomeVideo();
1067 }
1068
1069 void CalleeExpectsSomeAudioAndVideo() {
1070 CalleeExpectsSomeAudio();
1071 CalleeExpectsSomeVideo();
1072 }
1073
1074 // Caller's audio functions.
1075 void CallerExpectsSomeAudio(
1076 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1077 caller_audio_expectation_ = kExpectSomeFrames;
1078 caller_audio_frames_expected_ = expected_audio_frames;
1079 }
1080
1081 void CallerExpectsNoAudio() {
1082 caller_audio_expectation_ = kExpectNoFrames;
1083 caller_audio_frames_expected_ = 0;
1084 }
1085
1086 // Caller's video functions.
1087 void CallerExpectsSomeVideo(
1088 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1089 caller_video_expectation_ = kExpectSomeFrames;
1090 caller_video_frames_expected_ = expected_video_frames;
1091 }
1092
1093 void CallerExpectsNoVideo() {
1094 caller_video_expectation_ = kExpectNoFrames;
1095 caller_video_frames_expected_ = 0;
1096 }
1097
1098 // Callee's audio functions.
1099 void CalleeExpectsSomeAudio(
1100 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1101 callee_audio_expectation_ = kExpectSomeFrames;
1102 callee_audio_frames_expected_ = expected_audio_frames;
1103 }
1104
1105 void CalleeExpectsNoAudio() {
1106 callee_audio_expectation_ = kExpectNoFrames;
1107 callee_audio_frames_expected_ = 0;
1108 }
1109
1110 // Callee's video functions.
1111 void CalleeExpectsSomeVideo(
1112 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1113 callee_video_expectation_ = kExpectSomeFrames;
1114 callee_video_frames_expected_ = expected_video_frames;
1115 }
1116
1117 void CalleeExpectsNoVideo() {
1118 callee_video_expectation_ = kExpectNoFrames;
1119 callee_video_frames_expected_ = 0;
1120 }
1121
1122 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1123 ExpectFrames caller_video_expectation_ = kNoExpectation;
1124 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1125 ExpectFrames callee_video_expectation_ = kNoExpectation;
1126 int caller_audio_frames_expected_ = 0;
1127 int caller_video_frames_expected_ = 0;
1128 int callee_audio_frames_expected_ = 0;
1129 int callee_video_frames_expected_ = 0;
1130};
1131
deadbeef1dcb1642017-03-29 21:08:16 -07001132// Tests two PeerConnections connecting to each other end-to-end, using a
1133// virtual network, fake A/V capture and fake encoder/decoders. The
1134// PeerConnections share the threads/socket servers, but use separate versions
1135// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001136class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001137 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001138 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1139 : sdp_semantics_(sdp_semantics),
1140 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001141 fss_(new rtc::FirewallSocketServer(ss_.get())),
1142 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-29 21:08:16 -07001143 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001144 network_thread_->SetName("PCNetworkThread", this);
1145 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001146 RTC_CHECK(network_thread_->Start());
1147 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001148 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001149 }
1150
Seth Hampson2f0d7022018-02-20 11:54:42 -08001151 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 07:41:32 -07001152 // The PeerConnections should deleted before the TurnCustomizers.
1153 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1154 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1155 // that the TurnCustomizer outlives the life of the PeerConnection or else
1156 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001157 if (caller_) {
1158 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001159 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001160 }
1161 if (callee_) {
1162 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001163 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001164 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001165
1166 // If turn servers were created for the test they need to be destroyed on
1167 // the network thread.
1168 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1169 turn_servers_.clear();
1170 turn_customizers_.clear();
1171 });
deadbeef1dcb1642017-03-29 21:08:16 -07001172 }
1173
1174 bool SignalingStateStable() {
1175 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1176 }
1177
deadbeef71452802017-05-07 17:21:01 -07001178 bool DtlsConnected() {
1179 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1180 // are connected. This is an important distinction. Once we have separate
1181 // ICE and DTLS state, this check needs to use the DTLS state.
1182 return (callee()->ice_connection_state() ==
1183 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1184 callee()->ice_connection_state() ==
1185 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1186 (caller()->ice_connection_state() ==
1187 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1188 caller()->ice_connection_state() ==
1189 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1190 }
1191
Qingsi Wang7685e862018-06-11 20:15:46 -07001192 // When |event_log_factory| is null, the default implementation of the event
1193 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001194 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1195 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001196 const PeerConnectionFactory::Options* options,
1197 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001198 webrtc::PeerConnectionDependencies dependencies,
1199 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001200 RTCConfiguration modified_config;
1201 if (config) {
1202 modified_config = *config;
1203 }
Steve Anton3acffc32018-04-12 17:21:03 -07001204 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001205 if (!dependencies.cert_generator) {
1206 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 11:40:33 +02001207 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001208 }
1209 std::unique_ptr<PeerConnectionWrapper> client(
1210 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001211
Niels Möllerf06f9232018-08-07 12:32:18 +02001212 if (!client->Init(options, &modified_config, std::move(dependencies),
1213 network_thread_.get(), worker_thread_.get(),
1214 std::move(event_log_factory))) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001215 return nullptr;
1216 }
1217 return client;
1218 }
1219
Qingsi Wang7685e862018-06-11 20:15:46 -07001220 std::unique_ptr<PeerConnectionWrapper>
1221 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1222 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001223 const PeerConnectionFactory::Options* options,
1224 const RTCConfiguration* config,
1225 webrtc::PeerConnectionDependencies dependencies) {
1226 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1227 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möllerf06f9232018-08-07 12:32:18 +02001228 return CreatePeerConnectionWrapper(debug_name, options, config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001229 std::move(dependencies),
1230 std::move(event_log_factory));
1231 }
1232
deadbeef1dcb1642017-03-29 21:08:16 -07001233 bool CreatePeerConnectionWrappers() {
1234 return CreatePeerConnectionWrappersWithConfig(
1235 PeerConnectionInterface::RTCConfiguration(),
1236 PeerConnectionInterface::RTCConfiguration());
1237 }
1238
Steve Anton3acffc32018-04-12 17:21:03 -07001239 bool CreatePeerConnectionWrappersWithSdpSemantics(
1240 SdpSemantics caller_semantics,
1241 SdpSemantics callee_semantics) {
1242 // Can't specify the sdp_semantics in the passed-in configuration since it
1243 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1244 // stored in sdp_semantics_. So get around this by modifying the instance
1245 // variable before calling CreatePeerConnectionWrapper for the caller and
1246 // callee PeerConnections.
1247 SdpSemantics original_semantics = sdp_semantics_;
1248 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001249 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001250 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1251 nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001252 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001253 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001254 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1255 nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001256 sdp_semantics_ = original_semantics;
1257 return caller_ && callee_;
1258 }
1259
deadbeef1dcb1642017-03-29 21:08:16 -07001260 bool CreatePeerConnectionWrappersWithConfig(
1261 const PeerConnectionInterface::RTCConfiguration& caller_config,
1262 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001263 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001264 "Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001265 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001266 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001267 "Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001268 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001269 return caller_ && callee_;
1270 }
1271
1272 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1273 const PeerConnectionInterface::RTCConfiguration& caller_config,
1274 webrtc::PeerConnectionDependencies caller_dependencies,
1275 const PeerConnectionInterface::RTCConfiguration& callee_config,
1276 webrtc::PeerConnectionDependencies callee_dependencies) {
1277 caller_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001278 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001279 std::move(caller_dependencies), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001280 callee_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001281 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001282 std::move(callee_dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001283 return caller_ && callee_;
1284 }
1285
1286 bool CreatePeerConnectionWrappersWithOptions(
1287 const PeerConnectionFactory::Options& caller_options,
1288 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001289 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001290 "Caller", &caller_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001291 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001292 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001293 "Callee", &callee_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001294 webrtc::PeerConnectionDependencies(nullptr), nullptr);
1295 return caller_ && callee_;
1296 }
1297
1298 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1299 PeerConnectionInterface::RTCConfiguration default_config;
1300 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001301 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001302 webrtc::PeerConnectionDependencies(nullptr));
1303 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001304 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001305 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001306 return caller_ && callee_;
1307 }
1308
Seth Hampson2f0d7022018-02-20 11:54:42 -08001309 std::unique_ptr<PeerConnectionWrapper>
1310 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001311 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1312 new FakeRTCCertificateGenerator());
1313 cert_generator->use_alternate_key();
1314
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001315 webrtc::PeerConnectionDependencies dependencies(nullptr);
1316 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +02001317 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001318 std::move(dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001319 }
1320
Seth Hampsonaed71642018-06-11 07:41:32 -07001321 cricket::TestTurnServer* CreateTurnServer(
1322 rtc::SocketAddress internal_address,
1323 rtc::SocketAddress external_address,
1324 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1325 const std::string& common_name = "test turn server") {
1326 rtc::Thread* thread = network_thread();
1327 std::unique_ptr<cricket::TestTurnServer> turn_server =
1328 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1329 RTC_FROM_HERE,
1330 [thread, internal_address, external_address, type, common_name] {
Karl Wiberg918f50c2018-07-05 11:40:33 +02001331 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001332 thread, internal_address, external_address, type,
1333 /*ignore_bad_certs=*/true, common_name);
1334 });
1335 turn_servers_.push_back(std::move(turn_server));
1336 // Interactions with the turn server should be done on the network thread.
1337 return turn_servers_.back().get();
1338 }
1339
1340 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1341 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1342 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1343 RTC_FROM_HERE,
Karl Wiberg918f50c2018-07-05 11:40:33 +02001344 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001345 turn_customizers_.push_back(std::move(turn_customizer));
1346 // Interactions with the turn customizer should be done on the network
1347 // thread.
1348 return turn_customizers_.back().get();
1349 }
1350
1351 // Checks that the function counters for a TestTurnCustomizer are greater than
1352 // 0.
1353 void ExpectTurnCustomizerCountersIncremented(
1354 cricket::TestTurnCustomizer* turn_customizer) {
1355 unsigned int allow_channel_data_counter =
1356 network_thread()->Invoke<unsigned int>(
1357 RTC_FROM_HERE, [turn_customizer] {
1358 return turn_customizer->allow_channel_data_cnt_;
1359 });
1360 EXPECT_GT(allow_channel_data_counter, 0u);
1361 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1362 RTC_FROM_HERE,
1363 [turn_customizer] { return turn_customizer->modify_cnt_; });
1364 EXPECT_GT(modify_counter, 0u);
1365 }
1366
deadbeef1dcb1642017-03-29 21:08:16 -07001367 // Once called, SDP blobs and ICE candidates will be automatically signaled
1368 // between PeerConnections.
1369 void ConnectFakeSignaling() {
1370 caller_->set_signaling_message_receiver(callee_.get());
1371 callee_->set_signaling_message_receiver(caller_.get());
1372 }
1373
Steve Antonede9ca52017-10-16 13:04:27 -07001374 // Once called, SDP blobs will be automatically signaled between
1375 // PeerConnections. Note that ICE candidates will not be signaled unless they
1376 // are in the exchanged SDP blobs.
1377 void ConnectFakeSignalingForSdpOnly() {
1378 ConnectFakeSignaling();
1379 SetSignalIceCandidates(false);
1380 }
1381
deadbeef1dcb1642017-03-29 21:08:16 -07001382 void SetSignalingDelayMs(int delay_ms) {
1383 caller_->set_signaling_delay_ms(delay_ms);
1384 callee_->set_signaling_delay_ms(delay_ms);
1385 }
1386
Steve Antonede9ca52017-10-16 13:04:27 -07001387 void SetSignalIceCandidates(bool signal) {
1388 caller_->set_signal_ice_candidates(signal);
1389 callee_->set_signal_ice_candidates(signal);
1390 }
1391
deadbeef1dcb1642017-03-29 21:08:16 -07001392 // Messages may get lost on the unreliable DataChannel, so we send multiple
1393 // times to avoid test flakiness.
1394 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1395 const std::string& data,
1396 int retries) {
1397 for (int i = 0; i < retries; ++i) {
1398 dc->Send(DataBuffer(data));
1399 }
1400 }
1401
1402 rtc::Thread* network_thread() { return network_thread_.get(); }
1403
1404 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1405
1406 PeerConnectionWrapper* caller() { return caller_.get(); }
1407
1408 // Set the |caller_| to the |wrapper| passed in and return the
1409 // original |caller_|.
1410 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1411 PeerConnectionWrapper* wrapper) {
1412 PeerConnectionWrapper* old = caller_.release();
1413 caller_.reset(wrapper);
1414 return old;
1415 }
1416
1417 PeerConnectionWrapper* callee() { return callee_.get(); }
1418
1419 // Set the |callee_| to the |wrapper| passed in and return the
1420 // original |callee_|.
1421 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1422 PeerConnectionWrapper* wrapper) {
1423 PeerConnectionWrapper* old = callee_.release();
1424 callee_.reset(wrapper);
1425 return old;
1426 }
1427
Steve Antonede9ca52017-10-16 13:04:27 -07001428 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1429
Seth Hampson2f0d7022018-02-20 11:54:42 -08001430 // Expects the provided number of new frames to be received within
1431 // kMaxWaitForFramesMs. The new expected frames are specified in
1432 // |media_expectations|. Returns false if any of the expectations were
1433 // not met.
1434 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1435 // First initialize the expected frame counts based upon the current
1436 // frame count.
1437 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1438 if (media_expectations.caller_audio_expectation_ ==
1439 MediaExpectations::kExpectSomeFrames) {
1440 total_caller_audio_frames_expected +=
1441 media_expectations.caller_audio_frames_expected_;
1442 }
1443 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001444 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001445 if (media_expectations.caller_video_expectation_ ==
1446 MediaExpectations::kExpectSomeFrames) {
1447 total_caller_video_frames_expected +=
1448 media_expectations.caller_video_frames_expected_;
1449 }
1450 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1451 if (media_expectations.callee_audio_expectation_ ==
1452 MediaExpectations::kExpectSomeFrames) {
1453 total_callee_audio_frames_expected +=
1454 media_expectations.callee_audio_frames_expected_;
1455 }
1456 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001457 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001458 if (media_expectations.callee_video_expectation_ ==
1459 MediaExpectations::kExpectSomeFrames) {
1460 total_callee_video_frames_expected +=
1461 media_expectations.callee_video_frames_expected_;
1462 }
deadbeef1dcb1642017-03-29 21:08:16 -07001463
Seth Hampson2f0d7022018-02-20 11:54:42 -08001464 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001465 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001466 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001467 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001468 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001469 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001470 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001471 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001472 total_callee_video_frames_expected,
1473 kMaxWaitForFramesMs);
1474 bool expectations_correct =
1475 caller()->audio_frames_received() >=
1476 total_caller_audio_frames_expected &&
1477 caller()->min_video_frames_received_per_track() >=
1478 total_caller_video_frames_expected &&
1479 callee()->audio_frames_received() >=
1480 total_callee_audio_frames_expected &&
1481 callee()->min_video_frames_received_per_track() >=
1482 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001483
Seth Hampson2f0d7022018-02-20 11:54:42 -08001484 // After the combined wait, print out a more detailed message upon
1485 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001486 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001487 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001488 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001489 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001490 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001491 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001492 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001493 total_callee_video_frames_expected);
1494
1495 // We want to make sure nothing unexpected was received.
1496 if (media_expectations.caller_audio_expectation_ ==
1497 MediaExpectations::kExpectNoFrames) {
1498 EXPECT_EQ(caller()->audio_frames_received(),
1499 total_caller_audio_frames_expected);
1500 if (caller()->audio_frames_received() !=
1501 total_caller_audio_frames_expected) {
1502 expectations_correct = false;
1503 }
1504 }
1505 if (media_expectations.caller_video_expectation_ ==
1506 MediaExpectations::kExpectNoFrames) {
1507 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1508 total_caller_video_frames_expected);
1509 if (caller()->min_video_frames_received_per_track() !=
1510 total_caller_video_frames_expected) {
1511 expectations_correct = false;
1512 }
1513 }
1514 if (media_expectations.callee_audio_expectation_ ==
1515 MediaExpectations::kExpectNoFrames) {
1516 EXPECT_EQ(callee()->audio_frames_received(),
1517 total_callee_audio_frames_expected);
1518 if (callee()->audio_frames_received() !=
1519 total_callee_audio_frames_expected) {
1520 expectations_correct = false;
1521 }
1522 }
1523 if (media_expectations.callee_video_expectation_ ==
1524 MediaExpectations::kExpectNoFrames) {
1525 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1526 total_callee_video_frames_expected);
1527 if (callee()->min_video_frames_received_per_track() !=
1528 total_callee_video_frames_expected) {
1529 expectations_correct = false;
1530 }
1531 }
1532 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001533 }
1534
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001535 void TestNegotiatedCipherSuite(
1536 const PeerConnectionFactory::Options& caller_options,
1537 const PeerConnectionFactory::Options& callee_options,
1538 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001539 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1540 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001541 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001542 caller()->AddAudioVideoTracks();
1543 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001544 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001545 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001546 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001547 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001548 // TODO(bugs.webrtc.org/9456): Fix it.
1549 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1550 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1551 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001552 }
1553
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001554 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1555 bool remote_gcm_enabled,
1556 int expected_cipher_suite) {
1557 PeerConnectionFactory::Options caller_options;
1558 caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
1559 PeerConnectionFactory::Options callee_options;
1560 callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
1561 TestNegotiatedCipherSuite(caller_options, callee_options,
1562 expected_cipher_suite);
1563 }
1564
Seth Hampson2f0d7022018-02-20 11:54:42 -08001565 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001566 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001567
deadbeef1dcb1642017-03-29 21:08:16 -07001568 private:
1569 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001570 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001571 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001572 // |network_thread_| and |worker_thread_| are used by both
1573 // |caller_| and |callee_| so they must be destroyed
1574 // later.
1575 std::unique_ptr<rtc::Thread> network_thread_;
1576 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001577 // The turn servers and turn customizers should be accessed & deleted on the
1578 // network thread to avoid a race with the socket read/write that occurs
1579 // on the network thread.
1580 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1581 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001582 std::unique_ptr<PeerConnectionWrapper> caller_;
1583 std::unique_ptr<PeerConnectionWrapper> callee_;
1584};
1585
Seth Hampson2f0d7022018-02-20 11:54:42 -08001586class PeerConnectionIntegrationTest
1587 : public PeerConnectionIntegrationBaseTest,
1588 public ::testing::WithParamInterface<SdpSemantics> {
1589 protected:
1590 PeerConnectionIntegrationTest()
1591 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1592};
1593
1594class PeerConnectionIntegrationTestPlanB
1595 : public PeerConnectionIntegrationBaseTest {
1596 protected:
1597 PeerConnectionIntegrationTestPlanB()
1598 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1599};
1600
1601class PeerConnectionIntegrationTestUnifiedPlan
1602 : public PeerConnectionIntegrationBaseTest {
1603 protected:
1604 PeerConnectionIntegrationTestUnifiedPlan()
1605 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1606};
1607
deadbeef1dcb1642017-03-29 21:08:16 -07001608// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1609// includes testing that the callback is invoked if an observer is connected
1610// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001611TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001612 RtpReceiverObserverOnFirstPacketReceived) {
1613 ASSERT_TRUE(CreatePeerConnectionWrappers());
1614 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001615 caller()->AddAudioVideoTracks();
1616 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001617 // Start offer/answer exchange and wait for it to complete.
1618 caller()->CreateAndSetAndSignalOffer();
1619 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1620 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001621 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1622 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001623 // Wait for all "first packet received" callbacks to be fired.
1624 EXPECT_TRUE_WAIT(
1625 std::all_of(caller()->rtp_receiver_observers().begin(),
1626 caller()->rtp_receiver_observers().end(),
1627 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1628 return o->first_packet_received();
1629 }),
1630 kMaxWaitForFramesMs);
1631 EXPECT_TRUE_WAIT(
1632 std::all_of(callee()->rtp_receiver_observers().begin(),
1633 callee()->rtp_receiver_observers().end(),
1634 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1635 return o->first_packet_received();
1636 }),
1637 kMaxWaitForFramesMs);
1638 // If new observers are set after the first packet was already received, the
1639 // callback should still be invoked.
1640 caller()->ResetRtpReceiverObservers();
1641 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001642 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1643 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001644 EXPECT_TRUE(
1645 std::all_of(caller()->rtp_receiver_observers().begin(),
1646 caller()->rtp_receiver_observers().end(),
1647 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1648 return o->first_packet_received();
1649 }));
1650 EXPECT_TRUE(
1651 std::all_of(callee()->rtp_receiver_observers().begin(),
1652 callee()->rtp_receiver_observers().end(),
1653 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1654 return o->first_packet_received();
1655 }));
1656}
1657
1658class DummyDtmfObserver : public DtmfSenderObserverInterface {
1659 public:
1660 DummyDtmfObserver() : completed_(false) {}
1661
1662 // Implements DtmfSenderObserverInterface.
1663 void OnToneChange(const std::string& tone) override {
1664 tones_.push_back(tone);
1665 if (tone.empty()) {
1666 completed_ = true;
1667 }
1668 }
1669
1670 const std::vector<std::string>& tones() const { return tones_; }
1671 bool completed() const { return completed_; }
1672
1673 private:
1674 bool completed_;
1675 std::vector<std::string> tones_;
1676};
1677
1678// Assumes |sender| already has an audio track added and the offer/answer
1679// exchange is done.
1680void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1681 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001682 // We should be able to get a DTMF sender from the local sender.
1683 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1684 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1685 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001686 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001687 dtmf_sender->RegisterObserver(&observer);
1688
1689 // Test the DtmfSender object just created.
1690 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1691 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1692
1693 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1694 std::vector<std::string> tones = {"1", "a", ""};
1695 EXPECT_EQ(tones, observer.tones());
1696 dtmf_sender->UnregisterObserver();
1697 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1698}
1699
1700// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1701// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001702TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001703 ASSERT_TRUE(CreatePeerConnectionWrappers());
1704 ConnectFakeSignaling();
1705 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001706 caller()->AddAudioTrack();
1707 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001708 caller()->CreateAndSetAndSignalOffer();
1709 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001710 // DTLS must finish before the DTMF sender can be used reliably.
1711 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001712 TestDtmfFromSenderToReceiver(caller(), callee());
1713 TestDtmfFromSenderToReceiver(callee(), caller());
1714}
1715
1716// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1717// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001718TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001719 ASSERT_TRUE(CreatePeerConnectionWrappers());
1720 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001721
deadbeef1dcb1642017-03-29 21:08:16 -07001722 // Do normal offer/answer and wait for some frames to be received in each
1723 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001724 caller()->AddAudioVideoTracks();
1725 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001726 caller()->CreateAndSetAndSignalOffer();
1727 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001728 MediaExpectations media_expectations;
1729 media_expectations.ExpectBidirectionalAudioAndVideo();
1730 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001731 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1732 webrtc::kEnumCounterKeyProtocolDtls));
1733 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1734 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001735}
1736
1737// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001738TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001739 PeerConnectionInterface::RTCConfiguration sdes_config;
1740 sdes_config.enable_dtls_srtp.emplace(false);
1741 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1742 ConnectFakeSignaling();
1743
1744 // Do normal offer/answer and wait for some frames to be received in each
1745 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001746 caller()->AddAudioVideoTracks();
1747 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001748 caller()->CreateAndSetAndSignalOffer();
1749 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001750 MediaExpectations media_expectations;
1751 media_expectations.ExpectBidirectionalAudioAndVideo();
1752 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001753 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1754 webrtc::kEnumCounterKeyProtocolSdes));
1755 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1756 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001757}
1758
Steve Anton8c0f7a72017-10-03 10:03:10 -07001759// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1760// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001761TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001762 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1763 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1764 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1765 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1766 return pc->GetRemoteAudioSSLCertificate();
1767 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001768 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1769 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1770 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1771 return pc->GetRemoteAudioSSLCertChain();
1772 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001773
1774 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1775 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1776
1777 // Configure each side with a known certificate so they can be compared later.
1778 PeerConnectionInterface::RTCConfiguration caller_config;
1779 caller_config.enable_dtls_srtp.emplace(true);
1780 caller_config.certificates.push_back(caller_cert);
1781 PeerConnectionInterface::RTCConfiguration callee_config;
1782 callee_config.enable_dtls_srtp.emplace(true);
1783 callee_config.certificates.push_back(callee_cert);
1784 ASSERT_TRUE(
1785 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1786 ConnectFakeSignaling();
1787
1788 // When first initialized, there should not be a remote SSL certificate (and
1789 // calling this method should not crash).
1790 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1791 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001792 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1793 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001794
Steve Anton15324772018-01-16 10:26:49 -08001795 caller()->AddAudioTrack();
1796 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001797 caller()->CreateAndSetAndSignalOffer();
1798 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1799 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1800
1801 // Once DTLS has been connected, each side should return the other's SSL
1802 // certificate when calling GetRemoteAudioSSLCertificate.
1803
1804 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1805 ASSERT_TRUE(caller_remote_cert);
1806 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1807 caller_remote_cert->ToPEMString());
1808
1809 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1810 ASSERT_TRUE(callee_remote_cert);
1811 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1812 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001813
1814 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1815 ASSERT_TRUE(caller_remote_cert_chain);
1816 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1817 auto remote_cert = &caller_remote_cert_chain->Get(0);
1818 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1819 remote_cert->ToPEMString());
1820
1821 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1822 ASSERT_TRUE(callee_remote_cert_chain);
1823 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1824 remote_cert = &callee_remote_cert_chain->Get(0);
1825 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1826 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001827}
1828
deadbeef1dcb1642017-03-29 21:08:16 -07001829// This test sets up a call between two parties with a source resolution of
1830// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001831TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001832 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1833 ASSERT_TRUE(CreatePeerConnectionWrappers());
1834 ConnectFakeSignaling();
1835
Niels Möller5c7efe72018-05-11 10:34:46 +02001836 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1837 webrtc::FakePeriodicVideoSource::Config config;
1838 config.width = 1280;
1839 config.height = 720;
1840 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1841 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07001842
1843 // Do normal offer/answer and wait for at least one frame to be received in
1844 // each direction.
1845 caller()->CreateAndSetAndSignalOffer();
1846 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1847 callee()->min_video_frames_received_per_track() > 0,
1848 kMaxWaitForFramesMs);
1849
1850 // Check rendered aspect ratio.
1851 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1852 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1853 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1854 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1855}
1856
1857// This test sets up an one-way call, with media only from caller to
1858// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001859TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001860 ASSERT_TRUE(CreatePeerConnectionWrappers());
1861 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001862 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001863 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001864 MediaExpectations media_expectations;
1865 media_expectations.CalleeExpectsSomeAudioAndVideo();
1866 media_expectations.CallerExpectsNoAudio();
1867 media_expectations.CallerExpectsNoVideo();
1868 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001869}
1870
1871// This test sets up a audio call initially, with the callee rejecting video
1872// initially. Then later the callee decides to upgrade to audio/video, and
1873// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001874TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001875 ASSERT_TRUE(CreatePeerConnectionWrappers());
1876 ConnectFakeSignaling();
1877 // Initially, offer an audio/video stream from the caller, but refuse to
1878 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001879 caller()->AddAudioVideoTracks();
1880 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001881 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1882 PeerConnectionInterface::RTCOfferAnswerOptions options;
1883 options.offer_to_receive_video = 0;
1884 callee()->SetOfferAnswerOptions(options);
1885 } else {
1886 callee()->SetRemoteOfferHandler([this] {
1887 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1888 });
1889 }
deadbeef1dcb1642017-03-29 21:08:16 -07001890 // Do offer/answer and make sure audio is still received end-to-end.
1891 caller()->CreateAndSetAndSignalOffer();
1892 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001893 {
1894 MediaExpectations media_expectations;
1895 media_expectations.ExpectBidirectionalAudio();
1896 media_expectations.ExpectNoVideo();
1897 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1898 }
deadbeef1dcb1642017-03-29 21:08:16 -07001899 // Sanity check that the callee's description has a rejected video section.
1900 ASSERT_NE(nullptr, callee()->pc()->local_description());
1901 const ContentInfo* callee_video_content =
1902 GetFirstVideoContent(callee()->pc()->local_description()->description());
1903 ASSERT_NE(nullptr, callee_video_content);
1904 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001905
deadbeef1dcb1642017-03-29 21:08:16 -07001906 // Now negotiate with video and ensure negotiation succeeds, with video
1907 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001908 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001909 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1910 PeerConnectionInterface::RTCOfferAnswerOptions options;
1911 options.offer_to_receive_video = 1;
1912 callee()->SetOfferAnswerOptions(options);
1913 } else {
1914 callee()->SetRemoteOfferHandler(nullptr);
1915 caller()->SetRemoteOfferHandler([this] {
1916 // The caller creates a new transceiver to receive video on when receiving
1917 // the offer, but by default it is send only.
1918 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001919 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001920 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1921 transceivers[2]->receiver()->media_type());
1922 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1923 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1924 });
1925 }
deadbeef1dcb1642017-03-29 21:08:16 -07001926 callee()->CreateAndSetAndSignalOffer();
1927 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001928 {
1929 // Expect additional audio frames to be received after the upgrade.
1930 MediaExpectations media_expectations;
1931 media_expectations.ExpectBidirectionalAudioAndVideo();
1932 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1933 }
deadbeef1dcb1642017-03-29 21:08:16 -07001934}
1935
deadbeef4389b4d2017-09-07 09:07:36 -07001936// Simpler than the above test; just add an audio track to an established
1937// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001938TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07001939 ASSERT_TRUE(CreatePeerConnectionWrappers());
1940 ConnectFakeSignaling();
1941 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08001942 caller()->AddVideoTrack();
1943 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001944 caller()->CreateAndSetAndSignalOffer();
1945 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1946 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001947 caller()->AddAudioTrack();
1948 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001949 caller()->CreateAndSetAndSignalOffer();
1950 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1951 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001952 MediaExpectations media_expectations;
1953 media_expectations.ExpectBidirectionalAudioAndVideo();
1954 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07001955}
1956
deadbeef1dcb1642017-03-29 21:08:16 -07001957// This test sets up a call that's transferred to a new caller with a different
1958// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001959TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07001960 ASSERT_TRUE(CreatePeerConnectionWrappers());
1961 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001962 caller()->AddAudioVideoTracks();
1963 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001964 caller()->CreateAndSetAndSignalOffer();
1965 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1966
1967 // Keep the original peer around which will still send packets to the
1968 // receiving client. These SRTP packets will be dropped.
1969 std::unique_ptr<PeerConnectionWrapper> original_peer(
1970 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001971 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001972 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1973 // directly above.
1974 original_peer->pc()->Close();
1975
1976 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001977 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001978 caller()->CreateAndSetAndSignalOffer();
1979 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1980 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001981 MediaExpectations media_expectations;
1982 media_expectations.ExpectBidirectionalAudioAndVideo();
1983 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001984}
1985
1986// This test sets up a call that's transferred to a new callee with a different
1987// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001988TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07001989 ASSERT_TRUE(CreatePeerConnectionWrappers());
1990 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001991 caller()->AddAudioVideoTracks();
1992 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001993 caller()->CreateAndSetAndSignalOffer();
1994 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1995
1996 // Keep the original peer around which will still send packets to the
1997 // receiving client. These SRTP packets will be dropped.
1998 std::unique_ptr<PeerConnectionWrapper> original_peer(
1999 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002000 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002001 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2002 // directly above.
2003 original_peer->pc()->Close();
2004
2005 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002006 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002007 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2008 caller()->CreateAndSetAndSignalOffer();
2009 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2010 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002011 MediaExpectations media_expectations;
2012 media_expectations.ExpectBidirectionalAudioAndVideo();
2013 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002014}
2015
2016// This test sets up a non-bundled call and negotiates bundling at the same
2017// time as starting an ICE restart. When bundling is in effect in the restart,
2018// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002019TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002020 ASSERT_TRUE(CreatePeerConnectionWrappers());
2021 ConnectFakeSignaling();
2022
Steve Anton15324772018-01-16 10:26:49 -08002023 caller()->AddAudioVideoTracks();
2024 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002025 // Remove the bundle group from the SDP received by the callee.
2026 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2027 desc->RemoveGroupByName("BUNDLE");
2028 });
2029 caller()->CreateAndSetAndSignalOffer();
2030 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002031 {
2032 MediaExpectations media_expectations;
2033 media_expectations.ExpectBidirectionalAudioAndVideo();
2034 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2035 }
deadbeef1dcb1642017-03-29 21:08:16 -07002036 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2037 callee()->SetReceivedSdpMunger(nullptr);
2038 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2039 caller()->CreateAndSetAndSignalOffer();
2040 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2041
2042 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002043 {
2044 MediaExpectations media_expectations;
2045 media_expectations.ExpectBidirectionalAudioAndVideo();
2046 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2047 }
deadbeef1dcb1642017-03-29 21:08:16 -07002048}
2049
2050// Test CVO (Coordination of Video Orientation). If a video source is rotated
2051// and both peers support the CVO RTP header extension, the actual video frames
2052// don't need to be encoded in different resolutions, since the rotation is
2053// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002054TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002055 ASSERT_TRUE(CreatePeerConnectionWrappers());
2056 ConnectFakeSignaling();
2057 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002058 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002059 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002060 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002061 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2062
2063 // Wait for video frames to be received by both sides.
2064 caller()->CreateAndSetAndSignalOffer();
2065 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2066 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2067 callee()->min_video_frames_received_per_track() > 0,
2068 kMaxWaitForFramesMs);
2069
2070 // Ensure that the aspect ratio is unmodified.
2071 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2072 // not just assumed.
2073 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2074 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2075 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2076 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2077 // Ensure that the CVO bits were surfaced to the renderer.
2078 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2079 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2080}
2081
2082// Test that when the CVO extension isn't supported, video is rotated the
2083// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002084TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002085 ASSERT_TRUE(CreatePeerConnectionWrappers());
2086 ConnectFakeSignaling();
2087 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002088 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002089 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002090 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002091 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2092
2093 // Remove the CVO extension from the offered SDP.
2094 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2095 cricket::VideoContentDescription* video =
2096 GetFirstVideoContentDescription(desc);
2097 video->ClearRtpHeaderExtensions();
2098 });
2099 // Wait for video frames to be received by both sides.
2100 caller()->CreateAndSetAndSignalOffer();
2101 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2102 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2103 callee()->min_video_frames_received_per_track() > 0,
2104 kMaxWaitForFramesMs);
2105
2106 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2107 // rotation.
2108 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2109 // not just assumed.
2110 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2111 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2112 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2113 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2114 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2115 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2116 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2117}
2118
deadbeef1dcb1642017-03-29 21:08:16 -07002119// Test that if the answerer rejects the audio m= section, no audio is sent or
2120// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002121TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002122 ASSERT_TRUE(CreatePeerConnectionWrappers());
2123 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002124 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002125 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2126 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2127 // it will reject the audio m= section completely.
2128 PeerConnectionInterface::RTCOfferAnswerOptions options;
2129 options.offer_to_receive_audio = 0;
2130 callee()->SetOfferAnswerOptions(options);
2131 } else {
2132 // Stopping the audio RtpTransceiver will cause the media section to be
2133 // rejected in the answer.
2134 callee()->SetRemoteOfferHandler([this] {
2135 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2136 });
2137 }
Steve Anton15324772018-01-16 10:26:49 -08002138 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002139 // Do offer/answer and wait for successful end-to-end video frames.
2140 caller()->CreateAndSetAndSignalOffer();
2141 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002142 MediaExpectations media_expectations;
2143 media_expectations.ExpectBidirectionalVideo();
2144 media_expectations.ExpectNoAudio();
2145 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2146
deadbeef1dcb1642017-03-29 21:08:16 -07002147 // Sanity check that the callee's description has a rejected audio section.
2148 ASSERT_NE(nullptr, callee()->pc()->local_description());
2149 const ContentInfo* callee_audio_content =
2150 GetFirstAudioContent(callee()->pc()->local_description()->description());
2151 ASSERT_NE(nullptr, callee_audio_content);
2152 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002153 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2154 // The caller's transceiver should have stopped after receiving the answer.
2155 EXPECT_TRUE(caller()
2156 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2157 ->stopped());
2158 }
deadbeef1dcb1642017-03-29 21:08:16 -07002159}
2160
2161// Test that if the answerer rejects the video m= section, no video is sent or
2162// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002163TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002164 ASSERT_TRUE(CreatePeerConnectionWrappers());
2165 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002166 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002167 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2168 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2169 // it will reject the video m= section completely.
2170 PeerConnectionInterface::RTCOfferAnswerOptions options;
2171 options.offer_to_receive_video = 0;
2172 callee()->SetOfferAnswerOptions(options);
2173 } else {
2174 // Stopping the video RtpTransceiver will cause the media section to be
2175 // rejected in the answer.
2176 callee()->SetRemoteOfferHandler([this] {
2177 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2178 });
2179 }
Steve Anton15324772018-01-16 10:26:49 -08002180 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002181 // Do offer/answer and wait for successful end-to-end audio frames.
2182 caller()->CreateAndSetAndSignalOffer();
2183 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002184 MediaExpectations media_expectations;
2185 media_expectations.ExpectBidirectionalAudio();
2186 media_expectations.ExpectNoVideo();
2187 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2188
deadbeef1dcb1642017-03-29 21:08:16 -07002189 // Sanity check that the callee's description has a rejected video section.
2190 ASSERT_NE(nullptr, callee()->pc()->local_description());
2191 const ContentInfo* callee_video_content =
2192 GetFirstVideoContent(callee()->pc()->local_description()->description());
2193 ASSERT_NE(nullptr, callee_video_content);
2194 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002195 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2196 // The caller's transceiver should have stopped after receiving the answer.
2197 EXPECT_TRUE(caller()
2198 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2199 ->stopped());
2200 }
deadbeef1dcb1642017-03-29 21:08:16 -07002201}
2202
2203// Test that if the answerer rejects both audio and video m= sections, nothing
2204// bad happens.
2205// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2206// test anything but the fact that negotiation succeeds, which doesn't mean
2207// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002208TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002209 ASSERT_TRUE(CreatePeerConnectionWrappers());
2210 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002211 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002212 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2213 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2214 // will reject both audio and video m= sections.
2215 PeerConnectionInterface::RTCOfferAnswerOptions options;
2216 options.offer_to_receive_audio = 0;
2217 options.offer_to_receive_video = 0;
2218 callee()->SetOfferAnswerOptions(options);
2219 } else {
2220 callee()->SetRemoteOfferHandler([this] {
2221 // Stopping all transceivers will cause all media sections to be rejected.
2222 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2223 transceiver->Stop();
2224 }
2225 });
2226 }
deadbeef1dcb1642017-03-29 21:08:16 -07002227 // Do offer/answer and wait for stable signaling state.
2228 caller()->CreateAndSetAndSignalOffer();
2229 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002230
deadbeef1dcb1642017-03-29 21:08:16 -07002231 // Sanity check that the callee's description has rejected m= sections.
2232 ASSERT_NE(nullptr, callee()->pc()->local_description());
2233 const ContentInfo* callee_audio_content =
2234 GetFirstAudioContent(callee()->pc()->local_description()->description());
2235 ASSERT_NE(nullptr, callee_audio_content);
2236 EXPECT_TRUE(callee_audio_content->rejected);
2237 const ContentInfo* callee_video_content =
2238 GetFirstVideoContent(callee()->pc()->local_description()->description());
2239 ASSERT_NE(nullptr, callee_video_content);
2240 EXPECT_TRUE(callee_video_content->rejected);
2241}
2242
2243// This test sets up an audio and video call between two parties. After the
2244// call runs for a while, the caller sends an updated offer with video being
2245// rejected. Once the re-negotiation is done, the video flow should stop and
2246// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002247TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002248 ASSERT_TRUE(CreatePeerConnectionWrappers());
2249 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002250 caller()->AddAudioVideoTracks();
2251 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002252 caller()->CreateAndSetAndSignalOffer();
2253 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002254 {
2255 MediaExpectations media_expectations;
2256 media_expectations.ExpectBidirectionalAudioAndVideo();
2257 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2258 }
deadbeef1dcb1642017-03-29 21:08:16 -07002259 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002260 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2261 caller()->SetGeneratedSdpMunger(
2262 [](cricket::SessionDescription* description) {
2263 for (cricket::ContentInfo& content : description->contents()) {
2264 if (cricket::IsVideoContent(&content)) {
2265 content.rejected = true;
2266 }
2267 }
2268 });
2269 } else {
2270 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2271 }
deadbeef1dcb1642017-03-29 21:08:16 -07002272 caller()->CreateAndSetAndSignalOffer();
2273 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2274
2275 // Sanity check that the caller's description has a rejected video section.
2276 ASSERT_NE(nullptr, caller()->pc()->local_description());
2277 const ContentInfo* caller_video_content =
2278 GetFirstVideoContent(caller()->pc()->local_description()->description());
2279 ASSERT_NE(nullptr, caller_video_content);
2280 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002281 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002282 {
2283 MediaExpectations media_expectations;
2284 media_expectations.ExpectBidirectionalAudio();
2285 media_expectations.ExpectNoVideo();
2286 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2287 }
deadbeef1dcb1642017-03-29 21:08:16 -07002288}
2289
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002290// Do one offer/answer with audio, another that disables it (rejecting the m=
2291// section), and another that re-enables it. Regression test for:
2292// bugs.webrtc.org/6023
2293TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2294 ASSERT_TRUE(CreatePeerConnectionWrappers());
2295 ConnectFakeSignaling();
2296
2297 // Add audio track, do normal offer/answer.
2298 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2299 caller()->CreateLocalAudioTrack();
2300 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2301 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2302 caller()->CreateAndSetAndSignalOffer();
2303 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2304
2305 // Remove audio track, and set offer_to_receive_audio to false to cause the
2306 // m= section to be completely disabled, not just "recvonly".
2307 caller()->pc()->RemoveTrack(sender);
2308 PeerConnectionInterface::RTCOfferAnswerOptions options;
2309 options.offer_to_receive_audio = 0;
2310 caller()->SetOfferAnswerOptions(options);
2311 caller()->CreateAndSetAndSignalOffer();
2312 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2313
2314 // Add the audio track again, expecting negotiation to succeed and frames to
2315 // flow.
2316 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2317 options.offer_to_receive_audio = 1;
2318 caller()->SetOfferAnswerOptions(options);
2319 caller()->CreateAndSetAndSignalOffer();
2320 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2321
2322 MediaExpectations media_expectations;
2323 media_expectations.CalleeExpectsSomeAudio();
2324 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2325}
2326
deadbeef1dcb1642017-03-29 21:08:16 -07002327// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2328// is needed to support legacy endpoints.
2329// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2330// add a test for an end-to-end test without MID signaling either (basically,
2331// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002332TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002333 ASSERT_TRUE(CreatePeerConnectionWrappers());
2334 ConnectFakeSignaling();
2335 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002336 caller()->AddAudioVideoTracks();
2337 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002338 // Remove SSRCs and MSIDs from the received offer SDP.
2339 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002340 caller()->CreateAndSetAndSignalOffer();
2341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002342 MediaExpectations media_expectations;
2343 media_expectations.ExpectBidirectionalAudioAndVideo();
2344 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002345}
2346
Seth Hampson5897a6e2018-04-03 11:16:33 -07002347// Basic end-to-end test, without SSRC signaling. This means that the track
2348// was created properly and frames are delivered when the MSIDs are communicated
2349// with a=msid lines and no a=ssrc lines.
2350TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2351 EndToEndCallWithoutSsrcSignaling) {
2352 const char kStreamId[] = "streamId";
2353 ASSERT_TRUE(CreatePeerConnectionWrappers());
2354 ConnectFakeSignaling();
2355 // Add just audio tracks.
2356 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2357 callee()->AddAudioTrack();
2358
2359 // Remove SSRCs from the received offer SDP.
2360 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2361 caller()->CreateAndSetAndSignalOffer();
2362 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2363 MediaExpectations media_expectations;
2364 media_expectations.ExpectBidirectionalAudio();
2365 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2366}
2367
Steve Antondf527fd2018-04-27 15:52:03 -07002368// Tests that video flows between multiple video tracks when SSRCs are not
2369// signaled. This exercises the MID RTP header extension which is needed to
2370// demux the incoming video tracks.
2371TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2372 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2373 ASSERT_TRUE(CreatePeerConnectionWrappers());
2374 ConnectFakeSignaling();
2375 caller()->AddVideoTrack();
2376 caller()->AddVideoTrack();
2377 callee()->AddVideoTrack();
2378 callee()->AddVideoTrack();
2379
2380 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2381 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2382 caller()->CreateAndSetAndSignalOffer();
2383 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2384 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2385 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2386
2387 // Expect video to be received in both directions on both tracks.
2388 MediaExpectations media_expectations;
2389 media_expectations.ExpectBidirectionalVideo();
2390 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2391}
2392
deadbeef1dcb1642017-03-29 21:08:16 -07002393// Test that if two video tracks are sent (from caller to callee, in this test),
2394// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002395TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002396 ASSERT_TRUE(CreatePeerConnectionWrappers());
2397 ConnectFakeSignaling();
2398 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002399 caller()->AddAudioVideoTracks();
2400 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002401 caller()->CreateAndSetAndSignalOffer();
2402 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002403 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002404
2405 MediaExpectations media_expectations;
2406 media_expectations.CalleeExpectsSomeAudioAndVideo();
2407 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002408}
2409
2410static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2411 bool first = true;
2412 for (cricket::ContentInfo& content : desc->contents()) {
2413 if (first) {
2414 first = false;
2415 continue;
2416 }
2417 content.bundle_only = true;
2418 }
2419 first = true;
2420 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2421 if (first) {
2422 first = false;
2423 continue;
2424 }
2425 transport.description.ice_ufrag.clear();
2426 transport.description.ice_pwd.clear();
2427 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2428 transport.description.identity_fingerprint.reset(nullptr);
2429 }
2430}
2431
2432// Test that if applying a true "max bundle" offer, which uses ports of 0,
2433// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2434// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2435// successfully and media flows.
2436// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2437// TODO(deadbeef): Won't need this test once we start generating actual
2438// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002439TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002440 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2441 ASSERT_TRUE(CreatePeerConnectionWrappers());
2442 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002443 caller()->AddAudioVideoTracks();
2444 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002445 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2446 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2447 // but the first m= section.
2448 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2449 caller()->CreateAndSetAndSignalOffer();
2450 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002451 MediaExpectations media_expectations;
2452 media_expectations.ExpectBidirectionalAudioAndVideo();
2453 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002454}
2455
2456// Test that we can receive the audio output level from a remote audio track.
2457// TODO(deadbeef): Use a fake audio source and verify that the output level is
2458// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002459TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002460 ASSERT_TRUE(CreatePeerConnectionWrappers());
2461 ConnectFakeSignaling();
2462 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002463 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002464 caller()->CreateAndSetAndSignalOffer();
2465 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2466
2467 // Get the audio output level stats. Note that the level is not available
2468 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002469 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002470 kMaxWaitForFramesMs);
2471}
2472
2473// Test that an audio input level is reported.
2474// TODO(deadbeef): Use a fake audio source and verify that the input level is
2475// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002476TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002477 ASSERT_TRUE(CreatePeerConnectionWrappers());
2478 ConnectFakeSignaling();
2479 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002480 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002481 caller()->CreateAndSetAndSignalOffer();
2482 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2483
2484 // Get the audio input level stats. The level should be available very
2485 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002486 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002487 kMaxWaitForStatsMs);
2488}
2489
2490// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002491TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002492 ASSERT_TRUE(CreatePeerConnectionWrappers());
2493 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002494 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002495 // Do offer/answer, wait for the callee to receive some frames.
2496 caller()->CreateAndSetAndSignalOffer();
2497 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002498
2499 MediaExpectations media_expectations;
2500 media_expectations.CalleeExpectsSomeAudioAndVideo();
2501 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002502
2503 // Get a handle to the remote tracks created, so they can be used as GetStats
2504 // filters.
Steve Anton15324772018-01-16 10:26:49 -08002505 for (auto receiver : callee()->pc()->GetReceivers()) {
2506 // We received frames, so we definitely should have nonzero "received bytes"
2507 // stats at this point.
2508 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2509 0);
2510 }
deadbeef1dcb1642017-03-29 21:08:16 -07002511}
2512
2513// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002514TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002515 ASSERT_TRUE(CreatePeerConnectionWrappers());
2516 ConnectFakeSignaling();
2517 auto audio_track = caller()->CreateLocalAudioTrack();
2518 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002519 caller()->AddTrack(audio_track);
2520 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002521 // Do offer/answer, wait for the callee to receive some frames.
2522 caller()->CreateAndSetAndSignalOffer();
2523 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002524 MediaExpectations media_expectations;
2525 media_expectations.CalleeExpectsSomeAudioAndVideo();
2526 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002527
2528 // The callee received frames, so we definitely should have nonzero "sent
2529 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002530 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2531 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2532}
2533
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002534// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002535TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002536 ASSERT_TRUE(CreatePeerConnectionWrappers());
2537 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002538 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002539
Steve Anton15324772018-01-16 10:26:49 -08002540 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002541
2542 // Do offer/answer, wait for the callee to receive some frames.
2543 caller()->CreateAndSetAndSignalOffer();
2544 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2545
2546 // Get the remote audio track created on the receiver, so they can be used as
2547 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002548 auto receivers = callee()->pc()->GetReceivers();
2549 ASSERT_EQ(1u, receivers.size());
2550 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002551
2552 // Get the audio output level stats. Note that the level is not available
2553 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002554 EXPECT_TRUE_WAIT(
2555 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2556 0,
2557 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002558}
2559
deadbeefd8ad7882017-04-18 16:01:17 -07002560// Test that we can get stats (using the new stats implemnetation) for
2561// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2562// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002563TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002564 GetStatsForUnsignaledStreamWithNewStatsApi) {
2565 ASSERT_TRUE(CreatePeerConnectionWrappers());
2566 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002567 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002568 // Remove SSRCs and MSIDs from the received offer SDP.
2569 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2570 caller()->CreateAndSetAndSignalOffer();
2571 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002572 MediaExpectations media_expectations;
2573 media_expectations.CalleeExpectsSomeAudio(1);
2574 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002575
2576 // We received a frame, so we should have nonzero "bytes received" stats for
2577 // the unsignaled stream, if stats are working for it.
2578 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2579 callee()->NewGetStats();
2580 ASSERT_NE(nullptr, report);
2581 auto inbound_stream_stats =
2582 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2583 ASSERT_EQ(1U, inbound_stream_stats.size());
2584 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2585 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002586 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2587}
2588
Taylor Brandstettera4653442018-06-19 09:44:26 -07002589// Same as above but for the legacy stats implementation.
2590TEST_P(PeerConnectionIntegrationTest,
2591 GetStatsForUnsignaledStreamWithOldStatsApi) {
2592 ASSERT_TRUE(CreatePeerConnectionWrappers());
2593 ConnectFakeSignaling();
2594 caller()->AddAudioTrack();
2595 // Remove SSRCs and MSIDs from the received offer SDP.
2596 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2597 caller()->CreateAndSetAndSignalOffer();
2598 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2599
2600 // Note that, since the old stats implementation associates SSRCs with tracks
2601 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2602 // associated track ID. So we can't use the track "selector" argument.
2603 //
2604 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2605 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002606 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07002607 kDefaultTimeout);
2608}
2609
zhihuangf8164932017-05-19 13:09:47 -07002610// Test that we can successfully get the media related stats (audio level
2611// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002612TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002613 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2614 ASSERT_TRUE(CreatePeerConnectionWrappers());
2615 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002616 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002617 // Remove SSRCs and MSIDs from the received offer SDP.
2618 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2619 caller()->CreateAndSetAndSignalOffer();
2620 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002621 MediaExpectations media_expectations;
2622 media_expectations.CalleeExpectsSomeAudio(1);
2623 media_expectations.CalleeExpectsSomeVideo(1);
2624 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002625
2626 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2627 callee()->NewGetStats();
2628 ASSERT_NE(nullptr, report);
2629
2630 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2631 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2632 ASSERT_GE(audio_index, 0);
2633 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002634}
2635
deadbeef4e2deab2017-09-20 13:56:21 -07002636// Helper for test below.
2637void ModifySsrcs(cricket::SessionDescription* desc) {
2638 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002639 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002640 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002641 for (uint32_t& ssrc : stream.ssrcs) {
2642 ssrc = rtc::CreateRandomId();
2643 }
2644 }
2645 }
2646}
2647
2648// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2649// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2650// This should result in two "RTCInboundRTPStreamStats", but only one
2651// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2652// being reset to 0 once the SSRC change occurs.
2653//
2654// Regression test for this bug:
2655// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2656//
2657// The bug causes the track stats to only represent one of the two streams:
2658// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2659// that the track stat counters would reset to 0 when the new stream is
2660// received, and a 50% chance that they'll stop updating (while
2661// "concealed_samples" continues increasing, due to silence being generated for
2662// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002663TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002664 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002665 ASSERT_TRUE(CreatePeerConnectionWrappers());
2666 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002667 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002668 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2669 // that doesn't signal SSRCs (from the callee's perspective).
2670 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2671 caller()->CreateAndSetAndSignalOffer();
2672 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2673 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002674 {
2675 MediaExpectations media_expectations;
2676 media_expectations.CalleeExpectsSomeAudio(50);
2677 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2678 }
deadbeef4e2deab2017-09-20 13:56:21 -07002679 // Some audio frames were received, so we should have nonzero "samples
2680 // received" for the track.
2681 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2682 callee()->NewGetStats();
2683 ASSERT_NE(nullptr, report);
2684 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2685 ASSERT_EQ(1U, track_stats.size());
2686 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2687 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2688 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2689
2690 // Create a new offer and munge it to cause the caller to use a new SSRC.
2691 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2692 caller()->CreateAndSetAndSignalOffer();
2693 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2694 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2695 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002696 {
2697 MediaExpectations media_expectations;
2698 media_expectations.CalleeExpectsSomeAudio(25);
2699 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2700 }
deadbeef4e2deab2017-09-20 13:56:21 -07002701
2702 report = callee()->NewGetStats();
2703 ASSERT_NE(nullptr, report);
2704 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2705 ASSERT_EQ(1U, track_stats.size());
2706 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2707 // The "total samples received" stat should only be greater than it was
2708 // before.
2709 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2710 // Right now, the new SSRC will cause the counters to reset to 0.
2711 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2712
2713 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002714 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002715 // good sign that we're seeing stats from the old stream that's no longer
2716 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002717 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002718 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2719 EXPECT_LT(*track_stats[0]->concealed_samples,
2720 *track_stats[0]->total_samples_received *
2721 kAcceptableConcealedSamplesPercentage);
2722
2723 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2724 // sanity check that the SSRC really changed.
2725 // TODO(deadbeef): This isn't working right now, because we're not returning
2726 // *any* stats for the inactive stream. Uncomment when the bug is completely
2727 // fixed.
2728 // auto inbound_stream_stats =
2729 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2730 // ASSERT_EQ(2U, inbound_stream_stats.size());
2731}
2732
deadbeef1dcb1642017-03-29 21:08:16 -07002733// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002734TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002735 PeerConnectionFactory::Options dtls_10_options;
2736 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2737 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2738 dtls_10_options));
2739 ConnectFakeSignaling();
2740 // Do normal offer/answer and wait for some frames to be received in each
2741 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002742 caller()->AddAudioVideoTracks();
2743 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002744 caller()->CreateAndSetAndSignalOffer();
2745 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002746 MediaExpectations media_expectations;
2747 media_expectations.ExpectBidirectionalAudioAndVideo();
2748 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002749}
2750
2751// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002752TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002753 PeerConnectionFactory::Options dtls_10_options;
2754 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2755 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2756 dtls_10_options));
2757 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002758 caller()->AddAudioVideoTracks();
2759 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002760 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002761 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002762 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002763 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002764 kDefaultTimeout);
2765 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002766 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002767 // TODO(bugs.webrtc.org/9456): Fix it.
2768 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2769 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2770 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002771}
2772
2773// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002774TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002775 PeerConnectionFactory::Options dtls_12_options;
2776 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2777 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2778 dtls_12_options));
2779 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002780 caller()->AddAudioVideoTracks();
2781 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002782 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002783 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002784 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002785 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002786 kDefaultTimeout);
2787 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002788 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002789 // TODO(bugs.webrtc.org/9456): Fix it.
2790 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2791 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2792 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002793}
2794
2795// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2796// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002797TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002798 PeerConnectionFactory::Options caller_options;
2799 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2800 PeerConnectionFactory::Options callee_options;
2801 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2802 ASSERT_TRUE(
2803 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2804 ConnectFakeSignaling();
2805 // Do normal offer/answer and wait for some frames to be received in each
2806 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002807 caller()->AddAudioVideoTracks();
2808 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002809 caller()->CreateAndSetAndSignalOffer();
2810 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002811 MediaExpectations media_expectations;
2812 media_expectations.ExpectBidirectionalAudioAndVideo();
2813 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002814}
2815
2816// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2817// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002818TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07002819 PeerConnectionFactory::Options caller_options;
2820 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2821 PeerConnectionFactory::Options callee_options;
2822 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2823 ASSERT_TRUE(
2824 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2825 ConnectFakeSignaling();
2826 // Do normal offer/answer and wait for some frames to be received in each
2827 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002828 caller()->AddAudioVideoTracks();
2829 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002830 caller()->CreateAndSetAndSignalOffer();
2831 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002832 MediaExpectations media_expectations;
2833 media_expectations.ExpectBidirectionalAudioAndVideo();
2834 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002835}
2836
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002837// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2838// works as expected; the cipher should only be used if enabled by both sides.
2839TEST_P(PeerConnectionIntegrationTest,
2840 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2841 PeerConnectionFactory::Options caller_options;
2842 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2843 PeerConnectionFactory::Options callee_options;
2844 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2845 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2846 TestNegotiatedCipherSuite(caller_options, callee_options,
2847 expected_cipher_suite);
2848}
2849
2850TEST_P(PeerConnectionIntegrationTest,
2851 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2852 PeerConnectionFactory::Options caller_options;
2853 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2854 PeerConnectionFactory::Options callee_options;
2855 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2856 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2857 TestNegotiatedCipherSuite(caller_options, callee_options,
2858 expected_cipher_suite);
2859}
2860
2861TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2862 PeerConnectionFactory::Options caller_options;
2863 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2864 PeerConnectionFactory::Options callee_options;
2865 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2866 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2867 TestNegotiatedCipherSuite(caller_options, callee_options,
2868 expected_cipher_suite);
2869}
2870
deadbeef1dcb1642017-03-29 21:08:16 -07002871// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002872TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002873 bool local_gcm_enabled = false;
2874 bool remote_gcm_enabled = false;
2875 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2876 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2877 expected_cipher_suite);
2878}
2879
2880// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002881TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002882 bool local_gcm_enabled = true;
2883 bool remote_gcm_enabled = true;
2884 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2885 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2886 expected_cipher_suite);
2887}
2888
2889// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002890TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002891 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2892 bool local_gcm_enabled = true;
2893 bool remote_gcm_enabled = false;
2894 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2895 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2896 expected_cipher_suite);
2897}
2898
2899// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002900TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002901 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2902 bool local_gcm_enabled = false;
2903 bool remote_gcm_enabled = true;
2904 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2905 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2906 expected_cipher_suite);
2907}
2908
deadbeef7914b8c2017-04-21 03:23:33 -07002909// Verify that media can be transmitted end-to-end when GCM crypto suites are
2910// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2911// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2912// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002913TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07002914 PeerConnectionFactory::Options gcm_options;
2915 gcm_options.crypto_options.enable_gcm_crypto_suites = true;
2916 ASSERT_TRUE(
2917 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2918 ConnectFakeSignaling();
2919 // Do normal offer/answer and wait for some frames to be received in each
2920 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002921 caller()->AddAudioVideoTracks();
2922 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07002923 caller()->CreateAndSetAndSignalOffer();
2924 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002925 MediaExpectations media_expectations;
2926 media_expectations.ExpectBidirectionalAudioAndVideo();
2927 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07002928}
2929
deadbeef1dcb1642017-03-29 21:08:16 -07002930// This test sets up a call between two parties with audio, video and an RTP
2931// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002932TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02002933 PeerConnectionInterface::RTCConfiguration rtc_config;
2934 rtc_config.enable_rtp_data_channel = true;
2935 rtc_config.enable_dtls_srtp = false;
2936 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07002937 ConnectFakeSignaling();
2938 // Expect that data channel created on caller side will show up for callee as
2939 // well.
2940 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002941 caller()->AddAudioVideoTracks();
2942 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002943 caller()->CreateAndSetAndSignalOffer();
2944 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2945 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002946 MediaExpectations media_expectations;
2947 media_expectations.ExpectBidirectionalAudioAndVideo();
2948 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002949 ASSERT_NE(nullptr, caller()->data_channel());
2950 ASSERT_NE(nullptr, callee()->data_channel());
2951 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2952 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2953
2954 // Ensure data can be sent in both directions.
2955 std::string data = "hello world";
2956 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2957 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2958 kDefaultTimeout);
2959 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2960 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2961 kDefaultTimeout);
2962}
2963
2964// Ensure that an RTP data channel is signaled as closed for the caller when
2965// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002966TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002967 RtpDataChannelSignaledClosedInCalleeOffer) {
2968 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02002969 PeerConnectionInterface::RTCConfiguration rtc_config;
2970 rtc_config.enable_rtp_data_channel = true;
2971 rtc_config.enable_dtls_srtp = false;
2972 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07002973 ConnectFakeSignaling();
2974 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002975 caller()->AddAudioVideoTracks();
2976 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002977 caller()->CreateAndSetAndSignalOffer();
2978 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2979 ASSERT_NE(nullptr, caller()->data_channel());
2980 ASSERT_NE(nullptr, callee()->data_channel());
2981 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2982 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2983
2984 // Close the data channel on the callee, and do an updated offer/answer.
2985 callee()->data_channel()->Close();
2986 callee()->CreateAndSetAndSignalOffer();
2987 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2988 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2989 EXPECT_FALSE(callee()->data_observer()->IsOpen());
2990}
2991
2992// Tests that data is buffered in an RTP data channel until an observer is
2993// registered for it.
2994//
2995// NOTE: RTP data channels can receive data before the underlying
2996// transport has detected that a channel is writable and thus data can be
2997// received before the data channel state changes to open. That is hard to test
2998// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002999TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003000 DataBufferedUntilRtpDataChannelObserverRegistered) {
3001 // Use fake clock and simulated network delay so that we predictably can wait
3002 // until an SCTP message has been delivered without "sleep()"ing.
3003 rtc::ScopedFakeClock fake_clock;
3004 // Some things use a time of "0" as a special value, so we need to start out
3005 // the fake clock at a nonzero time.
3006 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003007 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003008 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3009 virtual_socket_server()->UpdateDelayDistribution();
3010
Niels Möllerf06f9232018-08-07 12:32:18 +02003011 PeerConnectionInterface::RTCConfiguration rtc_config;
3012 rtc_config.enable_rtp_data_channel = true;
3013 rtc_config.enable_dtls_srtp = false;
3014 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003015 ConnectFakeSignaling();
3016 caller()->CreateDataChannel();
3017 caller()->CreateAndSetAndSignalOffer();
3018 ASSERT_TRUE(caller()->data_channel() != nullptr);
3019 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
3020 kDefaultTimeout, fake_clock);
3021 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
3022 kDefaultTimeout, fake_clock);
3023 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3024 callee()->data_channel()->state(), kDefaultTimeout,
3025 fake_clock);
3026
3027 // Unregister the observer which is normally automatically registered.
3028 callee()->data_channel()->UnregisterObserver();
3029 // Send data and advance fake clock until it should have been received.
3030 std::string data = "hello world";
3031 caller()->data_channel()->Send(DataBuffer(data));
3032 SIMULATED_WAIT(false, 50, fake_clock);
3033
3034 // Attach data channel and expect data to be received immediately. Note that
3035 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3036 // further, but data can be received even if the callback is asynchronous.
3037 MockDataChannelObserver new_observer(callee()->data_channel());
3038 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
3039 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07003040 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3041 // If this is not done a DCHECK can be hit in ports.cc, because a large
3042 // negative number is calculated for the rtt due to the global clock changing.
3043 caller()->pc()->Close();
3044 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07003045}
3046
3047// This test sets up a call between two parties with audio, video and but only
3048// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003049TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003050 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3051 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003052 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003053 rtc_config_1.enable_dtls_srtp = false;
3054 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3055 rtc_config_2.enable_dtls_srtp = false;
3056 rtc_config_2.enable_dtls_srtp = false;
3057 ASSERT_TRUE(
3058 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003059 ConnectFakeSignaling();
3060 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003061 caller()->AddAudioVideoTracks();
3062 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003063 caller()->CreateAndSetAndSignalOffer();
3064 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3065 // The caller should still have a data channel, but it should be closed, and
3066 // one should ever have been created for the callee.
3067 EXPECT_TRUE(caller()->data_channel() != nullptr);
3068 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3069 EXPECT_EQ(nullptr, callee()->data_channel());
3070}
3071
3072// This test sets up a call between two parties with audio, and video. When
3073// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003074TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003075 PeerConnectionInterface::RTCConfiguration rtc_config;
3076 rtc_config.enable_rtp_data_channel = true;
3077 rtc_config.enable_dtls_srtp = false;
3078 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003079 ConnectFakeSignaling();
3080 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003081 caller()->AddAudioVideoTracks();
3082 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003083 caller()->CreateAndSetAndSignalOffer();
3084 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3085 // Create data channel and do new offer and answer.
3086 caller()->CreateDataChannel();
3087 caller()->CreateAndSetAndSignalOffer();
3088 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3089 ASSERT_NE(nullptr, caller()->data_channel());
3090 ASSERT_NE(nullptr, callee()->data_channel());
3091 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3092 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3093 // Ensure data can be sent in both directions.
3094 std::string data = "hello world";
3095 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3096 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3097 kDefaultTimeout);
3098 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3099 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3100 kDefaultTimeout);
3101}
3102
3103#ifdef HAVE_SCTP
3104
3105// This test sets up a call between two parties with audio, video and an SCTP
3106// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003107TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003108 ASSERT_TRUE(CreatePeerConnectionWrappers());
3109 ConnectFakeSignaling();
3110 // Expect that data channel created on caller side will show up for callee as
3111 // well.
3112 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003113 caller()->AddAudioVideoTracks();
3114 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003115 caller()->CreateAndSetAndSignalOffer();
3116 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3117 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003118 MediaExpectations media_expectations;
3119 media_expectations.ExpectBidirectionalAudioAndVideo();
3120 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003121 // Caller data channel should already exist (it created one). Callee data
3122 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3123 ASSERT_NE(nullptr, caller()->data_channel());
3124 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3125 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3126 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3127
3128 // Ensure data can be sent in both directions.
3129 std::string data = "hello world";
3130 caller()->data_channel()->Send(DataBuffer(data));
3131 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3132 kDefaultTimeout);
3133 callee()->data_channel()->Send(DataBuffer(data));
3134 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3135 kDefaultTimeout);
3136}
3137
3138// Ensure that when the callee closes an SCTP data channel, the closing
3139// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003140TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003141 // Same procedure as above test.
3142 ASSERT_TRUE(CreatePeerConnectionWrappers());
3143 ConnectFakeSignaling();
3144 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003145 caller()->AddAudioVideoTracks();
3146 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003147 caller()->CreateAndSetAndSignalOffer();
3148 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3149 ASSERT_NE(nullptr, caller()->data_channel());
3150 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3151 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3152 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3153
3154 // Close the data channel on the callee side, and wait for it to reach the
3155 // "closed" state on both sides.
3156 callee()->data_channel()->Close();
3157 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3158 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3159}
3160
Seth Hampson2f0d7022018-02-20 11:54:42 -08003161TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003162 ASSERT_TRUE(CreatePeerConnectionWrappers());
3163 ConnectFakeSignaling();
3164 webrtc::DataChannelInit init;
3165 init.id = 53;
3166 init.maxRetransmits = 52;
3167 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003168 caller()->AddAudioVideoTracks();
3169 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003170 caller()->CreateAndSetAndSignalOffer();
3171 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003172 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3173 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 11:41:54 -07003174 EXPECT_EQ(init.id, callee()->data_channel()->id());
3175 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3176 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3177 EXPECT_FALSE(callee()->data_channel()->negotiated());
3178}
3179
deadbeef1dcb1642017-03-29 21:08:16 -07003180// Test usrsctp's ability to process unordered data stream, where data actually
3181// arrives out of order using simulated delays. Previously there have been some
3182// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003183TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003184 // Introduce random network delays.
3185 // Otherwise it's not a true "unordered" test.
3186 virtual_socket_server()->set_delay_mean(20);
3187 virtual_socket_server()->set_delay_stddev(5);
3188 virtual_socket_server()->UpdateDelayDistribution();
3189 // Normal procedure, but with unordered data channel config.
3190 ASSERT_TRUE(CreatePeerConnectionWrappers());
3191 ConnectFakeSignaling();
3192 webrtc::DataChannelInit init;
3193 init.ordered = false;
3194 caller()->CreateDataChannel(&init);
3195 caller()->CreateAndSetAndSignalOffer();
3196 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3197 ASSERT_NE(nullptr, caller()->data_channel());
3198 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3199 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3200 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3201
3202 static constexpr int kNumMessages = 100;
3203 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3204 static constexpr size_t kMaxMessageSize = 4096;
3205 // Create and send random messages.
3206 std::vector<std::string> sent_messages;
3207 for (int i = 0; i < kNumMessages; ++i) {
3208 size_t length =
3209 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3210 std::string message;
3211 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3212 caller()->data_channel()->Send(DataBuffer(message));
3213 callee()->data_channel()->Send(DataBuffer(message));
3214 sent_messages.push_back(message);
3215 }
3216
3217 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003218 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003219 caller()->data_observer()->received_message_count(),
3220 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003221 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003222 callee()->data_observer()->received_message_count(),
3223 kDefaultTimeout);
3224
3225 // Sort and compare to make sure none of the messages were corrupted.
3226 std::vector<std::string> caller_received_messages =
3227 caller()->data_observer()->messages();
3228 std::vector<std::string> callee_received_messages =
3229 callee()->data_observer()->messages();
3230 std::sort(sent_messages.begin(), sent_messages.end());
3231 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3232 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3233 EXPECT_EQ(sent_messages, caller_received_messages);
3234 EXPECT_EQ(sent_messages, callee_received_messages);
3235}
3236
3237// This test sets up a call between two parties with audio, and video. When
3238// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003239TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003240 ASSERT_TRUE(CreatePeerConnectionWrappers());
3241 ConnectFakeSignaling();
3242 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003243 caller()->AddAudioVideoTracks();
3244 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003245 caller()->CreateAndSetAndSignalOffer();
3246 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3247 // Create data channel and do new offer and answer.
3248 caller()->CreateDataChannel();
3249 caller()->CreateAndSetAndSignalOffer();
3250 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3251 // Caller data channel should already exist (it created one). Callee data
3252 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3253 ASSERT_NE(nullptr, caller()->data_channel());
3254 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3255 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3256 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3257 // Ensure data can be sent in both directions.
3258 std::string data = "hello world";
3259 caller()->data_channel()->Send(DataBuffer(data));
3260 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3261 kDefaultTimeout);
3262 callee()->data_channel()->Send(DataBuffer(data));
3263 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3264 kDefaultTimeout);
3265}
3266
deadbeef7914b8c2017-04-21 03:23:33 -07003267// Set up a connection initially just using SCTP data channels, later upgrading
3268// to audio/video, ensuring frames are received end-to-end. Effectively the
3269// inverse of the test above.
3270// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003271TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003272 ASSERT_TRUE(CreatePeerConnectionWrappers());
3273 ConnectFakeSignaling();
3274 // Do initial offer/answer with just data channel.
3275 caller()->CreateDataChannel();
3276 caller()->CreateAndSetAndSignalOffer();
3277 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3278 // Wait until data can be sent over the data channel.
3279 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3280 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3281 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3282
3283 // Do subsequent offer/answer with two-way audio and video. Audio and video
3284 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003285 caller()->AddAudioVideoTracks();
3286 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003287 caller()->CreateAndSetAndSignalOffer();
3288 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003289 MediaExpectations media_expectations;
3290 media_expectations.ExpectBidirectionalAudioAndVideo();
3291 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003292}
3293
deadbeef8b7e9ad2017-05-25 09:38:55 -07003294static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 09:38:55 -07003295 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 15:14:30 -08003296 GetFirstDataContentDescription(desc);
3297 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003298 dcd_offer->set_use_sctpmap(false);
3299 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3300}
3301
3302// Test that the data channel works when a spec-compliant SCTP m= section is
3303// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3304// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003305TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003306 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3307 ASSERT_TRUE(CreatePeerConnectionWrappers());
3308 ConnectFakeSignaling();
3309 caller()->CreateDataChannel();
3310 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3311 caller()->CreateAndSetAndSignalOffer();
3312 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3313 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3314 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3315 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3316
3317 // Ensure data can be sent in both directions.
3318 std::string data = "hello world";
3319 caller()->data_channel()->Send(DataBuffer(data));
3320 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3321 kDefaultTimeout);
3322 callee()->data_channel()->Send(DataBuffer(data));
3323 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3324 kDefaultTimeout);
3325}
3326
deadbeef1dcb1642017-03-29 21:08:16 -07003327#endif // HAVE_SCTP
3328
3329// Test that the ICE connection and gathering states eventually reach
3330// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003331TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003332 ASSERT_TRUE(CreatePeerConnectionWrappers());
3333 ConnectFakeSignaling();
3334 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003335 caller()->AddAudioVideoTracks();
3336 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003337 caller()->CreateAndSetAndSignalOffer();
3338 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3339 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3340 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3341 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3342 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3343 // After the best candidate pair is selected and all candidates are signaled,
3344 // the ICE connection state should reach "complete".
3345 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3346 // answerer/"callee" by default) only reaches "connected". When this is
3347 // fixed, this test should be updated.
3348 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3349 caller()->ice_connection_state(), kDefaultTimeout);
3350 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3351 callee()->ice_connection_state(), kDefaultTimeout);
3352}
3353
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003354// Replaces the first candidate with a static address and configures a
3355// MockAsyncResolver to return the replaced address the first time the static
3356// address is resolved. Candidates past the first will not be signaled.
3357class ReplaceFirstCandidateAddressDropOthers final
3358 : public IceCandidateReplacerInterface {
3359 public:
3360 ReplaceFirstCandidateAddressDropOthers(
3361 const SocketAddress& new_address,
3362 rtc::MockAsyncResolver* mock_async_resolver)
3363 : mock_async_resolver_(mock_async_resolver), new_address_(new_address) {
3364 RTC_DCHECK(mock_async_resolver);
3365 }
3366
3367 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3368 const webrtc::IceCandidateInterface* candidate) override {
3369 if (replaced_candidate_) {
3370 return nullptr;
3371 }
3372
3373 replaced_candidate_ = true;
3374 cricket::Candidate new_candidate(candidate->candidate());
3375 new_candidate.set_address(new_address_);
3376 EXPECT_CALL(*mock_async_resolver_, GetResolvedAddress(_, _))
3377 .WillOnce(DoAll(SetArgPointee<1>(candidate->candidate().address()),
3378 Return(true)));
3379 EXPECT_CALL(*mock_async_resolver_, Destroy(_));
3380 return webrtc::CreateIceCandidate(
3381 candidate->sdp_mid(), candidate->sdp_mline_index(), new_candidate);
3382 }
3383
3384 private:
3385 rtc::MockAsyncResolver* mock_async_resolver_;
3386 SocketAddress new_address_;
3387 bool replaced_candidate_ = false;
3388};
3389
3390// Drops all candidates before they are signaled.
3391class DropAllCandidates final : public IceCandidateReplacerInterface {
3392 public:
3393 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3394 const webrtc::IceCandidateInterface*) override {
3395 return nullptr;
3396 }
3397};
3398
3399// Replace the first caller ICE candidate IP with a fake hostname and drop the
3400// other candidates. Drop all candidates on the callee side (to avoid a prflx
3401// connection). Use a mock resolver to resolve the hostname back to the original
3402// IP on the callee side and check that the ice connection connects.
3403TEST_P(PeerConnectionIntegrationTest,
3404 IceStatesReachCompletionWithRemoteHostname) {
3405 webrtc::MockAsyncResolverFactory* callee_mock_async_resolver_factory;
3406 {
3407 auto resolver_factory =
3408 absl::make_unique<webrtc::MockAsyncResolverFactory>();
3409 callee_mock_async_resolver_factory = resolver_factory.get();
3410 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3411 callee_deps.async_resolver_factory = std::move(resolver_factory);
3412
3413 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3414 RTCConfiguration(), webrtc::PeerConnectionDependencies(nullptr),
3415 RTCConfiguration(), std::move(callee_deps)));
3416 }
3417
3418 rtc::MockAsyncResolver mock_async_resolver;
3419
3420 // This also verifies that the injected AsyncResolverFactory is used by
3421 // P2PTransportChannel.
3422 EXPECT_CALL(*callee_mock_async_resolver_factory, Create())
3423 .WillOnce(Return(&mock_async_resolver));
3424 caller()->SetLocalIceCandidateReplacer(
3425 absl::make_unique<ReplaceFirstCandidateAddressDropOthers>(
3426 SocketAddress("a.b", 10000), &mock_async_resolver));
3427 callee()->SetLocalIceCandidateReplacer(
3428 absl::make_unique<DropAllCandidates>());
3429
3430 ConnectFakeSignaling();
3431 caller()->AddAudioVideoTracks();
3432 callee()->AddAudioVideoTracks();
3433 caller()->CreateAndSetAndSignalOffer();
3434 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3435 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3436 caller()->ice_connection_state(), kDefaultTimeout);
3437 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3438 callee()->ice_connection_state(), kDefaultTimeout);
3439}
3440
Steve Antonede9ca52017-10-16 13:04:27 -07003441// Test that firewalling the ICE connection causes the clients to identify the
3442// disconnected state and then removing the firewall causes them to reconnect.
3443class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003444 : public PeerConnectionIntegrationBaseTest,
3445 public ::testing::WithParamInterface<
3446 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003447 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003448 PeerConnectionIntegrationIceStatesTest()
3449 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3450 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003451 }
3452
3453 void StartStunServer(const SocketAddress& server_address) {
3454 stun_server_.reset(
3455 cricket::TestStunServer::Create(network_thread(), server_address));
3456 }
3457
3458 bool TestIPv6() {
3459 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3460 }
3461
3462 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 16:57:45 -07003463 network_thread()->Invoke<void>(
3464 RTC_FROM_HERE,
3465 rtc::Bind(&cricket::PortAllocator::set_flags,
3466 caller()->port_allocator(), port_allocator_flags_));
3467 network_thread()->Invoke<void>(
3468 RTC_FROM_HERE,
3469 rtc::Bind(&cricket::PortAllocator::set_flags,
3470 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 13:04:27 -07003471 }
3472
3473 std::vector<SocketAddress> CallerAddresses() {
3474 std::vector<SocketAddress> addresses;
3475 addresses.push_back(SocketAddress("1.1.1.1", 0));
3476 if (TestIPv6()) {
3477 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3478 }
3479 return addresses;
3480 }
3481
3482 std::vector<SocketAddress> CalleeAddresses() {
3483 std::vector<SocketAddress> addresses;
3484 addresses.push_back(SocketAddress("2.2.2.2", 0));
3485 if (TestIPv6()) {
3486 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3487 }
3488 return addresses;
3489 }
3490
3491 void SetUpNetworkInterfaces() {
3492 // Remove the default interfaces added by the test infrastructure.
3493 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3494 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3495
3496 // Add network addresses for test.
3497 for (const auto& caller_address : CallerAddresses()) {
3498 caller()->network()->AddInterface(caller_address);
3499 }
3500 for (const auto& callee_address : CalleeAddresses()) {
3501 callee()->network()->AddInterface(callee_address);
3502 }
3503 }
3504
3505 private:
3506 uint32_t port_allocator_flags_;
3507 std::unique_ptr<cricket::TestStunServer> stun_server_;
3508};
3509
3510// Tests that the PeerConnection goes through all the ICE gathering/connection
3511// states over the duration of the call. This includes Disconnected and Failed
3512// states, induced by putting a firewall between the peers and waiting for them
3513// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003514TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3515 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3516 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3517 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 13:04:27 -07003518
3519 const SocketAddress kStunServerAddress =
3520 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3521 StartStunServer(kStunServerAddress);
3522
3523 PeerConnectionInterface::RTCConfiguration config;
3524 PeerConnectionInterface::IceServer ice_stun_server;
3525 ice_stun_server.urls.push_back(
3526 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3527 kStunServerAddress.PortAsString());
3528 config.servers.push_back(ice_stun_server);
3529
3530 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3531 ConnectFakeSignaling();
3532 SetPortAllocatorFlags();
3533 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003534 caller()->AddAudioVideoTracks();
3535 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003536
3537 // Initial state before anything happens.
3538 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3539 caller()->ice_gathering_state());
3540 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3541 caller()->ice_connection_state());
3542
3543 // Start the call by creating the offer, setting it as the local description,
3544 // then sending it to the peer who will respond with an answer. This happens
3545 // asynchronously so that we can watch the states as it runs in the
3546 // background.
3547 caller()->CreateAndSetAndSignalOffer();
3548
Steve Anton83119dd2017-11-10 16:19:52 -08003549 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3550 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003551
3552 // Verify that the observer was notified of the intermediate transitions.
3553 EXPECT_THAT(caller()->ice_connection_state_history(),
3554 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3555 PeerConnectionInterface::kIceConnectionConnected,
3556 PeerConnectionInterface::kIceConnectionCompleted));
3557 EXPECT_THAT(caller()->ice_gathering_state_history(),
3558 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3559 PeerConnectionInterface::kIceGatheringComplete));
3560
3561 // Block connections to/from the caller and wait for ICE to become
3562 // disconnected.
3563 for (const auto& caller_address : CallerAddresses()) {
3564 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3565 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003566 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-10 16:19:52 -08003567 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3568 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003569
3570 // Let ICE re-establish by removing the firewall rules.
3571 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01003572 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-10 16:19:52 -08003573 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3574 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003575
3576 // According to RFC7675, if there is no response within 30 seconds then the
3577 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08003578 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07003579 constexpr int kConsentTimeout = 30000;
3580 for (const auto& caller_address : CallerAddresses()) {
3581 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3582 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003583 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-10 16:19:52 -08003584 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3585 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003586}
3587
3588// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3589// and that the statistics in the metric observers are updated correctly.
3590TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3591 ASSERT_TRUE(CreatePeerConnectionWrappers());
3592 ConnectFakeSignaling();
3593 SetPortAllocatorFlags();
3594 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003595 caller()->AddAudioVideoTracks();
3596 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003597 caller()->CreateAndSetAndSignalOffer();
3598
3599 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3600
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003601 // TODO(bugs.webrtc.org/9456): Fix it.
3602 const int num_best_ipv4 = webrtc::metrics::NumEvents(
3603 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
3604 const int num_best_ipv6 = webrtc::metrics::NumEvents(
3605 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003606 if (TestIPv6()) {
3607 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3608 // connection.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003609 EXPECT_EQ(0, num_best_ipv4);
3610 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003611 } else {
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003612 EXPECT_EQ(1, num_best_ipv4);
3613 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003614 }
3615
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003616 EXPECT_EQ(0, webrtc::metrics::NumEvents(
3617 "WebRTC.PeerConnection.CandidatePairType_UDP",
3618 webrtc::kIceCandidatePairHostHost));
3619 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3620 "WebRTC.PeerConnection.CandidatePairType_UDP",
3621 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07003622}
3623
3624constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3625 cricket::PORTALLOCATOR_DISABLE_STUN |
3626 cricket::PORTALLOCATOR_DISABLE_RELAY;
3627constexpr uint32_t kFlagsIPv6NoStun =
3628 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3629 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3630constexpr uint32_t kFlagsIPv4Stun =
3631 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3632
Seth Hampson2f0d7022018-02-20 11:54:42 -08003633INSTANTIATE_TEST_CASE_P(
3634 PeerConnectionIntegrationTest,
3635 PeerConnectionIntegrationIceStatesTest,
3636 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3637 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3638 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3639 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07003640
deadbeef1dcb1642017-03-29 21:08:16 -07003641// This test sets up a call between two parties with audio and video.
3642// During the call, the caller restarts ICE and the test verifies that
3643// new ICE candidates are generated and audio and video still can flow, and the
3644// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003645TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07003646 ASSERT_TRUE(CreatePeerConnectionWrappers());
3647 ConnectFakeSignaling();
3648 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08003649 caller()->AddAudioVideoTracks();
3650 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003651 caller()->CreateAndSetAndSignalOffer();
3652 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3653 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3654 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3655 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3656 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3657
3658 // To verify that the ICE restart actually occurs, get
3659 // ufrag/password/candidates before and after restart.
3660 // Create an SDP string of the first audio candidate for both clients.
3661 const webrtc::IceCandidateCollection* audio_candidates_caller =
3662 caller()->pc()->local_description()->candidates(0);
3663 const webrtc::IceCandidateCollection* audio_candidates_callee =
3664 callee()->pc()->local_description()->candidates(0);
3665 ASSERT_GT(audio_candidates_caller->count(), 0u);
3666 ASSERT_GT(audio_candidates_callee->count(), 0u);
3667 std::string caller_candidate_pre_restart;
3668 ASSERT_TRUE(
3669 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3670 std::string callee_candidate_pre_restart;
3671 ASSERT_TRUE(
3672 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3673 const cricket::SessionDescription* desc =
3674 caller()->pc()->local_description()->description();
3675 std::string caller_ufrag_pre_restart =
3676 desc->transport_infos()[0].description.ice_ufrag;
3677 desc = callee()->pc()->local_description()->description();
3678 std::string callee_ufrag_pre_restart =
3679 desc->transport_infos()[0].description.ice_ufrag;
3680
3681 // Have the caller initiate an ICE restart.
3682 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3683 caller()->CreateAndSetAndSignalOffer();
3684 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3685 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3686 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3687 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3688 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3689
3690 // Grab the ufrags/candidates again.
3691 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3692 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3693 ASSERT_GT(audio_candidates_caller->count(), 0u);
3694 ASSERT_GT(audio_candidates_callee->count(), 0u);
3695 std::string caller_candidate_post_restart;
3696 ASSERT_TRUE(
3697 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3698 std::string callee_candidate_post_restart;
3699 ASSERT_TRUE(
3700 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3701 desc = caller()->pc()->local_description()->description();
3702 std::string caller_ufrag_post_restart =
3703 desc->transport_infos()[0].description.ice_ufrag;
3704 desc = callee()->pc()->local_description()->description();
3705 std::string callee_ufrag_post_restart =
3706 desc->transport_infos()[0].description.ice_ufrag;
3707 // Sanity check that an ICE restart was actually negotiated in SDP.
3708 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3709 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3710 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3711 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3712
3713 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003714 MediaExpectations media_expectations;
3715 media_expectations.ExpectBidirectionalAudioAndVideo();
3716 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003717}
3718
3719// Verify that audio/video can be received end-to-end when ICE renomination is
3720// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003721TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07003722 PeerConnectionInterface::RTCConfiguration config;
3723 config.enable_ice_renomination = true;
3724 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3725 ConnectFakeSignaling();
3726 // Do normal offer/answer and wait for some frames to be received in each
3727 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003728 caller()->AddAudioVideoTracks();
3729 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003730 caller()->CreateAndSetAndSignalOffer();
3731 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3732 // Sanity check that ICE renomination was actually negotiated.
3733 const cricket::SessionDescription* desc =
3734 caller()->pc()->local_description()->description();
3735 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003736 ASSERT_NE(
3737 info.description.transport_options.end(),
3738 std::find(info.description.transport_options.begin(),
3739 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003740 }
3741 desc = callee()->pc()->local_description()->description();
3742 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003743 ASSERT_NE(
3744 info.description.transport_options.end(),
3745 std::find(info.description.transport_options.begin(),
3746 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003747 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08003748 MediaExpectations media_expectations;
3749 media_expectations.ExpectBidirectionalAudioAndVideo();
3750 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003751}
3752
Steve Anton6f25b092017-10-23 09:39:20 -07003753// With a max bundle policy and RTCP muxing, adding a new media description to
3754// the connection should not affect ICE at all because the new media will use
3755// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003756TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003757 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07003758 PeerConnectionInterface::RTCConfiguration config;
3759 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3760 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3761 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3762 config, PeerConnectionInterface::RTCConfiguration()));
3763 ConnectFakeSignaling();
3764
Steve Anton15324772018-01-16 10:26:49 -08003765 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003766 caller()->CreateAndSetAndSignalOffer();
3767 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07003768 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3769 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07003770
3771 caller()->clear_ice_connection_state_history();
3772
Steve Anton15324772018-01-16 10:26:49 -08003773 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003774 caller()->CreateAndSetAndSignalOffer();
3775 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3776
3777 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3778}
3779
deadbeef1dcb1642017-03-29 21:08:16 -07003780// This test sets up a call between two parties with audio and video. It then
3781// renegotiates setting the video m-line to "port 0", then later renegotiates
3782// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003783TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003784 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3785 ASSERT_TRUE(CreatePeerConnectionWrappers());
3786 ConnectFakeSignaling();
3787
3788 // Do initial negotiation, only sending media from the caller. Will result in
3789 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08003790 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003791 caller()->CreateAndSetAndSignalOffer();
3792 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3793
3794 // Negotiate again, disabling the video "m=" section (the callee will set the
3795 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003796 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3797 PeerConnectionInterface::RTCOfferAnswerOptions options;
3798 options.offer_to_receive_video = 0;
3799 callee()->SetOfferAnswerOptions(options);
3800 } else {
3801 callee()->SetRemoteOfferHandler([this] {
3802 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3803 });
3804 }
deadbeef1dcb1642017-03-29 21:08:16 -07003805 caller()->CreateAndSetAndSignalOffer();
3806 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3807 // Sanity check that video "m=" section was actually rejected.
3808 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3809 callee()->pc()->local_description()->description());
3810 ASSERT_NE(nullptr, answer_video_content);
3811 ASSERT_TRUE(answer_video_content->rejected);
3812
3813 // Enable video and do negotiation again, making sure video is received
3814 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003815 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3816 PeerConnectionInterface::RTCOfferAnswerOptions options;
3817 options.offer_to_receive_video = 1;
3818 callee()->SetOfferAnswerOptions(options);
3819 } else {
3820 // The caller's transceiver is stopped, so we need to add another track.
3821 auto caller_transceiver =
3822 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3823 EXPECT_TRUE(caller_transceiver->stopped());
3824 caller()->AddVideoTrack();
3825 }
3826 callee()->AddVideoTrack();
3827 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07003828 caller()->CreateAndSetAndSignalOffer();
3829 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003830
deadbeef1dcb1642017-03-29 21:08:16 -07003831 // Verify the caller receives frames from the newly added stream, and the
3832 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003833 MediaExpectations media_expectations;
3834 media_expectations.CalleeExpectsSomeAudio();
3835 media_expectations.ExpectBidirectionalVideo();
3836 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003837}
3838
deadbeef1dcb1642017-03-29 21:08:16 -07003839// This tests that if we negotiate after calling CreateSender but before we
3840// have a track, then set a track later, frames from the newly-set track are
3841// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003842TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07003843 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3844 ASSERT_TRUE(CreatePeerConnectionWrappers());
3845 ConnectFakeSignaling();
3846 auto caller_audio_sender =
3847 caller()->pc()->CreateSender("audio", "caller_stream");
3848 auto caller_video_sender =
3849 caller()->pc()->CreateSender("video", "caller_stream");
3850 auto callee_audio_sender =
3851 callee()->pc()->CreateSender("audio", "callee_stream");
3852 auto callee_video_sender =
3853 callee()->pc()->CreateSender("video", "callee_stream");
3854 caller()->CreateAndSetAndSignalOffer();
3855 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3856 // Wait for ICE to complete, without any tracks being set.
3857 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3858 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3859 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3860 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3861 // Now set the tracks, and expect frames to immediately start flowing.
3862 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3863 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3864 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3865 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08003866 MediaExpectations media_expectations;
3867 media_expectations.ExpectBidirectionalAudioAndVideo();
3868 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3869}
3870
3871// This tests that if we negotiate after calling AddTransceiver but before we
3872// have a track, then set a track later, frames from the newly-set tracks are
3873// received end-to-end.
3874TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3875 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3876 ASSERT_TRUE(CreatePeerConnectionWrappers());
3877 ConnectFakeSignaling();
3878 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3879 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3880 auto caller_audio_sender = audio_result.MoveValue()->sender();
3881 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3882 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3883 auto caller_video_sender = video_result.MoveValue()->sender();
3884 callee()->SetRemoteOfferHandler([this] {
3885 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3886 callee()->pc()->GetTransceivers()[0]->SetDirection(
3887 RtpTransceiverDirection::kSendRecv);
3888 callee()->pc()->GetTransceivers()[1]->SetDirection(
3889 RtpTransceiverDirection::kSendRecv);
3890 });
3891 caller()->CreateAndSetAndSignalOffer();
3892 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3893 // Wait for ICE to complete, without any tracks being set.
3894 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3895 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3896 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3897 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3898 // Now set the tracks, and expect frames to immediately start flowing.
3899 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3900 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3901 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3902 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3903 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3904 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3905 MediaExpectations media_expectations;
3906 media_expectations.ExpectBidirectionalAudioAndVideo();
3907 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003908}
3909
3910// This test verifies that a remote video track can be added via AddStream,
3911// and sent end-to-end. For this particular test, it's simply echoed back
3912// from the caller to the callee, rather than being forwarded to a third
3913// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003914TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07003915 ASSERT_TRUE(CreatePeerConnectionWrappers());
3916 ConnectFakeSignaling();
3917 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08003918 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003919 caller()->CreateAndSetAndSignalOffer();
3920 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003921 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07003922
3923 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3924 // time).
3925 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3926 callee()->CreateAndSetAndSignalOffer();
3927 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3928
Seth Hampson2f0d7022018-02-20 11:54:42 -08003929 MediaExpectations media_expectations;
3930 media_expectations.ExpectBidirectionalVideo();
3931 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003932}
3933
3934// Test that we achieve the expected end-to-end connection time, using a
3935// fake clock and simulated latency on the media and signaling paths.
3936// We use a TURN<->TURN connection because this is usually the quickest to
3937// set up initially, especially when we're confident the connection will work
3938// and can start sending media before we get a STUN response.
3939//
3940// With various optimizations enabled, here are the network delays we expect to
3941// be on the critical path:
3942// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3943// signaling answer (with DTLS fingerprint).
3944// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3945// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3946// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003947TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07003948 rtc::ScopedFakeClock fake_clock;
3949 // Some things use a time of "0" as a special value, so we need to start out
3950 // the fake clock at a nonzero time.
3951 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003952 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003953
3954 static constexpr int media_hop_delay_ms = 50;
3955 static constexpr int signaling_trip_delay_ms = 500;
3956 // For explanation of these values, see comment above.
3957 static constexpr int required_media_hops = 9;
3958 static constexpr int required_signaling_trips = 2;
3959 // For internal delays (such as posting an event asychronously).
3960 static constexpr int allowed_internal_delay_ms = 20;
3961 static constexpr int total_connection_time_ms =
3962 media_hop_delay_ms * required_media_hops +
3963 signaling_trip_delay_ms * required_signaling_trips +
3964 allowed_internal_delay_ms;
3965
3966 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3967 3478};
3968 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3969 0};
3970 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3971 3478};
3972 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3973 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07003974 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
3975 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003976
Seth Hampsonaed71642018-06-11 07:41:32 -07003977 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
3978 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07003979 // Bypass permission check on received packets so media can be sent before
3980 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07003981 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
3982 turn_server_1->set_enable_permission_checks(false);
3983 });
3984 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
3985 turn_server_2->set_enable_permission_checks(false);
3986 });
deadbeef1dcb1642017-03-29 21:08:16 -07003987
3988 PeerConnectionInterface::RTCConfiguration client_1_config;
3989 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3990 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3991 ice_server_1.username = "test";
3992 ice_server_1.password = "test";
3993 client_1_config.servers.push_back(ice_server_1);
3994 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3995 client_1_config.presume_writable_when_fully_relayed = true;
3996
3997 PeerConnectionInterface::RTCConfiguration client_2_config;
3998 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3999 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4000 ice_server_2.username = "test";
4001 ice_server_2.password = "test";
4002 client_2_config.servers.push_back(ice_server_2);
4003 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4004 client_2_config.presume_writable_when_fully_relayed = true;
4005
4006 ASSERT_TRUE(
4007 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4008 // Set up the simulated delays.
4009 SetSignalingDelayMs(signaling_trip_delay_ms);
4010 ConnectFakeSignaling();
4011 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4012 virtual_socket_server()->UpdateDelayDistribution();
4013
4014 // Set "offer to receive audio/video" without adding any tracks, so we just
4015 // set up ICE/DTLS with no media.
4016 PeerConnectionInterface::RTCOfferAnswerOptions options;
4017 options.offer_to_receive_audio = 1;
4018 options.offer_to_receive_video = 1;
4019 caller()->SetOfferAnswerOptions(options);
4020 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004021 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
4022 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004023 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4024 // If this is not done a DCHECK can be hit in ports.cc, because a large
4025 // negative number is calculated for the rtt due to the global clock changing.
4026 caller()->pc()->Close();
4027 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07004028}
4029
Jonas Orelandbdcee282017-10-10 14:01:40 +02004030// Verify that a TurnCustomizer passed in through RTCConfiguration
4031// is actually used by the underlying TURN candidate pair.
4032// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004033TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004034 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4035 3478};
4036 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4037 0};
4038 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4039 3478};
4040 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4041 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004042 CreateTurnServer(turn_server_1_internal_address,
4043 turn_server_1_external_address);
4044 CreateTurnServer(turn_server_2_internal_address,
4045 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004046
4047 PeerConnectionInterface::RTCConfiguration client_1_config;
4048 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4049 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4050 ice_server_1.username = "test";
4051 ice_server_1.password = "test";
4052 client_1_config.servers.push_back(ice_server_1);
4053 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004054 auto* customizer1 = CreateTurnCustomizer();
4055 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004056
4057 PeerConnectionInterface::RTCConfiguration client_2_config;
4058 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4059 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4060 ice_server_2.username = "test";
4061 ice_server_2.password = "test";
4062 client_2_config.servers.push_back(ice_server_2);
4063 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004064 auto* customizer2 = CreateTurnCustomizer();
4065 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004066
4067 ASSERT_TRUE(
4068 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4069 ConnectFakeSignaling();
4070
4071 // Set "offer to receive audio/video" without adding any tracks, so we just
4072 // set up ICE/DTLS with no media.
4073 PeerConnectionInterface::RTCOfferAnswerOptions options;
4074 options.offer_to_receive_audio = 1;
4075 options.offer_to_receive_video = 1;
4076 caller()->SetOfferAnswerOptions(options);
4077 caller()->CreateAndSetAndSignalOffer();
4078 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4079
Seth Hampsonaed71642018-06-11 07:41:32 -07004080 ExpectTurnCustomizerCountersIncremented(customizer1);
4081 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004082}
4083
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004084// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4085// send media between the caller and the callee.
4086TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4087 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4088 3478};
4089 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4090
4091 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004092 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4093 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004094
4095 webrtc::PeerConnectionInterface::IceServer ice_server;
4096 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4097 ice_server.username = "test";
4098 ice_server.password = "test";
4099
4100 PeerConnectionInterface::RTCConfiguration client_1_config;
4101 client_1_config.servers.push_back(ice_server);
4102 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4103
4104 PeerConnectionInterface::RTCConfiguration client_2_config;
4105 client_2_config.servers.push_back(ice_server);
4106 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4107
4108 ASSERT_TRUE(
4109 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4110
4111 // Do normal offer/answer and wait for ICE to complete.
4112 ConnectFakeSignaling();
4113 caller()->AddAudioVideoTracks();
4114 callee()->AddAudioVideoTracks();
4115 caller()->CreateAndSetAndSignalOffer();
4116 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4117 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4118 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4119
4120 MediaExpectations media_expectations;
4121 media_expectations.ExpectBidirectionalAudioAndVideo();
4122 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4123}
4124
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004125// Verify that a SSLCertificateVerifier passed in through
4126// PeerConnectionDependencies is actually used by the underlying SSL
4127// implementation to determine whether a certificate presented by the TURN
4128// server is accepted by the client. Note that openssladapter_unittest.cc
4129// contains more detailed, lower-level tests.
4130TEST_P(PeerConnectionIntegrationTest,
4131 SSLCertificateVerifierUsedForTurnConnections) {
4132 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4133 3478};
4134 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4135
4136 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4137 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004138 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4139 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004140
4141 webrtc::PeerConnectionInterface::IceServer ice_server;
4142 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4143 ice_server.username = "test";
4144 ice_server.password = "test";
4145
4146 PeerConnectionInterface::RTCConfiguration client_1_config;
4147 client_1_config.servers.push_back(ice_server);
4148 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4149
4150 PeerConnectionInterface::RTCConfiguration client_2_config;
4151 client_2_config.servers.push_back(ice_server);
4152 // Setting the type to kRelay forces the connection to go through a TURN
4153 // server.
4154 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4155
4156 // Get a copy to the pointer so we can verify calls later.
4157 rtc::TestCertificateVerifier* client_1_cert_verifier =
4158 new rtc::TestCertificateVerifier();
4159 client_1_cert_verifier->verify_certificate_ = true;
4160 rtc::TestCertificateVerifier* client_2_cert_verifier =
4161 new rtc::TestCertificateVerifier();
4162 client_2_cert_verifier->verify_certificate_ = true;
4163
4164 // Create the dependencies with the test certificate verifier.
4165 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4166 client_1_deps.tls_cert_verifier =
4167 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4168 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4169 client_2_deps.tls_cert_verifier =
4170 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4171
4172 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4173 client_1_config, std::move(client_1_deps), client_2_config,
4174 std::move(client_2_deps)));
4175 ConnectFakeSignaling();
4176
4177 // Set "offer to receive audio/video" without adding any tracks, so we just
4178 // set up ICE/DTLS with no media.
4179 PeerConnectionInterface::RTCOfferAnswerOptions options;
4180 options.offer_to_receive_audio = 1;
4181 options.offer_to_receive_video = 1;
4182 caller()->SetOfferAnswerOptions(options);
4183 caller()->CreateAndSetAndSignalOffer();
4184 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4185
4186 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4187 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004188}
4189
4190TEST_P(PeerConnectionIntegrationTest,
4191 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4192 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4193 3478};
4194 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4195
4196 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4197 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004198 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4199 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004200
4201 webrtc::PeerConnectionInterface::IceServer ice_server;
4202 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4203 ice_server.username = "test";
4204 ice_server.password = "test";
4205
4206 PeerConnectionInterface::RTCConfiguration client_1_config;
4207 client_1_config.servers.push_back(ice_server);
4208 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4209
4210 PeerConnectionInterface::RTCConfiguration client_2_config;
4211 client_2_config.servers.push_back(ice_server);
4212 // Setting the type to kRelay forces the connection to go through a TURN
4213 // server.
4214 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4215
4216 // Get a copy to the pointer so we can verify calls later.
4217 rtc::TestCertificateVerifier* client_1_cert_verifier =
4218 new rtc::TestCertificateVerifier();
4219 client_1_cert_verifier->verify_certificate_ = false;
4220 rtc::TestCertificateVerifier* client_2_cert_verifier =
4221 new rtc::TestCertificateVerifier();
4222 client_2_cert_verifier->verify_certificate_ = false;
4223
4224 // Create the dependencies with the test certificate verifier.
4225 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4226 client_1_deps.tls_cert_verifier =
4227 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4228 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4229 client_2_deps.tls_cert_verifier =
4230 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4231
4232 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4233 client_1_config, std::move(client_1_deps), client_2_config,
4234 std::move(client_2_deps)));
4235 ConnectFakeSignaling();
4236
4237 // Set "offer to receive audio/video" without adding any tracks, so we just
4238 // set up ICE/DTLS with no media.
4239 PeerConnectionInterface::RTCOfferAnswerOptions options;
4240 options.offer_to_receive_audio = 1;
4241 options.offer_to_receive_video = 1;
4242 caller()->SetOfferAnswerOptions(options);
4243 caller()->CreateAndSetAndSignalOffer();
4244 bool wait_res = true;
4245 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4246 // properly, should be able to just wait for a state of "failed" instead of
4247 // waiting a fixed 10 seconds.
4248 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4249 ASSERT_FALSE(wait_res);
4250
4251 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4252 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004253}
4254
deadbeefc964d0b2017-04-03 10:03:35 -07004255// Test that audio and video flow end-to-end when codec names don't use the
4256// expected casing, given that they're supposed to be case insensitive. To test
4257// this, all but one codec is removed from each media description, and its
4258// casing is changed.
4259//
4260// In the past, this has regressed and caused crashes/black video, due to the
4261// fact that code at some layers was doing case-insensitive comparisons and
4262// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004263TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004264 ASSERT_TRUE(CreatePeerConnectionWrappers());
4265 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004266 caller()->AddAudioVideoTracks();
4267 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004268
4269 // Remove all but one audio/video codec (opus and VP8), and change the
4270 // casing of the caller's generated offer.
4271 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4272 cricket::AudioContentDescription* audio =
4273 GetFirstAudioContentDescription(description);
4274 ASSERT_NE(nullptr, audio);
4275 auto audio_codecs = audio->codecs();
4276 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4277 [](const cricket::AudioCodec& codec) {
4278 return codec.name != "opus";
4279 }),
4280 audio_codecs.end());
4281 ASSERT_EQ(1u, audio_codecs.size());
4282 audio_codecs[0].name = "OpUs";
4283 audio->set_codecs(audio_codecs);
4284
4285 cricket::VideoContentDescription* video =
4286 GetFirstVideoContentDescription(description);
4287 ASSERT_NE(nullptr, video);
4288 auto video_codecs = video->codecs();
4289 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4290 [](const cricket::VideoCodec& codec) {
4291 return codec.name != "VP8";
4292 }),
4293 video_codecs.end());
4294 ASSERT_EQ(1u, video_codecs.size());
4295 video_codecs[0].name = "vP8";
4296 video->set_codecs(video_codecs);
4297 });
4298
4299 caller()->CreateAndSetAndSignalOffer();
4300 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4301
4302 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004303 MediaExpectations media_expectations;
4304 media_expectations.ExpectBidirectionalAudioAndVideo();
4305 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004306}
4307
Seth Hampson2f0d7022018-02-20 11:54:42 -08004308TEST_P(PeerConnectionIntegrationTest, GetSources) {
hbos8d609f62017-04-10 07:39:05 -07004309 ASSERT_TRUE(CreatePeerConnectionWrappers());
4310 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004311 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004312 caller()->CreateAndSetAndSignalOffer();
4313 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004314 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004315 MediaExpectations media_expectations;
4316 media_expectations.CalleeExpectsSomeAudio(1);
4317 ASSERT_TRUE(ExpectNewFrames(media_expectations));
hbos8d609f62017-04-10 07:39:05 -07004318 ASSERT_GT(callee()->pc()->GetReceivers().size(), 0u);
4319 auto receiver = callee()->pc()->GetReceivers()[0];
4320 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
4321
4322 auto contributing_sources = receiver->GetSources();
4323 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4324 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4325 contributing_sources[0].source_id());
4326}
4327
deadbeef2f425aa2017-04-14 10:41:32 -07004328// Test that if a track is removed and added again with a different stream ID,
4329// the new stream ID is successfully communicated in SDP and media continues to
4330// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004331// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4332// it will not reuse a transceiver that has already been sending. After creating
4333// a new transceiver it tries to create an offer with two senders of the same
4334// track ids and it fails.
4335TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004336 ASSERT_TRUE(CreatePeerConnectionWrappers());
4337 ConnectFakeSignaling();
4338
deadbeef2f425aa2017-04-14 10:41:32 -07004339 // Add track using stream 1, do offer/answer.
4340 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4341 caller()->CreateLocalAudioTrack();
4342 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07004343 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07004344 caller()->CreateAndSetAndSignalOffer();
4345 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004346 {
4347 MediaExpectations media_expectations;
4348 media_expectations.CalleeExpectsSomeAudio(1);
4349 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4350 }
deadbeef2f425aa2017-04-14 10:41:32 -07004351 // Remove the sender, and create a new one with the new stream.
4352 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07004353 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07004354 caller()->CreateAndSetAndSignalOffer();
4355 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4356 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004357 {
4358 MediaExpectations media_expectations;
4359 media_expectations.CalleeExpectsSomeAudio();
4360 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4361 }
deadbeef2f425aa2017-04-14 10:41:32 -07004362}
4363
Seth Hampson2f0d7022018-02-20 11:54:42 -08004364TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004365 ASSERT_TRUE(CreatePeerConnectionWrappers());
4366 ConnectFakeSignaling();
4367
Karl Wiberg918f50c2018-07-05 11:40:33 +02004368 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Elad Alon99c3fe52017-10-13 16:29:40 +02004369 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4370 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4371 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004372 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4373 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004374
Steve Anton15324772018-01-16 10:26:49 -08004375 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004376 caller()->CreateAndSetAndSignalOffer();
4377 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4378}
4379
Steve Antonede9ca52017-10-16 13:04:27 -07004380// Test that if candidates are only signaled by applying full session
4381// descriptions (instead of using AddIceCandidate), the peers can connect to
4382// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004383TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004384 ASSERT_TRUE(CreatePeerConnectionWrappers());
4385 // Each side will signal the session descriptions but not candidates.
4386 ConnectFakeSignalingForSdpOnly();
4387
4388 // Add audio video track and exchange the initial offer/answer with media
4389 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004390 caller()->AddAudioVideoTracks();
4391 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004392 caller()->CreateAndSetAndSignalOffer();
4393
4394 // Wait for all candidates to be gathered on both the caller and callee.
4395 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4396 caller()->ice_gathering_state(), kDefaultTimeout);
4397 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4398 callee()->ice_gathering_state(), kDefaultTimeout);
4399
4400 // The candidates will now be included in the session description, so
4401 // signaling them will start the ICE connection.
4402 caller()->CreateAndSetAndSignalOffer();
4403 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4404
4405 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004406 MediaExpectations media_expectations;
4407 media_expectations.ExpectBidirectionalAudioAndVideo();
4408 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004409}
4410
henrika5f6bf242017-11-01 11:06:56 +01004411// Test that SetAudioPlayout can be used to disable audio playout from the
4412// start, then later enable it. This may be useful, for example, if the caller
4413// needs to play a local ringtone until some event occurs, after which it
4414// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004415TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004416 ASSERT_TRUE(CreatePeerConnectionWrappers());
4417 ConnectFakeSignaling();
4418
4419 // Set up audio-only call where audio playout is disabled on caller's side.
4420 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004421 caller()->AddAudioTrack();
4422 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004423 caller()->CreateAndSetAndSignalOffer();
4424 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4425
4426 // Pump messages for a second.
4427 WAIT(false, 1000);
4428 // Since audio playout is disabled, the caller shouldn't have received
4429 // anything (at the playout level, at least).
4430 EXPECT_EQ(0, caller()->audio_frames_received());
4431 // As a sanity check, make sure the callee (for which playout isn't disabled)
4432 // did still see frames on its audio level.
4433 ASSERT_GT(callee()->audio_frames_received(), 0);
4434
4435 // Enable playout again, and ensure audio starts flowing.
4436 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004437 MediaExpectations media_expectations;
4438 media_expectations.ExpectBidirectionalAudio();
4439 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004440}
4441
4442double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4443 auto report = pc->NewGetStats();
4444 auto track_stats_list =
4445 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4446 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4447 for (const auto* track_stats : track_stats_list) {
4448 if (track_stats->remote_source.is_defined() &&
4449 *track_stats->remote_source) {
4450 remote_track_stats = track_stats;
4451 break;
4452 }
4453 }
4454
4455 if (!remote_track_stats->total_audio_energy.is_defined()) {
4456 return 0.0;
4457 }
4458 return *remote_track_stats->total_audio_energy;
4459}
4460
4461// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4462// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004463TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004464 DisableAudioPlayoutStillGeneratesAudioStats) {
4465 ASSERT_TRUE(CreatePeerConnectionWrappers());
4466 ConnectFakeSignaling();
4467
4468 // Set up audio-only call where playout is disabled but audio-processing is
4469 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004470 caller()->AddAudioTrack();
4471 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004472 caller()->pc()->SetAudioPlayout(false);
4473
4474 caller()->CreateAndSetAndSignalOffer();
4475 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4476
4477 // Wait for the callee to receive audio stats.
4478 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4479}
4480
henrika4f167df2017-11-01 14:45:55 +01004481// Test that SetAudioRecording can be used to disable audio recording from the
4482// start, then later enable it. This may be useful, for example, if the caller
4483// wants to ensure that no audio resources are active before a certain state
4484// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004485TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01004486 ASSERT_TRUE(CreatePeerConnectionWrappers());
4487 ConnectFakeSignaling();
4488
4489 // Set up audio-only call where audio recording is disabled on caller's side.
4490 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08004491 caller()->AddAudioTrack();
4492 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01004493 caller()->CreateAndSetAndSignalOffer();
4494 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4495
4496 // Pump messages for a second.
4497 WAIT(false, 1000);
4498 // Since caller has disabled audio recording, the callee shouldn't have
4499 // received anything.
4500 EXPECT_EQ(0, callee()->audio_frames_received());
4501 // As a sanity check, make sure the caller did still see frames on its
4502 // audio level since audio recording is enabled on the calle side.
4503 ASSERT_GT(caller()->audio_frames_received(), 0);
4504
4505 // Enable audio recording again, and ensure audio starts flowing.
4506 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004507 MediaExpectations media_expectations;
4508 media_expectations.ExpectBidirectionalAudio();
4509 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01004510}
4511
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004512// Test that after closing PeerConnections, they stop sending any packets (ICE,
4513// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004514TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004515 // Set up audio/video/data, wait for some frames to be received.
4516 ASSERT_TRUE(CreatePeerConnectionWrappers());
4517 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004518 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004519#ifdef HAVE_SCTP
4520 caller()->CreateDataChannel();
4521#endif
4522 caller()->CreateAndSetAndSignalOffer();
4523 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004524 MediaExpectations media_expectations;
4525 media_expectations.CalleeExpectsSomeAudioAndVideo();
4526 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004527 // Close PeerConnections.
4528 caller()->pc()->Close();
4529 callee()->pc()->Close();
4530 // Pump messages for a second, and ensure no new packets end up sent.
4531 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4532 WAIT(false, 1000);
4533 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4534 EXPECT_EQ(sent_packets_a, sent_packets_b);
4535}
4536
Steve Anton7eca0932018-03-30 15:18:41 -07004537// Test that transport stats are generated by the RTCStatsCollector for a
4538// connection that only involves data channels. This is a regression test for
4539// crbug.com/826972.
4540#ifdef HAVE_SCTP
4541TEST_P(PeerConnectionIntegrationTest,
4542 TransportStatsReportedForDataChannelOnlyConnection) {
4543 ASSERT_TRUE(CreatePeerConnectionWrappers());
4544 ConnectFakeSignaling();
4545 caller()->CreateDataChannel();
4546
4547 caller()->CreateAndSetAndSignalOffer();
4548 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4549 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4550
4551 auto caller_report = caller()->NewGetStats();
4552 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4553 auto callee_report = callee()->NewGetStats();
4554 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4555}
4556#endif // HAVE_SCTP
4557
Qingsi Wang7685e862018-06-11 20:15:46 -07004558TEST_P(PeerConnectionIntegrationTest,
4559 IceEventsGeneratedAndLoggedInRtcEventLog) {
4560 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4561 ConnectFakeSignaling();
4562 PeerConnectionInterface::RTCOfferAnswerOptions options;
4563 options.offer_to_receive_audio = 1;
4564 caller()->SetOfferAnswerOptions(options);
4565 caller()->CreateAndSetAndSignalOffer();
4566 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4567 ASSERT_NE(nullptr, caller()->event_log_factory());
4568 ASSERT_NE(nullptr, callee()->event_log_factory());
4569 webrtc::FakeRtcEventLog* caller_event_log =
4570 static_cast<webrtc::FakeRtcEventLog*>(
4571 caller()->event_log_factory()->last_log_created());
4572 webrtc::FakeRtcEventLog* callee_event_log =
4573 static_cast<webrtc::FakeRtcEventLog*>(
4574 callee()->event_log_factory()->last_log_created());
4575 ASSERT_NE(nullptr, caller_event_log);
4576 ASSERT_NE(nullptr, callee_event_log);
4577 int caller_ice_config_count = caller_event_log->GetEventCount(
4578 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4579 int caller_ice_event_count = caller_event_log->GetEventCount(
4580 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4581 int callee_ice_config_count = callee_event_log->GetEventCount(
4582 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4583 int callee_ice_event_count = callee_event_log->GetEventCount(
4584 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4585 EXPECT_LT(0, caller_ice_config_count);
4586 EXPECT_LT(0, caller_ice_event_count);
4587 EXPECT_LT(0, callee_ice_config_count);
4588 EXPECT_LT(0, callee_ice_event_count);
4589}
4590
Seth Hampson2f0d7022018-02-20 11:54:42 -08004591INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4592 PeerConnectionIntegrationTest,
4593 Values(SdpSemantics::kPlanB,
4594 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08004595
Steve Anton74255ff2018-01-24 18:32:57 -08004596// Tests that verify interoperability between Plan B and Unified Plan
4597// PeerConnections.
4598class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004599 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08004600 public ::testing::WithParamInterface<
4601 std::tuple<SdpSemantics, SdpSemantics>> {
4602 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004603 // Setting the SdpSemantics for the base test to kDefault does not matter
4604 // because we specify not to use the test semantics when creating
4605 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08004606 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07004607 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08004608 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08004609 callee_semantics_(std::get<1>(GetParam())) {}
4610
4611 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07004612 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4613 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08004614 }
4615
4616 const SdpSemantics caller_semantics_;
4617 const SdpSemantics callee_semantics_;
4618};
4619
4620TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4621 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4622 ConnectFakeSignaling();
4623
4624 caller()->CreateAndSetAndSignalOffer();
4625 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4626}
4627
4628TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4629 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4630 ConnectFakeSignaling();
4631 auto audio_sender = caller()->AddAudioTrack();
4632
4633 caller()->CreateAndSetAndSignalOffer();
4634 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4635
4636 // Verify that one audio receiver has been created on the remote and that it
4637 // has the same track ID as the sending track.
4638 auto receivers = callee()->pc()->GetReceivers();
4639 ASSERT_EQ(1u, receivers.size());
4640 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4641 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4642
Seth Hampson2f0d7022018-02-20 11:54:42 -08004643 MediaExpectations media_expectations;
4644 media_expectations.CalleeExpectsSomeAudio();
4645 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004646}
4647
4648TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4649 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4650 ConnectFakeSignaling();
4651 auto video_sender = caller()->AddVideoTrack();
4652 auto audio_sender = caller()->AddAudioTrack();
4653
4654 caller()->CreateAndSetAndSignalOffer();
4655 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4656
4657 // Verify that one audio and one video receiver have been created on the
4658 // remote and that they have the same track IDs as the sending tracks.
4659 auto audio_receivers =
4660 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4661 ASSERT_EQ(1u, audio_receivers.size());
4662 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4663 auto video_receivers =
4664 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4665 ASSERT_EQ(1u, video_receivers.size());
4666 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4667
Seth Hampson2f0d7022018-02-20 11:54:42 -08004668 MediaExpectations media_expectations;
4669 media_expectations.CalleeExpectsSomeAudioAndVideo();
4670 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004671}
4672
4673TEST_P(PeerConnectionIntegrationInteropTest,
4674 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4675 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4676 ConnectFakeSignaling();
4677 caller()->AddAudioVideoTracks();
4678 callee()->AddAudioVideoTracks();
4679
4680 caller()->CreateAndSetAndSignalOffer();
4681 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4682
Seth Hampson2f0d7022018-02-20 11:54:42 -08004683 MediaExpectations media_expectations;
4684 media_expectations.ExpectBidirectionalAudioAndVideo();
4685 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004686}
4687
4688TEST_P(PeerConnectionIntegrationInteropTest,
4689 ReverseRolesOneAudioLocalToOneVideoRemote) {
4690 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4691 ConnectFakeSignaling();
4692 caller()->AddAudioTrack();
4693 callee()->AddVideoTrack();
4694
4695 caller()->CreateAndSetAndSignalOffer();
4696 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4697
4698 // Verify that only the audio track has been negotiated.
4699 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4700 // Might also check that the callee's NegotiationNeeded flag is set.
4701
4702 // Reverse roles.
4703 callee()->CreateAndSetAndSignalOffer();
4704 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4705
Seth Hampson2f0d7022018-02-20 11:54:42 -08004706 MediaExpectations media_expectations;
4707 media_expectations.CallerExpectsSomeVideo();
4708 media_expectations.CalleeExpectsSomeAudio();
4709 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004710}
4711
Steve Antonba42e992018-04-09 14:10:01 -07004712INSTANTIATE_TEST_CASE_P(
4713 PeerConnectionIntegrationTest,
4714 PeerConnectionIntegrationInteropTest,
4715 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4716 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4717
4718// Test that if the Unified Plan side offers two video tracks then the Plan B
4719// side will only see the first one and ignore the second.
4720TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07004721 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4722 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08004723 ConnectFakeSignaling();
4724 auto first_sender = caller()->AddVideoTrack();
4725 caller()->AddVideoTrack();
4726
4727 caller()->CreateAndSetAndSignalOffer();
4728 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4729
4730 // Verify that there is only one receiver and it corresponds to the first
4731 // added track.
4732 auto receivers = callee()->pc()->GetReceivers();
4733 ASSERT_EQ(1u, receivers.size());
4734 EXPECT_TRUE(receivers[0]->track()->enabled());
4735 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4736
Seth Hampson2f0d7022018-02-20 11:54:42 -08004737 MediaExpectations media_expectations;
4738 media_expectations.CalleeExpectsSomeVideo();
4739 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004740}
4741
deadbeef1dcb1642017-03-29 21:08:16 -07004742} // namespace
4743
4744#endif // if !defined(THREAD_SANITIZER)