blob: 2d7b33106ca1444444e3f18d87d4052b43cff5cc [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// Disable for TSan v2, see
12// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
13#if !defined(THREAD_SANITIZER)
14
15#include <stdio.h>
16
deadbeef1dcb1642017-03-29 21:08:16 -070017#include <functional>
18#include <list>
19#include <map>
20#include <memory>
21#include <utility>
22#include <vector>
23
Steve Anton64b626b2019-01-28 17:25:26 -080024#include "absl/algorithm/container.h"
Qingsi Wang1dac6d82018-12-12 15:28:47 -080025#include "absl/memory/memory.h"
Karl Wiberg1b0eae32017-10-17 14:48:54 +020026#include "api/audio_codecs/builtin_audio_decoder_factory.h"
27#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "api/media_stream_interface.h"
29#include "api/peer_connection_interface.h"
30#include "api/peer_connection_proxy.h"
31#include "api/rtp_receiver_interface.h"
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080032#include "api/test/loopback_media_transport.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "api/uma_metrics.h"
Anders Carlsson67537952018-05-03 11:28:29 +020034#include "api/video_codecs/builtin_video_decoder_factory.h"
35#include "api/video_codecs/builtin_video_encoder_factory.h"
36#include "api/video_codecs/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070037#include "call/call.h"
38#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Bjorn Tereliusb8b3c992019-01-09 11:15:34 +010039#include "logging/rtc_event_log/rtc_event_log_factory.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070040#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080041#include "media/engine/fake_webrtc_video_engine.h"
42#include "media/engine/webrtc_media_engine.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070043#include "modules/audio_processing/include/audio_processing.h"
Steve Anton10542f22019-01-11 09:11:00 -080044#include "p2p/base/mock_async_resolver.h"
45#include "p2p/base/p2p_constants.h"
46#include "p2p/base/port_interface.h"
47#include "p2p/base/test_stun_server.h"
48#include "p2p/base/test_turn_customizer.h"
49#include "p2p/base/test_turn_server.h"
50#include "p2p/client/basic_port_allocator.h"
51#include "pc/dtmf_sender.h"
52#include "pc/local_audio_source.h"
53#include "pc/media_session.h"
54#include "pc/peer_connection.h"
55#include "pc/peer_connection_factory.h"
56#include "pc/rtp_media_utils.h"
57#include "pc/session_description.h"
58#include "pc/test/fake_audio_capture_module.h"
59#include "pc/test/fake_periodic_video_track_source.h"
60#include "pc/test/fake_rtc_certificate_generator.h"
61#include "pc/test/fake_video_track_renderer.h"
62#include "pc/test/mock_peer_connection_observers.h"
63#include "rtc_base/fake_network.h"
64#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020065#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020066#include "rtc_base/numerics/safe_conversions.h"
Steve Anton10542f22019-01-11 09:11:00 -080067#include "rtc_base/test_certificate_verifier.h"
68#include "rtc_base/time_utils.h"
69#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020070#include "system_wrappers/include/metrics.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020071#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070072
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010073namespace webrtc {
74namespace {
75
76using ::cricket::ContentInfo;
77using ::cricket::StreamParams;
78using ::rtc::SocketAddress;
79using ::testing::_;
Seth Hampson2f0d7022018-02-20 11:54:42 -080080using ::testing::Combine;
Steve Anton64b626b2019-01-28 17:25:26 -080081using ::testing::Contains;
Steve Antonede9ca52017-10-16 13:04:27 -070082using ::testing::ElementsAre;
Qingsi Wang1dac6d82018-12-12 15:28:47 -080083using ::testing::NiceMock;
Steve Anton64b626b2019-01-28 17:25:26 -080084using ::testing::Return;
Zach Stein6fcdc2f2018-08-23 16:25:55 -070085using ::testing::SetArgPointee;
Steve Antonffa6ce42018-11-30 09:26:08 -080086using ::testing::UnorderedElementsAreArray;
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010087using ::testing::Values;
Steve Anton74255ff2018-01-24 18:32:57 -080088using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
deadbeef1dcb1642017-03-29 21:08:16 -070089
90static const int kDefaultTimeout = 10000;
91static const int kMaxWaitForStatsMs = 3000;
92static const int kMaxWaitForActivationMs = 5000;
93static const int kMaxWaitForFramesMs = 10000;
94// Default number of audio/video frames to wait for before considering a test
95// successful.
96static const int kDefaultExpectedAudioFrameCount = 3;
97static const int kDefaultExpectedVideoFrameCount = 3;
98
deadbeef1dcb1642017-03-29 21:08:16 -070099static const char kDataChannelLabel[] = "data_channel";
100
101// SRTP cipher name negotiated by the tests. This must be updated if the
102// default changes.
Taylor Brandstetterfd350d72018-04-03 16:29:26 -0700103static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80;
deadbeef1dcb1642017-03-29 21:08:16 -0700104static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
105
Steve Antonede9ca52017-10-16 13:04:27 -0700106static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0);
107
deadbeef1dcb1642017-03-29 21:08:16 -0700108// Helper function for constructing offer/answer options to initiate an ICE
109// restart.
110PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
111 PeerConnectionInterface::RTCOfferAnswerOptions options;
112 options.ice_restart = true;
113 return options;
114}
115
deadbeefd8ad7882017-04-18 16:01:17 -0700116// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic"
117// attribute from received SDP, simulating a legacy endpoint.
118void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
119 for (ContentInfo& content : desc->contents()) {
Steve Antonb1c1de12017-12-21 15:14:30 -0800120 content.media_description()->mutable_streams().clear();
deadbeefd8ad7882017-04-18 16:01:17 -0700121 }
122 desc->set_msid_supported(false);
Henrik Boström5b147782018-12-04 11:25:05 +0100123 desc->set_msid_signaling(0);
deadbeefd8ad7882017-04-18 16:01:17 -0700124}
125
Seth Hampson5897a6e2018-04-03 11:16:33 -0700126// Removes all stream information besides the stream ids, simulating an
127// endpoint that only signals a=msid lines to convey stream_ids.
128void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
129 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700130 std::string track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700131 std::vector<std::string> stream_ids;
132 if (!content.media_description()->streams().empty()) {
Steve Antondf527fd2018-04-27 15:52:03 -0700133 const StreamParams& first_stream =
134 content.media_description()->streams()[0];
135 track_id = first_stream.id;
136 stream_ids = first_stream.stream_ids();
Seth Hampson5897a6e2018-04-03 11:16:33 -0700137 }
138 content.media_description()->mutable_streams().clear();
Steve Antondf527fd2018-04-27 15:52:03 -0700139 StreamParams new_stream;
140 new_stream.id = track_id;
Seth Hampson5897a6e2018-04-03 11:16:33 -0700141 new_stream.set_stream_ids(stream_ids);
142 content.media_description()->AddStream(new_stream);
143 }
144}
145
zhihuangf8164932017-05-19 13:09:47 -0700146int FindFirstMediaStatsIndexByKind(
147 const std::string& kind,
148 const std::vector<const webrtc::RTCMediaStreamTrackStats*>&
149 media_stats_vec) {
150 for (size_t i = 0; i < media_stats_vec.size(); i++) {
151 if (media_stats_vec[i]->kind.ValueToString() == kind) {
152 return i;
153 }
154 }
155 return -1;
156}
157
deadbeef1dcb1642017-03-29 21:08:16 -0700158class SignalingMessageReceiver {
159 public:
Steve Antona3a92c22017-12-07 10:27:41 -0800160 virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700161 virtual void ReceiveIceMessage(const std::string& sdp_mid,
162 int sdp_mline_index,
163 const std::string& msg) = 0;
164
165 protected:
166 SignalingMessageReceiver() {}
167 virtual ~SignalingMessageReceiver() {}
168};
169
170class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
171 public:
172 explicit MockRtpReceiverObserver(cricket::MediaType media_type)
173 : expected_media_type_(media_type) {}
174
175 void OnFirstPacketReceived(cricket::MediaType media_type) override {
176 ASSERT_EQ(expected_media_type_, media_type);
177 first_packet_received_ = true;
178 }
179
180 bool first_packet_received() const { return first_packet_received_; }
181
182 virtual ~MockRtpReceiverObserver() {}
183
184 private:
185 bool first_packet_received_ = false;
186 cricket::MediaType expected_media_type_;
187};
188
189// Helper class that wraps a peer connection, observes it, and can accept
190// signaling messages from another wrapper.
191//
192// Uses a fake network, fake A/V capture, and optionally fake
193// encoders/decoders, though they aren't used by default since they don't
194// advertise support of any codecs.
Steve Anton94286cb2017-09-26 16:20:19 -0700195// TODO(steveanton): See how this could become a subclass of
Seth Hampson2f0d7022018-02-20 11:54:42 -0800196// PeerConnectionWrapper defined in peerconnectionwrapper.h.
deadbeef1dcb1642017-03-29 21:08:16 -0700197class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
Steve Anton15324772018-01-16 10:26:49 -0800198 public SignalingMessageReceiver {
deadbeef1dcb1642017-03-29 21:08:16 -0700199 public:
200 // Different factory methods for convenience.
201 // TODO(deadbeef): Could use the pattern of:
202 //
203 // PeerConnectionWrapper =
204 // WrapperBuilder.WithConfig(...).WithOptions(...).build();
205 //
206 // To reduce some code duplication.
207 static PeerConnectionWrapper* CreateWithDtlsIdentityStore(
208 const std::string& debug_name,
209 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
210 rtc::Thread* network_thread,
211 rtc::Thread* worker_thread) {
212 PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700213 webrtc::PeerConnectionDependencies dependencies(nullptr);
214 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200215 if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800216 worker_thread, nullptr,
217 /*media_transport_factory=*/nullptr)) {
deadbeef1dcb1642017-03-29 21:08:16 -0700218 delete client;
219 return nullptr;
220 }
221 return client;
222 }
223
deadbeef2f425aa2017-04-14 10:41:32 -0700224 webrtc::PeerConnectionFactoryInterface* pc_factory() const {
225 return peer_connection_factory_.get();
226 }
227
deadbeef1dcb1642017-03-29 21:08:16 -0700228 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); }
229
230 // If a signaling message receiver is set (via ConnectFakeSignaling), this
231 // will set the whole offer/answer exchange in motion. Just need to wait for
232 // the signaling state to reach "stable".
233 void CreateAndSetAndSignalOffer() {
234 auto offer = CreateOffer();
235 ASSERT_NE(nullptr, offer);
236 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer)));
237 }
238
239 // Sets the options to be used when CreateAndSetAndSignalOffer is called, or
240 // when a remote offer is received (via fake signaling) and an answer is
241 // generated. By default, uses default options.
242 void SetOfferAnswerOptions(
243 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
244 offer_answer_options_ = options;
245 }
246
247 // Set a callback to be invoked when SDP is received via the fake signaling
248 // channel, which provides an opportunity to munge (modify) the SDP. This is
249 // used to test SDP being applied that a PeerConnection would normally not
250 // generate, but a non-JSEP endpoint might.
251 void SetReceivedSdpMunger(
252 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100253 received_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700254 }
255
deadbeefc964d0b2017-04-03 10:03:35 -0700256 // Similar to the above, but this is run on SDP immediately after it's
deadbeef1dcb1642017-03-29 21:08:16 -0700257 // generated.
258 void SetGeneratedSdpMunger(
259 std::function<void(cricket::SessionDescription*)> munger) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100260 generated_sdp_munger_ = std::move(munger);
deadbeef1dcb1642017-03-29 21:08:16 -0700261 }
262
Seth Hampson2f0d7022018-02-20 11:54:42 -0800263 // Set a callback to be invoked when a remote offer is received via the fake
264 // signaling channel. This provides an opportunity to change the
265 // PeerConnection state before an answer is created and sent to the caller.
266 void SetRemoteOfferHandler(std::function<void()> handler) {
267 remote_offer_handler_ = std::move(handler);
268 }
269
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800270 void SetRemoteAsyncResolver(rtc::MockAsyncResolver* resolver) {
271 remote_async_resolver_ = resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700272 }
273
Steve Antonede9ca52017-10-16 13:04:27 -0700274 // Every ICE connection state in order that has been seen by the observer.
275 std::vector<PeerConnectionInterface::IceConnectionState>
276 ice_connection_state_history() const {
277 return ice_connection_state_history_;
278 }
Steve Anton6f25b092017-10-23 09:39:20 -0700279 void clear_ice_connection_state_history() {
280 ice_connection_state_history_.clear();
281 }
Steve Antonede9ca52017-10-16 13:04:27 -0700282
Jonas Olsson635474e2018-10-18 15:58:17 +0200283 // Every PeerConnection state in order that has been seen by the observer.
284 std::vector<PeerConnectionInterface::PeerConnectionState>
285 peer_connection_state_history() const {
286 return peer_connection_state_history_;
287 }
288
Steve Antonede9ca52017-10-16 13:04:27 -0700289 // Every ICE gathering state in order that has been seen by the observer.
290 std::vector<PeerConnectionInterface::IceGatheringState>
291 ice_gathering_state_history() const {
292 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700293 }
294
Steve Anton15324772018-01-16 10:26:49 -0800295 void AddAudioVideoTracks() {
296 AddAudioTrack();
297 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700298 }
299
Steve Anton74255ff2018-01-24 18:32:57 -0800300 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
301 return AddTrack(CreateLocalAudioTrack());
302 }
deadbeef1dcb1642017-03-29 21:08:16 -0700303
Steve Anton74255ff2018-01-24 18:32:57 -0800304 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
305 return AddTrack(CreateLocalVideoTrack());
306 }
deadbeef1dcb1642017-03-29 21:08:16 -0700307
308 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200309 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700310 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200311 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700312 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200313 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700314 // TODO(perkj): Test audio source when it is implemented. Currently audio
315 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700316 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700317 source);
318 }
319
320 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Johannes Kron965e7942018-09-13 15:36:20 +0200321 webrtc::FakePeriodicVideoSource::Config config;
322 config.timestamp_offset_ms = rtc::TimeMillis();
323 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700324 }
325
326 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200327 CreateLocalVideoTrackWithConfig(
328 webrtc::FakePeriodicVideoSource::Config config) {
329 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700330 }
331
332 rtc::scoped_refptr<webrtc::VideoTrackInterface>
333 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200334 webrtc::FakePeriodicVideoSource::Config config;
335 config.rotation = rotation;
Johannes Kron965e7942018-09-13 15:36:20 +0200336 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200337 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700338 }
339
Steve Anton74255ff2018-01-24 18:32:57 -0800340 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
341 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800342 const std::vector<std::string>& stream_ids = {}) {
343 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800344 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800345 return result.MoveValue();
346 }
347
348 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
349 cricket::MediaType media_type) {
350 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100351 for (const auto& receiver : pc()->GetReceivers()) {
Steve Anton74255ff2018-01-24 18:32:57 -0800352 if (receiver->media_type() == media_type) {
353 receivers.push_back(receiver);
354 }
355 }
356 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700357 }
358
Seth Hampson2f0d7022018-02-20 11:54:42 -0800359 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
360 cricket::MediaType media_type) {
361 for (auto transceiver : pc()->GetTransceivers()) {
362 if (transceiver->receiver()->media_type() == media_type) {
363 return transceiver;
364 }
365 }
366 return nullptr;
367 }
368
deadbeef1dcb1642017-03-29 21:08:16 -0700369 bool SignalingStateStable() {
370 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
371 }
372
373 void CreateDataChannel() { CreateDataChannel(nullptr); }
374
375 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700376 CreateDataChannel(kDataChannelLabel, init);
377 }
378
379 void CreateDataChannel(const std::string& label,
380 const webrtc::DataChannelInit* init) {
381 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700382 ASSERT_TRUE(data_channel_.get() != nullptr);
383 data_observer_.reset(new MockDataChannelObserver(data_channel_));
384 }
385
386 DataChannelInterface* data_channel() { return data_channel_; }
387 const MockDataChannelObserver* data_observer() const {
388 return data_observer_.get();
389 }
390
391 int audio_frames_received() const {
392 return fake_audio_capture_module_->frames_received();
393 }
394
395 // Takes minimum of video frames received for each track.
396 //
397 // Can be used like:
398 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
399 //
400 // To ensure that all video tracks received at least a certain number of
401 // frames.
402 int min_video_frames_received_per_track() const {
403 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200404 if (fake_video_renderers_.empty()) {
405 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700406 }
deadbeef1dcb1642017-03-29 21:08:16 -0700407
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200408 for (const auto& pair : fake_video_renderers_) {
409 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700410 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200411 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700412 }
413
414 // Returns a MockStatsObserver in a state after stats gathering finished,
415 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700416 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700417 webrtc::MediaStreamTrackInterface* track) {
418 rtc::scoped_refptr<MockStatsObserver> observer(
419 new rtc::RefCountedObject<MockStatsObserver>());
420 EXPECT_TRUE(peer_connection_->GetStats(
421 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
422 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
423 return observer;
424 }
425
426 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700427 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
428 return OldGetStatsForTrack(nullptr);
429 }
430
431 // Synchronously gets stats and returns them. If it times out, fails the test
432 // and returns null.
433 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
434 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
435 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
436 peer_connection_->GetStats(callback);
437 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
438 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700439 }
440
441 int rendered_width() {
442 EXPECT_FALSE(fake_video_renderers_.empty());
443 return fake_video_renderers_.empty()
444 ? 0
445 : fake_video_renderers_.begin()->second->width();
446 }
447
448 int rendered_height() {
449 EXPECT_FALSE(fake_video_renderers_.empty());
450 return fake_video_renderers_.empty()
451 ? 0
452 : fake_video_renderers_.begin()->second->height();
453 }
454
455 double rendered_aspect_ratio() {
456 if (rendered_height() == 0) {
457 return 0.0;
458 }
459 return static_cast<double>(rendered_width()) / rendered_height();
460 }
461
462 webrtc::VideoRotation rendered_rotation() {
463 EXPECT_FALSE(fake_video_renderers_.empty());
464 return fake_video_renderers_.empty()
465 ? webrtc::kVideoRotation_0
466 : fake_video_renderers_.begin()->second->rotation();
467 }
468
469 int local_rendered_width() {
470 return local_video_renderer_ ? local_video_renderer_->width() : 0;
471 }
472
473 int local_rendered_height() {
474 return local_video_renderer_ ? local_video_renderer_->height() : 0;
475 }
476
477 double local_rendered_aspect_ratio() {
478 if (local_rendered_height() == 0) {
479 return 0.0;
480 }
481 return static_cast<double>(local_rendered_width()) /
482 local_rendered_height();
483 }
484
485 size_t number_of_remote_streams() {
486 if (!pc()) {
487 return 0;
488 }
489 return pc()->remote_streams()->count();
490 }
491
492 StreamCollectionInterface* remote_streams() const {
493 if (!pc()) {
494 ADD_FAILURE();
495 return nullptr;
496 }
497 return pc()->remote_streams();
498 }
499
500 StreamCollectionInterface* local_streams() {
501 if (!pc()) {
502 ADD_FAILURE();
503 return nullptr;
504 }
505 return pc()->local_streams();
506 }
507
508 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
509 return pc()->signaling_state();
510 }
511
512 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
513 return pc()->ice_connection_state();
514 }
515
Jonas Olsson7a6739e2019-01-15 16:31:55 +0100516 webrtc::PeerConnectionInterface::IceConnectionState
517 standardized_ice_connection_state() {
518 return pc()->standardized_ice_connection_state();
519 }
520
deadbeef1dcb1642017-03-29 21:08:16 -0700521 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
522 return pc()->ice_gathering_state();
523 }
524
525 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
526 // GetReceivers. They're updated automatically when a remote offer/answer
527 // from the fake signaling channel is applied, or when
528 // ResetRtpReceiverObservers below is called.
529 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
530 rtp_receiver_observers() {
531 return rtp_receiver_observers_;
532 }
533
534 void ResetRtpReceiverObservers() {
535 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100536 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
537 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700538 std::unique_ptr<MockRtpReceiverObserver> observer(
539 new MockRtpReceiverObserver(receiver->media_type()));
540 receiver->SetObserver(observer.get());
541 rtp_receiver_observers_.push_back(std::move(observer));
542 }
543 }
544
Steve Antonede9ca52017-10-16 13:04:27 -0700545 rtc::FakeNetworkManager* network() const {
546 return fake_network_manager_.get();
547 }
548 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
549
Qingsi Wang7685e862018-06-11 20:15:46 -0700550 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
551 return event_log_factory_;
552 }
553
deadbeef1dcb1642017-03-29 21:08:16 -0700554 private:
555 explicit PeerConnectionWrapper(const std::string& debug_name)
556 : debug_name_(debug_name) {}
557
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800558 bool Init(
559 const PeerConnectionFactory::Options* options,
560 const PeerConnectionInterface::RTCConfiguration* config,
561 webrtc::PeerConnectionDependencies dependencies,
562 rtc::Thread* network_thread,
563 rtc::Thread* worker_thread,
564 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
565 std::unique_ptr<webrtc::MediaTransportFactory> media_transport_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700566 // There's an error in this test code if Init ends up being called twice.
567 RTC_DCHECK(!peer_connection_);
568 RTC_DCHECK(!peer_connection_factory_);
569
570 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700571 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700572
573 std::unique_ptr<cricket::PortAllocator> port_allocator(
574 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700575 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700576 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
577 if (!fake_audio_capture_module_) {
578 return false;
579 }
deadbeef1dcb1642017-03-29 21:08:16 -0700580 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700581
582 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
583 pc_factory_dependencies.network_thread = network_thread;
584 pc_factory_dependencies.worker_thread = worker_thread;
585 pc_factory_dependencies.signaling_thread = signaling_thread;
586 pc_factory_dependencies.media_engine =
587 cricket::WebRtcMediaEngineFactory::Create(
588 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
589 fake_audio_capture_module_),
590 webrtc::CreateBuiltinAudioEncoderFactory(),
591 webrtc::CreateBuiltinAudioDecoderFactory(),
592 webrtc::CreateBuiltinVideoEncoderFactory(),
Qingsi Wang59844ce2018-11-01 04:45:53 +0000593 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr,
Qingsi Wang7685e862018-06-11 20:15:46 -0700594 webrtc::AudioProcessingBuilder().Create());
595 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
596 if (event_log_factory) {
597 event_log_factory_ = event_log_factory.get();
598 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
599 } else {
600 pc_factory_dependencies.event_log_factory =
601 webrtc::CreateRtcEventLogFactory();
602 }
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800603 if (media_transport_factory) {
604 pc_factory_dependencies.media_transport_factory =
605 std::move(media_transport_factory);
606 }
Qingsi Wang7685e862018-06-11 20:15:46 -0700607 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
608 std::move(pc_factory_dependencies));
609
deadbeef1dcb1642017-03-29 21:08:16 -0700610 if (!peer_connection_factory_) {
611 return false;
612 }
613 if (options) {
614 peer_connection_factory_->SetOptions(*options);
615 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800616 if (config) {
617 sdp_semantics_ = config->sdp_semantics;
618 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700619
620 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200621 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700622 return peer_connection_.get() != nullptr;
623 }
624
625 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700626 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700627 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700628 PeerConnectionInterface::RTCConfiguration modified_config;
629 // If |config| is null, this will result in a default configuration being
630 // used.
631 if (config) {
632 modified_config = *config;
633 }
634 // Disable resolution adaptation; we don't want it interfering with the
635 // test results.
636 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
637 // ratios and not specific resolutions, is this even necessary?
638 modified_config.set_cpu_adaptation(false);
639
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700640 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700641 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700642 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700643 }
644
645 void set_signaling_message_receiver(
646 SignalingMessageReceiver* signaling_message_receiver) {
647 signaling_message_receiver_ = signaling_message_receiver;
648 }
649
650 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
651
Steve Antonede9ca52017-10-16 13:04:27 -0700652 void set_signal_ice_candidates(bool signal) {
653 signal_ice_candidates_ = signal;
654 }
655
deadbeef1dcb1642017-03-29 21:08:16 -0700656 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200657 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700658 // Set max frame rate to 10fps to reduce the risk of test flakiness.
659 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200660 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700661
Niels Möller5c7efe72018-05-11 10:34:46 +0200662 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200663 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
664 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700665 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200666 peer_connection_factory_->CreateVideoTrack(
667 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700668 if (!local_video_renderer_) {
669 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
670 }
671 return track;
672 }
673
674 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100675 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800676 std::unique_ptr<SessionDescriptionInterface> desc =
677 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700678 if (received_sdp_munger_) {
679 received_sdp_munger_(desc->description());
680 }
681
682 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
683 // Setting a remote description may have changed the number of receivers,
684 // so reset the receiver observers.
685 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800686 if (remote_offer_handler_) {
687 remote_offer_handler_();
688 }
deadbeef1dcb1642017-03-29 21:08:16 -0700689 auto answer = CreateAnswer();
690 ASSERT_NE(nullptr, answer);
691 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
692 }
693
694 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100695 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800696 std::unique_ptr<SessionDescriptionInterface> desc =
697 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700698 if (received_sdp_munger_) {
699 received_sdp_munger_(desc->description());
700 }
701
702 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
703 // Set the RtpReceiverObserver after receivers are created.
704 ResetRtpReceiverObservers();
705 }
706
707 // Returns null on failure.
708 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
709 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
710 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
711 pc()->CreateOffer(observer, offer_answer_options_);
712 return WaitForDescriptionFromObserver(observer);
713 }
714
715 // Returns null on failure.
716 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
717 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
718 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
719 pc()->CreateAnswer(observer, offer_answer_options_);
720 return WaitForDescriptionFromObserver(observer);
721 }
722
723 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100724 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700725 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
726 if (!observer->result()) {
727 return nullptr;
728 }
729 auto description = observer->MoveDescription();
730 if (generated_sdp_munger_) {
731 generated_sdp_munger_(description->description());
732 }
733 return description;
734 }
735
736 // Setting the local description and sending the SDP message over the fake
737 // signaling channel are combined into the same method because the SDP
738 // message needs to be sent as soon as SetLocalDescription finishes, without
739 // waiting for the observer to be called. This ensures that ICE candidates
740 // don't outrace the description.
741 bool SetLocalDescriptionAndSendSdpMessage(
742 std::unique_ptr<SessionDescriptionInterface> desc) {
743 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
744 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100745 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800746 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700747 std::string sdp;
748 EXPECT_TRUE(desc->ToString(&sdp));
749 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800750 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
751 RemoveUnusedVideoRenderers();
752 }
deadbeef1dcb1642017-03-29 21:08:16 -0700753 // As mentioned above, we need to send the message immediately after
754 // SetLocalDescription.
755 SendSdpMessage(type, sdp);
756 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
757 return true;
758 }
759
760 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
761 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
762 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100763 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700764 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800765 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
766 RemoveUnusedVideoRenderers();
767 }
deadbeef1dcb1642017-03-29 21:08:16 -0700768 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
769 return observer->result();
770 }
771
Seth Hampson2f0d7022018-02-20 11:54:42 -0800772 // This is a work around to remove unused fake_video_renderers from
773 // transceivers that have either stopped or are no longer receiving.
774 void RemoveUnusedVideoRenderers() {
775 auto transceivers = pc()->GetTransceivers();
776 for (auto& transceiver : transceivers) {
777 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
778 continue;
779 }
780 // Remove fake video renderers from any stopped transceivers.
781 if (transceiver->stopped()) {
782 auto it =
783 fake_video_renderers_.find(transceiver->receiver()->track()->id());
784 if (it != fake_video_renderers_.end()) {
785 fake_video_renderers_.erase(it);
786 }
787 }
788 // Remove fake video renderers from any transceivers that are no longer
789 // receiving.
790 if ((transceiver->current_direction() &&
791 !webrtc::RtpTransceiverDirectionHasRecv(
792 *transceiver->current_direction()))) {
793 auto it =
794 fake_video_renderers_.find(transceiver->receiver()->track()->id());
795 if (it != fake_video_renderers_.end()) {
796 fake_video_renderers_.erase(it);
797 }
798 }
799 }
800 }
801
deadbeef1dcb1642017-03-29 21:08:16 -0700802 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
803 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800804 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700805 if (signaling_delay_ms_ == 0) {
806 RelaySdpMessageIfReceiverExists(type, msg);
807 } else {
808 invoker_.AsyncInvokeDelayed<void>(
809 RTC_FROM_HERE, rtc::Thread::Current(),
810 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
811 this, type, msg),
812 signaling_delay_ms_);
813 }
814 }
815
Steve Antona3a92c22017-12-07 10:27:41 -0800816 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700817 if (signaling_message_receiver_) {
818 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
819 }
820 }
821
822 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
823 // default).
824 void SendIceMessage(const std::string& sdp_mid,
825 int sdp_mline_index,
826 const std::string& msg) {
827 if (signaling_delay_ms_ == 0) {
828 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
829 } else {
830 invoker_.AsyncInvokeDelayed<void>(
831 RTC_FROM_HERE, rtc::Thread::Current(),
832 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
833 this, sdp_mid, sdp_mline_index, msg),
834 signaling_delay_ms_);
835 }
836 }
837
838 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
839 int sdp_mline_index,
840 const std::string& msg) {
841 if (signaling_message_receiver_) {
842 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
843 msg);
844 }
845 }
846
847 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800848 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
849 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700850 HandleIncomingOffer(msg);
851 } else {
852 HandleIncomingAnswer(msg);
853 }
854 }
855
856 void ReceiveIceMessage(const std::string& sdp_mid,
857 int sdp_mline_index,
858 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100859 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700860 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
861 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
862 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
863 }
864
865 // PeerConnectionObserver callbacks.
866 void OnSignalingChange(
867 webrtc::PeerConnectionInterface::SignalingState new_state) override {
868 EXPECT_EQ(pc()->signaling_state(), new_state);
869 }
Steve Anton15324772018-01-16 10:26:49 -0800870 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
871 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
872 streams) override {
873 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
874 rtc::scoped_refptr<VideoTrackInterface> video_track(
875 static_cast<VideoTrackInterface*>(receiver->track().get()));
876 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700877 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800878 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 11:40:33 +0200879 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700880 }
881 }
Steve Anton15324772018-01-16 10:26:49 -0800882 void OnRemoveTrack(
883 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
884 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
885 auto it = fake_video_renderers_.find(receiver->track()->id());
886 RTC_DCHECK(it != fake_video_renderers_.end());
887 fake_video_renderers_.erase(it);
888 }
889 }
deadbeef1dcb1642017-03-29 21:08:16 -0700890 void OnRenegotiationNeeded() override {}
891 void OnIceConnectionChange(
892 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
893 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700894 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700895 }
Jonas Olsson635474e2018-10-18 15:58:17 +0200896 void OnConnectionChange(
897 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override {
898 peer_connection_state_history_.push_back(new_state);
899 }
900
deadbeef1dcb1642017-03-29 21:08:16 -0700901 void OnIceGatheringChange(
902 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700903 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700904 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700905 }
906 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100907 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700908
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800909 if (remote_async_resolver_) {
910 const auto& local_candidate = candidate->candidate();
911 const auto& mdns_responder = network()->GetMdnsResponderForTesting();
912 if (local_candidate.address().IsUnresolvedIP()) {
913 RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE);
914 rtc::SocketAddress resolved_addr(local_candidate.address());
915 const auto resolved_ip = mdns_responder->GetMappedAddressForName(
916 local_candidate.address().hostname());
917 RTC_DCHECK(!resolved_ip.IsNil());
918 resolved_addr.SetResolvedIP(resolved_ip);
919 EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _))
920 .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true)));
921 EXPECT_CALL(*remote_async_resolver_, Destroy(_));
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700922 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700923 }
924
deadbeef1dcb1642017-03-29 21:08:16 -0700925 std::string ice_sdp;
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800926 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700927 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700928 // Remote party may be deleted.
929 return;
930 }
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800931 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
deadbeef1dcb1642017-03-29 21:08:16 -0700932 }
933 void OnDataChannel(
934 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100935 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700936 data_channel_ = data_channel;
937 data_observer_.reset(new MockDataChannelObserver(data_channel));
938 }
939
deadbeef1dcb1642017-03-29 21:08:16 -0700940 std::string debug_name_;
941
942 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
943
944 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
945 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
946 peer_connection_factory_;
947
Steve Antonede9ca52017-10-16 13:04:27 -0700948 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700949 // Needed to keep track of number of frames sent.
950 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
951 // Needed to keep track of number of frames received.
952 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
953 fake_video_renderers_;
954 // Needed to ensure frames aren't received for removed tracks.
955 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
956 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -0700957
958 // For remote peer communication.
959 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
960 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700961 bool signal_ice_candidates_ = true;
deadbeef1dcb1642017-03-29 21:08:16 -0700962
Niels Möller5c7efe72018-05-11 10:34:46 +0200963 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -0700964 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +0200965 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
966 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -0700967 // |local_video_renderer_| attached to the first created local video track.
968 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
969
Seth Hampson2f0d7022018-02-20 11:54:42 -0800970 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -0700971 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
972 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
973 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -0800974 std::function<void()> remote_offer_handler_;
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800975 rtc::MockAsyncResolver* remote_async_resolver_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -0700976 rtc::scoped_refptr<DataChannelInterface> data_channel_;
977 std::unique_ptr<MockDataChannelObserver> data_observer_;
978
979 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
980
Steve Antonede9ca52017-10-16 13:04:27 -0700981 std::vector<PeerConnectionInterface::IceConnectionState>
982 ice_connection_state_history_;
Jonas Olsson635474e2018-10-18 15:58:17 +0200983 std::vector<PeerConnectionInterface::PeerConnectionState>
984 peer_connection_state_history_;
Steve Antonede9ca52017-10-16 13:04:27 -0700985 std::vector<PeerConnectionInterface::IceGatheringState>
986 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700987
Qingsi Wang7685e862018-06-11 20:15:46 -0700988 webrtc::FakeRtcEventLogFactory* event_log_factory_;
989
deadbeef1dcb1642017-03-29 21:08:16 -0700990 rtc::AsyncInvoker invoker_;
991
Seth Hampson2f0d7022018-02-20 11:54:42 -0800992 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -0700993};
994
Elad Alon99c3fe52017-10-13 16:29:40 +0200995class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
996 public:
997 virtual ~MockRtcEventLogOutput() = default;
998 MOCK_CONST_METHOD0(IsActive, bool());
999 MOCK_METHOD1(Write, bool(const std::string&));
1000};
1001
Seth Hampson2f0d7022018-02-20 11:54:42 -08001002// This helper object is used for both specifying how many audio/video frames
1003// are expected to be received for a caller/callee. It provides helper functions
1004// to specify these expectations. The object initially starts in a state of no
1005// expectations.
1006class MediaExpectations {
1007 public:
1008 enum ExpectFrames {
1009 kExpectSomeFrames,
1010 kExpectNoFrames,
1011 kNoExpectation,
1012 };
1013
1014 void ExpectBidirectionalAudioAndVideo() {
1015 ExpectBidirectionalAudio();
1016 ExpectBidirectionalVideo();
1017 }
1018
1019 void ExpectBidirectionalAudio() {
1020 CallerExpectsSomeAudio();
1021 CalleeExpectsSomeAudio();
1022 }
1023
1024 void ExpectNoAudio() {
1025 CallerExpectsNoAudio();
1026 CalleeExpectsNoAudio();
1027 }
1028
1029 void ExpectBidirectionalVideo() {
1030 CallerExpectsSomeVideo();
1031 CalleeExpectsSomeVideo();
1032 }
1033
1034 void ExpectNoVideo() {
1035 CallerExpectsNoVideo();
1036 CalleeExpectsNoVideo();
1037 }
1038
1039 void CallerExpectsSomeAudioAndVideo() {
1040 CallerExpectsSomeAudio();
1041 CallerExpectsSomeVideo();
1042 }
1043
1044 void CalleeExpectsSomeAudioAndVideo() {
1045 CalleeExpectsSomeAudio();
1046 CalleeExpectsSomeVideo();
1047 }
1048
1049 // Caller's audio functions.
1050 void CallerExpectsSomeAudio(
1051 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1052 caller_audio_expectation_ = kExpectSomeFrames;
1053 caller_audio_frames_expected_ = expected_audio_frames;
1054 }
1055
1056 void CallerExpectsNoAudio() {
1057 caller_audio_expectation_ = kExpectNoFrames;
1058 caller_audio_frames_expected_ = 0;
1059 }
1060
1061 // Caller's video functions.
1062 void CallerExpectsSomeVideo(
1063 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1064 caller_video_expectation_ = kExpectSomeFrames;
1065 caller_video_frames_expected_ = expected_video_frames;
1066 }
1067
1068 void CallerExpectsNoVideo() {
1069 caller_video_expectation_ = kExpectNoFrames;
1070 caller_video_frames_expected_ = 0;
1071 }
1072
1073 // Callee's audio functions.
1074 void CalleeExpectsSomeAudio(
1075 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1076 callee_audio_expectation_ = kExpectSomeFrames;
1077 callee_audio_frames_expected_ = expected_audio_frames;
1078 }
1079
1080 void CalleeExpectsNoAudio() {
1081 callee_audio_expectation_ = kExpectNoFrames;
1082 callee_audio_frames_expected_ = 0;
1083 }
1084
1085 // Callee's video functions.
1086 void CalleeExpectsSomeVideo(
1087 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1088 callee_video_expectation_ = kExpectSomeFrames;
1089 callee_video_frames_expected_ = expected_video_frames;
1090 }
1091
1092 void CalleeExpectsNoVideo() {
1093 callee_video_expectation_ = kExpectNoFrames;
1094 callee_video_frames_expected_ = 0;
1095 }
1096
1097 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1098 ExpectFrames caller_video_expectation_ = kNoExpectation;
1099 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1100 ExpectFrames callee_video_expectation_ = kNoExpectation;
1101 int caller_audio_frames_expected_ = 0;
1102 int caller_video_frames_expected_ = 0;
1103 int callee_audio_frames_expected_ = 0;
1104 int callee_video_frames_expected_ = 0;
1105};
1106
deadbeef1dcb1642017-03-29 21:08:16 -07001107// Tests two PeerConnections connecting to each other end-to-end, using a
1108// virtual network, fake A/V capture and fake encoder/decoders. The
1109// PeerConnections share the threads/socket servers, but use separate versions
1110// of everything else (including "PeerConnectionFactory"s).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001111class PeerConnectionIntegrationBaseTest : public testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001112 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001113 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1114 : sdp_semantics_(sdp_semantics),
1115 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001116 fss_(new rtc::FirewallSocketServer(ss_.get())),
1117 network_thread_(new rtc::Thread(fss_.get())),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001118 worker_thread_(rtc::Thread::Create()),
1119 loopback_media_transports_(network_thread_.get()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001120 network_thread_->SetName("PCNetworkThread", this);
1121 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001122 RTC_CHECK(network_thread_->Start());
1123 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001124 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001125 }
1126
Seth Hampson2f0d7022018-02-20 11:54:42 -08001127 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 07:41:32 -07001128 // The PeerConnections should deleted before the TurnCustomizers.
1129 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1130 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1131 // that the TurnCustomizer outlives the life of the PeerConnection or else
1132 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001133 if (caller_) {
1134 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001135 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001136 }
1137 if (callee_) {
1138 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001139 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001140 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001141
1142 // If turn servers were created for the test they need to be destroyed on
1143 // the network thread.
1144 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1145 turn_servers_.clear();
1146 turn_customizers_.clear();
1147 });
deadbeef1dcb1642017-03-29 21:08:16 -07001148 }
1149
1150 bool SignalingStateStable() {
1151 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1152 }
1153
deadbeef71452802017-05-07 17:21:01 -07001154 bool DtlsConnected() {
Alex Loiko9289eda2018-11-23 16:18:59 +00001155 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1156 // are connected. This is an important distinction. Once we have separate
1157 // ICE and DTLS state, this check needs to use the DTLS state.
1158 return (callee()->ice_connection_state() ==
1159 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1160 callee()->ice_connection_state() ==
1161 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1162 (caller()->ice_connection_state() ==
1163 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1164 caller()->ice_connection_state() ==
1165 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
deadbeef71452802017-05-07 17:21:01 -07001166 }
1167
Qingsi Wang7685e862018-06-11 20:15:46 -07001168 // When |event_log_factory| is null, the default implementation of the event
1169 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001170 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1171 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001172 const PeerConnectionFactory::Options* options,
1173 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001174 webrtc::PeerConnectionDependencies dependencies,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001175 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
1176 std::unique_ptr<webrtc::MediaTransportFactory> media_transport_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001177 RTCConfiguration modified_config;
1178 if (config) {
1179 modified_config = *config;
1180 }
Steve Anton3acffc32018-04-12 17:21:03 -07001181 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001182 if (!dependencies.cert_generator) {
1183 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 11:40:33 +02001184 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001185 }
1186 std::unique_ptr<PeerConnectionWrapper> client(
1187 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001188
Niels Möllerf06f9232018-08-07 12:32:18 +02001189 if (!client->Init(options, &modified_config, std::move(dependencies),
1190 network_thread_.get(), worker_thread_.get(),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001191 std::move(event_log_factory),
1192 std::move(media_transport_factory))) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001193 return nullptr;
1194 }
1195 return client;
1196 }
1197
Qingsi Wang7685e862018-06-11 20:15:46 -07001198 std::unique_ptr<PeerConnectionWrapper>
1199 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1200 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001201 const PeerConnectionFactory::Options* options,
1202 const RTCConfiguration* config,
1203 webrtc::PeerConnectionDependencies dependencies) {
1204 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1205 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möllerf06f9232018-08-07 12:32:18 +02001206 return CreatePeerConnectionWrapper(debug_name, options, config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001207 std::move(dependencies),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001208 std::move(event_log_factory),
1209 /*media_transport_factory=*/nullptr);
Qingsi Wang7685e862018-06-11 20:15:46 -07001210 }
1211
deadbeef1dcb1642017-03-29 21:08:16 -07001212 bool CreatePeerConnectionWrappers() {
1213 return CreatePeerConnectionWrappersWithConfig(
1214 PeerConnectionInterface::RTCConfiguration(),
1215 PeerConnectionInterface::RTCConfiguration());
1216 }
1217
Steve Anton3acffc32018-04-12 17:21:03 -07001218 bool CreatePeerConnectionWrappersWithSdpSemantics(
1219 SdpSemantics caller_semantics,
1220 SdpSemantics callee_semantics) {
1221 // Can't specify the sdp_semantics in the passed-in configuration since it
1222 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1223 // stored in sdp_semantics_. So get around this by modifying the instance
1224 // variable before calling CreatePeerConnectionWrapper for the caller and
1225 // callee PeerConnections.
1226 SdpSemantics original_semantics = sdp_semantics_;
1227 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001228 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001229 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001230 nullptr, /*media_transport_factory=*/nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001231 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001232 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001233 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001234 nullptr, /*media_transport_factory=*/nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001235 sdp_semantics_ = original_semantics;
1236 return caller_ && callee_;
1237 }
1238
deadbeef1dcb1642017-03-29 21:08:16 -07001239 bool CreatePeerConnectionWrappersWithConfig(
1240 const PeerConnectionInterface::RTCConfiguration& caller_config,
1241 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001242 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001243 "Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001244 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1245 /*media_transport_factory=*/nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001246 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001247 "Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001248 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1249 /*media_transport_factory=*/nullptr);
1250 return caller_ && callee_;
1251 }
1252
1253 bool CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
1254 const PeerConnectionInterface::RTCConfiguration& caller_config,
1255 const PeerConnectionInterface::RTCConfiguration& callee_config,
1256 std::unique_ptr<webrtc::MediaTransportFactory> caller_factory,
1257 std::unique_ptr<webrtc::MediaTransportFactory> callee_factory) {
1258 caller_ =
1259 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
1260 webrtc::PeerConnectionDependencies(nullptr),
1261 nullptr, std::move(caller_factory));
1262 callee_ =
1263 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
1264 webrtc::PeerConnectionDependencies(nullptr),
1265 nullptr, std::move(callee_factory));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001266 return caller_ && callee_;
1267 }
1268
1269 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1270 const PeerConnectionInterface::RTCConfiguration& caller_config,
1271 webrtc::PeerConnectionDependencies caller_dependencies,
1272 const PeerConnectionInterface::RTCConfiguration& callee_config,
1273 webrtc::PeerConnectionDependencies callee_dependencies) {
1274 caller_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001275 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001276 std::move(caller_dependencies), nullptr,
1277 /*media_transport_factory=*/nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001278 callee_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001279 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001280 std::move(callee_dependencies), nullptr,
1281 /*media_transport_factory=*/nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001282 return caller_ && callee_;
1283 }
1284
1285 bool CreatePeerConnectionWrappersWithOptions(
1286 const PeerConnectionFactory::Options& caller_options,
1287 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001288 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001289 "Caller", &caller_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001290 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1291 /*media_transport_factory=*/nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001292 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001293 "Callee", &callee_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001294 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1295 /*media_transport_factory=*/nullptr);
Qingsi Wang7685e862018-06-11 20:15:46 -07001296 return caller_ && callee_;
1297 }
1298
1299 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1300 PeerConnectionInterface::RTCConfiguration default_config;
1301 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001302 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001303 webrtc::PeerConnectionDependencies(nullptr));
1304 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001305 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001306 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001307 return caller_ && callee_;
1308 }
1309
Seth Hampson2f0d7022018-02-20 11:54:42 -08001310 std::unique_ptr<PeerConnectionWrapper>
1311 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001312 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1313 new FakeRTCCertificateGenerator());
1314 cert_generator->use_alternate_key();
1315
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001316 webrtc::PeerConnectionDependencies dependencies(nullptr);
1317 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +02001318 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001319 std::move(dependencies), nullptr,
1320 /*media_transport_factory=*/nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001321 }
1322
Seth Hampsonaed71642018-06-11 07:41:32 -07001323 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 11:40:33 +02001333 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001334 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 11:40:33 +02001346 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001347 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-29 21:08:16 -07001369 // 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 13:04:27 -07001376 // 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-29 21:08:16 -07001384 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 13:04:27 -07001389 void SetSignalIceCandidates(bool signal) {
1390 caller_->set_signal_ice_candidates(signal);
1391 callee_->set_signal_ice_candidates(signal);
1392 }
1393
deadbeef1dcb1642017-03-29 21:08:16 -07001394 // 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
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001408 webrtc::MediaTransportPair* loopback_media_transports() {
1409 return &loopback_media_transports_;
1410 }
1411
deadbeef1dcb1642017-03-29 21:08:16 -07001412 PeerConnectionWrapper* caller() { return caller_.get(); }
1413
1414 // Set the |caller_| to the |wrapper| passed in and return the
1415 // original |caller_|.
1416 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1417 PeerConnectionWrapper* wrapper) {
1418 PeerConnectionWrapper* old = caller_.release();
1419 caller_.reset(wrapper);
1420 return old;
1421 }
1422
1423 PeerConnectionWrapper* callee() { return callee_.get(); }
1424
1425 // Set the |callee_| to the |wrapper| passed in and return the
1426 // original |callee_|.
1427 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1428 PeerConnectionWrapper* wrapper) {
1429 PeerConnectionWrapper* old = callee_.release();
1430 callee_.reset(wrapper);
1431 return old;
1432 }
1433
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001434 void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) {
1435 network_thread()->Invoke<void>(
1436 RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags,
1437 caller()->port_allocator(), caller_flags));
1438 network_thread()->Invoke<void>(
1439 RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags,
1440 callee()->port_allocator(), callee_flags));
1441 }
1442
Steve Antonede9ca52017-10-16 13:04:27 -07001443 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1444
Seth Hampson2f0d7022018-02-20 11:54:42 -08001445 // Expects the provided number of new frames to be received within
1446 // kMaxWaitForFramesMs. The new expected frames are specified in
1447 // |media_expectations|. Returns false if any of the expectations were
1448 // not met.
1449 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1450 // First initialize the expected frame counts based upon the current
1451 // frame count.
1452 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1453 if (media_expectations.caller_audio_expectation_ ==
1454 MediaExpectations::kExpectSomeFrames) {
1455 total_caller_audio_frames_expected +=
1456 media_expectations.caller_audio_frames_expected_;
1457 }
1458 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001459 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001460 if (media_expectations.caller_video_expectation_ ==
1461 MediaExpectations::kExpectSomeFrames) {
1462 total_caller_video_frames_expected +=
1463 media_expectations.caller_video_frames_expected_;
1464 }
1465 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1466 if (media_expectations.callee_audio_expectation_ ==
1467 MediaExpectations::kExpectSomeFrames) {
1468 total_callee_audio_frames_expected +=
1469 media_expectations.callee_audio_frames_expected_;
1470 }
1471 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001472 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001473 if (media_expectations.callee_video_expectation_ ==
1474 MediaExpectations::kExpectSomeFrames) {
1475 total_callee_video_frames_expected +=
1476 media_expectations.callee_video_frames_expected_;
1477 }
deadbeef1dcb1642017-03-29 21:08:16 -07001478
Seth Hampson2f0d7022018-02-20 11:54:42 -08001479 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001480 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001481 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001482 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001483 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001484 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001485 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001486 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001487 total_callee_video_frames_expected,
1488 kMaxWaitForFramesMs);
1489 bool expectations_correct =
1490 caller()->audio_frames_received() >=
1491 total_caller_audio_frames_expected &&
1492 caller()->min_video_frames_received_per_track() >=
1493 total_caller_video_frames_expected &&
1494 callee()->audio_frames_received() >=
1495 total_callee_audio_frames_expected &&
1496 callee()->min_video_frames_received_per_track() >=
1497 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001498
Seth Hampson2f0d7022018-02-20 11:54:42 -08001499 // After the combined wait, print out a more detailed message upon
1500 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001501 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001502 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001503 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001504 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001505 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001506 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001507 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001508 total_callee_video_frames_expected);
1509
1510 // We want to make sure nothing unexpected was received.
1511 if (media_expectations.caller_audio_expectation_ ==
1512 MediaExpectations::kExpectNoFrames) {
1513 EXPECT_EQ(caller()->audio_frames_received(),
1514 total_caller_audio_frames_expected);
1515 if (caller()->audio_frames_received() !=
1516 total_caller_audio_frames_expected) {
1517 expectations_correct = false;
1518 }
1519 }
1520 if (media_expectations.caller_video_expectation_ ==
1521 MediaExpectations::kExpectNoFrames) {
1522 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1523 total_caller_video_frames_expected);
1524 if (caller()->min_video_frames_received_per_track() !=
1525 total_caller_video_frames_expected) {
1526 expectations_correct = false;
1527 }
1528 }
1529 if (media_expectations.callee_audio_expectation_ ==
1530 MediaExpectations::kExpectNoFrames) {
1531 EXPECT_EQ(callee()->audio_frames_received(),
1532 total_callee_audio_frames_expected);
1533 if (callee()->audio_frames_received() !=
1534 total_callee_audio_frames_expected) {
1535 expectations_correct = false;
1536 }
1537 }
1538 if (media_expectations.callee_video_expectation_ ==
1539 MediaExpectations::kExpectNoFrames) {
1540 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1541 total_callee_video_frames_expected);
1542 if (callee()->min_video_frames_received_per_track() !=
1543 total_callee_video_frames_expected) {
1544 expectations_correct = false;
1545 }
1546 }
1547 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001548 }
1549
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001550 void TestNegotiatedCipherSuite(
1551 const PeerConnectionFactory::Options& caller_options,
1552 const PeerConnectionFactory::Options& callee_options,
1553 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001554 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1555 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001556 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001557 caller()->AddAudioVideoTracks();
1558 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001559 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001560 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001561 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001562 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001563 // TODO(bugs.webrtc.org/9456): Fix it.
Alex Loiko9289eda2018-11-23 16:18:59 +00001564 EXPECT_EQ(1, webrtc::metrics::NumEvents(
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001565 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1566 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001567 }
1568
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001569 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1570 bool remote_gcm_enabled,
1571 int expected_cipher_suite) {
1572 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001573 caller_options.crypto_options.srtp.enable_gcm_crypto_suites =
1574 local_gcm_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001575 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001576 callee_options.crypto_options.srtp.enable_gcm_crypto_suites =
1577 remote_gcm_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001578 TestNegotiatedCipherSuite(caller_options, callee_options,
1579 expected_cipher_suite);
1580 }
1581
Seth Hampson2f0d7022018-02-20 11:54:42 -08001582 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001583 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001584
deadbeef1dcb1642017-03-29 21:08:16 -07001585 private:
1586 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001587 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001588 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001589 // |network_thread_| and |worker_thread_| are used by both
1590 // |caller_| and |callee_| so they must be destroyed
1591 // later.
1592 std::unique_ptr<rtc::Thread> network_thread_;
1593 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001594 // The turn servers and turn customizers should be accessed & deleted on the
1595 // network thread to avoid a race with the socket read/write that occurs
1596 // on the network thread.
1597 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1598 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001599 webrtc::MediaTransportPair loopback_media_transports_;
deadbeef1dcb1642017-03-29 21:08:16 -07001600 std::unique_ptr<PeerConnectionWrapper> caller_;
1601 std::unique_ptr<PeerConnectionWrapper> callee_;
1602};
1603
Seth Hampson2f0d7022018-02-20 11:54:42 -08001604class PeerConnectionIntegrationTest
1605 : public PeerConnectionIntegrationBaseTest,
1606 public ::testing::WithParamInterface<SdpSemantics> {
1607 protected:
1608 PeerConnectionIntegrationTest()
1609 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1610};
1611
1612class PeerConnectionIntegrationTestPlanB
1613 : public PeerConnectionIntegrationBaseTest {
1614 protected:
1615 PeerConnectionIntegrationTestPlanB()
1616 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1617};
1618
1619class PeerConnectionIntegrationTestUnifiedPlan
1620 : public PeerConnectionIntegrationBaseTest {
1621 protected:
1622 PeerConnectionIntegrationTestUnifiedPlan()
1623 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1624};
1625
deadbeef1dcb1642017-03-29 21:08:16 -07001626// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1627// includes testing that the callback is invoked if an observer is connected
1628// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001629TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001630 RtpReceiverObserverOnFirstPacketReceived) {
1631 ASSERT_TRUE(CreatePeerConnectionWrappers());
1632 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001633 caller()->AddAudioVideoTracks();
1634 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001635 // Start offer/answer exchange and wait for it to complete.
1636 caller()->CreateAndSetAndSignalOffer();
1637 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1638 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001639 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1640 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001641 // Wait for all "first packet received" callbacks to be fired.
1642 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001643 absl::c_all_of(caller()->rtp_receiver_observers(),
1644 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1645 return o->first_packet_received();
1646 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001647 kMaxWaitForFramesMs);
1648 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001649 absl::c_all_of(callee()->rtp_receiver_observers(),
1650 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1651 return o->first_packet_received();
1652 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001653 kMaxWaitForFramesMs);
1654 // If new observers are set after the first packet was already received, the
1655 // callback should still be invoked.
1656 caller()->ResetRtpReceiverObservers();
1657 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001658 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1659 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001660 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001661 absl::c_all_of(caller()->rtp_receiver_observers(),
1662 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1663 return o->first_packet_received();
1664 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001665 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001666 absl::c_all_of(callee()->rtp_receiver_observers(),
1667 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1668 return o->first_packet_received();
1669 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001670}
1671
1672class DummyDtmfObserver : public DtmfSenderObserverInterface {
1673 public:
1674 DummyDtmfObserver() : completed_(false) {}
1675
1676 // Implements DtmfSenderObserverInterface.
1677 void OnToneChange(const std::string& tone) override {
1678 tones_.push_back(tone);
1679 if (tone.empty()) {
1680 completed_ = true;
1681 }
1682 }
1683
1684 const std::vector<std::string>& tones() const { return tones_; }
1685 bool completed() const { return completed_; }
1686
1687 private:
1688 bool completed_;
1689 std::vector<std::string> tones_;
1690};
1691
1692// Assumes |sender| already has an audio track added and the offer/answer
1693// exchange is done.
1694void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1695 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001696 // We should be able to get a DTMF sender from the local sender.
1697 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1698 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1699 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001700 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001701 dtmf_sender->RegisterObserver(&observer);
1702
1703 // Test the DtmfSender object just created.
1704 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1705 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1706
1707 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1708 std::vector<std::string> tones = {"1", "a", ""};
1709 EXPECT_EQ(tones, observer.tones());
1710 dtmf_sender->UnregisterObserver();
1711 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1712}
1713
1714// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1715// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001716TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001717 ASSERT_TRUE(CreatePeerConnectionWrappers());
1718 ConnectFakeSignaling();
1719 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001720 caller()->AddAudioTrack();
1721 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001722 caller()->CreateAndSetAndSignalOffer();
1723 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001724 // DTLS must finish before the DTMF sender can be used reliably.
1725 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001726 TestDtmfFromSenderToReceiver(caller(), callee());
1727 TestDtmfFromSenderToReceiver(callee(), caller());
1728}
1729
1730// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1731// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001732TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001733 ASSERT_TRUE(CreatePeerConnectionWrappers());
1734 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001735
deadbeef1dcb1642017-03-29 21:08:16 -07001736 // Do normal offer/answer and wait for some frames to be received in each
1737 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001738 caller()->AddAudioVideoTracks();
1739 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001740 caller()->CreateAndSetAndSignalOffer();
1741 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001742 MediaExpectations media_expectations;
1743 media_expectations.ExpectBidirectionalAudioAndVideo();
1744 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001745 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1746 webrtc::kEnumCounterKeyProtocolDtls));
1747 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1748 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001749}
1750
1751// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001752TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001753 PeerConnectionInterface::RTCConfiguration sdes_config;
1754 sdes_config.enable_dtls_srtp.emplace(false);
1755 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1756 ConnectFakeSignaling();
1757
1758 // Do normal offer/answer and wait for some frames to be received in each
1759 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001760 caller()->AddAudioVideoTracks();
1761 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001762 caller()->CreateAndSetAndSignalOffer();
1763 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001764 MediaExpectations media_expectations;
1765 media_expectations.ExpectBidirectionalAudioAndVideo();
1766 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001767 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1768 webrtc::kEnumCounterKeyProtocolSdes));
1769 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1770 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001771}
1772
Steve Anton8c0f7a72017-10-03 10:03:10 -07001773// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1774// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001775TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001776 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1777 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1778 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1779 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1780 return pc->GetRemoteAudioSSLCertificate();
1781 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001782 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1783 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1784 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1785 return pc->GetRemoteAudioSSLCertChain();
1786 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001787
1788 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1789 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1790
1791 // Configure each side with a known certificate so they can be compared later.
1792 PeerConnectionInterface::RTCConfiguration caller_config;
1793 caller_config.enable_dtls_srtp.emplace(true);
1794 caller_config.certificates.push_back(caller_cert);
1795 PeerConnectionInterface::RTCConfiguration callee_config;
1796 callee_config.enable_dtls_srtp.emplace(true);
1797 callee_config.certificates.push_back(callee_cert);
1798 ASSERT_TRUE(
1799 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1800 ConnectFakeSignaling();
1801
1802 // When first initialized, there should not be a remote SSL certificate (and
1803 // calling this method should not crash).
1804 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1805 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001806 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1807 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001808
Steve Anton15324772018-01-16 10:26:49 -08001809 caller()->AddAudioTrack();
1810 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001811 caller()->CreateAndSetAndSignalOffer();
1812 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1813 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1814
1815 // Once DTLS has been connected, each side should return the other's SSL
1816 // certificate when calling GetRemoteAudioSSLCertificate.
1817
1818 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1819 ASSERT_TRUE(caller_remote_cert);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001820 EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(),
Steve Anton8c0f7a72017-10-03 10:03:10 -07001821 caller_remote_cert->ToPEMString());
1822
1823 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1824 ASSERT_TRUE(callee_remote_cert);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001825 EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(),
Steve Anton8c0f7a72017-10-03 10:03:10 -07001826 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001827
1828 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1829 ASSERT_TRUE(caller_remote_cert_chain);
1830 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1831 auto remote_cert = &caller_remote_cert_chain->Get(0);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001832 EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(),
Zhi Huang70b820f2018-01-27 14:16:15 -08001833 remote_cert->ToPEMString());
1834
1835 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1836 ASSERT_TRUE(callee_remote_cert_chain);
1837 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1838 remote_cert = &callee_remote_cert_chain->Get(0);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001839 EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(),
Zhi Huang70b820f2018-01-27 14:16:15 -08001840 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001841}
1842
deadbeef1dcb1642017-03-29 21:08:16 -07001843// This test sets up a call between two parties with a source resolution of
1844// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001845TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001846 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1847 ASSERT_TRUE(CreatePeerConnectionWrappers());
1848 ConnectFakeSignaling();
1849
Niels Möller5c7efe72018-05-11 10:34:46 +02001850 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1851 webrtc::FakePeriodicVideoSource::Config config;
1852 config.width = 1280;
1853 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +02001854 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +02001855 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1856 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07001857
1858 // Do normal offer/answer and wait for at least one frame to be received in
1859 // each direction.
1860 caller()->CreateAndSetAndSignalOffer();
1861 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1862 callee()->min_video_frames_received_per_track() > 0,
1863 kMaxWaitForFramesMs);
1864
1865 // Check rendered aspect ratio.
1866 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1867 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1868 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1869 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1870}
1871
1872// This test sets up an one-way call, with media only from caller to
1873// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001874TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001875 ASSERT_TRUE(CreatePeerConnectionWrappers());
1876 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001877 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001878 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001879 MediaExpectations media_expectations;
1880 media_expectations.CalleeExpectsSomeAudioAndVideo();
1881 media_expectations.CallerExpectsNoAudio();
1882 media_expectations.CallerExpectsNoVideo();
1883 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001884}
1885
1886// This test sets up a audio call initially, with the callee rejecting video
1887// initially. Then later the callee decides to upgrade to audio/video, and
1888// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001889TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001890 ASSERT_TRUE(CreatePeerConnectionWrappers());
1891 ConnectFakeSignaling();
1892 // Initially, offer an audio/video stream from the caller, but refuse to
1893 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001894 caller()->AddAudioVideoTracks();
1895 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001896 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1897 PeerConnectionInterface::RTCOfferAnswerOptions options;
1898 options.offer_to_receive_video = 0;
1899 callee()->SetOfferAnswerOptions(options);
1900 } else {
1901 callee()->SetRemoteOfferHandler([this] {
1902 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1903 });
1904 }
deadbeef1dcb1642017-03-29 21:08:16 -07001905 // Do offer/answer and make sure audio is still received end-to-end.
1906 caller()->CreateAndSetAndSignalOffer();
1907 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001908 {
1909 MediaExpectations media_expectations;
1910 media_expectations.ExpectBidirectionalAudio();
1911 media_expectations.ExpectNoVideo();
1912 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1913 }
deadbeef1dcb1642017-03-29 21:08:16 -07001914 // Sanity check that the callee's description has a rejected video section.
1915 ASSERT_NE(nullptr, callee()->pc()->local_description());
1916 const ContentInfo* callee_video_content =
1917 GetFirstVideoContent(callee()->pc()->local_description()->description());
1918 ASSERT_NE(nullptr, callee_video_content);
1919 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001920
deadbeef1dcb1642017-03-29 21:08:16 -07001921 // Now negotiate with video and ensure negotiation succeeds, with video
1922 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001923 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001924 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1925 PeerConnectionInterface::RTCOfferAnswerOptions options;
1926 options.offer_to_receive_video = 1;
1927 callee()->SetOfferAnswerOptions(options);
1928 } else {
1929 callee()->SetRemoteOfferHandler(nullptr);
1930 caller()->SetRemoteOfferHandler([this] {
1931 // The caller creates a new transceiver to receive video on when receiving
1932 // the offer, but by default it is send only.
1933 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001934 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001935 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1936 transceivers[2]->receiver()->media_type());
1937 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1938 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1939 });
1940 }
deadbeef1dcb1642017-03-29 21:08:16 -07001941 callee()->CreateAndSetAndSignalOffer();
1942 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001943 {
1944 // Expect additional audio frames to be received after the upgrade.
1945 MediaExpectations media_expectations;
1946 media_expectations.ExpectBidirectionalAudioAndVideo();
1947 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1948 }
deadbeef1dcb1642017-03-29 21:08:16 -07001949}
1950
deadbeef4389b4d2017-09-07 09:07:36 -07001951// Simpler than the above test; just add an audio track to an established
1952// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001953TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07001954 ASSERT_TRUE(CreatePeerConnectionWrappers());
1955 ConnectFakeSignaling();
1956 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08001957 caller()->AddVideoTrack();
1958 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001959 caller()->CreateAndSetAndSignalOffer();
1960 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1961 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001962 caller()->AddAudioTrack();
1963 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07001964 caller()->CreateAndSetAndSignalOffer();
1965 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1966 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001967 MediaExpectations media_expectations;
1968 media_expectations.ExpectBidirectionalAudioAndVideo();
1969 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07001970}
1971
deadbeef1dcb1642017-03-29 21:08:16 -07001972// This test sets up a call that's transferred to a new caller with a different
1973// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001974TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07001975 ASSERT_TRUE(CreatePeerConnectionWrappers());
1976 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001977 caller()->AddAudioVideoTracks();
1978 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001979 caller()->CreateAndSetAndSignalOffer();
1980 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1981
1982 // Keep the original peer around which will still send packets to the
1983 // receiving client. These SRTP packets will be dropped.
1984 std::unique_ptr<PeerConnectionWrapper> original_peer(
1985 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001986 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07001987 // TODO(deadbeef): Why do we call Close here? That goes against the comment
1988 // directly above.
1989 original_peer->pc()->Close();
1990
1991 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001992 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001993 caller()->CreateAndSetAndSignalOffer();
1994 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1995 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001996 MediaExpectations media_expectations;
1997 media_expectations.ExpectBidirectionalAudioAndVideo();
1998 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001999}
2000
2001// This test sets up a call that's transferred to a new callee with a different
2002// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002003TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07002004 ASSERT_TRUE(CreatePeerConnectionWrappers());
2005 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002006 caller()->AddAudioVideoTracks();
2007 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002008 caller()->CreateAndSetAndSignalOffer();
2009 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2010
2011 // Keep the original peer around which will still send packets to the
2012 // receiving client. These SRTP packets will be dropped.
2013 std::unique_ptr<PeerConnectionWrapper> original_peer(
2014 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002015 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002016 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2017 // directly above.
2018 original_peer->pc()->Close();
2019
2020 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002021 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002022 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2023 caller()->CreateAndSetAndSignalOffer();
2024 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2025 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002026 MediaExpectations media_expectations;
2027 media_expectations.ExpectBidirectionalAudioAndVideo();
2028 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002029}
2030
2031// This test sets up a non-bundled call and negotiates bundling at the same
2032// time as starting an ICE restart. When bundling is in effect in the restart,
2033// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002034TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002035 ASSERT_TRUE(CreatePeerConnectionWrappers());
2036 ConnectFakeSignaling();
2037
Steve Anton15324772018-01-16 10:26:49 -08002038 caller()->AddAudioVideoTracks();
2039 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002040 // Remove the bundle group from the SDP received by the callee.
2041 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2042 desc->RemoveGroupByName("BUNDLE");
2043 });
2044 caller()->CreateAndSetAndSignalOffer();
2045 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002046 {
2047 MediaExpectations media_expectations;
2048 media_expectations.ExpectBidirectionalAudioAndVideo();
2049 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2050 }
deadbeef1dcb1642017-03-29 21:08:16 -07002051 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2052 callee()->SetReceivedSdpMunger(nullptr);
2053 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2054 caller()->CreateAndSetAndSignalOffer();
2055 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2056
2057 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002058 {
2059 MediaExpectations media_expectations;
2060 media_expectations.ExpectBidirectionalAudioAndVideo();
2061 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2062 }
deadbeef1dcb1642017-03-29 21:08:16 -07002063}
2064
2065// Test CVO (Coordination of Video Orientation). If a video source is rotated
2066// and both peers support the CVO RTP header extension, the actual video frames
2067// don't need to be encoded in different resolutions, since the rotation is
2068// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002069TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002070 ASSERT_TRUE(CreatePeerConnectionWrappers());
2071 ConnectFakeSignaling();
2072 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002073 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002074 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002075 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002076 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2077
2078 // Wait for video frames to be received by both sides.
2079 caller()->CreateAndSetAndSignalOffer();
2080 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2081 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2082 callee()->min_video_frames_received_per_track() > 0,
2083 kMaxWaitForFramesMs);
2084
2085 // Ensure that the aspect ratio is unmodified.
2086 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2087 // not just assumed.
2088 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2089 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2090 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2091 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2092 // Ensure that the CVO bits were surfaced to the renderer.
2093 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2094 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2095}
2096
2097// Test that when the CVO extension isn't supported, video is rotated the
2098// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002099TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002100 ASSERT_TRUE(CreatePeerConnectionWrappers());
2101 ConnectFakeSignaling();
2102 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002103 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002104 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002105 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002106 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2107
2108 // Remove the CVO extension from the offered SDP.
2109 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2110 cricket::VideoContentDescription* video =
2111 GetFirstVideoContentDescription(desc);
2112 video->ClearRtpHeaderExtensions();
2113 });
2114 // Wait for video frames to be received by both sides.
2115 caller()->CreateAndSetAndSignalOffer();
2116 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2117 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2118 callee()->min_video_frames_received_per_track() > 0,
2119 kMaxWaitForFramesMs);
2120
2121 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2122 // rotation.
2123 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2124 // not just assumed.
2125 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2126 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2127 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2128 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2129 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2130 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2131 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2132}
2133
deadbeef1dcb1642017-03-29 21:08:16 -07002134// Test that if the answerer rejects the audio m= section, no audio is sent or
2135// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002136TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002137 ASSERT_TRUE(CreatePeerConnectionWrappers());
2138 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002139 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002140 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2141 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2142 // it will reject the audio m= section completely.
2143 PeerConnectionInterface::RTCOfferAnswerOptions options;
2144 options.offer_to_receive_audio = 0;
2145 callee()->SetOfferAnswerOptions(options);
2146 } else {
2147 // Stopping the audio RtpTransceiver will cause the media section to be
2148 // rejected in the answer.
2149 callee()->SetRemoteOfferHandler([this] {
2150 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2151 });
2152 }
Steve Anton15324772018-01-16 10:26:49 -08002153 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002154 // Do offer/answer and wait for successful end-to-end video frames.
2155 caller()->CreateAndSetAndSignalOffer();
2156 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002157 MediaExpectations media_expectations;
2158 media_expectations.ExpectBidirectionalVideo();
2159 media_expectations.ExpectNoAudio();
2160 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2161
deadbeef1dcb1642017-03-29 21:08:16 -07002162 // Sanity check that the callee's description has a rejected audio section.
2163 ASSERT_NE(nullptr, callee()->pc()->local_description());
2164 const ContentInfo* callee_audio_content =
2165 GetFirstAudioContent(callee()->pc()->local_description()->description());
2166 ASSERT_NE(nullptr, callee_audio_content);
2167 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002168 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2169 // The caller's transceiver should have stopped after receiving the answer.
2170 EXPECT_TRUE(caller()
2171 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2172 ->stopped());
2173 }
deadbeef1dcb1642017-03-29 21:08:16 -07002174}
2175
2176// Test that if the answerer rejects the video m= section, no video is sent or
2177// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002178TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002179 ASSERT_TRUE(CreatePeerConnectionWrappers());
2180 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002181 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002182 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2183 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2184 // it will reject the video m= section completely.
2185 PeerConnectionInterface::RTCOfferAnswerOptions options;
2186 options.offer_to_receive_video = 0;
2187 callee()->SetOfferAnswerOptions(options);
2188 } else {
2189 // Stopping the video RtpTransceiver will cause the media section to be
2190 // rejected in the answer.
2191 callee()->SetRemoteOfferHandler([this] {
2192 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2193 });
2194 }
Steve Anton15324772018-01-16 10:26:49 -08002195 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002196 // Do offer/answer and wait for successful end-to-end audio frames.
2197 caller()->CreateAndSetAndSignalOffer();
2198 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002199 MediaExpectations media_expectations;
2200 media_expectations.ExpectBidirectionalAudio();
2201 media_expectations.ExpectNoVideo();
2202 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2203
deadbeef1dcb1642017-03-29 21:08:16 -07002204 // Sanity check that the callee's description has a rejected video section.
2205 ASSERT_NE(nullptr, callee()->pc()->local_description());
2206 const ContentInfo* callee_video_content =
2207 GetFirstVideoContent(callee()->pc()->local_description()->description());
2208 ASSERT_NE(nullptr, callee_video_content);
2209 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002210 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2211 // The caller's transceiver should have stopped after receiving the answer.
2212 EXPECT_TRUE(caller()
2213 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2214 ->stopped());
2215 }
deadbeef1dcb1642017-03-29 21:08:16 -07002216}
2217
2218// Test that if the answerer rejects both audio and video m= sections, nothing
2219// bad happens.
2220// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2221// test anything but the fact that negotiation succeeds, which doesn't mean
2222// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002223TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002224 ASSERT_TRUE(CreatePeerConnectionWrappers());
2225 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002226 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002227 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2228 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2229 // will reject both audio and video m= sections.
2230 PeerConnectionInterface::RTCOfferAnswerOptions options;
2231 options.offer_to_receive_audio = 0;
2232 options.offer_to_receive_video = 0;
2233 callee()->SetOfferAnswerOptions(options);
2234 } else {
2235 callee()->SetRemoteOfferHandler([this] {
2236 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002237 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002238 transceiver->Stop();
2239 }
2240 });
2241 }
deadbeef1dcb1642017-03-29 21:08:16 -07002242 // Do offer/answer and wait for stable signaling state.
2243 caller()->CreateAndSetAndSignalOffer();
2244 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002245
deadbeef1dcb1642017-03-29 21:08:16 -07002246 // Sanity check that the callee's description has rejected m= sections.
2247 ASSERT_NE(nullptr, callee()->pc()->local_description());
2248 const ContentInfo* callee_audio_content =
2249 GetFirstAudioContent(callee()->pc()->local_description()->description());
2250 ASSERT_NE(nullptr, callee_audio_content);
2251 EXPECT_TRUE(callee_audio_content->rejected);
2252 const ContentInfo* callee_video_content =
2253 GetFirstVideoContent(callee()->pc()->local_description()->description());
2254 ASSERT_NE(nullptr, callee_video_content);
2255 EXPECT_TRUE(callee_video_content->rejected);
2256}
2257
2258// This test sets up an audio and video call between two parties. After the
2259// call runs for a while, the caller sends an updated offer with video being
2260// rejected. Once the re-negotiation is done, the video flow should stop and
2261// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002262TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002263 ASSERT_TRUE(CreatePeerConnectionWrappers());
2264 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002265 caller()->AddAudioVideoTracks();
2266 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002267 caller()->CreateAndSetAndSignalOffer();
2268 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002269 {
2270 MediaExpectations media_expectations;
2271 media_expectations.ExpectBidirectionalAudioAndVideo();
2272 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2273 }
deadbeef1dcb1642017-03-29 21:08:16 -07002274 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002275 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2276 caller()->SetGeneratedSdpMunger(
2277 [](cricket::SessionDescription* description) {
2278 for (cricket::ContentInfo& content : description->contents()) {
2279 if (cricket::IsVideoContent(&content)) {
2280 content.rejected = true;
2281 }
2282 }
2283 });
2284 } else {
2285 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2286 }
deadbeef1dcb1642017-03-29 21:08:16 -07002287 caller()->CreateAndSetAndSignalOffer();
2288 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2289
2290 // Sanity check that the caller's description has a rejected video section.
2291 ASSERT_NE(nullptr, caller()->pc()->local_description());
2292 const ContentInfo* caller_video_content =
2293 GetFirstVideoContent(caller()->pc()->local_description()->description());
2294 ASSERT_NE(nullptr, caller_video_content);
2295 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002296 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002297 {
2298 MediaExpectations media_expectations;
2299 media_expectations.ExpectBidirectionalAudio();
2300 media_expectations.ExpectNoVideo();
2301 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2302 }
deadbeef1dcb1642017-03-29 21:08:16 -07002303}
2304
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002305// Do one offer/answer with audio, another that disables it (rejecting the m=
2306// section), and another that re-enables it. Regression test for:
2307// bugs.webrtc.org/6023
2308TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2309 ASSERT_TRUE(CreatePeerConnectionWrappers());
2310 ConnectFakeSignaling();
2311
2312 // Add audio track, do normal offer/answer.
2313 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2314 caller()->CreateLocalAudioTrack();
2315 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2316 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2317 caller()->CreateAndSetAndSignalOffer();
2318 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2319
2320 // Remove audio track, and set offer_to_receive_audio to false to cause the
2321 // m= section to be completely disabled, not just "recvonly".
2322 caller()->pc()->RemoveTrack(sender);
2323 PeerConnectionInterface::RTCOfferAnswerOptions options;
2324 options.offer_to_receive_audio = 0;
2325 caller()->SetOfferAnswerOptions(options);
2326 caller()->CreateAndSetAndSignalOffer();
2327 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2328
2329 // Add the audio track again, expecting negotiation to succeed and frames to
2330 // flow.
2331 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2332 options.offer_to_receive_audio = 1;
2333 caller()->SetOfferAnswerOptions(options);
2334 caller()->CreateAndSetAndSignalOffer();
2335 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2336
2337 MediaExpectations media_expectations;
2338 media_expectations.CalleeExpectsSomeAudio();
2339 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2340}
2341
deadbeef1dcb1642017-03-29 21:08:16 -07002342// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2343// is needed to support legacy endpoints.
2344// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2345// add a test for an end-to-end test without MID signaling either (basically,
2346// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002347TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002348 ASSERT_TRUE(CreatePeerConnectionWrappers());
2349 ConnectFakeSignaling();
2350 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002351 caller()->AddAudioVideoTracks();
2352 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002353 // Remove SSRCs and MSIDs from the received offer SDP.
2354 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002355 caller()->CreateAndSetAndSignalOffer();
2356 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002357 MediaExpectations media_expectations;
2358 media_expectations.ExpectBidirectionalAudioAndVideo();
2359 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002360}
2361
Seth Hampson5897a6e2018-04-03 11:16:33 -07002362// Basic end-to-end test, without SSRC signaling. This means that the track
2363// was created properly and frames are delivered when the MSIDs are communicated
2364// with a=msid lines and no a=ssrc lines.
2365TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2366 EndToEndCallWithoutSsrcSignaling) {
2367 const char kStreamId[] = "streamId";
2368 ASSERT_TRUE(CreatePeerConnectionWrappers());
2369 ConnectFakeSignaling();
2370 // Add just audio tracks.
2371 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2372 callee()->AddAudioTrack();
2373
2374 // Remove SSRCs from the received offer SDP.
2375 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2376 caller()->CreateAndSetAndSignalOffer();
2377 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2378 MediaExpectations media_expectations;
2379 media_expectations.ExpectBidirectionalAudio();
2380 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2381}
2382
Steve Antondf527fd2018-04-27 15:52:03 -07002383// Tests that video flows between multiple video tracks when SSRCs are not
2384// signaled. This exercises the MID RTP header extension which is needed to
2385// demux the incoming video tracks.
2386TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2387 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2388 ASSERT_TRUE(CreatePeerConnectionWrappers());
2389 ConnectFakeSignaling();
2390 caller()->AddVideoTrack();
2391 caller()->AddVideoTrack();
2392 callee()->AddVideoTrack();
2393 callee()->AddVideoTrack();
2394
2395 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2396 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2397 caller()->CreateAndSetAndSignalOffer();
2398 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2399 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2400 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2401
2402 // Expect video to be received in both directions on both tracks.
2403 MediaExpectations media_expectations;
2404 media_expectations.ExpectBidirectionalVideo();
2405 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2406}
2407
Henrik Boström5b147782018-12-04 11:25:05 +01002408TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
2409 ASSERT_TRUE(CreatePeerConnectionWrappers());
2410 ConnectFakeSignaling();
2411 caller()->AddAudioTrack();
2412 caller()->AddVideoTrack();
2413 caller()->CreateAndSetAndSignalOffer();
2414 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2415 auto callee_receivers = callee()->pc()->GetReceivers();
2416 ASSERT_EQ(2u, callee_receivers.size());
2417 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
2418 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
2419}
2420
2421TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
2422 ASSERT_TRUE(CreatePeerConnectionWrappers());
2423 ConnectFakeSignaling();
2424 caller()->AddAudioTrack();
2425 caller()->AddVideoTrack();
2426 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2427 caller()->CreateAndSetAndSignalOffer();
2428 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2429 auto callee_receivers = callee()->pc()->GetReceivers();
2430 ASSERT_EQ(2u, callee_receivers.size());
2431 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
2432 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
2433 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
2434 callee_receivers[1]->stream_ids()[0]);
2435 EXPECT_EQ(callee_receivers[0]->streams()[0],
2436 callee_receivers[1]->streams()[0]);
2437}
2438
deadbeef1dcb1642017-03-29 21:08:16 -07002439// Test that if two video tracks are sent (from caller to callee, in this test),
2440// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002441TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002442 ASSERT_TRUE(CreatePeerConnectionWrappers());
2443 ConnectFakeSignaling();
2444 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002445 caller()->AddAudioVideoTracks();
2446 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002447 caller()->CreateAndSetAndSignalOffer();
2448 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002449 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002450
2451 MediaExpectations media_expectations;
2452 media_expectations.CalleeExpectsSomeAudioAndVideo();
2453 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002454}
2455
2456static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2457 bool first = true;
2458 for (cricket::ContentInfo& content : desc->contents()) {
2459 if (first) {
2460 first = false;
2461 continue;
2462 }
2463 content.bundle_only = true;
2464 }
2465 first = true;
2466 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2467 if (first) {
2468 first = false;
2469 continue;
2470 }
2471 transport.description.ice_ufrag.clear();
2472 transport.description.ice_pwd.clear();
2473 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2474 transport.description.identity_fingerprint.reset(nullptr);
2475 }
2476}
2477
2478// Test that if applying a true "max bundle" offer, which uses ports of 0,
2479// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2480// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2481// successfully and media flows.
2482// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2483// TODO(deadbeef): Won't need this test once we start generating actual
2484// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002485TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002486 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2487 ASSERT_TRUE(CreatePeerConnectionWrappers());
2488 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002489 caller()->AddAudioVideoTracks();
2490 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002491 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2492 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2493 // but the first m= section.
2494 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2495 caller()->CreateAndSetAndSignalOffer();
2496 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002497 MediaExpectations media_expectations;
2498 media_expectations.ExpectBidirectionalAudioAndVideo();
2499 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002500}
2501
2502// Test that we can receive the audio output level from a remote audio track.
2503// TODO(deadbeef): Use a fake audio source and verify that the output level is
2504// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002505TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002506 ASSERT_TRUE(CreatePeerConnectionWrappers());
2507 ConnectFakeSignaling();
2508 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002509 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002510 caller()->CreateAndSetAndSignalOffer();
2511 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2512
2513 // Get the audio output level stats. Note that the level is not available
2514 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002515 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002516 kMaxWaitForFramesMs);
2517}
2518
2519// Test that an audio input level is reported.
2520// TODO(deadbeef): Use a fake audio source and verify that the input level is
2521// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002522TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002523 ASSERT_TRUE(CreatePeerConnectionWrappers());
2524 ConnectFakeSignaling();
2525 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002526 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002527 caller()->CreateAndSetAndSignalOffer();
2528 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2529
2530 // Get the audio input level stats. The level should be available very
2531 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002532 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002533 kMaxWaitForStatsMs);
2534}
2535
2536// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002537TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002538 ASSERT_TRUE(CreatePeerConnectionWrappers());
2539 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002540 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002541 // Do offer/answer, wait for the callee to receive some frames.
2542 caller()->CreateAndSetAndSignalOffer();
2543 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002544
2545 MediaExpectations media_expectations;
2546 media_expectations.CalleeExpectsSomeAudioAndVideo();
2547 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002548
2549 // Get a handle to the remote tracks created, so they can be used as GetStats
2550 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002551 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08002552 // We received frames, so we definitely should have nonzero "received bytes"
2553 // stats at this point.
2554 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2555 0);
2556 }
deadbeef1dcb1642017-03-29 21:08:16 -07002557}
2558
2559// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002560TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002561 ASSERT_TRUE(CreatePeerConnectionWrappers());
2562 ConnectFakeSignaling();
2563 auto audio_track = caller()->CreateLocalAudioTrack();
2564 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002565 caller()->AddTrack(audio_track);
2566 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002567 // Do offer/answer, wait for the callee to receive some frames.
2568 caller()->CreateAndSetAndSignalOffer();
2569 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002570 MediaExpectations media_expectations;
2571 media_expectations.CalleeExpectsSomeAudioAndVideo();
2572 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002573
2574 // The callee received frames, so we definitely should have nonzero "sent
2575 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002576 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2577 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2578}
2579
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002580// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002581TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002582 ASSERT_TRUE(CreatePeerConnectionWrappers());
2583 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002584 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002585
Steve Anton15324772018-01-16 10:26:49 -08002586 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002587
2588 // Do offer/answer, wait for the callee to receive some frames.
2589 caller()->CreateAndSetAndSignalOffer();
2590 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2591
2592 // Get the remote audio track created on the receiver, so they can be used as
2593 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002594 auto receivers = callee()->pc()->GetReceivers();
2595 ASSERT_EQ(1u, receivers.size());
2596 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002597
2598 // Get the audio output level stats. Note that the level is not available
2599 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002600 EXPECT_TRUE_WAIT(
2601 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2602 0,
2603 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002604}
2605
Steve Antona41959e2018-11-28 11:15:33 -08002606// Test that the track ID is associated with all local and remote SSRC stats
2607// using the old GetStats() and more than 1 audio and more than 1 video track.
2608// This is a regression test for crbug.com/906988
2609TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2610 OldGetStatsAssociatesTrackIdForManyMediaSections) {
2611 ASSERT_TRUE(CreatePeerConnectionWrappers());
2612 ConnectFakeSignaling();
2613 auto audio_sender_1 = caller()->AddAudioTrack();
2614 auto video_sender_1 = caller()->AddVideoTrack();
2615 auto audio_sender_2 = caller()->AddAudioTrack();
2616 auto video_sender_2 = caller()->AddVideoTrack();
2617 caller()->CreateAndSetAndSignalOffer();
2618 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2619
2620 MediaExpectations media_expectations;
2621 media_expectations.CalleeExpectsSomeAudioAndVideo();
2622 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
2623
2624 std::vector<std::string> track_ids = {
2625 audio_sender_1->track()->id(), video_sender_1->track()->id(),
2626 audio_sender_2->track()->id(), video_sender_2->track()->id()};
2627
2628 auto caller_stats = caller()->OldGetStats();
2629 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
2630 auto callee_stats = callee()->OldGetStats();
2631 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
2632}
2633
Steve Antonffa6ce42018-11-30 09:26:08 -08002634// Test that the new GetStats() returns stats for all outgoing/incoming streams
2635// with the correct track IDs if there are more than one audio and more than one
2636// video senders/receivers.
2637TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
2638 ASSERT_TRUE(CreatePeerConnectionWrappers());
2639 ConnectFakeSignaling();
2640 auto audio_sender_1 = caller()->AddAudioTrack();
2641 auto video_sender_1 = caller()->AddVideoTrack();
2642 auto audio_sender_2 = caller()->AddAudioTrack();
2643 auto video_sender_2 = caller()->AddVideoTrack();
2644 caller()->CreateAndSetAndSignalOffer();
2645 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2646
2647 MediaExpectations media_expectations;
2648 media_expectations.CalleeExpectsSomeAudioAndVideo();
2649 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
2650
2651 std::vector<std::string> track_ids = {
2652 audio_sender_1->track()->id(), video_sender_1->track()->id(),
2653 audio_sender_2->track()->id(), video_sender_2->track()->id()};
2654
2655 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
2656 caller()->NewGetStats();
2657 ASSERT_TRUE(caller_report);
2658 auto outbound_stream_stats =
2659 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
2660 ASSERT_EQ(4u, outbound_stream_stats.size());
2661 std::vector<std::string> outbound_track_ids;
2662 for (const auto& stat : outbound_stream_stats) {
2663 ASSERT_TRUE(stat->bytes_sent.is_defined());
2664 EXPECT_LT(0u, *stat->bytes_sent);
2665 ASSERT_TRUE(stat->track_id.is_defined());
2666 const auto* track_stat =
2667 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
2668 ASSERT_TRUE(track_stat);
2669 outbound_track_ids.push_back(*track_stat->track_identifier);
2670 }
2671 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
2672
2673 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
2674 callee()->NewGetStats();
2675 ASSERT_TRUE(callee_report);
2676 auto inbound_stream_stats =
2677 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2678 ASSERT_EQ(4u, inbound_stream_stats.size());
2679 std::vector<std::string> inbound_track_ids;
2680 for (const auto& stat : inbound_stream_stats) {
2681 ASSERT_TRUE(stat->bytes_received.is_defined());
2682 EXPECT_LT(0u, *stat->bytes_received);
2683 ASSERT_TRUE(stat->track_id.is_defined());
2684 const auto* track_stat =
2685 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
2686 ASSERT_TRUE(track_stat);
2687 inbound_track_ids.push_back(*track_stat->track_identifier);
2688 }
2689 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
2690}
2691
2692// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07002693// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2694// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002695TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002696 GetStatsForUnsignaledStreamWithNewStatsApi) {
2697 ASSERT_TRUE(CreatePeerConnectionWrappers());
2698 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002699 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002700 // Remove SSRCs and MSIDs from the received offer SDP.
2701 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2702 caller()->CreateAndSetAndSignalOffer();
2703 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002704 MediaExpectations media_expectations;
2705 media_expectations.CalleeExpectsSomeAudio(1);
2706 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002707
2708 // We received a frame, so we should have nonzero "bytes received" stats for
2709 // the unsignaled stream, if stats are working for it.
2710 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2711 callee()->NewGetStats();
2712 ASSERT_NE(nullptr, report);
2713 auto inbound_stream_stats =
2714 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2715 ASSERT_EQ(1U, inbound_stream_stats.size());
2716 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2717 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002718 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2719}
2720
Taylor Brandstettera4653442018-06-19 09:44:26 -07002721// Same as above but for the legacy stats implementation.
2722TEST_P(PeerConnectionIntegrationTest,
2723 GetStatsForUnsignaledStreamWithOldStatsApi) {
2724 ASSERT_TRUE(CreatePeerConnectionWrappers());
2725 ConnectFakeSignaling();
2726 caller()->AddAudioTrack();
2727 // Remove SSRCs and MSIDs from the received offer SDP.
2728 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2729 caller()->CreateAndSetAndSignalOffer();
2730 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2731
2732 // Note that, since the old stats implementation associates SSRCs with tracks
2733 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2734 // associated track ID. So we can't use the track "selector" argument.
2735 //
2736 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2737 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002738 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07002739 kDefaultTimeout);
2740}
2741
zhihuangf8164932017-05-19 13:09:47 -07002742// Test that we can successfully get the media related stats (audio level
2743// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002744TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002745 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2746 ASSERT_TRUE(CreatePeerConnectionWrappers());
2747 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002748 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002749 // Remove SSRCs and MSIDs from the received offer SDP.
2750 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2751 caller()->CreateAndSetAndSignalOffer();
2752 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002753 MediaExpectations media_expectations;
2754 media_expectations.CalleeExpectsSomeAudio(1);
2755 media_expectations.CalleeExpectsSomeVideo(1);
2756 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002757
2758 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2759 callee()->NewGetStats();
2760 ASSERT_NE(nullptr, report);
2761
2762 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2763 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2764 ASSERT_GE(audio_index, 0);
2765 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002766}
2767
deadbeef4e2deab2017-09-20 13:56:21 -07002768// Helper for test below.
2769void ModifySsrcs(cricket::SessionDescription* desc) {
2770 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002771 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002772 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002773 for (uint32_t& ssrc : stream.ssrcs) {
2774 ssrc = rtc::CreateRandomId();
2775 }
2776 }
2777 }
2778}
2779
2780// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2781// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2782// This should result in two "RTCInboundRTPStreamStats", but only one
2783// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2784// being reset to 0 once the SSRC change occurs.
2785//
2786// Regression test for this bug:
2787// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2788//
2789// The bug causes the track stats to only represent one of the two streams:
2790// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2791// that the track stat counters would reset to 0 when the new stream is
2792// received, and a 50% chance that they'll stop updating (while
2793// "concealed_samples" continues increasing, due to silence being generated for
2794// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002795TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002796 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002797 ASSERT_TRUE(CreatePeerConnectionWrappers());
2798 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002799 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002800 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2801 // that doesn't signal SSRCs (from the callee's perspective).
2802 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2803 caller()->CreateAndSetAndSignalOffer();
2804 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2805 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002806 {
2807 MediaExpectations media_expectations;
2808 media_expectations.CalleeExpectsSomeAudio(50);
2809 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2810 }
deadbeef4e2deab2017-09-20 13:56:21 -07002811 // Some audio frames were received, so we should have nonzero "samples
2812 // received" for the track.
2813 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2814 callee()->NewGetStats();
2815 ASSERT_NE(nullptr, report);
2816 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2817 ASSERT_EQ(1U, track_stats.size());
2818 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2819 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2820 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2821
2822 // Create a new offer and munge it to cause the caller to use a new SSRC.
2823 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2824 caller()->CreateAndSetAndSignalOffer();
2825 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2826 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2827 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002828 {
2829 MediaExpectations media_expectations;
2830 media_expectations.CalleeExpectsSomeAudio(25);
2831 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2832 }
deadbeef4e2deab2017-09-20 13:56:21 -07002833
2834 report = callee()->NewGetStats();
2835 ASSERT_NE(nullptr, report);
2836 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2837 ASSERT_EQ(1U, track_stats.size());
2838 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2839 // The "total samples received" stat should only be greater than it was
2840 // before.
2841 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2842 // Right now, the new SSRC will cause the counters to reset to 0.
2843 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2844
2845 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002846 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002847 // good sign that we're seeing stats from the old stream that's no longer
2848 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002849 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002850 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2851 EXPECT_LT(*track_stats[0]->concealed_samples,
2852 *track_stats[0]->total_samples_received *
2853 kAcceptableConcealedSamplesPercentage);
2854
2855 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2856 // sanity check that the SSRC really changed.
2857 // TODO(deadbeef): This isn't working right now, because we're not returning
2858 // *any* stats for the inactive stream. Uncomment when the bug is completely
2859 // fixed.
2860 // auto inbound_stream_stats =
2861 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2862 // ASSERT_EQ(2U, inbound_stream_stats.size());
2863}
2864
deadbeef1dcb1642017-03-29 21:08:16 -07002865// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002866TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002867 PeerConnectionFactory::Options dtls_10_options;
2868 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2869 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2870 dtls_10_options));
2871 ConnectFakeSignaling();
2872 // Do normal offer/answer and wait for some frames to be received in each
2873 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002874 caller()->AddAudioVideoTracks();
2875 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002876 caller()->CreateAndSetAndSignalOffer();
2877 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002878 MediaExpectations media_expectations;
2879 media_expectations.ExpectBidirectionalAudioAndVideo();
2880 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002881}
2882
2883// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002884TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002885 PeerConnectionFactory::Options dtls_10_options;
2886 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2887 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2888 dtls_10_options));
2889 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002890 caller()->AddAudioVideoTracks();
2891 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002892 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002893 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002894 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002895 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002896 kDefaultTimeout);
2897 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002898 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002899 // TODO(bugs.webrtc.org/9456): Fix it.
Alex Loiko9289eda2018-11-23 16:18:59 +00002900 EXPECT_EQ(1, webrtc::metrics::NumEvents(
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002901 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2902 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002903}
2904
2905// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002906TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002907 PeerConnectionFactory::Options dtls_12_options;
2908 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2909 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2910 dtls_12_options));
2911 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002912 caller()->AddAudioVideoTracks();
2913 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002914 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002915 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002916 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002917 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002918 kDefaultTimeout);
2919 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002920 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002921 // TODO(bugs.webrtc.org/9456): Fix it.
Alex Loiko9289eda2018-11-23 16:18:59 +00002922 EXPECT_EQ(1, webrtc::metrics::NumEvents(
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002923 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2924 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002925}
2926
2927// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2928// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002929TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002930 PeerConnectionFactory::Options caller_options;
2931 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2932 PeerConnectionFactory::Options callee_options;
2933 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2934 ASSERT_TRUE(
2935 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2936 ConnectFakeSignaling();
2937 // Do normal offer/answer and wait for some frames to be received in each
2938 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002939 caller()->AddAudioVideoTracks();
2940 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002941 caller()->CreateAndSetAndSignalOffer();
2942 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002943 MediaExpectations media_expectations;
2944 media_expectations.ExpectBidirectionalAudioAndVideo();
2945 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002946}
2947
2948// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
2949// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002950TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07002951 PeerConnectionFactory::Options caller_options;
2952 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2953 PeerConnectionFactory::Options callee_options;
2954 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2955 ASSERT_TRUE(
2956 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2957 ConnectFakeSignaling();
2958 // Do normal offer/answer and wait for some frames to be received in each
2959 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002960 caller()->AddAudioVideoTracks();
2961 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002962 caller()->CreateAndSetAndSignalOffer();
2963 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002964 MediaExpectations media_expectations;
2965 media_expectations.ExpectBidirectionalAudioAndVideo();
2966 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002967}
2968
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002969// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
2970// works as expected; the cipher should only be used if enabled by both sides.
2971TEST_P(PeerConnectionIntegrationTest,
2972 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
2973 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07002974 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002975 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07002976 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
2977 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002978 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2979 TestNegotiatedCipherSuite(caller_options, callee_options,
2980 expected_cipher_suite);
2981}
2982
2983TEST_P(PeerConnectionIntegrationTest,
2984 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
2985 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07002986 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
2987 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002988 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07002989 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002990 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
2991 TestNegotiatedCipherSuite(caller_options, callee_options,
2992 expected_cipher_suite);
2993}
2994
2995TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
2996 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07002997 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07002998 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07002999 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003000 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
3001 TestNegotiatedCipherSuite(caller_options, callee_options,
3002 expected_cipher_suite);
3003}
3004
deadbeef1dcb1642017-03-29 21:08:16 -07003005// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003006TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003007 bool local_gcm_enabled = false;
3008 bool remote_gcm_enabled = false;
3009 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3010 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3011 expected_cipher_suite);
3012}
3013
3014// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003015TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003016 bool local_gcm_enabled = true;
3017 bool remote_gcm_enabled = true;
3018 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
3019 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3020 expected_cipher_suite);
3021}
3022
3023// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003024TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003025 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
3026 bool local_gcm_enabled = true;
3027 bool remote_gcm_enabled = false;
3028 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3029 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3030 expected_cipher_suite);
3031}
3032
3033// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003034TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003035 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
3036 bool local_gcm_enabled = false;
3037 bool remote_gcm_enabled = true;
3038 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3039 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3040 expected_cipher_suite);
3041}
3042
deadbeef7914b8c2017-04-21 03:23:33 -07003043// Verify that media can be transmitted end-to-end when GCM crypto suites are
3044// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
3045// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
3046// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003047TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07003048 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003049 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
deadbeef7914b8c2017-04-21 03:23:33 -07003050 ASSERT_TRUE(
3051 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
3052 ConnectFakeSignaling();
3053 // Do normal offer/answer and wait for some frames to be received in each
3054 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003055 caller()->AddAudioVideoTracks();
3056 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003057 caller()->CreateAndSetAndSignalOffer();
3058 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003059 MediaExpectations media_expectations;
3060 media_expectations.ExpectBidirectionalAudioAndVideo();
3061 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003062}
3063
deadbeef1dcb1642017-03-29 21:08:16 -07003064// This test sets up a call between two parties with audio, video and an RTP
3065// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003066TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003067 PeerConnectionInterface::RTCConfiguration rtc_config;
3068 rtc_config.enable_rtp_data_channel = true;
3069 rtc_config.enable_dtls_srtp = false;
3070 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003071 ConnectFakeSignaling();
3072 // Expect that data channel created on caller side will show up for callee as
3073 // well.
3074 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003075 caller()->AddAudioVideoTracks();
3076 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003077 caller()->CreateAndSetAndSignalOffer();
3078 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3079 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003080 MediaExpectations media_expectations;
3081 media_expectations.ExpectBidirectionalAudioAndVideo();
3082 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003083 ASSERT_NE(nullptr, caller()->data_channel());
3084 ASSERT_NE(nullptr, callee()->data_channel());
3085 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3086 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3087
3088 // Ensure data can be sent in both directions.
3089 std::string data = "hello world";
3090 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3091 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3092 kDefaultTimeout);
3093 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3094 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3095 kDefaultTimeout);
3096}
3097
3098// Ensure that an RTP data channel is signaled as closed for the caller when
3099// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003100TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003101 RtpDataChannelSignaledClosedInCalleeOffer) {
3102 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02003103 PeerConnectionInterface::RTCConfiguration rtc_config;
3104 rtc_config.enable_rtp_data_channel = true;
3105 rtc_config.enable_dtls_srtp = false;
3106 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003107 ConnectFakeSignaling();
3108 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003109 caller()->AddAudioVideoTracks();
3110 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003111 caller()->CreateAndSetAndSignalOffer();
3112 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3113 ASSERT_NE(nullptr, caller()->data_channel());
3114 ASSERT_NE(nullptr, callee()->data_channel());
3115 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3116 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3117
3118 // Close the data channel on the callee, and do an updated offer/answer.
3119 callee()->data_channel()->Close();
3120 callee()->CreateAndSetAndSignalOffer();
3121 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3122 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3123 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3124}
3125
3126// Tests that data is buffered in an RTP data channel until an observer is
3127// registered for it.
3128//
3129// NOTE: RTP data channels can receive data before the underlying
3130// transport has detected that a channel is writable and thus data can be
3131// received before the data channel state changes to open. That is hard to test
3132// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003133TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003134 DataBufferedUntilRtpDataChannelObserverRegistered) {
3135 // Use fake clock and simulated network delay so that we predictably can wait
3136 // until an SCTP message has been delivered without "sleep()"ing.
3137 rtc::ScopedFakeClock fake_clock;
3138 // Some things use a time of "0" as a special value, so we need to start out
3139 // the fake clock at a nonzero time.
3140 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003141 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003142 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3143 virtual_socket_server()->UpdateDelayDistribution();
3144
Niels Möllerf06f9232018-08-07 12:32:18 +02003145 PeerConnectionInterface::RTCConfiguration rtc_config;
3146 rtc_config.enable_rtp_data_channel = true;
3147 rtc_config.enable_dtls_srtp = false;
3148 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003149 ConnectFakeSignaling();
3150 caller()->CreateDataChannel();
3151 caller()->CreateAndSetAndSignalOffer();
3152 ASSERT_TRUE(caller()->data_channel() != nullptr);
3153 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
3154 kDefaultTimeout, fake_clock);
3155 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
3156 kDefaultTimeout, fake_clock);
3157 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3158 callee()->data_channel()->state(), kDefaultTimeout,
3159 fake_clock);
3160
3161 // Unregister the observer which is normally automatically registered.
3162 callee()->data_channel()->UnregisterObserver();
3163 // Send data and advance fake clock until it should have been received.
3164 std::string data = "hello world";
3165 caller()->data_channel()->Send(DataBuffer(data));
3166 SIMULATED_WAIT(false, 50, fake_clock);
3167
3168 // Attach data channel and expect data to be received immediately. Note that
3169 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3170 // further, but data can be received even if the callback is asynchronous.
3171 MockDataChannelObserver new_observer(callee()->data_channel());
3172 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
3173 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07003174 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3175 // If this is not done a DCHECK can be hit in ports.cc, because a large
3176 // negative number is calculated for the rtt due to the global clock changing.
3177 caller()->pc()->Close();
3178 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07003179}
3180
3181// This test sets up a call between two parties with audio, video and but only
3182// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003183TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003184 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3185 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003186 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003187 rtc_config_1.enable_dtls_srtp = false;
3188 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3189 rtc_config_2.enable_dtls_srtp = false;
3190 rtc_config_2.enable_dtls_srtp = false;
3191 ASSERT_TRUE(
3192 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003193 ConnectFakeSignaling();
3194 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003195 caller()->AddAudioVideoTracks();
3196 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003197 caller()->CreateAndSetAndSignalOffer();
3198 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3199 // The caller should still have a data channel, but it should be closed, and
3200 // one should ever have been created for the callee.
3201 EXPECT_TRUE(caller()->data_channel() != nullptr);
3202 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3203 EXPECT_EQ(nullptr, callee()->data_channel());
3204}
3205
3206// This test sets up a call between two parties with audio, and video. When
3207// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003208TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003209 PeerConnectionInterface::RTCConfiguration rtc_config;
3210 rtc_config.enable_rtp_data_channel = true;
3211 rtc_config.enable_dtls_srtp = false;
3212 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003213 ConnectFakeSignaling();
3214 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003215 caller()->AddAudioVideoTracks();
3216 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003217 caller()->CreateAndSetAndSignalOffer();
3218 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3219 // Create data channel and do new offer and answer.
3220 caller()->CreateDataChannel();
3221 caller()->CreateAndSetAndSignalOffer();
3222 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3223 ASSERT_NE(nullptr, caller()->data_channel());
3224 ASSERT_NE(nullptr, callee()->data_channel());
3225 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3226 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3227 // Ensure data can be sent in both directions.
3228 std::string data = "hello world";
3229 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3230 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3231 kDefaultTimeout);
3232 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3233 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3234 kDefaultTimeout);
3235}
3236
3237#ifdef HAVE_SCTP
3238
3239// This test sets up a call between two parties with audio, video and an SCTP
3240// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003241TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003242 ASSERT_TRUE(CreatePeerConnectionWrappers());
3243 ConnectFakeSignaling();
3244 // Expect that data channel created on caller side will show up for callee as
3245 // well.
3246 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003247 caller()->AddAudioVideoTracks();
3248 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003249 caller()->CreateAndSetAndSignalOffer();
3250 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3251 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003252 MediaExpectations media_expectations;
3253 media_expectations.ExpectBidirectionalAudioAndVideo();
3254 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003255 // Caller data channel should already exist (it created one). Callee data
3256 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3257 ASSERT_NE(nullptr, caller()->data_channel());
3258 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3259 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3260 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3261
3262 // Ensure data can be sent in both directions.
3263 std::string data = "hello world";
3264 caller()->data_channel()->Send(DataBuffer(data));
3265 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3266 kDefaultTimeout);
3267 callee()->data_channel()->Send(DataBuffer(data));
3268 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3269 kDefaultTimeout);
3270}
3271
3272// Ensure that when the callee closes an SCTP data channel, the closing
3273// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003274TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003275 // Same procedure as above test.
3276 ASSERT_TRUE(CreatePeerConnectionWrappers());
3277 ConnectFakeSignaling();
3278 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003279 caller()->AddAudioVideoTracks();
3280 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003281 caller()->CreateAndSetAndSignalOffer();
3282 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3283 ASSERT_NE(nullptr, caller()->data_channel());
3284 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3285 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3286 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3287
3288 // Close the data channel on the callee side, and wait for it to reach the
3289 // "closed" state on both sides.
3290 callee()->data_channel()->Close();
3291 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3292 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3293}
3294
Seth Hampson2f0d7022018-02-20 11:54:42 -08003295TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003296 ASSERT_TRUE(CreatePeerConnectionWrappers());
3297 ConnectFakeSignaling();
3298 webrtc::DataChannelInit init;
3299 init.id = 53;
3300 init.maxRetransmits = 52;
3301 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003302 caller()->AddAudioVideoTracks();
3303 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003304 caller()->CreateAndSetAndSignalOffer();
3305 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003306 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3307 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Steve Antonda6c0952017-10-23 11:41:54 -07003308 EXPECT_EQ(init.id, callee()->data_channel()->id());
3309 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3310 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3311 EXPECT_FALSE(callee()->data_channel()->negotiated());
3312}
3313
deadbeef1dcb1642017-03-29 21:08:16 -07003314// Test usrsctp's ability to process unordered data stream, where data actually
3315// arrives out of order using simulated delays. Previously there have been some
3316// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003317TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003318 // Introduce random network delays.
3319 // Otherwise it's not a true "unordered" test.
3320 virtual_socket_server()->set_delay_mean(20);
3321 virtual_socket_server()->set_delay_stddev(5);
3322 virtual_socket_server()->UpdateDelayDistribution();
3323 // Normal procedure, but with unordered data channel config.
3324 ASSERT_TRUE(CreatePeerConnectionWrappers());
3325 ConnectFakeSignaling();
3326 webrtc::DataChannelInit init;
3327 init.ordered = false;
3328 caller()->CreateDataChannel(&init);
3329 caller()->CreateAndSetAndSignalOffer();
3330 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3331 ASSERT_NE(nullptr, caller()->data_channel());
3332 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3333 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3334 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3335
3336 static constexpr int kNumMessages = 100;
3337 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3338 static constexpr size_t kMaxMessageSize = 4096;
3339 // Create and send random messages.
3340 std::vector<std::string> sent_messages;
3341 for (int i = 0; i < kNumMessages; ++i) {
3342 size_t length =
3343 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3344 std::string message;
3345 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3346 caller()->data_channel()->Send(DataBuffer(message));
3347 callee()->data_channel()->Send(DataBuffer(message));
3348 sent_messages.push_back(message);
3349 }
3350
3351 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003352 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003353 caller()->data_observer()->received_message_count(),
3354 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003355 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003356 callee()->data_observer()->received_message_count(),
3357 kDefaultTimeout);
3358
3359 // Sort and compare to make sure none of the messages were corrupted.
3360 std::vector<std::string> caller_received_messages =
3361 caller()->data_observer()->messages();
3362 std::vector<std::string> callee_received_messages =
3363 callee()->data_observer()->messages();
Steve Anton64b626b2019-01-28 17:25:26 -08003364 absl::c_sort(sent_messages);
3365 absl::c_sort(caller_received_messages);
3366 absl::c_sort(callee_received_messages);
deadbeef1dcb1642017-03-29 21:08:16 -07003367 EXPECT_EQ(sent_messages, caller_received_messages);
3368 EXPECT_EQ(sent_messages, callee_received_messages);
3369}
3370
3371// This test sets up a call between two parties with audio, and video. When
3372// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003373TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003374 ASSERT_TRUE(CreatePeerConnectionWrappers());
3375 ConnectFakeSignaling();
3376 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003377 caller()->AddAudioVideoTracks();
3378 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003379 caller()->CreateAndSetAndSignalOffer();
3380 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3381 // Create data channel and do new offer and answer.
3382 caller()->CreateDataChannel();
3383 caller()->CreateAndSetAndSignalOffer();
3384 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3385 // Caller data channel should already exist (it created one). Callee data
3386 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3387 ASSERT_NE(nullptr, caller()->data_channel());
3388 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3389 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3390 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3391 // Ensure data can be sent in both directions.
3392 std::string data = "hello world";
3393 caller()->data_channel()->Send(DataBuffer(data));
3394 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3395 kDefaultTimeout);
3396 callee()->data_channel()->Send(DataBuffer(data));
3397 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3398 kDefaultTimeout);
3399}
3400
deadbeef7914b8c2017-04-21 03:23:33 -07003401// Set up a connection initially just using SCTP data channels, later upgrading
3402// to audio/video, ensuring frames are received end-to-end. Effectively the
3403// inverse of the test above.
3404// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003405TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003406 ASSERT_TRUE(CreatePeerConnectionWrappers());
3407 ConnectFakeSignaling();
3408 // Do initial offer/answer with just data channel.
3409 caller()->CreateDataChannel();
3410 caller()->CreateAndSetAndSignalOffer();
3411 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3412 // Wait until data can be sent over the data channel.
3413 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3414 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3415 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3416
3417 // Do subsequent offer/answer with two-way audio and video. Audio and video
3418 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003419 caller()->AddAudioVideoTracks();
3420 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003421 caller()->CreateAndSetAndSignalOffer();
3422 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003423 MediaExpectations media_expectations;
3424 media_expectations.ExpectBidirectionalAudioAndVideo();
3425 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003426}
3427
deadbeef8b7e9ad2017-05-25 09:38:55 -07003428static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
deadbeef8b7e9ad2017-05-25 09:38:55 -07003429 cricket::DataContentDescription* dcd_offer =
Steve Antonb1c1de12017-12-21 15:14:30 -08003430 GetFirstDataContentDescription(desc);
3431 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003432 dcd_offer->set_use_sctpmap(false);
3433 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3434}
3435
3436// Test that the data channel works when a spec-compliant SCTP m= section is
3437// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3438// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003439TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003440 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3441 ASSERT_TRUE(CreatePeerConnectionWrappers());
3442 ConnectFakeSignaling();
3443 caller()->CreateDataChannel();
3444 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3445 caller()->CreateAndSetAndSignalOffer();
3446 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3447 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3448 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3449 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3450
3451 // Ensure data can be sent in both directions.
3452 std::string data = "hello world";
3453 caller()->data_channel()->Send(DataBuffer(data));
3454 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3455 kDefaultTimeout);
3456 callee()->data_channel()->Send(DataBuffer(data));
3457 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3458 kDefaultTimeout);
3459}
3460
deadbeef1dcb1642017-03-29 21:08:16 -07003461#endif // HAVE_SCTP
3462
Bjorn Mellema2eb0a72018-11-09 10:13:51 -08003463// This test sets up a call between two parties with a media transport data
3464// channel.
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08003465TEST_P(PeerConnectionIntegrationTest, MediaTransportDataChannelEndToEnd) {
3466 PeerConnectionInterface::RTCConfiguration rtc_config;
3467 rtc_config.use_media_transport_for_data_channels = true;
3468 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3469 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3470 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3471 loopback_media_transports()->second_factory()));
3472 ConnectFakeSignaling();
3473
3474 // Expect that data channel created on caller side will show up for callee as
3475 // well.
3476 caller()->CreateDataChannel();
3477 caller()->CreateAndSetAndSignalOffer();
3478 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3479
3480 // Ensure that the media transport is ready.
3481 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3482 loopback_media_transports()->FlushAsyncInvokes();
3483
3484 // Caller data channel should already exist (it created one). Callee data
3485 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3486 ASSERT_NE(nullptr, caller()->data_channel());
3487 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3488 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3489 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3490
3491 // Ensure data can be sent in both directions.
3492 std::string data = "hello world";
3493 caller()->data_channel()->Send(DataBuffer(data));
3494 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3495 kDefaultTimeout);
3496 callee()->data_channel()->Send(DataBuffer(data));
3497 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3498 kDefaultTimeout);
3499}
3500
3501// Ensure that when the callee closes a media transport data channel, the
3502// closing procedure results in the data channel being closed for the caller
3503// as well.
3504TEST_P(PeerConnectionIntegrationTest, MediaTransportDataChannelCalleeCloses) {
3505 PeerConnectionInterface::RTCConfiguration rtc_config;
3506 rtc_config.use_media_transport_for_data_channels = true;
3507 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3508 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3509 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3510 loopback_media_transports()->second_factory()));
3511 ConnectFakeSignaling();
3512
3513 // Create a data channel on the caller and signal it to the callee.
3514 caller()->CreateDataChannel();
3515 caller()->CreateAndSetAndSignalOffer();
3516 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3517
3518 // Ensure that the media transport is ready.
3519 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3520 loopback_media_transports()->FlushAsyncInvokes();
3521
3522 // Data channels exist and open on both ends of the connection.
3523 ASSERT_NE(nullptr, caller()->data_channel());
3524 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3525 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3526 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3527
3528 // Close the data channel on the callee side, and wait for it to reach the
3529 // "closed" state on both sides.
3530 callee()->data_channel()->Close();
3531 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3532 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3533}
3534
3535TEST_P(PeerConnectionIntegrationTest,
3536 MediaTransportDataChannelConfigSentToOtherSide) {
3537 PeerConnectionInterface::RTCConfiguration rtc_config;
3538 rtc_config.use_media_transport_for_data_channels = true;
3539 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3540 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3541 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3542 loopback_media_transports()->second_factory()));
3543 ConnectFakeSignaling();
3544
3545 // Create a data channel with a non-default configuration and signal it to the
3546 // callee.
3547 webrtc::DataChannelInit init;
3548 init.id = 53;
3549 init.maxRetransmits = 52;
3550 caller()->CreateDataChannel("data-channel", &init);
3551 caller()->CreateAndSetAndSignalOffer();
3552 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3553
3554 // Ensure that the media transport is ready.
3555 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3556 loopback_media_transports()->FlushAsyncInvokes();
3557
3558 // Ensure that the data channel exists on the callee with the correct
3559 // configuration.
3560 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3561 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3562 EXPECT_EQ(init.id, callee()->data_channel()->id());
3563 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3564 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3565 EXPECT_FALSE(callee()->data_channel()->negotiated());
3566}
3567
Niels Möllerc68d2822018-11-20 14:52:05 +01003568TEST_P(PeerConnectionIntegrationTest, MediaTransportBidirectionalAudio) {
3569 PeerConnectionInterface::RTCConfiguration rtc_config;
3570 rtc_config.use_media_transport = true;
3571 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3572 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3573 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3574 loopback_media_transports()->second_factory()));
3575 ConnectFakeSignaling();
3576
3577 caller()->AddAudioTrack();
3578 callee()->AddAudioTrack();
3579 // Start offer/answer exchange and wait for it to complete.
3580 caller()->CreateAndSetAndSignalOffer();
3581 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3582
3583 // Ensure that the media transport is ready.
3584 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3585 loopback_media_transports()->FlushAsyncInvokes();
3586
3587 MediaExpectations media_expectations;
3588 media_expectations.ExpectBidirectionalAudio();
3589 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3590
3591 webrtc::MediaTransportPair::Stats first_stats =
3592 loopback_media_transports()->FirstStats();
3593 webrtc::MediaTransportPair::Stats second_stats =
3594 loopback_media_transports()->SecondStats();
3595
3596 EXPECT_GT(first_stats.received_audio_frames, 0);
3597 EXPECT_GE(second_stats.sent_audio_frames, first_stats.received_audio_frames);
3598
3599 EXPECT_GT(second_stats.received_audio_frames, 0);
3600 EXPECT_GE(first_stats.sent_audio_frames, second_stats.received_audio_frames);
3601}
3602
Niels Möller46879152019-01-07 15:54:47 +01003603TEST_P(PeerConnectionIntegrationTest, MediaTransportBidirectionalVideo) {
3604 PeerConnectionInterface::RTCConfiguration rtc_config;
3605 rtc_config.use_media_transport = true;
3606 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3607 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3608 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3609 loopback_media_transports()->second_factory()));
3610 ConnectFakeSignaling();
3611
3612 caller()->AddVideoTrack();
3613 callee()->AddVideoTrack();
3614 // Start offer/answer exchange and wait for it to complete.
3615 caller()->CreateAndSetAndSignalOffer();
3616 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3617
3618 // Ensure that the media transport is ready.
3619 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3620 loopback_media_transports()->FlushAsyncInvokes();
3621
3622 MediaExpectations media_expectations;
3623 media_expectations.ExpectBidirectionalVideo();
3624 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3625
3626 webrtc::MediaTransportPair::Stats first_stats =
3627 loopback_media_transports()->FirstStats();
3628 webrtc::MediaTransportPair::Stats second_stats =
3629 loopback_media_transports()->SecondStats();
3630
3631 EXPECT_GT(first_stats.received_video_frames, 0);
3632 EXPECT_GE(second_stats.sent_video_frames, first_stats.received_video_frames);
3633
3634 EXPECT_GT(second_stats.received_video_frames, 0);
3635 EXPECT_GE(first_stats.sent_video_frames, second_stats.received_video_frames);
3636}
3637
Piotr (Peter) Slatala55b91b92019-01-25 13:31:15 -08003638TEST_P(PeerConnectionIntegrationTest,
3639 MediaTransportDataChannelUsesRtpBidirectionalVideo) {
3640 PeerConnectionInterface::RTCConfiguration rtc_config;
3641 rtc_config.use_media_transport = false;
3642 rtc_config.use_media_transport_for_data_channels = true;
3643 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3644 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3645 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3646 loopback_media_transports()->second_factory()));
3647 ConnectFakeSignaling();
3648
3649 caller()->AddVideoTrack();
3650 callee()->AddVideoTrack();
3651 // Start offer/answer exchange and wait for it to complete.
3652 caller()->CreateAndSetAndSignalOffer();
3653 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3654
3655 MediaExpectations media_expectations;
3656 media_expectations.ExpectBidirectionalVideo();
3657 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3658}
3659
deadbeef1dcb1642017-03-29 21:08:16 -07003660// Test that the ICE connection and gathering states eventually reach
3661// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003662TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003663 ASSERT_TRUE(CreatePeerConnectionWrappers());
3664 ConnectFakeSignaling();
3665 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003666 caller()->AddAudioVideoTracks();
3667 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003668 caller()->CreateAndSetAndSignalOffer();
3669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3670 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3671 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3672 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3673 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3674 // After the best candidate pair is selected and all candidates are signaled,
3675 // the ICE connection state should reach "complete".
3676 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3677 // answerer/"callee" by default) only reaches "connected". When this is
3678 // fixed, this test should be updated.
3679 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3680 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00003681 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3682 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003683}
3684
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003685constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
3686 cricket::PORTALLOCATOR_DISABLE_RELAY |
3687 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003688
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003689// Use a mock resolver to resolve the hostname back to the original IP on both
3690// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003691TEST_P(PeerConnectionIntegrationTest,
3692 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003693 auto caller_resolver_factory =
3694 absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
3695 auto callee_resolver_factory =
3696 absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
3697 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
3698 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003699
3700 // This also verifies that the injected AsyncResolverFactory is used by
3701 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003702 EXPECT_CALL(*caller_resolver_factory, Create())
3703 .WillOnce(Return(&caller_async_resolver));
3704 webrtc::PeerConnectionDependencies caller_deps(nullptr);
3705 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
3706
3707 EXPECT_CALL(*callee_resolver_factory, Create())
3708 .WillOnce(Return(&callee_async_resolver));
3709 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3710 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
3711
3712 PeerConnectionInterface::RTCConfiguration config;
3713 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3714 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3715
3716 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3717 config, std::move(caller_deps), config, std::move(callee_deps)));
3718
3719 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
3720 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
3721
3722 // Enable hostname candidates with mDNS names.
3723 caller()->network()->CreateMdnsResponder(network_thread());
3724 callee()->network()->CreateMdnsResponder(network_thread());
3725
3726 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003727
3728 ConnectFakeSignaling();
3729 caller()->AddAudioVideoTracks();
3730 callee()->AddAudioVideoTracks();
3731 caller()->CreateAndSetAndSignalOffer();
3732 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3733 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3734 caller()->ice_connection_state(), kDefaultTimeout);
3735 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3736 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08003737
3738 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3739 "WebRTC.PeerConnection.CandidatePairType_UDP",
3740 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003741}
3742
Steve Antonede9ca52017-10-16 13:04:27 -07003743// Test that firewalling the ICE connection causes the clients to identify the
3744// disconnected state and then removing the firewall causes them to reconnect.
3745class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003746 : public PeerConnectionIntegrationBaseTest,
3747 public ::testing::WithParamInterface<
3748 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003749 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003750 PeerConnectionIntegrationIceStatesTest()
3751 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3752 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003753 }
3754
3755 void StartStunServer(const SocketAddress& server_address) {
3756 stun_server_.reset(
3757 cricket::TestStunServer::Create(network_thread(), server_address));
3758 }
3759
3760 bool TestIPv6() {
3761 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3762 }
3763
3764 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003765 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
3766 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07003767 }
3768
3769 std::vector<SocketAddress> CallerAddresses() {
3770 std::vector<SocketAddress> addresses;
3771 addresses.push_back(SocketAddress("1.1.1.1", 0));
3772 if (TestIPv6()) {
3773 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3774 }
3775 return addresses;
3776 }
3777
3778 std::vector<SocketAddress> CalleeAddresses() {
3779 std::vector<SocketAddress> addresses;
3780 addresses.push_back(SocketAddress("2.2.2.2", 0));
3781 if (TestIPv6()) {
3782 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3783 }
3784 return addresses;
3785 }
3786
3787 void SetUpNetworkInterfaces() {
3788 // Remove the default interfaces added by the test infrastructure.
3789 caller()->network()->RemoveInterface(kDefaultLocalAddress);
3790 callee()->network()->RemoveInterface(kDefaultLocalAddress);
3791
3792 // Add network addresses for test.
3793 for (const auto& caller_address : CallerAddresses()) {
3794 caller()->network()->AddInterface(caller_address);
3795 }
3796 for (const auto& callee_address : CalleeAddresses()) {
3797 callee()->network()->AddInterface(callee_address);
3798 }
3799 }
3800
3801 private:
3802 uint32_t port_allocator_flags_;
3803 std::unique_ptr<cricket::TestStunServer> stun_server_;
3804};
3805
3806// Tests that the PeerConnection goes through all the ICE gathering/connection
3807// states over the duration of the call. This includes Disconnected and Failed
3808// states, induced by putting a firewall between the peers and waiting for them
3809// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003810TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
3811 // TODO(bugs.webrtc.org/8295): When using a ScopedFakeClock, this test will
3812 // sometimes hit a DCHECK in platform_thread.cc about the PacerThread being
3813 // too busy. For now, revert to running without a fake clock.
Steve Antonede9ca52017-10-16 13:04:27 -07003814
3815 const SocketAddress kStunServerAddress =
3816 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3817 StartStunServer(kStunServerAddress);
3818
3819 PeerConnectionInterface::RTCConfiguration config;
3820 PeerConnectionInterface::IceServer ice_stun_server;
3821 ice_stun_server.urls.push_back(
3822 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3823 kStunServerAddress.PortAsString());
3824 config.servers.push_back(ice_stun_server);
3825
3826 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3827 ConnectFakeSignaling();
3828 SetPortAllocatorFlags();
3829 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003830 caller()->AddAudioVideoTracks();
3831 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003832
3833 // Initial state before anything happens.
3834 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3835 caller()->ice_gathering_state());
3836 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3837 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003838 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3839 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07003840
3841 // Start the call by creating the offer, setting it as the local description,
3842 // then sending it to the peer who will respond with an answer. This happens
3843 // asynchronously so that we can watch the states as it runs in the
3844 // background.
3845 caller()->CreateAndSetAndSignalOffer();
3846
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003847 ASSERT_EQ(PeerConnectionInterface::kIceConnectionCompleted,
3848 caller()->ice_connection_state());
Jonas Olssondf919fb2019-01-22 11:21:00 +01003849 ASSERT_EQ(PeerConnectionInterface::kIceConnectionConnected,
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003850 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07003851
3852 // Verify that the observer was notified of the intermediate transitions.
3853 EXPECT_THAT(caller()->ice_connection_state_history(),
3854 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3855 PeerConnectionInterface::kIceConnectionConnected,
3856 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02003857 EXPECT_THAT(
3858 caller()->peer_connection_state_history(),
3859 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02003860 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07003861 EXPECT_THAT(caller()->ice_gathering_state_history(),
3862 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3863 PeerConnectionInterface::kIceGatheringComplete));
3864
3865 // Block connections to/from the caller and wait for ICE to become
3866 // disconnected.
3867 for (const auto& caller_address : CallerAddresses()) {
3868 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3869 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003870 RTC_LOG(LS_INFO) << "Firewall rules applied";
Steve Anton83119dd2017-11-10 16:19:52 -08003871 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3872 caller()->ice_connection_state(), kDefaultTimeout);
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003873 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
3874 caller()->standardized_ice_connection_state(),
3875 kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003876
3877 // Let ICE re-establish by removing the firewall rules.
3878 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01003879 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Steve Anton83119dd2017-11-10 16:19:52 -08003880 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3881 caller()->ice_connection_state(), kDefaultTimeout);
Jonas Olssondf919fb2019-01-22 11:21:00 +01003882 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionConnected,
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003883 caller()->standardized_ice_connection_state(),
3884 kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003885
3886 // According to RFC7675, if there is no response within 30 seconds then the
3887 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08003888 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07003889 constexpr int kConsentTimeout = 30000;
3890 for (const auto& caller_address : CallerAddresses()) {
3891 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
3892 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01003893 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Steve Anton83119dd2017-11-10 16:19:52 -08003894 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3895 caller()->ice_connection_state(), kConsentTimeout);
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003896 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
3897 caller()->standardized_ice_connection_state(),
3898 kConsentTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07003899}
3900
3901// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
3902// and that the statistics in the metric observers are updated correctly.
3903TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
3904 ASSERT_TRUE(CreatePeerConnectionWrappers());
3905 ConnectFakeSignaling();
3906 SetPortAllocatorFlags();
3907 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003908 caller()->AddAudioVideoTracks();
3909 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003910 caller()->CreateAndSetAndSignalOffer();
3911
3912 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3913
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003914 // TODO(bugs.webrtc.org/9456): Fix it.
3915 const int num_best_ipv4 = webrtc::metrics::NumEvents(
3916 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
3917 const int num_best_ipv6 = webrtc::metrics::NumEvents(
3918 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003919 if (TestIPv6()) {
3920 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
3921 // connection.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003922 EXPECT_EQ(0, num_best_ipv4);
3923 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003924 } else {
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003925 EXPECT_EQ(1, num_best_ipv4);
3926 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07003927 }
3928
Qingsi Wang7fc821d2018-07-12 12:54:53 -07003929 EXPECT_EQ(0, webrtc::metrics::NumEvents(
3930 "WebRTC.PeerConnection.CandidatePairType_UDP",
3931 webrtc::kIceCandidatePairHostHost));
3932 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3933 "WebRTC.PeerConnection.CandidatePairType_UDP",
3934 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07003935}
3936
3937constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
3938 cricket::PORTALLOCATOR_DISABLE_STUN |
3939 cricket::PORTALLOCATOR_DISABLE_RELAY;
3940constexpr uint32_t kFlagsIPv6NoStun =
3941 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
3942 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
3943constexpr uint32_t kFlagsIPv4Stun =
3944 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
3945
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003946INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08003947 PeerConnectionIntegrationTest,
3948 PeerConnectionIntegrationIceStatesTest,
3949 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3950 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
3951 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
3952 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07003953
deadbeef1dcb1642017-03-29 21:08:16 -07003954// This test sets up a call between two parties with audio and video.
3955// During the call, the caller restarts ICE and the test verifies that
3956// new ICE candidates are generated and audio and video still can flow, and the
3957// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003958TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07003959 ASSERT_TRUE(CreatePeerConnectionWrappers());
3960 ConnectFakeSignaling();
3961 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08003962 caller()->AddAudioVideoTracks();
3963 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003964 caller()->CreateAndSetAndSignalOffer();
3965 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3966 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3967 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00003968 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3969 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07003970
3971 // To verify that the ICE restart actually occurs, get
3972 // ufrag/password/candidates before and after restart.
3973 // Create an SDP string of the first audio candidate for both clients.
3974 const webrtc::IceCandidateCollection* audio_candidates_caller =
3975 caller()->pc()->local_description()->candidates(0);
3976 const webrtc::IceCandidateCollection* audio_candidates_callee =
3977 callee()->pc()->local_description()->candidates(0);
3978 ASSERT_GT(audio_candidates_caller->count(), 0u);
3979 ASSERT_GT(audio_candidates_callee->count(), 0u);
3980 std::string caller_candidate_pre_restart;
3981 ASSERT_TRUE(
3982 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
3983 std::string callee_candidate_pre_restart;
3984 ASSERT_TRUE(
3985 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
3986 const cricket::SessionDescription* desc =
3987 caller()->pc()->local_description()->description();
3988 std::string caller_ufrag_pre_restart =
3989 desc->transport_infos()[0].description.ice_ufrag;
3990 desc = callee()->pc()->local_description()->description();
3991 std::string callee_ufrag_pre_restart =
3992 desc->transport_infos()[0].description.ice_ufrag;
3993
3994 // Have the caller initiate an ICE restart.
3995 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
3996 caller()->CreateAndSetAndSignalOffer();
3997 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3998 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3999 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004000 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07004001 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4002
4003 // Grab the ufrags/candidates again.
4004 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
4005 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
4006 ASSERT_GT(audio_candidates_caller->count(), 0u);
4007 ASSERT_GT(audio_candidates_callee->count(), 0u);
4008 std::string caller_candidate_post_restart;
4009 ASSERT_TRUE(
4010 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
4011 std::string callee_candidate_post_restart;
4012 ASSERT_TRUE(
4013 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
4014 desc = caller()->pc()->local_description()->description();
4015 std::string caller_ufrag_post_restart =
4016 desc->transport_infos()[0].description.ice_ufrag;
4017 desc = callee()->pc()->local_description()->description();
4018 std::string callee_ufrag_post_restart =
4019 desc->transport_infos()[0].description.ice_ufrag;
4020 // Sanity check that an ICE restart was actually negotiated in SDP.
4021 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
4022 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
4023 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
4024 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
4025
4026 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004027 MediaExpectations media_expectations;
4028 media_expectations.ExpectBidirectionalAudioAndVideo();
4029 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004030}
4031
4032// Verify that audio/video can be received end-to-end when ICE renomination is
4033// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004034TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07004035 PeerConnectionInterface::RTCConfiguration config;
4036 config.enable_ice_renomination = true;
4037 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4038 ConnectFakeSignaling();
4039 // Do normal offer/answer and wait for some frames to be received in each
4040 // direction.
Steve Anton15324772018-01-16 10:26:49 -08004041 caller()->AddAudioVideoTracks();
4042 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004043 caller()->CreateAndSetAndSignalOffer();
4044 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4045 // Sanity check that ICE renomination was actually negotiated.
4046 const cricket::SessionDescription* desc =
4047 caller()->pc()->local_description()->description();
4048 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004049 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004050 }
4051 desc = callee()->pc()->local_description()->description();
4052 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004053 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004054 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08004055 MediaExpectations media_expectations;
4056 media_expectations.ExpectBidirectionalAudioAndVideo();
4057 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004058}
4059
Steve Anton6f25b092017-10-23 09:39:20 -07004060// With a max bundle policy and RTCP muxing, adding a new media description to
4061// the connection should not affect ICE at all because the new media will use
4062// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004063TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08004064 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07004065 PeerConnectionInterface::RTCConfiguration config;
4066 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4067 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4068 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
4069 config, PeerConnectionInterface::RTCConfiguration()));
4070 ConnectFakeSignaling();
4071
Steve Anton15324772018-01-16 10:26:49 -08004072 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004073 caller()->CreateAndSetAndSignalOffer();
4074 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07004075 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4076 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07004077
4078 caller()->clear_ice_connection_state_history();
4079
Steve Anton15324772018-01-16 10:26:49 -08004080 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004081 caller()->CreateAndSetAndSignalOffer();
4082 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4083
4084 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
4085}
4086
deadbeef1dcb1642017-03-29 21:08:16 -07004087// This test sets up a call between two parties with audio and video. It then
4088// renegotiates setting the video m-line to "port 0", then later renegotiates
4089// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004090TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07004091 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
4092 ASSERT_TRUE(CreatePeerConnectionWrappers());
4093 ConnectFakeSignaling();
4094
4095 // Do initial negotiation, only sending media from the caller. Will result in
4096 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08004097 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004098 caller()->CreateAndSetAndSignalOffer();
4099 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4100
4101 // Negotiate again, disabling the video "m=" section (the callee will set the
4102 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004103 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4104 PeerConnectionInterface::RTCOfferAnswerOptions options;
4105 options.offer_to_receive_video = 0;
4106 callee()->SetOfferAnswerOptions(options);
4107 } else {
4108 callee()->SetRemoteOfferHandler([this] {
4109 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
4110 });
4111 }
deadbeef1dcb1642017-03-29 21:08:16 -07004112 caller()->CreateAndSetAndSignalOffer();
4113 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4114 // Sanity check that video "m=" section was actually rejected.
4115 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
4116 callee()->pc()->local_description()->description());
4117 ASSERT_NE(nullptr, answer_video_content);
4118 ASSERT_TRUE(answer_video_content->rejected);
4119
4120 // Enable video and do negotiation again, making sure video is received
4121 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004122 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4123 PeerConnectionInterface::RTCOfferAnswerOptions options;
4124 options.offer_to_receive_video = 1;
4125 callee()->SetOfferAnswerOptions(options);
4126 } else {
4127 // The caller's transceiver is stopped, so we need to add another track.
4128 auto caller_transceiver =
4129 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
4130 EXPECT_TRUE(caller_transceiver->stopped());
4131 caller()->AddVideoTrack();
4132 }
4133 callee()->AddVideoTrack();
4134 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07004135 caller()->CreateAndSetAndSignalOffer();
4136 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004137
deadbeef1dcb1642017-03-29 21:08:16 -07004138 // Verify the caller receives frames from the newly added stream, and the
4139 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004140 MediaExpectations media_expectations;
4141 media_expectations.CalleeExpectsSomeAudio();
4142 media_expectations.ExpectBidirectionalVideo();
4143 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004144}
4145
deadbeef1dcb1642017-03-29 21:08:16 -07004146// This tests that if we negotiate after calling CreateSender but before we
4147// have a track, then set a track later, frames from the newly-set track are
4148// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004149TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07004150 MediaFlowsAfterEarlyWarmupWithCreateSender) {
4151 ASSERT_TRUE(CreatePeerConnectionWrappers());
4152 ConnectFakeSignaling();
4153 auto caller_audio_sender =
4154 caller()->pc()->CreateSender("audio", "caller_stream");
4155 auto caller_video_sender =
4156 caller()->pc()->CreateSender("video", "caller_stream");
4157 auto callee_audio_sender =
4158 callee()->pc()->CreateSender("audio", "callee_stream");
4159 auto callee_video_sender =
4160 callee()->pc()->CreateSender("video", "callee_stream");
4161 caller()->CreateAndSetAndSignalOffer();
4162 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4163 // Wait for ICE to complete, without any tracks being set.
4164 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4165 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4166 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4167 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4168 // Now set the tracks, and expect frames to immediately start flowing.
4169 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4170 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4171 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4172 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08004173 MediaExpectations media_expectations;
4174 media_expectations.ExpectBidirectionalAudioAndVideo();
4175 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4176}
4177
4178// This tests that if we negotiate after calling AddTransceiver but before we
4179// have a track, then set a track later, frames from the newly-set tracks are
4180// received end-to-end.
4181TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
4182 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
4183 ASSERT_TRUE(CreatePeerConnectionWrappers());
4184 ConnectFakeSignaling();
4185 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
4186 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
4187 auto caller_audio_sender = audio_result.MoveValue()->sender();
4188 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
4189 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
4190 auto caller_video_sender = video_result.MoveValue()->sender();
4191 callee()->SetRemoteOfferHandler([this] {
4192 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
4193 callee()->pc()->GetTransceivers()[0]->SetDirection(
4194 RtpTransceiverDirection::kSendRecv);
4195 callee()->pc()->GetTransceivers()[1]->SetDirection(
4196 RtpTransceiverDirection::kSendRecv);
4197 });
4198 caller()->CreateAndSetAndSignalOffer();
4199 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4200 // Wait for ICE to complete, without any tracks being set.
4201 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4202 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4203 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4204 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4205 // Now set the tracks, and expect frames to immediately start flowing.
4206 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
4207 auto callee_video_sender = callee()->pc()->GetSenders()[1];
4208 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4209 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4210 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4211 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
4212 MediaExpectations media_expectations;
4213 media_expectations.ExpectBidirectionalAudioAndVideo();
4214 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004215}
4216
4217// This test verifies that a remote video track can be added via AddStream,
4218// and sent end-to-end. For this particular test, it's simply echoed back
4219// from the caller to the callee, rather than being forwarded to a third
4220// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004221TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07004222 ASSERT_TRUE(CreatePeerConnectionWrappers());
4223 ConnectFakeSignaling();
4224 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08004225 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07004226 caller()->CreateAndSetAndSignalOffer();
4227 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004228 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07004229
4230 // Echo the stream back, and do a new offer/anwer (initiated by callee this
4231 // time).
4232 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
4233 callee()->CreateAndSetAndSignalOffer();
4234 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4235
Seth Hampson2f0d7022018-02-20 11:54:42 -08004236 MediaExpectations media_expectations;
4237 media_expectations.ExpectBidirectionalVideo();
4238 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004239}
4240
4241// Test that we achieve the expected end-to-end connection time, using a
4242// fake clock and simulated latency on the media and signaling paths.
4243// We use a TURN<->TURN connection because this is usually the quickest to
4244// set up initially, especially when we're confident the connection will work
4245// and can start sending media before we get a STUN response.
4246//
4247// With various optimizations enabled, here are the network delays we expect to
4248// be on the critical path:
4249// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
4250// signaling answer (with DTLS fingerprint).
4251// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
4252// using TURN<->TURN pair, and DTLS exchange is 4 packets,
4253// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004254TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07004255 rtc::ScopedFakeClock fake_clock;
4256 // Some things use a time of "0" as a special value, so we need to start out
4257 // the fake clock at a nonzero time.
4258 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004259 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07004260
4261 static constexpr int media_hop_delay_ms = 50;
4262 static constexpr int signaling_trip_delay_ms = 500;
4263 // For explanation of these values, see comment above.
4264 static constexpr int required_media_hops = 9;
4265 static constexpr int required_signaling_trips = 2;
4266 // For internal delays (such as posting an event asychronously).
4267 static constexpr int allowed_internal_delay_ms = 20;
4268 static constexpr int total_connection_time_ms =
4269 media_hop_delay_ms * required_media_hops +
4270 signaling_trip_delay_ms * required_signaling_trips +
4271 allowed_internal_delay_ms;
4272
4273 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4274 3478};
4275 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4276 0};
4277 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4278 3478};
4279 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4280 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004281 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4282 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004283
Seth Hampsonaed71642018-06-11 07:41:32 -07004284 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4285 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07004286 // Bypass permission check on received packets so media can be sent before
4287 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07004288 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4289 turn_server_1->set_enable_permission_checks(false);
4290 });
4291 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4292 turn_server_2->set_enable_permission_checks(false);
4293 });
deadbeef1dcb1642017-03-29 21:08:16 -07004294
4295 PeerConnectionInterface::RTCConfiguration client_1_config;
4296 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4297 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4298 ice_server_1.username = "test";
4299 ice_server_1.password = "test";
4300 client_1_config.servers.push_back(ice_server_1);
4301 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4302 client_1_config.presume_writable_when_fully_relayed = true;
4303
4304 PeerConnectionInterface::RTCConfiguration client_2_config;
4305 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4306 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4307 ice_server_2.username = "test";
4308 ice_server_2.password = "test";
4309 client_2_config.servers.push_back(ice_server_2);
4310 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4311 client_2_config.presume_writable_when_fully_relayed = true;
4312
4313 ASSERT_TRUE(
4314 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4315 // Set up the simulated delays.
4316 SetSignalingDelayMs(signaling_trip_delay_ms);
4317 ConnectFakeSignaling();
4318 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4319 virtual_socket_server()->UpdateDelayDistribution();
4320
4321 // Set "offer to receive audio/video" without adding any tracks, so we just
4322 // set up ICE/DTLS with no media.
4323 PeerConnectionInterface::RTCOfferAnswerOptions options;
4324 options.offer_to_receive_audio = 1;
4325 options.offer_to_receive_video = 1;
4326 caller()->SetOfferAnswerOptions(options);
4327 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004328 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
4329 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004330 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4331 // If this is not done a DCHECK can be hit in ports.cc, because a large
4332 // negative number is calculated for the rtt due to the global clock changing.
4333 caller()->pc()->Close();
4334 callee()->pc()->Close();
deadbeef1dcb1642017-03-29 21:08:16 -07004335}
4336
Jonas Orelandbdcee282017-10-10 14:01:40 +02004337// Verify that a TurnCustomizer passed in through RTCConfiguration
4338// is actually used by the underlying TURN candidate pair.
4339// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004340TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004341 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4342 3478};
4343 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4344 0};
4345 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4346 3478};
4347 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4348 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004349 CreateTurnServer(turn_server_1_internal_address,
4350 turn_server_1_external_address);
4351 CreateTurnServer(turn_server_2_internal_address,
4352 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004353
4354 PeerConnectionInterface::RTCConfiguration client_1_config;
4355 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4356 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4357 ice_server_1.username = "test";
4358 ice_server_1.password = "test";
4359 client_1_config.servers.push_back(ice_server_1);
4360 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004361 auto* customizer1 = CreateTurnCustomizer();
4362 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004363
4364 PeerConnectionInterface::RTCConfiguration client_2_config;
4365 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4366 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4367 ice_server_2.username = "test";
4368 ice_server_2.password = "test";
4369 client_2_config.servers.push_back(ice_server_2);
4370 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004371 auto* customizer2 = CreateTurnCustomizer();
4372 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004373
4374 ASSERT_TRUE(
4375 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4376 ConnectFakeSignaling();
4377
4378 // Set "offer to receive audio/video" without adding any tracks, so we just
4379 // set up ICE/DTLS with no media.
4380 PeerConnectionInterface::RTCOfferAnswerOptions options;
4381 options.offer_to_receive_audio = 1;
4382 options.offer_to_receive_video = 1;
4383 caller()->SetOfferAnswerOptions(options);
4384 caller()->CreateAndSetAndSignalOffer();
4385 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4386
Seth Hampsonaed71642018-06-11 07:41:32 -07004387 ExpectTurnCustomizerCountersIncremented(customizer1);
4388 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004389}
4390
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004391// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4392// send media between the caller and the callee.
4393TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4394 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4395 3478};
4396 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4397
4398 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004399 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4400 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004401
4402 webrtc::PeerConnectionInterface::IceServer ice_server;
4403 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4404 ice_server.username = "test";
4405 ice_server.password = "test";
4406
4407 PeerConnectionInterface::RTCConfiguration client_1_config;
4408 client_1_config.servers.push_back(ice_server);
4409 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4410
4411 PeerConnectionInterface::RTCConfiguration client_2_config;
4412 client_2_config.servers.push_back(ice_server);
4413 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4414
4415 ASSERT_TRUE(
4416 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4417
4418 // Do normal offer/answer and wait for ICE to complete.
4419 ConnectFakeSignaling();
4420 caller()->AddAudioVideoTracks();
4421 callee()->AddAudioVideoTracks();
4422 caller()->CreateAndSetAndSignalOffer();
4423 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4424 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4425 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4426
4427 MediaExpectations media_expectations;
4428 media_expectations.ExpectBidirectionalAudioAndVideo();
4429 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4430}
4431
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004432// Verify that a SSLCertificateVerifier passed in through
4433// PeerConnectionDependencies is actually used by the underlying SSL
4434// implementation to determine whether a certificate presented by the TURN
4435// server is accepted by the client. Note that openssladapter_unittest.cc
4436// contains more detailed, lower-level tests.
4437TEST_P(PeerConnectionIntegrationTest,
4438 SSLCertificateVerifierUsedForTurnConnections) {
4439 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4440 3478};
4441 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4442
4443 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4444 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004445 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4446 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004447
4448 webrtc::PeerConnectionInterface::IceServer ice_server;
4449 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4450 ice_server.username = "test";
4451 ice_server.password = "test";
4452
4453 PeerConnectionInterface::RTCConfiguration client_1_config;
4454 client_1_config.servers.push_back(ice_server);
4455 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4456
4457 PeerConnectionInterface::RTCConfiguration client_2_config;
4458 client_2_config.servers.push_back(ice_server);
4459 // Setting the type to kRelay forces the connection to go through a TURN
4460 // server.
4461 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4462
4463 // Get a copy to the pointer so we can verify calls later.
4464 rtc::TestCertificateVerifier* client_1_cert_verifier =
4465 new rtc::TestCertificateVerifier();
4466 client_1_cert_verifier->verify_certificate_ = true;
4467 rtc::TestCertificateVerifier* client_2_cert_verifier =
4468 new rtc::TestCertificateVerifier();
4469 client_2_cert_verifier->verify_certificate_ = true;
4470
4471 // Create the dependencies with the test certificate verifier.
4472 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4473 client_1_deps.tls_cert_verifier =
4474 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4475 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4476 client_2_deps.tls_cert_verifier =
4477 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4478
4479 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4480 client_1_config, std::move(client_1_deps), client_2_config,
4481 std::move(client_2_deps)));
4482 ConnectFakeSignaling();
4483
4484 // Set "offer to receive audio/video" without adding any tracks, so we just
4485 // set up ICE/DTLS with no media.
4486 PeerConnectionInterface::RTCOfferAnswerOptions options;
4487 options.offer_to_receive_audio = 1;
4488 options.offer_to_receive_video = 1;
4489 caller()->SetOfferAnswerOptions(options);
4490 caller()->CreateAndSetAndSignalOffer();
4491 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4492
4493 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4494 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004495}
4496
4497TEST_P(PeerConnectionIntegrationTest,
4498 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4499 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4500 3478};
4501 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4502
4503 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4504 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004505 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4506 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004507
4508 webrtc::PeerConnectionInterface::IceServer ice_server;
4509 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4510 ice_server.username = "test";
4511 ice_server.password = "test";
4512
4513 PeerConnectionInterface::RTCConfiguration client_1_config;
4514 client_1_config.servers.push_back(ice_server);
4515 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4516
4517 PeerConnectionInterface::RTCConfiguration client_2_config;
4518 client_2_config.servers.push_back(ice_server);
4519 // Setting the type to kRelay forces the connection to go through a TURN
4520 // server.
4521 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4522
4523 // Get a copy to the pointer so we can verify calls later.
4524 rtc::TestCertificateVerifier* client_1_cert_verifier =
4525 new rtc::TestCertificateVerifier();
4526 client_1_cert_verifier->verify_certificate_ = false;
4527 rtc::TestCertificateVerifier* client_2_cert_verifier =
4528 new rtc::TestCertificateVerifier();
4529 client_2_cert_verifier->verify_certificate_ = false;
4530
4531 // Create the dependencies with the test certificate verifier.
4532 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4533 client_1_deps.tls_cert_verifier =
4534 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4535 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4536 client_2_deps.tls_cert_verifier =
4537 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4538
4539 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4540 client_1_config, std::move(client_1_deps), client_2_config,
4541 std::move(client_2_deps)));
4542 ConnectFakeSignaling();
4543
4544 // Set "offer to receive audio/video" without adding any tracks, so we just
4545 // set up ICE/DTLS with no media.
4546 PeerConnectionInterface::RTCOfferAnswerOptions options;
4547 options.offer_to_receive_audio = 1;
4548 options.offer_to_receive_video = 1;
4549 caller()->SetOfferAnswerOptions(options);
4550 caller()->CreateAndSetAndSignalOffer();
4551 bool wait_res = true;
4552 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4553 // properly, should be able to just wait for a state of "failed" instead of
4554 // waiting a fixed 10 seconds.
4555 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4556 ASSERT_FALSE(wait_res);
4557
4558 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4559 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004560}
4561
deadbeefc964d0b2017-04-03 10:03:35 -07004562// Test that audio and video flow end-to-end when codec names don't use the
4563// expected casing, given that they're supposed to be case insensitive. To test
4564// this, all but one codec is removed from each media description, and its
4565// casing is changed.
4566//
4567// In the past, this has regressed and caused crashes/black video, due to the
4568// fact that code at some layers was doing case-insensitive comparisons and
4569// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004570TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004571 ASSERT_TRUE(CreatePeerConnectionWrappers());
4572 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004573 caller()->AddAudioVideoTracks();
4574 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004575
4576 // Remove all but one audio/video codec (opus and VP8), and change the
4577 // casing of the caller's generated offer.
4578 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4579 cricket::AudioContentDescription* audio =
4580 GetFirstAudioContentDescription(description);
4581 ASSERT_NE(nullptr, audio);
4582 auto audio_codecs = audio->codecs();
4583 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4584 [](const cricket::AudioCodec& codec) {
4585 return codec.name != "opus";
4586 }),
4587 audio_codecs.end());
4588 ASSERT_EQ(1u, audio_codecs.size());
4589 audio_codecs[0].name = "OpUs";
4590 audio->set_codecs(audio_codecs);
4591
4592 cricket::VideoContentDescription* video =
4593 GetFirstVideoContentDescription(description);
4594 ASSERT_NE(nullptr, video);
4595 auto video_codecs = video->codecs();
4596 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4597 [](const cricket::VideoCodec& codec) {
4598 return codec.name != "VP8";
4599 }),
4600 video_codecs.end());
4601 ASSERT_EQ(1u, video_codecs.size());
4602 video_codecs[0].name = "vP8";
4603 video->set_codecs(video_codecs);
4604 });
4605
4606 caller()->CreateAndSetAndSignalOffer();
4607 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4608
4609 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004610 MediaExpectations media_expectations;
4611 media_expectations.ExpectBidirectionalAudioAndVideo();
4612 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004613}
4614
Jonas Oreland49ac5952018-09-26 16:04:32 +02004615TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07004616 ASSERT_TRUE(CreatePeerConnectionWrappers());
4617 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004618 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004619 caller()->CreateAndSetAndSignalOffer();
4620 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004621 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004622 MediaExpectations media_expectations;
4623 media_expectations.CalleeExpectsSomeAudio(1);
4624 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02004625 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07004626 auto receiver = callee()->pc()->GetReceivers()[0];
4627 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004628 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07004629 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4630 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02004631 sources[0].source_id());
4632 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
4633}
4634
4635TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
4636 ASSERT_TRUE(CreatePeerConnectionWrappers());
4637 ConnectFakeSignaling();
4638 caller()->AddVideoTrack();
4639 caller()->CreateAndSetAndSignalOffer();
4640 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4641 // Wait for one video frame to be received by the callee.
4642 MediaExpectations media_expectations;
4643 media_expectations.CalleeExpectsSomeVideo(1);
4644 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4645 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
4646 auto receiver = callee()->pc()->GetReceivers()[0];
4647 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
4648 auto sources = receiver->GetSources();
4649 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4650 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4651 sources[0].source_id());
4652 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07004653}
4654
deadbeef2f425aa2017-04-14 10:41:32 -07004655// Test that if a track is removed and added again with a different stream ID,
4656// the new stream ID is successfully communicated in SDP and media continues to
4657// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004658// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4659// it will not reuse a transceiver that has already been sending. After creating
4660// a new transceiver it tries to create an offer with two senders of the same
4661// track ids and it fails.
4662TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004663 ASSERT_TRUE(CreatePeerConnectionWrappers());
4664 ConnectFakeSignaling();
4665
deadbeef2f425aa2017-04-14 10:41:32 -07004666 // Add track using stream 1, do offer/answer.
4667 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4668 caller()->CreateLocalAudioTrack();
4669 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07004670 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07004671 caller()->CreateAndSetAndSignalOffer();
4672 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004673 {
4674 MediaExpectations media_expectations;
4675 media_expectations.CalleeExpectsSomeAudio(1);
4676 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4677 }
deadbeef2f425aa2017-04-14 10:41:32 -07004678 // Remove the sender, and create a new one with the new stream.
4679 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07004680 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07004681 caller()->CreateAndSetAndSignalOffer();
4682 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4683 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004684 {
4685 MediaExpectations media_expectations;
4686 media_expectations.CalleeExpectsSomeAudio();
4687 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4688 }
deadbeef2f425aa2017-04-14 10:41:32 -07004689}
4690
Seth Hampson2f0d7022018-02-20 11:54:42 -08004691TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004692 ASSERT_TRUE(CreatePeerConnectionWrappers());
4693 ConnectFakeSignaling();
4694
Karl Wiberg918f50c2018-07-05 11:40:33 +02004695 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Elad Alon99c3fe52017-10-13 16:29:40 +02004696 ON_CALL(*output, IsActive()).WillByDefault(testing::Return(true));
4697 ON_CALL(*output, Write(::testing::_)).WillByDefault(testing::Return(true));
4698 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004699 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4700 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004701
Steve Anton15324772018-01-16 10:26:49 -08004702 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004703 caller()->CreateAndSetAndSignalOffer();
4704 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4705}
4706
Steve Antonede9ca52017-10-16 13:04:27 -07004707// Test that if candidates are only signaled by applying full session
4708// descriptions (instead of using AddIceCandidate), the peers can connect to
4709// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004710TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004711 ASSERT_TRUE(CreatePeerConnectionWrappers());
4712 // Each side will signal the session descriptions but not candidates.
4713 ConnectFakeSignalingForSdpOnly();
4714
4715 // Add audio video track and exchange the initial offer/answer with media
4716 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004717 caller()->AddAudioVideoTracks();
4718 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004719 caller()->CreateAndSetAndSignalOffer();
4720
4721 // Wait for all candidates to be gathered on both the caller and callee.
4722 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4723 caller()->ice_gathering_state(), kDefaultTimeout);
4724 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4725 callee()->ice_gathering_state(), kDefaultTimeout);
4726
4727 // The candidates will now be included in the session description, so
4728 // signaling them will start the ICE connection.
4729 caller()->CreateAndSetAndSignalOffer();
4730 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4731
4732 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004733 MediaExpectations media_expectations;
4734 media_expectations.ExpectBidirectionalAudioAndVideo();
4735 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004736}
4737
henrika5f6bf242017-11-01 11:06:56 +01004738// Test that SetAudioPlayout can be used to disable audio playout from the
4739// start, then later enable it. This may be useful, for example, if the caller
4740// needs to play a local ringtone until some event occurs, after which it
4741// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004742TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004743 ASSERT_TRUE(CreatePeerConnectionWrappers());
4744 ConnectFakeSignaling();
4745
4746 // Set up audio-only call where audio playout is disabled on caller's side.
4747 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004748 caller()->AddAudioTrack();
4749 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004750 caller()->CreateAndSetAndSignalOffer();
4751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4752
4753 // Pump messages for a second.
4754 WAIT(false, 1000);
4755 // Since audio playout is disabled, the caller shouldn't have received
4756 // anything (at the playout level, at least).
4757 EXPECT_EQ(0, caller()->audio_frames_received());
4758 // As a sanity check, make sure the callee (for which playout isn't disabled)
4759 // did still see frames on its audio level.
4760 ASSERT_GT(callee()->audio_frames_received(), 0);
4761
4762 // Enable playout again, and ensure audio starts flowing.
4763 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004764 MediaExpectations media_expectations;
4765 media_expectations.ExpectBidirectionalAudio();
4766 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004767}
4768
4769double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4770 auto report = pc->NewGetStats();
4771 auto track_stats_list =
4772 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4773 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4774 for (const auto* track_stats : track_stats_list) {
4775 if (track_stats->remote_source.is_defined() &&
4776 *track_stats->remote_source) {
4777 remote_track_stats = track_stats;
4778 break;
4779 }
4780 }
4781
4782 if (!remote_track_stats->total_audio_energy.is_defined()) {
4783 return 0.0;
4784 }
4785 return *remote_track_stats->total_audio_energy;
4786}
4787
4788// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4789// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004790TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004791 DisableAudioPlayoutStillGeneratesAudioStats) {
4792 ASSERT_TRUE(CreatePeerConnectionWrappers());
4793 ConnectFakeSignaling();
4794
4795 // Set up audio-only call where playout is disabled but audio-processing is
4796 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004797 caller()->AddAudioTrack();
4798 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004799 caller()->pc()->SetAudioPlayout(false);
4800
4801 caller()->CreateAndSetAndSignalOffer();
4802 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4803
4804 // Wait for the callee to receive audio stats.
4805 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4806}
4807
henrika4f167df2017-11-01 14:45:55 +01004808// Test that SetAudioRecording can be used to disable audio recording from the
4809// start, then later enable it. This may be useful, for example, if the caller
4810// wants to ensure that no audio resources are active before a certain state
4811// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004812TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01004813 ASSERT_TRUE(CreatePeerConnectionWrappers());
4814 ConnectFakeSignaling();
4815
4816 // Set up audio-only call where audio recording is disabled on caller's side.
4817 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08004818 caller()->AddAudioTrack();
4819 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01004820 caller()->CreateAndSetAndSignalOffer();
4821 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4822
4823 // Pump messages for a second.
4824 WAIT(false, 1000);
4825 // Since caller has disabled audio recording, the callee shouldn't have
4826 // received anything.
4827 EXPECT_EQ(0, callee()->audio_frames_received());
4828 // As a sanity check, make sure the caller did still see frames on its
4829 // audio level since audio recording is enabled on the calle side.
4830 ASSERT_GT(caller()->audio_frames_received(), 0);
4831
4832 // Enable audio recording again, and ensure audio starts flowing.
4833 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004834 MediaExpectations media_expectations;
4835 media_expectations.ExpectBidirectionalAudio();
4836 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01004837}
4838
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004839// Test that after closing PeerConnections, they stop sending any packets (ICE,
4840// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004841TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004842 // Set up audio/video/data, wait for some frames to be received.
4843 ASSERT_TRUE(CreatePeerConnectionWrappers());
4844 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004845 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004846#ifdef HAVE_SCTP
4847 caller()->CreateDataChannel();
4848#endif
4849 caller()->CreateAndSetAndSignalOffer();
4850 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004851 MediaExpectations media_expectations;
4852 media_expectations.CalleeExpectsSomeAudioAndVideo();
4853 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08004854 // Close PeerConnections.
4855 caller()->pc()->Close();
4856 callee()->pc()->Close();
4857 // Pump messages for a second, and ensure no new packets end up sent.
4858 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
4859 WAIT(false, 1000);
4860 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
4861 EXPECT_EQ(sent_packets_a, sent_packets_b);
4862}
4863
Steve Anton7eca0932018-03-30 15:18:41 -07004864// Test that transport stats are generated by the RTCStatsCollector for a
4865// connection that only involves data channels. This is a regression test for
4866// crbug.com/826972.
4867#ifdef HAVE_SCTP
4868TEST_P(PeerConnectionIntegrationTest,
4869 TransportStatsReportedForDataChannelOnlyConnection) {
4870 ASSERT_TRUE(CreatePeerConnectionWrappers());
4871 ConnectFakeSignaling();
4872 caller()->CreateDataChannel();
4873
4874 caller()->CreateAndSetAndSignalOffer();
4875 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4876 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
4877
4878 auto caller_report = caller()->NewGetStats();
4879 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
4880 auto callee_report = callee()->NewGetStats();
4881 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
4882}
4883#endif // HAVE_SCTP
4884
Qingsi Wang7685e862018-06-11 20:15:46 -07004885TEST_P(PeerConnectionIntegrationTest,
4886 IceEventsGeneratedAndLoggedInRtcEventLog) {
4887 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
4888 ConnectFakeSignaling();
4889 PeerConnectionInterface::RTCOfferAnswerOptions options;
4890 options.offer_to_receive_audio = 1;
4891 caller()->SetOfferAnswerOptions(options);
4892 caller()->CreateAndSetAndSignalOffer();
4893 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4894 ASSERT_NE(nullptr, caller()->event_log_factory());
4895 ASSERT_NE(nullptr, callee()->event_log_factory());
4896 webrtc::FakeRtcEventLog* caller_event_log =
4897 static_cast<webrtc::FakeRtcEventLog*>(
4898 caller()->event_log_factory()->last_log_created());
4899 webrtc::FakeRtcEventLog* callee_event_log =
4900 static_cast<webrtc::FakeRtcEventLog*>(
4901 callee()->event_log_factory()->last_log_created());
4902 ASSERT_NE(nullptr, caller_event_log);
4903 ASSERT_NE(nullptr, callee_event_log);
4904 int caller_ice_config_count = caller_event_log->GetEventCount(
4905 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4906 int caller_ice_event_count = caller_event_log->GetEventCount(
4907 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4908 int callee_ice_config_count = callee_event_log->GetEventCount(
4909 webrtc::RtcEvent::Type::IceCandidatePairConfig);
4910 int callee_ice_event_count = callee_event_log->GetEventCount(
4911 webrtc::RtcEvent::Type::IceCandidatePairEvent);
4912 EXPECT_LT(0, caller_ice_config_count);
4913 EXPECT_LT(0, caller_ice_event_count);
4914 EXPECT_LT(0, callee_ice_config_count);
4915 EXPECT_LT(0, callee_ice_event_count);
4916}
4917
Mirko Bonadeic84f6612019-01-31 12:20:57 +01004918INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
4919 PeerConnectionIntegrationTest,
4920 Values(SdpSemantics::kPlanB,
4921 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08004922
Steve Anton74255ff2018-01-24 18:32:57 -08004923// Tests that verify interoperability between Plan B and Unified Plan
4924// PeerConnections.
4925class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08004926 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08004927 public ::testing::WithParamInterface<
4928 std::tuple<SdpSemantics, SdpSemantics>> {
4929 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08004930 // Setting the SdpSemantics for the base test to kDefault does not matter
4931 // because we specify not to use the test semantics when creating
4932 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08004933 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07004934 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08004935 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08004936 callee_semantics_(std::get<1>(GetParam())) {}
4937
4938 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07004939 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
4940 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08004941 }
4942
4943 const SdpSemantics caller_semantics_;
4944 const SdpSemantics callee_semantics_;
4945};
4946
4947TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
4948 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4949 ConnectFakeSignaling();
4950
4951 caller()->CreateAndSetAndSignalOffer();
4952 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4953}
4954
4955TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
4956 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4957 ConnectFakeSignaling();
4958 auto audio_sender = caller()->AddAudioTrack();
4959
4960 caller()->CreateAndSetAndSignalOffer();
4961 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4962
4963 // Verify that one audio receiver has been created on the remote and that it
4964 // has the same track ID as the sending track.
4965 auto receivers = callee()->pc()->GetReceivers();
4966 ASSERT_EQ(1u, receivers.size());
4967 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
4968 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
4969
Seth Hampson2f0d7022018-02-20 11:54:42 -08004970 MediaExpectations media_expectations;
4971 media_expectations.CalleeExpectsSomeAudio();
4972 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004973}
4974
4975TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
4976 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
4977 ConnectFakeSignaling();
4978 auto video_sender = caller()->AddVideoTrack();
4979 auto audio_sender = caller()->AddAudioTrack();
4980
4981 caller()->CreateAndSetAndSignalOffer();
4982 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4983
4984 // Verify that one audio and one video receiver have been created on the
4985 // remote and that they have the same track IDs as the sending tracks.
4986 auto audio_receivers =
4987 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
4988 ASSERT_EQ(1u, audio_receivers.size());
4989 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
4990 auto video_receivers =
4991 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
4992 ASSERT_EQ(1u, video_receivers.size());
4993 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
4994
Seth Hampson2f0d7022018-02-20 11:54:42 -08004995 MediaExpectations media_expectations;
4996 media_expectations.CalleeExpectsSomeAudioAndVideo();
4997 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08004998}
4999
5000TEST_P(PeerConnectionIntegrationInteropTest,
5001 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
5002 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5003 ConnectFakeSignaling();
5004 caller()->AddAudioVideoTracks();
5005 callee()->AddAudioVideoTracks();
5006
5007 caller()->CreateAndSetAndSignalOffer();
5008 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5009
Seth Hampson2f0d7022018-02-20 11:54:42 -08005010 MediaExpectations media_expectations;
5011 media_expectations.ExpectBidirectionalAudioAndVideo();
5012 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005013}
5014
5015TEST_P(PeerConnectionIntegrationInteropTest,
5016 ReverseRolesOneAudioLocalToOneVideoRemote) {
5017 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5018 ConnectFakeSignaling();
5019 caller()->AddAudioTrack();
5020 callee()->AddVideoTrack();
5021
5022 caller()->CreateAndSetAndSignalOffer();
5023 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5024
5025 // Verify that only the audio track has been negotiated.
5026 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
5027 // Might also check that the callee's NegotiationNeeded flag is set.
5028
5029 // Reverse roles.
5030 callee()->CreateAndSetAndSignalOffer();
5031 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5032
Seth Hampson2f0d7022018-02-20 11:54:42 -08005033 MediaExpectations media_expectations;
5034 media_expectations.CallerExpectsSomeVideo();
5035 media_expectations.CalleeExpectsSomeAudio();
5036 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005037}
5038
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005039INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07005040 PeerConnectionIntegrationTest,
5041 PeerConnectionIntegrationInteropTest,
5042 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
5043 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
5044
5045// Test that if the Unified Plan side offers two video tracks then the Plan B
5046// side will only see the first one and ignore the second.
5047TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07005048 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
5049 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08005050 ConnectFakeSignaling();
5051 auto first_sender = caller()->AddVideoTrack();
5052 caller()->AddVideoTrack();
5053
5054 caller()->CreateAndSetAndSignalOffer();
5055 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5056
5057 // Verify that there is only one receiver and it corresponds to the first
5058 // added track.
5059 auto receivers = callee()->pc()->GetReceivers();
5060 ASSERT_EQ(1u, receivers.size());
5061 EXPECT_TRUE(receivers[0]->track()->enabled());
5062 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
5063
Seth Hampson2f0d7022018-02-20 11:54:42 -08005064 MediaExpectations media_expectations;
5065 media_expectations.CalleeExpectsSomeVideo();
5066 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005067}
5068
Steve Anton2bed3972019-01-04 17:04:30 -08005069// Test that if the initial offer tagged BUNDLE section is rejected due to its
5070// associated RtpTransceiver being stopped and another transceiver is added,
5071// then renegotiation causes the callee to receive the new video track without
5072// error.
5073// This is a regression test for bugs.webrtc.org/9954
5074TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5075 ReOfferWithStoppedBundleTaggedTransceiver) {
5076 RTCConfiguration config;
5077 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
5078 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5079 ConnectFakeSignaling();
5080 auto audio_transceiver_or_error =
5081 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5082 ASSERT_TRUE(audio_transceiver_or_error.ok());
5083 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5084
5085 caller()->CreateAndSetAndSignalOffer();
5086 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5087 {
5088 MediaExpectations media_expectations;
5089 media_expectations.CalleeExpectsSomeAudio();
5090 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5091 }
5092
5093 audio_transceiver->Stop();
5094 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5095
5096 caller()->CreateAndSetAndSignalOffer();
5097 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5098 {
5099 MediaExpectations media_expectations;
5100 media_expectations.CalleeExpectsSomeVideo();
5101 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5102 }
5103}
5104
deadbeef1dcb1642017-03-29 21:08:16 -07005105} // namespace
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01005106} // namespace webrtc
deadbeef1dcb1642017-03-29 21:08:16 -07005107
5108#endif // if !defined(THREAD_SANITIZER)