blob: 525eba35b3176ad26bb8de4a4500cb550c615b63 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "api/test/fakeconstraints.h"
Anders Carlsson67537952018-05-03 11:28:29 +020032#include "api/video_codecs/builtin_video_decoder_factory.h"
33#include "api/video_codecs/builtin_video_encoder_factory.h"
34#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070035#include "call/call.h"
36#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
37#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "media/engine/fakewebrtcvideoengine.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070039#include "media/engine/webrtcmediaengine.h"
40#include "modules/audio_processing/include/audio_processing.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 Wang1a2cc0a2018-07-10 15:17:12 -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;
78using ::testing::Values;
deadbeef1dcb1642017-03-29 21:08:16 -070079using webrtc::DataBuffer;
80using webrtc::DataChannelInterface;
81using webrtc::DtmfSender;
82using webrtc::DtmfSenderInterface;
83using webrtc::DtmfSenderObserverInterface;
84using webrtc::FakeConstraints;
Steve Anton15324772018-01-16 10:26:49 -080085using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-29 21:08:16 -070086using webrtc::MediaConstraintsInterface;
87using webrtc::MediaStreamInterface;
88using webrtc::MediaStreamTrackInterface;
89using webrtc::MockCreateSessionDescriptionObserver;
90using webrtc::MockDataChannelObserver;
91using webrtc::MockSetSessionDescriptionObserver;
92using webrtc::MockStatsObserver;
93using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 10:03:10 -070094using webrtc::PeerConnection;
deadbeef1dcb1642017-03-29 21:08:16 -070095using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-24 18:32:57 -080096using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070097using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 10:03:10 -070098using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 10:26:49 -080099using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 15:18:41 -0700100using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-24 18:32:57 -0800101using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100102using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800103using webrtc::RtpSenderInterface;
104using webrtc::RtpTransceiverDirection;
105using webrtc::RtpTransceiverInit;
106using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-17 17:41:02 -0800107using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 10:27:41 -0800108using webrtc::SdpType;
deadbeef1dcb1642017-03-29 21:08:16 -0700109using webrtc::SessionDescriptionInterface;
110using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 10:26:49 -0800111using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-29 21:08:16 -0700112
113namespace {
114
115static const int kDefaultTimeout = 10000;
116static const int kMaxWaitForStatsMs = 3000;
117static const int kMaxWaitForActivationMs = 5000;
118static const int kMaxWaitForFramesMs = 10000;
119// Default number of audio/video frames to wait for before considering a test
120// successful.
121static const int kDefaultExpectedAudioFrameCount = 3;
122static const int kDefaultExpectedVideoFrameCount = 3;
123
deadbeef1dcb1642017-03-29 21:08:16 -0700124static const char kDataChannelLabel[] = "data_channel";
125
126// SRTP cipher name negotiated by the tests. This must be updated if the
127// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700128static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700129static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
130
Steve Antonede9ca52017-10-16 13:04:27 -0700131static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
132
deadbeef1dcb1642017-03-29 21:08:16 -0700133// Helper function for constructing offer/answer options to initiate an ICE
134// restart.
135PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
136 PeerConnectionInterface::RTCOfferAnswerOptions options;
137 options.ice_restart = true;
138 return options;
139}
140
deadbeefd8ad7882017-04-18 16:01:17 -0700141// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
142// attribute from received SDP, simulating a legacy endpoint.
143void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
144 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800145 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700146 }
147 desc->set_msid_supported(false);
148}
149
Seth Hampson5897a6e2018-04-03 11:16:33 -0700150// Removes all stream information besides the stream ids, simulating an
151// endpoint that only signals a=msid lines to convey stream_ids.
152void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
153 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700154 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700155 std::vector<std::string> stream_ids;
156 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700157 const StreamParams& first_stream =
158 content.media_description()->streams()[0];
159 track_id = first_stream.id;
160 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700161 }
162 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700163 StreamParams new_stream;
164 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700165 new_stream.set_stream_ids(stream_ids);
166 content.media_description()->AddStream(new_stream);
167 }
168}
169
zhihuangf8164932017-05-19 13:09:47 -0700170int FindFirstMediaStatsIndexByKind(
171 const std::string& kind,
172 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
173 media_stats_vec) {
174 for (size_t i = 0; i < media_stats_vec.size(); i++) {
175 if (media_stats_vec[i]->kind.ValueToString() == kind) {
176 return i;
177 }
178 }
179 return -1;
180}
181
deadbeef1dcb1642017-03-29 21:08:16 -0700182class SignalingMessageReceiver {
183 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800184 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700185 virtual void ReceiveIceMessage(const std::string& sdp_mid,
186 int sdp_mline_index,
187 const std::string& msg) = 0;
188
189 protected:
190 SignalingMessageReceiver() {}
191 virtual ~SignalingMessageReceiver() {}
192};
193
194class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
195 public:
196 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
197 : expected_media_type_(media_type) {}
198
199 void OnFirstPacketReceived(cricket::MediaType media_type) override {
200 ASSERT_EQ(expected_media_type_, media_type);
201 first_packet_received_ = true;
202 }
203
204 bool first_packet_received() const { return first_packet_received_; }
205
206 virtual ~MockRtpReceiverObserver() {}
207
208 private:
209 bool first_packet_received_ = false;
210 cricket::MediaType expected_media_type_;
211};
212
213// Helper class that wraps a peer connection, observes it, and can accept
214// signaling messages from another wrapper.
215//
216// Uses a fake network, fake A/V capture, and optionally fake
217// encoders/decoders, though they aren't used by default since they don't
218// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700219// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800220// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700221class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800222 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700223 public:
224 // Different factory methods for convenience.
225 // TODO(deadbeef): Could use the pattern of:
226 //
227 // PeerConnectionWrapper =
228 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
229 //
230 // To reduce some code duplication.
231 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
232 const std::string& debug_name,
233 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
234 rtc::Thread* network_thread,
235 rtc::Thread* worker_thread) {
236 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700237 webrtc::PeerConnectionDependencies dependencies(nullptr);
238 dependencies.cert_generator = std::move(cert_generator);
239 if (!client->Init(nullptr, nullptr, nullptr, std::move(dependencies),
Qingsi Wang7685e862018-06-11 20:15:46 -0700240 network_thread, worker_thread, nullptr)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700241 delete client;
242 return nullptr;
243 }
244 return client;
245 }
246
deadbeef2f425aa2017-04-14 10:41:32 -0700247 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
248 return peer_connection_factory_.get();
249 }
250
deadbeef1dcb1642017-03-29 21:08:16 -0700251 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
252
253 // If a signaling message receiver is set (via ConnectFakeSignaling), this
254 // will set the whole offer/answer exchange in motion. Just need to wait for
255 // the signaling state to reach "stable".
256 void CreateAndSetAndSignalOffer() {
257 auto offer = CreateOffer();
258 ASSERT_NE(nullptr, offer);
259 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
260 }
261
262 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
263 // when a remote offer is received (via fake signaling) and an answer is
264 // generated. By default, uses default options.
265 void SetOfferAnswerOptions(
266 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
267 offer_answer_options_ = options;
268 }
269
270 // Set a callback to be invoked when SDP is received via the fake signaling
271 // channel, which provides an opportunity to munge (modify) the SDP. This is
272 // used to test SDP being applied that a PeerConnection would normally not
273 // generate, but a non-JSEP endpoint might.
274 void SetReceivedSdpMunger(
275 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100276 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700277 }
278
deadbeefc964d0b2017-04-03 10:03:35 -0700279 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700280 // generated.
281 void SetGeneratedSdpMunger(
282 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100283 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700284 }
285
Seth Hampson2f0d7022018-02-20 11:54:42 -0800286 // Set a callback to be invoked when a remote offer is received via the fake
287 // signaling channel. This provides an opportunity to change the
288 // PeerConnection state before an answer is created and sent to the caller.
289 void SetRemoteOfferHandler(std::function<void()> handler) {
290 remote_offer_handler_ = std::move(handler);
291 }
292
Steve Antonede9ca52017-10-16 13:04:27 -0700293 // Every ICE connection state in order that has been seen by the observer.
294 std::vector<PeerConnectionInterface::IceConnectionState>
295 ice_connection_state_history() const {
296 return ice_connection_state_history_;
297 }
Steve Anton6f25b092017-10-23 09:39:20 -0700298 void clear_ice_connection_state_history() {
299 ice_connection_state_history_.clear();
300 }
Steve Antonede9ca52017-10-16 13:04:27 -0700301
302 // Every ICE gathering state in order that has been seen by the observer.
303 std::vector<PeerConnectionInterface::IceGatheringState>
304 ice_gathering_state_history() const {
305 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700306 }
307
Steve Anton15324772018-01-16 10:26:49 -0800308 void AddAudioVideoTracks() {
309 AddAudioTrack();
310 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700311 }
312
Steve Anton74255ff2018-01-24 18:32:57 -0800313 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
314 return AddTrack(CreateLocalAudioTrack());
315 }
deadbeef1dcb1642017-03-29 21:08:16 -0700316
Steve Anton74255ff2018-01-24 18:32:57 -0800317 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
318 return AddTrack(CreateLocalVideoTrack());
319 }
deadbeef1dcb1642017-03-29 21:08:16 -0700320
321 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200322 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700323 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200324 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700325 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200326 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700327 // TODO(perkj): Test audio source when it is implemented. Currently audio
328 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700329 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700330 source);
331 }
332
333 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Niels Möller5c7efe72018-05-11 10:34:46 +0200334 return CreateLocalVideoTrackInternal(
335 webrtc::FakePeriodicVideoSource::Config());
deadbeef1dcb1642017-03-29 21:08:16 -0700336 }
337
338 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200339 CreateLocalVideoTrackWithConfig(
340 webrtc::FakePeriodicVideoSource::Config config) {
341 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700342 }
343
344 rtc::scoped_refptr<webrtc::VideoTrackInterface>
345 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200346 webrtc::FakePeriodicVideoSource::Config config;
347 config.rotation = rotation;
348 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700349 }
350
Steve Anton74255ff2018-01-24 18:32:57 -0800351 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
352 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800353 const std::vector<std::string>& stream_ids = {}) {
354 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800355 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800356 return result.MoveValue();
357 }
358
359 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
360 cricket::MediaType media_type) {
361 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
362 for (auto receiver : pc()->GetReceivers()) {
363 if (receiver->media_type() == media_type) {
364 receivers.push_back(receiver);
365 }
366 }
367 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700368 }
369
Seth Hampson2f0d7022018-02-20 11:54:42 -0800370 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
371 cricket::MediaType media_type) {
372 for (auto transceiver : pc()->GetTransceivers()) {
373 if (transceiver->receiver()->media_type() == media_type) {
374 return transceiver;
375 }
376 }
377 return nullptr;
378 }
379
deadbeef1dcb1642017-03-29 21:08:16 -0700380 bool SignalingStateStable() {
381 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
382 }
383
384 void CreateDataChannel() { CreateDataChannel(nullptr); }
385
386 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700387 CreateDataChannel(kDataChannelLabel, init);
388 }
389
390 void CreateDataChannel(const std::string& label,
391 const webrtc::DataChannelInit* init) {
392 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700393 ASSERT_TRUE(data_channel_.get() != nullptr);
394 data_observer_.reset(new MockDataChannelObserver(data_channel_));
395 }
396
397 DataChannelInterface* data_channel() { return data_channel_; }
398 const MockDataChannelObserver* data_observer() const {
399 return data_observer_.get();
400 }
401
402 int audio_frames_received() const {
403 return fake_audio_capture_module_->frames_received();
404 }
405
406 // Takes minimum of video frames received for each track.
407 //
408 // Can be used like:
409 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
410 //
411 // To ensure that all video tracks received at least a certain number of
412 // frames.
413 int min_video_frames_received_per_track() const {
414 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200415 if (fake_video_renderers_.empty()) {
416 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700417 }
deadbeef1dcb1642017-03-29 21:08:16 -0700418
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200419 for (const auto& pair : fake_video_renderers_) {
420 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700421 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200422 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700423 }
424
425 // Returns a MockStatsObserver in a state after stats gathering finished,
426 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700427 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700428 webrtc::MediaStreamTrackInterface* track) {
429 rtc::scoped_refptr<MockStatsObserver> observer(
430 new rtc::RefCountedObject<MockStatsObserver>());
431 EXPECT_TRUE(peer_connection_->GetStats(
432 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
433 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
434 return observer;
435 }
436
437 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700438 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
439 return OldGetStatsForTrack(nullptr);
440 }
441
442 // Synchronously gets stats and returns them. If it times out, fails the test
443 // and returns null.
444 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
445 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
446 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
447 peer_connection_->GetStats(callback);
448 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
449 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700450 }
451
452 int rendered_width() {
453 EXPECT_FALSE(fake_video_renderers_.empty());
454 return fake_video_renderers_.empty()
455 ? 0
456 : fake_video_renderers_.begin()->second->width();
457 }
458
459 int rendered_height() {
460 EXPECT_FALSE(fake_video_renderers_.empty());
461 return fake_video_renderers_.empty()
462 ? 0
463 : fake_video_renderers_.begin()->second->height();
464 }
465
466 double rendered_aspect_ratio() {
467 if (rendered_height() == 0) {
468 return 0.0;
469 }
470 return static_cast<double>(rendered_width()) / rendered_height();
471 }
472
473 webrtc::VideoRotation rendered_rotation() {
474 EXPECT_FALSE(fake_video_renderers_.empty());
475 return fake_video_renderers_.empty()
476 ? webrtc::kVideoRotation_0
477 : fake_video_renderers_.begin()->second->rotation();
478 }
479
480 int local_rendered_width() {
481 return local_video_renderer_ ? local_video_renderer_->width() : 0;
482 }
483
484 int local_rendered_height() {
485 return local_video_renderer_ ? local_video_renderer_->height() : 0;
486 }
487
488 double local_rendered_aspect_ratio() {
489 if (local_rendered_height() == 0) {
490 return 0.0;
491 }
492 return static_cast<double>(local_rendered_width()) /
493 local_rendered_height();
494 }
495
496 size_t number_of_remote_streams() {
497 if (!pc()) {
498 return 0;
499 }
500 return pc()->remote_streams()->count();
501 }
502
503 StreamCollectionInterface* remote_streams() const {
504 if (!pc()) {
505 ADD_FAILURE();
506 return nullptr;
507 }
508 return pc()->remote_streams();
509 }
510
511 StreamCollectionInterface* local_streams() {
512 if (!pc()) {
513 ADD_FAILURE();
514 return nullptr;
515 }
516 return pc()->local_streams();
517 }
518
519 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
520 return pc()->signaling_state();
521 }
522
523 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
524 return pc()->ice_connection_state();
525 }
526
527 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
528 return pc()->ice_gathering_state();
529 }
530
531 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
532 // GetReceivers. They're updated automatically when a remote offer/answer
533 // from the fake signaling channel is applied, or when
534 // ResetRtpReceiverObservers below is called.
535 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
536 rtp_receiver_observers() {
537 return rtp_receiver_observers_;
538 }
539
540 void ResetRtpReceiverObservers() {
541 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100542 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
543 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700544 std::unique_ptr<MockRtpReceiverObserver> observer(
545 new MockRtpReceiverObserver(receiver->media_type()));
546 receiver->SetObserver(observer.get());
547 rtp_receiver_observers_.push_back(std::move(observer));
548 }
549 }
550
Steve Antonede9ca52017-10-16 13:04:27 -0700551 rtc::FakeNetworkManager* network() const {
552 return fake_network_manager_.get();
553 }
554 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
555
Qingsi Wang7685e862018-06-11 20:15:46 -0700556 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
557 return event_log_factory_;
558 }
559
deadbeef1dcb1642017-03-29 21:08:16 -0700560 private:
561 explicit PeerConnectionWrapper(const std::string& debug_name)
562 : debug_name_(debug_name) {}
563
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700564 bool Init(const MediaConstraintsInterface* constraints,
565 const PeerConnectionFactory::Options* options,
566 const PeerConnectionInterface::RTCConfiguration* config,
567 webrtc::PeerConnectionDependencies dependencies,
568 rtc::Thread* network_thread,
Qingsi Wang7685e862018-06-11 20:15:46 -0700569 rtc::Thread* worker_thread,
570 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700571 // There's an error in this test code if Init ends up being called twice.
572 RTC_DCHECK(!peer_connection_);
573 RTC_DCHECK(!peer_connection_factory_);
574
575 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700576 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700577
578 std::unique_ptr<cricket::PortAllocator> port_allocator(
579 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700580 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700581 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
582 if (!fake_audio_capture_module_) {
583 return false;
584 }
deadbeef1dcb1642017-03-29 21:08:16 -0700585 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700586
587 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
588 pc_factory_dependencies.network_thread = network_thread;
589 pc_factory_dependencies.worker_thread = worker_thread;
590 pc_factory_dependencies.signaling_thread = signaling_thread;
591 pc_factory_dependencies.media_engine =
592 cricket::WebRtcMediaEngineFactory::Create(
593 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
594 fake_audio_capture_module_),
595 webrtc::CreateBuiltinAudioEncoderFactory(),
596 webrtc::CreateBuiltinAudioDecoderFactory(),
597 webrtc::CreateBuiltinVideoEncoderFactory(),
598 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
599 webrtc::AudioProcessingBuilder().Create());
600 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
601 if (event_log_factory) {
602 event_log_factory_ = event_log_factory.get();
603 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
604 } else {
605 pc_factory_dependencies.event_log_factory =
606 webrtc::CreateRtcEventLogFactory();
607 }
608 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
609 std::move(pc_factory_dependencies));
610
deadbeef1dcb1642017-03-29 21:08:16 -0700611 if (!peer_connection_factory_) {
612 return false;
613 }
614 if (options) {
615 peer_connection_factory_->SetOptions(*options);
616 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800617 if (config) {
618 sdp_semantics_ = config->sdp_semantics;
619 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700620
621 dependencies.allocator = std::move(port_allocator);
deadbeef1dcb1642017-03-29 21:08:16 -0700622 peer_connection_ =
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700623 CreatePeerConnection(constraints, config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700624 return peer_connection_.get() != nullptr;
625 }
626
627 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700628 const MediaConstraintsInterface* constraints,
629 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700630 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700631 PeerConnectionInterface::RTCConfiguration modified_config;
632 // If |config| is null, this will result in a default configuration being
633 // used.
634 if (config) {
635 modified_config = *config;
636 }
637 // Disable resolution adaptation; we don't want it interfering with the
638 // test results.
639 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
640 // ratios and not specific resolutions, is this even necessary?
641 modified_config.set_cpu_adaptation(false);
642
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700643 // Use the legacy interface.
644 if (constraints != nullptr) {
645 return peer_connection_factory_->CreatePeerConnection(
646 modified_config, constraints, std::move(dependencies.allocator),
647 std::move(dependencies.cert_generator), this);
648 }
649 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700650 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700651 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700652 }
653
654 void set_signaling_message_receiver(
655 SignalingMessageReceiver* signaling_message_receiver) {
656 signaling_message_receiver_ = signaling_message_receiver;
657 }
658
659 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
660
Steve Antonede9ca52017-10-16 13:04:27 -0700661 void set_signal_ice_candidates(bool signal) {
662 signal_ice_candidates_ = signal;
663 }
664
deadbeef1dcb1642017-03-29 21:08:16 -0700665 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200666 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700667 // Set max frame rate to 10fps to reduce the risk of test flakiness.
668 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200669 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700670
Niels Möller5c7efe72018-05-11 10:34:46 +0200671 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200672 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
673 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700674 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200675 peer_connection_factory_->CreateVideoTrack(
676 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700677 if (!local_video_renderer_) {
678 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
679 }
680 return track;
681 }
682
683 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100684 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800685 std::unique_ptr<SessionDescriptionInterface> desc =
686 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700687 if (received_sdp_munger_) {
688 received_sdp_munger_(desc->description());
689 }
690
691 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
692 // Setting a remote description may have changed the number of receivers,
693 // so reset the receiver observers.
694 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800695 if (remote_offer_handler_) {
696 remote_offer_handler_();
697 }
deadbeef1dcb1642017-03-29 21:08:16 -0700698 auto answer = CreateAnswer();
699 ASSERT_NE(nullptr, answer);
700 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
701 }
702
703 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100704 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800705 std::unique_ptr<SessionDescriptionInterface> desc =
706 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700707 if (received_sdp_munger_) {
708 received_sdp_munger_(desc->description());
709 }
710
711 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
712 // Set the RtpReceiverObserver after receivers are created.
713 ResetRtpReceiverObservers();
714 }
715
716 // Returns null on failure.
717 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
718 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
719 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
720 pc()->CreateOffer(observer, offer_answer_options_);
721 return WaitForDescriptionFromObserver(observer);
722 }
723
724 // Returns null on failure.
725 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
726 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
727 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
728 pc()->CreateAnswer(observer, offer_answer_options_);
729 return WaitForDescriptionFromObserver(observer);
730 }
731
732 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100733 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700734 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
735 if (!observer->result()) {
736 return nullptr;
737 }
738 auto description = observer->MoveDescription();
739 if (generated_sdp_munger_) {
740 generated_sdp_munger_(description->description());
741 }
742 return description;
743 }
744
745 // Setting the local description and sending the SDP message over the fake
746 // signaling channel are combined into the same method because the SDP
747 // message needs to be sent as soon as SetLocalDescription finishes, without
748 // waiting for the observer to be called. This ensures that ICE candidates
749 // don't outrace the description.
750 bool SetLocalDescriptionAndSendSdpMessage(
751 std::unique_ptr<SessionDescriptionInterface> desc) {
752 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
753 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100754 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800755 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700756 std::string sdp;
757 EXPECT_TRUE(desc->ToString(&sdp));
758 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800759 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
760 RemoveUnusedVideoRenderers();
761 }
deadbeef1dcb1642017-03-29 21:08:16 -0700762 // As mentioned above, we need to send the message immediately after
763 // SetLocalDescription.
764 SendSdpMessage(type, sdp);
765 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
766 return true;
767 }
768
769 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
770 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
771 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100772 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700773 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800774 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
775 RemoveUnusedVideoRenderers();
776 }
deadbeef1dcb1642017-03-29 21:08:16 -0700777 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
778 return observer->result();
779 }
780
Seth Hampson2f0d7022018-02-20 11:54:42 -0800781 // This is a work around to remove unused fake_video_renderers from
782 // transceivers that have either stopped or are no longer receiving.
783 void RemoveUnusedVideoRenderers() {
784 auto transceivers = pc()->GetTransceivers();
785 for (auto& transceiver : transceivers) {
786 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
787 continue;
788 }
789 // Remove fake video renderers from any stopped transceivers.
790 if (transceiver->stopped()) {
791 auto it =
792 fake_video_renderers_.find(transceiver->receiver()->track()->id());
793 if (it != fake_video_renderers_.end()) {
794 fake_video_renderers_.erase(it);
795 }
796 }
797 // Remove fake video renderers from any transceivers that are no longer
798 // receiving.
799 if ((transceiver->current_direction() &&
800 !webrtc::RtpTransceiverDirectionHasRecv(
801 *transceiver->current_direction()))) {
802 auto it =
803 fake_video_renderers_.find(transceiver->receiver()->track()->id());
804 if (it != fake_video_renderers_.end()) {
805 fake_video_renderers_.erase(it);
806 }
807 }
808 }
809 }
810
deadbeef1dcb1642017-03-29 21:08:16 -0700811 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
812 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800813 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700814 if (signaling_delay_ms_ == 0) {
815 RelaySdpMessageIfReceiverExists(type, msg);
816 } else {
817 invoker_.AsyncInvokeDelayed<void>(
818 RTC_FROM_HERE, rtc::Thread::Current(),
819 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
820 this, type, msg),
821 signaling_delay_ms_);
822 }
823 }
824
Steve Antona3a92c22017-12-07 10:27:41 -0800825 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700826 if (signaling_message_receiver_) {
827 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
828 }
829 }
830
831 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
832 // default).
833 void SendIceMessage(const std::string& sdp_mid,
834 int sdp_mline_index,
835 const std::string& msg) {
836 if (signaling_delay_ms_ == 0) {
837 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
838 } else {
839 invoker_.AsyncInvokeDelayed<void>(
840 RTC_FROM_HERE, rtc::Thread::Current(),
841 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
842 this, sdp_mid, sdp_mline_index, msg),
843 signaling_delay_ms_);
844 }
845 }
846
847 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
848 int sdp_mline_index,
849 const std::string& msg) {
850 if (signaling_message_receiver_) {
851 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
852 msg);
853 }
854 }
855
856 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800857 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
858 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700859 HandleIncomingOffer(msg);
860 } else {
861 HandleIncomingAnswer(msg);
862 }
863 }
864
865 void ReceiveIceMessage(const std::string& sdp_mid,
866 int sdp_mline_index,
867 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100868 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700869 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
870 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
871 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
872 }
873
874 // PeerConnectionObserver callbacks.
875 void OnSignalingChange(
876 webrtc::PeerConnectionInterface::SignalingState new_state) override {
877 EXPECT_EQ(pc()->signaling_state(), new_state);
878 }
Steve Anton15324772018-01-16 10:26:49 -0800879 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
880 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
881 streams) override {
882 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
883 rtc::scoped_refptr<VideoTrackInterface> video_track(
884 static_cast<VideoTrackInterface*>(receiver->track().get()));
885 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700886 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800887 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 11:40:33 +0200888 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700889 }
890 }
Steve Anton15324772018-01-16 10:26:49 -0800891 void OnRemoveTrack(
892 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
893 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
894 auto it = fake_video_renderers_.find(receiver->track()->id());
895 RTC_DCHECK(it != fake_video_renderers_.end());
896 fake_video_renderers_.erase(it);
897 }
898 }
deadbeef1dcb1642017-03-29 21:08:16 -0700899 void OnRenegotiationNeeded() override {}
900 void OnIceConnectionChange(
901 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
902 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700903 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700904 }
905 void OnIceGatheringChange(
906 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700907 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700908 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700909 }
910 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100911 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700912
913 std::string ice_sdp;
914 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700915 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700916 // Remote party may be deleted.
917 return;
918 }
919 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
920 }
921 void OnDataChannel(
922 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100923 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700924 data_channel_ = data_channel;
925 data_observer_.reset(new MockDataChannelObserver(data_channel));
926 }
927
deadbeef1dcb1642017-03-29 21:08:16 -0700928 std::string debug_name_;
929
930 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
931
932 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
933 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
934 peer_connection_factory_;
935
Steve Antonede9ca52017-10-16 13:04:27 -0700936 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700937 // Needed to keep track of number of frames sent.
938 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
939 // Needed to keep track of number of frames received.
940 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
941 fake_video_renderers_;
942 // Needed to ensure frames aren't received for removed tracks.
943 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
944 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -0700945
946 // For remote peer communication.
947 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
948 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700949 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-29 21:08:16 -0700950
Niels Möller5c7efe72018-05-11 10:34:46 +0200951 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -0700952 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +0200953 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
954 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -0700955 // |local_video_renderer_| attached to the first created local video track.
956 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
957
Seth Hampson2f0d7022018-02-20 11:54:42 -0800958 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -0700959 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
960 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
961 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800962 std::function<void()> remote_offer_handler_;
deadbeef1dcb1642017-03-29 21:08:16 -0700963
964 rtc::scoped_refptr<DataChannelInterface> data_channel_;
965 std::unique_ptr<MockDataChannelObserver> data_observer_;
966
967 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
968
Steve Antonede9ca52017-10-16 13:04:27 -0700969 std::vector<PeerConnectionInterface::IceConnectionState>
970 ice_connection_state_history_;
971 std::vector<PeerConnectionInterface::IceGatheringState>
972 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700973
Qingsi Wang7685e862018-06-11 20:15:46 -0700974 webrtc::FakeRtcEventLogFactory* event_log_factory_;
975
deadbeef1dcb1642017-03-29 21:08:16 -0700976 rtc::AsyncInvoker invoker_;
977
Seth Hampson2f0d7022018-02-20 11:54:42 -0800978 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -0700979};
980
Elad Alon99c3fe52017-10-13 16:29:40 +0200981class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
982 public:
983 virtual ~MockRtcEventLogOutput() = default;
984 MOCK_CONST_METHOD0(IsActive, bool());
985 MOCK_METHOD1(Write, bool(const std::string&));
986};
987
Seth Hampson2f0d7022018-02-20 11:54:42 -0800988// This helper object is used for both specifying how many audio/video frames
989// are expected to be received for a caller/callee. It provides helper functions
990// to specify these expectations. The object initially starts in a state of no
991// expectations.
992class MediaExpectations {
993 public:
994 enum ExpectFrames {
995 kExpectSomeFrames,
996 kExpectNoFrames,
997 kNoExpectation,
998 };
999
1000 void ExpectBidirectionalAudioAndVideo() {
1001 ExpectBidirectionalAudio();
1002 ExpectBidirectionalVideo();
1003 }
1004
1005 void ExpectBidirectionalAudio() {
1006 CallerExpectsSomeAudio();
1007 CalleeExpectsSomeAudio();
1008 }
1009
1010 void ExpectNoAudio() {
1011 CallerExpectsNoAudio();
1012 CalleeExpectsNoAudio();
1013 }
1014
1015 void ExpectBidirectionalVideo() {
1016 CallerExpectsSomeVideo();
1017 CalleeExpectsSomeVideo();
1018 }
1019
1020 void ExpectNoVideo() {
1021 CallerExpectsNoVideo();
1022 CalleeExpectsNoVideo();
1023 }
1024
1025 void CallerExpectsSomeAudioAndVideo() {
1026 CallerExpectsSomeAudio();
1027 CallerExpectsSomeVideo();
1028 }
1029
1030 void CalleeExpectsSomeAudioAndVideo() {
1031 CalleeExpectsSomeAudio();
1032 CalleeExpectsSomeVideo();
1033 }
1034
1035 // Caller's audio functions.
1036 void CallerExpectsSomeAudio(
1037 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1038 caller_audio_expectation_ = kExpectSomeFrames;
1039 caller_audio_frames_expected_ = expected_audio_frames;
1040 }
1041
1042 void CallerExpectsNoAudio() {
1043 caller_audio_expectation_ = kExpectNoFrames;
1044 caller_audio_frames_expected_ = 0;
1045 }
1046
1047 // Caller's video functions.
1048 void CallerExpectsSomeVideo(
1049 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1050 caller_video_expectation_ = kExpectSomeFrames;
1051 caller_video_frames_expected_ = expected_video_frames;
1052 }
1053
1054 void CallerExpectsNoVideo() {
1055 caller_video_expectation_ = kExpectNoFrames;
1056 caller_video_frames_expected_ = 0;
1057 }
1058
1059 // Callee's audio functions.
1060 void CalleeExpectsSomeAudio(
1061 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1062 callee_audio_expectation_ = kExpectSomeFrames;
1063 callee_audio_frames_expected_ = expected_audio_frames;
1064 }
1065
1066 void CalleeExpectsNoAudio() {
1067 callee_audio_expectation_ = kExpectNoFrames;
1068 callee_audio_frames_expected_ = 0;
1069 }
1070
1071 // Callee's video functions.
1072 void CalleeExpectsSomeVideo(
1073 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1074 callee_video_expectation_ = kExpectSomeFrames;
1075 callee_video_frames_expected_ = expected_video_frames;
1076 }
1077
1078 void CalleeExpectsNoVideo() {
1079 callee_video_expectation_ = kExpectNoFrames;
1080 callee_video_frames_expected_ = 0;
1081 }
1082
1083 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1084 ExpectFrames caller_video_expectation_ = kNoExpectation;
1085 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1086 ExpectFrames callee_video_expectation_ = kNoExpectation;
1087 int caller_audio_frames_expected_ = 0;
1088 int caller_video_frames_expected_ = 0;
1089 int callee_audio_frames_expected_ = 0;
1090 int callee_video_frames_expected_ = 0;
1091};
1092
deadbeef1dcb1642017-03-29 21:08:16 -07001093// Tests two PeerConnections connecting to each other end-to-end, using a
1094// virtual network, fake A/V capture and fake encoder/decoders. The
1095// PeerConnections share the threads/socket servers, but use separate versions
1096// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001097class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001098 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001099 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1100 : sdp_semantics_(sdp_semantics),
1101 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001102 fss_(new rtc::FirewallSocketServer(ss_.get())),
1103 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-29 21:08:16 -07001104 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001105 network_thread_->SetName("PCNetworkThread", this);
1106 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001107 RTC_CHECK(network_thread_->Start());
1108 RTC_CHECK(worker_thread_->Start());
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07001109 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001110 }
1111
Seth Hampson2f0d7022018-02-20 11:54:42 -08001112 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 07:41:32 -07001113 // The PeerConnections should deleted before the TurnCustomizers.
1114 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1115 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1116 // that the TurnCustomizer outlives the life of the PeerConnection or else
1117 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001118 if (caller_) {
1119 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001120 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001121 }
1122 if (callee_) {
1123 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001124 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001125 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001126
1127 // If turn servers were created for the test they need to be destroyed on
1128 // the network thread.
1129 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1130 turn_servers_.clear();
1131 turn_customizers_.clear();
1132 });
deadbeef1dcb1642017-03-29 21:08:16 -07001133 }
1134
1135 bool SignalingStateStable() {
1136 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1137 }
1138
deadbeef71452802017-05-07 17:21:01 -07001139 bool DtlsConnected() {
1140 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1141 // are connected. This is an important distinction. Once we have separate
1142 // ICE and DTLS state, this check needs to use the DTLS state.
1143 return (callee()->ice_connection_state() ==
1144 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1145 callee()->ice_connection_state() ==
1146 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1147 (caller()->ice_connection_state() ==
1148 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1149 caller()->ice_connection_state() ==
1150 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1151 }
1152
Qingsi Wang7685e862018-06-11 20:15:46 -07001153 // When |event_log_factory| is null, the default implementation of the event
1154 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001155 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1156 const std::string& debug_name,
1157 const MediaConstraintsInterface* constraints,
1158 const PeerConnectionFactory::Options* options,
1159 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001160 webrtc::PeerConnectionDependencies dependencies,
1161 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001162 RTCConfiguration modified_config;
1163 if (config) {
1164 modified_config = *config;
1165 }
Steve Anton3acffc32018-04-12 17:21:03 -07001166 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001167 if (!dependencies.cert_generator) {
1168 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 11:40:33 +02001169 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001170 }
1171 std::unique_ptr<PeerConnectionWrapper> client(
1172 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001173
Seth Hampson2f0d7022018-02-20 11:54:42 -08001174 if (!client->Init(constraints, options, &modified_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001175 std::move(dependencies), network_thread_.get(),
Qingsi Wang7685e862018-06-11 20:15:46 -07001176 worker_thread_.get(), std::move(event_log_factory))) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001177 return nullptr;
1178 }
1179 return client;
1180 }
1181
Qingsi Wang7685e862018-06-11 20:15:46 -07001182 std::unique_ptr<PeerConnectionWrapper>
1183 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1184 const std::string& debug_name,
1185 const MediaConstraintsInterface* constraints,
1186 const PeerConnectionFactory::Options* options,
1187 const RTCConfiguration* config,
1188 webrtc::PeerConnectionDependencies dependencies) {
1189 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1190 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
1191 return CreatePeerConnectionWrapper(debug_name, constraints, options, config,
1192 std::move(dependencies),
1193 std::move(event_log_factory));
1194 }
1195
deadbeef1dcb1642017-03-29 21:08:16 -07001196 bool CreatePeerConnectionWrappers() {
1197 return CreatePeerConnectionWrappersWithConfig(
1198 PeerConnectionInterface::RTCConfiguration(),
1199 PeerConnectionInterface::RTCConfiguration());
1200 }
1201
Steve Anton3acffc32018-04-12 17:21:03 -07001202 bool CreatePeerConnectionWrappersWithSdpSemantics(
1203 SdpSemantics caller_semantics,
1204 SdpSemantics callee_semantics) {
1205 // Can't specify the sdp_semantics in the passed-in configuration since it
1206 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1207 // stored in sdp_semantics_. So get around this by modifying the instance
1208 // variable before calling CreatePeerConnectionWrapper for the caller and
1209 // callee PeerConnections.
1210 SdpSemantics original_semantics = sdp_semantics_;
1211 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001212 caller_ = CreatePeerConnectionWrapper(
1213 "Caller", nullptr, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001214 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001215 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001216 callee_ = CreatePeerConnectionWrapper(
1217 "Callee", nullptr, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001218 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001219 sdp_semantics_ = original_semantics;
1220 return caller_ && callee_;
1221 }
1222
deadbeef1dcb1642017-03-29 21:08:16 -07001223 bool CreatePeerConnectionWrappersWithConstraints(
1224 MediaConstraintsInterface* caller_constraints,
1225 MediaConstraintsInterface* callee_constraints) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001226 caller_ = CreatePeerConnectionWrapper(
1227 "Caller", caller_constraints, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001228 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001229 callee_ = CreatePeerConnectionWrapper(
1230 "Callee", callee_constraints, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001231 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001232
deadbeef1dcb1642017-03-29 21:08:16 -07001233 return caller_ && callee_;
1234 }
1235
1236 bool CreatePeerConnectionWrappersWithConfig(
1237 const PeerConnectionInterface::RTCConfiguration& caller_config,
1238 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001239 caller_ = CreatePeerConnectionWrapper(
1240 "Caller", nullptr, nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001241 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001242 callee_ = CreatePeerConnectionWrapper(
1243 "Callee", nullptr, nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001244 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001245 return caller_ && callee_;
1246 }
1247
1248 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1249 const PeerConnectionInterface::RTCConfiguration& caller_config,
1250 webrtc::PeerConnectionDependencies caller_dependencies,
1251 const PeerConnectionInterface::RTCConfiguration& callee_config,
1252 webrtc::PeerConnectionDependencies callee_dependencies) {
1253 caller_ =
1254 CreatePeerConnectionWrapper("Caller", nullptr, nullptr, &caller_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001255 std::move(caller_dependencies), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001256 callee_ =
1257 CreatePeerConnectionWrapper("Callee", nullptr, nullptr, &callee_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001258 std::move(callee_dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001259 return caller_ && callee_;
1260 }
1261
1262 bool CreatePeerConnectionWrappersWithOptions(
1263 const PeerConnectionFactory::Options& caller_options,
1264 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001265 caller_ = CreatePeerConnectionWrapper(
1266 "Caller", nullptr, &caller_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001267 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001268 callee_ = CreatePeerConnectionWrapper(
1269 "Callee", nullptr, &callee_options, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001270 webrtc::PeerConnectionDependencies(nullptr), nullptr);
1271 return caller_ && callee_;
1272 }
1273
1274 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1275 PeerConnectionInterface::RTCConfiguration default_config;
1276 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
1277 "Caller", nullptr, nullptr, &default_config,
1278 webrtc::PeerConnectionDependencies(nullptr));
1279 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
1280 "Callee", nullptr, nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001281 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001282 return caller_ && callee_;
1283 }
1284
Seth Hampson2f0d7022018-02-20 11:54:42 -08001285 std::unique_ptr<PeerConnectionWrapper>
1286 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001287 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1288 new FakeRTCCertificateGenerator());
1289 cert_generator->use_alternate_key();
1290
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001291 webrtc::PeerConnectionDependencies dependencies(nullptr);
1292 dependencies.cert_generator = std::move(cert_generator);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001293 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr, nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -07001294 std::move(dependencies), nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001295 }
1296
Seth Hampsonaed71642018-06-11 07:41:32 -07001297 cricket::TestTurnServer* CreateTurnServer(
1298 rtc::SocketAddress internal_address,
1299 rtc::SocketAddress external_address,
1300 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1301 const std::string& common_name = "test turn server") {
1302 rtc::Thread* thread = network_thread();
1303 std::unique_ptr<cricket::TestTurnServer> turn_server =
1304 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1305 RTC_FROM_HERE,
1306 [thread, internal_address, external_address, type, common_name] {
Karl Wiberg918f50c2018-07-05 11:40:33 +02001307 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001308 thread, internal_address, external_address, type,
1309 /*ignore_bad_certs=*/true, common_name);
1310 });
1311 turn_servers_.push_back(std::move(turn_server));
1312 // Interactions with the turn server should be done on the network thread.
1313 return turn_servers_.back().get();
1314 }
1315
1316 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1317 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1318 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1319 RTC_FROM_HERE,
Karl Wiberg918f50c2018-07-05 11:40:33 +02001320 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001321 turn_customizers_.push_back(std::move(turn_customizer));
1322 // Interactions with the turn customizer should be done on the network
1323 // thread.
1324 return turn_customizers_.back().get();
1325 }
1326
1327 // Checks that the function counters for a TestTurnCustomizer are greater than
1328 // 0.
1329 void ExpectTurnCustomizerCountersIncremented(
1330 cricket::TestTurnCustomizer* turn_customizer) {
1331 unsigned int allow_channel_data_counter =
1332 network_thread()->Invoke<unsigned int>(
1333 RTC_FROM_HERE, [turn_customizer] {
1334 return turn_customizer->allow_channel_data_cnt_;
1335 });
1336 EXPECT_GT(allow_channel_data_counter, 0u);
1337 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1338 RTC_FROM_HERE,
1339 [turn_customizer] { return turn_customizer->modify_cnt_; });
1340 EXPECT_GT(modify_counter, 0u);
1341 }
1342
deadbeef1dcb1642017-03-29 21:08:16 -07001343 // Once called, SDP blobs and ICE candidates will be automatically signaled
1344 // between PeerConnections.
1345 void ConnectFakeSignaling() {
1346 caller_->set_signaling_message_receiver(callee_.get());
1347 callee_->set_signaling_message_receiver(caller_.get());
1348 }
1349
Steve Antonede9ca52017-10-16 13:04:27 -07001350 // Once called, SDP blobs will be automatically signaled between
1351 // PeerConnections. Note that ICE candidates will not be signaled unless they
1352 // are in the exchanged SDP blobs.
1353 void ConnectFakeSignalingForSdpOnly() {
1354 ConnectFakeSignaling();
1355 SetSignalIceCandidates(false);
1356 }
1357
deadbeef1dcb1642017-03-29 21:08:16 -07001358 void SetSignalingDelayMs(int delay_ms) {
1359 caller_->set_signaling_delay_ms(delay_ms);
1360 callee_->set_signaling_delay_ms(delay_ms);
1361 }
1362
Steve Antonede9ca52017-10-16 13:04:27 -07001363 void SetSignalIceCandidates(bool signal) {
1364 caller_->set_signal_ice_candidates(signal);
1365 callee_->set_signal_ice_candidates(signal);
1366 }
1367
deadbeef1dcb1642017-03-29 21:08:16 -07001368 // Messages may get lost on the unreliable DataChannel, so we send multiple
1369 // times to avoid test flakiness.
1370 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1371 const std::string& data,
1372 int retries) {
1373 for (int i = 0; i < retries; ++i) {
1374 dc->Send(DataBuffer(data));
1375 }
1376 }
1377
1378 rtc::Thread* network_thread() { return network_thread_.get(); }
1379
1380 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1381
1382 PeerConnectionWrapper* caller() { return caller_.get(); }
1383
1384 // Set the |caller_| to the |wrapper| passed in and return the
1385 // original |caller_|.
1386 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1387 PeerConnectionWrapper* wrapper) {
1388 PeerConnectionWrapper* old = caller_.release();
1389 caller_.reset(wrapper);
1390 return old;
1391 }
1392
1393 PeerConnectionWrapper* callee() { return callee_.get(); }
1394
1395 // Set the |callee_| to the |wrapper| passed in and return the
1396 // original |callee_|.
1397 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1398 PeerConnectionWrapper* wrapper) {
1399 PeerConnectionWrapper* old = callee_.release();
1400 callee_.reset(wrapper);
1401 return old;
1402 }
1403
Steve Antonede9ca52017-10-16 13:04:27 -07001404 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1405
Seth Hampson2f0d7022018-02-20 11:54:42 -08001406 // Expects the provided number of new frames to be received within
1407 // kMaxWaitForFramesMs. The new expected frames are specified in
1408 // |media_expectations|. Returns false if any of the expectations were
1409 // not met.
1410 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1411 // First initialize the expected frame counts based upon the current
1412 // frame count.
1413 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1414 if (media_expectations.caller_audio_expectation_ ==
1415 MediaExpectations::kExpectSomeFrames) {
1416 total_caller_audio_frames_expected +=
1417 media_expectations.caller_audio_frames_expected_;
1418 }
1419 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001420 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001421 if (media_expectations.caller_video_expectation_ ==
1422 MediaExpectations::kExpectSomeFrames) {
1423 total_caller_video_frames_expected +=
1424 media_expectations.caller_video_frames_expected_;
1425 }
1426 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1427 if (media_expectations.callee_audio_expectation_ ==
1428 MediaExpectations::kExpectSomeFrames) {
1429 total_callee_audio_frames_expected +=
1430 media_expectations.callee_audio_frames_expected_;
1431 }
1432 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001433 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001434 if (media_expectations.callee_video_expectation_ ==
1435 MediaExpectations::kExpectSomeFrames) {
1436 total_callee_video_frames_expected +=
1437 media_expectations.callee_video_frames_expected_;
1438 }
deadbeef1dcb1642017-03-29 21:08:16 -07001439
Seth Hampson2f0d7022018-02-20 11:54:42 -08001440 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001441 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001442 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001443 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001444 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001445 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001446 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001447 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001448 total_callee_video_frames_expected,
1449 kMaxWaitForFramesMs);
1450 bool expectations_correct =
1451 caller()->audio_frames_received() >=
1452 total_caller_audio_frames_expected &&
1453 caller()->min_video_frames_received_per_track() >=
1454 total_caller_video_frames_expected &&
1455 callee()->audio_frames_received() >=
1456 total_callee_audio_frames_expected &&
1457 callee()->min_video_frames_received_per_track() >=
1458 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001459
Seth Hampson2f0d7022018-02-20 11:54:42 -08001460 // After the combined wait, print out a more detailed message upon
1461 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001462 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001463 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001464 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001465 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001466 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001467 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001468 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001469 total_callee_video_frames_expected);
1470
1471 // We want to make sure nothing unexpected was received.
1472 if (media_expectations.caller_audio_expectation_ ==
1473 MediaExpectations::kExpectNoFrames) {
1474 EXPECT_EQ(caller()->audio_frames_received(),
1475 total_caller_audio_frames_expected);
1476 if (caller()->audio_frames_received() !=
1477 total_caller_audio_frames_expected) {
1478 expectations_correct = false;
1479 }
1480 }
1481 if (media_expectations.caller_video_expectation_ ==
1482 MediaExpectations::kExpectNoFrames) {
1483 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1484 total_caller_video_frames_expected);
1485 if (caller()->min_video_frames_received_per_track() !=
1486 total_caller_video_frames_expected) {
1487 expectations_correct = false;
1488 }
1489 }
1490 if (media_expectations.callee_audio_expectation_ ==
1491 MediaExpectations::kExpectNoFrames) {
1492 EXPECT_EQ(callee()->audio_frames_received(),
1493 total_callee_audio_frames_expected);
1494 if (callee()->audio_frames_received() !=
1495 total_callee_audio_frames_expected) {
1496 expectations_correct = false;
1497 }
1498 }
1499 if (media_expectations.callee_video_expectation_ ==
1500 MediaExpectations::kExpectNoFrames) {
1501 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1502 total_callee_video_frames_expected);
1503 if (callee()->min_video_frames_received_per_track() !=
1504 total_callee_video_frames_expected) {
1505 expectations_correct = false;
1506 }
1507 }
1508 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001509 }
1510
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001511 void TestNegotiatedCipherSuite(
1512 const PeerConnectionFactory::Options& caller_options,
1513 const PeerConnectionFactory::Options& callee_options,
1514 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001515 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1516 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001517 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001518 caller()->AddAudioVideoTracks();
1519 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001520 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07001521 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001522 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001523 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07001524 // TODO(bugs.webrtc.org/9456): Fix it.
1525 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1526 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1527 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001528 }
1529
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001530 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1531 bool remote_gcm_enabled,
1532 int expected_cipher_suite) {
1533 PeerConnectionFactory::Options caller_options;
1534 caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
1535 PeerConnectionFactory::Options callee_options;
1536 callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
1537 TestNegotiatedCipherSuite(caller_options, callee_options,
1538 expected_cipher_suite);
1539 }
1540
Seth Hampson2f0d7022018-02-20 11:54:42 -08001541 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001542 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001543
deadbeef1dcb1642017-03-29 21:08:16 -07001544 private:
1545 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001546 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001547 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001548 // |network_thread_| and |worker_thread_| are used by both
1549 // |caller_| and |callee_| so they must be destroyed
1550 // later.
1551 std::unique_ptr<rtc::Thread> network_thread_;
1552 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001553 // The turn servers and turn customizers should be accessed & deleted on the
1554 // network thread to avoid a race with the socket read/write that occurs
1555 // on the network thread.
1556 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1557 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-29 21:08:16 -07001558 std::unique_ptr<PeerConnectionWrapper> caller_;
1559 std::unique_ptr<PeerConnectionWrapper> callee_;
1560};
1561
Seth Hampson2f0d7022018-02-20 11:54:42 -08001562class PeerConnectionIntegrationTest
1563 : public PeerConnectionIntegrationBaseTest,
1564 public ::testing::WithParamInterface<SdpSemantics> {
1565 protected:
1566 PeerConnectionIntegrationTest()
1567 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1568};
1569
1570class PeerConnectionIntegrationTestPlanB
1571 : public PeerConnectionIntegrationBaseTest {
1572 protected:
1573 PeerConnectionIntegrationTestPlanB()
1574 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1575};
1576
1577class PeerConnectionIntegrationTestUnifiedPlan
1578 : public PeerConnectionIntegrationBaseTest {
1579 protected:
1580 PeerConnectionIntegrationTestUnifiedPlan()
1581 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1582};
1583
deadbeef1dcb1642017-03-29 21:08:16 -07001584// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1585// includes testing that the callback is invoked if an observer is connected
1586// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001587TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001588 RtpReceiverObserverOnFirstPacketReceived) {
1589 ASSERT_TRUE(CreatePeerConnectionWrappers());
1590 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001591 caller()->AddAudioVideoTracks();
1592 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001593 // Start offer/answer exchange and wait for it to complete.
1594 caller()->CreateAndSetAndSignalOffer();
1595 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1596 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001597 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1598 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001599 // Wait for all "first packet received" callbacks to be fired.
1600 EXPECT_TRUE_WAIT(
1601 std::all_of(caller()->rtp_receiver_observers().begin(),
1602 caller()->rtp_receiver_observers().end(),
1603 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1604 return o->first_packet_received();
1605 }),
1606 kMaxWaitForFramesMs);
1607 EXPECT_TRUE_WAIT(
1608 std::all_of(callee()->rtp_receiver_observers().begin(),
1609 callee()->rtp_receiver_observers().end(),
1610 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1611 return o->first_packet_received();
1612 }),
1613 kMaxWaitForFramesMs);
1614 // If new observers are set after the first packet was already received, the
1615 // callback should still be invoked.
1616 caller()->ResetRtpReceiverObservers();
1617 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001618 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1619 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001620 EXPECT_TRUE(
1621 std::all_of(caller()->rtp_receiver_observers().begin(),
1622 caller()->rtp_receiver_observers().end(),
1623 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1624 return o->first_packet_received();
1625 }));
1626 EXPECT_TRUE(
1627 std::all_of(callee()->rtp_receiver_observers().begin(),
1628 callee()->rtp_receiver_observers().end(),
1629 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1630 return o->first_packet_received();
1631 }));
1632}
1633
1634class DummyDtmfObserver : public DtmfSenderObserverInterface {
1635 public:
1636 DummyDtmfObserver() : completed_(false) {}
1637
1638 // Implements DtmfSenderObserverInterface.
1639 void OnToneChange(const std::string& tone) override {
1640 tones_.push_back(tone);
1641 if (tone.empty()) {
1642 completed_ = true;
1643 }
1644 }
1645
1646 const std::vector<std::string>& tones() const { return tones_; }
1647 bool completed() const { return completed_; }
1648
1649 private:
1650 bool completed_;
1651 std::vector<std::string> tones_;
1652};
1653
1654// Assumes |sender| already has an audio track added and the offer/answer
1655// exchange is done.
1656void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1657 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001658 // We should be able to get a DTMF sender from the local sender.
1659 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1660 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1661 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001662 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001663 dtmf_sender->RegisterObserver(&observer);
1664
1665 // Test the DtmfSender object just created.
1666 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1667 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1668
1669 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1670 std::vector<std::string> tones = {"1", "a", ""};
1671 EXPECT_EQ(tones, observer.tones());
1672 dtmf_sender->UnregisterObserver();
1673 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1674}
1675
1676// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1677// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001678TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001679 ASSERT_TRUE(CreatePeerConnectionWrappers());
1680 ConnectFakeSignaling();
1681 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001682 caller()->AddAudioTrack();
1683 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001684 caller()->CreateAndSetAndSignalOffer();
1685 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001686 // DTLS must finish before the DTMF sender can be used reliably.
1687 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001688 TestDtmfFromSenderToReceiver(caller(), callee());
1689 TestDtmfFromSenderToReceiver(callee(), caller());
1690}
1691
1692// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1693// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001694TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001695 ASSERT_TRUE(CreatePeerConnectionWrappers());
1696 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001697
deadbeef1dcb1642017-03-29 21:08:16 -07001698 // Do normal offer/answer and wait for some frames to be received in each
1699 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001700 caller()->AddAudioVideoTracks();
1701 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001702 caller()->CreateAndSetAndSignalOffer();
1703 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001704 MediaExpectations media_expectations;
1705 media_expectations.ExpectBidirectionalAudioAndVideo();
1706 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07001707 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1708 webrtc::kEnumCounterKeyProtocolDtls));
1709 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1710 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001711}
1712
1713// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001714TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001715 PeerConnectionInterface::RTCConfiguration sdes_config;
1716 sdes_config.enable_dtls_srtp.emplace(false);
1717 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1718 ConnectFakeSignaling();
1719
1720 // Do normal offer/answer and wait for some frames to be received in each
1721 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001722 caller()->AddAudioVideoTracks();
1723 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001724 caller()->CreateAndSetAndSignalOffer();
1725 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001726 MediaExpectations media_expectations;
1727 media_expectations.ExpectBidirectionalAudioAndVideo();
1728 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07001729 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1730 webrtc::kEnumCounterKeyProtocolSdes));
1731 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1732 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001733}
1734
Steve Anton8c0f7a72017-10-03 10:03:10 -07001735// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1736// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001737TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001738 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1739 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1740 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1741 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1742 return pc->GetRemoteAudioSSLCertificate();
1743 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001744 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1745 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1746 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1747 return pc->GetRemoteAudioSSLCertChain();
1748 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001749
1750 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1751 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1752
1753 // Configure each side with a known certificate so they can be compared later.
1754 PeerConnectionInterface::RTCConfiguration caller_config;
1755 caller_config.enable_dtls_srtp.emplace(true);
1756 caller_config.certificates.push_back(caller_cert);
1757 PeerConnectionInterface::RTCConfiguration callee_config;
1758 callee_config.enable_dtls_srtp.emplace(true);
1759 callee_config.certificates.push_back(callee_cert);
1760 ASSERT_TRUE(
1761 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1762 ConnectFakeSignaling();
1763
1764 // When first initialized, there should not be a remote SSL certificate (and
1765 // calling this method should not crash).
1766 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1767 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001768 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1769 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001770
Steve Anton15324772018-01-16 10:26:49 -08001771 caller()->AddAudioTrack();
1772 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001773 caller()->CreateAndSetAndSignalOffer();
1774 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1775 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1776
1777 // Once DTLS has been connected, each side should return the other's SSL
1778 // certificate when calling GetRemoteAudioSSLCertificate.
1779
1780 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1781 ASSERT_TRUE(caller_remote_cert);
1782 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1783 caller_remote_cert->ToPEMString());
1784
1785 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1786 ASSERT_TRUE(callee_remote_cert);
1787 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1788 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001789
1790 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1791 ASSERT_TRUE(caller_remote_cert_chain);
1792 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1793 auto remote_cert = &caller_remote_cert_chain->Get(0);
1794 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1795 remote_cert->ToPEMString());
1796
1797 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1798 ASSERT_TRUE(callee_remote_cert_chain);
1799 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1800 remote_cert = &callee_remote_cert_chain->Get(0);
1801 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1802 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001803}
1804
deadbeef1dcb1642017-03-29 21:08:16 -07001805// This test sets up a call between two parties with a source resolution of
1806// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001807TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001808 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1809 ASSERT_TRUE(CreatePeerConnectionWrappers());
1810 ConnectFakeSignaling();
1811
Niels Möller5c7efe72018-05-11 10:34:46 +02001812 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1813 webrtc::FakePeriodicVideoSource::Config config;
1814 config.width = 1280;
1815 config.height = 720;
1816 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1817 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07001818
1819 // Do normal offer/answer and wait for at least one frame to be received in
1820 // each direction.
1821 caller()->CreateAndSetAndSignalOffer();
1822 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1823 callee()->min_video_frames_received_per_track() > 0,
1824 kMaxWaitForFramesMs);
1825
1826 // Check rendered aspect ratio.
1827 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1828 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1829 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1830 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1831}
1832
1833// This test sets up an one-way call, with media only from caller to
1834// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001835TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001836 ASSERT_TRUE(CreatePeerConnectionWrappers());
1837 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001838 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001839 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001840 MediaExpectations media_expectations;
1841 media_expectations.CalleeExpectsSomeAudioAndVideo();
1842 media_expectations.CallerExpectsNoAudio();
1843 media_expectations.CallerExpectsNoVideo();
1844 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001845}
1846
1847// This test sets up a audio call initially, with the callee rejecting video
1848// initially. Then later the callee decides to upgrade to audio/video, and
1849// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001850TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001851 ASSERT_TRUE(CreatePeerConnectionWrappers());
1852 ConnectFakeSignaling();
1853 // Initially, offer an audio/video stream from the caller, but refuse to
1854 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001855 caller()->AddAudioVideoTracks();
1856 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001857 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1858 PeerConnectionInterface::RTCOfferAnswerOptions options;
1859 options.offer_to_receive_video = 0;
1860 callee()->SetOfferAnswerOptions(options);
1861 } else {
1862 callee()->SetRemoteOfferHandler([this] {
1863 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1864 });
1865 }
deadbeef1dcb1642017-03-29 21:08:16 -07001866 // Do offer/answer and make sure audio is still received end-to-end.
1867 caller()->CreateAndSetAndSignalOffer();
1868 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001869 {
1870 MediaExpectations media_expectations;
1871 media_expectations.ExpectBidirectionalAudio();
1872 media_expectations.ExpectNoVideo();
1873 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1874 }
deadbeef1dcb1642017-03-29 21:08:16 -07001875 // Sanity check that the callee's description has a rejected video section.
1876 ASSERT_NE(nullptr, callee()->pc()->local_description());
1877 const ContentInfo* callee_video_content =
1878 GetFirstVideoContent(callee()->pc()->local_description()->description());
1879 ASSERT_NE(nullptr, callee_video_content);
1880 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001881
deadbeef1dcb1642017-03-29 21:08:16 -07001882 // Now negotiate with video and ensure negotiation succeeds, with video
1883 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001884 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001885 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1886 PeerConnectionInterface::RTCOfferAnswerOptions options;
1887 options.offer_to_receive_video = 1;
1888 callee()->SetOfferAnswerOptions(options);
1889 } else {
1890 callee()->SetRemoteOfferHandler(nullptr);
1891 caller()->SetRemoteOfferHandler([this] {
1892 // The caller creates a new transceiver to receive video on when receiving
1893 // the offer, but by default it is send only.
1894 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001895 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001896 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1897 transceivers[2]->receiver()->media_type());
1898 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1899 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1900 });
1901 }
deadbeef1dcb1642017-03-29 21:08:16 -07001902 callee()->CreateAndSetAndSignalOffer();
1903 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001904 {
1905 // Expect additional audio frames to be received after the upgrade.
1906 MediaExpectations media_expectations;
1907 media_expectations.ExpectBidirectionalAudioAndVideo();
1908 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1909 }
deadbeef1dcb1642017-03-29 21:08:16 -07001910}
1911
deadbeef4389b4d2017-09-07 09:07:36 -07001912// Simpler than the above test; just add an audio track to an established
1913// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001914TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07001915 ASSERT_TRUE(CreatePeerConnectionWrappers());
1916 ConnectFakeSignaling();
1917 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08001918 caller()->AddVideoTrack();
1919 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001920 caller()->CreateAndSetAndSignalOffer();
1921 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1922 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001923 caller()->AddAudioTrack();
1924 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001925 caller()->CreateAndSetAndSignalOffer();
1926 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1927 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001928 MediaExpectations media_expectations;
1929 media_expectations.ExpectBidirectionalAudioAndVideo();
1930 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07001931}
1932
deadbeef1dcb1642017-03-29 21:08:16 -07001933// This test sets up a call that's transferred to a new caller with a different
1934// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001935TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07001936 ASSERT_TRUE(CreatePeerConnectionWrappers());
1937 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001938 caller()->AddAudioVideoTracks();
1939 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001940 caller()->CreateAndSetAndSignalOffer();
1941 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1942
1943 // Keep the original peer around which will still send packets to the
1944 // receiving client. These SRTP packets will be dropped.
1945 std::unique_ptr<PeerConnectionWrapper> original_peer(
1946 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001947 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001948 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1949 // directly above.
1950 original_peer->pc()->Close();
1951
1952 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001953 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001954 caller()->CreateAndSetAndSignalOffer();
1955 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1956 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001957 MediaExpectations media_expectations;
1958 media_expectations.ExpectBidirectionalAudioAndVideo();
1959 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001960}
1961
1962// This test sets up a call that's transferred to a new callee with a different
1963// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001964TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07001965 ASSERT_TRUE(CreatePeerConnectionWrappers());
1966 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001967 caller()->AddAudioVideoTracks();
1968 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001969 caller()->CreateAndSetAndSignalOffer();
1970 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1971
1972 // Keep the original peer around which will still send packets to the
1973 // receiving client. These SRTP packets will be dropped.
1974 std::unique_ptr<PeerConnectionWrapper> original_peer(
1975 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001976 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001977 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1978 // directly above.
1979 original_peer->pc()->Close();
1980
1981 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001982 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001983 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
1984 caller()->CreateAndSetAndSignalOffer();
1985 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1986 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001987 MediaExpectations media_expectations;
1988 media_expectations.ExpectBidirectionalAudioAndVideo();
1989 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001990}
1991
1992// This test sets up a non-bundled call and negotiates bundling at the same
1993// time as starting an ICE restart. When bundling is in effect in the restart,
1994// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001995TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07001996 ASSERT_TRUE(CreatePeerConnectionWrappers());
1997 ConnectFakeSignaling();
1998
Steve Anton15324772018-01-16 10:26:49 -08001999 caller()->AddAudioVideoTracks();
2000 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002001 // Remove the bundle group from the SDP received by the callee.
2002 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2003 desc->RemoveGroupByName("BUNDLE");
2004 });
2005 caller()->CreateAndSetAndSignalOffer();
2006 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002007 {
2008 MediaExpectations media_expectations;
2009 media_expectations.ExpectBidirectionalAudioAndVideo();
2010 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2011 }
deadbeef1dcb1642017-03-29 21:08:16 -07002012 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2013 callee()->SetReceivedSdpMunger(nullptr);
2014 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2015 caller()->CreateAndSetAndSignalOffer();
2016 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2017
2018 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002019 {
2020 MediaExpectations media_expectations;
2021 media_expectations.ExpectBidirectionalAudioAndVideo();
2022 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2023 }
deadbeef1dcb1642017-03-29 21:08:16 -07002024}
2025
2026// Test CVO (Coordination of Video Orientation). If a video source is rotated
2027// and both peers support the CVO RTP header extension, the actual video frames
2028// don't need to be encoded in different resolutions, since the rotation is
2029// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002030TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002031 ASSERT_TRUE(CreatePeerConnectionWrappers());
2032 ConnectFakeSignaling();
2033 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002034 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002035 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002036 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002037 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2038
2039 // Wait for video frames to be received by both sides.
2040 caller()->CreateAndSetAndSignalOffer();
2041 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2042 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2043 callee()->min_video_frames_received_per_track() > 0,
2044 kMaxWaitForFramesMs);
2045
2046 // Ensure that the aspect ratio is unmodified.
2047 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2048 // not just assumed.
2049 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2050 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2051 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2052 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2053 // Ensure that the CVO bits were surfaced to the renderer.
2054 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2055 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2056}
2057
2058// Test that when the CVO extension isn't supported, video is rotated the
2059// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002060TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002061 ASSERT_TRUE(CreatePeerConnectionWrappers());
2062 ConnectFakeSignaling();
2063 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002064 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002065 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002066 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002067 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2068
2069 // Remove the CVO extension from the offered SDP.
2070 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2071 cricket::VideoContentDescription* video =
2072 GetFirstVideoContentDescription(desc);
2073 video->ClearRtpHeaderExtensions();
2074 });
2075 // Wait for video frames to be received by both sides.
2076 caller()->CreateAndSetAndSignalOffer();
2077 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2078 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2079 callee()->min_video_frames_received_per_track() > 0,
2080 kMaxWaitForFramesMs);
2081
2082 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2083 // rotation.
2084 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2085 // not just assumed.
2086 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2087 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2088 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2089 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2090 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2091 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2092 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2093}
2094
deadbeef1dcb1642017-03-29 21:08:16 -07002095// Test that if the answerer rejects the audio m= section, no audio is sent or
2096// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002097TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002098 ASSERT_TRUE(CreatePeerConnectionWrappers());
2099 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002100 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002101 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2102 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2103 // it will reject the audio m= section completely.
2104 PeerConnectionInterface::RTCOfferAnswerOptions options;
2105 options.offer_to_receive_audio = 0;
2106 callee()->SetOfferAnswerOptions(options);
2107 } else {
2108 // Stopping the audio RtpTransceiver will cause the media section to be
2109 // rejected in the answer.
2110 callee()->SetRemoteOfferHandler([this] {
2111 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2112 });
2113 }
Steve Anton15324772018-01-16 10:26:49 -08002114 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002115 // Do offer/answer and wait for successful end-to-end video frames.
2116 caller()->CreateAndSetAndSignalOffer();
2117 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002118 MediaExpectations media_expectations;
2119 media_expectations.ExpectBidirectionalVideo();
2120 media_expectations.ExpectNoAudio();
2121 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2122
deadbeef1dcb1642017-03-29 21:08:16 -07002123 // Sanity check that the callee's description has a rejected audio section.
2124 ASSERT_NE(nullptr, callee()->pc()->local_description());
2125 const ContentInfo* callee_audio_content =
2126 GetFirstAudioContent(callee()->pc()->local_description()->description());
2127 ASSERT_NE(nullptr, callee_audio_content);
2128 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002129 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2130 // The caller's transceiver should have stopped after receiving the answer.
2131 EXPECT_TRUE(caller()
2132 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2133 ->stopped());
2134 }
deadbeef1dcb1642017-03-29 21:08:16 -07002135}
2136
2137// Test that if the answerer rejects the video m= section, no video is sent or
2138// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002139TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002140 ASSERT_TRUE(CreatePeerConnectionWrappers());
2141 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002142 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002143 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2144 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2145 // it will reject the video m= section completely.
2146 PeerConnectionInterface::RTCOfferAnswerOptions options;
2147 options.offer_to_receive_video = 0;
2148 callee()->SetOfferAnswerOptions(options);
2149 } else {
2150 // Stopping the video RtpTransceiver will cause the media section to be
2151 // rejected in the answer.
2152 callee()->SetRemoteOfferHandler([this] {
2153 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2154 });
2155 }
Steve Anton15324772018-01-16 10:26:49 -08002156 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002157 // Do offer/answer and wait for successful end-to-end audio frames.
2158 caller()->CreateAndSetAndSignalOffer();
2159 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002160 MediaExpectations media_expectations;
2161 media_expectations.ExpectBidirectionalAudio();
2162 media_expectations.ExpectNoVideo();
2163 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2164
deadbeef1dcb1642017-03-29 21:08:16 -07002165 // Sanity check that the callee's description has a rejected video section.
2166 ASSERT_NE(nullptr, callee()->pc()->local_description());
2167 const ContentInfo* callee_video_content =
2168 GetFirstVideoContent(callee()->pc()->local_description()->description());
2169 ASSERT_NE(nullptr, callee_video_content);
2170 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002171 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2172 // The caller's transceiver should have stopped after receiving the answer.
2173 EXPECT_TRUE(caller()
2174 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2175 ->stopped());
2176 }
deadbeef1dcb1642017-03-29 21:08:16 -07002177}
2178
2179// Test that if the answerer rejects both audio and video m= sections, nothing
2180// bad happens.
2181// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2182// test anything but the fact that negotiation succeeds, which doesn't mean
2183// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002184TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002185 ASSERT_TRUE(CreatePeerConnectionWrappers());
2186 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002187 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002188 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2189 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2190 // will reject both audio and video m= sections.
2191 PeerConnectionInterface::RTCOfferAnswerOptions options;
2192 options.offer_to_receive_audio = 0;
2193 options.offer_to_receive_video = 0;
2194 callee()->SetOfferAnswerOptions(options);
2195 } else {
2196 callee()->SetRemoteOfferHandler([this] {
2197 // Stopping all transceivers will cause all media sections to be rejected.
2198 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2199 transceiver->Stop();
2200 }
2201 });
2202 }
deadbeef1dcb1642017-03-29 21:08:16 -07002203 // Do offer/answer and wait for stable signaling state.
2204 caller()->CreateAndSetAndSignalOffer();
2205 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002206
deadbeef1dcb1642017-03-29 21:08:16 -07002207 // Sanity check that the callee's description has rejected m= sections.
2208 ASSERT_NE(nullptr, callee()->pc()->local_description());
2209 const ContentInfo* callee_audio_content =
2210 GetFirstAudioContent(callee()->pc()->local_description()->description());
2211 ASSERT_NE(nullptr, callee_audio_content);
2212 EXPECT_TRUE(callee_audio_content->rejected);
2213 const ContentInfo* callee_video_content =
2214 GetFirstVideoContent(callee()->pc()->local_description()->description());
2215 ASSERT_NE(nullptr, callee_video_content);
2216 EXPECT_TRUE(callee_video_content->rejected);
2217}
2218
2219// This test sets up an audio and video call between two parties. After the
2220// call runs for a while, the caller sends an updated offer with video being
2221// rejected. Once the re-negotiation is done, the video flow should stop and
2222// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002223TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002224 ASSERT_TRUE(CreatePeerConnectionWrappers());
2225 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002226 caller()->AddAudioVideoTracks();
2227 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002228 caller()->CreateAndSetAndSignalOffer();
2229 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002230 {
2231 MediaExpectations media_expectations;
2232 media_expectations.ExpectBidirectionalAudioAndVideo();
2233 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2234 }
deadbeef1dcb1642017-03-29 21:08:16 -07002235 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002236 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2237 caller()->SetGeneratedSdpMunger(
2238 [](cricket::SessionDescription* description) {
2239 for (cricket::ContentInfo& content : description->contents()) {
2240 if (cricket::IsVideoContent(&content)) {
2241 content.rejected = true;
2242 }
2243 }
2244 });
2245 } else {
2246 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2247 }
deadbeef1dcb1642017-03-29 21:08:16 -07002248 caller()->CreateAndSetAndSignalOffer();
2249 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2250
2251 // Sanity check that the caller's description has a rejected video section.
2252 ASSERT_NE(nullptr, caller()->pc()->local_description());
2253 const ContentInfo* caller_video_content =
2254 GetFirstVideoContent(caller()->pc()->local_description()->description());
2255 ASSERT_NE(nullptr, caller_video_content);
2256 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002257 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002258 {
2259 MediaExpectations media_expectations;
2260 media_expectations.ExpectBidirectionalAudio();
2261 media_expectations.ExpectNoVideo();
2262 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2263 }
deadbeef1dcb1642017-03-29 21:08:16 -07002264}
2265
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002266// Do one offer/answer with audio, another that disables it (rejecting the m=
2267// section), and another that re-enables it. Regression test for:
2268// bugs.webrtc.org/6023
2269TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2270 ASSERT_TRUE(CreatePeerConnectionWrappers());
2271 ConnectFakeSignaling();
2272
2273 // Add audio track, do normal offer/answer.
2274 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2275 caller()->CreateLocalAudioTrack();
2276 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2277 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2278 caller()->CreateAndSetAndSignalOffer();
2279 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2280
2281 // Remove audio track, and set offer_to_receive_audio to false to cause the
2282 // m= section to be completely disabled, not just "recvonly".
2283 caller()->pc()->RemoveTrack(sender);
2284 PeerConnectionInterface::RTCOfferAnswerOptions options;
2285 options.offer_to_receive_audio = 0;
2286 caller()->SetOfferAnswerOptions(options);
2287 caller()->CreateAndSetAndSignalOffer();
2288 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2289
2290 // Add the audio track again, expecting negotiation to succeed and frames to
2291 // flow.
2292 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2293 options.offer_to_receive_audio = 1;
2294 caller()->SetOfferAnswerOptions(options);
2295 caller()->CreateAndSetAndSignalOffer();
2296 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2297
2298 MediaExpectations media_expectations;
2299 media_expectations.CalleeExpectsSomeAudio();
2300 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2301}
2302
deadbeef1dcb1642017-03-29 21:08:16 -07002303// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2304// is needed to support legacy endpoints.
2305// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2306// add a test for an end-to-end test without MID signaling either (basically,
2307// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002308TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002309 ASSERT_TRUE(CreatePeerConnectionWrappers());
2310 ConnectFakeSignaling();
2311 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002312 caller()->AddAudioVideoTracks();
2313 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002314 // Remove SSRCs and MSIDs from the received offer SDP.
2315 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002316 caller()->CreateAndSetAndSignalOffer();
2317 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002318 MediaExpectations media_expectations;
2319 media_expectations.ExpectBidirectionalAudioAndVideo();
2320 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002321}
2322
Seth Hampson5897a6e2018-04-03 11:16:33 -07002323// Basic end-to-end test, without SSRC signaling. This means that the track
2324// was created properly and frames are delivered when the MSIDs are communicated
2325// with a=msid lines and no a=ssrc lines.
2326TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2327 EndToEndCallWithoutSsrcSignaling) {
2328 const char kStreamId[] = "streamId";
2329 ASSERT_TRUE(CreatePeerConnectionWrappers());
2330 ConnectFakeSignaling();
2331 // Add just audio tracks.
2332 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2333 callee()->AddAudioTrack();
2334
2335 // Remove SSRCs from the received offer SDP.
2336 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2337 caller()->CreateAndSetAndSignalOffer();
2338 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2339 MediaExpectations media_expectations;
2340 media_expectations.ExpectBidirectionalAudio();
2341 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2342}
2343
Steve Antondf527fd2018-04-27 15:52:03 -07002344// Tests that video flows between multiple video tracks when SSRCs are not
2345// signaled. This exercises the MID RTP header extension which is needed to
2346// demux the incoming video tracks.
2347TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2348 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2349 ASSERT_TRUE(CreatePeerConnectionWrappers());
2350 ConnectFakeSignaling();
2351 caller()->AddVideoTrack();
2352 caller()->AddVideoTrack();
2353 callee()->AddVideoTrack();
2354 callee()->AddVideoTrack();
2355
2356 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2357 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2358 caller()->CreateAndSetAndSignalOffer();
2359 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2360 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2361 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2362
2363 // Expect video to be received in both directions on both tracks.
2364 MediaExpectations media_expectations;
2365 media_expectations.ExpectBidirectionalVideo();
2366 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2367}
2368
deadbeef1dcb1642017-03-29 21:08:16 -07002369// Test that if two video tracks are sent (from caller to callee, in this test),
2370// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002371TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002372 ASSERT_TRUE(CreatePeerConnectionWrappers());
2373 ConnectFakeSignaling();
2374 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002375 caller()->AddAudioVideoTracks();
2376 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002377 caller()->CreateAndSetAndSignalOffer();
2378 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002379 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002380
2381 MediaExpectations media_expectations;
2382 media_expectations.CalleeExpectsSomeAudioAndVideo();
2383 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002384}
2385
2386static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2387 bool first = true;
2388 for (cricket::ContentInfo& content : desc->contents()) {
2389 if (first) {
2390 first = false;
2391 continue;
2392 }
2393 content.bundle_only = true;
2394 }
2395 first = true;
2396 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2397 if (first) {
2398 first = false;
2399 continue;
2400 }
2401 transport.description.ice_ufrag.clear();
2402 transport.description.ice_pwd.clear();
2403 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2404 transport.description.identity_fingerprint.reset(nullptr);
2405 }
2406}
2407
2408// Test that if applying a true "max bundle" offer, which uses ports of 0,
2409// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2410// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2411// successfully and media flows.
2412// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2413// TODO(deadbeef): Won't need this test once we start generating actual
2414// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002415TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002416 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2417 ASSERT_TRUE(CreatePeerConnectionWrappers());
2418 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002419 caller()->AddAudioVideoTracks();
2420 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002421 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2422 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2423 // but the first m= section.
2424 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2425 caller()->CreateAndSetAndSignalOffer();
2426 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002427 MediaExpectations media_expectations;
2428 media_expectations.ExpectBidirectionalAudioAndVideo();
2429 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002430}
2431
2432// Test that we can receive the audio output level from a remote audio track.
2433// TODO(deadbeef): Use a fake audio source and verify that the output level is
2434// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002435TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002436 ASSERT_TRUE(CreatePeerConnectionWrappers());
2437 ConnectFakeSignaling();
2438 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002439 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002440 caller()->CreateAndSetAndSignalOffer();
2441 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2442
2443 // Get the audio output level stats. Note that the level is not available
2444 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002445 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002446 kMaxWaitForFramesMs);
2447}
2448
2449// Test that an audio input level is reported.
2450// TODO(deadbeef): Use a fake audio source and verify that the input level is
2451// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002452TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002453 ASSERT_TRUE(CreatePeerConnectionWrappers());
2454 ConnectFakeSignaling();
2455 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002456 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002457 caller()->CreateAndSetAndSignalOffer();
2458 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2459
2460 // Get the audio input level stats. The level should be available very
2461 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002462 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002463 kMaxWaitForStatsMs);
2464}
2465
2466// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002467TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002468 ASSERT_TRUE(CreatePeerConnectionWrappers());
2469 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002470 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002471 // Do offer/answer, wait for the callee to receive some frames.
2472 caller()->CreateAndSetAndSignalOffer();
2473 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002474
2475 MediaExpectations media_expectations;
2476 media_expectations.CalleeExpectsSomeAudioAndVideo();
2477 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002478
2479 // Get a handle to the remote tracks created, so they can be used as GetStats
2480 // filters.
Steve Anton15324772018-01-16 10:26:49 -08002481 for (auto receiver : callee()->pc()->GetReceivers()) {
2482 // We received frames, so we definitely should have nonzero "received bytes"
2483 // stats at this point.
2484 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2485 0);
2486 }
deadbeef1dcb1642017-03-29 21:08:16 -07002487}
2488
2489// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002490TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002491 ASSERT_TRUE(CreatePeerConnectionWrappers());
2492 ConnectFakeSignaling();
2493 auto audio_track = caller()->CreateLocalAudioTrack();
2494 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002495 caller()->AddTrack(audio_track);
2496 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002497 // Do offer/answer, wait for the callee to receive some frames.
2498 caller()->CreateAndSetAndSignalOffer();
2499 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002500 MediaExpectations media_expectations;
2501 media_expectations.CalleeExpectsSomeAudioAndVideo();
2502 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002503
2504 // The callee received frames, so we definitely should have nonzero "sent
2505 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002506 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2507 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2508}
2509
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002510// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002511TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002512 ASSERT_TRUE(CreatePeerConnectionWrappers());
2513 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002514 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002515
Steve Anton15324772018-01-16 10:26:49 -08002516 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002517
2518 // Do offer/answer, wait for the callee to receive some frames.
2519 caller()->CreateAndSetAndSignalOffer();
2520 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2521
2522 // Get the remote audio track created on the receiver, so they can be used as
2523 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002524 auto receivers = callee()->pc()->GetReceivers();
2525 ASSERT_EQ(1u, receivers.size());
2526 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002527
2528 // Get the audio output level stats. Note that the level is not available
2529 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002530 EXPECT_TRUE_WAIT(
2531 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2532 0,
2533 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002534}
2535
deadbeefd8ad7882017-04-18 16:01:17 -07002536// Test that we can get stats (using the new stats implemnetation) for
2537// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2538// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002539TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002540 GetStatsForUnsignaledStreamWithNewStatsApi) {
2541 ASSERT_TRUE(CreatePeerConnectionWrappers());
2542 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002543 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002544 // Remove SSRCs and MSIDs from the received offer SDP.
2545 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2546 caller()->CreateAndSetAndSignalOffer();
2547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002548 MediaExpectations media_expectations;
2549 media_expectations.CalleeExpectsSomeAudio(1);
2550 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002551
2552 // We received a frame, so we should have nonzero "bytes received" stats for
2553 // the unsignaled stream, if stats are working for it.
2554 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2555 callee()->NewGetStats();
2556 ASSERT_NE(nullptr, report);
2557 auto inbound_stream_stats =
2558 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2559 ASSERT_EQ(1U, inbound_stream_stats.size());
2560 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2561 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002562 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2563}
2564
Taylor Brandstettera4653442018-06-19 09:44:26 -07002565// Same as above but for the legacy stats implementation.
2566TEST_P(PeerConnectionIntegrationTest,
2567 GetStatsForUnsignaledStreamWithOldStatsApi) {
2568 ASSERT_TRUE(CreatePeerConnectionWrappers());
2569 ConnectFakeSignaling();
2570 caller()->AddAudioTrack();
2571 // Remove SSRCs and MSIDs from the received offer SDP.
2572 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2573 caller()->CreateAndSetAndSignalOffer();
2574 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2575
2576 // Note that, since the old stats implementation associates SSRCs with tracks
2577 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2578 // associated track ID. So we can't use the track "selector" argument.
2579 //
2580 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2581 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002582 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07002583 kDefaultTimeout);
2584}
2585
zhihuangf8164932017-05-19 13:09:47 -07002586// Test that we can successfully get the media related stats (audio level
2587// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002588TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002589 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2590 ASSERT_TRUE(CreatePeerConnectionWrappers());
2591 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002592 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002593 // Remove SSRCs and MSIDs from the received offer SDP.
2594 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2595 caller()->CreateAndSetAndSignalOffer();
2596 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002597 MediaExpectations media_expectations;
2598 media_expectations.CalleeExpectsSomeAudio(1);
2599 media_expectations.CalleeExpectsSomeVideo(1);
2600 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002601
2602 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2603 callee()->NewGetStats();
2604 ASSERT_NE(nullptr, report);
2605
2606 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2607 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2608 ASSERT_GE(audio_index, 0);
2609 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002610}
2611
deadbeef4e2deab2017-09-20 13:56:21 -07002612// Helper for test below.
2613void ModifySsrcs(cricket::SessionDescription* desc) {
2614 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002615 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002616 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002617 for (uint32_t& ssrc : stream.ssrcs) {
2618 ssrc = rtc::CreateRandomId();
2619 }
2620 }
2621 }
2622}
2623
2624// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2625// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2626// This should result in two "RTCInboundRTPStreamStats", but only one
2627// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2628// being reset to 0 once the SSRC change occurs.
2629//
2630// Regression test for this bug:
2631// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2632//
2633// The bug causes the track stats to only represent one of the two streams:
2634// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2635// that the track stat counters would reset to 0 when the new stream is
2636// received, and a 50% chance that they'll stop updating (while
2637// "concealed_samples" continues increasing, due to silence being generated for
2638// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002639TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002640 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002641 ASSERT_TRUE(CreatePeerConnectionWrappers());
2642 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002643 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002644 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2645 // that doesn't signal SSRCs (from the callee's perspective).
2646 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2647 caller()->CreateAndSetAndSignalOffer();
2648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2649 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002650 {
2651 MediaExpectations media_expectations;
2652 media_expectations.CalleeExpectsSomeAudio(50);
2653 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2654 }
deadbeef4e2deab2017-09-20 13:56:21 -07002655 // Some audio frames were received, so we should have nonzero "samples
2656 // received" for the track.
2657 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2658 callee()->NewGetStats();
2659 ASSERT_NE(nullptr, report);
2660 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2661 ASSERT_EQ(1U, track_stats.size());
2662 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2663 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2664 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2665
2666 // Create a new offer and munge it to cause the caller to use a new SSRC.
2667 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2668 caller()->CreateAndSetAndSignalOffer();
2669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2670 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2671 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002672 {
2673 MediaExpectations media_expectations;
2674 media_expectations.CalleeExpectsSomeAudio(25);
2675 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2676 }
deadbeef4e2deab2017-09-20 13:56:21 -07002677
2678 report = callee()->NewGetStats();
2679 ASSERT_NE(nullptr, report);
2680 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2681 ASSERT_EQ(1U, track_stats.size());
2682 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2683 // The "total samples received" stat should only be greater than it was
2684 // before.
2685 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2686 // Right now, the new SSRC will cause the counters to reset to 0.
2687 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2688
2689 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002690 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002691 // good sign that we're seeing stats from the old stream that's no longer
2692 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002693 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002694 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2695 EXPECT_LT(*track_stats[0]->concealed_samples,
2696 *track_stats[0]->total_samples_received *
2697 kAcceptableConcealedSamplesPercentage);
2698
2699 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2700 // sanity check that the SSRC really changed.
2701 // TODO(deadbeef): This isn't working right now, because we're not returning
2702 // *any* stats for the inactive stream. Uncomment when the bug is completely
2703 // fixed.
2704 // auto inbound_stream_stats =
2705 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2706 // ASSERT_EQ(2U, inbound_stream_stats.size());
2707}
2708
deadbeef1dcb1642017-03-29 21:08:16 -07002709// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002710TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002711 PeerConnectionFactory::Options dtls_10_options;
2712 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2713 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2714 dtls_10_options));
2715 ConnectFakeSignaling();
2716 // Do normal offer/answer and wait for some frames to be received in each
2717 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002718 caller()->AddAudioVideoTracks();
2719 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002720 caller()->CreateAndSetAndSignalOffer();
2721 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002722 MediaExpectations media_expectations;
2723 media_expectations.ExpectBidirectionalAudioAndVideo();
2724 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002725}
2726
2727// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002728TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002729 PeerConnectionFactory::Options dtls_10_options;
2730 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2731 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2732 dtls_10_options));
2733 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002734 caller()->AddAudioVideoTracks();
2735 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002736 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07002737 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002738 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002739 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002740 kDefaultTimeout);
2741 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002742 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07002743 // TODO(bugs.webrtc.org/9456): Fix it.
2744 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2745 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2746 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002747}
2748
2749// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002750TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002751 PeerConnectionFactory::Options dtls_12_options;
2752 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2753 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2754 dtls_12_options));
2755 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002756 caller()->AddAudioVideoTracks();
2757 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002758 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07002759 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002760 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002761 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002762 kDefaultTimeout);
2763 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002764 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07002765 // TODO(bugs.webrtc.org/9456): Fix it.
2766 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2767 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2768 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002769}
2770
2771// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2772// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002773TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002774 PeerConnectionFactory::Options caller_options;
2775 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2776 PeerConnectionFactory::Options callee_options;
2777 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2778 ASSERT_TRUE(
2779 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2780 ConnectFakeSignaling();
2781 // Do normal offer/answer and wait for some frames to be received in each
2782 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002783 caller()->AddAudioVideoTracks();
2784 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002785 caller()->CreateAndSetAndSignalOffer();
2786 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002787 MediaExpectations media_expectations;
2788 media_expectations.ExpectBidirectionalAudioAndVideo();
2789 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002790}
2791
2792// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2793// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002794TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07002795 PeerConnectionFactory::Options caller_options;
2796 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2797 PeerConnectionFactory::Options callee_options;
2798 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2799 ASSERT_TRUE(
2800 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2801 ConnectFakeSignaling();
2802 // Do normal offer/answer and wait for some frames to be received in each
2803 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002804 caller()->AddAudioVideoTracks();
2805 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002806 caller()->CreateAndSetAndSignalOffer();
2807 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002808 MediaExpectations media_expectations;
2809 media_expectations.ExpectBidirectionalAudioAndVideo();
2810 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002811}
2812
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002813// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2814// works as expected; the cipher should only be used if enabled by both sides.
2815TEST_P(PeerConnectionIntegrationTest,
2816 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2817 PeerConnectionFactory::Options caller_options;
2818 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2819 PeerConnectionFactory::Options callee_options;
2820 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2821 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2822 TestNegotiatedCipherSuite(caller_options, callee_options,
2823 expected_cipher_suite);
2824}
2825
2826TEST_P(PeerConnectionIntegrationTest,
2827 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2828 PeerConnectionFactory::Options caller_options;
2829 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2830 PeerConnectionFactory::Options callee_options;
2831 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2832 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2833 TestNegotiatedCipherSuite(caller_options, callee_options,
2834 expected_cipher_suite);
2835}
2836
2837TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2838 PeerConnectionFactory::Options caller_options;
2839 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2840 PeerConnectionFactory::Options callee_options;
2841 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2842 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2843 TestNegotiatedCipherSuite(caller_options, callee_options,
2844 expected_cipher_suite);
2845}
2846
deadbeef1dcb1642017-03-29 21:08:16 -07002847// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002848TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002849 bool local_gcm_enabled = false;
2850 bool remote_gcm_enabled = false;
2851 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2852 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2853 expected_cipher_suite);
2854}
2855
2856// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002857TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07002858 bool local_gcm_enabled = true;
2859 bool remote_gcm_enabled = true;
2860 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2861 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2862 expected_cipher_suite);
2863}
2864
2865// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002866TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002867 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2868 bool local_gcm_enabled = true;
2869 bool remote_gcm_enabled = false;
2870 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2871 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2872 expected_cipher_suite);
2873}
2874
2875// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002876TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002877 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2878 bool local_gcm_enabled = false;
2879 bool remote_gcm_enabled = true;
2880 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2881 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2882 expected_cipher_suite);
2883}
2884
deadbeef7914b8c2017-04-21 03:23:33 -07002885// Verify that media can be transmitted end-to-end when GCM crypto suites are
2886// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2887// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2888// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002889TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07002890 PeerConnectionFactory::Options gcm_options;
2891 gcm_options.crypto_options.enable_gcm_crypto_suites = true;
2892 ASSERT_TRUE(
2893 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2894 ConnectFakeSignaling();
2895 // Do normal offer/answer and wait for some frames to be received in each
2896 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002897 caller()->AddAudioVideoTracks();
2898 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07002899 caller()->CreateAndSetAndSignalOffer();
2900 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002901 MediaExpectations media_expectations;
2902 media_expectations.ExpectBidirectionalAudioAndVideo();
2903 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07002904}
2905
deadbeef1dcb1642017-03-29 21:08:16 -07002906// This test sets up a call between two parties with audio, video and an RTP
2907// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002908TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07002909 FakeConstraints setup_constraints;
2910 setup_constraints.SetAllowRtpDataChannels();
2911 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2912 &setup_constraints));
2913 ConnectFakeSignaling();
2914 // Expect that data channel created on caller side will show up for callee as
2915 // well.
2916 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002917 caller()->AddAudioVideoTracks();
2918 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002919 caller()->CreateAndSetAndSignalOffer();
2920 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2921 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002922 MediaExpectations media_expectations;
2923 media_expectations.ExpectBidirectionalAudioAndVideo();
2924 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002925 ASSERT_NE(nullptr, caller()->data_channel());
2926 ASSERT_NE(nullptr, callee()->data_channel());
2927 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2928 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2929
2930 // Ensure data can be sent in both directions.
2931 std::string data = "hello world";
2932 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2933 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2934 kDefaultTimeout);
2935 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2936 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2937 kDefaultTimeout);
2938}
2939
2940// Ensure that an RTP data channel is signaled as closed for the caller when
2941// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002942TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002943 RtpDataChannelSignaledClosedInCalleeOffer) {
2944 // Same procedure as above test.
2945 FakeConstraints setup_constraints;
2946 setup_constraints.SetAllowRtpDataChannels();
2947 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
2948 &setup_constraints));
2949 ConnectFakeSignaling();
2950 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08002951 caller()->AddAudioVideoTracks();
2952 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002953 caller()->CreateAndSetAndSignalOffer();
2954 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2955 ASSERT_NE(nullptr, caller()->data_channel());
2956 ASSERT_NE(nullptr, callee()->data_channel());
2957 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2958 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2959
2960 // Close the data channel on the callee, and do an updated offer/answer.
2961 callee()->data_channel()->Close();
2962 callee()->CreateAndSetAndSignalOffer();
2963 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2964 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2965 EXPECT_FALSE(callee()->data_observer()->IsOpen());
2966}
2967
2968// Tests that data is buffered in an RTP data channel until an observer is
2969// registered for it.
2970//
2971// NOTE: RTP data channels can receive data before the underlying
2972// transport has detected that a channel is writable and thus data can be
2973// received before the data channel state changes to open. That is hard to test
2974// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002975TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002976 DataBufferedUntilRtpDataChannelObserverRegistered) {
2977 // Use fake clock and simulated network delay so that we predictably can wait
2978 // until an SCTP message has been delivered without "sleep()"ing.
2979 rtc::ScopedFakeClock fake_clock;
2980 // Some things use a time of "0" as a special value, so we need to start out
2981 // the fake clock at a nonzero time.
2982 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02002983 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07002984 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
2985 virtual_socket_server()->UpdateDelayDistribution();
2986
2987 FakeConstraints constraints;
2988 constraints.SetAllowRtpDataChannels();
2989 ASSERT_TRUE(
2990 CreatePeerConnectionWrappersWithConstraints(&constraints, &constraints));
2991 ConnectFakeSignaling();
2992 caller()->CreateDataChannel();
2993 caller()->CreateAndSetAndSignalOffer();
2994 ASSERT_TRUE(caller()->data_channel() != nullptr);
2995 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
2996 kDefaultTimeout, fake_clock);
2997 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
2998 kDefaultTimeout, fake_clock);
2999 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3000 callee()->data_channel()->state(), kDefaultTimeout,
3001 fake_clock);
3002
3003 // Unregister the observer which is normally automatically registered.
3004 callee()->data_channel()->UnregisterObserver();
3005 // Send data and advance fake clock until it should have been received.
3006 std::string data = "hello world";
3007 caller()->data_channel()->Send(DataBuffer(data));
3008 SIMULATED_WAIT(false, 50, fake_clock);
3009
3010 // Attach data channel and expect data to be received immediately. Note that
3011 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3012 // further, but data can be received even if the callback is asynchronous.
3013 MockDataChannelObserver new_observer(callee()->data_channel());
3014 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
3015 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07003016 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3017 // If this is not done a DCHECK can be hit in ports.cc, because a large
3018 // negative number is calculated for the rtt due to the global clock changing.
3019 caller()->pc()->Close();
3020 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07003021}
3022
3023// This test sets up a call between two parties with audio, video and but only
3024// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003025TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07003026 FakeConstraints setup_constraints_1;
3027 setup_constraints_1.SetAllowRtpDataChannels();
3028 // Must disable DTLS to make negotiation succeed.
3029 setup_constraints_1.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
3030 false);
3031 FakeConstraints setup_constraints_2;
3032 setup_constraints_2.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
3033 false);
3034 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(
3035 &setup_constraints_1, &setup_constraints_2));
3036 ConnectFakeSignaling();
3037 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003038 caller()->AddAudioVideoTracks();
3039 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003040 caller()->CreateAndSetAndSignalOffer();
3041 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3042 // The caller should still have a data channel, but it should be closed, and
3043 // one should ever have been created for the callee.
3044 EXPECT_TRUE(caller()->data_channel() != nullptr);
3045 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3046 EXPECT_EQ(nullptr, callee()->data_channel());
3047}
3048
3049// This test sets up a call between two parties with audio, and video. When
3050// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003051TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003052 FakeConstraints setup_constraints;
3053 setup_constraints.SetAllowRtpDataChannels();
3054 ASSERT_TRUE(CreatePeerConnectionWrappersWithConstraints(&setup_constraints,
3055 &setup_constraints));
3056 ConnectFakeSignaling();
3057 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003058 caller()->AddAudioVideoTracks();
3059 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003060 caller()->CreateAndSetAndSignalOffer();
3061 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3062 // Create data channel and do new offer and answer.
3063 caller()->CreateDataChannel();
3064 caller()->CreateAndSetAndSignalOffer();
3065 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3066 ASSERT_NE(nullptr, caller()->data_channel());
3067 ASSERT_NE(nullptr, callee()->data_channel());
3068 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3069 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3070 // Ensure data can be sent in both directions.
3071 std::string data = "hello world";
3072 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3073 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3074 kDefaultTimeout);
3075 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3076 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3077 kDefaultTimeout);
3078}
3079
3080#ifdef HAVE_SCTP
3081
3082// This test sets up a call between two parties with audio, video and an SCTP
3083// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003084TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003085 ASSERT_TRUE(CreatePeerConnectionWrappers());
3086 ConnectFakeSignaling();
3087 // Expect that data channel created on caller side will show up for callee as
3088 // well.
3089 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003090 caller()->AddAudioVideoTracks();
3091 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003092 caller()->CreateAndSetAndSignalOffer();
3093 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3094 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003095 MediaExpectations media_expectations;
3096 media_expectations.ExpectBidirectionalAudioAndVideo();
3097 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003098 // Caller data channel should already exist (it created one). Callee data
3099 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3100 ASSERT_NE(nullptr, caller()->data_channel());
3101 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3102 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3103 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3104
3105 // Ensure data can be sent in both directions.
3106 std::string data = "hello world";
3107 caller()->data_channel()->Send(DataBuffer(data));
3108 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3109 kDefaultTimeout);
3110 callee()->data_channel()->Send(DataBuffer(data));
3111 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3112 kDefaultTimeout);
3113}
3114
3115// Ensure that when the callee closes an SCTP data channel, the closing
3116// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003117TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003118 // Same procedure as above test.
3119 ASSERT_TRUE(CreatePeerConnectionWrappers());
3120 ConnectFakeSignaling();
3121 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003122 caller()->AddAudioVideoTracks();
3123 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003124 caller()->CreateAndSetAndSignalOffer();
3125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3126 ASSERT_NE(nullptr, caller()->data_channel());
3127 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3128 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3129 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3130
3131 // Close the data channel on the callee side, and wait for it to reach the
3132 // "closed" state on both sides.
3133 callee()->data_channel()->Close();
3134 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3135 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3136}
3137
Seth Hampson2f0d7022018-02-20 11:54:42 -08003138TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003139 ASSERT_TRUE(CreatePeerConnectionWrappers());
3140 ConnectFakeSignaling();
3141 webrtc::DataChannelInit init;
3142 init.id = 53;
3143 init.maxRetransmits = 52;
3144 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003145 caller()->AddAudioVideoTracks();
3146 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003147 caller()->CreateAndSetAndSignalOffer();
3148 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003149 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3150 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 11:41:54 -07003151 EXPECT_EQ(init.id, callee()->data_channel()->id());
3152 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3153 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3154 EXPECT_FALSE(callee()->data_channel()->negotiated());
3155}
3156
deadbeef1dcb1642017-03-29 21:08:16 -07003157// Test usrsctp's ability to process unordered data stream, where data actually
3158// arrives out of order using simulated delays. Previously there have been some
3159// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003160TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003161 // Introduce random network delays.
3162 // Otherwise it's not a true "unordered" test.
3163 virtual_socket_server()->set_delay_mean(20);
3164 virtual_socket_server()->set_delay_stddev(5);
3165 virtual_socket_server()->UpdateDelayDistribution();
3166 // Normal procedure, but with unordered data channel config.
3167 ASSERT_TRUE(CreatePeerConnectionWrappers());
3168 ConnectFakeSignaling();
3169 webrtc::DataChannelInit init;
3170 init.ordered = false;
3171 caller()->CreateDataChannel(&init);
3172 caller()->CreateAndSetAndSignalOffer();
3173 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3174 ASSERT_NE(nullptr, caller()->data_channel());
3175 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3176 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3177 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3178
3179 static constexpr int kNumMessages = 100;
3180 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3181 static constexpr size_t kMaxMessageSize = 4096;
3182 // Create and send random messages.
3183 std::vector<std::string> sent_messages;
3184 for (int i = 0; i < kNumMessages; ++i) {
3185 size_t length =
3186 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3187 std::string message;
3188 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3189 caller()->data_channel()->Send(DataBuffer(message));
3190 callee()->data_channel()->Send(DataBuffer(message));
3191 sent_messages.push_back(message);
3192 }
3193
3194 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003195 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003196 caller()->data_observer()->received_message_count(),
3197 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003198 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003199 callee()->data_observer()->received_message_count(),
3200 kDefaultTimeout);
3201
3202 // Sort and compare to make sure none of the messages were corrupted.
3203 std::vector<std::string> caller_received_messages =
3204 caller()->data_observer()->messages();
3205 std::vector<std::string> callee_received_messages =
3206 callee()->data_observer()->messages();
3207 std::sort(sent_messages.begin(), sent_messages.end());
3208 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3209 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3210 EXPECT_EQ(sent_messages, caller_received_messages);
3211 EXPECT_EQ(sent_messages, callee_received_messages);
3212}
3213
3214// This test sets up a call between two parties with audio, and video. When
3215// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003216TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003217 ASSERT_TRUE(CreatePeerConnectionWrappers());
3218 ConnectFakeSignaling();
3219 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003220 caller()->AddAudioVideoTracks();
3221 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003222 caller()->CreateAndSetAndSignalOffer();
3223 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3224 // Create data channel and do new offer and answer.
3225 caller()->CreateDataChannel();
3226 caller()->CreateAndSetAndSignalOffer();
3227 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3228 // Caller data channel should already exist (it created one). Callee data
3229 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3230 ASSERT_NE(nullptr, caller()->data_channel());
3231 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3232 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3233 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3234 // Ensure data can be sent in both directions.
3235 std::string data = "hello world";
3236 caller()->data_channel()->Send(DataBuffer(data));
3237 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3238 kDefaultTimeout);
3239 callee()->data_channel()->Send(DataBuffer(data));
3240 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3241 kDefaultTimeout);
3242}
3243
deadbeef7914b8c2017-04-21 03:23:33 -07003244// Set up a connection initially just using SCTP data channels, later upgrading
3245// to audio/video, ensuring frames are received end-to-end. Effectively the
3246// inverse of the test above.
3247// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003248TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003249 ASSERT_TRUE(CreatePeerConnectionWrappers());
3250 ConnectFakeSignaling();
3251 // Do initial offer/answer with just data channel.
3252 caller()->CreateDataChannel();
3253 caller()->CreateAndSetAndSignalOffer();
3254 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3255 // Wait until data can be sent over the data channel.
3256 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3257 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3258 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3259
3260 // Do subsequent offer/answer with two-way audio and video. Audio and video
3261 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003262 caller()->AddAudioVideoTracks();
3263 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003264 caller()->CreateAndSetAndSignalOffer();
3265 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003266 MediaExpectations media_expectations;
3267 media_expectations.ExpectBidirectionalAudioAndVideo();
3268 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003269}
3270
deadbeef8b7e9ad2017-05-25 09:38:55 -07003271static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 09:38:55 -07003272 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 15:14:30 -08003273 GetFirstDataContentDescription(desc);
3274 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003275 dcd_offer->set_use_sctpmap(false);
3276 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3277}
3278
3279// Test that the data channel works when a spec-compliant SCTP m= section is
3280// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3281// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003282TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003283 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3284 ASSERT_TRUE(CreatePeerConnectionWrappers());
3285 ConnectFakeSignaling();
3286 caller()->CreateDataChannel();
3287 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3288 caller()->CreateAndSetAndSignalOffer();
3289 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3290 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3291 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3292 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3293
3294 // Ensure data can be sent in both directions.
3295 std::string data = "hello world";
3296 caller()->data_channel()->Send(DataBuffer(data));
3297 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3298 kDefaultTimeout);
3299 callee()->data_channel()->Send(DataBuffer(data));
3300 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3301 kDefaultTimeout);
3302}
3303
deadbeef1dcb1642017-03-29 21:08:16 -07003304#endif // HAVE_SCTP
3305
3306// Test that the ICE connection and gathering states eventually reach
3307// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003308TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003309 ASSERT_TRUE(CreatePeerConnectionWrappers());
3310 ConnectFakeSignaling();
3311 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003312 caller()->AddAudioVideoTracks();
3313 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003314 caller()->CreateAndSetAndSignalOffer();
3315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3316 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3317 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3318 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3319 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3320 // After the best candidate pair is selected and all candidates are signaled,
3321 // the ICE connection state should reach "complete".
3322 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3323 // answerer/"callee" by default) only reaches "connected". When this is
3324 // fixed, this test should be updated.
3325 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3326 caller()->ice_connection_state(), kDefaultTimeout);
3327 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3328 callee()->ice_connection_state(), kDefaultTimeout);
3329}
3330
Steve Antonede9ca52017-10-16 13:04:27 -07003331// Test that firewalling the ICE connection causes the clients to identify the
3332// disconnected state and then removing the firewall causes them to reconnect.
3333class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003334 : public PeerConnectionIntegrationBaseTest,
3335 public ::testing::WithParamInterface<
3336 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003337 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003338 PeerConnectionIntegrationIceStatesTest()
3339 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3340 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003341 }
3342
3343 void StartStunServer(const SocketAddress& server_address) {
3344 stun_server_.reset(
3345 cricket::TestStunServer::Create(network_thread(), server_address));
3346 }
3347
3348 bool TestIPv6() {
3349 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3350 }
3351
3352 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 16:57:45 -07003353 network_thread()->Invoke<void>(
3354 RTC_FROM_HERE,
3355 rtc::Bind(&cricket::PortAllocator::set_flags,
3356 caller()->port_allocator(), port_allocator_flags_));
3357 network_thread()->Invoke<void>(
3358 RTC_FROM_HERE,
3359 rtc::Bind(&cricket::PortAllocator::set_flags,
3360 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 13:04:27 -07003361 }
3362
3363 std::vector<SocketAddress> CallerAddresses() {
3364 std::vector<SocketAddress> addresses;
3365 addresses.push_back(SocketAddress("1.1.1.1", 0));
3366 if (TestIPv6()) {
3367 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3368 }
3369 return addresses;
3370 }
3371
3372 std::vector<SocketAddress> CalleeAddresses() {
3373 std::vector<SocketAddress> addresses;
3374 addresses.push_back(SocketAddress("2.2.2.2", 0));
3375 if (TestIPv6()) {
3376 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3377 }
3378 return addresses;
3379 }
3380
3381 void SetUpNetworkInterfaces() {
3382 // Remove the default interfaces added by the test infrastructure.
3383 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3384 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3385
3386 // Add network addresses for test.
3387 for (const auto& caller_address : CallerAddresses()) {
3388 caller()->network()->AddInterface(caller_address);
3389 }
3390 for (const auto& callee_address : CalleeAddresses()) {
3391 callee()->network()->AddInterface(callee_address);
3392 }
3393 }
3394
3395 private:
3396 uint32_t port_allocator_flags_;
3397 std::unique_ptr<cricket::TestStunServer> stun_server_;
3398};
3399
3400// Tests that the PeerConnection goes through all the ICE gathering/connection
3401// states over the duration of the call. This includes Disconnected and Failed
3402// states, induced by putting a firewall between the peers and waiting for them
3403// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003404TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3405 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3406 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3407 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 13:04:27 -07003408
3409 const SocketAddress kStunServerAddress =
3410 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3411 StartStunServer(kStunServerAddress);
3412
3413 PeerConnectionInterface::RTCConfiguration config;
3414 PeerConnectionInterface::IceServer ice_stun_server;
3415 ice_stun_server.urls.push_back(
3416 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3417 kStunServerAddress.PortAsString());
3418 config.servers.push_back(ice_stun_server);
3419
3420 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3421 ConnectFakeSignaling();
3422 SetPortAllocatorFlags();
3423 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003424 caller()->AddAudioVideoTracks();
3425 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003426
3427 // Initial state before anything happens.
3428 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3429 caller()->ice_gathering_state());
3430 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3431 caller()->ice_connection_state());
3432
3433 // Start the call by creating the offer, setting it as the local description,
3434 // then sending it to the peer who will respond with an answer. This happens
3435 // asynchronously so that we can watch the states as it runs in the
3436 // background.
3437 caller()->CreateAndSetAndSignalOffer();
3438
Steve Anton83119dd2017-11-10 16:19:52 -08003439 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3440 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003441
3442 // Verify that the observer was notified of the intermediate transitions.
3443 EXPECT_THAT(caller()->ice_connection_state_history(),
3444 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3445 PeerConnectionInterface::kIceConnectionConnected,
3446 PeerConnectionInterface::kIceConnectionCompleted));
3447 EXPECT_THAT(caller()->ice_gathering_state_history(),
3448 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3449 PeerConnectionInterface::kIceGatheringComplete));
3450
3451 // Block connections to/from the caller and wait for ICE to become
3452 // disconnected.
3453 for (const auto& caller_address : CallerAddresses()) {
3454 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3455 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003456 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-10 16:19:52 -08003457 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3458 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003459
3460 // Let ICE re-establish by removing the firewall rules.
3461 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01003462 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-10 16:19:52 -08003463 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3464 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003465
3466 // According to RFC7675, if there is no response within 30 seconds then the
3467 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08003468 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07003469 constexpr int kConsentTimeout = 30000;
3470 for (const auto& caller_address : CallerAddresses()) {
3471 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3472 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003473 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-10 16:19:52 -08003474 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3475 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003476}
3477
3478// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3479// and that the statistics in the metric observers are updated correctly.
3480TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3481 ASSERT_TRUE(CreatePeerConnectionWrappers());
3482 ConnectFakeSignaling();
3483 SetPortAllocatorFlags();
3484 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003485 caller()->AddAudioVideoTracks();
3486 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003487 caller()->CreateAndSetAndSignalOffer();
3488
3489 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3490
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07003491 // TODO(bugs.webrtc.org/9456): Fix it.
3492 const int num_best_ipv4 = webrtc::metrics::NumEvents(
3493 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
3494 const int num_best_ipv6 = webrtc::metrics::NumEvents(
3495 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003496 if (TestIPv6()) {
3497 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3498 // connection.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003499 EXPECT_EQ(0, num_best_ipv4);
3500 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003501 } else {
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003502 EXPECT_EQ(1, num_best_ipv4);
3503 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003504 }
3505
Qingsi Wang1a2cc0a2018-07-10 15:17:12 -07003506 EXPECT_EQ(0, webrtc::metrics::NumEvents(
3507 "WebRTC.PeerConnection.CandidatePairType_UDP",
3508 webrtc::kIceCandidatePairHostHost));
3509 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3510 "WebRTC.PeerConnection.CandidatePairType_UDP",
3511 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07003512}
3513
3514constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3515 cricket::PORTALLOCATOR_DISABLE_STUN |
3516 cricket::PORTALLOCATOR_DISABLE_RELAY;
3517constexpr uint32_t kFlagsIPv6NoStun =
3518 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3519 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3520constexpr uint32_t kFlagsIPv4Stun =
3521 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3522
Seth Hampson2f0d7022018-02-20 11:54:42 -08003523INSTANTIATE_TEST_CASE_P(
3524 PeerConnectionIntegrationTest,
3525 PeerConnectionIntegrationIceStatesTest,
3526 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3527 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3528 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3529 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07003530
deadbeef1dcb1642017-03-29 21:08:16 -07003531// This test sets up a call between two parties with audio and video.
3532// During the call, the caller restarts ICE and the test verifies that
3533// new ICE candidates are generated and audio and video still can flow, and the
3534// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003535TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07003536 ASSERT_TRUE(CreatePeerConnectionWrappers());
3537 ConnectFakeSignaling();
3538 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08003539 caller()->AddAudioVideoTracks();
3540 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003541 caller()->CreateAndSetAndSignalOffer();
3542 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3543 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3544 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3545 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3546 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3547
3548 // To verify that the ICE restart actually occurs, get
3549 // ufrag/password/candidates before and after restart.
3550 // Create an SDP string of the first audio candidate for both clients.
3551 const webrtc::IceCandidateCollection* audio_candidates_caller =
3552 caller()->pc()->local_description()->candidates(0);
3553 const webrtc::IceCandidateCollection* audio_candidates_callee =
3554 callee()->pc()->local_description()->candidates(0);
3555 ASSERT_GT(audio_candidates_caller->count(), 0u);
3556 ASSERT_GT(audio_candidates_callee->count(), 0u);
3557 std::string caller_candidate_pre_restart;
3558 ASSERT_TRUE(
3559 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3560 std::string callee_candidate_pre_restart;
3561 ASSERT_TRUE(
3562 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3563 const cricket::SessionDescription* desc =
3564 caller()->pc()->local_description()->description();
3565 std::string caller_ufrag_pre_restart =
3566 desc->transport_infos()[0].description.ice_ufrag;
3567 desc = callee()->pc()->local_description()->description();
3568 std::string callee_ufrag_pre_restart =
3569 desc->transport_infos()[0].description.ice_ufrag;
3570
3571 // Have the caller initiate an ICE restart.
3572 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3573 caller()->CreateAndSetAndSignalOffer();
3574 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3575 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3576 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3577 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3578 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3579
3580 // Grab the ufrags/candidates again.
3581 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3582 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3583 ASSERT_GT(audio_candidates_caller->count(), 0u);
3584 ASSERT_GT(audio_candidates_callee->count(), 0u);
3585 std::string caller_candidate_post_restart;
3586 ASSERT_TRUE(
3587 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3588 std::string callee_candidate_post_restart;
3589 ASSERT_TRUE(
3590 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3591 desc = caller()->pc()->local_description()->description();
3592 std::string caller_ufrag_post_restart =
3593 desc->transport_infos()[0].description.ice_ufrag;
3594 desc = callee()->pc()->local_description()->description();
3595 std::string callee_ufrag_post_restart =
3596 desc->transport_infos()[0].description.ice_ufrag;
3597 // Sanity check that an ICE restart was actually negotiated in SDP.
3598 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3599 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3600 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3601 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3602
3603 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003604 MediaExpectations media_expectations;
3605 media_expectations.ExpectBidirectionalAudioAndVideo();
3606 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003607}
3608
3609// Verify that audio/video can be received end-to-end when ICE renomination is
3610// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003611TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07003612 PeerConnectionInterface::RTCConfiguration config;
3613 config.enable_ice_renomination = true;
3614 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3615 ConnectFakeSignaling();
3616 // Do normal offer/answer and wait for some frames to be received in each
3617 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003618 caller()->AddAudioVideoTracks();
3619 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003620 caller()->CreateAndSetAndSignalOffer();
3621 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3622 // Sanity check that ICE renomination was actually negotiated.
3623 const cricket::SessionDescription* desc =
3624 caller()->pc()->local_description()->description();
3625 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003626 ASSERT_NE(
3627 info.description.transport_options.end(),
3628 std::find(info.description.transport_options.begin(),
3629 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003630 }
3631 desc = callee()->pc()->local_description()->description();
3632 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 02:41:29 -07003633 ASSERT_NE(
3634 info.description.transport_options.end(),
3635 std::find(info.description.transport_options.begin(),
3636 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07003637 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08003638 MediaExpectations media_expectations;
3639 media_expectations.ExpectBidirectionalAudioAndVideo();
3640 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003641}
3642
Steve Anton6f25b092017-10-23 09:39:20 -07003643// With a max bundle policy and RTCP muxing, adding a new media description to
3644// the connection should not affect ICE at all because the new media will use
3645// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003646TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08003647 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07003648 PeerConnectionInterface::RTCConfiguration config;
3649 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3650 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3651 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3652 config, PeerConnectionInterface::RTCConfiguration()));
3653 ConnectFakeSignaling();
3654
Steve Anton15324772018-01-16 10:26:49 -08003655 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003656 caller()->CreateAndSetAndSignalOffer();
3657 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07003658 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3659 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07003660
3661 caller()->clear_ice_connection_state_history();
3662
Steve Anton15324772018-01-16 10:26:49 -08003663 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07003664 caller()->CreateAndSetAndSignalOffer();
3665 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3666
3667 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3668}
3669
deadbeef1dcb1642017-03-29 21:08:16 -07003670// This test sets up a call between two parties with audio and video. It then
3671// renegotiates setting the video m-line to "port 0", then later renegotiates
3672// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003673TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003674 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3675 ASSERT_TRUE(CreatePeerConnectionWrappers());
3676 ConnectFakeSignaling();
3677
3678 // Do initial negotiation, only sending media from the caller. Will result in
3679 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08003680 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003681 caller()->CreateAndSetAndSignalOffer();
3682 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3683
3684 // Negotiate again, disabling the video "m=" section (the callee will set the
3685 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003686 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3687 PeerConnectionInterface::RTCOfferAnswerOptions options;
3688 options.offer_to_receive_video = 0;
3689 callee()->SetOfferAnswerOptions(options);
3690 } else {
3691 callee()->SetRemoteOfferHandler([this] {
3692 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3693 });
3694 }
deadbeef1dcb1642017-03-29 21:08:16 -07003695 caller()->CreateAndSetAndSignalOffer();
3696 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3697 // Sanity check that video "m=" section was actually rejected.
3698 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3699 callee()->pc()->local_description()->description());
3700 ASSERT_NE(nullptr, answer_video_content);
3701 ASSERT_TRUE(answer_video_content->rejected);
3702
3703 // Enable video and do negotiation again, making sure video is received
3704 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003705 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3706 PeerConnectionInterface::RTCOfferAnswerOptions options;
3707 options.offer_to_receive_video = 1;
3708 callee()->SetOfferAnswerOptions(options);
3709 } else {
3710 // The caller's transceiver is stopped, so we need to add another track.
3711 auto caller_transceiver =
3712 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3713 EXPECT_TRUE(caller_transceiver->stopped());
3714 caller()->AddVideoTrack();
3715 }
3716 callee()->AddVideoTrack();
3717 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07003718 caller()->CreateAndSetAndSignalOffer();
3719 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003720
deadbeef1dcb1642017-03-29 21:08:16 -07003721 // Verify the caller receives frames from the newly added stream, and the
3722 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003723 MediaExpectations media_expectations;
3724 media_expectations.CalleeExpectsSomeAudio();
3725 media_expectations.ExpectBidirectionalVideo();
3726 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003727}
3728
deadbeef1dcb1642017-03-29 21:08:16 -07003729// This tests that if we negotiate after calling CreateSender but before we
3730// have a track, then set a track later, frames from the newly-set track are
3731// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003732TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07003733 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3734 ASSERT_TRUE(CreatePeerConnectionWrappers());
3735 ConnectFakeSignaling();
3736 auto caller_audio_sender =
3737 caller()->pc()->CreateSender("audio", "caller_stream");
3738 auto caller_video_sender =
3739 caller()->pc()->CreateSender("video", "caller_stream");
3740 auto callee_audio_sender =
3741 callee()->pc()->CreateSender("audio", "callee_stream");
3742 auto callee_video_sender =
3743 callee()->pc()->CreateSender("video", "callee_stream");
3744 caller()->CreateAndSetAndSignalOffer();
3745 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3746 // Wait for ICE to complete, without any tracks being set.
3747 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3748 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3749 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3750 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3751 // Now set the tracks, and expect frames to immediately start flowing.
3752 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3753 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3754 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3755 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08003756 MediaExpectations media_expectations;
3757 media_expectations.ExpectBidirectionalAudioAndVideo();
3758 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3759}
3760
3761// This tests that if we negotiate after calling AddTransceiver but before we
3762// have a track, then set a track later, frames from the newly-set tracks are
3763// received end-to-end.
3764TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3765 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3766 ASSERT_TRUE(CreatePeerConnectionWrappers());
3767 ConnectFakeSignaling();
3768 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3769 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3770 auto caller_audio_sender = audio_result.MoveValue()->sender();
3771 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3772 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3773 auto caller_video_sender = video_result.MoveValue()->sender();
3774 callee()->SetRemoteOfferHandler([this] {
3775 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3776 callee()->pc()->GetTransceivers()[0]->SetDirection(
3777 RtpTransceiverDirection::kSendRecv);
3778 callee()->pc()->GetTransceivers()[1]->SetDirection(
3779 RtpTransceiverDirection::kSendRecv);
3780 });
3781 caller()->CreateAndSetAndSignalOffer();
3782 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3783 // Wait for ICE to complete, without any tracks being set.
3784 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3785 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3786 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3787 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3788 // Now set the tracks, and expect frames to immediately start flowing.
3789 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3790 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3791 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3792 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3793 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3794 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3795 MediaExpectations media_expectations;
3796 media_expectations.ExpectBidirectionalAudioAndVideo();
3797 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003798}
3799
3800// This test verifies that a remote video track can be added via AddStream,
3801// and sent end-to-end. For this particular test, it's simply echoed back
3802// from the caller to the callee, rather than being forwarded to a third
3803// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003804TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07003805 ASSERT_TRUE(CreatePeerConnectionWrappers());
3806 ConnectFakeSignaling();
3807 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08003808 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07003809 caller()->CreateAndSetAndSignalOffer();
3810 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003811 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07003812
3813 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3814 // time).
3815 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3816 callee()->CreateAndSetAndSignalOffer();
3817 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3818
Seth Hampson2f0d7022018-02-20 11:54:42 -08003819 MediaExpectations media_expectations;
3820 media_expectations.ExpectBidirectionalVideo();
3821 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003822}
3823
3824// Test that we achieve the expected end-to-end connection time, using a
3825// fake clock and simulated latency on the media and signaling paths.
3826// We use a TURN<->TURN connection because this is usually the quickest to
3827// set up initially, especially when we're confident the connection will work
3828// and can start sending media before we get a STUN response.
3829//
3830// With various optimizations enabled, here are the network delays we expect to
3831// be on the critical path:
3832// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3833// signaling answer (with DTLS fingerprint).
3834// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3835// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3836// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003837TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07003838 rtc::ScopedFakeClock fake_clock;
3839 // Some things use a time of "0" as a special value, so we need to start out
3840 // the fake clock at a nonzero time.
3841 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003842 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003843
3844 static constexpr int media_hop_delay_ms = 50;
3845 static constexpr int signaling_trip_delay_ms = 500;
3846 // For explanation of these values, see comment above.
3847 static constexpr int required_media_hops = 9;
3848 static constexpr int required_signaling_trips = 2;
3849 // For internal delays (such as posting an event asychronously).
3850 static constexpr int allowed_internal_delay_ms = 20;
3851 static constexpr int total_connection_time_ms =
3852 media_hop_delay_ms * required_media_hops +
3853 signaling_trip_delay_ms * required_signaling_trips +
3854 allowed_internal_delay_ms;
3855
3856 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3857 3478};
3858 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3859 0};
3860 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3861 3478};
3862 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3863 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07003864 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
3865 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003866
Seth Hampsonaed71642018-06-11 07:41:32 -07003867 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
3868 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07003869 // Bypass permission check on received packets so media can be sent before
3870 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07003871 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
3872 turn_server_1->set_enable_permission_checks(false);
3873 });
3874 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
3875 turn_server_2->set_enable_permission_checks(false);
3876 });
deadbeef1dcb1642017-03-29 21:08:16 -07003877
3878 PeerConnectionInterface::RTCConfiguration client_1_config;
3879 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3880 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3881 ice_server_1.username = "test";
3882 ice_server_1.password = "test";
3883 client_1_config.servers.push_back(ice_server_1);
3884 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3885 client_1_config.presume_writable_when_fully_relayed = true;
3886
3887 PeerConnectionInterface::RTCConfiguration client_2_config;
3888 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3889 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3890 ice_server_2.username = "test";
3891 ice_server_2.password = "test";
3892 client_2_config.servers.push_back(ice_server_2);
3893 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3894 client_2_config.presume_writable_when_fully_relayed = true;
3895
3896 ASSERT_TRUE(
3897 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3898 // Set up the simulated delays.
3899 SetSignalingDelayMs(signaling_trip_delay_ms);
3900 ConnectFakeSignaling();
3901 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
3902 virtual_socket_server()->UpdateDelayDistribution();
3903
3904 // Set "offer to receive audio/video" without adding any tracks, so we just
3905 // set up ICE/DTLS with no media.
3906 PeerConnectionInterface::RTCOfferAnswerOptions options;
3907 options.offer_to_receive_audio = 1;
3908 options.offer_to_receive_video = 1;
3909 caller()->SetOfferAnswerOptions(options);
3910 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07003911 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
3912 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07003913 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3914 // If this is not done a DCHECK can be hit in ports.cc, because a large
3915 // negative number is calculated for the rtt due to the global clock changing.
3916 caller()->pc()->Close();
3917 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07003918}
3919
Jonas Orelandbdcee282017-10-10 14:01:40 +02003920// Verify that a TurnCustomizer passed in through RTCConfiguration
3921// is actually used by the underlying TURN candidate pair.
3922// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003923TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02003924 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3925 3478};
3926 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3927 0};
3928 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3929 3478};
3930 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3931 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07003932 CreateTurnServer(turn_server_1_internal_address,
3933 turn_server_1_external_address);
3934 CreateTurnServer(turn_server_2_internal_address,
3935 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003936
3937 PeerConnectionInterface::RTCConfiguration client_1_config;
3938 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3939 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3940 ice_server_1.username = "test";
3941 ice_server_1.password = "test";
3942 client_1_config.servers.push_back(ice_server_1);
3943 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07003944 auto* customizer1 = CreateTurnCustomizer();
3945 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02003946
3947 PeerConnectionInterface::RTCConfiguration client_2_config;
3948 webrtc::PeerConnectionInterface::IceServer ice_server_2;
3949 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
3950 ice_server_2.username = "test";
3951 ice_server_2.password = "test";
3952 client_2_config.servers.push_back(ice_server_2);
3953 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07003954 auto* customizer2 = CreateTurnCustomizer();
3955 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02003956
3957 ASSERT_TRUE(
3958 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
3959 ConnectFakeSignaling();
3960
3961 // Set "offer to receive audio/video" without adding any tracks, so we just
3962 // set up ICE/DTLS with no media.
3963 PeerConnectionInterface::RTCOfferAnswerOptions options;
3964 options.offer_to_receive_audio = 1;
3965 options.offer_to_receive_video = 1;
3966 caller()->SetOfferAnswerOptions(options);
3967 caller()->CreateAndSetAndSignalOffer();
3968 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3969
Seth Hampsonaed71642018-06-11 07:41:32 -07003970 ExpectTurnCustomizerCountersIncremented(customizer1);
3971 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02003972}
3973
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07003974// Verifies that you can use TCP instead of UDP to connect to a TURN server and
3975// send media between the caller and the callee.
3976TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
3977 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3978 3478};
3979 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3980
3981 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07003982 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
3983 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07003984
3985 webrtc::PeerConnectionInterface::IceServer ice_server;
3986 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
3987 ice_server.username = "test";
3988 ice_server.password = "test";
3989
3990 PeerConnectionInterface::RTCConfiguration client_1_config;
3991 client_1_config.servers.push_back(ice_server);
3992 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3993
3994 PeerConnectionInterface::RTCConfiguration client_2_config;
3995 client_2_config.servers.push_back(ice_server);
3996 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
3997
3998 ASSERT_TRUE(
3999 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4000
4001 // Do normal offer/answer and wait for ICE to complete.
4002 ConnectFakeSignaling();
4003 caller()->AddAudioVideoTracks();
4004 callee()->AddAudioVideoTracks();
4005 caller()->CreateAndSetAndSignalOffer();
4006 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4007 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4008 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4009
4010 MediaExpectations media_expectations;
4011 media_expectations.ExpectBidirectionalAudioAndVideo();
4012 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4013}
4014
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004015// Verify that a SSLCertificateVerifier passed in through
4016// PeerConnectionDependencies is actually used by the underlying SSL
4017// implementation to determine whether a certificate presented by the TURN
4018// server is accepted by the client. Note that openssladapter_unittest.cc
4019// contains more detailed, lower-level tests.
4020TEST_P(PeerConnectionIntegrationTest,
4021 SSLCertificateVerifierUsedForTurnConnections) {
4022 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4023 3478};
4024 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4025
4026 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4027 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004028 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4029 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004030
4031 webrtc::PeerConnectionInterface::IceServer ice_server;
4032 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4033 ice_server.username = "test";
4034 ice_server.password = "test";
4035
4036 PeerConnectionInterface::RTCConfiguration client_1_config;
4037 client_1_config.servers.push_back(ice_server);
4038 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4039
4040 PeerConnectionInterface::RTCConfiguration client_2_config;
4041 client_2_config.servers.push_back(ice_server);
4042 // Setting the type to kRelay forces the connection to go through a TURN
4043 // server.
4044 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4045
4046 // Get a copy to the pointer so we can verify calls later.
4047 rtc::TestCertificateVerifier* client_1_cert_verifier =
4048 new rtc::TestCertificateVerifier();
4049 client_1_cert_verifier->verify_certificate_ = true;
4050 rtc::TestCertificateVerifier* client_2_cert_verifier =
4051 new rtc::TestCertificateVerifier();
4052 client_2_cert_verifier->verify_certificate_ = true;
4053
4054 // Create the dependencies with the test certificate verifier.
4055 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4056 client_1_deps.tls_cert_verifier =
4057 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4058 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4059 client_2_deps.tls_cert_verifier =
4060 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4061
4062 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4063 client_1_config, std::move(client_1_deps), client_2_config,
4064 std::move(client_2_deps)));
4065 ConnectFakeSignaling();
4066
4067 // Set "offer to receive audio/video" without adding any tracks, so we just
4068 // set up ICE/DTLS with no media.
4069 PeerConnectionInterface::RTCOfferAnswerOptions options;
4070 options.offer_to_receive_audio = 1;
4071 options.offer_to_receive_video = 1;
4072 caller()->SetOfferAnswerOptions(options);
4073 caller()->CreateAndSetAndSignalOffer();
4074 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4075
4076 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4077 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004078}
4079
4080TEST_P(PeerConnectionIntegrationTest,
4081 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4082 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4083 3478};
4084 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4085
4086 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4087 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004088 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4089 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004090
4091 webrtc::PeerConnectionInterface::IceServer ice_server;
4092 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4093 ice_server.username = "test";
4094 ice_server.password = "test";
4095
4096 PeerConnectionInterface::RTCConfiguration client_1_config;
4097 client_1_config.servers.push_back(ice_server);
4098 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4099
4100 PeerConnectionInterface::RTCConfiguration client_2_config;
4101 client_2_config.servers.push_back(ice_server);
4102 // Setting the type to kRelay forces the connection to go through a TURN
4103 // server.
4104 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4105
4106 // Get a copy to the pointer so we can verify calls later.
4107 rtc::TestCertificateVerifier* client_1_cert_verifier =
4108 new rtc::TestCertificateVerifier();
4109 client_1_cert_verifier->verify_certificate_ = false;
4110 rtc::TestCertificateVerifier* client_2_cert_verifier =
4111 new rtc::TestCertificateVerifier();
4112 client_2_cert_verifier->verify_certificate_ = false;
4113
4114 // Create the dependencies with the test certificate verifier.
4115 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4116 client_1_deps.tls_cert_verifier =
4117 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4118 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4119 client_2_deps.tls_cert_verifier =
4120 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4121
4122 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4123 client_1_config, std::move(client_1_deps), client_2_config,
4124 std::move(client_2_deps)));
4125 ConnectFakeSignaling();
4126
4127 // Set "offer to receive audio/video" without adding any tracks, so we just
4128 // set up ICE/DTLS with no media.
4129 PeerConnectionInterface::RTCOfferAnswerOptions options;
4130 options.offer_to_receive_audio = 1;
4131 options.offer_to_receive_video = 1;
4132 caller()->SetOfferAnswerOptions(options);
4133 caller()->CreateAndSetAndSignalOffer();
4134 bool wait_res = true;
4135 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4136 // properly, should be able to just wait for a state of "failed" instead of
4137 // waiting a fixed 10 seconds.
4138 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4139 ASSERT_FALSE(wait_res);
4140
4141 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4142 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004143}
4144
deadbeefc964d0b2017-04-03 10:03:35 -07004145// Test that audio and video flow end-to-end when codec names don't use the
4146// expected casing, given that they're supposed to be case insensitive. To test
4147// this, all but one codec is removed from each media description, and its
4148// casing is changed.
4149//
4150// In the past, this has regressed and caused crashes/black video, due to the
4151// fact that code at some layers was doing case-insensitive comparisons and
4152// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004153TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004154 ASSERT_TRUE(CreatePeerConnectionWrappers());
4155 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004156 caller()->AddAudioVideoTracks();
4157 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004158
4159 // Remove all but one audio/video codec (opus and VP8), and change the
4160 // casing of the caller's generated offer.
4161 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4162 cricket::AudioContentDescription* audio =
4163 GetFirstAudioContentDescription(description);
4164 ASSERT_NE(nullptr, audio);
4165 auto audio_codecs = audio->codecs();
4166 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4167 [](const cricket::AudioCodec& codec) {
4168 return codec.name != "opus";
4169 }),
4170 audio_codecs.end());
4171 ASSERT_EQ(1u, audio_codecs.size());
4172 audio_codecs[0].name = "OpUs";
4173 audio->set_codecs(audio_codecs);
4174
4175 cricket::VideoContentDescription* video =
4176 GetFirstVideoContentDescription(description);
4177 ASSERT_NE(nullptr, video);
4178 auto video_codecs = video->codecs();
4179 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4180 [](const cricket::VideoCodec& codec) {
4181 return codec.name != "VP8";
4182 }),
4183 video_codecs.end());
4184 ASSERT_EQ(1u, video_codecs.size());
4185 video_codecs[0].name = "vP8";
4186 video->set_codecs(video_codecs);
4187 });
4188
4189 caller()->CreateAndSetAndSignalOffer();
4190 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4191
4192 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004193 MediaExpectations media_expectations;
4194 media_expectations.ExpectBidirectionalAudioAndVideo();
4195 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004196}
4197
Seth Hampson2f0d7022018-02-20 11:54:42 -08004198TEST_P(PeerConnectionIntegrationTest, GetSources) {
hbos8d609f62017-04-10 07:39:05 -07004199 ASSERT_TRUE(CreatePeerConnectionWrappers());
4200 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004201 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004202 caller()->CreateAndSetAndSignalOffer();
4203 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004204 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004205 MediaExpectations media_expectations;
4206 media_expectations.CalleeExpectsSomeAudio(1);
4207 ASSERT_TRUE(ExpectNewFrames(media_expectations));
hbos8d609f62017-04-10 07:39:05 -07004208 ASSERT_GT(callee()->pc()->GetReceivers().size(), 0u);
4209 auto receiver = callee()->pc()->GetReceivers()[0];
4210 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
4211
4212 auto contributing_sources = receiver->GetSources();
4213 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4214 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4215 contributing_sources[0].source_id());
4216}
4217
deadbeef2f425aa2017-04-14 10:41:32 -07004218// Test that if a track is removed and added again with a different stream ID,
4219// the new stream ID is successfully communicated in SDP and media continues to
4220// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004221// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4222// it will not reuse a transceiver that has already been sending. After creating
4223// a new transceiver it tries to create an offer with two senders of the same
4224// track ids and it fails.
4225TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004226 ASSERT_TRUE(CreatePeerConnectionWrappers());
4227 ConnectFakeSignaling();
4228
4229 rtc::scoped_refptr<MediaStreamInterface> stream_1 =
4230 caller()->pc_factory()->CreateLocalMediaStream("stream_1");
4231 rtc::scoped_refptr<MediaStreamInterface> stream_2 =
4232 caller()->pc_factory()->CreateLocalMediaStream("stream_2");
4233
4234 // Add track using stream 1, do offer/answer.
4235 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4236 caller()->CreateLocalAudioTrack();
4237 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
4238 caller()->pc()->AddTrack(track, {stream_1.get()});
4239 caller()->CreateAndSetAndSignalOffer();
4240 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004241 {
4242 MediaExpectations media_expectations;
4243 media_expectations.CalleeExpectsSomeAudio(1);
4244 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4245 }
deadbeef2f425aa2017-04-14 10:41:32 -07004246 // Remove the sender, and create a new one with the new stream.
4247 caller()->pc()->RemoveTrack(sender);
4248 sender = caller()->pc()->AddTrack(track, {stream_2.get()});
4249 caller()->CreateAndSetAndSignalOffer();
4250 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4251 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004252 {
4253 MediaExpectations media_expectations;
4254 media_expectations.CalleeExpectsSomeAudio();
4255 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4256 }
deadbeef2f425aa2017-04-14 10:41:32 -07004257}
4258
Seth Hampson2f0d7022018-02-20 11:54:42 -08004259TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004260 ASSERT_TRUE(CreatePeerConnectionWrappers());
4261 ConnectFakeSignaling();
4262
Karl Wiberg918f50c2018-07-05 11:40:33 +02004263 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Elad Alon99c3fe52017-10-13 16:29:40 +02004264 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4265 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4266 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004267 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4268 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004269
Steve Anton15324772018-01-16 10:26:49 -08004270 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004271 caller()->CreateAndSetAndSignalOffer();
4272 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4273}
4274
Steve Antonede9ca52017-10-16 13:04:27 -07004275// Test that if candidates are only signaled by applying full session
4276// descriptions (instead of using AddIceCandidate), the peers can connect to
4277// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004278TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004279 ASSERT_TRUE(CreatePeerConnectionWrappers());
4280 // Each side will signal the session descriptions but not candidates.
4281 ConnectFakeSignalingForSdpOnly();
4282
4283 // Add audio video track and exchange the initial offer/answer with media
4284 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004285 caller()->AddAudioVideoTracks();
4286 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004287 caller()->CreateAndSetAndSignalOffer();
4288
4289 // Wait for all candidates to be gathered on both the caller and callee.
4290 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4291 caller()->ice_gathering_state(), kDefaultTimeout);
4292 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4293 callee()->ice_gathering_state(), kDefaultTimeout);
4294
4295 // The candidates will now be included in the session description, so
4296 // signaling them will start the ICE connection.
4297 caller()->CreateAndSetAndSignalOffer();
4298 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4299
4300 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004301 MediaExpectations media_expectations;
4302 media_expectations.ExpectBidirectionalAudioAndVideo();
4303 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004304}
4305
henrika5f6bf242017-11-01 11:06:56 +01004306// Test that SetAudioPlayout can be used to disable audio playout from the
4307// start, then later enable it. This may be useful, for example, if the caller
4308// needs to play a local ringtone until some event occurs, after which it
4309// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004310TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004311 ASSERT_TRUE(CreatePeerConnectionWrappers());
4312 ConnectFakeSignaling();
4313
4314 // Set up audio-only call where audio playout is disabled on caller's side.
4315 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004316 caller()->AddAudioTrack();
4317 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004318 caller()->CreateAndSetAndSignalOffer();
4319 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4320
4321 // Pump messages for a second.
4322 WAIT(false, 1000);
4323 // Since audio playout is disabled, the caller shouldn't have received
4324 // anything (at the playout level, at least).
4325 EXPECT_EQ(0, caller()->audio_frames_received());
4326 // As a sanity check, make sure the callee (for which playout isn't disabled)
4327 // did still see frames on its audio level.
4328 ASSERT_GT(callee()->audio_frames_received(), 0);
4329
4330 // Enable playout again, and ensure audio starts flowing.
4331 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004332 MediaExpectations media_expectations;
4333 media_expectations.ExpectBidirectionalAudio();
4334 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004335}
4336
4337double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4338 auto report = pc->NewGetStats();
4339 auto track_stats_list =
4340 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4341 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4342 for (const auto* track_stats : track_stats_list) {
4343 if (track_stats->remote_source.is_defined() &&
4344 *track_stats->remote_source) {
4345 remote_track_stats = track_stats;
4346 break;
4347 }
4348 }
4349
4350 if (!remote_track_stats->total_audio_energy.is_defined()) {
4351 return 0.0;
4352 }
4353 return *remote_track_stats->total_audio_energy;
4354}
4355
4356// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4357// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004358TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004359 DisableAudioPlayoutStillGeneratesAudioStats) {
4360 ASSERT_TRUE(CreatePeerConnectionWrappers());
4361 ConnectFakeSignaling();
4362
4363 // Set up audio-only call where playout is disabled but audio-processing is
4364 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004365 caller()->AddAudioTrack();
4366 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004367 caller()->pc()->SetAudioPlayout(false);
4368
4369 caller()->CreateAndSetAndSignalOffer();
4370 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4371
4372 // Wait for the callee to receive audio stats.
4373 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4374}
4375
henrika4f167df2017-11-01 14:45:55 +01004376// Test that SetAudioRecording can be used to disable audio recording from the
4377// start, then later enable it. This may be useful, for example, if the caller
4378// wants to ensure that no audio resources are active before a certain state
4379// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004380TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01004381 ASSERT_TRUE(CreatePeerConnectionWrappers());
4382 ConnectFakeSignaling();
4383
4384 // Set up audio-only call where audio recording is disabled on caller's side.
4385 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08004386 caller()->AddAudioTrack();
4387 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01004388 caller()->CreateAndSetAndSignalOffer();
4389 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4390
4391 // Pump messages for a second.
4392 WAIT(false, 1000);
4393 // Since caller has disabled audio recording, the callee shouldn't have
4394 // received anything.
4395 EXPECT_EQ(0, callee()->audio_frames_received());
4396 // As a sanity check, make sure the caller did still see frames on its
4397 // audio level since audio recording is enabled on the calle side.
4398 ASSERT_GT(caller()->audio_frames_received(), 0);
4399
4400 // Enable audio recording again, and ensure audio starts flowing.
4401 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004402 MediaExpectations media_expectations;
4403 media_expectations.ExpectBidirectionalAudio();
4404 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01004405}
4406
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004407// Test that after closing PeerConnections, they stop sending any packets (ICE,
4408// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004409TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004410 // Set up audio/video/data, wait for some frames to be received.
4411 ASSERT_TRUE(CreatePeerConnectionWrappers());
4412 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004413 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004414#ifdef HAVE_SCTP
4415 caller()->CreateDataChannel();
4416#endif
4417 caller()->CreateAndSetAndSignalOffer();
4418 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004419 MediaExpectations media_expectations;
4420 media_expectations.CalleeExpectsSomeAudioAndVideo();
4421 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004422 // Close PeerConnections.
4423 caller()->pc()->Close();
4424 callee()->pc()->Close();
4425 // Pump messages for a second, and ensure no new packets end up sent.
4426 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4427 WAIT(false, 1000);
4428 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4429 EXPECT_EQ(sent_packets_a, sent_packets_b);
4430}
4431
Steve Anton7eca0932018-03-30 15:18:41 -07004432// Test that transport stats are generated by the RTCStatsCollector for a
4433// connection that only involves data channels. This is a regression test for
4434// crbug.com/826972.
4435#ifdef HAVE_SCTP
4436TEST_P(PeerConnectionIntegrationTest,
4437 TransportStatsReportedForDataChannelOnlyConnection) {
4438 ASSERT_TRUE(CreatePeerConnectionWrappers());
4439 ConnectFakeSignaling();
4440 caller()->CreateDataChannel();
4441
4442 caller()->CreateAndSetAndSignalOffer();
4443 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4444 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4445
4446 auto caller_report = caller()->NewGetStats();
4447 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4448 auto callee_report = callee()->NewGetStats();
4449 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4450}
4451#endif // HAVE_SCTP
4452
Qingsi Wang7685e862018-06-11 20:15:46 -07004453TEST_P(PeerConnectionIntegrationTest,
4454 IceEventsGeneratedAndLoggedInRtcEventLog) {
4455 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4456 ConnectFakeSignaling();
4457 PeerConnectionInterface::RTCOfferAnswerOptions options;
4458 options.offer_to_receive_audio = 1;
4459 caller()->SetOfferAnswerOptions(options);
4460 caller()->CreateAndSetAndSignalOffer();
4461 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4462 ASSERT_NE(nullptr, caller()->event_log_factory());
4463 ASSERT_NE(nullptr, callee()->event_log_factory());
4464 webrtc::FakeRtcEventLog* caller_event_log =
4465 static_cast<webrtc::FakeRtcEventLog*>(
4466 caller()->event_log_factory()->last_log_created());
4467 webrtc::FakeRtcEventLog* callee_event_log =
4468 static_cast<webrtc::FakeRtcEventLog*>(
4469 callee()->event_log_factory()->last_log_created());
4470 ASSERT_NE(nullptr, caller_event_log);
4471 ASSERT_NE(nullptr, callee_event_log);
4472 int caller_ice_config_count = caller_event_log->GetEventCount(
4473 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4474 int caller_ice_event_count = caller_event_log->GetEventCount(
4475 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4476 int callee_ice_config_count = callee_event_log->GetEventCount(
4477 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4478 int callee_ice_event_count = callee_event_log->GetEventCount(
4479 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4480 EXPECT_LT(0, caller_ice_config_count);
4481 EXPECT_LT(0, caller_ice_event_count);
4482 EXPECT_LT(0, callee_ice_config_count);
4483 EXPECT_LT(0, callee_ice_event_count);
4484}
4485
Seth Hampson2f0d7022018-02-20 11:54:42 -08004486INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4487 PeerConnectionIntegrationTest,
4488 Values(SdpSemantics::kPlanB,
4489 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08004490
Steve Anton74255ff2018-01-24 18:32:57 -08004491// Tests that verify interoperability between Plan B and Unified Plan
4492// PeerConnections.
4493class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004494 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08004495 public ::testing::WithParamInterface<
4496 std::tuple<SdpSemantics, SdpSemantics>> {
4497 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004498 // Setting the SdpSemantics for the base test to kDefault does not matter
4499 // because we specify not to use the test semantics when creating
4500 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08004501 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07004502 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08004503 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08004504 callee_semantics_(std::get<1>(GetParam())) {}
4505
4506 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07004507 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4508 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08004509 }
4510
4511 const SdpSemantics caller_semantics_;
4512 const SdpSemantics callee_semantics_;
4513};
4514
4515TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4516 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4517 ConnectFakeSignaling();
4518
4519 caller()->CreateAndSetAndSignalOffer();
4520 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4521}
4522
4523TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4524 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4525 ConnectFakeSignaling();
4526 auto audio_sender = caller()->AddAudioTrack();
4527
4528 caller()->CreateAndSetAndSignalOffer();
4529 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4530
4531 // Verify that one audio receiver has been created on the remote and that it
4532 // has the same track ID as the sending track.
4533 auto receivers = callee()->pc()->GetReceivers();
4534 ASSERT_EQ(1u, receivers.size());
4535 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4536 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4537
Seth Hampson2f0d7022018-02-20 11:54:42 -08004538 MediaExpectations media_expectations;
4539 media_expectations.CalleeExpectsSomeAudio();
4540 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004541}
4542
4543TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4544 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4545 ConnectFakeSignaling();
4546 auto video_sender = caller()->AddVideoTrack();
4547 auto audio_sender = caller()->AddAudioTrack();
4548
4549 caller()->CreateAndSetAndSignalOffer();
4550 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4551
4552 // Verify that one audio and one video receiver have been created on the
4553 // remote and that they have the same track IDs as the sending tracks.
4554 auto audio_receivers =
4555 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4556 ASSERT_EQ(1u, audio_receivers.size());
4557 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4558 auto video_receivers =
4559 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4560 ASSERT_EQ(1u, video_receivers.size());
4561 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4562
Seth Hampson2f0d7022018-02-20 11:54:42 -08004563 MediaExpectations media_expectations;
4564 media_expectations.CalleeExpectsSomeAudioAndVideo();
4565 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004566}
4567
4568TEST_P(PeerConnectionIntegrationInteropTest,
4569 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4570 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4571 ConnectFakeSignaling();
4572 caller()->AddAudioVideoTracks();
4573 callee()->AddAudioVideoTracks();
4574
4575 caller()->CreateAndSetAndSignalOffer();
4576 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4577
Seth Hampson2f0d7022018-02-20 11:54:42 -08004578 MediaExpectations media_expectations;
4579 media_expectations.ExpectBidirectionalAudioAndVideo();
4580 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004581}
4582
4583TEST_P(PeerConnectionIntegrationInteropTest,
4584 ReverseRolesOneAudioLocalToOneVideoRemote) {
4585 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4586 ConnectFakeSignaling();
4587 caller()->AddAudioTrack();
4588 callee()->AddVideoTrack();
4589
4590 caller()->CreateAndSetAndSignalOffer();
4591 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4592
4593 // Verify that only the audio track has been negotiated.
4594 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4595 // Might also check that the callee's NegotiationNeeded flag is set.
4596
4597 // Reverse roles.
4598 callee()->CreateAndSetAndSignalOffer();
4599 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4600
Seth Hampson2f0d7022018-02-20 11:54:42 -08004601 MediaExpectations media_expectations;
4602 media_expectations.CallerExpectsSomeVideo();
4603 media_expectations.CalleeExpectsSomeAudio();
4604 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004605}
4606
Steve Antonba42e992018-04-09 14:10:01 -07004607INSTANTIATE_TEST_CASE_P(
4608 PeerConnectionIntegrationTest,
4609 PeerConnectionIntegrationInteropTest,
4610 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4611 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4612
4613// Test that if the Unified Plan side offers two video tracks then the Plan B
4614// side will only see the first one and ignore the second.
4615TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07004616 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4617 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08004618 ConnectFakeSignaling();
4619 auto first_sender = caller()->AddVideoTrack();
4620 caller()->AddVideoTrack();
4621
4622 caller()->CreateAndSetAndSignalOffer();
4623 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4624
4625 // Verify that there is only one receiver and it corresponds to the first
4626 // added track.
4627 auto receivers = callee()->pc()->GetReceivers();
4628 ASSERT_EQ(1u, receivers.size());
4629 EXPECT_TRUE(receivers[0]->track()->enabled());
4630 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4631
Seth Hampson2f0d7022018-02-20 11:54:42 -08004632 MediaExpectations media_expectations;
4633 media_expectations.CalleeExpectsSomeVideo();
4634 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004635}
4636
deadbeef1dcb1642017-03-29 21:08:16 -07004637} // namespace
4638
4639#endif // if !defined(THREAD_SANITIZER)