blob: 28e0110355037ed4d7ec916326ae68f171ce13d3 [file] [log] [blame]
deadbeef1dcb1642017-03-30 04:08:161/*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// Disable for TSan v2, see
12// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
13#if !defined(THREAD_SANITIZER)
14
15#include <stdio.h>
16
17#include <algorithm>
18#include <functional>
19#include <list>
20#include <map>
21#include <memory>
22#include <utility>
23#include <vector>
24
Karl Wiberg1b0eae32017-10-17 12:48:5425#include "api/audio_codecs/builtin_audio_decoder_factory.h"
26#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3127#include "api/mediastreaminterface.h"
28#include "api/peerconnectioninterface.h"
Steve Anton8c0f7a72017-10-03 17:03:1029#include "api/peerconnectionproxy.h"
Mirko Bonadeic61ce0d2017-11-21 16:04:2030#include "api/rtpreceiverinterface.h"
Anders Carlsson67537952018-05-03 09:28:2931#include "api/video_codecs/builtin_video_decoder_factory.h"
32#include "api/video_codecs/builtin_video_encoder_factory.h"
33#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-12 03:15:4634#include "call/call.h"
35#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
36#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3137#include "media/engine/fakewebrtcvideoengine.h"
Qingsi Wang7685e862018-06-12 03:15:4638#include "media/engine/webrtcmediaengine.h"
39#include "modules/audio_processing/include/audio_processing.h"
Zach Stein6fcdc2f2018-08-23 23:25:5540#include "p2p/base/mockasyncresolver.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3141#include "p2p/base/p2pconstants.h"
42#include "p2p/base/portinterface.h"
Steve Antonede9ca52017-10-16 20:04:2743#include "p2p/base/teststunserver.h"
Jonas Orelandbdcee282017-10-10 12:01:4044#include "p2p/base/testturncustomizer.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3145#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 19:54:4252#include "pc/rtpmediautils.h"
Steve Anton4ab68ee2017-12-19 22:26:1153#include "pc/sessiondescription.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3154#include "pc/test/fakeaudiocapturemodule.h"
Niels Möller0f405822018-05-17 07:16:4155#include "pc/test/fakeperiodicvideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3156#include "pc/test/fakertccertificategenerator.h"
57#include "pc/test/fakevideotrackrenderer.h"
58#include "pc/test/mockpeerconnectionobservers.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3159#include "rtc_base/fakenetwork.h"
Steve Antonede9ca52017-10-16 20:04:2760#include "rtc_base/firewallsocketserver.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3161#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 10:53:2362#include "rtc_base/numerics/safe_conversions.h"
Benjamin Wrightd6f86e82018-05-08 20:12:2563#include "rtc_base/testcertificateverifier.h"
Johannes Kron965e7942018-09-13 13:36:2064#include "rtc_base/timeutils.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3165#include "rtc_base/virtualsocketserver.h"
Mirko Bonadei17f48782018-09-28 06:51:1066#include "system_wrappers/include/metrics.h"
Elad Alon99c3fe52017-10-13 14:29:4067#include "test/gmock.h"
deadbeef1dcb1642017-03-30 04:08:1668
69using cricket::ContentInfo;
70using cricket::FakeWebRtcVideoDecoder;
71using cricket::FakeWebRtcVideoDecoderFactory;
72using cricket::FakeWebRtcVideoEncoder;
73using cricket::FakeWebRtcVideoEncoderFactory;
74using cricket::MediaContentDescription;
Steve Antondf527fd2018-04-27 22:52:0375using cricket::StreamParams;
Steve Antonede9ca52017-10-16 20:04:2776using rtc::SocketAddress;
Seth Hampson2f0d7022018-02-20 19:54:4277using ::testing::Combine;
Steve Antonede9ca52017-10-16 20:04:2778using ::testing::ElementsAre;
Zach Stein6fcdc2f2018-08-23 23:25:5579using ::testing::Return;
80using ::testing::SetArgPointee;
Steve Antonede9ca52017-10-16 20:04:2781using ::testing::Values;
Zach Stein6fcdc2f2018-08-23 23:25:5582using ::testing::_;
deadbeef1dcb1642017-03-30 04:08:1683using webrtc::DataBuffer;
84using webrtc::DataChannelInterface;
85using webrtc::DtmfSender;
86using webrtc::DtmfSenderInterface;
87using webrtc::DtmfSenderObserverInterface;
Steve Anton15324772018-01-16 18:26:4988using webrtc::FakeVideoTrackRenderer;
deadbeef1dcb1642017-03-30 04:08:1689using webrtc::MediaStreamInterface;
90using webrtc::MediaStreamTrackInterface;
91using webrtc::MockCreateSessionDescriptionObserver;
92using webrtc::MockDataChannelObserver;
93using webrtc::MockSetSessionDescriptionObserver;
94using webrtc::MockStatsObserver;
95using webrtc::ObserverInterface;
Steve Anton8c0f7a72017-10-03 17:03:1096using webrtc::PeerConnection;
deadbeef1dcb1642017-03-30 04:08:1697using webrtc::PeerConnectionInterface;
Steve Anton74255ff2018-01-25 02:32:5798using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-30 04:08:1699using webrtc::PeerConnectionFactory;
Steve Anton8c0f7a72017-10-03 17:03:10100using webrtc::PeerConnectionProxy;
Steve Anton15324772018-01-16 18:26:49101using webrtc::RTCErrorType;
Steve Anton7eca0932018-03-30 22:18:41102using webrtc::RTCTransportStats;
Steve Anton74255ff2018-01-25 02:32:57103using webrtc::RtpSenderInterface;
Mirko Bonadeic61ce0d2017-11-21 16:04:20104using webrtc::RtpReceiverInterface;
Seth Hampson2f0d7022018-02-20 19:54:42105using webrtc::RtpSenderInterface;
106using webrtc::RtpTransceiverDirection;
107using webrtc::RtpTransceiverInit;
108using webrtc::RtpTransceiverInterface;
Steve Antond3679212018-01-18 01:41:02109using webrtc::SdpSemantics;
Steve Antona3a92c22017-12-07 18:27:41110using webrtc::SdpType;
deadbeef1dcb1642017-03-30 04:08:16111using webrtc::SessionDescriptionInterface;
112using webrtc::StreamCollectionInterface;
Steve Anton15324772018-01-16 18:26:49113using webrtc::VideoTrackInterface;
deadbeef1dcb1642017-03-30 04:08:16114
115namespace {
116
117static const int kDefaultTimeout = 10000;
118static const int kMaxWaitForStatsMs = 3000;
119static const int kMaxWaitForActivationMs = 5000;
120static const int kMaxWaitForFramesMs = 10000;
121// Default number of audio/video frames to wait for before considering a test
122// successful.
123static const int kDefaultExpectedAudioFrameCount = 3;
124static const int kDefaultExpectedVideoFrameCount = 3;
125
deadbeef1dcb1642017-03-30 04:08:16126static const char kDataChannelLabel[] = "data_channel";
127
128// SRTP cipher name negotiated by the tests. This must be updated if the
129// default changes.
Taylor Brandstetterfd350d72018-04-03 23:29:26130static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-30 04:08:16131static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
132
Steve Antonede9ca52017-10-16 20:04:27133static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
134
deadbeef1dcb1642017-03-30 04:08:16135// Helper function for constructing offer/answer options to initiate an ICE
136// restart.
137PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
138 PeerConnectionInterface::RTCOfferAnswerOptions options;
139 options.ice_restart = true;
140 return options;
141}
142
deadbeefd8ad7882017-04-18 23:01:17143// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
144// attribute from received SDP, simulating a legacy endpoint.
145void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
146 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 23:14:30147 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 23:01:17148 }
149 desc->set_msid_supported(false);
150}
151
Seth Hampson5897a6e2018-04-03 18:16:33152// Removes all stream information besides the stream ids, simulating an
153// endpoint that only signals a=msid lines to convey stream_ids.
154void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
155 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 22:52:03156 std::string track_id;
Seth Hampson5897a6e2018-04-03 18:16:33157 std::vector<std::string> stream_ids;
158 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 22:52:03159 const StreamParams& first_stream =
160 content.media_description()->streams()[0];
161 track_id = first_stream.id;
162 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 18:16:33163 }
164 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 22:52:03165 StreamParams new_stream;
166 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 18:16:33167 new_stream.set_stream_ids(stream_ids);
168 content.media_description()->AddStream(new_stream);
169 }
170}
171
zhihuangf8164932017-05-19 20:09:47172int FindFirstMediaStatsIndexByKind(
173 const std::string& kind,
174 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
175 media_stats_vec) {
176 for (size_t i = 0; i < media_stats_vec.size(); i++) {
177 if (media_stats_vec[i]->kind.ValueToString() == kind) {
178 return i;
179 }
180 }
181 return -1;
182}
183
deadbeef1dcb1642017-03-30 04:08:16184class SignalingMessageReceiver {
185 public:
Steve Antona3a92c22017-12-07 18:27:41186 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-30 04:08:16187 virtual void ReceiveIceMessage(const std::string& sdp_mid,
188 int sdp_mline_index,
189 const std::string& msg) = 0;
190
191 protected:
192 SignalingMessageReceiver() {}
193 virtual ~SignalingMessageReceiver() {}
194};
195
196class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
197 public:
198 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
199 : expected_media_type_(media_type) {}
200
201 void OnFirstPacketReceived(cricket::MediaType media_type) override {
202 ASSERT_EQ(expected_media_type_, media_type);
203 first_packet_received_ = true;
204 }
205
206 bool first_packet_received() const { return first_packet_received_; }
207
208 virtual ~MockRtpReceiverObserver() {}
209
210 private:
211 bool first_packet_received_ = false;
212 cricket::MediaType expected_media_type_;
213};
214
Zach Stein6fcdc2f2018-08-23 23:25:55215// Used by PeerConnectionWrapper::OnIceCandidate to allow a test to modify an
216// ICE candidate before it is signaled.
217class IceCandidateReplacerInterface {
218 public:
219 virtual ~IceCandidateReplacerInterface() = default;
220 // Return nullptr to drop the candidate (it won't be signaled to the other
221 // side).
222 virtual std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
223 const webrtc::IceCandidateInterface*) = 0;
224};
225
deadbeef1dcb1642017-03-30 04:08:16226// Helper class that wraps a peer connection, observes it, and can accept
227// signaling messages from another wrapper.
228//
229// Uses a fake network, fake A/V capture, and optionally fake
230// encoders/decoders, though they aren't used by default since they don't
231// advertise support of any codecs.
Steve Anton94286cb2017-09-26 23:20:19232// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 19:54:42233// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-30 04:08:16234class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 18:26:49235 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-30 04:08:16236 public:
237 // Different factory methods for convenience.
238 // TODO(deadbeef): Could use the pattern of:
239 //
240 // PeerConnectionWrapper =
241 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
242 //
243 // To reduce some code duplication.
244 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
245 const std::string& debug_name,
246 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
247 rtc::Thread* network_thread,
248 rtc::Thread* worker_thread) {
249 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 20:12:25250 webrtc::PeerConnectionDependencies dependencies(nullptr);
251 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 10:32:18252 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
253 worker_thread, nullptr)) {
deadbeef1dcb1642017-03-30 04:08:16254 delete client;
255 return nullptr;
256 }
257 return client;
258 }
259
deadbeef2f425aa2017-04-14 17:41:32260 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
261 return peer_connection_factory_.get();
262 }
263
deadbeef1dcb1642017-03-30 04:08:16264 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
265
266 // If a signaling message receiver is set (via ConnectFakeSignaling), this
267 // will set the whole offer/answer exchange in motion. Just need to wait for
268 // the signaling state to reach "stable".
269 void CreateAndSetAndSignalOffer() {
270 auto offer = CreateOffer();
271 ASSERT_NE(nullptr, offer);
272 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
273 }
274
275 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
276 // when a remote offer is received (via fake signaling) and an answer is
277 // generated. By default, uses default options.
278 void SetOfferAnswerOptions(
279 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
280 offer_answer_options_ = options;
281 }
282
283 // Set a callback to be invoked when SDP is received via the fake signaling
284 // channel, which provides an opportunity to munge (modify) the SDP. This is
285 // used to test SDP being applied that a PeerConnection would normally not
286 // generate, but a non-JSEP endpoint might.
287 void SetReceivedSdpMunger(
288 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 16:04:20289 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-30 04:08:16290 }
291
deadbeefc964d0b2017-04-03 17:03:35292 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-30 04:08:16293 // generated.
294 void SetGeneratedSdpMunger(
295 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 16:04:20296 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-30 04:08:16297 }
298
Seth Hampson2f0d7022018-02-20 19:54:42299 // Set a callback to be invoked when a remote offer is received via the fake
300 // signaling channel. This provides an opportunity to change the
301 // PeerConnection state before an answer is created and sent to the caller.
302 void SetRemoteOfferHandler(std::function<void()> handler) {
303 remote_offer_handler_ = std::move(handler);
304 }
305
Zach Stein6fcdc2f2018-08-23 23:25:55306 void SetLocalIceCandidateReplacer(
307 std::unique_ptr<IceCandidateReplacerInterface> replacer) {
308 local_ice_candidate_replacer_ = std::move(replacer);
309 }
310
Steve Antonede9ca52017-10-16 20:04:27311 // Every ICE connection state in order that has been seen by the observer.
312 std::vector<PeerConnectionInterface::IceConnectionState>
313 ice_connection_state_history() const {
314 return ice_connection_state_history_;
315 }
Steve Anton6f25b092017-10-23 16:39:20316 void clear_ice_connection_state_history() {
317 ice_connection_state_history_.clear();
318 }
Steve Antonede9ca52017-10-16 20:04:27319
320 // Every ICE gathering state in order that has been seen by the observer.
321 std::vector<PeerConnectionInterface::IceGatheringState>
322 ice_gathering_state_history() const {
323 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-30 04:08:16324 }
325
Steve Anton15324772018-01-16 18:26:49326 void AddAudioVideoTracks() {
327 AddAudioTrack();
328 AddVideoTrack();
deadbeef1dcb1642017-03-30 04:08:16329 }
330
Steve Anton74255ff2018-01-25 02:32:57331 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
332 return AddTrack(CreateLocalAudioTrack());
333 }
deadbeef1dcb1642017-03-30 04:08:16334
Steve Anton74255ff2018-01-25 02:32:57335 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
336 return AddTrack(CreateLocalVideoTrack());
337 }
deadbeef1dcb1642017-03-30 04:08:16338
339 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 09:23:35340 cricket::AudioOptions options;
deadbeef1dcb1642017-03-30 04:08:16341 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 09:23:35342 options.highpass_filter = false;
deadbeef1dcb1642017-03-30 04:08:16343 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 09:23:35344 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-30 04:08:16345 // TODO(perkj): Test audio source when it is implemented. Currently audio
346 // always use the default input.
deadbeefb1a15d72017-09-07 21:12:05347 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-30 04:08:16348 source);
349 }
350
351 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Johannes Kron965e7942018-09-13 13:36:20352 webrtc::FakePeriodicVideoSource::Config config;
353 config.timestamp_offset_ms = rtc::TimeMillis();
354 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-30 04:08:16355 }
356
357 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 08:34:46358 CreateLocalVideoTrackWithConfig(
359 webrtc::FakePeriodicVideoSource::Config config) {
360 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-30 04:08:16361 }
362
363 rtc::scoped_refptr<webrtc::VideoTrackInterface>
364 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 08:34:46365 webrtc::FakePeriodicVideoSource::Config config;
366 config.rotation = rotation;
Johannes Kron965e7942018-09-13 13:36:20367 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 08:34:46368 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-30 04:08:16369 }
370
Steve Anton74255ff2018-01-25 02:32:57371 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
372 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10373 const std::vector<std::string>& stream_ids = {}) {
374 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 18:26:49375 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-25 02:32:57376 return result.MoveValue();
377 }
378
379 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
380 cricket::MediaType media_type) {
381 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
382 for (auto receiver : pc()->GetReceivers()) {
383 if (receiver->media_type() == media_type) {
384 receivers.push_back(receiver);
385 }
386 }
387 return receivers;
deadbeef1dcb1642017-03-30 04:08:16388 }
389
Seth Hampson2f0d7022018-02-20 19:54:42390 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
391 cricket::MediaType media_type) {
392 for (auto transceiver : pc()->GetTransceivers()) {
393 if (transceiver->receiver()->media_type() == media_type) {
394 return transceiver;
395 }
396 }
397 return nullptr;
398 }
399
deadbeef1dcb1642017-03-30 04:08:16400 bool SignalingStateStable() {
401 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
402 }
403
404 void CreateDataChannel() { CreateDataChannel(nullptr); }
405
406 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 18:41:54407 CreateDataChannel(kDataChannelLabel, init);
408 }
409
410 void CreateDataChannel(const std::string& label,
411 const webrtc::DataChannelInit* init) {
412 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-30 04:08:16413 ASSERT_TRUE(data_channel_.get() != nullptr);
414 data_observer_.reset(new MockDataChannelObserver(data_channel_));
415 }
416
417 DataChannelInterface* data_channel() { return data_channel_; }
418 const MockDataChannelObserver* data_observer() const {
419 return data_observer_.get();
420 }
421
422 int audio_frames_received() const {
423 return fake_audio_capture_module_->frames_received();
424 }
425
426 // Takes minimum of video frames received for each track.
427 //
428 // Can be used like:
429 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
430 //
431 // To ensure that all video tracks received at least a certain number of
432 // frames.
433 int min_video_frames_received_per_track() const {
434 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 07:48:06435 if (fake_video_renderers_.empty()) {
436 return 0;
deadbeef1dcb1642017-03-30 04:08:16437 }
deadbeef1dcb1642017-03-30 04:08:16438
Anders Carlsson5f2bb622018-05-14 07:48:06439 for (const auto& pair : fake_video_renderers_) {
440 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-30 04:08:16441 }
Anders Carlsson5f2bb622018-05-14 07:48:06442 return min_frames;
deadbeef1dcb1642017-03-30 04:08:16443 }
444
445 // Returns a MockStatsObserver in a state after stats gathering finished,
446 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 23:01:17447 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-30 04:08:16448 webrtc::MediaStreamTrackInterface* track) {
449 rtc::scoped_refptr<MockStatsObserver> observer(
450 new rtc::RefCountedObject<MockStatsObserver>());
451 EXPECT_TRUE(peer_connection_->GetStats(
452 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
453 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
454 return observer;
455 }
456
457 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 23:01:17458 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
459 return OldGetStatsForTrack(nullptr);
460 }
461
462 // Synchronously gets stats and returns them. If it times out, fails the test
463 // and returns null.
464 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
465 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
466 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
467 peer_connection_->GetStats(callback);
468 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
469 return callback->report();
deadbeef1dcb1642017-03-30 04:08:16470 }
471
472 int rendered_width() {
473 EXPECT_FALSE(fake_video_renderers_.empty());
474 return fake_video_renderers_.empty()
475 ? 0
476 : fake_video_renderers_.begin()->second->width();
477 }
478
479 int rendered_height() {
480 EXPECT_FALSE(fake_video_renderers_.empty());
481 return fake_video_renderers_.empty()
482 ? 0
483 : fake_video_renderers_.begin()->second->height();
484 }
485
486 double rendered_aspect_ratio() {
487 if (rendered_height() == 0) {
488 return 0.0;
489 }
490 return static_cast<double>(rendered_width()) / rendered_height();
491 }
492
493 webrtc::VideoRotation rendered_rotation() {
494 EXPECT_FALSE(fake_video_renderers_.empty());
495 return fake_video_renderers_.empty()
496 ? webrtc::kVideoRotation_0
497 : fake_video_renderers_.begin()->second->rotation();
498 }
499
500 int local_rendered_width() {
501 return local_video_renderer_ ? local_video_renderer_->width() : 0;
502 }
503
504 int local_rendered_height() {
505 return local_video_renderer_ ? local_video_renderer_->height() : 0;
506 }
507
508 double local_rendered_aspect_ratio() {
509 if (local_rendered_height() == 0) {
510 return 0.0;
511 }
512 return static_cast<double>(local_rendered_width()) /
513 local_rendered_height();
514 }
515
516 size_t number_of_remote_streams() {
517 if (!pc()) {
518 return 0;
519 }
520 return pc()->remote_streams()->count();
521 }
522
523 StreamCollectionInterface* remote_streams() const {
524 if (!pc()) {
525 ADD_FAILURE();
526 return nullptr;
527 }
528 return pc()->remote_streams();
529 }
530
531 StreamCollectionInterface* local_streams() {
532 if (!pc()) {
533 ADD_FAILURE();
534 return nullptr;
535 }
536 return pc()->local_streams();
537 }
538
539 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
540 return pc()->signaling_state();
541 }
542
543 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
544 return pc()->ice_connection_state();
545 }
546
547 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
548 return pc()->ice_gathering_state();
549 }
550
551 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
552 // GetReceivers. They're updated automatically when a remote offer/answer
553 // from the fake signaling channel is applied, or when
554 // ResetRtpReceiverObservers below is called.
555 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
556 rtp_receiver_observers() {
557 return rtp_receiver_observers_;
558 }
559
560 void ResetRtpReceiverObservers() {
561 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 16:04:20562 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
563 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-30 04:08:16564 std::unique_ptr<MockRtpReceiverObserver> observer(
565 new MockRtpReceiverObserver(receiver->media_type()));
566 receiver->SetObserver(observer.get());
567 rtp_receiver_observers_.push_back(std::move(observer));
568 }
569 }
570
Steve Antonede9ca52017-10-16 20:04:27571 rtc::FakeNetworkManager* network() const {
572 return fake_network_manager_.get();
573 }
574 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
575
Qingsi Wang7685e862018-06-12 03:15:46576 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
577 return event_log_factory_;
578 }
579
deadbeef1dcb1642017-03-30 04:08:16580 private:
581 explicit PeerConnectionWrapper(const std::string& debug_name)
582 : debug_name_(debug_name) {}
583
Niels Möllerf06f9232018-08-07 10:32:18584 bool Init(const PeerConnectionFactory::Options* options,
Benjamin Wrightd6f86e82018-05-08 20:12:25585 const PeerConnectionInterface::RTCConfiguration* config,
586 webrtc::PeerConnectionDependencies dependencies,
587 rtc::Thread* network_thread,
Qingsi Wang7685e862018-06-12 03:15:46588 rtc::Thread* worker_thread,
589 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
deadbeef1dcb1642017-03-30 04:08:16590 // There's an error in this test code if Init ends up being called twice.
591 RTC_DCHECK(!peer_connection_);
592 RTC_DCHECK(!peer_connection_factory_);
593
594 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 20:04:27595 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-30 04:08:16596
597 std::unique_ptr<cricket::PortAllocator> port_allocator(
598 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 20:04:27599 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-30 04:08:16600 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
601 if (!fake_audio_capture_module_) {
602 return false;
603 }
deadbeef1dcb1642017-03-30 04:08:16604 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-12 03:15:46605
606 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
607 pc_factory_dependencies.network_thread = network_thread;
608 pc_factory_dependencies.worker_thread = worker_thread;
609 pc_factory_dependencies.signaling_thread = signaling_thread;
610 pc_factory_dependencies.media_engine =
611 cricket::WebRtcMediaEngineFactory::Create(
612 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
613 fake_audio_capture_module_),
614 webrtc::CreateBuiltinAudioEncoderFactory(),
615 webrtc::CreateBuiltinAudioDecoderFactory(),
616 webrtc::CreateBuiltinVideoEncoderFactory(),
617 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
618 webrtc::AudioProcessingBuilder().Create());
619 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
620 if (event_log_factory) {
621 event_log_factory_ = event_log_factory.get();
622 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
623 } else {
624 pc_factory_dependencies.event_log_factory =
625 webrtc::CreateRtcEventLogFactory();
626 }
627 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
628 std::move(pc_factory_dependencies));
629
deadbeef1dcb1642017-03-30 04:08:16630 if (!peer_connection_factory_) {
631 return false;
632 }
633 if (options) {
634 peer_connection_factory_->SetOptions(*options);
635 }
Seth Hampson2f0d7022018-02-20 19:54:42636 if (config) {
637 sdp_semantics_ = config->sdp_semantics;
638 }
Benjamin Wrightd6f86e82018-05-08 20:12:25639
640 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 10:32:18641 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-30 04:08:16642 return peer_connection_.get() != nullptr;
643 }
644
645 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-30 04:08:16646 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 20:12:25647 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-30 04:08:16648 PeerConnectionInterface::RTCConfiguration modified_config;
649 // If |config| is null, this will result in a default configuration being
650 // used.
651 if (config) {
652 modified_config = *config;
653 }
654 // Disable resolution adaptation; we don't want it interfering with the
655 // test results.
656 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
657 // ratios and not specific resolutions, is this even necessary?
658 modified_config.set_cpu_adaptation(false);
659
Benjamin Wrightd6f86e82018-05-08 20:12:25660 dependencies.observer = this;
deadbeef1dcb1642017-03-30 04:08:16661 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 20:12:25662 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-30 04:08:16663 }
664
665 void set_signaling_message_receiver(
666 SignalingMessageReceiver* signaling_message_receiver) {
667 signaling_message_receiver_ = signaling_message_receiver;
668 }
669
670 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
671
Steve Antonede9ca52017-10-16 20:04:27672 void set_signal_ice_candidates(bool signal) {
673 signal_ice_candidates_ = signal;
674 }
675
deadbeef1dcb1642017-03-30 04:08:16676 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 08:34:46677 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-30 04:08:16678 // Set max frame rate to 10fps to reduce the risk of test flakiness.
679 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 08:34:46680 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-30 04:08:16681
Niels Möller5c7efe72018-05-11 08:34:46682 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 07:16:41683 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
684 config, false /* remote */));
deadbeef1dcb1642017-03-30 04:08:16685 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 08:34:46686 peer_connection_factory_->CreateVideoTrack(
687 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-30 04:08:16688 if (!local_video_renderer_) {
689 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
690 }
691 return track;
692 }
693
694 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 10:09:25695 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 18:27:41696 std::unique_ptr<SessionDescriptionInterface> desc =
697 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-30 04:08:16698 if (received_sdp_munger_) {
699 received_sdp_munger_(desc->description());
700 }
701
702 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
703 // Setting a remote description may have changed the number of receivers,
704 // so reset the receiver observers.
705 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 19:54:42706 if (remote_offer_handler_) {
707 remote_offer_handler_();
708 }
deadbeef1dcb1642017-03-30 04:08:16709 auto answer = CreateAnswer();
710 ASSERT_NE(nullptr, answer);
711 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
712 }
713
714 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 10:09:25715 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 18:27:41716 std::unique_ptr<SessionDescriptionInterface> desc =
717 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-30 04:08:16718 if (received_sdp_munger_) {
719 received_sdp_munger_(desc->description());
720 }
721
722 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
723 // Set the RtpReceiverObserver after receivers are created.
724 ResetRtpReceiverObservers();
725 }
726
727 // Returns null on failure.
728 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
729 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
730 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
731 pc()->CreateOffer(observer, offer_answer_options_);
732 return WaitForDescriptionFromObserver(observer);
733 }
734
735 // Returns null on failure.
736 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
737 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
738 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
739 pc()->CreateAnswer(observer, offer_answer_options_);
740 return WaitForDescriptionFromObserver(observer);
741 }
742
743 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 16:04:20744 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-30 04:08:16745 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
746 if (!observer->result()) {
747 return nullptr;
748 }
749 auto description = observer->MoveDescription();
750 if (generated_sdp_munger_) {
751 generated_sdp_munger_(description->description());
752 }
753 return description;
754 }
755
756 // Setting the local description and sending the SDP message over the fake
757 // signaling channel are combined into the same method because the SDP
758 // message needs to be sent as soon as SetLocalDescription finishes, without
759 // waiting for the observer to be called. This ensures that ICE candidates
760 // don't outrace the description.
761 bool SetLocalDescriptionAndSendSdpMessage(
762 std::unique_ptr<SessionDescriptionInterface> desc) {
763 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
764 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 10:09:25765 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 18:27:41766 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-30 04:08:16767 std::string sdp;
768 EXPECT_TRUE(desc->ToString(&sdp));
769 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 19:54:42770 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
771 RemoveUnusedVideoRenderers();
772 }
deadbeef1dcb1642017-03-30 04:08:16773 // As mentioned above, we need to send the message immediately after
774 // SetLocalDescription.
775 SendSdpMessage(type, sdp);
776 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
777 return true;
778 }
779
780 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
781 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
782 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 10:09:25783 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-30 04:08:16784 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 19:54:42785 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
786 RemoveUnusedVideoRenderers();
787 }
deadbeef1dcb1642017-03-30 04:08:16788 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
789 return observer->result();
790 }
791
Seth Hampson2f0d7022018-02-20 19:54:42792 // This is a work around to remove unused fake_video_renderers from
793 // transceivers that have either stopped or are no longer receiving.
794 void RemoveUnusedVideoRenderers() {
795 auto transceivers = pc()->GetTransceivers();
796 for (auto& transceiver : transceivers) {
797 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
798 continue;
799 }
800 // Remove fake video renderers from any stopped transceivers.
801 if (transceiver->stopped()) {
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 // Remove fake video renderers from any transceivers that are no longer
809 // receiving.
810 if ((transceiver->current_direction() &&
811 !webrtc::RtpTransceiverDirectionHasRecv(
812 *transceiver->current_direction()))) {
813 auto it =
814 fake_video_renderers_.find(transceiver->receiver()->track()->id());
815 if (it != fake_video_renderers_.end()) {
816 fake_video_renderers_.erase(it);
817 }
818 }
819 }
820 }
821
deadbeef1dcb1642017-03-30 04:08:16822 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
823 // default).
Steve Antona3a92c22017-12-07 18:27:41824 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-30 04:08:16825 if (signaling_delay_ms_ == 0) {
826 RelaySdpMessageIfReceiverExists(type, msg);
827 } else {
828 invoker_.AsyncInvokeDelayed<void>(
829 RTC_FROM_HERE, rtc::Thread::Current(),
830 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
831 this, type, msg),
832 signaling_delay_ms_);
833 }
834 }
835
Steve Antona3a92c22017-12-07 18:27:41836 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-30 04:08:16837 if (signaling_message_receiver_) {
838 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
839 }
840 }
841
842 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
843 // default).
844 void SendIceMessage(const std::string& sdp_mid,
845 int sdp_mline_index,
846 const std::string& msg) {
847 if (signaling_delay_ms_ == 0) {
848 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
849 } else {
850 invoker_.AsyncInvokeDelayed<void>(
851 RTC_FROM_HERE, rtc::Thread::Current(),
852 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
853 this, sdp_mid, sdp_mline_index, msg),
854 signaling_delay_ms_);
855 }
856 }
857
858 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
859 int sdp_mline_index,
860 const std::string& msg) {
861 if (signaling_message_receiver_) {
862 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
863 msg);
864 }
865 }
866
867 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 18:27:41868 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
869 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-30 04:08:16870 HandleIncomingOffer(msg);
871 } else {
872 HandleIncomingAnswer(msg);
873 }
874 }
875
876 void ReceiveIceMessage(const std::string& sdp_mid,
877 int sdp_mline_index,
878 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 10:09:25879 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-30 04:08:16880 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
881 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
882 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
883 }
884
885 // PeerConnectionObserver callbacks.
886 void OnSignalingChange(
887 webrtc::PeerConnectionInterface::SignalingState new_state) override {
888 EXPECT_EQ(pc()->signaling_state(), new_state);
889 }
Steve Anton15324772018-01-16 18:26:49890 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
891 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
892 streams) override {
893 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
894 rtc::scoped_refptr<VideoTrackInterface> video_track(
895 static_cast<VideoTrackInterface*>(receiver->track().get()));
896 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-30 04:08:16897 fake_video_renderers_.end());
Steve Anton15324772018-01-16 18:26:49898 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 09:40:33899 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-30 04:08:16900 }
901 }
Steve Anton15324772018-01-16 18:26:49902 void OnRemoveTrack(
903 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
904 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
905 auto it = fake_video_renderers_.find(receiver->track()->id());
906 RTC_DCHECK(it != fake_video_renderers_.end());
907 fake_video_renderers_.erase(it);
908 }
909 }
deadbeef1dcb1642017-03-30 04:08:16910 void OnRenegotiationNeeded() override {}
911 void OnIceConnectionChange(
912 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
913 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 20:04:27914 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-30 04:08:16915 }
916 void OnIceGatheringChange(
917 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-30 04:08:16918 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 20:04:27919 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-30 04:08:16920 }
Zach Stein6fcdc2f2018-08-23 23:25:55921 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceIceCandidate(
922 const webrtc::IceCandidateInterface* candidate) {
923 std::string candidate_string;
924 candidate->ToString(&candidate_string);
925
926 auto owned_candidate =
927 local_ice_candidate_replacer_->ReplaceCandidate(candidate);
928 if (!owned_candidate) {
929 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer dropped \""
930 << candidate_string << "\"";
931 return nullptr;
932 }
933 std::string owned_candidate_string;
934 owned_candidate->ToString(&owned_candidate_string);
935 RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer changed \""
936 << candidate_string << "\" to \"" << owned_candidate_string
937 << "\"";
938 return owned_candidate;
939 }
deadbeef1dcb1642017-03-30 04:08:16940 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 10:09:25941 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-30 04:08:16942
Zach Stein6fcdc2f2018-08-23 23:25:55943 const webrtc::IceCandidateInterface* new_candidate = candidate;
944 std::unique_ptr<webrtc::IceCandidateInterface> owned_candidate;
945 if (local_ice_candidate_replacer_) {
946 owned_candidate = ReplaceIceCandidate(candidate);
947 if (!owned_candidate) {
948 return; // The candidate was dropped.
949 }
950 new_candidate = owned_candidate.get();
951 }
952
deadbeef1dcb1642017-03-30 04:08:16953 std::string ice_sdp;
Zach Stein6fcdc2f2018-08-23 23:25:55954 EXPECT_TRUE(new_candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 20:04:27955 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-30 04:08:16956 // Remote party may be deleted.
957 return;
958 }
Zach Stein6fcdc2f2018-08-23 23:25:55959 SendIceMessage(new_candidate->sdp_mid(), new_candidate->sdp_mline_index(),
960 ice_sdp);
deadbeef1dcb1642017-03-30 04:08:16961 }
962 void OnDataChannel(
963 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 10:09:25964 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-30 04:08:16965 data_channel_ = data_channel;
966 data_observer_.reset(new MockDataChannelObserver(data_channel));
967 }
968
deadbeef1dcb1642017-03-30 04:08:16969 std::string debug_name_;
970
971 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
972
973 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
974 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
975 peer_connection_factory_;
976
Steve Antonede9ca52017-10-16 20:04:27977 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-30 04:08:16978 // Needed to keep track of number of frames sent.
979 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
980 // Needed to keep track of number of frames received.
981 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
982 fake_video_renderers_;
983 // Needed to ensure frames aren't received for removed tracks.
984 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
985 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-30 04:08:16986
987 // For remote peer communication.
988 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
989 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 20:04:27990 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-30 04:08:16991
Niels Möller5c7efe72018-05-11 08:34:46992 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-30 04:08:16993 // them, if required.
Niels Möller5c7efe72018-05-11 08:34:46994 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
995 video_track_sources_;
deadbeef1dcb1642017-03-30 04:08:16996 // |local_video_renderer_| attached to the first created local video track.
997 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
998
Seth Hampson2f0d7022018-02-20 19:54:42999 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-30 04:08:161000 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1001 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1002 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 19:54:421003 std::function<void()> remote_offer_handler_;
Zach Stein6fcdc2f2018-08-23 23:25:551004 std::unique_ptr<IceCandidateReplacerInterface> local_ice_candidate_replacer_;
deadbeef1dcb1642017-03-30 04:08:161005 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1006 std::unique_ptr<MockDataChannelObserver> data_observer_;
1007
1008 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1009
Steve Antonede9ca52017-10-16 20:04:271010 std::vector<PeerConnectionInterface::IceConnectionState>
1011 ice_connection_state_history_;
1012 std::vector<PeerConnectionInterface::IceGatheringState>
1013 ice_gathering_state_history_;
deadbeef1dcb1642017-03-30 04:08:161014
Qingsi Wang7685e862018-06-12 03:15:461015 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1016
deadbeef1dcb1642017-03-30 04:08:161017 rtc::AsyncInvoker invoker_;
1018
Seth Hampson2f0d7022018-02-20 19:54:421019 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-30 04:08:161020};
1021
Elad Alon99c3fe52017-10-13 14:29:401022class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1023 public:
1024 virtual ~MockRtcEventLogOutput() = default;
1025 MOCK_CONST_METHOD0(IsActive, bool());
1026 MOCK_METHOD1(Write, bool(const std::string&));
1027};
1028
Seth Hampson2f0d7022018-02-20 19:54:421029// This helper object is used for both specifying how many audio/video frames
1030// are expected to be received for a caller/callee. It provides helper functions
1031// to specify these expectations. The object initially starts in a state of no
1032// expectations.
1033class MediaExpectations {
1034 public:
1035 enum ExpectFrames {
1036 kExpectSomeFrames,
1037 kExpectNoFrames,
1038 kNoExpectation,
1039 };
1040
1041 void ExpectBidirectionalAudioAndVideo() {
1042 ExpectBidirectionalAudio();
1043 ExpectBidirectionalVideo();
1044 }
1045
1046 void ExpectBidirectionalAudio() {
1047 CallerExpectsSomeAudio();
1048 CalleeExpectsSomeAudio();
1049 }
1050
1051 void ExpectNoAudio() {
1052 CallerExpectsNoAudio();
1053 CalleeExpectsNoAudio();
1054 }
1055
1056 void ExpectBidirectionalVideo() {
1057 CallerExpectsSomeVideo();
1058 CalleeExpectsSomeVideo();
1059 }
1060
1061 void ExpectNoVideo() {
1062 CallerExpectsNoVideo();
1063 CalleeExpectsNoVideo();
1064 }
1065
1066 void CallerExpectsSomeAudioAndVideo() {
1067 CallerExpectsSomeAudio();
1068 CallerExpectsSomeVideo();
1069 }
1070
1071 void CalleeExpectsSomeAudioAndVideo() {
1072 CalleeExpectsSomeAudio();
1073 CalleeExpectsSomeVideo();
1074 }
1075
1076 // Caller's audio functions.
1077 void CallerExpectsSomeAudio(
1078 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1079 caller_audio_expectation_ = kExpectSomeFrames;
1080 caller_audio_frames_expected_ = expected_audio_frames;
1081 }
1082
1083 void CallerExpectsNoAudio() {
1084 caller_audio_expectation_ = kExpectNoFrames;
1085 caller_audio_frames_expected_ = 0;
1086 }
1087
1088 // Caller's video functions.
1089 void CallerExpectsSomeVideo(
1090 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1091 caller_video_expectation_ = kExpectSomeFrames;
1092 caller_video_frames_expected_ = expected_video_frames;
1093 }
1094
1095 void CallerExpectsNoVideo() {
1096 caller_video_expectation_ = kExpectNoFrames;
1097 caller_video_frames_expected_ = 0;
1098 }
1099
1100 // Callee's audio functions.
1101 void CalleeExpectsSomeAudio(
1102 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1103 callee_audio_expectation_ = kExpectSomeFrames;
1104 callee_audio_frames_expected_ = expected_audio_frames;
1105 }
1106
1107 void CalleeExpectsNoAudio() {
1108 callee_audio_expectation_ = kExpectNoFrames;
1109 callee_audio_frames_expected_ = 0;
1110 }
1111
1112 // Callee's video functions.
1113 void CalleeExpectsSomeVideo(
1114 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1115 callee_video_expectation_ = kExpectSomeFrames;
1116 callee_video_frames_expected_ = expected_video_frames;
1117 }
1118
1119 void CalleeExpectsNoVideo() {
1120 callee_video_expectation_ = kExpectNoFrames;
1121 callee_video_frames_expected_ = 0;
1122 }
1123
1124 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1125 ExpectFrames caller_video_expectation_ = kNoExpectation;
1126 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1127 ExpectFrames callee_video_expectation_ = kNoExpectation;
1128 int caller_audio_frames_expected_ = 0;
1129 int caller_video_frames_expected_ = 0;
1130 int callee_audio_frames_expected_ = 0;
1131 int callee_video_frames_expected_ = 0;
1132};
1133
deadbeef1dcb1642017-03-30 04:08:161134// Tests two PeerConnections connecting to each other end-to-end, using a
1135// virtual network, fake A/V capture and fake encoder/decoders. The
1136// PeerConnections share the threads/socket servers, but use separate versions
1137// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 19:54:421138class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-30 04:08:161139 public:
Seth Hampson2f0d7022018-02-20 19:54:421140 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1141 : sdp_semantics_(sdp_semantics),
1142 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 20:04:271143 fss_(new rtc::FirewallSocketServer(ss_.get())),
1144 network_thread_(new rtc::Thread(fss_.get())),
deadbeef1dcb1642017-03-30 04:08:161145 worker_thread_(rtc::Thread::Create()) {
Sebastian Jansson8a793a02018-03-13 14:21:481146 network_thread_->SetName("PCNetworkThread", this);
1147 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-30 04:08:161148 RTC_CHECK(network_thread_->Start());
1149 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 19:54:531150 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-30 04:08:161151 }
1152
Seth Hampson2f0d7022018-02-20 19:54:421153 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 14:41:321154 // The PeerConnections should deleted before the TurnCustomizers.
1155 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1156 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1157 // that the TurnCustomizer outlives the life of the PeerConnection or else
1158 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-30 04:08:161159 if (caller_) {
1160 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 14:41:321161 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-30 04:08:161162 }
1163 if (callee_) {
1164 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 14:41:321165 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-30 04:08:161166 }
Seth Hampsonaed71642018-06-11 14:41:321167
1168 // If turn servers were created for the test they need to be destroyed on
1169 // the network thread.
1170 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1171 turn_servers_.clear();
1172 turn_customizers_.clear();
1173 });
deadbeef1dcb1642017-03-30 04:08:161174 }
1175
1176 bool SignalingStateStable() {
1177 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1178 }
1179
deadbeef71452802017-05-08 00:21:011180 bool DtlsConnected() {
1181 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1182 // are connected. This is an important distinction. Once we have separate
1183 // ICE and DTLS state, this check needs to use the DTLS state.
1184 return (callee()->ice_connection_state() ==
1185 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1186 callee()->ice_connection_state() ==
1187 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1188 (caller()->ice_connection_state() ==
1189 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1190 caller()->ice_connection_state() ==
1191 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
1192 }
1193
Qingsi Wang7685e862018-06-12 03:15:461194 // When |event_log_factory| is null, the default implementation of the event
1195 // log factory will be used.
Seth Hampson2f0d7022018-02-20 19:54:421196 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1197 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 19:54:421198 const PeerConnectionFactory::Options* options,
1199 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-12 03:15:461200 webrtc::PeerConnectionDependencies dependencies,
1201 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory) {
Seth Hampson2f0d7022018-02-20 19:54:421202 RTCConfiguration modified_config;
1203 if (config) {
1204 modified_config = *config;
1205 }
Steve Anton3acffc32018-04-13 00:21:031206 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 20:12:251207 if (!dependencies.cert_generator) {
1208 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 09:40:331209 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 19:54:421210 }
1211 std::unique_ptr<PeerConnectionWrapper> client(
1212 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 20:12:251213
Niels Möllerf06f9232018-08-07 10:32:181214 if (!client->Init(options, &modified_config, std::move(dependencies),
1215 network_thread_.get(), worker_thread_.get(),
1216 std::move(event_log_factory))) {
Seth Hampson2f0d7022018-02-20 19:54:421217 return nullptr;
1218 }
1219 return client;
1220 }
1221
Qingsi Wang7685e862018-06-12 03:15:461222 std::unique_ptr<PeerConnectionWrapper>
1223 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1224 const std::string& debug_name,
Qingsi Wang7685e862018-06-12 03:15:461225 const PeerConnectionFactory::Options* options,
1226 const RTCConfiguration* config,
1227 webrtc::PeerConnectionDependencies dependencies) {
1228 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1229 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möllerf06f9232018-08-07 10:32:181230 return CreatePeerConnectionWrapper(debug_name, options, config,
Qingsi Wang7685e862018-06-12 03:15:461231 std::move(dependencies),
1232 std::move(event_log_factory));
1233 }
1234
deadbeef1dcb1642017-03-30 04:08:161235 bool CreatePeerConnectionWrappers() {
1236 return CreatePeerConnectionWrappersWithConfig(
1237 PeerConnectionInterface::RTCConfiguration(),
1238 PeerConnectionInterface::RTCConfiguration());
1239 }
1240
Steve Anton3acffc32018-04-13 00:21:031241 bool CreatePeerConnectionWrappersWithSdpSemantics(
1242 SdpSemantics caller_semantics,
1243 SdpSemantics callee_semantics) {
1244 // Can't specify the sdp_semantics in the passed-in configuration since it
1245 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1246 // stored in sdp_semantics_. So get around this by modifying the instance
1247 // variable before calling CreatePeerConnectionWrapper for the caller and
1248 // callee PeerConnections.
1249 SdpSemantics original_semantics = sdp_semantics_;
1250 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 20:12:251251 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181252 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1253 nullptr);
Steve Anton3acffc32018-04-13 00:21:031254 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 20:12:251255 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181256 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
1257 nullptr);
Steve Anton3acffc32018-04-13 00:21:031258 sdp_semantics_ = original_semantics;
1259 return caller_ && callee_;
1260 }
1261
deadbeef1dcb1642017-03-30 04:08:161262 bool CreatePeerConnectionWrappersWithConfig(
1263 const PeerConnectionInterface::RTCConfiguration& caller_config,
1264 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 20:12:251265 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181266 "Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-12 03:15:461267 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251268 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181269 "Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-12 03:15:461270 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251271 return caller_ && callee_;
1272 }
1273
1274 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1275 const PeerConnectionInterface::RTCConfiguration& caller_config,
1276 webrtc::PeerConnectionDependencies caller_dependencies,
1277 const PeerConnectionInterface::RTCConfiguration& callee_config,
1278 webrtc::PeerConnectionDependencies callee_dependencies) {
1279 caller_ =
Niels Möllerf06f9232018-08-07 10:32:181280 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
Qingsi Wang7685e862018-06-12 03:15:461281 std::move(caller_dependencies), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251282 callee_ =
Niels Möllerf06f9232018-08-07 10:32:181283 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
Qingsi Wang7685e862018-06-12 03:15:461284 std::move(callee_dependencies), nullptr);
deadbeef1dcb1642017-03-30 04:08:161285 return caller_ && callee_;
1286 }
1287
1288 bool CreatePeerConnectionWrappersWithOptions(
1289 const PeerConnectionFactory::Options& caller_options,
1290 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 20:12:251291 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181292 "Caller", &caller_options, nullptr,
Qingsi Wang7685e862018-06-12 03:15:461293 webrtc::PeerConnectionDependencies(nullptr), nullptr);
Benjamin Wrightd6f86e82018-05-08 20:12:251294 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 10:32:181295 "Callee", &callee_options, nullptr,
Qingsi Wang7685e862018-06-12 03:15:461296 webrtc::PeerConnectionDependencies(nullptr), nullptr);
1297 return caller_ && callee_;
1298 }
1299
1300 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1301 PeerConnectionInterface::RTCConfiguration default_config;
1302 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 10:32:181303 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-12 03:15:461304 webrtc::PeerConnectionDependencies(nullptr));
1305 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 10:32:181306 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 20:12:251307 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-30 04:08:161308 return caller_ && callee_;
1309 }
1310
Seth Hampson2f0d7022018-02-20 19:54:421311 std::unique_ptr<PeerConnectionWrapper>
1312 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-30 04:08:161313 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1314 new FakeRTCCertificateGenerator());
1315 cert_generator->use_alternate_key();
1316
Benjamin Wrightd6f86e82018-05-08 20:12:251317 webrtc::PeerConnectionDependencies dependencies(nullptr);
1318 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 10:32:181319 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
Qingsi Wang7685e862018-06-12 03:15:461320 std::move(dependencies), nullptr);
deadbeef1dcb1642017-03-30 04:08:161321 }
1322
Seth Hampsonaed71642018-06-11 14:41:321323 cricket::TestTurnServer* CreateTurnServer(
1324 rtc::SocketAddress internal_address,
1325 rtc::SocketAddress external_address,
1326 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1327 const std::string& common_name = "test turn server") {
1328 rtc::Thread* thread = network_thread();
1329 std::unique_ptr<cricket::TestTurnServer> turn_server =
1330 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1331 RTC_FROM_HERE,
1332 [thread, internal_address, external_address, type, common_name] {
Karl Wiberg918f50c2018-07-05 09:40:331333 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 14:41:321334 thread, internal_address, external_address, type,
1335 /*ignore_bad_certs=*/true, common_name);
1336 });
1337 turn_servers_.push_back(std::move(turn_server));
1338 // Interactions with the turn server should be done on the network thread.
1339 return turn_servers_.back().get();
1340 }
1341
1342 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1343 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1344 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1345 RTC_FROM_HERE,
Karl Wiberg918f50c2018-07-05 09:40:331346 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 14:41:321347 turn_customizers_.push_back(std::move(turn_customizer));
1348 // Interactions with the turn customizer should be done on the network
1349 // thread.
1350 return turn_customizers_.back().get();
1351 }
1352
1353 // Checks that the function counters for a TestTurnCustomizer are greater than
1354 // 0.
1355 void ExpectTurnCustomizerCountersIncremented(
1356 cricket::TestTurnCustomizer* turn_customizer) {
1357 unsigned int allow_channel_data_counter =
1358 network_thread()->Invoke<unsigned int>(
1359 RTC_FROM_HERE, [turn_customizer] {
1360 return turn_customizer->allow_channel_data_cnt_;
1361 });
1362 EXPECT_GT(allow_channel_data_counter, 0u);
1363 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1364 RTC_FROM_HERE,
1365 [turn_customizer] { return turn_customizer->modify_cnt_; });
1366 EXPECT_GT(modify_counter, 0u);
1367 }
1368
deadbeef1dcb1642017-03-30 04:08:161369 // Once called, SDP blobs and ICE candidates will be automatically signaled
1370 // between PeerConnections.
1371 void ConnectFakeSignaling() {
1372 caller_->set_signaling_message_receiver(callee_.get());
1373 callee_->set_signaling_message_receiver(caller_.get());
1374 }
1375
Steve Antonede9ca52017-10-16 20:04:271376 // Once called, SDP blobs will be automatically signaled between
1377 // PeerConnections. Note that ICE candidates will not be signaled unless they
1378 // are in the exchanged SDP blobs.
1379 void ConnectFakeSignalingForSdpOnly() {
1380 ConnectFakeSignaling();
1381 SetSignalIceCandidates(false);
1382 }
1383
deadbeef1dcb1642017-03-30 04:08:161384 void SetSignalingDelayMs(int delay_ms) {
1385 caller_->set_signaling_delay_ms(delay_ms);
1386 callee_->set_signaling_delay_ms(delay_ms);
1387 }
1388
Steve Antonede9ca52017-10-16 20:04:271389 void SetSignalIceCandidates(bool signal) {
1390 caller_->set_signal_ice_candidates(signal);
1391 callee_->set_signal_ice_candidates(signal);
1392 }
1393
deadbeef1dcb1642017-03-30 04:08:161394 // Messages may get lost on the unreliable DataChannel, so we send multiple
1395 // times to avoid test flakiness.
1396 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1397 const std::string& data,
1398 int retries) {
1399 for (int i = 0; i < retries; ++i) {
1400 dc->Send(DataBuffer(data));
1401 }
1402 }
1403
1404 rtc::Thread* network_thread() { return network_thread_.get(); }
1405
1406 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1407
1408 PeerConnectionWrapper* caller() { return caller_.get(); }
1409
1410 // Set the |caller_| to the |wrapper| passed in and return the
1411 // original |caller_|.
1412 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1413 PeerConnectionWrapper* wrapper) {
1414 PeerConnectionWrapper* old = caller_.release();
1415 caller_.reset(wrapper);
1416 return old;
1417 }
1418
1419 PeerConnectionWrapper* callee() { return callee_.get(); }
1420
1421 // Set the |callee_| to the |wrapper| passed in and return the
1422 // original |callee_|.
1423 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1424 PeerConnectionWrapper* wrapper) {
1425 PeerConnectionWrapper* old = callee_.release();
1426 callee_.reset(wrapper);
1427 return old;
1428 }
1429
Steve Antonede9ca52017-10-16 20:04:271430 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1431
Seth Hampson2f0d7022018-02-20 19:54:421432 // Expects the provided number of new frames to be received within
1433 // kMaxWaitForFramesMs. The new expected frames are specified in
1434 // |media_expectations|. Returns false if any of the expectations were
1435 // not met.
1436 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1437 // First initialize the expected frame counts based upon the current
1438 // frame count.
1439 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1440 if (media_expectations.caller_audio_expectation_ ==
1441 MediaExpectations::kExpectSomeFrames) {
1442 total_caller_audio_frames_expected +=
1443 media_expectations.caller_audio_frames_expected_;
1444 }
1445 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-30 04:08:161446 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 19:54:421447 if (media_expectations.caller_video_expectation_ ==
1448 MediaExpectations::kExpectSomeFrames) {
1449 total_caller_video_frames_expected +=
1450 media_expectations.caller_video_frames_expected_;
1451 }
1452 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1453 if (media_expectations.callee_audio_expectation_ ==
1454 MediaExpectations::kExpectSomeFrames) {
1455 total_callee_audio_frames_expected +=
1456 media_expectations.callee_audio_frames_expected_;
1457 }
1458 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-30 04:08:161459 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 19:54:421460 if (media_expectations.callee_video_expectation_ ==
1461 MediaExpectations::kExpectSomeFrames) {
1462 total_callee_video_frames_expected +=
1463 media_expectations.callee_video_frames_expected_;
1464 }
deadbeef1dcb1642017-03-30 04:08:161465
Seth Hampson2f0d7022018-02-20 19:54:421466 // Wait for the expected frames.
deadbeef1dcb1642017-03-30 04:08:161467 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 19:54:421468 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-30 04:08:161469 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 19:54:421470 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-30 04:08:161471 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 19:54:421472 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-30 04:08:161473 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 19:54:421474 total_callee_video_frames_expected,
1475 kMaxWaitForFramesMs);
1476 bool expectations_correct =
1477 caller()->audio_frames_received() >=
1478 total_caller_audio_frames_expected &&
1479 caller()->min_video_frames_received_per_track() >=
1480 total_caller_video_frames_expected &&
1481 callee()->audio_frames_received() >=
1482 total_callee_audio_frames_expected &&
1483 callee()->min_video_frames_received_per_track() >=
1484 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-30 04:08:161485
Seth Hampson2f0d7022018-02-20 19:54:421486 // After the combined wait, print out a more detailed message upon
1487 // failure.
deadbeef1dcb1642017-03-30 04:08:161488 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 19:54:421489 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-30 04:08:161490 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 19:54:421491 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-30 04:08:161492 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 19:54:421493 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-30 04:08:161494 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 19:54:421495 total_callee_video_frames_expected);
1496
1497 // We want to make sure nothing unexpected was received.
1498 if (media_expectations.caller_audio_expectation_ ==
1499 MediaExpectations::kExpectNoFrames) {
1500 EXPECT_EQ(caller()->audio_frames_received(),
1501 total_caller_audio_frames_expected);
1502 if (caller()->audio_frames_received() !=
1503 total_caller_audio_frames_expected) {
1504 expectations_correct = false;
1505 }
1506 }
1507 if (media_expectations.caller_video_expectation_ ==
1508 MediaExpectations::kExpectNoFrames) {
1509 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1510 total_caller_video_frames_expected);
1511 if (caller()->min_video_frames_received_per_track() !=
1512 total_caller_video_frames_expected) {
1513 expectations_correct = false;
1514 }
1515 }
1516 if (media_expectations.callee_audio_expectation_ ==
1517 MediaExpectations::kExpectNoFrames) {
1518 EXPECT_EQ(callee()->audio_frames_received(),
1519 total_callee_audio_frames_expected);
1520 if (callee()->audio_frames_received() !=
1521 total_callee_audio_frames_expected) {
1522 expectations_correct = false;
1523 }
1524 }
1525 if (media_expectations.callee_video_expectation_ ==
1526 MediaExpectations::kExpectNoFrames) {
1527 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1528 total_callee_video_frames_expected);
1529 if (callee()->min_video_frames_received_per_track() !=
1530 total_callee_video_frames_expected) {
1531 expectations_correct = false;
1532 }
1533 }
1534 return expectations_correct;
deadbeef1dcb1642017-03-30 04:08:161535 }
1536
Taylor Brandstetter5e55fe82018-03-23 18:50:161537 void TestNegotiatedCipherSuite(
1538 const PeerConnectionFactory::Options& caller_options,
1539 const PeerConnectionFactory::Options& callee_options,
1540 int expected_cipher_suite) {
deadbeef1dcb1642017-03-30 04:08:161541 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1542 callee_options));
deadbeef1dcb1642017-03-30 04:08:161543 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491544 caller()->AddAudioVideoTracks();
1545 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161546 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 19:54:531547 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:161548 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 23:01:171549 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 19:54:531550 // TODO(bugs.webrtc.org/9456): Fix it.
1551 EXPECT_EQ(1, webrtc::metrics::NumEvents(
1552 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1553 expected_cipher_suite));
deadbeef1dcb1642017-03-30 04:08:161554 }
1555
Taylor Brandstetter5e55fe82018-03-23 18:50:161556 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1557 bool remote_gcm_enabled,
1558 int expected_cipher_suite) {
1559 PeerConnectionFactory::Options caller_options;
1560 caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
1561 PeerConnectionFactory::Options callee_options;
1562 callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
1563 TestNegotiatedCipherSuite(caller_options, callee_options,
1564 expected_cipher_suite);
1565 }
1566
Seth Hampson2f0d7022018-02-20 19:54:421567 protected:
Steve Anton3acffc32018-04-13 00:21:031568 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 19:54:421569
deadbeef1dcb1642017-03-30 04:08:161570 private:
1571 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-30 04:08:161572 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 20:04:271573 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-30 04:08:161574 // |network_thread_| and |worker_thread_| are used by both
1575 // |caller_| and |callee_| so they must be destroyed
1576 // later.
1577 std::unique_ptr<rtc::Thread> network_thread_;
1578 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 14:41:321579 // The turn servers and turn customizers should be accessed & deleted on the
1580 // network thread to avoid a race with the socket read/write that occurs
1581 // on the network thread.
1582 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1583 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
deadbeef1dcb1642017-03-30 04:08:161584 std::unique_ptr<PeerConnectionWrapper> caller_;
1585 std::unique_ptr<PeerConnectionWrapper> callee_;
1586};
1587
Seth Hampson2f0d7022018-02-20 19:54:421588class PeerConnectionIntegrationTest
1589 : public PeerConnectionIntegrationBaseTest,
1590 public ::testing::WithParamInterface<SdpSemantics> {
1591 protected:
1592 PeerConnectionIntegrationTest()
1593 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1594};
1595
1596class PeerConnectionIntegrationTestPlanB
1597 : public PeerConnectionIntegrationBaseTest {
1598 protected:
1599 PeerConnectionIntegrationTestPlanB()
1600 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1601};
1602
1603class PeerConnectionIntegrationTestUnifiedPlan
1604 : public PeerConnectionIntegrationBaseTest {
1605 protected:
1606 PeerConnectionIntegrationTestUnifiedPlan()
1607 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1608};
1609
deadbeef1dcb1642017-03-30 04:08:161610// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1611// includes testing that the callback is invoked if an observer is connected
1612// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 19:54:421613TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:161614 RtpReceiverObserverOnFirstPacketReceived) {
1615 ASSERT_TRUE(CreatePeerConnectionWrappers());
1616 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491617 caller()->AddAudioVideoTracks();
1618 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161619 // Start offer/answer exchange and wait for it to complete.
1620 caller()->CreateAndSetAndSignalOffer();
1621 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1622 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 10:53:231623 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1624 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-30 04:08:161625 // Wait for all "first packet received" callbacks to be fired.
1626 EXPECT_TRUE_WAIT(
1627 std::all_of(caller()->rtp_receiver_observers().begin(),
1628 caller()->rtp_receiver_observers().end(),
1629 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1630 return o->first_packet_received();
1631 }),
1632 kMaxWaitForFramesMs);
1633 EXPECT_TRUE_WAIT(
1634 std::all_of(callee()->rtp_receiver_observers().begin(),
1635 callee()->rtp_receiver_observers().end(),
1636 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1637 return o->first_packet_received();
1638 }),
1639 kMaxWaitForFramesMs);
1640 // If new observers are set after the first packet was already received, the
1641 // callback should still be invoked.
1642 caller()->ResetRtpReceiverObservers();
1643 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 10:53:231644 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1645 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-30 04:08:161646 EXPECT_TRUE(
1647 std::all_of(caller()->rtp_receiver_observers().begin(),
1648 caller()->rtp_receiver_observers().end(),
1649 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1650 return o->first_packet_received();
1651 }));
1652 EXPECT_TRUE(
1653 std::all_of(callee()->rtp_receiver_observers().begin(),
1654 callee()->rtp_receiver_observers().end(),
1655 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1656 return o->first_packet_received();
1657 }));
1658}
1659
1660class DummyDtmfObserver : public DtmfSenderObserverInterface {
1661 public:
1662 DummyDtmfObserver() : completed_(false) {}
1663
1664 // Implements DtmfSenderObserverInterface.
1665 void OnToneChange(const std::string& tone) override {
1666 tones_.push_back(tone);
1667 if (tone.empty()) {
1668 completed_ = true;
1669 }
1670 }
1671
1672 const std::vector<std::string>& tones() const { return tones_; }
1673 bool completed() const { return completed_; }
1674
1675 private:
1676 bool completed_;
1677 std::vector<std::string> tones_;
1678};
1679
1680// Assumes |sender| already has an audio track added and the offer/answer
1681// exchange is done.
1682void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1683 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 18:26:491684 // We should be able to get a DTMF sender from the local sender.
1685 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1686 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1687 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-30 04:08:161688 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-30 04:08:161689 dtmf_sender->RegisterObserver(&observer);
1690
1691 // Test the DtmfSender object just created.
1692 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1693 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1694
1695 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1696 std::vector<std::string> tones = {"1", "a", ""};
1697 EXPECT_EQ(tones, observer.tones());
1698 dtmf_sender->UnregisterObserver();
1699 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1700}
1701
1702// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1703// direction).
Seth Hampson2f0d7022018-02-20 19:54:421704TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-30 04:08:161705 ASSERT_TRUE(CreatePeerConnectionWrappers());
1706 ConnectFakeSignaling();
1707 // Only need audio for DTMF.
Steve Anton15324772018-01-16 18:26:491708 caller()->AddAudioTrack();
1709 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-30 04:08:161710 caller()->CreateAndSetAndSignalOffer();
1711 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-08 00:21:011712 // DTLS must finish before the DTMF sender can be used reliably.
1713 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:161714 TestDtmfFromSenderToReceiver(caller(), callee());
1715 TestDtmfFromSenderToReceiver(callee(), caller());
1716}
1717
1718// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1719// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 19:54:421720TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-30 04:08:161721 ASSERT_TRUE(CreatePeerConnectionWrappers());
1722 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 15:04:131723
deadbeef1dcb1642017-03-30 04:08:161724 // Do normal offer/answer and wait for some frames to be received in each
1725 // direction.
Steve Anton15324772018-01-16 18:26:491726 caller()->AddAudioVideoTracks();
1727 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161728 caller()->CreateAndSetAndSignalOffer();
1729 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421730 MediaExpectations media_expectations;
1731 media_expectations.ExpectBidirectionalAudioAndVideo();
1732 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 19:54:531733 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1734 webrtc::kEnumCounterKeyProtocolDtls));
1735 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1736 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-30 04:08:161737}
1738
1739// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 19:54:421740TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-30 04:08:161741 PeerConnectionInterface::RTCConfiguration sdes_config;
1742 sdes_config.enable_dtls_srtp.emplace(false);
1743 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1744 ConnectFakeSignaling();
1745
1746 // Do normal offer/answer and wait for some frames to be received in each
1747 // direction.
Steve Anton15324772018-01-16 18:26:491748 caller()->AddAudioVideoTracks();
1749 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161750 caller()->CreateAndSetAndSignalOffer();
1751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421752 MediaExpectations media_expectations;
1753 media_expectations.ExpectBidirectionalAudioAndVideo();
1754 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 19:54:531755 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1756 webrtc::kEnumCounterKeyProtocolSdes));
1757 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1758 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-30 04:08:161759}
1760
Steve Anton8c0f7a72017-10-03 17:03:101761// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1762// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 19:54:421763TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 17:03:101764 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1765 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1766 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1767 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1768 return pc->GetRemoteAudioSSLCertificate();
1769 };
Zhi Huang70b820f2018-01-27 22:16:151770 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1771 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1772 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1773 return pc->GetRemoteAudioSSLCertChain();
1774 };
Steve Anton8c0f7a72017-10-03 17:03:101775
1776 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1777 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1778
1779 // Configure each side with a known certificate so they can be compared later.
1780 PeerConnectionInterface::RTCConfiguration caller_config;
1781 caller_config.enable_dtls_srtp.emplace(true);
1782 caller_config.certificates.push_back(caller_cert);
1783 PeerConnectionInterface::RTCConfiguration callee_config;
1784 callee_config.enable_dtls_srtp.emplace(true);
1785 callee_config.certificates.push_back(callee_cert);
1786 ASSERT_TRUE(
1787 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1788 ConnectFakeSignaling();
1789
1790 // When first initialized, there should not be a remote SSL certificate (and
1791 // calling this method should not crash).
1792 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1793 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 22:16:151794 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1795 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 17:03:101796
Steve Anton15324772018-01-16 18:26:491797 caller()->AddAudioTrack();
1798 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 17:03:101799 caller()->CreateAndSetAndSignalOffer();
1800 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1801 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1802
1803 // Once DTLS has been connected, each side should return the other's SSL
1804 // certificate when calling GetRemoteAudioSSLCertificate.
1805
1806 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1807 ASSERT_TRUE(caller_remote_cert);
1808 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1809 caller_remote_cert->ToPEMString());
1810
1811 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1812 ASSERT_TRUE(callee_remote_cert);
1813 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1814 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 22:16:151815
1816 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1817 ASSERT_TRUE(caller_remote_cert_chain);
1818 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1819 auto remote_cert = &caller_remote_cert_chain->Get(0);
1820 EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
1821 remote_cert->ToPEMString());
1822
1823 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1824 ASSERT_TRUE(callee_remote_cert_chain);
1825 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1826 remote_cert = &callee_remote_cert_chain->Get(0);
1827 EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
1828 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 17:03:101829}
1830
deadbeef1dcb1642017-03-30 04:08:161831// This test sets up a call between two parties with a source resolution of
1832// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 19:54:421833TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:161834 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1835 ASSERT_TRUE(CreatePeerConnectionWrappers());
1836 ConnectFakeSignaling();
1837
Niels Möller5c7efe72018-05-11 08:34:461838 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1839 webrtc::FakePeriodicVideoSource::Config config;
1840 config.width = 1280;
1841 config.height = 720;
Johannes Kron965e7942018-09-13 13:36:201842 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 08:34:461843 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1844 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-30 04:08:161845
1846 // Do normal offer/answer and wait for at least one frame to be received in
1847 // each direction.
1848 caller()->CreateAndSetAndSignalOffer();
1849 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1850 callee()->min_video_frames_received_per_track() > 0,
1851 kMaxWaitForFramesMs);
1852
1853 // Check rendered aspect ratio.
1854 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1855 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1856 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1857 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1858}
1859
1860// This test sets up an one-way call, with media only from caller to
1861// callee.
Seth Hampson2f0d7022018-02-20 19:54:421862TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-30 04:08:161863 ASSERT_TRUE(CreatePeerConnectionWrappers());
1864 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491865 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161866 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 19:54:421867 MediaExpectations media_expectations;
1868 media_expectations.CalleeExpectsSomeAudioAndVideo();
1869 media_expectations.CallerExpectsNoAudio();
1870 media_expectations.CallerExpectsNoVideo();
1871 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:161872}
1873
1874// This test sets up a audio call initially, with the callee rejecting video
1875// initially. Then later the callee decides to upgrade to audio/video, and
1876// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 19:54:421877TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-30 04:08:161878 ASSERT_TRUE(CreatePeerConnectionWrappers());
1879 ConnectFakeSignaling();
1880 // Initially, offer an audio/video stream from the caller, but refuse to
1881 // send/receive video on the callee side.
Steve Anton15324772018-01-16 18:26:491882 caller()->AddAudioVideoTracks();
1883 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 19:54:421884 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1885 PeerConnectionInterface::RTCOfferAnswerOptions options;
1886 options.offer_to_receive_video = 0;
1887 callee()->SetOfferAnswerOptions(options);
1888 } else {
1889 callee()->SetRemoteOfferHandler([this] {
1890 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1891 });
1892 }
deadbeef1dcb1642017-03-30 04:08:161893 // Do offer/answer and make sure audio is still received end-to-end.
1894 caller()->CreateAndSetAndSignalOffer();
1895 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421896 {
1897 MediaExpectations media_expectations;
1898 media_expectations.ExpectBidirectionalAudio();
1899 media_expectations.ExpectNoVideo();
1900 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1901 }
deadbeef1dcb1642017-03-30 04:08:161902 // Sanity check that the callee's description has a rejected video section.
1903 ASSERT_NE(nullptr, callee()->pc()->local_description());
1904 const ContentInfo* callee_video_content =
1905 GetFirstVideoContent(callee()->pc()->local_description()->description());
1906 ASSERT_NE(nullptr, callee_video_content);
1907 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 19:54:421908
deadbeef1dcb1642017-03-30 04:08:161909 // Now negotiate with video and ensure negotiation succeeds, with video
1910 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 18:26:491911 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 19:54:421912 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1913 PeerConnectionInterface::RTCOfferAnswerOptions options;
1914 options.offer_to_receive_video = 1;
1915 callee()->SetOfferAnswerOptions(options);
1916 } else {
1917 callee()->SetRemoteOfferHandler(nullptr);
1918 caller()->SetRemoteOfferHandler([this] {
1919 // The caller creates a new transceiver to receive video on when receiving
1920 // the offer, but by default it is send only.
1921 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 10:53:231922 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 19:54:421923 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1924 transceivers[2]->receiver()->media_type());
1925 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1926 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1927 });
1928 }
deadbeef1dcb1642017-03-30 04:08:161929 callee()->CreateAndSetAndSignalOffer();
1930 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:421931 {
1932 // Expect additional audio frames to be received after the upgrade.
1933 MediaExpectations media_expectations;
1934 media_expectations.ExpectBidirectionalAudioAndVideo();
1935 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1936 }
deadbeef1dcb1642017-03-30 04:08:161937}
1938
deadbeef4389b4d2017-09-07 16:07:361939// Simpler than the above test; just add an audio track to an established
1940// video-only connection.
Seth Hampson2f0d7022018-02-20 19:54:421941TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 16:07:361942 ASSERT_TRUE(CreatePeerConnectionWrappers());
1943 ConnectFakeSignaling();
1944 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 18:26:491945 caller()->AddVideoTrack();
1946 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 16:07:361947 caller()->CreateAndSetAndSignalOffer();
1948 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1949 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 18:26:491950 caller()->AddAudioTrack();
1951 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 16:07:361952 caller()->CreateAndSetAndSignalOffer();
1953 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1954 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:421955 MediaExpectations media_expectations;
1956 media_expectations.ExpectBidirectionalAudioAndVideo();
1957 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 16:07:361958}
1959
deadbeef1dcb1642017-03-30 04:08:161960// This test sets up a call that's transferred to a new caller with a different
1961// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 19:54:421962TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-30 04:08:161963 ASSERT_TRUE(CreatePeerConnectionWrappers());
1964 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491965 caller()->AddAudioVideoTracks();
1966 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161967 caller()->CreateAndSetAndSignalOffer();
1968 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1969
1970 // Keep the original peer around which will still send packets to the
1971 // receiving client. These SRTP packets will be dropped.
1972 std::unique_ptr<PeerConnectionWrapper> original_peer(
1973 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 19:54:421974 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-30 04:08:161975 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1976 // directly above.
1977 original_peer->pc()->Close();
1978
1979 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491980 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161981 caller()->CreateAndSetAndSignalOffer();
1982 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1983 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:421984 MediaExpectations media_expectations;
1985 media_expectations.ExpectBidirectionalAudioAndVideo();
1986 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:161987}
1988
1989// This test sets up a call that's transferred to a new callee with a different
1990// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 19:54:421991TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-30 04:08:161992 ASSERT_TRUE(CreatePeerConnectionWrappers());
1993 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:491994 caller()->AddAudioVideoTracks();
1995 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:161996 caller()->CreateAndSetAndSignalOffer();
1997 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1998
1999 // Keep the original peer around which will still send packets to the
2000 // receiving client. These SRTP packets will be dropped.
2001 std::unique_ptr<PeerConnectionWrapper> original_peer(
2002 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 19:54:422003 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-30 04:08:162004 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2005 // directly above.
2006 original_peer->pc()->Close();
2007
2008 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492009 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162010 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2011 caller()->CreateAndSetAndSignalOffer();
2012 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2013 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:422014 MediaExpectations media_expectations;
2015 media_expectations.ExpectBidirectionalAudioAndVideo();
2016 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162017}
2018
2019// This test sets up a non-bundled call and negotiates bundling at the same
2020// time as starting an ICE restart. When bundling is in effect in the restart,
2021// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 19:54:422022TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-30 04:08:162023 ASSERT_TRUE(CreatePeerConnectionWrappers());
2024 ConnectFakeSignaling();
2025
Steve Anton15324772018-01-16 18:26:492026 caller()->AddAudioVideoTracks();
2027 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162028 // Remove the bundle group from the SDP received by the callee.
2029 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2030 desc->RemoveGroupByName("BUNDLE");
2031 });
2032 caller()->CreateAndSetAndSignalOffer();
2033 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422034 {
2035 MediaExpectations media_expectations;
2036 media_expectations.ExpectBidirectionalAudioAndVideo();
2037 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2038 }
deadbeef1dcb1642017-03-30 04:08:162039 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2040 callee()->SetReceivedSdpMunger(nullptr);
2041 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2042 caller()->CreateAndSetAndSignalOffer();
2043 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2044
2045 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 19:54:422046 {
2047 MediaExpectations media_expectations;
2048 media_expectations.ExpectBidirectionalAudioAndVideo();
2049 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2050 }
deadbeef1dcb1642017-03-30 04:08:162051}
2052
2053// Test CVO (Coordination of Video Orientation). If a video source is rotated
2054// and both peers support the CVO RTP header extension, the actual video frames
2055// don't need to be encoded in different resolutions, since the rotation is
2056// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 19:54:422057TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-30 04:08:162058 ASSERT_TRUE(CreatePeerConnectionWrappers());
2059 ConnectFakeSignaling();
2060 // Add rotated video tracks.
Steve Anton15324772018-01-16 18:26:492061 caller()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162062 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 18:26:492063 callee()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162064 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2065
2066 // Wait for video frames to be received by both sides.
2067 caller()->CreateAndSetAndSignalOffer();
2068 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2069 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2070 callee()->min_video_frames_received_per_track() > 0,
2071 kMaxWaitForFramesMs);
2072
2073 // Ensure that the aspect ratio is unmodified.
2074 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2075 // not just assumed.
2076 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2077 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2078 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2079 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2080 // Ensure that the CVO bits were surfaced to the renderer.
2081 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2082 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2083}
2084
2085// Test that when the CVO extension isn't supported, video is rotated the
2086// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 19:54:422087TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-30 04:08:162088 ASSERT_TRUE(CreatePeerConnectionWrappers());
2089 ConnectFakeSignaling();
2090 // Add rotated video tracks.
Steve Anton15324772018-01-16 18:26:492091 caller()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162092 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 18:26:492093 callee()->AddTrack(
deadbeef1dcb1642017-03-30 04:08:162094 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2095
2096 // Remove the CVO extension from the offered SDP.
2097 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2098 cricket::VideoContentDescription* video =
2099 GetFirstVideoContentDescription(desc);
2100 video->ClearRtpHeaderExtensions();
2101 });
2102 // Wait for video frames to be received by both sides.
2103 caller()->CreateAndSetAndSignalOffer();
2104 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2105 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2106 callee()->min_video_frames_received_per_track() > 0,
2107 kMaxWaitForFramesMs);
2108
2109 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2110 // rotation.
2111 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2112 // not just assumed.
2113 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2114 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2115 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2116 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2117 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2118 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2119 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2120}
2121
deadbeef1dcb1642017-03-30 04:08:162122// Test that if the answerer rejects the audio m= section, no audio is sent or
2123// received, but video still can be.
Seth Hampson2f0d7022018-02-20 19:54:422124TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-30 04:08:162125 ASSERT_TRUE(CreatePeerConnectionWrappers());
2126 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492127 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 19:54:422128 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2129 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2130 // it will reject the audio m= section completely.
2131 PeerConnectionInterface::RTCOfferAnswerOptions options;
2132 options.offer_to_receive_audio = 0;
2133 callee()->SetOfferAnswerOptions(options);
2134 } else {
2135 // Stopping the audio RtpTransceiver will cause the media section to be
2136 // rejected in the answer.
2137 callee()->SetRemoteOfferHandler([this] {
2138 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2139 });
2140 }
Steve Anton15324772018-01-16 18:26:492141 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-30 04:08:162142 // Do offer/answer and wait for successful end-to-end video frames.
2143 caller()->CreateAndSetAndSignalOffer();
2144 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422145 MediaExpectations media_expectations;
2146 media_expectations.ExpectBidirectionalVideo();
2147 media_expectations.ExpectNoAudio();
2148 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2149
deadbeef1dcb1642017-03-30 04:08:162150 // Sanity check that the callee's description has a rejected audio section.
2151 ASSERT_NE(nullptr, callee()->pc()->local_description());
2152 const ContentInfo* callee_audio_content =
2153 GetFirstAudioContent(callee()->pc()->local_description()->description());
2154 ASSERT_NE(nullptr, callee_audio_content);
2155 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 19:54:422156 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2157 // The caller's transceiver should have stopped after receiving the answer.
2158 EXPECT_TRUE(caller()
2159 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2160 ->stopped());
2161 }
deadbeef1dcb1642017-03-30 04:08:162162}
2163
2164// Test that if the answerer rejects the video m= section, no video is sent or
2165// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 19:54:422166TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-30 04:08:162167 ASSERT_TRUE(CreatePeerConnectionWrappers());
2168 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492169 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 19:54:422170 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2171 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2172 // it will reject the video m= section completely.
2173 PeerConnectionInterface::RTCOfferAnswerOptions options;
2174 options.offer_to_receive_video = 0;
2175 callee()->SetOfferAnswerOptions(options);
2176 } else {
2177 // Stopping the video RtpTransceiver will cause the media section to be
2178 // rejected in the answer.
2179 callee()->SetRemoteOfferHandler([this] {
2180 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2181 });
2182 }
Steve Anton15324772018-01-16 18:26:492183 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-30 04:08:162184 // Do offer/answer and wait for successful end-to-end audio frames.
2185 caller()->CreateAndSetAndSignalOffer();
2186 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422187 MediaExpectations media_expectations;
2188 media_expectations.ExpectBidirectionalAudio();
2189 media_expectations.ExpectNoVideo();
2190 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2191
deadbeef1dcb1642017-03-30 04:08:162192 // Sanity check that the callee's description has a rejected video section.
2193 ASSERT_NE(nullptr, callee()->pc()->local_description());
2194 const ContentInfo* callee_video_content =
2195 GetFirstVideoContent(callee()->pc()->local_description()->description());
2196 ASSERT_NE(nullptr, callee_video_content);
2197 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 19:54:422198 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2199 // The caller's transceiver should have stopped after receiving the answer.
2200 EXPECT_TRUE(caller()
2201 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2202 ->stopped());
2203 }
deadbeef1dcb1642017-03-30 04:08:162204}
2205
2206// Test that if the answerer rejects both audio and video m= sections, nothing
2207// bad happens.
2208// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2209// test anything but the fact that negotiation succeeds, which doesn't mean
2210// much.
Seth Hampson2f0d7022018-02-20 19:54:422211TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-30 04:08:162212 ASSERT_TRUE(CreatePeerConnectionWrappers());
2213 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492214 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 19:54:422215 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2216 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2217 // will reject both audio and video m= sections.
2218 PeerConnectionInterface::RTCOfferAnswerOptions options;
2219 options.offer_to_receive_audio = 0;
2220 options.offer_to_receive_video = 0;
2221 callee()->SetOfferAnswerOptions(options);
2222 } else {
2223 callee()->SetRemoteOfferHandler([this] {
2224 // Stopping all transceivers will cause all media sections to be rejected.
2225 for (auto transceiver : callee()->pc()->GetTransceivers()) {
2226 transceiver->Stop();
2227 }
2228 });
2229 }
deadbeef1dcb1642017-03-30 04:08:162230 // Do offer/answer and wait for stable signaling state.
2231 caller()->CreateAndSetAndSignalOffer();
2232 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422233
deadbeef1dcb1642017-03-30 04:08:162234 // Sanity check that the callee's description has rejected m= sections.
2235 ASSERT_NE(nullptr, callee()->pc()->local_description());
2236 const ContentInfo* callee_audio_content =
2237 GetFirstAudioContent(callee()->pc()->local_description()->description());
2238 ASSERT_NE(nullptr, callee_audio_content);
2239 EXPECT_TRUE(callee_audio_content->rejected);
2240 const ContentInfo* callee_video_content =
2241 GetFirstVideoContent(callee()->pc()->local_description()->description());
2242 ASSERT_NE(nullptr, callee_video_content);
2243 EXPECT_TRUE(callee_video_content->rejected);
2244}
2245
2246// This test sets up an audio and video call between two parties. After the
2247// call runs for a while, the caller sends an updated offer with video being
2248// rejected. Once the re-negotiation is done, the video flow should stop and
2249// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 19:54:422250TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-30 04:08:162251 ASSERT_TRUE(CreatePeerConnectionWrappers());
2252 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492253 caller()->AddAudioVideoTracks();
2254 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162255 caller()->CreateAndSetAndSignalOffer();
2256 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422257 {
2258 MediaExpectations media_expectations;
2259 media_expectations.ExpectBidirectionalAudioAndVideo();
2260 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2261 }
deadbeef1dcb1642017-03-30 04:08:162262 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 19:54:422263 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2264 caller()->SetGeneratedSdpMunger(
2265 [](cricket::SessionDescription* description) {
2266 for (cricket::ContentInfo& content : description->contents()) {
2267 if (cricket::IsVideoContent(&content)) {
2268 content.rejected = true;
2269 }
2270 }
2271 });
2272 } else {
2273 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2274 }
deadbeef1dcb1642017-03-30 04:08:162275 caller()->CreateAndSetAndSignalOffer();
2276 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2277
2278 // Sanity check that the caller's description has a rejected video section.
2279 ASSERT_NE(nullptr, caller()->pc()->local_description());
2280 const ContentInfo* caller_video_content =
2281 GetFirstVideoContent(caller()->pc()->local_description()->description());
2282 ASSERT_NE(nullptr, caller_video_content);
2283 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-30 04:08:162284 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 19:54:422285 {
2286 MediaExpectations media_expectations;
2287 media_expectations.ExpectBidirectionalAudio();
2288 media_expectations.ExpectNoVideo();
2289 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2290 }
deadbeef1dcb1642017-03-30 04:08:162291}
2292
Taylor Brandstetter60c8dc82018-04-11 22:20:272293// Do one offer/answer with audio, another that disables it (rejecting the m=
2294// section), and another that re-enables it. Regression test for:
2295// bugs.webrtc.org/6023
2296TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2297 ASSERT_TRUE(CreatePeerConnectionWrappers());
2298 ConnectFakeSignaling();
2299
2300 // Add audio track, do normal offer/answer.
2301 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2302 caller()->CreateLocalAudioTrack();
2303 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2304 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2305 caller()->CreateAndSetAndSignalOffer();
2306 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2307
2308 // Remove audio track, and set offer_to_receive_audio to false to cause the
2309 // m= section to be completely disabled, not just "recvonly".
2310 caller()->pc()->RemoveTrack(sender);
2311 PeerConnectionInterface::RTCOfferAnswerOptions options;
2312 options.offer_to_receive_audio = 0;
2313 caller()->SetOfferAnswerOptions(options);
2314 caller()->CreateAndSetAndSignalOffer();
2315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2316
2317 // Add the audio track again, expecting negotiation to succeed and frames to
2318 // flow.
2319 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2320 options.offer_to_receive_audio = 1;
2321 caller()->SetOfferAnswerOptions(options);
2322 caller()->CreateAndSetAndSignalOffer();
2323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2324
2325 MediaExpectations media_expectations;
2326 media_expectations.CalleeExpectsSomeAudio();
2327 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2328}
2329
deadbeef1dcb1642017-03-30 04:08:162330// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2331// is needed to support legacy endpoints.
2332// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2333// add a test for an end-to-end test without MID signaling either (basically,
2334// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 19:54:422335TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-30 04:08:162336 ASSERT_TRUE(CreatePeerConnectionWrappers());
2337 ConnectFakeSignaling();
2338 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 18:26:492339 caller()->AddAudioVideoTracks();
2340 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 23:01:172341 // Remove SSRCs and MSIDs from the received offer SDP.
2342 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-30 04:08:162343 caller()->CreateAndSetAndSignalOffer();
2344 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422345 MediaExpectations media_expectations;
2346 media_expectations.ExpectBidirectionalAudioAndVideo();
2347 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162348}
2349
Seth Hampson5897a6e2018-04-03 18:16:332350// Basic end-to-end test, without SSRC signaling. This means that the track
2351// was created properly and frames are delivered when the MSIDs are communicated
2352// with a=msid lines and no a=ssrc lines.
2353TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2354 EndToEndCallWithoutSsrcSignaling) {
2355 const char kStreamId[] = "streamId";
2356 ASSERT_TRUE(CreatePeerConnectionWrappers());
2357 ConnectFakeSignaling();
2358 // Add just audio tracks.
2359 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2360 callee()->AddAudioTrack();
2361
2362 // Remove SSRCs from the received offer SDP.
2363 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2364 caller()->CreateAndSetAndSignalOffer();
2365 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2366 MediaExpectations media_expectations;
2367 media_expectations.ExpectBidirectionalAudio();
2368 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2369}
2370
Steve Antondf527fd2018-04-27 22:52:032371// Tests that video flows between multiple video tracks when SSRCs are not
2372// signaled. This exercises the MID RTP header extension which is needed to
2373// demux the incoming video tracks.
2374TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2375 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2376 ASSERT_TRUE(CreatePeerConnectionWrappers());
2377 ConnectFakeSignaling();
2378 caller()->AddVideoTrack();
2379 caller()->AddVideoTrack();
2380 callee()->AddVideoTrack();
2381 callee()->AddVideoTrack();
2382
2383 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2384 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2385 caller()->CreateAndSetAndSignalOffer();
2386 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2387 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2388 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2389
2390 // Expect video to be received in both directions on both tracks.
2391 MediaExpectations media_expectations;
2392 media_expectations.ExpectBidirectionalVideo();
2393 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2394}
2395
deadbeef1dcb1642017-03-30 04:08:162396// Test that if two video tracks are sent (from caller to callee, in this test),
2397// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:422398TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-30 04:08:162399 ASSERT_TRUE(CreatePeerConnectionWrappers());
2400 ConnectFakeSignaling();
2401 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 18:26:492402 caller()->AddAudioVideoTracks();
2403 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-30 04:08:162404 caller()->CreateAndSetAndSignalOffer();
2405 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 18:26:492406 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 19:54:422407
2408 MediaExpectations media_expectations;
2409 media_expectations.CalleeExpectsSomeAudioAndVideo();
2410 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162411}
2412
2413static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2414 bool first = true;
2415 for (cricket::ContentInfo& content : desc->contents()) {
2416 if (first) {
2417 first = false;
2418 continue;
2419 }
2420 content.bundle_only = true;
2421 }
2422 first = true;
2423 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2424 if (first) {
2425 first = false;
2426 continue;
2427 }
2428 transport.description.ice_ufrag.clear();
2429 transport.description.ice_pwd.clear();
2430 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2431 transport.description.identity_fingerprint.reset(nullptr);
2432 }
2433}
2434
2435// Test that if applying a true "max bundle" offer, which uses ports of 0,
2436// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2437// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2438// successfully and media flows.
2439// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2440// TODO(deadbeef): Won't need this test once we start generating actual
2441// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 19:54:422442TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162443 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2444 ASSERT_TRUE(CreatePeerConnectionWrappers());
2445 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492446 caller()->AddAudioVideoTracks();
2447 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162448 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2449 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2450 // but the first m= section.
2451 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2452 caller()->CreateAndSetAndSignalOffer();
2453 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422454 MediaExpectations media_expectations;
2455 media_expectations.ExpectBidirectionalAudioAndVideo();
2456 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162457}
2458
2459// Test that we can receive the audio output level from a remote audio track.
2460// TODO(deadbeef): Use a fake audio source and verify that the output level is
2461// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 19:54:422462TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162463 ASSERT_TRUE(CreatePeerConnectionWrappers());
2464 ConnectFakeSignaling();
2465 // Just add an audio track.
Steve Anton15324772018-01-16 18:26:492466 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-30 04:08:162467 caller()->CreateAndSetAndSignalOffer();
2468 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2469
2470 // Get the audio output level stats. Note that the level is not available
2471 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 23:01:172472 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-30 04:08:162473 kMaxWaitForFramesMs);
2474}
2475
2476// Test that an audio input level is reported.
2477// TODO(deadbeef): Use a fake audio source and verify that the input level is
2478// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 19:54:422479TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162480 ASSERT_TRUE(CreatePeerConnectionWrappers());
2481 ConnectFakeSignaling();
2482 // Just add an audio track.
Steve Anton15324772018-01-16 18:26:492483 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-30 04:08:162484 caller()->CreateAndSetAndSignalOffer();
2485 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2486
2487 // Get the audio input level stats. The level should be available very
2488 // soon after the test starts.
deadbeefd8ad7882017-04-18 23:01:172489 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-30 04:08:162490 kMaxWaitForStatsMs);
2491}
2492
2493// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 19:54:422494TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162495 ASSERT_TRUE(CreatePeerConnectionWrappers());
2496 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492497 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162498 // Do offer/answer, wait for the callee to receive some frames.
2499 caller()->CreateAndSetAndSignalOffer();
2500 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422501
2502 MediaExpectations media_expectations;
2503 media_expectations.CalleeExpectsSomeAudioAndVideo();
2504 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162505
2506 // Get a handle to the remote tracks created, so they can be used as GetStats
2507 // filters.
Steve Anton15324772018-01-16 18:26:492508 for (auto receiver : callee()->pc()->GetReceivers()) {
2509 // We received frames, so we definitely should have nonzero "received bytes"
2510 // stats at this point.
2511 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2512 0);
2513 }
deadbeef1dcb1642017-03-30 04:08:162514}
2515
2516// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 19:54:422517TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-30 04:08:162518 ASSERT_TRUE(CreatePeerConnectionWrappers());
2519 ConnectFakeSignaling();
2520 auto audio_track = caller()->CreateLocalAudioTrack();
2521 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 18:26:492522 caller()->AddTrack(audio_track);
2523 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-30 04:08:162524 // Do offer/answer, wait for the callee to receive some frames.
2525 caller()->CreateAndSetAndSignalOffer();
2526 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422527 MediaExpectations media_expectations;
2528 media_expectations.CalleeExpectsSomeAudioAndVideo();
2529 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162530
2531 // The callee received frames, so we definitely should have nonzero "sent
2532 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 23:01:172533 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2534 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2535}
2536
Fredrik Solenberg73276ad2017-09-14 12:46:472537// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 19:54:422538TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 12:46:472539 ASSERT_TRUE(CreatePeerConnectionWrappers());
2540 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492541 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 12:46:472542
Steve Anton15324772018-01-16 18:26:492543 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 12:46:472544
2545 // Do offer/answer, wait for the callee to receive some frames.
2546 caller()->CreateAndSetAndSignalOffer();
2547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2548
2549 // Get the remote audio track created on the receiver, so they can be used as
2550 // GetStats filters.
Steve Antonfc853712018-03-01 21:48:582551 auto receivers = callee()->pc()->GetReceivers();
2552 ASSERT_EQ(1u, receivers.size());
2553 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 12:46:472554
2555 // Get the audio output level stats. Note that the level is not available
2556 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 17:48:352557 EXPECT_TRUE_WAIT(
2558 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2559 0,
2560 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 12:46:472561}
2562
deadbeefd8ad7882017-04-18 23:01:172563// Test that we can get stats (using the new stats implemnetation) for
2564// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2565// SDP.
Seth Hampson2f0d7022018-02-20 19:54:422566TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 23:01:172567 GetStatsForUnsignaledStreamWithNewStatsApi) {
2568 ASSERT_TRUE(CreatePeerConnectionWrappers());
2569 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492570 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 23:01:172571 // Remove SSRCs and MSIDs from the received offer SDP.
2572 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2573 caller()->CreateAndSetAndSignalOffer();
2574 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422575 MediaExpectations media_expectations;
2576 media_expectations.CalleeExpectsSomeAudio(1);
2577 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 23:01:172578
2579 // We received a frame, so we should have nonzero "bytes received" stats for
2580 // the unsignaled stream, if stats are working for it.
2581 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2582 callee()->NewGetStats();
2583 ASSERT_NE(nullptr, report);
2584 auto inbound_stream_stats =
2585 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2586 ASSERT_EQ(1U, inbound_stream_stats.size());
2587 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2588 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 20:09:472589 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2590}
2591
Taylor Brandstettera4653442018-06-19 16:44:262592// Same as above but for the legacy stats implementation.
2593TEST_P(PeerConnectionIntegrationTest,
2594 GetStatsForUnsignaledStreamWithOldStatsApi) {
2595 ASSERT_TRUE(CreatePeerConnectionWrappers());
2596 ConnectFakeSignaling();
2597 caller()->AddAudioTrack();
2598 // Remove SSRCs and MSIDs from the received offer SDP.
2599 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2600 caller()->CreateAndSetAndSignalOffer();
2601 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2602
2603 // Note that, since the old stats implementation associates SSRCs with tracks
2604 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2605 // associated track ID. So we can't use the track "selector" argument.
2606 //
2607 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2608 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 10:53:232609 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 16:44:262610 kDefaultTimeout);
2611}
2612
zhihuangf8164932017-05-19 20:09:472613// Test that we can successfully get the media related stats (audio level
2614// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 19:54:422615TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 20:09:472616 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2617 ASSERT_TRUE(CreatePeerConnectionWrappers());
2618 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492619 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 20:09:472620 // Remove SSRCs and MSIDs from the received offer SDP.
2621 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2622 caller()->CreateAndSetAndSignalOffer();
2623 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422624 MediaExpectations media_expectations;
2625 media_expectations.CalleeExpectsSomeAudio(1);
2626 media_expectations.CalleeExpectsSomeVideo(1);
2627 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 20:09:472628
2629 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2630 callee()->NewGetStats();
2631 ASSERT_NE(nullptr, report);
2632
2633 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2634 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2635 ASSERT_GE(audio_index, 0);
2636 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-30 04:08:162637}
2638
deadbeef4e2deab2017-09-20 20:56:212639// Helper for test below.
2640void ModifySsrcs(cricket::SessionDescription* desc) {
2641 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 22:52:032642 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 23:14:302643 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 20:56:212644 for (uint32_t& ssrc : stream.ssrcs) {
2645 ssrc = rtc::CreateRandomId();
2646 }
2647 }
2648 }
2649}
2650
2651// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2652// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2653// This should result in two "RTCInboundRTPStreamStats", but only one
2654// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2655// being reset to 0 once the SSRC change occurs.
2656//
2657// Regression test for this bug:
2658// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2659//
2660// The bug causes the track stats to only represent one of the two streams:
2661// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2662// that the track stat counters would reset to 0 when the new stream is
2663// received, and a 50% chance that they'll stop updating (while
2664// "concealed_samples" continues increasing, due to silence being generated for
2665// the inactive stream).
Seth Hampson2f0d7022018-02-20 19:54:422666TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-11 00:19:522667 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 20:56:212668 ASSERT_TRUE(CreatePeerConnectionWrappers());
2669 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492670 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 20:56:212671 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2672 // that doesn't signal SSRCs (from the callee's perspective).
2673 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2674 caller()->CreateAndSetAndSignalOffer();
2675 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2676 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 19:54:422677 {
2678 MediaExpectations media_expectations;
2679 media_expectations.CalleeExpectsSomeAudio(50);
2680 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2681 }
deadbeef4e2deab2017-09-20 20:56:212682 // Some audio frames were received, so we should have nonzero "samples
2683 // received" for the track.
2684 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2685 callee()->NewGetStats();
2686 ASSERT_NE(nullptr, report);
2687 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2688 ASSERT_EQ(1U, track_stats.size());
2689 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2690 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2691 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2692
2693 // Create a new offer and munge it to cause the caller to use a new SSRC.
2694 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2695 caller()->CreateAndSetAndSignalOffer();
2696 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2697 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2698 // SSRC.
Seth Hampson2f0d7022018-02-20 19:54:422699 {
2700 MediaExpectations media_expectations;
2701 media_expectations.CalleeExpectsSomeAudio(25);
2702 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2703 }
deadbeef4e2deab2017-09-20 20:56:212704
2705 report = callee()->NewGetStats();
2706 ASSERT_NE(nullptr, report);
2707 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2708 ASSERT_EQ(1U, track_stats.size());
2709 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2710 // The "total samples received" stat should only be greater than it was
2711 // before.
2712 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2713 // Right now, the new SSRC will cause the counters to reset to 0.
2714 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2715
2716 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-11 00:19:522717 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 20:56:212718 // good sign that we're seeing stats from the old stream that's no longer
2719 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-11 00:19:522720 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 20:56:212721 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2722 EXPECT_LT(*track_stats[0]->concealed_samples,
2723 *track_stats[0]->total_samples_received *
2724 kAcceptableConcealedSamplesPercentage);
2725
2726 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2727 // sanity check that the SSRC really changed.
2728 // TODO(deadbeef): This isn't working right now, because we're not returning
2729 // *any* stats for the inactive stream. Uncomment when the bug is completely
2730 // fixed.
2731 // auto inbound_stream_stats =
2732 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2733 // ASSERT_EQ(2U, inbound_stream_stats.size());
2734}
2735
deadbeef1dcb1642017-03-30 04:08:162736// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 19:54:422737TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-30 04:08:162738 PeerConnectionFactory::Options dtls_10_options;
2739 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2740 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2741 dtls_10_options));
2742 ConnectFakeSignaling();
2743 // Do normal offer/answer and wait for some frames to be received in each
2744 // direction.
Steve Anton15324772018-01-16 18:26:492745 caller()->AddAudioVideoTracks();
2746 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162747 caller()->CreateAndSetAndSignalOffer();
2748 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422749 MediaExpectations media_expectations;
2750 media_expectations.ExpectBidirectionalAudioAndVideo();
2751 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162752}
2753
2754// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:422755TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-30 04:08:162756 PeerConnectionFactory::Options dtls_10_options;
2757 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2758 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2759 dtls_10_options));
2760 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492761 caller()->AddAudioVideoTracks();
2762 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162763 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 19:54:532764 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:162765 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 23:01:172766 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-30 04:08:162767 kDefaultTimeout);
2768 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 23:01:172769 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 19:54:532770 // TODO(bugs.webrtc.org/9456): Fix it.
2771 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2772 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2773 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-30 04:08:162774}
2775
2776// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:422777TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-30 04:08:162778 PeerConnectionFactory::Options dtls_12_options;
2779 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2780 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2781 dtls_12_options));
2782 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:492783 caller()->AddAudioVideoTracks();
2784 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162785 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 19:54:532786 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-30 04:08:162787 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 23:01:172788 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-30 04:08:162789 kDefaultTimeout);
2790 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 23:01:172791 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 19:54:532792 // TODO(bugs.webrtc.org/9456): Fix it.
2793 EXPECT_EQ(1, webrtc::metrics::NumEvents(
2794 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2795 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-30 04:08:162796}
2797
2798// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2799// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 19:54:422800TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-30 04:08:162801 PeerConnectionFactory::Options caller_options;
2802 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2803 PeerConnectionFactory::Options callee_options;
2804 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2805 ASSERT_TRUE(
2806 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2807 ConnectFakeSignaling();
2808 // Do normal offer/answer and wait for some frames to be received in each
2809 // direction.
Steve Anton15324772018-01-16 18:26:492810 caller()->AddAudioVideoTracks();
2811 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162812 caller()->CreateAndSetAndSignalOffer();
2813 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422814 MediaExpectations media_expectations;
2815 media_expectations.ExpectBidirectionalAudioAndVideo();
2816 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162817}
2818
2819// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2820// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 19:54:422821TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-30 04:08:162822 PeerConnectionFactory::Options caller_options;
2823 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2824 PeerConnectionFactory::Options callee_options;
2825 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2826 ASSERT_TRUE(
2827 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2828 ConnectFakeSignaling();
2829 // Do normal offer/answer and wait for some frames to be received in each
2830 // direction.
Steve Anton15324772018-01-16 18:26:492831 caller()->AddAudioVideoTracks();
2832 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162833 caller()->CreateAndSetAndSignalOffer();
2834 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422835 MediaExpectations media_expectations;
2836 media_expectations.ExpectBidirectionalAudioAndVideo();
2837 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162838}
2839
Taylor Brandstetter5e55fe82018-03-23 18:50:162840// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2841// works as expected; the cipher should only be used if enabled by both sides.
2842TEST_P(PeerConnectionIntegrationTest,
2843 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2844 PeerConnectionFactory::Options caller_options;
2845 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2846 PeerConnectionFactory::Options callee_options;
2847 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2848 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2849 TestNegotiatedCipherSuite(caller_options, callee_options,
2850 expected_cipher_suite);
2851}
2852
2853TEST_P(PeerConnectionIntegrationTest,
2854 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2855 PeerConnectionFactory::Options caller_options;
2856 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
2857 PeerConnectionFactory::Options callee_options;
2858 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2859 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2860 TestNegotiatedCipherSuite(caller_options, callee_options,
2861 expected_cipher_suite);
2862}
2863
2864TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2865 PeerConnectionFactory::Options caller_options;
2866 caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2867 PeerConnectionFactory::Options callee_options;
2868 callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
2869 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
2870 TestNegotiatedCipherSuite(caller_options, callee_options,
2871 expected_cipher_suite);
2872}
2873
deadbeef1dcb1642017-03-30 04:08:162874// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 19:54:422875TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-30 04:08:162876 bool local_gcm_enabled = false;
2877 bool remote_gcm_enabled = false;
2878 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2879 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2880 expected_cipher_suite);
2881}
2882
2883// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 19:54:422884TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-30 04:08:162885 bool local_gcm_enabled = true;
2886 bool remote_gcm_enabled = true;
2887 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
2888 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2889 expected_cipher_suite);
2890}
2891
2892// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 19:54:422893TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162894 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
2895 bool local_gcm_enabled = true;
2896 bool remote_gcm_enabled = false;
2897 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2898 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2899 expected_cipher_suite);
2900}
2901
2902// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 19:54:422903TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162904 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
2905 bool local_gcm_enabled = false;
2906 bool remote_gcm_enabled = true;
2907 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
2908 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
2909 expected_cipher_suite);
2910}
2911
deadbeef7914b8c2017-04-21 10:23:332912// Verify that media can be transmitted end-to-end when GCM crypto suites are
2913// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
2914// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
2915// works with it.
Seth Hampson2f0d7022018-02-20 19:54:422916TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 10:23:332917 PeerConnectionFactory::Options gcm_options;
2918 gcm_options.crypto_options.enable_gcm_crypto_suites = true;
2919 ASSERT_TRUE(
2920 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
2921 ConnectFakeSignaling();
2922 // Do normal offer/answer and wait for some frames to be received in each
2923 // direction.
Steve Anton15324772018-01-16 18:26:492924 caller()->AddAudioVideoTracks();
2925 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 10:23:332926 caller()->CreateAndSetAndSignalOffer();
2927 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:422928 MediaExpectations media_expectations;
2929 media_expectations.ExpectBidirectionalAudioAndVideo();
2930 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 10:23:332931}
2932
deadbeef1dcb1642017-03-30 04:08:162933// This test sets up a call between two parties with audio, video and an RTP
2934// data channel.
Seth Hampson2f0d7022018-02-20 19:54:422935TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 10:32:182936 PeerConnectionInterface::RTCConfiguration rtc_config;
2937 rtc_config.enable_rtp_data_channel = true;
2938 rtc_config.enable_dtls_srtp = false;
2939 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:162940 ConnectFakeSignaling();
2941 // Expect that data channel created on caller side will show up for callee as
2942 // well.
2943 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:492944 caller()->AddAudioVideoTracks();
2945 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162946 caller()->CreateAndSetAndSignalOffer();
2947 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2948 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 19:54:422949 MediaExpectations media_expectations;
2950 media_expectations.ExpectBidirectionalAudioAndVideo();
2951 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:162952 ASSERT_NE(nullptr, caller()->data_channel());
2953 ASSERT_NE(nullptr, callee()->data_channel());
2954 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2955 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2956
2957 // Ensure data can be sent in both directions.
2958 std::string data = "hello world";
2959 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
2960 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
2961 kDefaultTimeout);
2962 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
2963 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
2964 kDefaultTimeout);
2965}
2966
2967// Ensure that an RTP data channel is signaled as closed for the caller when
2968// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 19:54:422969TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:162970 RtpDataChannelSignaledClosedInCalleeOffer) {
2971 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 10:32:182972 PeerConnectionInterface::RTCConfiguration rtc_config;
2973 rtc_config.enable_rtp_data_channel = true;
2974 rtc_config.enable_dtls_srtp = false;
2975 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:162976 ConnectFakeSignaling();
2977 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:492978 caller()->AddAudioVideoTracks();
2979 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:162980 caller()->CreateAndSetAndSignalOffer();
2981 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2982 ASSERT_NE(nullptr, caller()->data_channel());
2983 ASSERT_NE(nullptr, callee()->data_channel());
2984 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
2985 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
2986
2987 // Close the data channel on the callee, and do an updated offer/answer.
2988 callee()->data_channel()->Close();
2989 callee()->CreateAndSetAndSignalOffer();
2990 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2991 EXPECT_FALSE(caller()->data_observer()->IsOpen());
2992 EXPECT_FALSE(callee()->data_observer()->IsOpen());
2993}
2994
2995// Tests that data is buffered in an RTP data channel until an observer is
2996// registered for it.
2997//
2998// NOTE: RTP data channels can receive data before the underlying
2999// transport has detected that a channel is writable and thus data can be
3000// received before the data channel state changes to open. That is hard to test
3001// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 19:54:423002TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:163003 DataBufferedUntilRtpDataChannelObserverRegistered) {
3004 // Use fake clock and simulated network delay so that we predictably can wait
3005 // until an SCTP message has been delivered without "sleep()"ing.
3006 rtc::ScopedFakeClock fake_clock;
3007 // Some things use a time of "0" as a special value, so we need to start out
3008 // the fake clock at a nonzero time.
3009 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 12:52:223010 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-30 04:08:163011 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3012 virtual_socket_server()->UpdateDelayDistribution();
3013
Niels Möllerf06f9232018-08-07 10:32:183014 PeerConnectionInterface::RTCConfiguration rtc_config;
3015 rtc_config.enable_rtp_data_channel = true;
3016 rtc_config.enable_dtls_srtp = false;
3017 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:163018 ConnectFakeSignaling();
3019 caller()->CreateDataChannel();
3020 caller()->CreateAndSetAndSignalOffer();
3021 ASSERT_TRUE(caller()->data_channel() != nullptr);
3022 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
3023 kDefaultTimeout, fake_clock);
3024 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
3025 kDefaultTimeout, fake_clock);
3026 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3027 callee()->data_channel()->state(), kDefaultTimeout,
3028 fake_clock);
3029
3030 // Unregister the observer which is normally automatically registered.
3031 callee()->data_channel()->UnregisterObserver();
3032 // Send data and advance fake clock until it should have been received.
3033 std::string data = "hello world";
3034 caller()->data_channel()->Send(DataBuffer(data));
3035 SIMULATED_WAIT(false, 50, fake_clock);
3036
3037 // Attach data channel and expect data to be received immediately. Note that
3038 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3039 // further, but data can be received even if the callback is asynchronous.
3040 MockDataChannelObserver new_observer(callee()->data_channel());
3041 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
3042 fake_clock);
Seth Hampson1d4a76d2018-06-19 21:31:413043 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3044 // If this is not done a DCHECK can be hit in ports.cc, because a large
3045 // negative number is calculated for the rtt due to the global clock changing.
3046 caller()->pc()->Close();
3047 callee()->pc()->Close();
deadbeef1dcb1642017-03-30 04:08:163048}
3049
3050// This test sets up a call between two parties with audio, video and but only
3051// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 19:54:423052TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 10:32:183053 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3054 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-30 04:08:163055 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 10:32:183056 rtc_config_1.enable_dtls_srtp = false;
3057 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3058 rtc_config_2.enable_dtls_srtp = false;
3059 rtc_config_2.enable_dtls_srtp = false;
3060 ASSERT_TRUE(
3061 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-30 04:08:163062 ConnectFakeSignaling();
3063 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:493064 caller()->AddAudioVideoTracks();
3065 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163066 caller()->CreateAndSetAndSignalOffer();
3067 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3068 // The caller should still have a data channel, but it should be closed, and
3069 // one should ever have been created for the callee.
3070 EXPECT_TRUE(caller()->data_channel() != nullptr);
3071 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3072 EXPECT_EQ(nullptr, callee()->data_channel());
3073}
3074
3075// This test sets up a call between two parties with audio, and video. When
3076// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:423077TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 10:32:183078 PeerConnectionInterface::RTCConfiguration rtc_config;
3079 rtc_config.enable_rtp_data_channel = true;
3080 rtc_config.enable_dtls_srtp = false;
3081 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-30 04:08:163082 ConnectFakeSignaling();
3083 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 18:26:493084 caller()->AddAudioVideoTracks();
3085 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163086 caller()->CreateAndSetAndSignalOffer();
3087 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3088 // Create data channel and do new offer and answer.
3089 caller()->CreateDataChannel();
3090 caller()->CreateAndSetAndSignalOffer();
3091 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3092 ASSERT_NE(nullptr, caller()->data_channel());
3093 ASSERT_NE(nullptr, callee()->data_channel());
3094 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3095 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3096 // Ensure data can be sent in both directions.
3097 std::string data = "hello world";
3098 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3099 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3100 kDefaultTimeout);
3101 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3102 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3103 kDefaultTimeout);
3104}
3105
3106#ifdef HAVE_SCTP
3107
3108// This test sets up a call between two parties with audio, video and an SCTP
3109// data channel.
Seth Hampson2f0d7022018-02-20 19:54:423110TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-30 04:08:163111 ASSERT_TRUE(CreatePeerConnectionWrappers());
3112 ConnectFakeSignaling();
3113 // Expect that data channel created on caller side will show up for callee as
3114 // well.
3115 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:493116 caller()->AddAudioVideoTracks();
3117 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163118 caller()->CreateAndSetAndSignalOffer();
3119 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3120 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 19:54:423121 MediaExpectations media_expectations;
3122 media_expectations.ExpectBidirectionalAudioAndVideo();
3123 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163124 // Caller data channel should already exist (it created one). Callee data
3125 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3126 ASSERT_NE(nullptr, caller()->data_channel());
3127 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3128 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3129 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3130
3131 // Ensure data can be sent in both directions.
3132 std::string data = "hello world";
3133 caller()->data_channel()->Send(DataBuffer(data));
3134 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3135 kDefaultTimeout);
3136 callee()->data_channel()->Send(DataBuffer(data));
3137 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3138 kDefaultTimeout);
3139}
3140
3141// Ensure that when the callee closes an SCTP data channel, the closing
3142// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 19:54:423143TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-30 04:08:163144 // Same procedure as above test.
3145 ASSERT_TRUE(CreatePeerConnectionWrappers());
3146 ConnectFakeSignaling();
3147 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 18:26:493148 caller()->AddAudioVideoTracks();
3149 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163150 caller()->CreateAndSetAndSignalOffer();
3151 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3152 ASSERT_NE(nullptr, caller()->data_channel());
3153 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3154 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3155 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3156
3157 // Close the data channel on the callee side, and wait for it to reach the
3158 // "closed" state on both sides.
3159 callee()->data_channel()->Close();
3160 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3161 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3162}
3163
Seth Hampson2f0d7022018-02-20 19:54:423164TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 18:41:543165 ASSERT_TRUE(CreatePeerConnectionWrappers());
3166 ConnectFakeSignaling();
3167 webrtc::DataChannelInit init;
3168 init.id = 53;
3169 init.maxRetransmits = 52;
3170 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 18:26:493171 caller()->AddAudioVideoTracks();
3172 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 18:41:543173 caller()->CreateAndSetAndSignalOffer();
3174 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 20:04:123175 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3176 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 18:41:543177 EXPECT_EQ(init.id, callee()->data_channel()->id());
3178 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3179 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3180 EXPECT_FALSE(callee()->data_channel()->negotiated());
3181}
3182
deadbeef1dcb1642017-03-30 04:08:163183// Test usrsctp's ability to process unordered data stream, where data actually
3184// arrives out of order using simulated delays. Previously there have been some
3185// bugs in this area.
Seth Hampson2f0d7022018-02-20 19:54:423186TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-30 04:08:163187 // Introduce random network delays.
3188 // Otherwise it's not a true "unordered" test.
3189 virtual_socket_server()->set_delay_mean(20);
3190 virtual_socket_server()->set_delay_stddev(5);
3191 virtual_socket_server()->UpdateDelayDistribution();
3192 // Normal procedure, but with unordered data channel config.
3193 ASSERT_TRUE(CreatePeerConnectionWrappers());
3194 ConnectFakeSignaling();
3195 webrtc::DataChannelInit init;
3196 init.ordered = false;
3197 caller()->CreateDataChannel(&init);
3198 caller()->CreateAndSetAndSignalOffer();
3199 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3200 ASSERT_NE(nullptr, caller()->data_channel());
3201 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3202 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3203 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3204
3205 static constexpr int kNumMessages = 100;
3206 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3207 static constexpr size_t kMaxMessageSize = 4096;
3208 // Create and send random messages.
3209 std::vector<std::string> sent_messages;
3210 for (int i = 0; i < kNumMessages; ++i) {
3211 size_t length =
3212 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3213 std::string message;
3214 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3215 caller()->data_channel()->Send(DataBuffer(message));
3216 callee()->data_channel()->Send(DataBuffer(message));
3217 sent_messages.push_back(message);
3218 }
3219
3220 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 10:53:233221 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-30 04:08:163222 caller()->data_observer()->received_message_count(),
3223 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 10:53:233224 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-30 04:08:163225 callee()->data_observer()->received_message_count(),
3226 kDefaultTimeout);
3227
3228 // Sort and compare to make sure none of the messages were corrupted.
3229 std::vector<std::string> caller_received_messages =
3230 caller()->data_observer()->messages();
3231 std::vector<std::string> callee_received_messages =
3232 callee()->data_observer()->messages();
3233 std::sort(sent_messages.begin(), sent_messages.end());
3234 std::sort(caller_received_messages.begin(), caller_received_messages.end());
3235 std::sort(callee_received_messages.begin(), callee_received_messages.end());
3236 EXPECT_EQ(sent_messages, caller_received_messages);
3237 EXPECT_EQ(sent_messages, callee_received_messages);
3238}
3239
3240// This test sets up a call between two parties with audio, and video. When
3241// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 19:54:423242TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-30 04:08:163243 ASSERT_TRUE(CreatePeerConnectionWrappers());
3244 ConnectFakeSignaling();
3245 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 18:26:493246 caller()->AddAudioVideoTracks();
3247 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163248 caller()->CreateAndSetAndSignalOffer();
3249 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3250 // Create data channel and do new offer and answer.
3251 caller()->CreateDataChannel();
3252 caller()->CreateAndSetAndSignalOffer();
3253 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3254 // Caller data channel should already exist (it created one). Callee data
3255 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3256 ASSERT_NE(nullptr, caller()->data_channel());
3257 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3258 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3259 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3260 // Ensure data can be sent in both directions.
3261 std::string data = "hello world";
3262 caller()->data_channel()->Send(DataBuffer(data));
3263 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3264 kDefaultTimeout);
3265 callee()->data_channel()->Send(DataBuffer(data));
3266 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3267 kDefaultTimeout);
3268}
3269
deadbeef7914b8c2017-04-21 10:23:333270// Set up a connection initially just using SCTP data channels, later upgrading
3271// to audio/video, ensuring frames are received end-to-end. Effectively the
3272// inverse of the test above.
3273// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 19:54:423274TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 10:23:333275 ASSERT_TRUE(CreatePeerConnectionWrappers());
3276 ConnectFakeSignaling();
3277 // Do initial offer/answer with just data channel.
3278 caller()->CreateDataChannel();
3279 caller()->CreateAndSetAndSignalOffer();
3280 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3281 // Wait until data can be sent over the data channel.
3282 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3283 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3284 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3285
3286 // Do subsequent offer/answer with two-way audio and video. Audio and video
3287 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 18:26:493288 caller()->AddAudioVideoTracks();
3289 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 10:23:333290 caller()->CreateAndSetAndSignalOffer();
3291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:423292 MediaExpectations media_expectations;
3293 media_expectations.ExpectBidirectionalAudioAndVideo();
3294 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 10:23:333295}
3296
deadbeef8b7e9ad2017-05-25 16:38:553297static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 16:38:553298 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 23:14:303299 GetFirstDataContentDescription(desc);
3300 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 16:38:553301 dcd_offer->set_use_sctpmap(false);
3302 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3303}
3304
3305// Test that the data channel works when a spec-compliant SCTP m= section is
3306// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3307// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 19:54:423308TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 16:38:553309 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3310 ASSERT_TRUE(CreatePeerConnectionWrappers());
3311 ConnectFakeSignaling();
3312 caller()->CreateDataChannel();
3313 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3314 caller()->CreateAndSetAndSignalOffer();
3315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3316 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3317 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3318 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3319
3320 // Ensure data can be sent in both directions.
3321 std::string data = "hello world";
3322 caller()->data_channel()->Send(DataBuffer(data));
3323 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3324 kDefaultTimeout);
3325 callee()->data_channel()->Send(DataBuffer(data));
3326 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3327 kDefaultTimeout);
3328}
3329
deadbeef1dcb1642017-03-30 04:08:163330#endif // HAVE_SCTP
3331
3332// Test that the ICE connection and gathering states eventually reach
3333// "complete".
Seth Hampson2f0d7022018-02-20 19:54:423334TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-30 04:08:163335 ASSERT_TRUE(CreatePeerConnectionWrappers());
3336 ConnectFakeSignaling();
3337 // Do normal offer/answer.
Steve Anton15324772018-01-16 18:26:493338 caller()->AddAudioVideoTracks();
3339 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163340 caller()->CreateAndSetAndSignalOffer();
3341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3342 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3343 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3344 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3345 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3346 // After the best candidate pair is selected and all candidates are signaled,
3347 // the ICE connection state should reach "complete".
3348 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3349 // answerer/"callee" by default) only reaches "connected". When this is
3350 // fixed, this test should be updated.
3351 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3352 caller()->ice_connection_state(), kDefaultTimeout);
3353 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3354 callee()->ice_connection_state(), kDefaultTimeout);
3355}
3356
Zach Stein6fcdc2f2018-08-23 23:25:553357// Replaces the first candidate with a static address and configures a
3358// MockAsyncResolver to return the replaced address the first time the static
3359// address is resolved. Candidates past the first will not be signaled.
3360class ReplaceFirstCandidateAddressDropOthers final
3361 : public IceCandidateReplacerInterface {
3362 public:
3363 ReplaceFirstCandidateAddressDropOthers(
3364 const SocketAddress& new_address,
3365 rtc::MockAsyncResolver* mock_async_resolver)
3366 : mock_async_resolver_(mock_async_resolver), new_address_(new_address) {
3367 RTC_DCHECK(mock_async_resolver);
3368 }
3369
3370 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3371 const webrtc::IceCandidateInterface* candidate) override {
3372 if (replaced_candidate_) {
3373 return nullptr;
3374 }
3375
3376 replaced_candidate_ = true;
3377 cricket::Candidate new_candidate(candidate->candidate());
3378 new_candidate.set_address(new_address_);
3379 EXPECT_CALL(*mock_async_resolver_, GetResolvedAddress(_, _))
3380 .WillOnce(DoAll(SetArgPointee<1>(candidate->candidate().address()),
3381 Return(true)));
3382 EXPECT_CALL(*mock_async_resolver_, Destroy(_));
3383 return webrtc::CreateIceCandidate(
3384 candidate->sdp_mid(), candidate->sdp_mline_index(), new_candidate);
3385 }
3386
3387 private:
3388 rtc::MockAsyncResolver* mock_async_resolver_;
3389 SocketAddress new_address_;
3390 bool replaced_candidate_ = false;
3391};
3392
3393// Drops all candidates before they are signaled.
3394class DropAllCandidates final : public IceCandidateReplacerInterface {
3395 public:
3396 std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate(
3397 const webrtc::IceCandidateInterface*) override {
3398 return nullptr;
3399 }
3400};
3401
3402// Replace the first caller ICE candidate IP with a fake hostname and drop the
3403// other candidates. Drop all candidates on the callee side (to avoid a prflx
3404// connection). Use a mock resolver to resolve the hostname back to the original
3405// IP on the callee side and check that the ice connection connects.
3406TEST_P(PeerConnectionIntegrationTest,
3407 IceStatesReachCompletionWithRemoteHostname) {
3408 webrtc::MockAsyncResolverFactory* callee_mock_async_resolver_factory;
3409 {
3410 auto resolver_factory =
3411 absl::make_unique<webrtc::MockAsyncResolverFactory>();
3412 callee_mock_async_resolver_factory = resolver_factory.get();
3413 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3414 callee_deps.async_resolver_factory = std::move(resolver_factory);
3415
3416 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3417 RTCConfiguration(), webrtc::PeerConnectionDependencies(nullptr),
3418 RTCConfiguration(), std::move(callee_deps)));
3419 }
3420
3421 rtc::MockAsyncResolver mock_async_resolver;
3422
3423 // This also verifies that the injected AsyncResolverFactory is used by
3424 // P2PTransportChannel.
3425 EXPECT_CALL(*callee_mock_async_resolver_factory, Create())
3426 .WillOnce(Return(&mock_async_resolver));
3427 caller()->SetLocalIceCandidateReplacer(
3428 absl::make_unique<ReplaceFirstCandidateAddressDropOthers>(
3429 SocketAddress("a.b", 10000), &mock_async_resolver));
3430 callee()->SetLocalIceCandidateReplacer(
3431 absl::make_unique<DropAllCandidates>());
3432
3433 ConnectFakeSignaling();
3434 caller()->AddAudioVideoTracks();
3435 callee()->AddAudioVideoTracks();
3436 caller()->CreateAndSetAndSignalOffer();
3437 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3438 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3439 caller()->ice_connection_state(), kDefaultTimeout);
3440 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3441 callee()->ice_connection_state(), kDefaultTimeout);
3442}
3443
Steve Antonede9ca52017-10-16 20:04:273444// Test that firewalling the ICE connection causes the clients to identify the
3445// disconnected state and then removing the firewall causes them to reconnect.
3446class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 19:54:423447 : public PeerConnectionIntegrationBaseTest,
3448 public ::testing::WithParamInterface<
3449 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 20:04:273450 protected:
Seth Hampson2f0d7022018-02-20 19:54:423451 PeerConnectionIntegrationIceStatesTest()
3452 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3453 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 20:04:273454 }
3455
3456 void StartStunServer(const SocketAddress& server_address) {
3457 stun_server_.reset(
3458 cricket::TestStunServer::Create(network_thread(), server_address));
3459 }
3460
3461 bool TestIPv6() {
3462 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3463 }
3464
3465 void SetPortAllocatorFlags() {
Qingsi Wanga2d60672018-04-11 23:57:453466 network_thread()->Invoke<void>(
3467 RTC_FROM_HERE,
3468 rtc::Bind(&cricket::PortAllocator::set_flags,
3469 caller()->port_allocator(), port_allocator_flags_));
3470 network_thread()->Invoke<void>(
3471 RTC_FROM_HERE,
3472 rtc::Bind(&cricket::PortAllocator::set_flags,
3473 callee()->port_allocator(), port_allocator_flags_));
Steve Antonede9ca52017-10-16 20:04:273474 }
3475
3476 std::vector<SocketAddress> CallerAddresses() {
3477 std::vector<SocketAddress> addresses;
3478 addresses.push_back(SocketAddress("1.1.1.1", 0));
3479 if (TestIPv6()) {
3480 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3481 }
3482 return addresses;
3483 }
3484
3485 std::vector<SocketAddress> CalleeAddresses() {
3486 std::vector<SocketAddress> addresses;
3487 addresses.push_back(SocketAddress("2.2.2.2", 0));
3488 if (TestIPv6()) {
3489 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3490 }
3491 return addresses;
3492 }
3493
3494 void SetUpNetworkInterfaces() {
3495 // Remove the default interfaces added by the test infrastructure.
3496 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3497 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3498
3499 // Add network addresses for test.
3500 for (const auto& caller_address : CallerAddresses()) {
3501 caller()->network()->AddInterface(caller_address);
3502 }
3503 for (const auto& callee_address : CalleeAddresses()) {
3504 callee()->network()->AddInterface(callee_address);
3505 }
3506 }
3507
3508 private:
3509 uint32_t port_allocator_flags_;
3510 std::unique_ptr<cricket::TestStunServer> stun_server_;
3511};
3512
3513// Tests that the PeerConnection goes through all the ICE gathering/connection
3514// states over the duration of the call. This includes Disconnected and Failed
3515// states, induced by putting a firewall between the peers and waiting for them
3516// to time out.
Steve Anton83119dd2017-11-11 00:19:523517TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3518 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3519 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3520 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 20:04:273521
3522 const SocketAddress kStunServerAddress =
3523 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3524 StartStunServer(kStunServerAddress);
3525
3526 PeerConnectionInterface::RTCConfiguration config;
3527 PeerConnectionInterface::IceServer ice_stun_server;
3528 ice_stun_server.urls.push_back(
3529 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3530 kStunServerAddress.PortAsString());
3531 config.servers.push_back(ice_stun_server);
3532
3533 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3534 ConnectFakeSignaling();
3535 SetPortAllocatorFlags();
3536 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 18:26:493537 caller()->AddAudioVideoTracks();
3538 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 20:04:273539
3540 // Initial state before anything happens.
3541 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3542 caller()->ice_gathering_state());
3543 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3544 caller()->ice_connection_state());
3545
3546 // Start the call by creating the offer, setting it as the local description,
3547 // then sending it to the peer who will respond with an answer. This happens
3548 // asynchronously so that we can watch the states as it runs in the
3549 // background.
3550 caller()->CreateAndSetAndSignalOffer();
3551
Steve Anton83119dd2017-11-11 00:19:523552 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3553 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 20:04:273554
3555 // Verify that the observer was notified of the intermediate transitions.
3556 EXPECT_THAT(caller()->ice_connection_state_history(),
3557 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3558 PeerConnectionInterface::kIceConnectionConnected,
3559 PeerConnectionInterface::kIceConnectionCompleted));
3560 EXPECT_THAT(caller()->ice_gathering_state_history(),
3561 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3562 PeerConnectionInterface::kIceGatheringComplete));
3563
3564 // Block connections to/from the caller and wait for ICE to become
3565 // disconnected.
3566 for (const auto& caller_address : CallerAddresses()) {
3567 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3568 }
Mirko Bonadei675513b2017-11-09 10:09:253569 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-11 00:19:523570 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3571 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 20:04:273572
3573 // Let ICE re-establish by removing the firewall rules.
3574 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 10:09:253575 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-11 00:19:523576 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3577 caller()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 20:04:273578
3579 // According to RFC7675, if there is no response within 30 seconds then the
3580 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-11 00:19:523581 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 20:04:273582 constexpr int kConsentTimeout = 30000;
3583 for (const auto& caller_address : CallerAddresses()) {
3584 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3585 }
Mirko Bonadei675513b2017-11-09 10:09:253586 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-11 00:19:523587 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3588 caller()->ice_connection_state(), kConsentTimeout);
Steve Antonede9ca52017-10-16 20:04:273589}
3590
3591// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3592// and that the statistics in the metric observers are updated correctly.
3593TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3594 ASSERT_TRUE(CreatePeerConnectionWrappers());
3595 ConnectFakeSignaling();
3596 SetPortAllocatorFlags();
3597 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 18:26:493598 caller()->AddAudioVideoTracks();
3599 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 20:04:273600 caller()->CreateAndSetAndSignalOffer();
3601
3602 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3603
Qingsi Wang7fc821d2018-07-12 19:54:533604 // TODO(bugs.webrtc.org/9456): Fix it.
3605 const int num_best_ipv4 = webrtc::metrics::NumEvents(
3606 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
3607 const int num_best_ipv6 = webrtc::metrics::NumEvents(
3608 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 20:04:273609 if (TestIPv6()) {
3610 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3611 // connection.
Mirko Bonadeie12c1fe2018-07-03 10:53:233612 EXPECT_EQ(0, num_best_ipv4);
3613 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 20:04:273614 } else {
Mirko Bonadeie12c1fe2018-07-03 10:53:233615 EXPECT_EQ(1, num_best_ipv4);
3616 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 20:04:273617 }
3618
Qingsi Wang7fc821d2018-07-12 19:54:533619 EXPECT_EQ(0, webrtc::metrics::NumEvents(
3620 "WebRTC.PeerConnection.CandidatePairType_UDP",
3621 webrtc::kIceCandidatePairHostHost));
3622 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3623 "WebRTC.PeerConnection.CandidatePairType_UDP",
3624 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 20:04:273625}
3626
3627constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3628 cricket::PORTALLOCATOR_DISABLE_STUN |
3629 cricket::PORTALLOCATOR_DISABLE_RELAY;
3630constexpr uint32_t kFlagsIPv6NoStun =
3631 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3632 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3633constexpr uint32_t kFlagsIPv4Stun =
3634 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3635
Seth Hampson2f0d7022018-02-20 19:54:423636INSTANTIATE_TEST_CASE_P(
3637 PeerConnectionIntegrationTest,
3638 PeerConnectionIntegrationIceStatesTest,
3639 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3640 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3641 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3642 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 20:04:273643
deadbeef1dcb1642017-03-30 04:08:163644// This test sets up a call between two parties with audio and video.
3645// During the call, the caller restarts ICE and the test verifies that
3646// new ICE candidates are generated and audio and video still can flow, and the
3647// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 19:54:423648TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-30 04:08:163649 ASSERT_TRUE(CreatePeerConnectionWrappers());
3650 ConnectFakeSignaling();
3651 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 18:26:493652 caller()->AddAudioVideoTracks();
3653 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163654 caller()->CreateAndSetAndSignalOffer();
3655 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3656 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3657 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3658 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3659 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3660
3661 // To verify that the ICE restart actually occurs, get
3662 // ufrag/password/candidates before and after restart.
3663 // Create an SDP string of the first audio candidate for both clients.
3664 const webrtc::IceCandidateCollection* audio_candidates_caller =
3665 caller()->pc()->local_description()->candidates(0);
3666 const webrtc::IceCandidateCollection* audio_candidates_callee =
3667 callee()->pc()->local_description()->candidates(0);
3668 ASSERT_GT(audio_candidates_caller->count(), 0u);
3669 ASSERT_GT(audio_candidates_callee->count(), 0u);
3670 std::string caller_candidate_pre_restart;
3671 ASSERT_TRUE(
3672 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3673 std::string callee_candidate_pre_restart;
3674 ASSERT_TRUE(
3675 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3676 const cricket::SessionDescription* desc =
3677 caller()->pc()->local_description()->description();
3678 std::string caller_ufrag_pre_restart =
3679 desc->transport_infos()[0].description.ice_ufrag;
3680 desc = callee()->pc()->local_description()->description();
3681 std::string callee_ufrag_pre_restart =
3682 desc->transport_infos()[0].description.ice_ufrag;
3683
3684 // Have the caller initiate an ICE restart.
3685 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3686 caller()->CreateAndSetAndSignalOffer();
3687 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3688 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3689 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3690 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3691 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3692
3693 // Grab the ufrags/candidates again.
3694 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
3695 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
3696 ASSERT_GT(audio_candidates_caller->count(), 0u);
3697 ASSERT_GT(audio_candidates_callee->count(), 0u);
3698 std::string caller_candidate_post_restart;
3699 ASSERT_TRUE(
3700 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
3701 std::string callee_candidate_post_restart;
3702 ASSERT_TRUE(
3703 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
3704 desc = caller()->pc()->local_description()->description();
3705 std::string caller_ufrag_post_restart =
3706 desc->transport_infos()[0].description.ice_ufrag;
3707 desc = callee()->pc()->local_description()->description();
3708 std::string callee_ufrag_post_restart =
3709 desc->transport_infos()[0].description.ice_ufrag;
3710 // Sanity check that an ICE restart was actually negotiated in SDP.
3711 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
3712 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
3713 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
3714 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
3715
3716 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 19:54:423717 MediaExpectations media_expectations;
3718 media_expectations.ExpectBidirectionalAudioAndVideo();
3719 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163720}
3721
3722// Verify that audio/video can be received end-to-end when ICE renomination is
3723// enabled.
Seth Hampson2f0d7022018-02-20 19:54:423724TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-30 04:08:163725 PeerConnectionInterface::RTCConfiguration config;
3726 config.enable_ice_renomination = true;
3727 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3728 ConnectFakeSignaling();
3729 // Do normal offer/answer and wait for some frames to be received in each
3730 // direction.
Steve Anton15324772018-01-16 18:26:493731 caller()->AddAudioVideoTracks();
3732 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163733 caller()->CreateAndSetAndSignalOffer();
3734 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3735 // Sanity check that ICE renomination was actually negotiated.
3736 const cricket::SessionDescription* desc =
3737 caller()->pc()->local_description()->description();
3738 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 09:41:293739 ASSERT_NE(
3740 info.description.transport_options.end(),
3741 std::find(info.description.transport_options.begin(),
3742 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-30 04:08:163743 }
3744 desc = callee()->pc()->local_description()->description();
3745 for (const cricket::TransportInfo& info : desc->transport_infos()) {
deadbeef30952b42017-04-21 09:41:293746 ASSERT_NE(
3747 info.description.transport_options.end(),
3748 std::find(info.description.transport_options.begin(),
3749 info.description.transport_options.end(), "renomination"));
deadbeef1dcb1642017-03-30 04:08:163750 }
Seth Hampson2f0d7022018-02-20 19:54:423751 MediaExpectations media_expectations;
3752 media_expectations.ExpectBidirectionalAudioAndVideo();
3753 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163754}
3755
Steve Anton6f25b092017-10-23 16:39:203756// With a max bundle policy and RTCP muxing, adding a new media description to
3757// the connection should not affect ICE at all because the new media will use
3758// the existing connection.
Seth Hampson2f0d7022018-02-20 19:54:423759TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-11 00:19:523760 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 16:39:203761 PeerConnectionInterface::RTCConfiguration config;
3762 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3763 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3764 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
3765 config, PeerConnectionInterface::RTCConfiguration()));
3766 ConnectFakeSignaling();
3767
Steve Anton15324772018-01-16 18:26:493768 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 16:39:203769 caller()->CreateAndSetAndSignalOffer();
3770 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 19:24:503771 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3772 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 16:39:203773
3774 caller()->clear_ice_connection_state_history();
3775
Steve Anton15324772018-01-16 18:26:493776 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 16:39:203777 caller()->CreateAndSetAndSignalOffer();
3778 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3779
3780 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
3781}
3782
deadbeef1dcb1642017-03-30 04:08:163783// This test sets up a call between two parties with audio and video. It then
3784// renegotiates setting the video m-line to "port 0", then later renegotiates
3785// again, enabling video.
Seth Hampson2f0d7022018-02-20 19:54:423786TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-30 04:08:163787 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
3788 ASSERT_TRUE(CreatePeerConnectionWrappers());
3789 ConnectFakeSignaling();
3790
3791 // Do initial negotiation, only sending media from the caller. Will result in
3792 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 18:26:493793 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-30 04:08:163794 caller()->CreateAndSetAndSignalOffer();
3795 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3796
3797 // Negotiate again, disabling the video "m=" section (the callee will set the
3798 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 19:54:423799 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3800 PeerConnectionInterface::RTCOfferAnswerOptions options;
3801 options.offer_to_receive_video = 0;
3802 callee()->SetOfferAnswerOptions(options);
3803 } else {
3804 callee()->SetRemoteOfferHandler([this] {
3805 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
3806 });
3807 }
deadbeef1dcb1642017-03-30 04:08:163808 caller()->CreateAndSetAndSignalOffer();
3809 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3810 // Sanity check that video "m=" section was actually rejected.
3811 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
3812 callee()->pc()->local_description()->description());
3813 ASSERT_NE(nullptr, answer_video_content);
3814 ASSERT_TRUE(answer_video_content->rejected);
3815
3816 // Enable video and do negotiation again, making sure video is received
3817 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 19:54:423818 if (sdp_semantics_ == SdpSemantics::kPlanB) {
3819 PeerConnectionInterface::RTCOfferAnswerOptions options;
3820 options.offer_to_receive_video = 1;
3821 callee()->SetOfferAnswerOptions(options);
3822 } else {
3823 // The caller's transceiver is stopped, so we need to add another track.
3824 auto caller_transceiver =
3825 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
3826 EXPECT_TRUE(caller_transceiver->stopped());
3827 caller()->AddVideoTrack();
3828 }
3829 callee()->AddVideoTrack();
3830 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-30 04:08:163831 caller()->CreateAndSetAndSignalOffer();
3832 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:423833
deadbeef1dcb1642017-03-30 04:08:163834 // Verify the caller receives frames from the newly added stream, and the
3835 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 19:54:423836 MediaExpectations media_expectations;
3837 media_expectations.CalleeExpectsSomeAudio();
3838 media_expectations.ExpectBidirectionalVideo();
3839 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163840}
3841
deadbeef1dcb1642017-03-30 04:08:163842// This tests that if we negotiate after calling CreateSender but before we
3843// have a track, then set a track later, frames from the newly-set track are
3844// received end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:423845TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-30 04:08:163846 MediaFlowsAfterEarlyWarmupWithCreateSender) {
3847 ASSERT_TRUE(CreatePeerConnectionWrappers());
3848 ConnectFakeSignaling();
3849 auto caller_audio_sender =
3850 caller()->pc()->CreateSender("audio", "caller_stream");
3851 auto caller_video_sender =
3852 caller()->pc()->CreateSender("video", "caller_stream");
3853 auto callee_audio_sender =
3854 callee()->pc()->CreateSender("audio", "callee_stream");
3855 auto callee_video_sender =
3856 callee()->pc()->CreateSender("video", "callee_stream");
3857 caller()->CreateAndSetAndSignalOffer();
3858 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3859 // Wait for ICE to complete, without any tracks being set.
3860 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3861 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3862 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3863 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3864 // Now set the tracks, and expect frames to immediately start flowing.
3865 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3866 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3867 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3868 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 19:54:423869 MediaExpectations media_expectations;
3870 media_expectations.ExpectBidirectionalAudioAndVideo();
3871 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3872}
3873
3874// This tests that if we negotiate after calling AddTransceiver but before we
3875// have a track, then set a track later, frames from the newly-set tracks are
3876// received end-to-end.
3877TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3878 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
3879 ASSERT_TRUE(CreatePeerConnectionWrappers());
3880 ConnectFakeSignaling();
3881 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3882 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
3883 auto caller_audio_sender = audio_result.MoveValue()->sender();
3884 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3885 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
3886 auto caller_video_sender = video_result.MoveValue()->sender();
3887 callee()->SetRemoteOfferHandler([this] {
3888 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
3889 callee()->pc()->GetTransceivers()[0]->SetDirection(
3890 RtpTransceiverDirection::kSendRecv);
3891 callee()->pc()->GetTransceivers()[1]->SetDirection(
3892 RtpTransceiverDirection::kSendRecv);
3893 });
3894 caller()->CreateAndSetAndSignalOffer();
3895 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3896 // Wait for ICE to complete, without any tracks being set.
3897 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3898 caller()->ice_connection_state(), kMaxWaitForFramesMs);
3899 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3900 callee()->ice_connection_state(), kMaxWaitForFramesMs);
3901 // Now set the tracks, and expect frames to immediately start flowing.
3902 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
3903 auto callee_video_sender = callee()->pc()->GetSenders()[1];
3904 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
3905 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
3906 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
3907 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
3908 MediaExpectations media_expectations;
3909 media_expectations.ExpectBidirectionalAudioAndVideo();
3910 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163911}
3912
3913// This test verifies that a remote video track can be added via AddStream,
3914// and sent end-to-end. For this particular test, it's simply echoed back
3915// from the caller to the callee, rather than being forwarded to a third
3916// PeerConnection.
Seth Hampson2f0d7022018-02-20 19:54:423917TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-30 04:08:163918 ASSERT_TRUE(CreatePeerConnectionWrappers());
3919 ConnectFakeSignaling();
3920 // Just send a video track from the caller.
Steve Anton15324772018-01-16 18:26:493921 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-30 04:08:163922 caller()->CreateAndSetAndSignalOffer();
3923 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 10:53:233924 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-30 04:08:163925
3926 // Echo the stream back, and do a new offer/anwer (initiated by callee this
3927 // time).
3928 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
3929 callee()->CreateAndSetAndSignalOffer();
3930 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
3931
Seth Hampson2f0d7022018-02-20 19:54:423932 MediaExpectations media_expectations;
3933 media_expectations.ExpectBidirectionalVideo();
3934 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-30 04:08:163935}
3936
3937// Test that we achieve the expected end-to-end connection time, using a
3938// fake clock and simulated latency on the media and signaling paths.
3939// We use a TURN<->TURN connection because this is usually the quickest to
3940// set up initially, especially when we're confident the connection will work
3941// and can start sending media before we get a STUN response.
3942//
3943// With various optimizations enabled, here are the network delays we expect to
3944// be on the critical path:
3945// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
3946// signaling answer (with DTLS fingerprint).
3947// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
3948// using TURN<->TURN pair, and DTLS exchange is 4 packets,
3949// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 19:54:423950TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-30 04:08:163951 rtc::ScopedFakeClock fake_clock;
3952 // Some things use a time of "0" as a special value, so we need to start out
3953 // the fake clock at a nonzero time.
3954 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 12:52:223955 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-30 04:08:163956
3957 static constexpr int media_hop_delay_ms = 50;
3958 static constexpr int signaling_trip_delay_ms = 500;
3959 // For explanation of these values, see comment above.
3960 static constexpr int required_media_hops = 9;
3961 static constexpr int required_signaling_trips = 2;
3962 // For internal delays (such as posting an event asychronously).
3963 static constexpr int allowed_internal_delay_ms = 20;
3964 static constexpr int total_connection_time_ms =
3965 media_hop_delay_ms * required_media_hops +
3966 signaling_trip_delay_ms * required_signaling_trips +
3967 allowed_internal_delay_ms;
3968
3969 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
3970 3478};
3971 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
3972 0};
3973 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
3974 3478};
3975 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
3976 0};
Seth Hampsonaed71642018-06-11 14:41:323977 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
3978 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 12:01:403979
Seth Hampsonaed71642018-06-11 14:41:323980 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
3981 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-30 04:08:163982 // Bypass permission check on received packets so media can be sent before
3983 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 14:41:323984 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
3985 turn_server_1->set_enable_permission_checks(false);
3986 });
3987 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
3988 turn_server_2->set_enable_permission_checks(false);
3989 });
deadbeef1dcb1642017-03-30 04:08:163990
3991 PeerConnectionInterface::RTCConfiguration client_1_config;
3992 webrtc::PeerConnectionInterface::IceServer ice_server_1;
3993 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
3994 ice_server_1.username = "test";
3995 ice_server_1.password = "test";
3996 client_1_config.servers.push_back(ice_server_1);
3997 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
3998 client_1_config.presume_writable_when_fully_relayed = true;
3999
4000 PeerConnectionInterface::RTCConfiguration client_2_config;
4001 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4002 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4003 ice_server_2.username = "test";
4004 ice_server_2.password = "test";
4005 client_2_config.servers.push_back(ice_server_2);
4006 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4007 client_2_config.presume_writable_when_fully_relayed = true;
4008
4009 ASSERT_TRUE(
4010 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4011 // Set up the simulated delays.
4012 SetSignalingDelayMs(signaling_trip_delay_ms);
4013 ConnectFakeSignaling();
4014 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4015 virtual_socket_server()->UpdateDelayDistribution();
4016
4017 // Set "offer to receive audio/video" without adding any tracks, so we just
4018 // set up ICE/DTLS with no media.
4019 PeerConnectionInterface::RTCOfferAnswerOptions options;
4020 options.offer_to_receive_audio = 1;
4021 options.offer_to_receive_video = 1;
4022 caller()->SetOfferAnswerOptions(options);
4023 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-08 00:21:014024 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
4025 fake_clock);
Seth Hampson1d4a76d2018-06-19 21:31:414026 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4027 // If this is not done a DCHECK can be hit in ports.cc, because a large
4028 // negative number is calculated for the rtt due to the global clock changing.
4029 caller()->pc()->Close();
4030 callee()->pc()->Close();
deadbeef1dcb1642017-03-30 04:08:164031}
4032
Jonas Orelandbdcee282017-10-10 12:01:404033// Verify that a TurnCustomizer passed in through RTCConfiguration
4034// is actually used by the underlying TURN candidate pair.
4035// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 19:54:424036TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 12:01:404037 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4038 3478};
4039 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4040 0};
4041 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4042 3478};
4043 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4044 0};
Seth Hampsonaed71642018-06-11 14:41:324045 CreateTurnServer(turn_server_1_internal_address,
4046 turn_server_1_external_address);
4047 CreateTurnServer(turn_server_2_internal_address,
4048 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 12:01:404049
4050 PeerConnectionInterface::RTCConfiguration client_1_config;
4051 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4052 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4053 ice_server_1.username = "test";
4054 ice_server_1.password = "test";
4055 client_1_config.servers.push_back(ice_server_1);
4056 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 14:41:324057 auto* customizer1 = CreateTurnCustomizer();
4058 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 12:01:404059
4060 PeerConnectionInterface::RTCConfiguration client_2_config;
4061 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4062 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4063 ice_server_2.username = "test";
4064 ice_server_2.password = "test";
4065 client_2_config.servers.push_back(ice_server_2);
4066 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 14:41:324067 auto* customizer2 = CreateTurnCustomizer();
4068 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 12:01:404069
4070 ASSERT_TRUE(
4071 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4072 ConnectFakeSignaling();
4073
4074 // Set "offer to receive audio/video" without adding any tracks, so we just
4075 // set up ICE/DTLS with no media.
4076 PeerConnectionInterface::RTCOfferAnswerOptions options;
4077 options.offer_to_receive_audio = 1;
4078 options.offer_to_receive_video = 1;
4079 caller()->SetOfferAnswerOptions(options);
4080 caller()->CreateAndSetAndSignalOffer();
4081 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4082
Seth Hampsonaed71642018-06-11 14:41:324083 ExpectTurnCustomizerCountersIncremented(customizer1);
4084 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 12:01:404085}
4086
Benjamin Wright2d5f3cb2018-05-22 21:46:064087// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4088// send media between the caller and the callee.
4089TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4090 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4091 3478};
4092 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4093
4094 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 14:41:324095 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4096 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 21:46:064097
4098 webrtc::PeerConnectionInterface::IceServer ice_server;
4099 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4100 ice_server.username = "test";
4101 ice_server.password = "test";
4102
4103 PeerConnectionInterface::RTCConfiguration client_1_config;
4104 client_1_config.servers.push_back(ice_server);
4105 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4106
4107 PeerConnectionInterface::RTCConfiguration client_2_config;
4108 client_2_config.servers.push_back(ice_server);
4109 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4110
4111 ASSERT_TRUE(
4112 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4113
4114 // Do normal offer/answer and wait for ICE to complete.
4115 ConnectFakeSignaling();
4116 caller()->AddAudioVideoTracks();
4117 callee()->AddAudioVideoTracks();
4118 caller()->CreateAndSetAndSignalOffer();
4119 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4120 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4121 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4122
4123 MediaExpectations media_expectations;
4124 media_expectations.ExpectBidirectionalAudioAndVideo();
4125 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4126}
4127
Benjamin Wrightd6f86e82018-05-08 20:12:254128// Verify that a SSLCertificateVerifier passed in through
4129// PeerConnectionDependencies is actually used by the underlying SSL
4130// implementation to determine whether a certificate presented by the TURN
4131// server is accepted by the client. Note that openssladapter_unittest.cc
4132// contains more detailed, lower-level tests.
4133TEST_P(PeerConnectionIntegrationTest,
4134 SSLCertificateVerifierUsedForTurnConnections) {
4135 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4136 3478};
4137 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4138
4139 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4140 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 14:41:324141 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4142 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 20:12:254143
4144 webrtc::PeerConnectionInterface::IceServer ice_server;
4145 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4146 ice_server.username = "test";
4147 ice_server.password = "test";
4148
4149 PeerConnectionInterface::RTCConfiguration client_1_config;
4150 client_1_config.servers.push_back(ice_server);
4151 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4152
4153 PeerConnectionInterface::RTCConfiguration client_2_config;
4154 client_2_config.servers.push_back(ice_server);
4155 // Setting the type to kRelay forces the connection to go through a TURN
4156 // server.
4157 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4158
4159 // Get a copy to the pointer so we can verify calls later.
4160 rtc::TestCertificateVerifier* client_1_cert_verifier =
4161 new rtc::TestCertificateVerifier();
4162 client_1_cert_verifier->verify_certificate_ = true;
4163 rtc::TestCertificateVerifier* client_2_cert_verifier =
4164 new rtc::TestCertificateVerifier();
4165 client_2_cert_verifier->verify_certificate_ = true;
4166
4167 // Create the dependencies with the test certificate verifier.
4168 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4169 client_1_deps.tls_cert_verifier =
4170 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4171 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4172 client_2_deps.tls_cert_verifier =
4173 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4174
4175 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4176 client_1_config, std::move(client_1_deps), client_2_config,
4177 std::move(client_2_deps)));
4178 ConnectFakeSignaling();
4179
4180 // Set "offer to receive audio/video" without adding any tracks, so we just
4181 // set up ICE/DTLS with no media.
4182 PeerConnectionInterface::RTCOfferAnswerOptions options;
4183 options.offer_to_receive_audio = 1;
4184 options.offer_to_receive_video = 1;
4185 caller()->SetOfferAnswerOptions(options);
4186 caller()->CreateAndSetAndSignalOffer();
4187 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4188
4189 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4190 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 20:12:254191}
4192
4193TEST_P(PeerConnectionIntegrationTest,
4194 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4195 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4196 3478};
4197 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4198
4199 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4200 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 14:41:324201 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4202 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 20:12:254203
4204 webrtc::PeerConnectionInterface::IceServer ice_server;
4205 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4206 ice_server.username = "test";
4207 ice_server.password = "test";
4208
4209 PeerConnectionInterface::RTCConfiguration client_1_config;
4210 client_1_config.servers.push_back(ice_server);
4211 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4212
4213 PeerConnectionInterface::RTCConfiguration client_2_config;
4214 client_2_config.servers.push_back(ice_server);
4215 // Setting the type to kRelay forces the connection to go through a TURN
4216 // server.
4217 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4218
4219 // Get a copy to the pointer so we can verify calls later.
4220 rtc::TestCertificateVerifier* client_1_cert_verifier =
4221 new rtc::TestCertificateVerifier();
4222 client_1_cert_verifier->verify_certificate_ = false;
4223 rtc::TestCertificateVerifier* client_2_cert_verifier =
4224 new rtc::TestCertificateVerifier();
4225 client_2_cert_verifier->verify_certificate_ = false;
4226
4227 // Create the dependencies with the test certificate verifier.
4228 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4229 client_1_deps.tls_cert_verifier =
4230 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4231 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4232 client_2_deps.tls_cert_verifier =
4233 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4234
4235 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4236 client_1_config, std::move(client_1_deps), client_2_config,
4237 std::move(client_2_deps)));
4238 ConnectFakeSignaling();
4239
4240 // Set "offer to receive audio/video" without adding any tracks, so we just
4241 // set up ICE/DTLS with no media.
4242 PeerConnectionInterface::RTCOfferAnswerOptions options;
4243 options.offer_to_receive_audio = 1;
4244 options.offer_to_receive_video = 1;
4245 caller()->SetOfferAnswerOptions(options);
4246 caller()->CreateAndSetAndSignalOffer();
4247 bool wait_res = true;
4248 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4249 // properly, should be able to just wait for a state of "failed" instead of
4250 // waiting a fixed 10 seconds.
4251 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4252 ASSERT_FALSE(wait_res);
4253
4254 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4255 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 20:12:254256}
4257
deadbeefc964d0b2017-04-03 17:03:354258// Test that audio and video flow end-to-end when codec names don't use the
4259// expected casing, given that they're supposed to be case insensitive. To test
4260// this, all but one codec is removed from each media description, and its
4261// casing is changed.
4262//
4263// In the past, this has regressed and caused crashes/black video, due to the
4264// fact that code at some layers was doing case-insensitive comparisons and
4265// code at other layers was not.
Seth Hampson2f0d7022018-02-20 19:54:424266TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 17:03:354267 ASSERT_TRUE(CreatePeerConnectionWrappers());
4268 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:494269 caller()->AddAudioVideoTracks();
4270 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 17:03:354271
4272 // Remove all but one audio/video codec (opus and VP8), and change the
4273 // casing of the caller's generated offer.
4274 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4275 cricket::AudioContentDescription* audio =
4276 GetFirstAudioContentDescription(description);
4277 ASSERT_NE(nullptr, audio);
4278 auto audio_codecs = audio->codecs();
4279 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4280 [](const cricket::AudioCodec& codec) {
4281 return codec.name != "opus";
4282 }),
4283 audio_codecs.end());
4284 ASSERT_EQ(1u, audio_codecs.size());
4285 audio_codecs[0].name = "OpUs";
4286 audio->set_codecs(audio_codecs);
4287
4288 cricket::VideoContentDescription* video =
4289 GetFirstVideoContentDescription(description);
4290 ASSERT_NE(nullptr, video);
4291 auto video_codecs = video->codecs();
4292 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4293 [](const cricket::VideoCodec& codec) {
4294 return codec.name != "VP8";
4295 }),
4296 video_codecs.end());
4297 ASSERT_EQ(1u, video_codecs.size());
4298 video_codecs[0].name = "vP8";
4299 video->set_codecs(video_codecs);
4300 });
4301
4302 caller()->CreateAndSetAndSignalOffer();
4303 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4304
4305 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:424306 MediaExpectations media_expectations;
4307 media_expectations.ExpectBidirectionalAudioAndVideo();
4308 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 17:03:354309}
4310
Jonas Oreland49ac5952018-09-26 14:04:324311TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 14:39:054312 ASSERT_TRUE(CreatePeerConnectionWrappers());
4313 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:494314 caller()->AddAudioTrack();
hbos8d609f62017-04-10 14:39:054315 caller()->CreateAndSetAndSignalOffer();
4316 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 23:01:174317 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 19:54:424318 MediaExpectations media_expectations;
4319 media_expectations.CalleeExpectsSomeAudio(1);
4320 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 14:04:324321 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 14:39:054322 auto receiver = callee()->pc()->GetReceivers()[0];
4323 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 14:04:324324 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 14:39:054325 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4326 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 14:04:324327 sources[0].source_id());
4328 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
4329}
4330
4331TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
4332 ASSERT_TRUE(CreatePeerConnectionWrappers());
4333 ConnectFakeSignaling();
4334 caller()->AddVideoTrack();
4335 caller()->CreateAndSetAndSignalOffer();
4336 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4337 // Wait for one video frame to be received by the callee.
4338 MediaExpectations media_expectations;
4339 media_expectations.CalleeExpectsSomeVideo(1);
4340 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4341 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
4342 auto receiver = callee()->pc()->GetReceivers()[0];
4343 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
4344 auto sources = receiver->GetSources();
4345 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4346 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4347 sources[0].source_id());
4348 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 14:39:054349}
4350
deadbeef2f425aa2017-04-14 17:41:324351// Test that if a track is removed and added again with a different stream ID,
4352// the new stream ID is successfully communicated in SDP and media continues to
4353// flow end-to-end.
Seth Hampson2f0d7022018-02-20 19:54:424354// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4355// it will not reuse a transceiver that has already been sending. After creating
4356// a new transceiver it tries to create an offer with two senders of the same
4357// track ids and it fails.
4358TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 17:41:324359 ASSERT_TRUE(CreatePeerConnectionWrappers());
4360 ConnectFakeSignaling();
4361
deadbeef2f425aa2017-04-14 17:41:324362 // Add track using stream 1, do offer/answer.
4363 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4364 caller()->CreateLocalAudioTrack();
4365 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 18:13:444366 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 17:41:324367 caller()->CreateAndSetAndSignalOffer();
4368 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:424369 {
4370 MediaExpectations media_expectations;
4371 media_expectations.CalleeExpectsSomeAudio(1);
4372 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4373 }
deadbeef2f425aa2017-04-14 17:41:324374 // Remove the sender, and create a new one with the new stream.
4375 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 18:13:444376 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 17:41:324377 caller()->CreateAndSetAndSignalOffer();
4378 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4379 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 19:54:424380 {
4381 MediaExpectations media_expectations;
4382 media_expectations.CalleeExpectsSomeAudio();
4383 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4384 }
deadbeef2f425aa2017-04-14 17:41:324385}
4386
Seth Hampson2f0d7022018-02-20 19:54:424387TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 14:29:404388 ASSERT_TRUE(CreatePeerConnectionWrappers());
4389 ConnectFakeSignaling();
4390
Karl Wiberg918f50c2018-07-05 09:40:334391 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Elad Alon99c3fe52017-10-13 14:29:404392 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4393 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4394 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 16:38:144395 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4396 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 14:29:404397
Steve Anton15324772018-01-16 18:26:494398 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 14:29:404399 caller()->CreateAndSetAndSignalOffer();
4400 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4401}
4402
Steve Antonede9ca52017-10-16 20:04:274403// Test that if candidates are only signaled by applying full session
4404// descriptions (instead of using AddIceCandidate), the peers can connect to
4405// each other and exchange media.
Seth Hampson2f0d7022018-02-20 19:54:424406TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 20:04:274407 ASSERT_TRUE(CreatePeerConnectionWrappers());
4408 // Each side will signal the session descriptions but not candidates.
4409 ConnectFakeSignalingForSdpOnly();
4410
4411 // Add audio video track and exchange the initial offer/answer with media
4412 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 18:26:494413 caller()->AddAudioVideoTracks();
4414 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 20:04:274415 caller()->CreateAndSetAndSignalOffer();
4416
4417 // Wait for all candidates to be gathered on both the caller and callee.
4418 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4419 caller()->ice_gathering_state(), kDefaultTimeout);
4420 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4421 callee()->ice_gathering_state(), kDefaultTimeout);
4422
4423 // The candidates will now be included in the session description, so
4424 // signaling them will start the ICE connection.
4425 caller()->CreateAndSetAndSignalOffer();
4426 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4427
4428 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 19:54:424429 MediaExpectations media_expectations;
4430 media_expectations.ExpectBidirectionalAudioAndVideo();
4431 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 20:04:274432}
4433
henrika5f6bf242017-11-01 10:06:564434// Test that SetAudioPlayout can be used to disable audio playout from the
4435// start, then later enable it. This may be useful, for example, if the caller
4436// needs to play a local ringtone until some event occurs, after which it
4437// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 19:54:424438TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 10:06:564439 ASSERT_TRUE(CreatePeerConnectionWrappers());
4440 ConnectFakeSignaling();
4441
4442 // Set up audio-only call where audio playout is disabled on caller's side.
4443 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 18:26:494444 caller()->AddAudioTrack();
4445 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 10:06:564446 caller()->CreateAndSetAndSignalOffer();
4447 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4448
4449 // Pump messages for a second.
4450 WAIT(false, 1000);
4451 // Since audio playout is disabled, the caller shouldn't have received
4452 // anything (at the playout level, at least).
4453 EXPECT_EQ(0, caller()->audio_frames_received());
4454 // As a sanity check, make sure the callee (for which playout isn't disabled)
4455 // did still see frames on its audio level.
4456 ASSERT_GT(callee()->audio_frames_received(), 0);
4457
4458 // Enable playout again, and ensure audio starts flowing.
4459 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 19:54:424460 MediaExpectations media_expectations;
4461 media_expectations.ExpectBidirectionalAudio();
4462 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 10:06:564463}
4464
4465double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4466 auto report = pc->NewGetStats();
4467 auto track_stats_list =
4468 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4469 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4470 for (const auto* track_stats : track_stats_list) {
4471 if (track_stats->remote_source.is_defined() &&
4472 *track_stats->remote_source) {
4473 remote_track_stats = track_stats;
4474 break;
4475 }
4476 }
4477
4478 if (!remote_track_stats->total_audio_energy.is_defined()) {
4479 return 0.0;
4480 }
4481 return *remote_track_stats->total_audio_energy;
4482}
4483
4484// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4485// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 19:54:424486TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 10:06:564487 DisableAudioPlayoutStillGeneratesAudioStats) {
4488 ASSERT_TRUE(CreatePeerConnectionWrappers());
4489 ConnectFakeSignaling();
4490
4491 // Set up audio-only call where playout is disabled but audio-processing is
4492 // still active.
Steve Anton15324772018-01-16 18:26:494493 caller()->AddAudioTrack();
4494 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 10:06:564495 caller()->pc()->SetAudioPlayout(false);
4496
4497 caller()->CreateAndSetAndSignalOffer();
4498 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4499
4500 // Wait for the callee to receive audio stats.
4501 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4502}
4503
henrika4f167df2017-11-01 13:45:554504// Test that SetAudioRecording can be used to disable audio recording from the
4505// start, then later enable it. This may be useful, for example, if the caller
4506// wants to ensure that no audio resources are active before a certain state
4507// is reached.
Seth Hampson2f0d7022018-02-20 19:54:424508TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 13:45:554509 ASSERT_TRUE(CreatePeerConnectionWrappers());
4510 ConnectFakeSignaling();
4511
4512 // Set up audio-only call where audio recording is disabled on caller's side.
4513 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 18:26:494514 caller()->AddAudioTrack();
4515 callee()->AddAudioTrack();
henrika4f167df2017-11-01 13:45:554516 caller()->CreateAndSetAndSignalOffer();
4517 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4518
4519 // Pump messages for a second.
4520 WAIT(false, 1000);
4521 // Since caller has disabled audio recording, the callee shouldn't have
4522 // received anything.
4523 EXPECT_EQ(0, callee()->audio_frames_received());
4524 // As a sanity check, make sure the caller did still see frames on its
4525 // audio level since audio recording is enabled on the calle side.
4526 ASSERT_GT(caller()->audio_frames_received(), 0);
4527
4528 // Enable audio recording again, and ensure audio starts flowing.
4529 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 19:54:424530 MediaExpectations media_expectations;
4531 media_expectations.ExpectBidirectionalAudio();
4532 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 13:45:554533}
4534
Taylor Brandstetter389a97c2018-01-04 00:26:064535// Test that after closing PeerConnections, they stop sending any packets (ICE,
4536// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 19:54:424537TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-04 00:26:064538 // Set up audio/video/data, wait for some frames to be received.
4539 ASSERT_TRUE(CreatePeerConnectionWrappers());
4540 ConnectFakeSignaling();
Steve Anton15324772018-01-16 18:26:494541 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-04 00:26:064542#ifdef HAVE_SCTP
4543 caller()->CreateDataChannel();
4544#endif
4545 caller()->CreateAndSetAndSignalOffer();
4546 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 19:54:424547 MediaExpectations media_expectations;
4548 media_expectations.CalleeExpectsSomeAudioAndVideo();
4549 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-04 00:26:064550 // Close PeerConnections.
4551 caller()->pc()->Close();
4552 callee()->pc()->Close();
4553 // Pump messages for a second, and ensure no new packets end up sent.
4554 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4555 WAIT(false, 1000);
4556 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4557 EXPECT_EQ(sent_packets_a, sent_packets_b);
4558}
4559
Steve Anton7eca0932018-03-30 22:18:414560// Test that transport stats are generated by the RTCStatsCollector for a
4561// connection that only involves data channels. This is a regression test for
4562// crbug.com/826972.
4563#ifdef HAVE_SCTP
4564TEST_P(PeerConnectionIntegrationTest,
4565 TransportStatsReportedForDataChannelOnlyConnection) {
4566 ASSERT_TRUE(CreatePeerConnectionWrappers());
4567 ConnectFakeSignaling();
4568 caller()->CreateDataChannel();
4569
4570 caller()->CreateAndSetAndSignalOffer();
4571 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4572 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4573
4574 auto caller_report = caller()->NewGetStats();
4575 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4576 auto callee_report = callee()->NewGetStats();
4577 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4578}
4579#endif // HAVE_SCTP
4580
Qingsi Wang7685e862018-06-12 03:15:464581TEST_P(PeerConnectionIntegrationTest,
4582 IceEventsGeneratedAndLoggedInRtcEventLog) {
4583 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4584 ConnectFakeSignaling();
4585 PeerConnectionInterface::RTCOfferAnswerOptions options;
4586 options.offer_to_receive_audio = 1;
4587 caller()->SetOfferAnswerOptions(options);
4588 caller()->CreateAndSetAndSignalOffer();
4589 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4590 ASSERT_NE(nullptr, caller()->event_log_factory());
4591 ASSERT_NE(nullptr, callee()->event_log_factory());
4592 webrtc::FakeRtcEventLog* caller_event_log =
4593 static_cast<webrtc::FakeRtcEventLog*>(
4594 caller()->event_log_factory()->last_log_created());
4595 webrtc::FakeRtcEventLog* callee_event_log =
4596 static_cast<webrtc::FakeRtcEventLog*>(
4597 callee()->event_log_factory()->last_log_created());
4598 ASSERT_NE(nullptr, caller_event_log);
4599 ASSERT_NE(nullptr, callee_event_log);
4600 int caller_ice_config_count = caller_event_log->GetEventCount(
4601 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4602 int caller_ice_event_count = caller_event_log->GetEventCount(
4603 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4604 int callee_ice_config_count = callee_event_log->GetEventCount(
4605 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4606 int callee_ice_event_count = callee_event_log->GetEventCount(
4607 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4608 EXPECT_LT(0, caller_ice_config_count);
4609 EXPECT_LT(0, caller_ice_event_count);
4610 EXPECT_LT(0, callee_ice_config_count);
4611 EXPECT_LT(0, callee_ice_event_count);
4612}
4613
Seth Hampson2f0d7022018-02-20 19:54:424614INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest,
4615 PeerConnectionIntegrationTest,
4616 Values(SdpSemantics::kPlanB,
4617 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-18 01:41:024618
Steve Anton74255ff2018-01-25 02:32:574619// Tests that verify interoperability between Plan B and Unified Plan
4620// PeerConnections.
4621class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 19:54:424622 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-25 02:32:574623 public ::testing::WithParamInterface<
4624 std::tuple<SdpSemantics, SdpSemantics>> {
4625 protected:
Seth Hampson2f0d7022018-02-20 19:54:424626 // Setting the SdpSemantics for the base test to kDefault does not matter
4627 // because we specify not to use the test semantics when creating
4628 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-25 02:32:574629 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-13 00:21:034630 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 19:54:424631 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-25 02:32:574632 callee_semantics_(std::get<1>(GetParam())) {}
4633
4634 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-13 00:21:034635 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4636 callee_semantics_);
Steve Anton74255ff2018-01-25 02:32:574637 }
4638
4639 const SdpSemantics caller_semantics_;
4640 const SdpSemantics callee_semantics_;
4641};
4642
4643TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4644 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4645 ConnectFakeSignaling();
4646
4647 caller()->CreateAndSetAndSignalOffer();
4648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4649}
4650
4651TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4652 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4653 ConnectFakeSignaling();
4654 auto audio_sender = caller()->AddAudioTrack();
4655
4656 caller()->CreateAndSetAndSignalOffer();
4657 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4658
4659 // Verify that one audio receiver has been created on the remote and that it
4660 // has the same track ID as the sending track.
4661 auto receivers = callee()->pc()->GetReceivers();
4662 ASSERT_EQ(1u, receivers.size());
4663 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4664 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4665
Seth Hampson2f0d7022018-02-20 19:54:424666 MediaExpectations media_expectations;
4667 media_expectations.CalleeExpectsSomeAudio();
4668 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574669}
4670
4671TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4672 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4673 ConnectFakeSignaling();
4674 auto video_sender = caller()->AddVideoTrack();
4675 auto audio_sender = caller()->AddAudioTrack();
4676
4677 caller()->CreateAndSetAndSignalOffer();
4678 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4679
4680 // Verify that one audio and one video receiver have been created on the
4681 // remote and that they have the same track IDs as the sending tracks.
4682 auto audio_receivers =
4683 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4684 ASSERT_EQ(1u, audio_receivers.size());
4685 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4686 auto video_receivers =
4687 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4688 ASSERT_EQ(1u, video_receivers.size());
4689 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4690
Seth Hampson2f0d7022018-02-20 19:54:424691 MediaExpectations media_expectations;
4692 media_expectations.CalleeExpectsSomeAudioAndVideo();
4693 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574694}
4695
4696TEST_P(PeerConnectionIntegrationInteropTest,
4697 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
4698 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4699 ConnectFakeSignaling();
4700 caller()->AddAudioVideoTracks();
4701 callee()->AddAudioVideoTracks();
4702
4703 caller()->CreateAndSetAndSignalOffer();
4704 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4705
Seth Hampson2f0d7022018-02-20 19:54:424706 MediaExpectations media_expectations;
4707 media_expectations.ExpectBidirectionalAudioAndVideo();
4708 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574709}
4710
4711TEST_P(PeerConnectionIntegrationInteropTest,
4712 ReverseRolesOneAudioLocalToOneVideoRemote) {
4713 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4714 ConnectFakeSignaling();
4715 caller()->AddAudioTrack();
4716 callee()->AddVideoTrack();
4717
4718 caller()->CreateAndSetAndSignalOffer();
4719 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4720
4721 // Verify that only the audio track has been negotiated.
4722 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
4723 // Might also check that the callee's NegotiationNeeded flag is set.
4724
4725 // Reverse roles.
4726 callee()->CreateAndSetAndSignalOffer();
4727 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4728
Seth Hampson2f0d7022018-02-20 19:54:424729 MediaExpectations media_expectations;
4730 media_expectations.CallerExpectsSomeVideo();
4731 media_expectations.CalleeExpectsSomeAudio();
4732 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574733}
4734
Steve Antonba42e992018-04-09 21:10:014735INSTANTIATE_TEST_CASE_P(
4736 PeerConnectionIntegrationTest,
4737 PeerConnectionIntegrationInteropTest,
4738 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4739 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
4740
4741// Test that if the Unified Plan side offers two video tracks then the Plan B
4742// side will only see the first one and ignore the second.
4743TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-13 00:21:034744 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
4745 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-25 02:32:574746 ConnectFakeSignaling();
4747 auto first_sender = caller()->AddVideoTrack();
4748 caller()->AddVideoTrack();
4749
4750 caller()->CreateAndSetAndSignalOffer();
4751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4752
4753 // Verify that there is only one receiver and it corresponds to the first
4754 // added track.
4755 auto receivers = callee()->pc()->GetReceivers();
4756 ASSERT_EQ(1u, receivers.size());
4757 EXPECT_TRUE(receivers[0]->track()->enabled());
4758 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
4759
Seth Hampson2f0d7022018-02-20 19:54:424760 MediaExpectations media_expectations;
4761 media_expectations.CalleeExpectsSomeVideo();
4762 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-25 02:32:574763}
4764
deadbeef1dcb1642017-03-30 04:08:164765} // namespace
4766
4767#endif // if !defined(THREAD_SANITIZER)