blob: 42d6c51e66b9ad72a12cd2dfdc624f35cb7d06e4 [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"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "api/media_stream_interface.h"
27#include "api/peer_connection_interface.h"
28#include "api/peer_connection_proxy.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020029#include "api/rtc_event_log/rtc_event_log_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "api/rtp_receiver_interface.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020031#include "api/task_queue/default_task_queue_factory.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/sdp_video_format.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070035#include "call/call.h"
36#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "media/engine/fake_webrtc_video_engine.h"
38#include "media/engine/webrtc_media_engine.h"
Danil Chapovalov9da25bd2019-06-20 10:19:42 +020039#include "media/engine/webrtc_media_engine_defaults.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "p2p/base/mock_async_resolver.h"
41#include "p2p/base/p2p_constants.h"
42#include "p2p/base/port_interface.h"
43#include "p2p/base/test_stun_server.h"
44#include "p2p/base/test_turn_customizer.h"
45#include "p2p/base/test_turn_server.h"
46#include "p2p/client/basic_port_allocator.h"
47#include "pc/dtmf_sender.h"
48#include "pc/local_audio_source.h"
49#include "pc/media_session.h"
50#include "pc/peer_connection.h"
51#include "pc/peer_connection_factory.h"
52#include "pc/rtp_media_utils.h"
53#include "pc/session_description.h"
54#include "pc/test/fake_audio_capture_module.h"
55#include "pc/test/fake_periodic_video_track_source.h"
56#include "pc/test/fake_rtc_certificate_generator.h"
57#include "pc/test/fake_video_track_renderer.h"
58#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010059#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070060#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080061#include "rtc_base/fake_network.h"
62#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020063#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020064#include "rtc_base/numerics/safe_conversions.h"
Steve Anton10542f22019-01-11 09:11:00 -080065#include "rtc_base/test_certificate_verifier.h"
66#include "rtc_base/time_utils.h"
67#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020068#include "system_wrappers/include/metrics.h"
Qingsi Wangc129c352019-04-18 10:41:58 -070069#include "test/field_trial.h"
Elad Alon99c3fe52017-10-13 16:29:40 +020070#include "test/gmock.h"
deadbeef1dcb1642017-03-29 21:08:16 -070071
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010072namespace webrtc {
73namespace {
74
75using ::cricket::ContentInfo;
76using ::cricket::StreamParams;
77using ::rtc::SocketAddress;
78using ::testing::_;
Seth Hampson2f0d7022018-02-20 11:54:42 -080079using ::testing::Combine;
Steve Anton64b626b2019-01-28 17:25:26 -080080using ::testing::Contains;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010081using ::testing::DoAll;
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 Olssonacd8ae72019-02-25 15:26:24 +0100283 // Every standardized ICE connection state in order that has been seen by the
284 // observer.
285 std::vector<PeerConnectionInterface::IceConnectionState>
286 standardized_ice_connection_state_history() const {
287 return standardized_ice_connection_state_history_;
288 }
289
Jonas Olsson635474e2018-10-18 15:58:17 +0200290 // Every PeerConnection state in order that has been seen by the observer.
291 std::vector<PeerConnectionInterface::PeerConnectionState>
292 peer_connection_state_history() const {
293 return peer_connection_state_history_;
294 }
295
Steve Antonede9ca52017-10-16 13:04:27 -0700296 // Every ICE gathering state in order that has been seen by the observer.
297 std::vector<PeerConnectionInterface::IceGatheringState>
298 ice_gathering_state_history() const {
299 return ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -0700300 }
301
Steve Anton15324772018-01-16 10:26:49 -0800302 void AddAudioVideoTracks() {
303 AddAudioTrack();
304 AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700305 }
306
Steve Anton74255ff2018-01-24 18:32:57 -0800307 rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack() {
308 return AddTrack(CreateLocalAudioTrack());
309 }
deadbeef1dcb1642017-03-29 21:08:16 -0700310
Steve Anton74255ff2018-01-24 18:32:57 -0800311 rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack() {
312 return AddTrack(CreateLocalVideoTrack());
313 }
deadbeef1dcb1642017-03-29 21:08:16 -0700314
315 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack() {
Niels Möller2d02e082018-05-21 11:23:35 +0200316 cricket::AudioOptions options;
deadbeef1dcb1642017-03-29 21:08:16 -0700317 // Disable highpass filter so that we can get all the test audio frames.
Niels Möller2d02e082018-05-21 11:23:35 +0200318 options.highpass_filter = false;
deadbeef1dcb1642017-03-29 21:08:16 -0700319 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200320 peer_connection_factory_->CreateAudioSource(options);
deadbeef1dcb1642017-03-29 21:08:16 -0700321 // TODO(perkj): Test audio source when it is implemented. Currently audio
322 // always use the default input.
deadbeefb1a15d72017-09-07 14:12:05 -0700323 return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(),
deadbeef1dcb1642017-03-29 21:08:16 -0700324 source);
325 }
326
327 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
Johannes Kron965e7942018-09-13 15:36:20 +0200328 webrtc::FakePeriodicVideoSource::Config config;
329 config.timestamp_offset_ms = rtc::TimeMillis();
330 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700331 }
332
333 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller5c7efe72018-05-11 10:34:46 +0200334 CreateLocalVideoTrackWithConfig(
335 webrtc::FakePeriodicVideoSource::Config config) {
336 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700337 }
338
339 rtc::scoped_refptr<webrtc::VideoTrackInterface>
340 CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
Niels Möller5c7efe72018-05-11 10:34:46 +0200341 webrtc::FakePeriodicVideoSource::Config config;
342 config.rotation = rotation;
Johannes Kron965e7942018-09-13 15:36:20 +0200343 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200344 return CreateLocalVideoTrackInternal(config);
deadbeef1dcb1642017-03-29 21:08:16 -0700345 }
346
Steve Anton74255ff2018-01-24 18:32:57 -0800347 rtc::scoped_refptr<RtpSenderInterface> AddTrack(
348 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800349 const std::vector<std::string>& stream_ids = {}) {
350 auto result = pc()->AddTrack(track, stream_ids);
Steve Anton15324772018-01-16 10:26:49 -0800351 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
Steve Anton74255ff2018-01-24 18:32:57 -0800352 return result.MoveValue();
353 }
354
355 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceiversOfType(
356 cricket::MediaType media_type) {
357 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
Mirko Bonadei739baf02019-01-27 17:29:42 +0100358 for (const auto& receiver : pc()->GetReceivers()) {
Steve Anton74255ff2018-01-24 18:32:57 -0800359 if (receiver->media_type() == media_type) {
360 receivers.push_back(receiver);
361 }
362 }
363 return receivers;
deadbeef1dcb1642017-03-29 21:08:16 -0700364 }
365
Seth Hampson2f0d7022018-02-20 11:54:42 -0800366 rtc::scoped_refptr<RtpTransceiverInterface> GetFirstTransceiverOfType(
367 cricket::MediaType media_type) {
368 for (auto transceiver : pc()->GetTransceivers()) {
369 if (transceiver->receiver()->media_type() == media_type) {
370 return transceiver;
371 }
372 }
373 return nullptr;
374 }
375
deadbeef1dcb1642017-03-29 21:08:16 -0700376 bool SignalingStateStable() {
377 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable;
378 }
379
380 void CreateDataChannel() { CreateDataChannel(nullptr); }
381
382 void CreateDataChannel(const webrtc::DataChannelInit* init) {
Steve Antonda6c0952017-10-23 11:41:54 -0700383 CreateDataChannel(kDataChannelLabel, init);
384 }
385
386 void CreateDataChannel(const std::string& label,
387 const webrtc::DataChannelInit* init) {
388 data_channel_ = pc()->CreateDataChannel(label, init);
deadbeef1dcb1642017-03-29 21:08:16 -0700389 ASSERT_TRUE(data_channel_.get() != nullptr);
390 data_observer_.reset(new MockDataChannelObserver(data_channel_));
391 }
392
393 DataChannelInterface* data_channel() { return data_channel_; }
394 const MockDataChannelObserver* data_observer() const {
395 return data_observer_.get();
396 }
397
398 int audio_frames_received() const {
399 return fake_audio_capture_module_->frames_received();
400 }
401
402 // Takes minimum of video frames received for each track.
403 //
404 // Can be used like:
405 // EXPECT_GE(expected_frames, min_video_frames_received_per_track());
406 //
407 // To ensure that all video tracks received at least a certain number of
408 // frames.
409 int min_video_frames_received_per_track() const {
410 int min_frames = INT_MAX;
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200411 if (fake_video_renderers_.empty()) {
412 return 0;
deadbeef1dcb1642017-03-29 21:08:16 -0700413 }
deadbeef1dcb1642017-03-29 21:08:16 -0700414
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200415 for (const auto& pair : fake_video_renderers_) {
416 min_frames = std::min(min_frames, pair.second->num_rendered_frames());
deadbeef1dcb1642017-03-29 21:08:16 -0700417 }
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200418 return min_frames;
deadbeef1dcb1642017-03-29 21:08:16 -0700419 }
420
421 // Returns a MockStatsObserver in a state after stats gathering finished,
422 // which can be used to access the gathered stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700423 rtc::scoped_refptr<MockStatsObserver> OldGetStatsForTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700424 webrtc::MediaStreamTrackInterface* track) {
425 rtc::scoped_refptr<MockStatsObserver> observer(
426 new rtc::RefCountedObject<MockStatsObserver>());
427 EXPECT_TRUE(peer_connection_->GetStats(
428 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard));
429 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
430 return observer;
431 }
432
433 // Version that doesn't take a track "filter", and gathers all stats.
deadbeefd8ad7882017-04-18 16:01:17 -0700434 rtc::scoped_refptr<MockStatsObserver> OldGetStats() {
435 return OldGetStatsForTrack(nullptr);
436 }
437
438 // Synchronously gets stats and returns them. If it times out, fails the test
439 // and returns null.
440 rtc::scoped_refptr<const webrtc::RTCStatsReport> NewGetStats() {
441 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
442 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
443 peer_connection_->GetStats(callback);
444 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
445 return callback->report();
deadbeef1dcb1642017-03-29 21:08:16 -0700446 }
447
448 int rendered_width() {
449 EXPECT_FALSE(fake_video_renderers_.empty());
450 return fake_video_renderers_.empty()
451 ? 0
452 : fake_video_renderers_.begin()->second->width();
453 }
454
455 int rendered_height() {
456 EXPECT_FALSE(fake_video_renderers_.empty());
457 return fake_video_renderers_.empty()
458 ? 0
459 : fake_video_renderers_.begin()->second->height();
460 }
461
462 double rendered_aspect_ratio() {
463 if (rendered_height() == 0) {
464 return 0.0;
465 }
466 return static_cast<double>(rendered_width()) / rendered_height();
467 }
468
469 webrtc::VideoRotation rendered_rotation() {
470 EXPECT_FALSE(fake_video_renderers_.empty());
471 return fake_video_renderers_.empty()
472 ? webrtc::kVideoRotation_0
473 : fake_video_renderers_.begin()->second->rotation();
474 }
475
476 int local_rendered_width() {
477 return local_video_renderer_ ? local_video_renderer_->width() : 0;
478 }
479
480 int local_rendered_height() {
481 return local_video_renderer_ ? local_video_renderer_->height() : 0;
482 }
483
484 double local_rendered_aspect_ratio() {
485 if (local_rendered_height() == 0) {
486 return 0.0;
487 }
488 return static_cast<double>(local_rendered_width()) /
489 local_rendered_height();
490 }
491
492 size_t number_of_remote_streams() {
493 if (!pc()) {
494 return 0;
495 }
496 return pc()->remote_streams()->count();
497 }
498
499 StreamCollectionInterface* remote_streams() const {
500 if (!pc()) {
501 ADD_FAILURE();
502 return nullptr;
503 }
504 return pc()->remote_streams();
505 }
506
507 StreamCollectionInterface* local_streams() {
508 if (!pc()) {
509 ADD_FAILURE();
510 return nullptr;
511 }
512 return pc()->local_streams();
513 }
514
515 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
516 return pc()->signaling_state();
517 }
518
519 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
520 return pc()->ice_connection_state();
521 }
522
Jonas Olsson7a6739e2019-01-15 16:31:55 +0100523 webrtc::PeerConnectionInterface::IceConnectionState
524 standardized_ice_connection_state() {
525 return pc()->standardized_ice_connection_state();
526 }
527
deadbeef1dcb1642017-03-29 21:08:16 -0700528 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
529 return pc()->ice_gathering_state();
530 }
531
532 // Returns a MockRtpReceiverObserver for each RtpReceiver returned by
533 // GetReceivers. They're updated automatically when a remote offer/answer
534 // from the fake signaling channel is applied, or when
535 // ResetRtpReceiverObservers below is called.
536 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>&
537 rtp_receiver_observers() {
538 return rtp_receiver_observers_;
539 }
540
541 void ResetRtpReceiverObservers() {
542 rtp_receiver_observers_.clear();
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100543 for (const rtc::scoped_refptr<RtpReceiverInterface>& receiver :
544 pc()->GetReceivers()) {
deadbeef1dcb1642017-03-29 21:08:16 -0700545 std::unique_ptr<MockRtpReceiverObserver> observer(
546 new MockRtpReceiverObserver(receiver->media_type()));
547 receiver->SetObserver(observer.get());
548 rtp_receiver_observers_.push_back(std::move(observer));
549 }
550 }
551
Qingsi Wangecd30542019-05-22 14:34:56 -0700552 rtc::FakeNetworkManager* network_manager() const {
Steve Antonede9ca52017-10-16 13:04:27 -0700553 return fake_network_manager_.get();
554 }
555 cricket::PortAllocator* port_allocator() const { return port_allocator_; }
556
Qingsi Wang7685e862018-06-11 20:15:46 -0700557 webrtc::FakeRtcEventLogFactory* event_log_factory() const {
558 return event_log_factory_;
559 }
560
Qingsi Wangc129c352019-04-18 10:41:58 -0700561 const cricket::Candidate& last_candidate_gathered() const {
562 return last_candidate_gathered_;
563 }
Eldar Relloda13ea22019-06-01 12:23:43 +0300564 const cricket::IceCandidateErrorEvent& error_event() const {
565 return error_event_;
566 }
Qingsi Wangc129c352019-04-18 10:41:58 -0700567
Qingsi Wangecd30542019-05-22 14:34:56 -0700568 // Sets the mDNS responder for the owned fake network manager and keeps a
569 // reference to the responder.
570 void SetMdnsResponder(
571 std::unique_ptr<webrtc::FakeMdnsResponder> mdns_responder) {
572 RTC_DCHECK(mdns_responder != nullptr);
573 mdns_responder_ = mdns_responder.get();
574 network_manager()->set_mdns_responder(std::move(mdns_responder));
575 }
576
deadbeef1dcb1642017-03-29 21:08:16 -0700577 private:
578 explicit PeerConnectionWrapper(const std::string& debug_name)
579 : debug_name_(debug_name) {}
580
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800581 bool Init(
582 const PeerConnectionFactory::Options* options,
583 const PeerConnectionInterface::RTCConfiguration* config,
584 webrtc::PeerConnectionDependencies dependencies,
585 rtc::Thread* network_thread,
586 rtc::Thread* worker_thread,
587 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
588 std::unique_ptr<webrtc::MediaTransportFactory> media_transport_factory) {
deadbeef1dcb1642017-03-29 21:08:16 -0700589 // There's an error in this test code if Init ends up being called twice.
590 RTC_DCHECK(!peer_connection_);
591 RTC_DCHECK(!peer_connection_factory_);
592
593 fake_network_manager_.reset(new rtc::FakeNetworkManager());
Steve Antonede9ca52017-10-16 13:04:27 -0700594 fake_network_manager_->AddInterface(kDefaultLocalAddress);
deadbeef1dcb1642017-03-29 21:08:16 -0700595
596 std::unique_ptr<cricket::PortAllocator> port_allocator(
597 new cricket::BasicPortAllocator(fake_network_manager_.get()));
Steve Antonede9ca52017-10-16 13:04:27 -0700598 port_allocator_ = port_allocator.get();
deadbeef1dcb1642017-03-29 21:08:16 -0700599 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
600 if (!fake_audio_capture_module_) {
601 return false;
602 }
deadbeef1dcb1642017-03-29 21:08:16 -0700603 rtc::Thread* const signaling_thread = rtc::Thread::Current();
Qingsi Wang7685e862018-06-11 20:15:46 -0700604
605 webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies;
606 pc_factory_dependencies.network_thread = network_thread;
607 pc_factory_dependencies.worker_thread = worker_thread;
608 pc_factory_dependencies.signaling_thread = signaling_thread;
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200609 pc_factory_dependencies.task_queue_factory =
610 webrtc::CreateDefaultTaskQueueFactory();
611 cricket::MediaEngineDependencies media_deps;
612 media_deps.task_queue_factory =
613 pc_factory_dependencies.task_queue_factory.get();
614 media_deps.adm = fake_audio_capture_module_;
615 webrtc::SetMediaEngineDefaults(&media_deps);
Qingsi Wang7685e862018-06-11 20:15:46 -0700616 pc_factory_dependencies.media_engine =
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200617 cricket::CreateMediaEngine(std::move(media_deps));
Qingsi Wang7685e862018-06-11 20:15:46 -0700618 pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
619 if (event_log_factory) {
620 event_log_factory_ = event_log_factory.get();
621 pc_factory_dependencies.event_log_factory = std::move(event_log_factory);
622 } else {
623 pc_factory_dependencies.event_log_factory =
Danil Chapovalov9da25bd2019-06-20 10:19:42 +0200624 absl::make_unique<webrtc::RtcEventLogFactory>(
625 pc_factory_dependencies.task_queue_factory.get());
Qingsi Wang7685e862018-06-11 20:15:46 -0700626 }
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800627 if (media_transport_factory) {
628 pc_factory_dependencies.media_transport_factory =
629 std::move(media_transport_factory);
630 }
Qingsi Wang7685e862018-06-11 20:15:46 -0700631 peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory(
632 std::move(pc_factory_dependencies));
633
deadbeef1dcb1642017-03-29 21:08:16 -0700634 if (!peer_connection_factory_) {
635 return false;
636 }
637 if (options) {
638 peer_connection_factory_->SetOptions(*options);
639 }
Seth Hampson2f0d7022018-02-20 11:54:42 -0800640 if (config) {
641 sdp_semantics_ = config->sdp_semantics;
642 }
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700643
644 dependencies.allocator = std::move(port_allocator);
Niels Möllerf06f9232018-08-07 12:32:18 +0200645 peer_connection_ = CreatePeerConnection(config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700646 return peer_connection_.get() != nullptr;
647 }
648
649 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
deadbeef1dcb1642017-03-29 21:08:16 -0700650 const PeerConnectionInterface::RTCConfiguration* config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700651 webrtc::PeerConnectionDependencies dependencies) {
deadbeef1dcb1642017-03-29 21:08:16 -0700652 PeerConnectionInterface::RTCConfiguration modified_config;
653 // If |config| is null, this will result in a default configuration being
654 // used.
655 if (config) {
656 modified_config = *config;
657 }
658 // Disable resolution adaptation; we don't want it interfering with the
659 // test results.
660 // TODO(deadbeef): Do something more robust. Since we're testing for aspect
661 // ratios and not specific resolutions, is this even necessary?
662 modified_config.set_cpu_adaptation(false);
663
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700664 dependencies.observer = this;
deadbeef1dcb1642017-03-29 21:08:16 -0700665 return peer_connection_factory_->CreatePeerConnection(
Benjamin Wrightd6f86e82018-05-08 13:12:25 -0700666 modified_config, std::move(dependencies));
deadbeef1dcb1642017-03-29 21:08:16 -0700667 }
668
669 void set_signaling_message_receiver(
670 SignalingMessageReceiver* signaling_message_receiver) {
671 signaling_message_receiver_ = signaling_message_receiver;
672 }
673
674 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
675
Steve Antonede9ca52017-10-16 13:04:27 -0700676 void set_signal_ice_candidates(bool signal) {
677 signal_ice_candidates_ = signal;
678 }
679
deadbeef1dcb1642017-03-29 21:08:16 -0700680 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
Niels Möller5c7efe72018-05-11 10:34:46 +0200681 webrtc::FakePeriodicVideoSource::Config config) {
deadbeef1dcb1642017-03-29 21:08:16 -0700682 // Set max frame rate to 10fps to reduce the risk of test flakiness.
683 // TODO(deadbeef): Do something more robust.
Niels Möller5c7efe72018-05-11 10:34:46 +0200684 config.frame_interval_ms = 100;
deadbeef1dcb1642017-03-29 21:08:16 -0700685
Niels Möller5c7efe72018-05-11 10:34:46 +0200686 video_track_sources_.emplace_back(
Niels Möller0f405822018-05-17 09:16:41 +0200687 new rtc::RefCountedObject<webrtc::FakePeriodicVideoTrackSource>(
688 config, false /* remote */));
deadbeef1dcb1642017-03-29 21:08:16 -0700689 rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
Niels Möller5c7efe72018-05-11 10:34:46 +0200690 peer_connection_factory_->CreateVideoTrack(
691 rtc::CreateRandomUuid(), video_track_sources_.back()));
deadbeef1dcb1642017-03-29 21:08:16 -0700692 if (!local_video_renderer_) {
693 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
694 }
695 return track;
696 }
697
698 void HandleIncomingOffer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100699 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer";
Steve Antona3a92c22017-12-07 10:27:41 -0800700 std::unique_ptr<SessionDescriptionInterface> desc =
701 webrtc::CreateSessionDescription(SdpType::kOffer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700702 if (received_sdp_munger_) {
703 received_sdp_munger_(desc->description());
704 }
705
706 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
707 // Setting a remote description may have changed the number of receivers,
708 // so reset the receiver observers.
709 ResetRtpReceiverObservers();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800710 if (remote_offer_handler_) {
711 remote_offer_handler_();
712 }
deadbeef1dcb1642017-03-29 21:08:16 -0700713 auto answer = CreateAnswer();
714 ASSERT_NE(nullptr, answer);
715 EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
716 }
717
718 void HandleIncomingAnswer(const std::string& msg) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100719 RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
Steve Antona3a92c22017-12-07 10:27:41 -0800720 std::unique_ptr<SessionDescriptionInterface> desc =
721 webrtc::CreateSessionDescription(SdpType::kAnswer, msg);
deadbeef1dcb1642017-03-29 21:08:16 -0700722 if (received_sdp_munger_) {
723 received_sdp_munger_(desc->description());
724 }
725
726 EXPECT_TRUE(SetRemoteDescription(std::move(desc)));
727 // Set the RtpReceiverObserver after receivers are created.
728 ResetRtpReceiverObservers();
729 }
730
731 // Returns null on failure.
732 std::unique_ptr<SessionDescriptionInterface> CreateOffer() {
733 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
734 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
735 pc()->CreateOffer(observer, offer_answer_options_);
736 return WaitForDescriptionFromObserver(observer);
737 }
738
739 // Returns null on failure.
740 std::unique_ptr<SessionDescriptionInterface> CreateAnswer() {
741 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
742 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
743 pc()->CreateAnswer(observer, offer_answer_options_);
744 return WaitForDescriptionFromObserver(observer);
745 }
746
747 std::unique_ptr<SessionDescriptionInterface> WaitForDescriptionFromObserver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100748 MockCreateSessionDescriptionObserver* observer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700749 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
750 if (!observer->result()) {
751 return nullptr;
752 }
753 auto description = observer->MoveDescription();
754 if (generated_sdp_munger_) {
755 generated_sdp_munger_(description->description());
756 }
757 return description;
758 }
759
760 // Setting the local description and sending the SDP message over the fake
761 // signaling channel are combined into the same method because the SDP
762 // message needs to be sent as soon as SetLocalDescription finishes, without
763 // waiting for the observer to be called. This ensures that ICE candidates
764 // don't outrace the description.
765 bool SetLocalDescriptionAndSendSdpMessage(
766 std::unique_ptr<SessionDescriptionInterface> desc) {
767 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
768 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100769 RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage";
Steve Antona3a92c22017-12-07 10:27:41 -0800770 SdpType type = desc->GetType();
deadbeef1dcb1642017-03-29 21:08:16 -0700771 std::string sdp;
772 EXPECT_TRUE(desc->ToString(&sdp));
773 pc()->SetLocalDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800774 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
775 RemoveUnusedVideoRenderers();
776 }
deadbeef1dcb1642017-03-29 21:08:16 -0700777 // As mentioned above, we need to send the message immediately after
778 // SetLocalDescription.
779 SendSdpMessage(type, sdp);
780 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
781 return true;
782 }
783
784 bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc) {
785 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
786 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
Mirko Bonadei675513b2017-11-09 11:09:25 +0100787 RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription";
deadbeef1dcb1642017-03-29 21:08:16 -0700788 pc()->SetRemoteDescription(observer, desc.release());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800789 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
790 RemoveUnusedVideoRenderers();
791 }
deadbeef1dcb1642017-03-29 21:08:16 -0700792 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
793 return observer->result();
794 }
795
Seth Hampson2f0d7022018-02-20 11:54:42 -0800796 // This is a work around to remove unused fake_video_renderers from
797 // transceivers that have either stopped or are no longer receiving.
798 void RemoveUnusedVideoRenderers() {
799 auto transceivers = pc()->GetTransceivers();
800 for (auto& transceiver : transceivers) {
801 if (transceiver->receiver()->media_type() != cricket::MEDIA_TYPE_VIDEO) {
802 continue;
803 }
804 // Remove fake video renderers from any stopped transceivers.
805 if (transceiver->stopped()) {
806 auto it =
807 fake_video_renderers_.find(transceiver->receiver()->track()->id());
808 if (it != fake_video_renderers_.end()) {
809 fake_video_renderers_.erase(it);
810 }
811 }
812 // Remove fake video renderers from any transceivers that are no longer
813 // receiving.
814 if ((transceiver->current_direction() &&
815 !webrtc::RtpTransceiverDirectionHasRecv(
816 *transceiver->current_direction()))) {
817 auto it =
818 fake_video_renderers_.find(transceiver->receiver()->track()->id());
819 if (it != fake_video_renderers_.end()) {
820 fake_video_renderers_.erase(it);
821 }
822 }
823 }
824 }
825
deadbeef1dcb1642017-03-29 21:08:16 -0700826 // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by
827 // default).
Steve Antona3a92c22017-12-07 10:27:41 -0800828 void SendSdpMessage(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700829 if (signaling_delay_ms_ == 0) {
830 RelaySdpMessageIfReceiverExists(type, msg);
831 } else {
832 invoker_.AsyncInvokeDelayed<void>(
833 RTC_FROM_HERE, rtc::Thread::Current(),
834 rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists,
835 this, type, msg),
836 signaling_delay_ms_);
837 }
838 }
839
Steve Antona3a92c22017-12-07 10:27:41 -0800840 void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) {
deadbeef1dcb1642017-03-29 21:08:16 -0700841 if (signaling_message_receiver_) {
842 signaling_message_receiver_->ReceiveSdpMessage(type, msg);
843 }
844 }
845
846 // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by
847 // default).
848 void SendIceMessage(const std::string& sdp_mid,
849 int sdp_mline_index,
850 const std::string& msg) {
851 if (signaling_delay_ms_ == 0) {
852 RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg);
853 } else {
854 invoker_.AsyncInvokeDelayed<void>(
855 RTC_FROM_HERE, rtc::Thread::Current(),
856 rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists,
857 this, sdp_mid, sdp_mline_index, msg),
858 signaling_delay_ms_);
859 }
860 }
861
862 void RelayIceMessageIfReceiverExists(const std::string& sdp_mid,
863 int sdp_mline_index,
864 const std::string& msg) {
865 if (signaling_message_receiver_) {
866 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
867 msg);
868 }
869 }
870
871 // SignalingMessageReceiver callbacks.
Steve Antona3a92c22017-12-07 10:27:41 -0800872 void ReceiveSdpMessage(SdpType type, const std::string& msg) override {
873 if (type == SdpType::kOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700874 HandleIncomingOffer(msg);
875 } else {
876 HandleIncomingAnswer(msg);
877 }
878 }
879
880 void ReceiveIceMessage(const std::string& sdp_mid,
881 int sdp_mline_index,
882 const std::string& msg) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100883 RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage";
deadbeef1dcb1642017-03-29 21:08:16 -0700884 std::unique_ptr<webrtc::IceCandidateInterface> candidate(
885 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr));
886 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
887 }
888
889 // PeerConnectionObserver callbacks.
890 void OnSignalingChange(
891 webrtc::PeerConnectionInterface::SignalingState new_state) override {
892 EXPECT_EQ(pc()->signaling_state(), new_state);
893 }
Steve Anton15324772018-01-16 10:26:49 -0800894 void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
895 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
896 streams) override {
897 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
898 rtc::scoped_refptr<VideoTrackInterface> video_track(
899 static_cast<VideoTrackInterface*>(receiver->track().get()));
900 ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) ==
deadbeef1dcb1642017-03-29 21:08:16 -0700901 fake_video_renderers_.end());
Steve Anton15324772018-01-16 10:26:49 -0800902 fake_video_renderers_[video_track->id()] =
Karl Wiberg918f50c2018-07-05 11:40:33 +0200903 absl::make_unique<FakeVideoTrackRenderer>(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -0700904 }
905 }
Steve Anton15324772018-01-16 10:26:49 -0800906 void OnRemoveTrack(
907 rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
908 if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
909 auto it = fake_video_renderers_.find(receiver->track()->id());
910 RTC_DCHECK(it != fake_video_renderers_.end());
911 fake_video_renderers_.erase(it);
912 }
913 }
deadbeef1dcb1642017-03-29 21:08:16 -0700914 void OnRenegotiationNeeded() override {}
915 void OnIceConnectionChange(
916 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
917 EXPECT_EQ(pc()->ice_connection_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700918 ice_connection_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700919 }
Jonas Olssonacd8ae72019-02-25 15:26:24 +0100920 void OnStandardizedIceConnectionChange(
921 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
922 standardized_ice_connection_state_history_.push_back(new_state);
923 }
Jonas Olsson635474e2018-10-18 15:58:17 +0200924 void OnConnectionChange(
925 webrtc::PeerConnectionInterface::PeerConnectionState new_state) override {
926 peer_connection_state_history_.push_back(new_state);
927 }
928
deadbeef1dcb1642017-03-29 21:08:16 -0700929 void OnIceGatheringChange(
930 webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
deadbeef1dcb1642017-03-29 21:08:16 -0700931 EXPECT_EQ(pc()->ice_gathering_state(), new_state);
Steve Antonede9ca52017-10-16 13:04:27 -0700932 ice_gathering_state_history_.push_back(new_state);
deadbeef1dcb1642017-03-29 21:08:16 -0700933 }
934 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100935 RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate";
deadbeef1dcb1642017-03-29 21:08:16 -0700936
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800937 if (remote_async_resolver_) {
938 const auto& local_candidate = candidate->candidate();
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800939 if (local_candidate.address().IsUnresolvedIP()) {
940 RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE);
941 rtc::SocketAddress resolved_addr(local_candidate.address());
Qingsi Wangecd30542019-05-22 14:34:56 -0700942 const auto resolved_ip = mdns_responder_->GetMappedAddressForName(
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800943 local_candidate.address().hostname());
944 RTC_DCHECK(!resolved_ip.IsNil());
945 resolved_addr.SetResolvedIP(resolved_ip);
946 EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _))
947 .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true)));
948 EXPECT_CALL(*remote_async_resolver_, Destroy(_));
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700949 }
Zach Stein6fcdc2f2018-08-23 16:25:55 -0700950 }
951
deadbeef1dcb1642017-03-29 21:08:16 -0700952 std::string ice_sdp;
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800953 EXPECT_TRUE(candidate->ToString(&ice_sdp));
Steve Antonede9ca52017-10-16 13:04:27 -0700954 if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) {
deadbeef1dcb1642017-03-29 21:08:16 -0700955 // Remote party may be deleted.
956 return;
957 }
Qingsi Wang1dac6d82018-12-12 15:28:47 -0800958 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
Qingsi Wangc129c352019-04-18 10:41:58 -0700959 last_candidate_gathered_ = candidate->candidate();
deadbeef1dcb1642017-03-29 21:08:16 -0700960 }
Eldar Relloda13ea22019-06-01 12:23:43 +0300961 void OnIceCandidateError(const std::string& host_candidate,
962 const std::string& url,
963 int error_code,
964 const std::string& error_text) override {
965 error_event_ = cricket::IceCandidateErrorEvent(host_candidate, url,
966 error_code, error_text);
967 }
deadbeef1dcb1642017-03-29 21:08:16 -0700968 void OnDataChannel(
969 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100970 RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel";
deadbeef1dcb1642017-03-29 21:08:16 -0700971 data_channel_ = data_channel;
972 data_observer_.reset(new MockDataChannelObserver(data_channel));
973 }
974
deadbeef1dcb1642017-03-29 21:08:16 -0700975 std::string debug_name_;
976
977 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
Qingsi Wangecd30542019-05-22 14:34:56 -0700978 // Reference to the mDNS responder owned by |fake_network_manager_| after set.
979 webrtc::FakeMdnsResponder* mdns_responder_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -0700980
981 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
982 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
983 peer_connection_factory_;
984
Steve Antonede9ca52017-10-16 13:04:27 -0700985 cricket::PortAllocator* port_allocator_;
deadbeef1dcb1642017-03-29 21:08:16 -0700986 // Needed to keep track of number of frames sent.
987 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
988 // Needed to keep track of number of frames received.
989 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
990 fake_video_renderers_;
991 // Needed to ensure frames aren't received for removed tracks.
992 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>>
993 removed_fake_video_renderers_;
deadbeef1dcb1642017-03-29 21:08:16 -0700994
995 // For remote peer communication.
996 SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
997 int signaling_delay_ms_ = 0;
Steve Antonede9ca52017-10-16 13:04:27 -0700998 bool signal_ice_candidates_ = true;
Qingsi Wangc129c352019-04-18 10:41:58 -0700999 cricket::Candidate last_candidate_gathered_;
Eldar Relloda13ea22019-06-01 12:23:43 +03001000 cricket::IceCandidateErrorEvent error_event_;
deadbeef1dcb1642017-03-29 21:08:16 -07001001
Niels Möller5c7efe72018-05-11 10:34:46 +02001002 // Store references to the video sources we've created, so that we can stop
deadbeef1dcb1642017-03-29 21:08:16 -07001003 // them, if required.
Niels Möller5c7efe72018-05-11 10:34:46 +02001004 std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
1005 video_track_sources_;
deadbeef1dcb1642017-03-29 21:08:16 -07001006 // |local_video_renderer_| attached to the first created local video track.
1007 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
1008
Seth Hampson2f0d7022018-02-20 11:54:42 -08001009 SdpSemantics sdp_semantics_;
deadbeef1dcb1642017-03-29 21:08:16 -07001010 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_;
1011 std::function<void(cricket::SessionDescription*)> received_sdp_munger_;
1012 std::function<void(cricket::SessionDescription*)> generated_sdp_munger_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001013 std::function<void()> remote_offer_handler_;
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001014 rtc::MockAsyncResolver* remote_async_resolver_ = nullptr;
deadbeef1dcb1642017-03-29 21:08:16 -07001015 rtc::scoped_refptr<DataChannelInterface> data_channel_;
1016 std::unique_ptr<MockDataChannelObserver> data_observer_;
1017
1018 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_;
1019
Steve Antonede9ca52017-10-16 13:04:27 -07001020 std::vector<PeerConnectionInterface::IceConnectionState>
1021 ice_connection_state_history_;
Jonas Olssonacd8ae72019-02-25 15:26:24 +01001022 std::vector<PeerConnectionInterface::IceConnectionState>
1023 standardized_ice_connection_state_history_;
Jonas Olsson635474e2018-10-18 15:58:17 +02001024 std::vector<PeerConnectionInterface::PeerConnectionState>
1025 peer_connection_state_history_;
Steve Antonede9ca52017-10-16 13:04:27 -07001026 std::vector<PeerConnectionInterface::IceGatheringState>
1027 ice_gathering_state_history_;
deadbeef1dcb1642017-03-29 21:08:16 -07001028
Qingsi Wang7685e862018-06-11 20:15:46 -07001029 webrtc::FakeRtcEventLogFactory* event_log_factory_;
1030
deadbeef1dcb1642017-03-29 21:08:16 -07001031 rtc::AsyncInvoker invoker_;
1032
Seth Hampson2f0d7022018-02-20 11:54:42 -08001033 friend class PeerConnectionIntegrationBaseTest;
deadbeef1dcb1642017-03-29 21:08:16 -07001034};
1035
Elad Alon99c3fe52017-10-13 16:29:40 +02001036class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput {
1037 public:
1038 virtual ~MockRtcEventLogOutput() = default;
1039 MOCK_CONST_METHOD0(IsActive, bool());
1040 MOCK_METHOD1(Write, bool(const std::string&));
1041};
1042
Seth Hampson2f0d7022018-02-20 11:54:42 -08001043// This helper object is used for both specifying how many audio/video frames
1044// are expected to be received for a caller/callee. It provides helper functions
1045// to specify these expectations. The object initially starts in a state of no
1046// expectations.
1047class MediaExpectations {
1048 public:
1049 enum ExpectFrames {
1050 kExpectSomeFrames,
1051 kExpectNoFrames,
1052 kNoExpectation,
1053 };
1054
1055 void ExpectBidirectionalAudioAndVideo() {
1056 ExpectBidirectionalAudio();
1057 ExpectBidirectionalVideo();
1058 }
1059
1060 void ExpectBidirectionalAudio() {
1061 CallerExpectsSomeAudio();
1062 CalleeExpectsSomeAudio();
1063 }
1064
1065 void ExpectNoAudio() {
1066 CallerExpectsNoAudio();
1067 CalleeExpectsNoAudio();
1068 }
1069
1070 void ExpectBidirectionalVideo() {
1071 CallerExpectsSomeVideo();
1072 CalleeExpectsSomeVideo();
1073 }
1074
1075 void ExpectNoVideo() {
1076 CallerExpectsNoVideo();
1077 CalleeExpectsNoVideo();
1078 }
1079
1080 void CallerExpectsSomeAudioAndVideo() {
1081 CallerExpectsSomeAudio();
1082 CallerExpectsSomeVideo();
1083 }
1084
1085 void CalleeExpectsSomeAudioAndVideo() {
1086 CalleeExpectsSomeAudio();
1087 CalleeExpectsSomeVideo();
1088 }
1089
1090 // Caller's audio functions.
1091 void CallerExpectsSomeAudio(
1092 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1093 caller_audio_expectation_ = kExpectSomeFrames;
1094 caller_audio_frames_expected_ = expected_audio_frames;
1095 }
1096
1097 void CallerExpectsNoAudio() {
1098 caller_audio_expectation_ = kExpectNoFrames;
1099 caller_audio_frames_expected_ = 0;
1100 }
1101
1102 // Caller's video functions.
1103 void CallerExpectsSomeVideo(
1104 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1105 caller_video_expectation_ = kExpectSomeFrames;
1106 caller_video_frames_expected_ = expected_video_frames;
1107 }
1108
1109 void CallerExpectsNoVideo() {
1110 caller_video_expectation_ = kExpectNoFrames;
1111 caller_video_frames_expected_ = 0;
1112 }
1113
1114 // Callee's audio functions.
1115 void CalleeExpectsSomeAudio(
1116 int expected_audio_frames = kDefaultExpectedAudioFrameCount) {
1117 callee_audio_expectation_ = kExpectSomeFrames;
1118 callee_audio_frames_expected_ = expected_audio_frames;
1119 }
1120
1121 void CalleeExpectsNoAudio() {
1122 callee_audio_expectation_ = kExpectNoFrames;
1123 callee_audio_frames_expected_ = 0;
1124 }
1125
1126 // Callee's video functions.
1127 void CalleeExpectsSomeVideo(
1128 int expected_video_frames = kDefaultExpectedVideoFrameCount) {
1129 callee_video_expectation_ = kExpectSomeFrames;
1130 callee_video_frames_expected_ = expected_video_frames;
1131 }
1132
1133 void CalleeExpectsNoVideo() {
1134 callee_video_expectation_ = kExpectNoFrames;
1135 callee_video_frames_expected_ = 0;
1136 }
1137
1138 ExpectFrames caller_audio_expectation_ = kNoExpectation;
1139 ExpectFrames caller_video_expectation_ = kNoExpectation;
1140 ExpectFrames callee_audio_expectation_ = kNoExpectation;
1141 ExpectFrames callee_video_expectation_ = kNoExpectation;
1142 int caller_audio_frames_expected_ = 0;
1143 int caller_video_frames_expected_ = 0;
1144 int callee_audio_frames_expected_ = 0;
1145 int callee_video_frames_expected_ = 0;
1146};
1147
deadbeef1dcb1642017-03-29 21:08:16 -07001148// Tests two PeerConnections connecting to each other end-to-end, using a
1149// virtual network, fake A/V capture and fake encoder/decoders. The
1150// PeerConnections share the threads/socket servers, but use separate versions
1151// of everything else (including "PeerConnectionFactory"s).
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001152class PeerConnectionIntegrationBaseTest : public ::testing::Test {
deadbeef1dcb1642017-03-29 21:08:16 -07001153 public:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001154 explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics)
1155 : sdp_semantics_(sdp_semantics),
1156 ss_(new rtc::VirtualSocketServer()),
Steve Antonede9ca52017-10-16 13:04:27 -07001157 fss_(new rtc::FirewallSocketServer(ss_.get())),
1158 network_thread_(new rtc::Thread(fss_.get())),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001159 worker_thread_(rtc::Thread::Create()),
1160 loopback_media_transports_(network_thread_.get()) {
Sebastian Jansson8a793a02018-03-13 15:21:48 +01001161 network_thread_->SetName("PCNetworkThread", this);
1162 worker_thread_->SetName("PCWorkerThread", this);
deadbeef1dcb1642017-03-29 21:08:16 -07001163 RTC_CHECK(network_thread_->Start());
1164 RTC_CHECK(worker_thread_->Start());
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001165 webrtc::metrics::Reset();
deadbeef1dcb1642017-03-29 21:08:16 -07001166 }
1167
Seth Hampson2f0d7022018-02-20 11:54:42 -08001168 ~PeerConnectionIntegrationBaseTest() {
Seth Hampsonaed71642018-06-11 07:41:32 -07001169 // The PeerConnections should deleted before the TurnCustomizers.
1170 // A TurnPort is created with a raw pointer to a TurnCustomizer. The
1171 // TurnPort has the same lifetime as the PeerConnection, so it's expected
1172 // that the TurnCustomizer outlives the life of the PeerConnection or else
1173 // when Send() is called it will hit a seg fault.
deadbeef1dcb1642017-03-29 21:08:16 -07001174 if (caller_) {
1175 caller_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001176 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001177 }
1178 if (callee_) {
1179 callee_->set_signaling_message_receiver(nullptr);
Seth Hampsonaed71642018-06-11 07:41:32 -07001180 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001181 }
Seth Hampsonaed71642018-06-11 07:41:32 -07001182
1183 // If turn servers were created for the test they need to be destroyed on
1184 // the network thread.
1185 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1186 turn_servers_.clear();
1187 turn_customizers_.clear();
1188 });
deadbeef1dcb1642017-03-29 21:08:16 -07001189 }
1190
1191 bool SignalingStateStable() {
1192 return caller_->SignalingStateStable() && callee_->SignalingStateStable();
1193 }
1194
deadbeef71452802017-05-07 17:21:01 -07001195 bool DtlsConnected() {
Alex Loiko9289eda2018-11-23 16:18:59 +00001196 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
1197 // are connected. This is an important distinction. Once we have separate
1198 // ICE and DTLS state, this check needs to use the DTLS state.
1199 return (callee()->ice_connection_state() ==
1200 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1201 callee()->ice_connection_state() ==
1202 webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
1203 (caller()->ice_connection_state() ==
1204 webrtc::PeerConnectionInterface::kIceConnectionConnected ||
1205 caller()->ice_connection_state() ==
1206 webrtc::PeerConnectionInterface::kIceConnectionCompleted);
deadbeef71452802017-05-07 17:21:01 -07001207 }
1208
Qingsi Wang7685e862018-06-11 20:15:46 -07001209 // When |event_log_factory| is null, the default implementation of the event
1210 // log factory will be used.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001211 std::unique_ptr<PeerConnectionWrapper> CreatePeerConnectionWrapper(
1212 const std::string& debug_name,
Seth Hampson2f0d7022018-02-20 11:54:42 -08001213 const PeerConnectionFactory::Options* options,
1214 const RTCConfiguration* config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001215 webrtc::PeerConnectionDependencies dependencies,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001216 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory,
1217 std::unique_ptr<webrtc::MediaTransportFactory> media_transport_factory) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001218 RTCConfiguration modified_config;
1219 if (config) {
1220 modified_config = *config;
1221 }
Steve Anton3acffc32018-04-12 17:21:03 -07001222 modified_config.sdp_semantics = sdp_semantics_;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001223 if (!dependencies.cert_generator) {
1224 dependencies.cert_generator =
Karl Wiberg918f50c2018-07-05 11:40:33 +02001225 absl::make_unique<FakeRTCCertificateGenerator>();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001226 }
1227 std::unique_ptr<PeerConnectionWrapper> client(
1228 new PeerConnectionWrapper(debug_name));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001229
Niels Möllerf06f9232018-08-07 12:32:18 +02001230 if (!client->Init(options, &modified_config, std::move(dependencies),
1231 network_thread_.get(), worker_thread_.get(),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001232 std::move(event_log_factory),
1233 std::move(media_transport_factory))) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08001234 return nullptr;
1235 }
1236 return client;
1237 }
1238
Qingsi Wang7685e862018-06-11 20:15:46 -07001239 std::unique_ptr<PeerConnectionWrapper>
1240 CreatePeerConnectionWrapperWithFakeRtcEventLog(
1241 const std::string& debug_name,
Qingsi Wang7685e862018-06-11 20:15:46 -07001242 const PeerConnectionFactory::Options* options,
1243 const RTCConfiguration* config,
1244 webrtc::PeerConnectionDependencies dependencies) {
1245 std::unique_ptr<webrtc::FakeRtcEventLogFactory> event_log_factory(
1246 new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current()));
Niels Möllerf06f9232018-08-07 12:32:18 +02001247 return CreatePeerConnectionWrapper(debug_name, options, config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001248 std::move(dependencies),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001249 std::move(event_log_factory),
1250 /*media_transport_factory=*/nullptr);
Qingsi Wang7685e862018-06-11 20:15:46 -07001251 }
1252
deadbeef1dcb1642017-03-29 21:08:16 -07001253 bool CreatePeerConnectionWrappers() {
1254 return CreatePeerConnectionWrappersWithConfig(
1255 PeerConnectionInterface::RTCConfiguration(),
1256 PeerConnectionInterface::RTCConfiguration());
1257 }
1258
Steve Anton3acffc32018-04-12 17:21:03 -07001259 bool CreatePeerConnectionWrappersWithSdpSemantics(
1260 SdpSemantics caller_semantics,
1261 SdpSemantics callee_semantics) {
1262 // Can't specify the sdp_semantics in the passed-in configuration since it
1263 // will be overwritten by CreatePeerConnectionWrapper with whatever is
1264 // stored in sdp_semantics_. So get around this by modifying the instance
1265 // variable before calling CreatePeerConnectionWrapper for the caller and
1266 // callee PeerConnections.
1267 SdpSemantics original_semantics = sdp_semantics_;
1268 sdp_semantics_ = caller_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001269 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001270 "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001271 nullptr, /*media_transport_factory=*/nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001272 sdp_semantics_ = callee_semantics;
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001273 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001274 "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr),
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001275 nullptr, /*media_transport_factory=*/nullptr);
Steve Anton3acffc32018-04-12 17:21:03 -07001276 sdp_semantics_ = original_semantics;
1277 return caller_ && callee_;
1278 }
1279
deadbeef1dcb1642017-03-29 21:08:16 -07001280 bool CreatePeerConnectionWrappersWithConfig(
1281 const PeerConnectionInterface::RTCConfiguration& caller_config,
1282 const PeerConnectionInterface::RTCConfiguration& callee_config) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001283 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001284 "Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001285 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1286 /*media_transport_factory=*/nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001287 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001288 "Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001289 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1290 /*media_transport_factory=*/nullptr);
1291 return caller_ && callee_;
1292 }
1293
1294 bool CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
1295 const PeerConnectionInterface::RTCConfiguration& caller_config,
1296 const PeerConnectionInterface::RTCConfiguration& callee_config,
1297 std::unique_ptr<webrtc::MediaTransportFactory> caller_factory,
1298 std::unique_ptr<webrtc::MediaTransportFactory> callee_factory) {
1299 caller_ =
1300 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
1301 webrtc::PeerConnectionDependencies(nullptr),
1302 nullptr, std::move(caller_factory));
1303 callee_ =
1304 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
1305 webrtc::PeerConnectionDependencies(nullptr),
1306 nullptr, std::move(callee_factory));
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001307 return caller_ && callee_;
1308 }
1309
1310 bool CreatePeerConnectionWrappersWithConfigAndDeps(
1311 const PeerConnectionInterface::RTCConfiguration& caller_config,
1312 webrtc::PeerConnectionDependencies caller_dependencies,
1313 const PeerConnectionInterface::RTCConfiguration& callee_config,
1314 webrtc::PeerConnectionDependencies callee_dependencies) {
1315 caller_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001316 CreatePeerConnectionWrapper("Caller", nullptr, &caller_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001317 std::move(caller_dependencies), nullptr,
1318 /*media_transport_factory=*/nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001319 callee_ =
Niels Möllerf06f9232018-08-07 12:32:18 +02001320 CreatePeerConnectionWrapper("Callee", nullptr, &callee_config,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001321 std::move(callee_dependencies), nullptr,
1322 /*media_transport_factory=*/nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001323 return caller_ && callee_;
1324 }
1325
1326 bool CreatePeerConnectionWrappersWithOptions(
1327 const PeerConnectionFactory::Options& caller_options,
1328 const PeerConnectionFactory::Options& callee_options) {
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001329 caller_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001330 "Caller", &caller_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001331 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1332 /*media_transport_factory=*/nullptr);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001333 callee_ = CreatePeerConnectionWrapper(
Niels Möllerf06f9232018-08-07 12:32:18 +02001334 "Callee", &callee_options, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001335 webrtc::PeerConnectionDependencies(nullptr), nullptr,
1336 /*media_transport_factory=*/nullptr);
Qingsi Wang7685e862018-06-11 20:15:46 -07001337 return caller_ && callee_;
1338 }
1339
1340 bool CreatePeerConnectionWrappersWithFakeRtcEventLog() {
1341 PeerConnectionInterface::RTCConfiguration default_config;
1342 caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001343 "Caller", nullptr, &default_config,
Qingsi Wang7685e862018-06-11 20:15:46 -07001344 webrtc::PeerConnectionDependencies(nullptr));
1345 callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog(
Niels Möllerf06f9232018-08-07 12:32:18 +02001346 "Callee", nullptr, &default_config,
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001347 webrtc::PeerConnectionDependencies(nullptr));
deadbeef1dcb1642017-03-29 21:08:16 -07001348 return caller_ && callee_;
1349 }
1350
Seth Hampson2f0d7022018-02-20 11:54:42 -08001351 std::unique_ptr<PeerConnectionWrapper>
1352 CreatePeerConnectionWrapperWithAlternateKey() {
deadbeef1dcb1642017-03-29 21:08:16 -07001353 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
1354 new FakeRTCCertificateGenerator());
1355 cert_generator->use_alternate_key();
1356
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07001357 webrtc::PeerConnectionDependencies dependencies(nullptr);
1358 dependencies.cert_generator = std::move(cert_generator);
Niels Möllerf06f9232018-08-07 12:32:18 +02001359 return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr,
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001360 std::move(dependencies), nullptr,
1361 /*media_transport_factory=*/nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07001362 }
1363
Seth Hampsonaed71642018-06-11 07:41:32 -07001364 cricket::TestTurnServer* CreateTurnServer(
1365 rtc::SocketAddress internal_address,
1366 rtc::SocketAddress external_address,
1367 cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP,
1368 const std::string& common_name = "test turn server") {
1369 rtc::Thread* thread = network_thread();
1370 std::unique_ptr<cricket::TestTurnServer> turn_server =
1371 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnServer>>(
1372 RTC_FROM_HERE,
1373 [thread, internal_address, external_address, type, common_name] {
Karl Wiberg918f50c2018-07-05 11:40:33 +02001374 return absl::make_unique<cricket::TestTurnServer>(
Seth Hampsonaed71642018-06-11 07:41:32 -07001375 thread, internal_address, external_address, type,
1376 /*ignore_bad_certs=*/true, common_name);
1377 });
1378 turn_servers_.push_back(std::move(turn_server));
1379 // Interactions with the turn server should be done on the network thread.
1380 return turn_servers_.back().get();
1381 }
1382
1383 cricket::TestTurnCustomizer* CreateTurnCustomizer() {
1384 std::unique_ptr<cricket::TestTurnCustomizer> turn_customizer =
1385 network_thread()->Invoke<std::unique_ptr<cricket::TestTurnCustomizer>>(
1386 RTC_FROM_HERE,
Karl Wiberg918f50c2018-07-05 11:40:33 +02001387 [] { return absl::make_unique<cricket::TestTurnCustomizer>(); });
Seth Hampsonaed71642018-06-11 07:41:32 -07001388 turn_customizers_.push_back(std::move(turn_customizer));
1389 // Interactions with the turn customizer should be done on the network
1390 // thread.
1391 return turn_customizers_.back().get();
1392 }
1393
1394 // Checks that the function counters for a TestTurnCustomizer are greater than
1395 // 0.
1396 void ExpectTurnCustomizerCountersIncremented(
1397 cricket::TestTurnCustomizer* turn_customizer) {
1398 unsigned int allow_channel_data_counter =
1399 network_thread()->Invoke<unsigned int>(
1400 RTC_FROM_HERE, [turn_customizer] {
1401 return turn_customizer->allow_channel_data_cnt_;
1402 });
1403 EXPECT_GT(allow_channel_data_counter, 0u);
1404 unsigned int modify_counter = network_thread()->Invoke<unsigned int>(
1405 RTC_FROM_HERE,
1406 [turn_customizer] { return turn_customizer->modify_cnt_; });
1407 EXPECT_GT(modify_counter, 0u);
1408 }
1409
deadbeef1dcb1642017-03-29 21:08:16 -07001410 // Once called, SDP blobs and ICE candidates will be automatically signaled
1411 // between PeerConnections.
1412 void ConnectFakeSignaling() {
1413 caller_->set_signaling_message_receiver(callee_.get());
1414 callee_->set_signaling_message_receiver(caller_.get());
1415 }
1416
Steve Antonede9ca52017-10-16 13:04:27 -07001417 // Once called, SDP blobs will be automatically signaled between
1418 // PeerConnections. Note that ICE candidates will not be signaled unless they
1419 // are in the exchanged SDP blobs.
1420 void ConnectFakeSignalingForSdpOnly() {
1421 ConnectFakeSignaling();
1422 SetSignalIceCandidates(false);
1423 }
1424
deadbeef1dcb1642017-03-29 21:08:16 -07001425 void SetSignalingDelayMs(int delay_ms) {
1426 caller_->set_signaling_delay_ms(delay_ms);
1427 callee_->set_signaling_delay_ms(delay_ms);
1428 }
1429
Steve Antonede9ca52017-10-16 13:04:27 -07001430 void SetSignalIceCandidates(bool signal) {
1431 caller_->set_signal_ice_candidates(signal);
1432 callee_->set_signal_ice_candidates(signal);
1433 }
1434
deadbeef1dcb1642017-03-29 21:08:16 -07001435 // Messages may get lost on the unreliable DataChannel, so we send multiple
1436 // times to avoid test flakiness.
1437 void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc,
1438 const std::string& data,
1439 int retries) {
1440 for (int i = 0; i < retries; ++i) {
1441 dc->Send(DataBuffer(data));
1442 }
1443 }
1444
1445 rtc::Thread* network_thread() { return network_thread_.get(); }
1446
1447 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
1448
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001449 webrtc::MediaTransportPair* loopback_media_transports() {
1450 return &loopback_media_transports_;
1451 }
1452
deadbeef1dcb1642017-03-29 21:08:16 -07001453 PeerConnectionWrapper* caller() { return caller_.get(); }
1454
1455 // Set the |caller_| to the |wrapper| passed in and return the
1456 // original |caller_|.
1457 PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent(
1458 PeerConnectionWrapper* wrapper) {
1459 PeerConnectionWrapper* old = caller_.release();
1460 caller_.reset(wrapper);
1461 return old;
1462 }
1463
1464 PeerConnectionWrapper* callee() { return callee_.get(); }
1465
1466 // Set the |callee_| to the |wrapper| passed in and return the
1467 // original |callee_|.
1468 PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent(
1469 PeerConnectionWrapper* wrapper) {
1470 PeerConnectionWrapper* old = callee_.release();
1471 callee_.reset(wrapper);
1472 return old;
1473 }
1474
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001475 void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) {
1476 network_thread()->Invoke<void>(
1477 RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags,
1478 caller()->port_allocator(), caller_flags));
1479 network_thread()->Invoke<void>(
1480 RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags,
1481 callee()->port_allocator(), callee_flags));
1482 }
1483
Steve Antonede9ca52017-10-16 13:04:27 -07001484 rtc::FirewallSocketServer* firewall() const { return fss_.get(); }
1485
Seth Hampson2f0d7022018-02-20 11:54:42 -08001486 // Expects the provided number of new frames to be received within
1487 // kMaxWaitForFramesMs. The new expected frames are specified in
1488 // |media_expectations|. Returns false if any of the expectations were
1489 // not met.
1490 bool ExpectNewFrames(const MediaExpectations& media_expectations) {
1491 // First initialize the expected frame counts based upon the current
1492 // frame count.
1493 int total_caller_audio_frames_expected = caller()->audio_frames_received();
1494 if (media_expectations.caller_audio_expectation_ ==
1495 MediaExpectations::kExpectSomeFrames) {
1496 total_caller_audio_frames_expected +=
1497 media_expectations.caller_audio_frames_expected_;
1498 }
1499 int total_caller_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001500 caller()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001501 if (media_expectations.caller_video_expectation_ ==
1502 MediaExpectations::kExpectSomeFrames) {
1503 total_caller_video_frames_expected +=
1504 media_expectations.caller_video_frames_expected_;
1505 }
1506 int total_callee_audio_frames_expected = callee()->audio_frames_received();
1507 if (media_expectations.callee_audio_expectation_ ==
1508 MediaExpectations::kExpectSomeFrames) {
1509 total_callee_audio_frames_expected +=
1510 media_expectations.callee_audio_frames_expected_;
1511 }
1512 int total_callee_video_frames_expected =
deadbeef1dcb1642017-03-29 21:08:16 -07001513 callee()->min_video_frames_received_per_track();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001514 if (media_expectations.callee_video_expectation_ ==
1515 MediaExpectations::kExpectSomeFrames) {
1516 total_callee_video_frames_expected +=
1517 media_expectations.callee_video_frames_expected_;
1518 }
deadbeef1dcb1642017-03-29 21:08:16 -07001519
Seth Hampson2f0d7022018-02-20 11:54:42 -08001520 // Wait for the expected frames.
deadbeef1dcb1642017-03-29 21:08:16 -07001521 EXPECT_TRUE_WAIT(caller()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001522 total_caller_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001523 caller()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001524 total_caller_video_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001525 callee()->audio_frames_received() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001526 total_callee_audio_frames_expected &&
deadbeef1dcb1642017-03-29 21:08:16 -07001527 callee()->min_video_frames_received_per_track() >=
Seth Hampson2f0d7022018-02-20 11:54:42 -08001528 total_callee_video_frames_expected,
1529 kMaxWaitForFramesMs);
1530 bool expectations_correct =
1531 caller()->audio_frames_received() >=
1532 total_caller_audio_frames_expected &&
1533 caller()->min_video_frames_received_per_track() >=
1534 total_caller_video_frames_expected &&
1535 callee()->audio_frames_received() >=
1536 total_callee_audio_frames_expected &&
1537 callee()->min_video_frames_received_per_track() >=
1538 total_callee_video_frames_expected;
deadbeef1dcb1642017-03-29 21:08:16 -07001539
Seth Hampson2f0d7022018-02-20 11:54:42 -08001540 // After the combined wait, print out a more detailed message upon
1541 // failure.
deadbeef1dcb1642017-03-29 21:08:16 -07001542 EXPECT_GE(caller()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001543 total_caller_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001544 EXPECT_GE(caller()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001545 total_caller_video_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001546 EXPECT_GE(callee()->audio_frames_received(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001547 total_callee_audio_frames_expected);
deadbeef1dcb1642017-03-29 21:08:16 -07001548 EXPECT_GE(callee()->min_video_frames_received_per_track(),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001549 total_callee_video_frames_expected);
1550
1551 // We want to make sure nothing unexpected was received.
1552 if (media_expectations.caller_audio_expectation_ ==
1553 MediaExpectations::kExpectNoFrames) {
1554 EXPECT_EQ(caller()->audio_frames_received(),
1555 total_caller_audio_frames_expected);
1556 if (caller()->audio_frames_received() !=
1557 total_caller_audio_frames_expected) {
1558 expectations_correct = false;
1559 }
1560 }
1561 if (media_expectations.caller_video_expectation_ ==
1562 MediaExpectations::kExpectNoFrames) {
1563 EXPECT_EQ(caller()->min_video_frames_received_per_track(),
1564 total_caller_video_frames_expected);
1565 if (caller()->min_video_frames_received_per_track() !=
1566 total_caller_video_frames_expected) {
1567 expectations_correct = false;
1568 }
1569 }
1570 if (media_expectations.callee_audio_expectation_ ==
1571 MediaExpectations::kExpectNoFrames) {
1572 EXPECT_EQ(callee()->audio_frames_received(),
1573 total_callee_audio_frames_expected);
1574 if (callee()->audio_frames_received() !=
1575 total_callee_audio_frames_expected) {
1576 expectations_correct = false;
1577 }
1578 }
1579 if (media_expectations.callee_video_expectation_ ==
1580 MediaExpectations::kExpectNoFrames) {
1581 EXPECT_EQ(callee()->min_video_frames_received_per_track(),
1582 total_callee_video_frames_expected);
1583 if (callee()->min_video_frames_received_per_track() !=
1584 total_callee_video_frames_expected) {
1585 expectations_correct = false;
1586 }
1587 }
1588 return expectations_correct;
deadbeef1dcb1642017-03-29 21:08:16 -07001589 }
1590
Steve Antond91969e2019-05-30 12:27:03 -07001591 void ClosePeerConnections() {
1592 caller()->pc()->Close();
1593 callee()->pc()->Close();
1594 }
1595
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001596 void TestNegotiatedCipherSuite(
1597 const PeerConnectionFactory::Options& caller_options,
1598 const PeerConnectionFactory::Options& callee_options,
1599 int expected_cipher_suite) {
deadbeef1dcb1642017-03-29 21:08:16 -07001600 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
1601 callee_options));
deadbeef1dcb1642017-03-29 21:08:16 -07001602 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001603 caller()->AddAudioVideoTracks();
1604 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001605 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001606 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001607 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite),
deadbeefd8ad7882017-04-18 16:01:17 -07001608 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001609 // TODO(bugs.webrtc.org/9456): Fix it.
Alex Loiko9289eda2018-11-23 16:18:59 +00001610 EXPECT_EQ(1, webrtc::metrics::NumEvents(
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001611 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1612 expected_cipher_suite));
deadbeef1dcb1642017-03-29 21:08:16 -07001613 }
1614
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001615 void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
1616 bool remote_gcm_enabled,
1617 int expected_cipher_suite) {
1618 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001619 caller_options.crypto_options.srtp.enable_gcm_crypto_suites =
1620 local_gcm_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001621 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001622 callee_options.crypto_options.srtp.enable_gcm_crypto_suites =
1623 remote_gcm_enabled;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001624 TestNegotiatedCipherSuite(caller_options, callee_options,
1625 expected_cipher_suite);
1626 }
1627
Seth Hampson2f0d7022018-02-20 11:54:42 -08001628 protected:
Steve Anton3acffc32018-04-12 17:21:03 -07001629 SdpSemantics sdp_semantics_;
Seth Hampson2f0d7022018-02-20 11:54:42 -08001630
deadbeef1dcb1642017-03-29 21:08:16 -07001631 private:
1632 // |ss_| is used by |network_thread_| so it must be destroyed later.
deadbeef1dcb1642017-03-29 21:08:16 -07001633 std::unique_ptr<rtc::VirtualSocketServer> ss_;
Steve Antonede9ca52017-10-16 13:04:27 -07001634 std::unique_ptr<rtc::FirewallSocketServer> fss_;
deadbeef1dcb1642017-03-29 21:08:16 -07001635 // |network_thread_| and |worker_thread_| are used by both
1636 // |caller_| and |callee_| so they must be destroyed
1637 // later.
1638 std::unique_ptr<rtc::Thread> network_thread_;
1639 std::unique_ptr<rtc::Thread> worker_thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -07001640 // The turn servers and turn customizers should be accessed & deleted on the
1641 // network thread to avoid a race with the socket read/write that occurs
1642 // on the network thread.
1643 std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
1644 std::vector<std::unique_ptr<cricket::TestTurnCustomizer>> turn_customizers_;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08001645 webrtc::MediaTransportPair loopback_media_transports_;
deadbeef1dcb1642017-03-29 21:08:16 -07001646 std::unique_ptr<PeerConnectionWrapper> caller_;
1647 std::unique_ptr<PeerConnectionWrapper> callee_;
1648};
1649
Seth Hampson2f0d7022018-02-20 11:54:42 -08001650class PeerConnectionIntegrationTest
1651 : public PeerConnectionIntegrationBaseTest,
1652 public ::testing::WithParamInterface<SdpSemantics> {
1653 protected:
1654 PeerConnectionIntegrationTest()
1655 : PeerConnectionIntegrationBaseTest(GetParam()) {}
1656};
1657
1658class PeerConnectionIntegrationTestPlanB
1659 : public PeerConnectionIntegrationBaseTest {
1660 protected:
1661 PeerConnectionIntegrationTestPlanB()
1662 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
1663};
1664
1665class PeerConnectionIntegrationTestUnifiedPlan
1666 : public PeerConnectionIntegrationBaseTest {
1667 protected:
1668 PeerConnectionIntegrationTestUnifiedPlan()
1669 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
1670};
1671
deadbeef1dcb1642017-03-29 21:08:16 -07001672// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
1673// includes testing that the callback is invoked if an observer is connected
1674// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001675TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001676 RtpReceiverObserverOnFirstPacketReceived) {
1677 ASSERT_TRUE(CreatePeerConnectionWrappers());
1678 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001679 caller()->AddAudioVideoTracks();
1680 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001681 // Start offer/answer exchange and wait for it to complete.
1682 caller()->CreateAndSetAndSignalOffer();
1683 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1684 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001685 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1686 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001687 // Wait for all "first packet received" callbacks to be fired.
1688 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001689 absl::c_all_of(caller()->rtp_receiver_observers(),
1690 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1691 return o->first_packet_received();
1692 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001693 kMaxWaitForFramesMs);
1694 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -08001695 absl::c_all_of(callee()->rtp_receiver_observers(),
1696 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1697 return o->first_packet_received();
1698 }),
deadbeef1dcb1642017-03-29 21:08:16 -07001699 kMaxWaitForFramesMs);
1700 // If new observers are set after the first packet was already received, the
1701 // callback should still be invoked.
1702 caller()->ResetRtpReceiverObservers();
1703 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001704 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
1705 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -07001706 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001707 absl::c_all_of(caller()->rtp_receiver_observers(),
1708 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1709 return o->first_packet_received();
1710 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001711 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -08001712 absl::c_all_of(callee()->rtp_receiver_observers(),
1713 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
1714 return o->first_packet_received();
1715 }));
deadbeef1dcb1642017-03-29 21:08:16 -07001716}
1717
1718class DummyDtmfObserver : public DtmfSenderObserverInterface {
1719 public:
1720 DummyDtmfObserver() : completed_(false) {}
1721
1722 // Implements DtmfSenderObserverInterface.
1723 void OnToneChange(const std::string& tone) override {
1724 tones_.push_back(tone);
1725 if (tone.empty()) {
1726 completed_ = true;
1727 }
1728 }
1729
1730 const std::vector<std::string>& tones() const { return tones_; }
1731 bool completed() const { return completed_; }
1732
1733 private:
1734 bool completed_;
1735 std::vector<std::string> tones_;
1736};
1737
1738// Assumes |sender| already has an audio track added and the offer/answer
1739// exchange is done.
1740void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender,
1741 PeerConnectionWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -08001742 // We should be able to get a DTMF sender from the local sender.
1743 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
1744 sender->pc()->GetSenders().at(0)->GetDtmfSender();
1745 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -07001746 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -07001747 dtmf_sender->RegisterObserver(&observer);
1748
1749 // Test the DtmfSender object just created.
1750 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1751 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
1752
1753 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
1754 std::vector<std::string> tones = {"1", "a", ""};
1755 EXPECT_EQ(tones, observer.tones());
1756 dtmf_sender->UnregisterObserver();
1757 // TODO(deadbeef): Verify the tones were actually received end-to-end.
1758}
1759
1760// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
1761// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001762TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -07001763 ASSERT_TRUE(CreatePeerConnectionWrappers());
1764 ConnectFakeSignaling();
1765 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -08001766 caller()->AddAudioTrack();
1767 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001768 caller()->CreateAndSetAndSignalOffer();
1769 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -07001770 // DTLS must finish before the DTMF sender can be used reliably.
1771 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001772 TestDtmfFromSenderToReceiver(caller(), callee());
1773 TestDtmfFromSenderToReceiver(callee(), caller());
1774}
1775
1776// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
1777// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001778TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -07001779 ASSERT_TRUE(CreatePeerConnectionWrappers());
1780 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +01001781
deadbeef1dcb1642017-03-29 21:08:16 -07001782 // Do normal offer/answer and wait for some frames to be received in each
1783 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001784 caller()->AddAudioVideoTracks();
1785 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001786 caller()->CreateAndSetAndSignalOffer();
1787 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001788 MediaExpectations media_expectations;
1789 media_expectations.ExpectBidirectionalAudioAndVideo();
1790 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001791 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1792 webrtc::kEnumCounterKeyProtocolDtls));
1793 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1794 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -07001795}
1796
1797// Uses SDES instead of DTLS for key agreement.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001798TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
deadbeef1dcb1642017-03-29 21:08:16 -07001799 PeerConnectionInterface::RTCConfiguration sdes_config;
1800 sdes_config.enable_dtls_srtp.emplace(false);
1801 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
1802 ConnectFakeSignaling();
1803
1804 // Do normal offer/answer and wait for some frames to be received in each
1805 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001806 caller()->AddAudioVideoTracks();
1807 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001808 caller()->CreateAndSetAndSignalOffer();
1809 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001810 MediaExpectations media_expectations;
1811 media_expectations.ExpectBidirectionalAudioAndVideo();
1812 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001813 EXPECT_LE(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1814 webrtc::kEnumCounterKeyProtocolSdes));
1815 EXPECT_EQ(0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
1816 webrtc::kEnumCounterKeyProtocolDtls));
deadbeef1dcb1642017-03-29 21:08:16 -07001817}
1818
Steve Anton8c0f7a72017-10-03 10:03:10 -07001819// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
1820// certificate once the DTLS handshake has finished.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001821TEST_P(PeerConnectionIntegrationTest,
Steve Anton8c0f7a72017-10-03 10:03:10 -07001822 GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
1823 auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
1824 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1825 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1826 return pc->GetRemoteAudioSSLCertificate();
1827 };
Zhi Huang70b820f2018-01-27 14:16:15 -08001828 auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) {
1829 auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
1830 auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
1831 return pc->GetRemoteAudioSSLCertChain();
1832 };
Steve Anton8c0f7a72017-10-03 10:03:10 -07001833
1834 auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
1835 auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
1836
1837 // Configure each side with a known certificate so they can be compared later.
1838 PeerConnectionInterface::RTCConfiguration caller_config;
1839 caller_config.enable_dtls_srtp.emplace(true);
1840 caller_config.certificates.push_back(caller_cert);
1841 PeerConnectionInterface::RTCConfiguration callee_config;
1842 callee_config.enable_dtls_srtp.emplace(true);
1843 callee_config.certificates.push_back(callee_cert);
1844 ASSERT_TRUE(
1845 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
1846 ConnectFakeSignaling();
1847
1848 // When first initialized, there should not be a remote SSL certificate (and
1849 // calling this method should not crash).
1850 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
1851 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
Zhi Huang70b820f2018-01-27 14:16:15 -08001852 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller()));
1853 EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee()));
Steve Anton8c0f7a72017-10-03 10:03:10 -07001854
Steve Anton15324772018-01-16 10:26:49 -08001855 caller()->AddAudioTrack();
1856 callee()->AddAudioTrack();
Steve Anton8c0f7a72017-10-03 10:03:10 -07001857 caller()->CreateAndSetAndSignalOffer();
1858 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1859 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1860
1861 // Once DTLS has been connected, each side should return the other's SSL
1862 // certificate when calling GetRemoteAudioSSLCertificate.
1863
1864 auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
1865 ASSERT_TRUE(caller_remote_cert);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001866 EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(),
Steve Anton8c0f7a72017-10-03 10:03:10 -07001867 caller_remote_cert->ToPEMString());
1868
1869 auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
1870 ASSERT_TRUE(callee_remote_cert);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001871 EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(),
Steve Anton8c0f7a72017-10-03 10:03:10 -07001872 callee_remote_cert->ToPEMString());
Zhi Huang70b820f2018-01-27 14:16:15 -08001873
1874 auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller());
1875 ASSERT_TRUE(caller_remote_cert_chain);
1876 ASSERT_EQ(1U, caller_remote_cert_chain->GetSize());
1877 auto remote_cert = &caller_remote_cert_chain->Get(0);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001878 EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(),
Zhi Huang70b820f2018-01-27 14:16:15 -08001879 remote_cert->ToPEMString());
1880
1881 auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee());
1882 ASSERT_TRUE(callee_remote_cert_chain);
1883 ASSERT_EQ(1U, callee_remote_cert_chain->GetSize());
1884 remote_cert = &callee_remote_cert_chain->Get(0);
Benjamin Wright6c6c9df2018-10-25 01:16:26 -07001885 EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(),
Zhi Huang70b820f2018-01-27 14:16:15 -08001886 remote_cert->ToPEMString());
Steve Anton8c0f7a72017-10-03 10:03:10 -07001887}
1888
deadbeef1dcb1642017-03-29 21:08:16 -07001889// This test sets up a call between two parties with a source resolution of
1890// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001891TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001892 Send1280By720ResolutionAndReceive16To9AspectRatio) {
1893 ASSERT_TRUE(CreatePeerConnectionWrappers());
1894 ConnectFakeSignaling();
1895
Niels Möller5c7efe72018-05-11 10:34:46 +02001896 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
1897 webrtc::FakePeriodicVideoSource::Config config;
1898 config.width = 1280;
1899 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +02001900 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +02001901 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
1902 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -07001903
1904 // Do normal offer/answer and wait for at least one frame to be received in
1905 // each direction.
1906 caller()->CreateAndSetAndSignalOffer();
1907 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
1908 callee()->min_video_frames_received_per_track() > 0,
1909 kMaxWaitForFramesMs);
1910
1911 // Check rendered aspect ratio.
1912 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
1913 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
1914 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
1915 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
1916}
1917
1918// This test sets up an one-way call, with media only from caller to
1919// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001920TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -07001921 ASSERT_TRUE(CreatePeerConnectionWrappers());
1922 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001923 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001924 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001925 MediaExpectations media_expectations;
1926 media_expectations.CalleeExpectsSomeAudioAndVideo();
1927 media_expectations.CallerExpectsNoAudio();
1928 media_expectations.CallerExpectsNoVideo();
1929 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001930}
1931
1932// This test sets up a audio call initially, with the callee rejecting video
1933// initially. Then later the callee decides to upgrade to audio/video, and
1934// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001935TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -07001936 ASSERT_TRUE(CreatePeerConnectionWrappers());
1937 ConnectFakeSignaling();
1938 // Initially, offer an audio/video stream from the caller, but refuse to
1939 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -08001940 caller()->AddAudioVideoTracks();
1941 callee()->AddAudioTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001942 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1943 PeerConnectionInterface::RTCOfferAnswerOptions options;
1944 options.offer_to_receive_video = 0;
1945 callee()->SetOfferAnswerOptions(options);
1946 } else {
1947 callee()->SetRemoteOfferHandler([this] {
1948 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
1949 });
1950 }
deadbeef1dcb1642017-03-29 21:08:16 -07001951 // Do offer/answer and make sure audio is still received end-to-end.
1952 caller()->CreateAndSetAndSignalOffer();
1953 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001954 {
1955 MediaExpectations media_expectations;
1956 media_expectations.ExpectBidirectionalAudio();
1957 media_expectations.ExpectNoVideo();
1958 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1959 }
deadbeef1dcb1642017-03-29 21:08:16 -07001960 // Sanity check that the callee's description has a rejected video section.
1961 ASSERT_NE(nullptr, callee()->pc()->local_description());
1962 const ContentInfo* callee_video_content =
1963 GetFirstVideoContent(callee()->pc()->local_description()->description());
1964 ASSERT_NE(nullptr, callee_video_content);
1965 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001966
deadbeef1dcb1642017-03-29 21:08:16 -07001967 // Now negotiate with video and ensure negotiation succeeds, with video
1968 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -08001969 callee()->AddVideoTrack();
Seth Hampson2f0d7022018-02-20 11:54:42 -08001970 if (sdp_semantics_ == SdpSemantics::kPlanB) {
1971 PeerConnectionInterface::RTCOfferAnswerOptions options;
1972 options.offer_to_receive_video = 1;
1973 callee()->SetOfferAnswerOptions(options);
1974 } else {
1975 callee()->SetRemoteOfferHandler(nullptr);
1976 caller()->SetRemoteOfferHandler([this] {
1977 // The caller creates a new transceiver to receive video on when receiving
1978 // the offer, but by default it is send only.
1979 auto transceivers = caller()->pc()->GetTransceivers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001980 ASSERT_EQ(3U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001981 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
1982 transceivers[2]->receiver()->media_type());
1983 transceivers[2]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
1984 transceivers[2]->SetDirection(RtpTransceiverDirection::kSendRecv);
1985 });
1986 }
deadbeef1dcb1642017-03-29 21:08:16 -07001987 callee()->CreateAndSetAndSignalOffer();
1988 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001989 {
1990 // Expect additional audio frames to be received after the upgrade.
1991 MediaExpectations media_expectations;
1992 media_expectations.ExpectBidirectionalAudioAndVideo();
1993 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1994 }
deadbeef1dcb1642017-03-29 21:08:16 -07001995}
1996
deadbeef4389b4d2017-09-07 09:07:36 -07001997// Simpler than the above test; just add an audio track to an established
1998// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001999TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -07002000 ASSERT_TRUE(CreatePeerConnectionWrappers());
2001 ConnectFakeSignaling();
2002 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -08002003 caller()->AddVideoTrack();
2004 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002005 caller()->CreateAndSetAndSignalOffer();
2006 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2007 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08002008 caller()->AddAudioTrack();
2009 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -07002010 caller()->CreateAndSetAndSignalOffer();
2011 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2012 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002013 MediaExpectations media_expectations;
2014 media_expectations.ExpectBidirectionalAudioAndVideo();
2015 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -07002016}
2017
deadbeef1dcb1642017-03-29 21:08:16 -07002018// This test sets up a call that's transferred to a new caller with a different
2019// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002020TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -07002021 ASSERT_TRUE(CreatePeerConnectionWrappers());
2022 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002023 caller()->AddAudioVideoTracks();
2024 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002025 caller()->CreateAndSetAndSignalOffer();
2026 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2027
2028 // Keep the original peer around which will still send packets to the
2029 // receiving client. These SRTP packets will be dropped.
2030 std::unique_ptr<PeerConnectionWrapper> original_peer(
2031 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002032 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002033 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2034 // directly above.
2035 original_peer->pc()->Close();
2036
2037 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002038 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002039 caller()->CreateAndSetAndSignalOffer();
2040 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2041 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002042 MediaExpectations media_expectations;
2043 media_expectations.ExpectBidirectionalAudioAndVideo();
2044 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002045}
2046
2047// This test sets up a call that's transferred to a new callee with a different
2048// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002049TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -07002050 ASSERT_TRUE(CreatePeerConnectionWrappers());
2051 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002052 caller()->AddAudioVideoTracks();
2053 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002054 caller()->CreateAndSetAndSignalOffer();
2055 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2056
2057 // Keep the original peer around which will still send packets to the
2058 // receiving client. These SRTP packets will be dropped.
2059 std::unique_ptr<PeerConnectionWrapper> original_peer(
2060 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002061 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -07002062 // TODO(deadbeef): Why do we call Close here? That goes against the comment
2063 // directly above.
2064 original_peer->pc()->Close();
2065
2066 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002067 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002068 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2069 caller()->CreateAndSetAndSignalOffer();
2070 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2071 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002072 MediaExpectations media_expectations;
2073 media_expectations.ExpectBidirectionalAudioAndVideo();
2074 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002075}
2076
2077// This test sets up a non-bundled call and negotiates bundling at the same
2078// time as starting an ICE restart. When bundling is in effect in the restart,
2079// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002080TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -07002081 ASSERT_TRUE(CreatePeerConnectionWrappers());
2082 ConnectFakeSignaling();
2083
Steve Anton15324772018-01-16 10:26:49 -08002084 caller()->AddAudioVideoTracks();
2085 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002086 // Remove the bundle group from the SDP received by the callee.
2087 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2088 desc->RemoveGroupByName("BUNDLE");
2089 });
2090 caller()->CreateAndSetAndSignalOffer();
2091 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002092 {
2093 MediaExpectations media_expectations;
2094 media_expectations.ExpectBidirectionalAudioAndVideo();
2095 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2096 }
deadbeef1dcb1642017-03-29 21:08:16 -07002097 // Now stop removing the BUNDLE group, and trigger an ICE restart.
2098 callee()->SetReceivedSdpMunger(nullptr);
2099 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2100 caller()->CreateAndSetAndSignalOffer();
2101 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2102
2103 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002104 {
2105 MediaExpectations media_expectations;
2106 media_expectations.ExpectBidirectionalAudioAndVideo();
2107 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2108 }
deadbeef1dcb1642017-03-29 21:08:16 -07002109}
2110
2111// Test CVO (Coordination of Video Orientation). If a video source is rotated
2112// and both peers support the CVO RTP header extension, the actual video frames
2113// don't need to be encoded in different resolutions, since the rotation is
2114// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002115TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002116 ASSERT_TRUE(CreatePeerConnectionWrappers());
2117 ConnectFakeSignaling();
2118 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002119 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002120 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002121 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002122 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2123
2124 // Wait for video frames to be received by both sides.
2125 caller()->CreateAndSetAndSignalOffer();
2126 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2127 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2128 callee()->min_video_frames_received_per_track() > 0,
2129 kMaxWaitForFramesMs);
2130
2131 // Ensure that the aspect ratio is unmodified.
2132 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2133 // not just assumed.
2134 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
2135 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
2136 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
2137 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
2138 // Ensure that the CVO bits were surfaced to the renderer.
2139 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
2140 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
2141}
2142
2143// Test that when the CVO extension isn't supported, video is rotated the
2144// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002145TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -07002146 ASSERT_TRUE(CreatePeerConnectionWrappers());
2147 ConnectFakeSignaling();
2148 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -08002149 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002150 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -08002151 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -07002152 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
2153
2154 // Remove the CVO extension from the offered SDP.
2155 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
2156 cricket::VideoContentDescription* video =
2157 GetFirstVideoContentDescription(desc);
2158 video->ClearRtpHeaderExtensions();
2159 });
2160 // Wait for video frames to be received by both sides.
2161 caller()->CreateAndSetAndSignalOffer();
2162 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2163 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
2164 callee()->min_video_frames_received_per_track() > 0,
2165 kMaxWaitForFramesMs);
2166
2167 // Expect that the aspect ratio is inversed to account for the 90/270 degree
2168 // rotation.
2169 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
2170 // not just assumed.
2171 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
2172 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
2173 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
2174 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
2175 // Expect that each endpoint is unaware of the rotation of the other endpoint.
2176 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
2177 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
2178}
2179
deadbeef1dcb1642017-03-29 21:08:16 -07002180// Test that if the answerer rejects the audio m= section, no audio is sent or
2181// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002182TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002183 ASSERT_TRUE(CreatePeerConnectionWrappers());
2184 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002185 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002186 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2187 // Only add video track for callee, and set offer_to_receive_audio to 0, so
2188 // it will reject the audio m= section completely.
2189 PeerConnectionInterface::RTCOfferAnswerOptions options;
2190 options.offer_to_receive_audio = 0;
2191 callee()->SetOfferAnswerOptions(options);
2192 } else {
2193 // Stopping the audio RtpTransceiver will cause the media section to be
2194 // rejected in the answer.
2195 callee()->SetRemoteOfferHandler([this] {
2196 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->Stop();
2197 });
2198 }
Steve Anton15324772018-01-16 10:26:49 -08002199 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002200 // Do offer/answer and wait for successful end-to-end video frames.
2201 caller()->CreateAndSetAndSignalOffer();
2202 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002203 MediaExpectations media_expectations;
2204 media_expectations.ExpectBidirectionalVideo();
2205 media_expectations.ExpectNoAudio();
2206 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2207
deadbeef1dcb1642017-03-29 21:08:16 -07002208 // Sanity check that the callee's description has a rejected audio section.
2209 ASSERT_NE(nullptr, callee()->pc()->local_description());
2210 const ContentInfo* callee_audio_content =
2211 GetFirstAudioContent(callee()->pc()->local_description()->description());
2212 ASSERT_NE(nullptr, callee_audio_content);
2213 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002214 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2215 // The caller's transceiver should have stopped after receiving the answer.
2216 EXPECT_TRUE(caller()
2217 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
2218 ->stopped());
2219 }
deadbeef1dcb1642017-03-29 21:08:16 -07002220}
2221
2222// Test that if the answerer rejects the video m= section, no video is sent or
2223// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002224TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -07002225 ASSERT_TRUE(CreatePeerConnectionWrappers());
2226 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002227 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002228 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2229 // Only add audio track for callee, and set offer_to_receive_video to 0, so
2230 // it will reject the video m= section completely.
2231 PeerConnectionInterface::RTCOfferAnswerOptions options;
2232 options.offer_to_receive_video = 0;
2233 callee()->SetOfferAnswerOptions(options);
2234 } else {
2235 // Stopping the video RtpTransceiver will cause the media section to be
2236 // rejected in the answer.
2237 callee()->SetRemoteOfferHandler([this] {
2238 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2239 });
2240 }
Steve Anton15324772018-01-16 10:26:49 -08002241 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -07002242 // Do offer/answer and wait for successful end-to-end audio frames.
2243 caller()->CreateAndSetAndSignalOffer();
2244 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002245 MediaExpectations media_expectations;
2246 media_expectations.ExpectBidirectionalAudio();
2247 media_expectations.ExpectNoVideo();
2248 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2249
deadbeef1dcb1642017-03-29 21:08:16 -07002250 // Sanity check that the callee's description has a rejected video section.
2251 ASSERT_NE(nullptr, callee()->pc()->local_description());
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);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002256 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
2257 // The caller's transceiver should have stopped after receiving the answer.
2258 EXPECT_TRUE(caller()
2259 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2260 ->stopped());
2261 }
deadbeef1dcb1642017-03-29 21:08:16 -07002262}
2263
2264// Test that if the answerer rejects both audio and video m= sections, nothing
2265// bad happens.
2266// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
2267// test anything but the fact that negotiation succeeds, which doesn't mean
2268// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002269TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -07002270 ASSERT_TRUE(CreatePeerConnectionWrappers());
2271 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002272 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002273 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2274 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
2275 // will reject both audio and video m= sections.
2276 PeerConnectionInterface::RTCOfferAnswerOptions options;
2277 options.offer_to_receive_audio = 0;
2278 options.offer_to_receive_video = 0;
2279 callee()->SetOfferAnswerOptions(options);
2280 } else {
2281 callee()->SetRemoteOfferHandler([this] {
2282 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002283 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002284 transceiver->Stop();
2285 }
2286 });
2287 }
deadbeef1dcb1642017-03-29 21:08:16 -07002288 // Do offer/answer and wait for stable signaling state.
2289 caller()->CreateAndSetAndSignalOffer();
2290 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002291
deadbeef1dcb1642017-03-29 21:08:16 -07002292 // Sanity check that the callee's description has rejected m= sections.
2293 ASSERT_NE(nullptr, callee()->pc()->local_description());
2294 const ContentInfo* callee_audio_content =
2295 GetFirstAudioContent(callee()->pc()->local_description()->description());
2296 ASSERT_NE(nullptr, callee_audio_content);
2297 EXPECT_TRUE(callee_audio_content->rejected);
2298 const ContentInfo* callee_video_content =
2299 GetFirstVideoContent(callee()->pc()->local_description()->description());
2300 ASSERT_NE(nullptr, callee_video_content);
2301 EXPECT_TRUE(callee_video_content->rejected);
2302}
2303
2304// This test sets up an audio and video call between two parties. After the
2305// call runs for a while, the caller sends an updated offer with video being
2306// rejected. Once the re-negotiation is done, the video flow should stop and
2307// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002308TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07002309 ASSERT_TRUE(CreatePeerConnectionWrappers());
2310 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002311 caller()->AddAudioVideoTracks();
2312 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002313 caller()->CreateAndSetAndSignalOffer();
2314 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002315 {
2316 MediaExpectations media_expectations;
2317 media_expectations.ExpectBidirectionalAudioAndVideo();
2318 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2319 }
deadbeef1dcb1642017-03-29 21:08:16 -07002320 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002321 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2322 caller()->SetGeneratedSdpMunger(
2323 [](cricket::SessionDescription* description) {
2324 for (cricket::ContentInfo& content : description->contents()) {
2325 if (cricket::IsVideoContent(&content)) {
2326 content.rejected = true;
2327 }
2328 }
2329 });
2330 } else {
2331 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
2332 }
deadbeef1dcb1642017-03-29 21:08:16 -07002333 caller()->CreateAndSetAndSignalOffer();
2334 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2335
2336 // Sanity check that the caller's description has a rejected video section.
2337 ASSERT_NE(nullptr, caller()->pc()->local_description());
2338 const ContentInfo* caller_video_content =
2339 GetFirstVideoContent(caller()->pc()->local_description()->description());
2340 ASSERT_NE(nullptr, caller_video_content);
2341 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -07002342 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002343 {
2344 MediaExpectations media_expectations;
2345 media_expectations.ExpectBidirectionalAudio();
2346 media_expectations.ExpectNoVideo();
2347 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2348 }
deadbeef1dcb1642017-03-29 21:08:16 -07002349}
2350
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -07002351// Do one offer/answer with audio, another that disables it (rejecting the m=
2352// section), and another that re-enables it. Regression test for:
2353// bugs.webrtc.org/6023
2354TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
2355 ASSERT_TRUE(CreatePeerConnectionWrappers());
2356 ConnectFakeSignaling();
2357
2358 // Add audio track, do normal offer/answer.
2359 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2360 caller()->CreateLocalAudioTrack();
2361 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2362 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2363 caller()->CreateAndSetAndSignalOffer();
2364 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2365
2366 // Remove audio track, and set offer_to_receive_audio to false to cause the
2367 // m= section to be completely disabled, not just "recvonly".
2368 caller()->pc()->RemoveTrack(sender);
2369 PeerConnectionInterface::RTCOfferAnswerOptions options;
2370 options.offer_to_receive_audio = 0;
2371 caller()->SetOfferAnswerOptions(options);
2372 caller()->CreateAndSetAndSignalOffer();
2373 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2374
2375 // Add the audio track again, expecting negotiation to succeed and frames to
2376 // flow.
2377 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
2378 options.offer_to_receive_audio = 1;
2379 caller()->SetOfferAnswerOptions(options);
2380 caller()->CreateAndSetAndSignalOffer();
2381 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2382
2383 MediaExpectations media_expectations;
2384 media_expectations.CalleeExpectsSomeAudio();
2385 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2386}
2387
deadbeef1dcb1642017-03-29 21:08:16 -07002388// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
2389// is needed to support legacy endpoints.
2390// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
2391// add a test for an end-to-end test without MID signaling either (basically,
2392// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002393TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07002394 ASSERT_TRUE(CreatePeerConnectionWrappers());
2395 ConnectFakeSignaling();
2396 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08002397 caller()->AddAudioVideoTracks();
2398 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07002399 // Remove SSRCs and MSIDs from the received offer SDP.
2400 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07002401 caller()->CreateAndSetAndSignalOffer();
2402 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002403 MediaExpectations media_expectations;
2404 media_expectations.ExpectBidirectionalAudioAndVideo();
2405 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002406}
2407
Seth Hampson5897a6e2018-04-03 11:16:33 -07002408// Basic end-to-end test, without SSRC signaling. This means that the track
2409// was created properly and frames are delivered when the MSIDs are communicated
2410// with a=msid lines and no a=ssrc lines.
2411TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2412 EndToEndCallWithoutSsrcSignaling) {
2413 const char kStreamId[] = "streamId";
2414 ASSERT_TRUE(CreatePeerConnectionWrappers());
2415 ConnectFakeSignaling();
2416 // Add just audio tracks.
2417 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
2418 callee()->AddAudioTrack();
2419
2420 // Remove SSRCs from the received offer SDP.
2421 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
2422 caller()->CreateAndSetAndSignalOffer();
2423 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2424 MediaExpectations media_expectations;
2425 media_expectations.ExpectBidirectionalAudio();
2426 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2427}
2428
Steve Antondf527fd2018-04-27 15:52:03 -07002429// Tests that video flows between multiple video tracks when SSRCs are not
2430// signaled. This exercises the MID RTP header extension which is needed to
2431// demux the incoming video tracks.
2432TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2433 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
2434 ASSERT_TRUE(CreatePeerConnectionWrappers());
2435 ConnectFakeSignaling();
2436 caller()->AddVideoTrack();
2437 caller()->AddVideoTrack();
2438 callee()->AddVideoTrack();
2439 callee()->AddVideoTrack();
2440
2441 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2442 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
2443 caller()->CreateAndSetAndSignalOffer();
2444 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2445 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
2446 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
2447
2448 // Expect video to be received in both directions on both tracks.
2449 MediaExpectations media_expectations;
2450 media_expectations.ExpectBidirectionalVideo();
2451 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2452}
2453
Henrik Boström5b147782018-12-04 11:25:05 +01002454TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
2455 ASSERT_TRUE(CreatePeerConnectionWrappers());
2456 ConnectFakeSignaling();
2457 caller()->AddAudioTrack();
2458 caller()->AddVideoTrack();
2459 caller()->CreateAndSetAndSignalOffer();
2460 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2461 auto callee_receivers = callee()->pc()->GetReceivers();
2462 ASSERT_EQ(2u, callee_receivers.size());
2463 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
2464 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
2465}
2466
2467TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
2468 ASSERT_TRUE(CreatePeerConnectionWrappers());
2469 ConnectFakeSignaling();
2470 caller()->AddAudioTrack();
2471 caller()->AddVideoTrack();
2472 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2473 caller()->CreateAndSetAndSignalOffer();
2474 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2475 auto callee_receivers = callee()->pc()->GetReceivers();
2476 ASSERT_EQ(2u, callee_receivers.size());
2477 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
2478 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
2479 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
2480 callee_receivers[1]->stream_ids()[0]);
2481 EXPECT_EQ(callee_receivers[0]->streams()[0],
2482 callee_receivers[1]->streams()[0]);
2483}
2484
deadbeef1dcb1642017-03-29 21:08:16 -07002485// Test that if two video tracks are sent (from caller to callee, in this test),
2486// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002487TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07002488 ASSERT_TRUE(CreatePeerConnectionWrappers());
2489 ConnectFakeSignaling();
2490 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08002491 caller()->AddAudioVideoTracks();
2492 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002493 caller()->CreateAndSetAndSignalOffer();
2494 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08002495 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002496
2497 MediaExpectations media_expectations;
2498 media_expectations.CalleeExpectsSomeAudioAndVideo();
2499 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002500}
2501
2502static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
2503 bool first = true;
2504 for (cricket::ContentInfo& content : desc->contents()) {
2505 if (first) {
2506 first = false;
2507 continue;
2508 }
2509 content.bundle_only = true;
2510 }
2511 first = true;
2512 for (cricket::TransportInfo& transport : desc->transport_infos()) {
2513 if (first) {
2514 first = false;
2515 continue;
2516 }
2517 transport.description.ice_ufrag.clear();
2518 transport.description.ice_pwd.clear();
2519 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
2520 transport.description.identity_fingerprint.reset(nullptr);
2521 }
2522}
2523
2524// Test that if applying a true "max bundle" offer, which uses ports of 0,
2525// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
2526// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
2527// successfully and media flows.
2528// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
2529// TODO(deadbeef): Won't need this test once we start generating actual
2530// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002531TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002532 EndToEndCallWithSpecCompliantMaxBundleOffer) {
2533 ASSERT_TRUE(CreatePeerConnectionWrappers());
2534 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002535 caller()->AddAudioVideoTracks();
2536 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002537 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
2538 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
2539 // but the first m= section.
2540 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
2541 caller()->CreateAndSetAndSignalOffer();
2542 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002543 MediaExpectations media_expectations;
2544 media_expectations.ExpectBidirectionalAudioAndVideo();
2545 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002546}
2547
2548// Test that we can receive the audio output level from a remote audio track.
2549// TODO(deadbeef): Use a fake audio source and verify that the output level is
2550// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002551TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002552 ASSERT_TRUE(CreatePeerConnectionWrappers());
2553 ConnectFakeSignaling();
2554 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002555 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002556 caller()->CreateAndSetAndSignalOffer();
2557 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2558
2559 // Get the audio output level stats. Note that the level is not available
2560 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07002561 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002562 kMaxWaitForFramesMs);
2563}
2564
2565// Test that an audio input level is reported.
2566// TODO(deadbeef): Use a fake audio source and verify that the input level is
2567// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002568TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002569 ASSERT_TRUE(CreatePeerConnectionWrappers());
2570 ConnectFakeSignaling();
2571 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08002572 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002573 caller()->CreateAndSetAndSignalOffer();
2574 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2575
2576 // Get the audio input level stats. The level should be available very
2577 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07002578 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07002579 kMaxWaitForStatsMs);
2580}
2581
2582// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002583TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002584 ASSERT_TRUE(CreatePeerConnectionWrappers());
2585 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002586 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002587 // Do offer/answer, wait for the callee to receive some frames.
2588 caller()->CreateAndSetAndSignalOffer();
2589 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002590
2591 MediaExpectations media_expectations;
2592 media_expectations.CalleeExpectsSomeAudioAndVideo();
2593 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002594
2595 // Get a handle to the remote tracks created, so they can be used as GetStats
2596 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01002597 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08002598 // We received frames, so we definitely should have nonzero "received bytes"
2599 // stats at this point.
2600 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
2601 0);
2602 }
deadbeef1dcb1642017-03-29 21:08:16 -07002603}
2604
2605// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002606TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07002607 ASSERT_TRUE(CreatePeerConnectionWrappers());
2608 ConnectFakeSignaling();
2609 auto audio_track = caller()->CreateLocalAudioTrack();
2610 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08002611 caller()->AddTrack(audio_track);
2612 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07002613 // Do offer/answer, wait for the callee to receive some frames.
2614 caller()->CreateAndSetAndSignalOffer();
2615 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002616 MediaExpectations media_expectations;
2617 media_expectations.CalleeExpectsSomeAudioAndVideo();
2618 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002619
2620 // The callee received frames, so we definitely should have nonzero "sent
2621 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07002622 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
2623 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
2624}
2625
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002626// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002627TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002628 ASSERT_TRUE(CreatePeerConnectionWrappers());
2629 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002630 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002631
Steve Anton15324772018-01-16 10:26:49 -08002632 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002633
2634 // Do offer/answer, wait for the callee to receive some frames.
2635 caller()->CreateAndSetAndSignalOffer();
2636 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2637
2638 // Get the remote audio track created on the receiver, so they can be used as
2639 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08002640 auto receivers = callee()->pc()->GetReceivers();
2641 ASSERT_EQ(1u, receivers.size());
2642 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002643
2644 // Get the audio output level stats. Note that the level is not available
2645 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07002646 EXPECT_TRUE_WAIT(
2647 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
2648 0,
2649 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02002650}
2651
Steve Antona41959e2018-11-28 11:15:33 -08002652// Test that the track ID is associated with all local and remote SSRC stats
2653// using the old GetStats() and more than 1 audio and more than 1 video track.
2654// This is a regression test for crbug.com/906988
2655TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2656 OldGetStatsAssociatesTrackIdForManyMediaSections) {
2657 ASSERT_TRUE(CreatePeerConnectionWrappers());
2658 ConnectFakeSignaling();
2659 auto audio_sender_1 = caller()->AddAudioTrack();
2660 auto video_sender_1 = caller()->AddVideoTrack();
2661 auto audio_sender_2 = caller()->AddAudioTrack();
2662 auto video_sender_2 = caller()->AddVideoTrack();
2663 caller()->CreateAndSetAndSignalOffer();
2664 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2665
2666 MediaExpectations media_expectations;
2667 media_expectations.CalleeExpectsSomeAudioAndVideo();
2668 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
2669
2670 std::vector<std::string> track_ids = {
2671 audio_sender_1->track()->id(), video_sender_1->track()->id(),
2672 audio_sender_2->track()->id(), video_sender_2->track()->id()};
2673
2674 auto caller_stats = caller()->OldGetStats();
2675 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
2676 auto callee_stats = callee()->OldGetStats();
2677 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
2678}
2679
Steve Antonffa6ce42018-11-30 09:26:08 -08002680// Test that the new GetStats() returns stats for all outgoing/incoming streams
2681// with the correct track IDs if there are more than one audio and more than one
2682// video senders/receivers.
2683TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
2684 ASSERT_TRUE(CreatePeerConnectionWrappers());
2685 ConnectFakeSignaling();
2686 auto audio_sender_1 = caller()->AddAudioTrack();
2687 auto video_sender_1 = caller()->AddVideoTrack();
2688 auto audio_sender_2 = caller()->AddAudioTrack();
2689 auto video_sender_2 = caller()->AddVideoTrack();
2690 caller()->CreateAndSetAndSignalOffer();
2691 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2692
2693 MediaExpectations media_expectations;
2694 media_expectations.CalleeExpectsSomeAudioAndVideo();
2695 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
2696
2697 std::vector<std::string> track_ids = {
2698 audio_sender_1->track()->id(), video_sender_1->track()->id(),
2699 audio_sender_2->track()->id(), video_sender_2->track()->id()};
2700
2701 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
2702 caller()->NewGetStats();
2703 ASSERT_TRUE(caller_report);
2704 auto outbound_stream_stats =
2705 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
2706 ASSERT_EQ(4u, outbound_stream_stats.size());
2707 std::vector<std::string> outbound_track_ids;
2708 for (const auto& stat : outbound_stream_stats) {
2709 ASSERT_TRUE(stat->bytes_sent.is_defined());
2710 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02002711 if (*stat->kind == "video") {
2712 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
2713 EXPECT_GT(*stat->key_frames_encoded, 0u);
2714 ASSERT_TRUE(stat->frames_encoded.is_defined());
2715 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
2716 }
Steve Antonffa6ce42018-11-30 09:26:08 -08002717 ASSERT_TRUE(stat->track_id.is_defined());
2718 const auto* track_stat =
2719 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
2720 ASSERT_TRUE(track_stat);
2721 outbound_track_ids.push_back(*track_stat->track_identifier);
2722 }
2723 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
2724
2725 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
2726 callee()->NewGetStats();
2727 ASSERT_TRUE(callee_report);
2728 auto inbound_stream_stats =
2729 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2730 ASSERT_EQ(4u, inbound_stream_stats.size());
2731 std::vector<std::string> inbound_track_ids;
2732 for (const auto& stat : inbound_stream_stats) {
2733 ASSERT_TRUE(stat->bytes_received.is_defined());
2734 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02002735 if (*stat->kind == "video") {
2736 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
2737 EXPECT_GT(*stat->key_frames_decoded, 0u);
2738 ASSERT_TRUE(stat->frames_decoded.is_defined());
2739 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
2740 }
Steve Antonffa6ce42018-11-30 09:26:08 -08002741 ASSERT_TRUE(stat->track_id.is_defined());
2742 const auto* track_stat =
2743 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
2744 ASSERT_TRUE(track_stat);
2745 inbound_track_ids.push_back(*track_stat->track_identifier);
2746 }
2747 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
2748}
2749
2750// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07002751// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
2752// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002753TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07002754 GetStatsForUnsignaledStreamWithNewStatsApi) {
2755 ASSERT_TRUE(CreatePeerConnectionWrappers());
2756 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002757 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07002758 // Remove SSRCs and MSIDs from the received offer SDP.
2759 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2760 caller()->CreateAndSetAndSignalOffer();
2761 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002762 MediaExpectations media_expectations;
2763 media_expectations.CalleeExpectsSomeAudio(1);
2764 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07002765
2766 // We received a frame, so we should have nonzero "bytes received" stats for
2767 // the unsignaled stream, if stats are working for it.
2768 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2769 callee()->NewGetStats();
2770 ASSERT_NE(nullptr, report);
2771 auto inbound_stream_stats =
2772 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2773 ASSERT_EQ(1U, inbound_stream_stats.size());
2774 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
2775 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07002776 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
2777}
2778
Taylor Brandstettera4653442018-06-19 09:44:26 -07002779// Same as above but for the legacy stats implementation.
2780TEST_P(PeerConnectionIntegrationTest,
2781 GetStatsForUnsignaledStreamWithOldStatsApi) {
2782 ASSERT_TRUE(CreatePeerConnectionWrappers());
2783 ConnectFakeSignaling();
2784 caller()->AddAudioTrack();
2785 // Remove SSRCs and MSIDs from the received offer SDP.
2786 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2787 caller()->CreateAndSetAndSignalOffer();
2788 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2789
2790 // Note that, since the old stats implementation associates SSRCs with tracks
2791 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
2792 // associated track ID. So we can't use the track "selector" argument.
2793 //
2794 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
2795 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002796 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07002797 kDefaultTimeout);
2798}
2799
zhihuangf8164932017-05-19 13:09:47 -07002800// Test that we can successfully get the media related stats (audio level
2801// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002802TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07002803 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
2804 ASSERT_TRUE(CreatePeerConnectionWrappers());
2805 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002806 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07002807 // Remove SSRCs and MSIDs from the received offer SDP.
2808 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2809 caller()->CreateAndSetAndSignalOffer();
2810 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002811 MediaExpectations media_expectations;
2812 media_expectations.CalleeExpectsSomeAudio(1);
2813 media_expectations.CalleeExpectsSomeVideo(1);
2814 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07002815
2816 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2817 callee()->NewGetStats();
2818 ASSERT_NE(nullptr, report);
2819
2820 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2821 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
2822 ASSERT_GE(audio_index, 0);
2823 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07002824}
2825
deadbeef4e2deab2017-09-20 13:56:21 -07002826// Helper for test below.
2827void ModifySsrcs(cricket::SessionDescription* desc) {
2828 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07002829 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08002830 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07002831 for (uint32_t& ssrc : stream.ssrcs) {
2832 ssrc = rtc::CreateRandomId();
2833 }
2834 }
2835 }
2836}
2837
2838// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
2839// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
2840// This should result in two "RTCInboundRTPStreamStats", but only one
2841// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
2842// being reset to 0 once the SSRC change occurs.
2843//
2844// Regression test for this bug:
2845// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
2846//
2847// The bug causes the track stats to only represent one of the two streams:
2848// whichever one has the higher SSRC. So with this bug, there was a 50% chance
2849// that the track stat counters would reset to 0 when the new stream is
2850// received, and a 50% chance that they'll stop updating (while
2851// "concealed_samples" continues increasing, due to silence being generated for
2852// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002853TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08002854 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07002855 ASSERT_TRUE(CreatePeerConnectionWrappers());
2856 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002857 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07002858 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
2859 // that doesn't signal SSRCs (from the callee's perspective).
2860 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
2861 caller()->CreateAndSetAndSignalOffer();
2862 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2863 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002864 {
2865 MediaExpectations media_expectations;
2866 media_expectations.CalleeExpectsSomeAudio(50);
2867 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2868 }
deadbeef4e2deab2017-09-20 13:56:21 -07002869 // Some audio frames were received, so we should have nonzero "samples
2870 // received" for the track.
2871 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
2872 callee()->NewGetStats();
2873 ASSERT_NE(nullptr, report);
2874 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2875 ASSERT_EQ(1U, track_stats.size());
2876 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2877 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
2878 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
2879
2880 // Create a new offer and munge it to cause the caller to use a new SSRC.
2881 caller()->SetGeneratedSdpMunger(ModifySsrcs);
2882 caller()->CreateAndSetAndSignalOffer();
2883 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2884 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
2885 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002886 {
2887 MediaExpectations media_expectations;
2888 media_expectations.CalleeExpectsSomeAudio(25);
2889 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2890 }
deadbeef4e2deab2017-09-20 13:56:21 -07002891
2892 report = callee()->NewGetStats();
2893 ASSERT_NE(nullptr, report);
2894 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2895 ASSERT_EQ(1U, track_stats.size());
2896 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
2897 // The "total samples received" stat should only be greater than it was
2898 // before.
2899 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
2900 // Right now, the new SSRC will cause the counters to reset to 0.
2901 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
2902
2903 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08002904 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07002905 // good sign that we're seeing stats from the old stream that's no longer
2906 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08002907 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07002908 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
2909 EXPECT_LT(*track_stats[0]->concealed_samples,
2910 *track_stats[0]->total_samples_received *
2911 kAcceptableConcealedSamplesPercentage);
2912
2913 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
2914 // sanity check that the SSRC really changed.
2915 // TODO(deadbeef): This isn't working right now, because we're not returning
2916 // *any* stats for the inactive stream. Uncomment when the bug is completely
2917 // fixed.
2918 // auto inbound_stream_stats =
2919 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2920 // ASSERT_EQ(2U, inbound_stream_stats.size());
2921}
2922
deadbeef1dcb1642017-03-29 21:08:16 -07002923// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002924TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002925 PeerConnectionFactory::Options dtls_10_options;
2926 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2927 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2928 dtls_10_options));
2929 ConnectFakeSignaling();
2930 // Do normal offer/answer and wait for some frames to be received in each
2931 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002932 caller()->AddAudioVideoTracks();
2933 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002934 caller()->CreateAndSetAndSignalOffer();
2935 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002936 MediaExpectations media_expectations;
2937 media_expectations.ExpectBidirectionalAudioAndVideo();
2938 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002939}
2940
2941// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002942TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002943 PeerConnectionFactory::Options dtls_10_options;
2944 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2945 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
2946 dtls_10_options));
2947 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002948 caller()->AddAudioVideoTracks();
2949 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002950 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002951 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002952 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002953 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002954 kDefaultTimeout);
2955 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002956 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002957 // TODO(bugs.webrtc.org/9456): Fix it.
Alex Loiko9289eda2018-11-23 16:18:59 +00002958 EXPECT_EQ(1, webrtc::metrics::NumEvents(
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002959 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2960 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002961}
2962
2963// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002964TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07002965 PeerConnectionFactory::Options dtls_12_options;
2966 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2967 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
2968 dtls_12_options));
2969 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002970 caller()->AddAudioVideoTracks();
2971 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002972 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002973 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07002974 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07002975 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07002976 kDefaultTimeout);
2977 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07002978 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002979 // TODO(bugs.webrtc.org/9456): Fix it.
Alex Loiko9289eda2018-11-23 16:18:59 +00002980 EXPECT_EQ(1, webrtc::metrics::NumEvents(
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002981 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
2982 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07002983}
2984
2985// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
2986// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002987TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07002988 PeerConnectionFactory::Options caller_options;
2989 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
2990 PeerConnectionFactory::Options callee_options;
2991 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
2992 ASSERT_TRUE(
2993 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
2994 ConnectFakeSignaling();
2995 // Do normal offer/answer and wait for some frames to be received in each
2996 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002997 caller()->AddAudioVideoTracks();
2998 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002999 caller()->CreateAndSetAndSignalOffer();
3000 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003001 MediaExpectations media_expectations;
3002 media_expectations.ExpectBidirectionalAudioAndVideo();
3003 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003004}
3005
3006// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
3007// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003008TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07003009 PeerConnectionFactory::Options caller_options;
3010 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
3011 PeerConnectionFactory::Options callee_options;
3012 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
3013 ASSERT_TRUE(
3014 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
3015 ConnectFakeSignaling();
3016 // Do normal offer/answer and wait for some frames to be received in each
3017 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003018 caller()->AddAudioVideoTracks();
3019 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003020 caller()->CreateAndSetAndSignalOffer();
3021 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003022 MediaExpectations media_expectations;
3023 media_expectations.ExpectBidirectionalAudioAndVideo();
3024 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003025}
3026
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003027// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
3028// works as expected; the cipher should only be used if enabled by both sides.
3029TEST_P(PeerConnectionIntegrationTest,
3030 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
3031 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003032 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003033 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003034 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3035 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003036 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3037 TestNegotiatedCipherSuite(caller_options, callee_options,
3038 expected_cipher_suite);
3039}
3040
3041TEST_P(PeerConnectionIntegrationTest,
3042 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
3043 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003044 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
3045 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003046 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003047 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003048 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
3049 TestNegotiatedCipherSuite(caller_options, callee_options,
3050 expected_cipher_suite);
3051}
3052
3053TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
3054 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003055 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003056 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003057 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07003058 int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
3059 TestNegotiatedCipherSuite(caller_options, callee_options,
3060 expected_cipher_suite);
3061}
3062
deadbeef1dcb1642017-03-29 21:08:16 -07003063// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003064TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003065 bool local_gcm_enabled = false;
3066 bool remote_gcm_enabled = false;
3067 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3068 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3069 expected_cipher_suite);
3070}
3071
3072// Test that a GCM cipher is used if both ends support it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003073TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07003074 bool local_gcm_enabled = true;
3075 bool remote_gcm_enabled = true;
3076 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
3077 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3078 expected_cipher_suite);
3079}
3080
3081// Test that GCM isn't used if only the offerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003082TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003083 NonGcmCipherUsedWhenOnlyCallerSupportsGcm) {
3084 bool local_gcm_enabled = true;
3085 bool remote_gcm_enabled = false;
3086 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3087 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3088 expected_cipher_suite);
3089}
3090
3091// Test that GCM isn't used if only the answerer supports it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003092TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003093 NonGcmCipherUsedWhenOnlyCalleeSupportsGcm) {
3094 bool local_gcm_enabled = false;
3095 bool remote_gcm_enabled = true;
3096 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
3097 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
3098 expected_cipher_suite);
3099}
3100
deadbeef7914b8c2017-04-21 03:23:33 -07003101// Verify that media can be transmitted end-to-end when GCM crypto suites are
3102// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
3103// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
3104// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003105TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07003106 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07003107 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
deadbeef7914b8c2017-04-21 03:23:33 -07003108 ASSERT_TRUE(
3109 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
3110 ConnectFakeSignaling();
3111 // Do normal offer/answer and wait for some frames to be received in each
3112 // direction.
Steve Anton15324772018-01-16 10:26:49 -08003113 caller()->AddAudioVideoTracks();
3114 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003115 caller()->CreateAndSetAndSignalOffer();
3116 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003117 MediaExpectations media_expectations;
3118 media_expectations.ExpectBidirectionalAudioAndVideo();
3119 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003120}
3121
deadbeef1dcb1642017-03-29 21:08:16 -07003122// This test sets up a call between two parties with audio, video and an RTP
3123// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003124TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003125 PeerConnectionInterface::RTCConfiguration rtc_config;
3126 rtc_config.enable_rtp_data_channel = true;
3127 rtc_config.enable_dtls_srtp = false;
3128 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003129 ConnectFakeSignaling();
3130 // Expect that data channel created on caller side will show up for callee as
3131 // well.
3132 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003133 caller()->AddAudioVideoTracks();
3134 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003135 caller()->CreateAndSetAndSignalOffer();
3136 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3137 // Ensure the existence of the RTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003138 MediaExpectations media_expectations;
3139 media_expectations.ExpectBidirectionalAudioAndVideo();
3140 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003141 ASSERT_NE(nullptr, caller()->data_channel());
3142 ASSERT_NE(nullptr, callee()->data_channel());
3143 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3144 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3145
3146 // Ensure data can be sent in both directions.
3147 std::string data = "hello world";
3148 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3149 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3150 kDefaultTimeout);
3151 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3152 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3153 kDefaultTimeout);
3154}
3155
3156// Ensure that an RTP data channel is signaled as closed for the caller when
3157// the callee rejects it in a subsequent offer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003158TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003159 RtpDataChannelSignaledClosedInCalleeOffer) {
3160 // Same procedure as above test.
Niels Möllerf06f9232018-08-07 12:32:18 +02003161 PeerConnectionInterface::RTCConfiguration rtc_config;
3162 rtc_config.enable_rtp_data_channel = true;
3163 rtc_config.enable_dtls_srtp = false;
3164 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003165 ConnectFakeSignaling();
3166 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003167 caller()->AddAudioVideoTracks();
3168 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003169 caller()->CreateAndSetAndSignalOffer();
3170 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3171 ASSERT_NE(nullptr, caller()->data_channel());
3172 ASSERT_NE(nullptr, callee()->data_channel());
3173 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3174 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3175
3176 // Close the data channel on the callee, and do an updated offer/answer.
3177 callee()->data_channel()->Close();
3178 callee()->CreateAndSetAndSignalOffer();
3179 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3180 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3181 EXPECT_FALSE(callee()->data_observer()->IsOpen());
3182}
3183
3184// Tests that data is buffered in an RTP data channel until an observer is
3185// registered for it.
3186//
3187// NOTE: RTP data channels can receive data before the underlying
3188// transport has detected that a channel is writable and thus data can be
3189// received before the data channel state changes to open. That is hard to test
3190// but the same buffering is expected to be used in that case.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003191TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07003192 DataBufferedUntilRtpDataChannelObserverRegistered) {
3193 // Use fake clock and simulated network delay so that we predictably can wait
3194 // until an SCTP message has been delivered without "sleep()"ing.
3195 rtc::ScopedFakeClock fake_clock;
3196 // Some things use a time of "0" as a special value, so we need to start out
3197 // the fake clock at a nonzero time.
3198 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02003199 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07003200 virtual_socket_server()->set_delay_mean(5); // 5 ms per hop.
3201 virtual_socket_server()->UpdateDelayDistribution();
3202
Niels Möllerf06f9232018-08-07 12:32:18 +02003203 PeerConnectionInterface::RTCConfiguration rtc_config;
3204 rtc_config.enable_rtp_data_channel = true;
3205 rtc_config.enable_dtls_srtp = false;
3206 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003207 ConnectFakeSignaling();
3208 caller()->CreateDataChannel();
3209 caller()->CreateAndSetAndSignalOffer();
3210 ASSERT_TRUE(caller()->data_channel() != nullptr);
3211 ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr,
3212 kDefaultTimeout, fake_clock);
3213 ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(),
3214 kDefaultTimeout, fake_clock);
3215 ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen,
3216 callee()->data_channel()->state(), kDefaultTimeout,
3217 fake_clock);
3218
3219 // Unregister the observer which is normally automatically registered.
3220 callee()->data_channel()->UnregisterObserver();
3221 // Send data and advance fake clock until it should have been received.
3222 std::string data = "hello world";
3223 caller()->data_channel()->Send(DataBuffer(data));
3224 SIMULATED_WAIT(false, 50, fake_clock);
3225
3226 // Attach data channel and expect data to be received immediately. Note that
3227 // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any
3228 // further, but data can be received even if the callback is asynchronous.
3229 MockDataChannelObserver new_observer(callee()->data_channel());
3230 EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout,
3231 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07003232 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
3233 // If this is not done a DCHECK can be hit in ports.cc, because a large
3234 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07003235 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07003236}
3237
3238// This test sets up a call between two parties with audio, video and but only
3239// the caller client supports RTP data channels.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003240TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003241 PeerConnectionInterface::RTCConfiguration rtc_config_1;
3242 rtc_config_1.enable_rtp_data_channel = true;
deadbeef1dcb1642017-03-29 21:08:16 -07003243 // Must disable DTLS to make negotiation succeed.
Niels Möllerf06f9232018-08-07 12:32:18 +02003244 rtc_config_1.enable_dtls_srtp = false;
3245 PeerConnectionInterface::RTCConfiguration rtc_config_2;
3246 rtc_config_2.enable_dtls_srtp = false;
3247 rtc_config_2.enable_dtls_srtp = false;
3248 ASSERT_TRUE(
3249 CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2));
deadbeef1dcb1642017-03-29 21:08:16 -07003250 ConnectFakeSignaling();
3251 caller()->CreateDataChannel();
Harald Alvestrandf3736ed2019-04-08 13:09:30 +02003252 ASSERT_TRUE(caller()->data_channel() != nullptr);
Steve Anton15324772018-01-16 10:26:49 -08003253 caller()->AddAudioVideoTracks();
3254 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003255 caller()->CreateAndSetAndSignalOffer();
3256 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3257 // The caller should still have a data channel, but it should be closed, and
3258 // one should ever have been created for the callee.
3259 EXPECT_TRUE(caller()->data_channel() != nullptr);
3260 EXPECT_FALSE(caller()->data_observer()->IsOpen());
3261 EXPECT_EQ(nullptr, callee()->data_channel());
3262}
3263
3264// This test sets up a call between two parties with audio, and video. When
3265// audio and video is setup and flowing, an RTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003266TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) {
Niels Möllerf06f9232018-08-07 12:32:18 +02003267 PeerConnectionInterface::RTCConfiguration rtc_config;
3268 rtc_config.enable_rtp_data_channel = true;
3269 rtc_config.enable_dtls_srtp = false;
3270 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config));
deadbeef1dcb1642017-03-29 21:08:16 -07003271 ConnectFakeSignaling();
3272 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003273 caller()->AddAudioVideoTracks();
3274 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003275 caller()->CreateAndSetAndSignalOffer();
3276 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3277 // Create data channel and do new offer and answer.
3278 caller()->CreateDataChannel();
3279 caller()->CreateAndSetAndSignalOffer();
3280 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3281 ASSERT_NE(nullptr, caller()->data_channel());
3282 ASSERT_NE(nullptr, callee()->data_channel());
3283 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3284 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3285 // Ensure data can be sent in both directions.
3286 std::string data = "hello world";
3287 SendRtpDataWithRetries(caller()->data_channel(), data, 5);
3288 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3289 kDefaultTimeout);
3290 SendRtpDataWithRetries(callee()->data_channel(), data, 5);
3291 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3292 kDefaultTimeout);
3293}
3294
3295#ifdef HAVE_SCTP
3296
3297// This test sets up a call between two parties with audio, video and an SCTP
3298// data channel.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003299TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003300 ASSERT_TRUE(CreatePeerConnectionWrappers());
3301 ConnectFakeSignaling();
3302 // Expect that data channel created on caller side will show up for callee as
3303 // well.
3304 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003305 caller()->AddAudioVideoTracks();
3306 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003307 caller()->CreateAndSetAndSignalOffer();
3308 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3309 // Ensure the existence of the SCTP data channel didn't impede audio/video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003310 MediaExpectations media_expectations;
3311 media_expectations.ExpectBidirectionalAudioAndVideo();
3312 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07003313 // Caller data channel should already exist (it created one). Callee data
3314 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3315 ASSERT_NE(nullptr, caller()->data_channel());
3316 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3317 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3318 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3319
3320 // Ensure data can be sent in both directions.
3321 std::string data = "hello world";
3322 caller()->data_channel()->Send(DataBuffer(data));
3323 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3324 kDefaultTimeout);
3325 callee()->data_channel()->Send(DataBuffer(data));
3326 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3327 kDefaultTimeout);
3328}
3329
3330// Ensure that when the callee closes an SCTP data channel, the closing
3331// procedure results in the data channel being closed for the caller as well.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003332TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003333 // Same procedure as above test.
3334 ASSERT_TRUE(CreatePeerConnectionWrappers());
3335 ConnectFakeSignaling();
3336 caller()->CreateDataChannel();
Steve Anton15324772018-01-16 10:26:49 -08003337 caller()->AddAudioVideoTracks();
3338 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003339 caller()->CreateAndSetAndSignalOffer();
3340 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3341 ASSERT_NE(nullptr, caller()->data_channel());
3342 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3343 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3344 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3345
3346 // Close the data channel on the callee side, and wait for it to reach the
3347 // "closed" state on both sides.
3348 callee()->data_channel()->Close();
3349 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3350 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3351}
3352
Seth Hampson2f0d7022018-02-20 11:54:42 -08003353TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
Steve Antonda6c0952017-10-23 11:41:54 -07003354 ASSERT_TRUE(CreatePeerConnectionWrappers());
3355 ConnectFakeSignaling();
3356 webrtc::DataChannelInit init;
3357 init.id = 53;
3358 init.maxRetransmits = 52;
3359 caller()->CreateDataChannel("data-channel", &init);
Steve Anton15324772018-01-16 10:26:49 -08003360 caller()->AddAudioVideoTracks();
3361 callee()->AddAudioVideoTracks();
Steve Antonda6c0952017-10-23 11:41:54 -07003362 caller()->CreateAndSetAndSignalOffer();
3363 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton074dece2017-10-24 13:04:12 -07003364 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3365 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Harald Alvestrand5c4d2ee2019-04-01 12:58:15 +02003366 // Since "negotiated" is false, the "id" parameter should be ignored.
3367 EXPECT_NE(init.id, callee()->data_channel()->id());
Steve Antonda6c0952017-10-23 11:41:54 -07003368 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3369 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3370 EXPECT_FALSE(callee()->data_channel()->negotiated());
3371}
3372
deadbeef1dcb1642017-03-29 21:08:16 -07003373// Test usrsctp's ability to process unordered data stream, where data actually
3374// arrives out of order using simulated delays. Previously there have been some
3375// bugs in this area.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003376TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) {
deadbeef1dcb1642017-03-29 21:08:16 -07003377 // Introduce random network delays.
3378 // Otherwise it's not a true "unordered" test.
3379 virtual_socket_server()->set_delay_mean(20);
3380 virtual_socket_server()->set_delay_stddev(5);
3381 virtual_socket_server()->UpdateDelayDistribution();
3382 // Normal procedure, but with unordered data channel config.
3383 ASSERT_TRUE(CreatePeerConnectionWrappers());
3384 ConnectFakeSignaling();
3385 webrtc::DataChannelInit init;
3386 init.ordered = false;
3387 caller()->CreateDataChannel(&init);
3388 caller()->CreateAndSetAndSignalOffer();
3389 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3390 ASSERT_NE(nullptr, caller()->data_channel());
3391 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3392 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3393 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3394
3395 static constexpr int kNumMessages = 100;
3396 // Deliberately chosen to be larger than the MTU so messages get fragmented.
3397 static constexpr size_t kMaxMessageSize = 4096;
3398 // Create and send random messages.
3399 std::vector<std::string> sent_messages;
3400 for (int i = 0; i < kNumMessages; ++i) {
3401 size_t length =
3402 (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand)
3403 std::string message;
3404 ASSERT_TRUE(rtc::CreateRandomString(length, &message));
3405 caller()->data_channel()->Send(DataBuffer(message));
3406 callee()->data_channel()->Send(DataBuffer(message));
3407 sent_messages.push_back(message);
3408 }
3409
3410 // Wait for all messages to be received.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003411 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003412 caller()->data_observer()->received_message_count(),
3413 kDefaultTimeout);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02003414 EXPECT_EQ_WAIT(rtc::checked_cast<size_t>(kNumMessages),
deadbeef1dcb1642017-03-29 21:08:16 -07003415 callee()->data_observer()->received_message_count(),
3416 kDefaultTimeout);
3417
3418 // Sort and compare to make sure none of the messages were corrupted.
3419 std::vector<std::string> caller_received_messages =
3420 caller()->data_observer()->messages();
3421 std::vector<std::string> callee_received_messages =
3422 callee()->data_observer()->messages();
Steve Anton64b626b2019-01-28 17:25:26 -08003423 absl::c_sort(sent_messages);
3424 absl::c_sort(caller_received_messages);
3425 absl::c_sort(callee_received_messages);
deadbeef1dcb1642017-03-29 21:08:16 -07003426 EXPECT_EQ(sent_messages, caller_received_messages);
3427 EXPECT_EQ(sent_messages, callee_received_messages);
3428}
3429
3430// This test sets up a call between two parties with audio, and video. When
3431// audio and video are setup and flowing, an SCTP data channel is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003432TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -07003433 ASSERT_TRUE(CreatePeerConnectionWrappers());
3434 ConnectFakeSignaling();
3435 // Do initial offer/answer with audio/video.
Steve Anton15324772018-01-16 10:26:49 -08003436 caller()->AddAudioVideoTracks();
3437 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003438 caller()->CreateAndSetAndSignalOffer();
3439 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3440 // Create data channel and do new offer and answer.
3441 caller()->CreateDataChannel();
3442 caller()->CreateAndSetAndSignalOffer();
3443 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3444 // Caller data channel should already exist (it created one). Callee data
3445 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3446 ASSERT_NE(nullptr, caller()->data_channel());
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 // Ensure data can be sent in both directions.
3451 std::string data = "hello world";
3452 caller()->data_channel()->Send(DataBuffer(data));
3453 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3454 kDefaultTimeout);
3455 callee()->data_channel()->Send(DataBuffer(data));
3456 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3457 kDefaultTimeout);
3458}
3459
deadbeef7914b8c2017-04-21 03:23:33 -07003460// Set up a connection initially just using SCTP data channels, later upgrading
3461// to audio/video, ensuring frames are received end-to-end. Effectively the
3462// inverse of the test above.
3463// This was broken in M57; see https://crbug.com/711243
Seth Hampson2f0d7022018-02-20 11:54:42 -08003464TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
deadbeef7914b8c2017-04-21 03:23:33 -07003465 ASSERT_TRUE(CreatePeerConnectionWrappers());
3466 ConnectFakeSignaling();
3467 // Do initial offer/answer with just data channel.
3468 caller()->CreateDataChannel();
3469 caller()->CreateAndSetAndSignalOffer();
3470 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3471 // Wait until data can be sent over the data channel.
3472 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3473 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3474 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3475
3476 // Do subsequent offer/answer with two-way audio and video. Audio and video
3477 // should end up bundled on the DTLS/ICE transport already used for data.
Steve Anton15324772018-01-16 10:26:49 -08003478 caller()->AddAudioVideoTracks();
3479 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07003480 caller()->CreateAndSetAndSignalOffer();
3481 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003482 MediaExpectations media_expectations;
3483 media_expectations.ExpectBidirectionalAudioAndVideo();
3484 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07003485}
3486
deadbeef8b7e9ad2017-05-25 09:38:55 -07003487static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +02003488 cricket::SctpDataContentDescription* dcd_offer =
3489 GetFirstSctpDataContentDescription(desc);
Steve Antonb1c1de12017-12-21 15:14:30 -08003490 ASSERT_TRUE(dcd_offer);
deadbeef8b7e9ad2017-05-25 09:38:55 -07003491 dcd_offer->set_use_sctpmap(false);
3492 dcd_offer->set_protocol("UDP/DTLS/SCTP");
3493}
3494
3495// Test that the data channel works when a spec-compliant SCTP m= section is
3496// offered (using "a=sctp-port" instead of "a=sctpmap", and using
3497// "UDP/DTLS/SCTP" as the protocol).
Seth Hampson2f0d7022018-02-20 11:54:42 -08003498TEST_P(PeerConnectionIntegrationTest,
deadbeef8b7e9ad2017-05-25 09:38:55 -07003499 DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
3500 ASSERT_TRUE(CreatePeerConnectionWrappers());
3501 ConnectFakeSignaling();
3502 caller()->CreateDataChannel();
3503 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
3504 caller()->CreateAndSetAndSignalOffer();
3505 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3506 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3507 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3508 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3509
3510 // Ensure data can be sent in both directions.
3511 std::string data = "hello world";
3512 caller()->data_channel()->Send(DataBuffer(data));
3513 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3514 kDefaultTimeout);
3515 callee()->data_channel()->Send(DataBuffer(data));
3516 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3517 kDefaultTimeout);
3518}
3519
deadbeef1dcb1642017-03-29 21:08:16 -07003520#endif // HAVE_SCTP
3521
Bjorn Mellema2eb0a72018-11-09 10:13:51 -08003522// This test sets up a call between two parties with a media transport data
3523// channel.
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08003524TEST_P(PeerConnectionIntegrationTest, MediaTransportDataChannelEndToEnd) {
3525 PeerConnectionInterface::RTCConfiguration rtc_config;
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -08003526 rtc_config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3527 rtc_config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08003528 rtc_config.use_media_transport_for_data_channels = true;
3529 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3530 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3531 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3532 loopback_media_transports()->second_factory()));
3533 ConnectFakeSignaling();
3534
3535 // Expect that data channel created on caller side will show up for callee as
3536 // well.
3537 caller()->CreateDataChannel();
3538 caller()->CreateAndSetAndSignalOffer();
3539 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3540
3541 // Ensure that the media transport is ready.
3542 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3543 loopback_media_transports()->FlushAsyncInvokes();
3544
3545 // Caller data channel should already exist (it created one). Callee data
3546 // channel may not exist yet, since negotiation happens in-band, not in SDP.
3547 ASSERT_NE(nullptr, caller()->data_channel());
3548 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3549 EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3550 EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3551
3552 // Ensure data can be sent in both directions.
3553 std::string data = "hello world";
3554 caller()->data_channel()->Send(DataBuffer(data));
3555 EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(),
3556 kDefaultTimeout);
3557 callee()->data_channel()->Send(DataBuffer(data));
3558 EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(),
3559 kDefaultTimeout);
3560}
3561
3562// Ensure that when the callee closes a media transport data channel, the
3563// closing procedure results in the data channel being closed for the caller
3564// as well.
3565TEST_P(PeerConnectionIntegrationTest, MediaTransportDataChannelCalleeCloses) {
3566 PeerConnectionInterface::RTCConfiguration rtc_config;
3567 rtc_config.use_media_transport_for_data_channels = true;
3568 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3569 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3570 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3571 loopback_media_transports()->second_factory()));
3572 ConnectFakeSignaling();
3573
3574 // Create a data channel on the caller and signal it to the callee.
3575 caller()->CreateDataChannel();
3576 caller()->CreateAndSetAndSignalOffer();
3577 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3578
3579 // Ensure that the media transport is ready.
3580 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3581 loopback_media_transports()->FlushAsyncInvokes();
3582
3583 // Data channels exist and open on both ends of the connection.
3584 ASSERT_NE(nullptr, caller()->data_channel());
3585 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3586 ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout);
3587 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
3588
3589 // Close the data channel on the callee side, and wait for it to reach the
3590 // "closed" state on both sides.
3591 callee()->data_channel()->Close();
3592 EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout);
3593 EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout);
3594}
3595
3596TEST_P(PeerConnectionIntegrationTest,
3597 MediaTransportDataChannelConfigSentToOtherSide) {
3598 PeerConnectionInterface::RTCConfiguration rtc_config;
3599 rtc_config.use_media_transport_for_data_channels = true;
3600 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3601 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3602 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3603 loopback_media_transports()->second_factory()));
3604 ConnectFakeSignaling();
3605
3606 // Create a data channel with a non-default configuration and signal it to the
3607 // callee.
3608 webrtc::DataChannelInit init;
3609 init.id = 53;
3610 init.maxRetransmits = 52;
3611 caller()->CreateDataChannel("data-channel", &init);
3612 caller()->CreateAndSetAndSignalOffer();
3613 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3614
3615 // Ensure that the media transport is ready.
3616 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3617 loopback_media_transports()->FlushAsyncInvokes();
3618
3619 // Ensure that the data channel exists on the callee with the correct
3620 // configuration.
3621 ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout);
3622 ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout);
Harald Alvestrand5c4d2ee2019-04-01 12:58:15 +02003623 // Since "negotiate" is false, the "id" parameter is ignored.
3624 EXPECT_NE(init.id, callee()->data_channel()->id());
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08003625 EXPECT_EQ("data-channel", callee()->data_channel()->label());
3626 EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits());
3627 EXPECT_FALSE(callee()->data_channel()->negotiated());
3628}
3629
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -08003630TEST_P(PeerConnectionIntegrationTest, MediaTransportOfferUpgrade) {
3631 PeerConnectionInterface::RTCConfiguration rtc_config;
3632 rtc_config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3633 rtc_config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3634 rtc_config.use_media_transport = true;
3635 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3636 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3637 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3638 loopback_media_transports()->second_factory()));
3639 ConnectFakeSignaling();
3640
3641 // Do initial offer/answer with just a video track.
3642 caller()->AddVideoTrack();
3643 callee()->AddVideoTrack();
3644 caller()->CreateAndSetAndSignalOffer();
3645 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3646
3647 // Ensure that the media transport is ready.
3648 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3649 loopback_media_transports()->FlushAsyncInvokes();
3650
3651 // Now add an audio track and do another offer/answer.
3652 caller()->AddAudioTrack();
3653 callee()->AddAudioTrack();
3654 caller()->CreateAndSetAndSignalOffer();
3655 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3656
3657 // Ensure both audio and video frames are received end-to-end.
3658 MediaExpectations media_expectations;
3659 media_expectations.ExpectBidirectionalAudioAndVideo();
3660 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3661
3662 // The second offer should not have generated another media transport.
3663 // Media transport was kept alive, and was not recreated.
3664 EXPECT_EQ(1, loopback_media_transports()->first_factory_transport_count());
3665 EXPECT_EQ(1, loopback_media_transports()->second_factory_transport_count());
3666}
3667
3668TEST_P(PeerConnectionIntegrationTest, MediaTransportOfferUpgradeOnTheCallee) {
3669 PeerConnectionInterface::RTCConfiguration rtc_config;
3670 rtc_config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3671 rtc_config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3672 rtc_config.use_media_transport = true;
3673 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3674 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3675 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3676 loopback_media_transports()->second_factory()));
3677 ConnectFakeSignaling();
3678
3679 // Do initial offer/answer with just a video track.
3680 caller()->AddVideoTrack();
3681 callee()->AddVideoTrack();
3682 caller()->CreateAndSetAndSignalOffer();
3683 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3684
3685 // Ensure that the media transport is ready.
3686 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3687 loopback_media_transports()->FlushAsyncInvokes();
3688
3689 // Now add an audio track and do another offer/answer.
3690 caller()->AddAudioTrack();
3691 callee()->AddAudioTrack();
3692 callee()->CreateAndSetAndSignalOffer();
3693 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3694
3695 // Ensure both audio and video frames are received end-to-end.
3696 MediaExpectations media_expectations;
3697 media_expectations.ExpectBidirectionalAudioAndVideo();
3698 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3699
3700 // The second offer should not have generated another media transport.
3701 // Media transport was kept alive, and was not recreated.
3702 EXPECT_EQ(1, loopback_media_transports()->first_factory_transport_count());
3703 EXPECT_EQ(1, loopback_media_transports()->second_factory_transport_count());
3704}
3705
Niels Möllerc68d2822018-11-20 14:52:05 +01003706TEST_P(PeerConnectionIntegrationTest, MediaTransportBidirectionalAudio) {
3707 PeerConnectionInterface::RTCConfiguration rtc_config;
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -08003708 rtc_config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3709 rtc_config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
Niels Möllerc68d2822018-11-20 14:52:05 +01003710 rtc_config.use_media_transport = true;
3711 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3712 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3713 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3714 loopback_media_transports()->second_factory()));
3715 ConnectFakeSignaling();
3716
3717 caller()->AddAudioTrack();
3718 callee()->AddAudioTrack();
3719 // Start offer/answer exchange and wait for it to complete.
3720 caller()->CreateAndSetAndSignalOffer();
3721 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3722
3723 // Ensure that the media transport is ready.
3724 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3725 loopback_media_transports()->FlushAsyncInvokes();
3726
3727 MediaExpectations media_expectations;
3728 media_expectations.ExpectBidirectionalAudio();
3729 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3730
3731 webrtc::MediaTransportPair::Stats first_stats =
3732 loopback_media_transports()->FirstStats();
3733 webrtc::MediaTransportPair::Stats second_stats =
3734 loopback_media_transports()->SecondStats();
3735
3736 EXPECT_GT(first_stats.received_audio_frames, 0);
3737 EXPECT_GE(second_stats.sent_audio_frames, first_stats.received_audio_frames);
3738
3739 EXPECT_GT(second_stats.received_audio_frames, 0);
3740 EXPECT_GE(first_stats.sent_audio_frames, second_stats.received_audio_frames);
3741}
3742
Niels Möller46879152019-01-07 15:54:47 +01003743TEST_P(PeerConnectionIntegrationTest, MediaTransportBidirectionalVideo) {
3744 PeerConnectionInterface::RTCConfiguration rtc_config;
3745 rtc_config.use_media_transport = true;
3746 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3747 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3748 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3749 loopback_media_transports()->second_factory()));
3750 ConnectFakeSignaling();
3751
3752 caller()->AddVideoTrack();
3753 callee()->AddVideoTrack();
3754 // Start offer/answer exchange and wait for it to complete.
3755 caller()->CreateAndSetAndSignalOffer();
3756 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3757
3758 // Ensure that the media transport is ready.
3759 loopback_media_transports()->SetState(webrtc::MediaTransportState::kWritable);
3760 loopback_media_transports()->FlushAsyncInvokes();
3761
3762 MediaExpectations media_expectations;
3763 media_expectations.ExpectBidirectionalVideo();
3764 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3765
3766 webrtc::MediaTransportPair::Stats first_stats =
3767 loopback_media_transports()->FirstStats();
3768 webrtc::MediaTransportPair::Stats second_stats =
3769 loopback_media_transports()->SecondStats();
3770
3771 EXPECT_GT(first_stats.received_video_frames, 0);
3772 EXPECT_GE(second_stats.sent_video_frames, first_stats.received_video_frames);
3773
3774 EXPECT_GT(second_stats.received_video_frames, 0);
3775 EXPECT_GE(first_stats.sent_video_frames, second_stats.received_video_frames);
3776}
3777
Piotr (Peter) Slatala55b91b92019-01-25 13:31:15 -08003778TEST_P(PeerConnectionIntegrationTest,
3779 MediaTransportDataChannelUsesRtpBidirectionalVideo) {
3780 PeerConnectionInterface::RTCConfiguration rtc_config;
3781 rtc_config.use_media_transport = false;
3782 rtc_config.use_media_transport_for_data_channels = true;
3783 rtc_config.enable_dtls_srtp = false; // SDES is required for media transport.
3784 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndMediaTransportFactory(
3785 rtc_config, rtc_config, loopback_media_transports()->first_factory(),
3786 loopback_media_transports()->second_factory()));
3787 ConnectFakeSignaling();
3788
3789 caller()->AddVideoTrack();
3790 callee()->AddVideoTrack();
3791 // Start offer/answer exchange and wait for it to complete.
3792 caller()->CreateAndSetAndSignalOffer();
3793 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3794
3795 MediaExpectations media_expectations;
3796 media_expectations.ExpectBidirectionalVideo();
3797 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3798}
3799
deadbeef1dcb1642017-03-29 21:08:16 -07003800// Test that the ICE connection and gathering states eventually reach
3801// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08003802TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07003803 ASSERT_TRUE(CreatePeerConnectionWrappers());
3804 ConnectFakeSignaling();
3805 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08003806 caller()->AddAudioVideoTracks();
3807 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07003808 caller()->CreateAndSetAndSignalOffer();
3809 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3810 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3811 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
3812 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
3813 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
3814 // After the best candidate pair is selected and all candidates are signaled,
3815 // the ICE connection state should reach "complete".
3816 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
3817 // answerer/"callee" by default) only reaches "connected". When this is
3818 // fixed, this test should be updated.
3819 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3820 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00003821 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3822 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07003823}
3824
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003825constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
3826 cricket::PORTALLOCATOR_DISABLE_RELAY |
3827 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003828
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003829// Use a mock resolver to resolve the hostname back to the original IP on both
3830// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003831TEST_P(PeerConnectionIntegrationTest,
3832 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003833 auto caller_resolver_factory =
3834 absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
3835 auto callee_resolver_factory =
3836 absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
3837 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
3838 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003839
3840 // This also verifies that the injected AsyncResolverFactory is used by
3841 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003842 EXPECT_CALL(*caller_resolver_factory, Create())
3843 .WillOnce(Return(&caller_async_resolver));
3844 webrtc::PeerConnectionDependencies caller_deps(nullptr);
3845 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
3846
3847 EXPECT_CALL(*callee_resolver_factory, Create())
3848 .WillOnce(Return(&callee_async_resolver));
3849 webrtc::PeerConnectionDependencies callee_deps(nullptr);
3850 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
3851
3852 PeerConnectionInterface::RTCConfiguration config;
3853 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3854 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
3855
3856 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
3857 config, std::move(caller_deps), config, std::move(callee_deps)));
3858
3859 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
3860 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
3861
3862 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07003863 caller()->SetMdnsResponder(
3864 absl::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
3865 callee()->SetMdnsResponder(
3866 absl::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003867
3868 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003869
3870 ConnectFakeSignaling();
3871 caller()->AddAudioVideoTracks();
3872 callee()->AddAudioVideoTracks();
3873 caller()->CreateAndSetAndSignalOffer();
3874 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3875 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
3876 caller()->ice_connection_state(), kDefaultTimeout);
3877 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3878 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08003879
3880 EXPECT_EQ(1, webrtc::metrics::NumEvents(
3881 "WebRTC.PeerConnection.CandidatePairType_UDP",
3882 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07003883}
3884
Steve Antonede9ca52017-10-16 13:04:27 -07003885// Test that firewalling the ICE connection causes the clients to identify the
3886// disconnected state and then removing the firewall causes them to reconnect.
3887class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003888 : public PeerConnectionIntegrationBaseTest,
3889 public ::testing::WithParamInterface<
3890 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07003891 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003892 PeerConnectionIntegrationIceStatesTest()
3893 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
3894 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07003895 }
3896
3897 void StartStunServer(const SocketAddress& server_address) {
3898 stun_server_.reset(
3899 cricket::TestStunServer::Create(network_thread(), server_address));
3900 }
3901
3902 bool TestIPv6() {
3903 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
3904 }
3905
3906 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08003907 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
3908 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07003909 }
3910
3911 std::vector<SocketAddress> CallerAddresses() {
3912 std::vector<SocketAddress> addresses;
3913 addresses.push_back(SocketAddress("1.1.1.1", 0));
3914 if (TestIPv6()) {
3915 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
3916 }
3917 return addresses;
3918 }
3919
3920 std::vector<SocketAddress> CalleeAddresses() {
3921 std::vector<SocketAddress> addresses;
3922 addresses.push_back(SocketAddress("2.2.2.2", 0));
3923 if (TestIPv6()) {
3924 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
3925 }
3926 return addresses;
3927 }
3928
3929 void SetUpNetworkInterfaces() {
3930 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07003931 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
3932 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07003933
3934 // Add network addresses for test.
3935 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07003936 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07003937 }
3938 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07003939 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07003940 }
3941 }
3942
3943 private:
3944 uint32_t port_allocator_flags_;
3945 std::unique_ptr<cricket::TestStunServer> stun_server_;
3946};
3947
3948// Tests that the PeerConnection goes through all the ICE gathering/connection
3949// states over the duration of the call. This includes Disconnected and Failed
3950// states, induced by putting a firewall between the peers and waiting for them
3951// to time out.
Steve Anton83119dd2017-11-10 16:19:52 -08003952TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01003953 rtc::ScopedFakeClock fake_clock;
3954 // Some things use a time of "0" as a special value, so we need to start out
3955 // the fake clock at a nonzero time.
3956 fake_clock.AdvanceTime(TimeDelta::seconds(1));
Steve Antonede9ca52017-10-16 13:04:27 -07003957
3958 const SocketAddress kStunServerAddress =
3959 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
3960 StartStunServer(kStunServerAddress);
3961
3962 PeerConnectionInterface::RTCConfiguration config;
3963 PeerConnectionInterface::IceServer ice_stun_server;
3964 ice_stun_server.urls.push_back(
3965 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
3966 kStunServerAddress.PortAsString());
3967 config.servers.push_back(ice_stun_server);
3968
3969 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3970 ConnectFakeSignaling();
3971 SetPortAllocatorFlags();
3972 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08003973 caller()->AddAudioVideoTracks();
3974 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003975
3976 // Initial state before anything happens.
3977 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
3978 caller()->ice_gathering_state());
3979 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3980 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003981 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
3982 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07003983
3984 // Start the call by creating the offer, setting it as the local description,
3985 // then sending it to the peer who will respond with an answer. This happens
3986 // asynchronously so that we can watch the states as it runs in the
3987 // background.
3988 caller()->CreateAndSetAndSignalOffer();
3989
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003990 ASSERT_EQ(PeerConnectionInterface::kIceConnectionCompleted,
3991 caller()->ice_connection_state());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01003992 ASSERT_EQ(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olsson7a6739e2019-01-15 16:31:55 +01003993 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07003994
3995 // Verify that the observer was notified of the intermediate transitions.
3996 EXPECT_THAT(caller()->ice_connection_state_history(),
3997 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
3998 PeerConnectionInterface::kIceConnectionConnected,
3999 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004000 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
4001 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
4002 PeerConnectionInterface::kIceConnectionConnected,
4003 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02004004 EXPECT_THAT(
4005 caller()->peer_connection_state_history(),
4006 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02004007 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07004008 EXPECT_THAT(caller()->ice_gathering_state_history(),
4009 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
4010 PeerConnectionInterface::kIceGatheringComplete));
4011
4012 // Block connections to/from the caller and wait for ICE to become
4013 // disconnected.
4014 for (const auto& caller_address : CallerAddresses()) {
4015 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4016 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004017 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004018 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4019 caller()->ice_connection_state(), kDefaultTimeout,
4020 fake_clock);
4021 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
4022 caller()->standardized_ice_connection_state(),
4023 kDefaultTimeout, fake_clock);
Steve Antonede9ca52017-10-16 13:04:27 -07004024
4025 // Let ICE re-establish by removing the firewall rules.
4026 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01004027 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004028 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4029 caller()->ice_connection_state(), kDefaultTimeout,
4030 fake_clock);
Jonas Olssonacd8ae72019-02-25 15:26:24 +01004031 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004032 caller()->standardized_ice_connection_state(),
4033 kDefaultTimeout, fake_clock);
Steve Antonede9ca52017-10-16 13:04:27 -07004034
4035 // According to RFC7675, if there is no response within 30 seconds then the
4036 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08004037 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07004038 constexpr int kConsentTimeout = 30000;
4039 for (const auto& caller_address : CallerAddresses()) {
4040 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4041 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01004042 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01004043 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4044 caller()->ice_connection_state(), kConsentTimeout,
4045 fake_clock);
4046 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4047 caller()->standardized_ice_connection_state(),
4048 kConsentTimeout, fake_clock);
4049
4050 // We need to manually close the peerconnections before the fake clock goes
4051 // out of scope, or we trigger a DCHECK in rtp_sender.cc when we briefly
4052 // return to using non-faked time.
4053 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
4054 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
4055}
4056
4057// Tests that if the connection doesn't get set up properly we eventually reach
4058// the "failed" iceConnectionState.
4059TEST_P(PeerConnectionIntegrationIceStatesTest, IceStateSetupFailure) {
4060 rtc::ScopedFakeClock fake_clock;
4061 // Some things use a time of "0" as a special value, so we need to start out
4062 // the fake clock at a nonzero time.
4063 fake_clock.AdvanceTime(TimeDelta::seconds(1));
4064
4065 // Block connections to/from the caller and wait for ICE to become
4066 // disconnected.
4067 for (const auto& caller_address : CallerAddresses()) {
4068 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
4069 }
4070
4071 ASSERT_TRUE(CreatePeerConnectionWrappers());
4072 ConnectFakeSignaling();
4073 SetPortAllocatorFlags();
4074 SetUpNetworkInterfaces();
4075 caller()->AddAudioVideoTracks();
4076 caller()->CreateAndSetAndSignalOffer();
4077
4078 // According to RFC7675, if there is no response within 30 seconds then the
4079 // peer should consider the other side to have rejected the connection. This
4080 // is signaled by the state transitioning to "failed".
4081 constexpr int kConsentTimeout = 30000;
4082 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
4083 caller()->standardized_ice_connection_state(),
4084 kConsentTimeout, fake_clock);
4085
4086 // We need to manually close the peerconnections before the fake clock goes
4087 // out of scope, or we trigger a DCHECK in rtp_sender.cc when we briefly
4088 // return to using non-faked time.
4089 delete SetCallerPcWrapperAndReturnCurrent(nullptr);
4090 delete SetCalleePcWrapperAndReturnCurrent(nullptr);
Steve Antonede9ca52017-10-16 13:04:27 -07004091}
4092
4093// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
4094// and that the statistics in the metric observers are updated correctly.
4095TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) {
4096 ASSERT_TRUE(CreatePeerConnectionWrappers());
4097 ConnectFakeSignaling();
4098 SetPortAllocatorFlags();
4099 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08004100 caller()->AddAudioVideoTracks();
4101 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004102 caller()->CreateAndSetAndSignalOffer();
4103
4104 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4105
Qingsi Wang7fc821d2018-07-12 12:54:53 -07004106 // TODO(bugs.webrtc.org/9456): Fix it.
4107 const int num_best_ipv4 = webrtc::metrics::NumEvents(
4108 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
4109 const int num_best_ipv6 = webrtc::metrics::NumEvents(
4110 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004111 if (TestIPv6()) {
4112 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
4113 // connection.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004114 EXPECT_EQ(0, num_best_ipv4);
4115 EXPECT_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004116 } else {
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004117 EXPECT_EQ(1, num_best_ipv4);
4118 EXPECT_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07004119 }
4120
Qingsi Wang7fc821d2018-07-12 12:54:53 -07004121 EXPECT_EQ(0, webrtc::metrics::NumEvents(
4122 "WebRTC.PeerConnection.CandidatePairType_UDP",
4123 webrtc::kIceCandidatePairHostHost));
4124 EXPECT_EQ(1, webrtc::metrics::NumEvents(
4125 "WebRTC.PeerConnection.CandidatePairType_UDP",
4126 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07004127}
4128
4129constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
4130 cricket::PORTALLOCATOR_DISABLE_STUN |
4131 cricket::PORTALLOCATOR_DISABLE_RELAY;
4132constexpr uint32_t kFlagsIPv6NoStun =
4133 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
4134 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
4135constexpr uint32_t kFlagsIPv4Stun =
4136 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
4137
Mirko Bonadeic84f6612019-01-31 12:20:57 +01004138INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08004139 PeerConnectionIntegrationTest,
4140 PeerConnectionIntegrationIceStatesTest,
4141 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
4142 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
4143 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
4144 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07004145
deadbeef1dcb1642017-03-29 21:08:16 -07004146// This test sets up a call between two parties with audio and video.
4147// During the call, the caller restarts ICE and the test verifies that
4148// new ICE candidates are generated and audio and video still can flow, and the
4149// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004150TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07004151 ASSERT_TRUE(CreatePeerConnectionWrappers());
4152 ConnectFakeSignaling();
4153 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08004154 caller()->AddAudioVideoTracks();
4155 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004156 caller()->CreateAndSetAndSignalOffer();
4157 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4158 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4159 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004160 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4161 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07004162
4163 // To verify that the ICE restart actually occurs, get
4164 // ufrag/password/candidates before and after restart.
4165 // Create an SDP string of the first audio candidate for both clients.
4166 const webrtc::IceCandidateCollection* audio_candidates_caller =
4167 caller()->pc()->local_description()->candidates(0);
4168 const webrtc::IceCandidateCollection* audio_candidates_callee =
4169 callee()->pc()->local_description()->candidates(0);
4170 ASSERT_GT(audio_candidates_caller->count(), 0u);
4171 ASSERT_GT(audio_candidates_callee->count(), 0u);
4172 std::string caller_candidate_pre_restart;
4173 ASSERT_TRUE(
4174 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
4175 std::string callee_candidate_pre_restart;
4176 ASSERT_TRUE(
4177 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
4178 const cricket::SessionDescription* desc =
4179 caller()->pc()->local_description()->description();
4180 std::string caller_ufrag_pre_restart =
4181 desc->transport_infos()[0].description.ice_ufrag;
4182 desc = callee()->pc()->local_description()->description();
4183 std::string callee_ufrag_pre_restart =
4184 desc->transport_infos()[0].description.ice_ufrag;
4185
4186 // Have the caller initiate an ICE restart.
4187 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
4188 caller()->CreateAndSetAndSignalOffer();
4189 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4190 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4191 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00004192 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07004193 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4194
4195 // Grab the ufrags/candidates again.
4196 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
4197 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
4198 ASSERT_GT(audio_candidates_caller->count(), 0u);
4199 ASSERT_GT(audio_candidates_callee->count(), 0u);
4200 std::string caller_candidate_post_restart;
4201 ASSERT_TRUE(
4202 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
4203 std::string callee_candidate_post_restart;
4204 ASSERT_TRUE(
4205 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
4206 desc = caller()->pc()->local_description()->description();
4207 std::string caller_ufrag_post_restart =
4208 desc->transport_infos()[0].description.ice_ufrag;
4209 desc = callee()->pc()->local_description()->description();
4210 std::string callee_ufrag_post_restart =
4211 desc->transport_infos()[0].description.ice_ufrag;
4212 // Sanity check that an ICE restart was actually negotiated in SDP.
4213 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
4214 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
4215 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
4216 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
4217
4218 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004219 MediaExpectations media_expectations;
4220 media_expectations.ExpectBidirectionalAudioAndVideo();
4221 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004222}
4223
4224// Verify that audio/video can be received end-to-end when ICE renomination is
4225// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004226TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07004227 PeerConnectionInterface::RTCConfiguration config;
4228 config.enable_ice_renomination = true;
4229 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
4230 ConnectFakeSignaling();
4231 // Do normal offer/answer and wait for some frames to be received in each
4232 // direction.
Steve Anton15324772018-01-16 10:26:49 -08004233 caller()->AddAudioVideoTracks();
4234 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004235 caller()->CreateAndSetAndSignalOffer();
4236 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4237 // Sanity check that ICE renomination was actually negotiated.
4238 const cricket::SessionDescription* desc =
4239 caller()->pc()->local_description()->description();
4240 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004241 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004242 }
4243 desc = callee()->pc()->local_description()->description();
4244 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08004245 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07004246 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08004247 MediaExpectations media_expectations;
4248 media_expectations.ExpectBidirectionalAudioAndVideo();
4249 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004250}
4251
Steve Anton6f25b092017-10-23 09:39:20 -07004252// With a max bundle policy and RTCP muxing, adding a new media description to
4253// the connection should not affect ICE at all because the new media will use
4254// the existing connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004255TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08004256 AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07004257 PeerConnectionInterface::RTCConfiguration config;
4258 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
4259 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
4260 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
4261 config, PeerConnectionInterface::RTCConfiguration()));
4262 ConnectFakeSignaling();
4263
Steve Anton15324772018-01-16 10:26:49 -08004264 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004265 caller()->CreateAndSetAndSignalOffer();
4266 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07004267 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
4268 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07004269
4270 caller()->clear_ice_connection_state_history();
4271
Steve Anton15324772018-01-16 10:26:49 -08004272 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07004273 caller()->CreateAndSetAndSignalOffer();
4274 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4275
4276 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
4277}
4278
deadbeef1dcb1642017-03-29 21:08:16 -07004279// This test sets up a call between two parties with audio and video. It then
4280// renegotiates setting the video m-line to "port 0", then later renegotiates
4281// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004282TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07004283 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
4284 ASSERT_TRUE(CreatePeerConnectionWrappers());
4285 ConnectFakeSignaling();
4286
4287 // Do initial negotiation, only sending media from the caller. Will result in
4288 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08004289 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07004290 caller()->CreateAndSetAndSignalOffer();
4291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4292
4293 // Negotiate again, disabling the video "m=" section (the callee will set the
4294 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08004295 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4296 PeerConnectionInterface::RTCOfferAnswerOptions options;
4297 options.offer_to_receive_video = 0;
4298 callee()->SetOfferAnswerOptions(options);
4299 } else {
4300 callee()->SetRemoteOfferHandler([this] {
4301 callee()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->Stop();
4302 });
4303 }
deadbeef1dcb1642017-03-29 21:08:16 -07004304 caller()->CreateAndSetAndSignalOffer();
4305 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4306 // Sanity check that video "m=" section was actually rejected.
4307 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
4308 callee()->pc()->local_description()->description());
4309 ASSERT_NE(nullptr, answer_video_content);
4310 ASSERT_TRUE(answer_video_content->rejected);
4311
4312 // Enable video and do negotiation again, making sure video is received
4313 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004314 if (sdp_semantics_ == SdpSemantics::kPlanB) {
4315 PeerConnectionInterface::RTCOfferAnswerOptions options;
4316 options.offer_to_receive_video = 1;
4317 callee()->SetOfferAnswerOptions(options);
4318 } else {
4319 // The caller's transceiver is stopped, so we need to add another track.
4320 auto caller_transceiver =
4321 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
4322 EXPECT_TRUE(caller_transceiver->stopped());
4323 caller()->AddVideoTrack();
4324 }
4325 callee()->AddVideoTrack();
4326 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07004327 caller()->CreateAndSetAndSignalOffer();
4328 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004329
deadbeef1dcb1642017-03-29 21:08:16 -07004330 // Verify the caller receives frames from the newly added stream, and the
4331 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004332 MediaExpectations media_expectations;
4333 media_expectations.CalleeExpectsSomeAudio();
4334 media_expectations.ExpectBidirectionalVideo();
4335 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004336}
4337
deadbeef1dcb1642017-03-29 21:08:16 -07004338// This tests that if we negotiate after calling CreateSender but before we
4339// have a track, then set a track later, frames from the newly-set track are
4340// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004341TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07004342 MediaFlowsAfterEarlyWarmupWithCreateSender) {
4343 ASSERT_TRUE(CreatePeerConnectionWrappers());
4344 ConnectFakeSignaling();
4345 auto caller_audio_sender =
4346 caller()->pc()->CreateSender("audio", "caller_stream");
4347 auto caller_video_sender =
4348 caller()->pc()->CreateSender("video", "caller_stream");
4349 auto callee_audio_sender =
4350 callee()->pc()->CreateSender("audio", "callee_stream");
4351 auto callee_video_sender =
4352 callee()->pc()->CreateSender("video", "callee_stream");
4353 caller()->CreateAndSetAndSignalOffer();
4354 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4355 // Wait for ICE to complete, without any tracks being set.
4356 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4357 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4358 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4359 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4360 // Now set the tracks, and expect frames to immediately start flowing.
4361 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4362 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4363 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4364 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08004365 MediaExpectations media_expectations;
4366 media_expectations.ExpectBidirectionalAudioAndVideo();
4367 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4368}
4369
4370// This tests that if we negotiate after calling AddTransceiver but before we
4371// have a track, then set a track later, frames from the newly-set tracks are
4372// received end-to-end.
4373TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
4374 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
4375 ASSERT_TRUE(CreatePeerConnectionWrappers());
4376 ConnectFakeSignaling();
4377 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
4378 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
4379 auto caller_audio_sender = audio_result.MoveValue()->sender();
4380 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
4381 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
4382 auto caller_video_sender = video_result.MoveValue()->sender();
4383 callee()->SetRemoteOfferHandler([this] {
4384 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
4385 callee()->pc()->GetTransceivers()[0]->SetDirection(
4386 RtpTransceiverDirection::kSendRecv);
4387 callee()->pc()->GetTransceivers()[1]->SetDirection(
4388 RtpTransceiverDirection::kSendRecv);
4389 });
4390 caller()->CreateAndSetAndSignalOffer();
4391 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4392 // Wait for ICE to complete, without any tracks being set.
4393 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
4394 caller()->ice_connection_state(), kMaxWaitForFramesMs);
4395 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4396 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4397 // Now set the tracks, and expect frames to immediately start flowing.
4398 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
4399 auto callee_video_sender = callee()->pc()->GetSenders()[1];
4400 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
4401 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
4402 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
4403 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
4404 MediaExpectations media_expectations;
4405 media_expectations.ExpectBidirectionalAudioAndVideo();
4406 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004407}
4408
4409// This test verifies that a remote video track can be added via AddStream,
4410// and sent end-to-end. For this particular test, it's simply echoed back
4411// from the caller to the callee, rather than being forwarded to a third
4412// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004413TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07004414 ASSERT_TRUE(CreatePeerConnectionWrappers());
4415 ConnectFakeSignaling();
4416 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08004417 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07004418 caller()->CreateAndSetAndSignalOffer();
4419 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02004420 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07004421
4422 // Echo the stream back, and do a new offer/anwer (initiated by callee this
4423 // time).
4424 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
4425 callee()->CreateAndSetAndSignalOffer();
4426 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
4427
Seth Hampson2f0d7022018-02-20 11:54:42 -08004428 MediaExpectations media_expectations;
4429 media_expectations.ExpectBidirectionalVideo();
4430 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07004431}
4432
4433// Test that we achieve the expected end-to-end connection time, using a
4434// fake clock and simulated latency on the media and signaling paths.
4435// We use a TURN<->TURN connection because this is usually the quickest to
4436// set up initially, especially when we're confident the connection will work
4437// and can start sending media before we get a STUN response.
4438//
4439// With various optimizations enabled, here are the network delays we expect to
4440// be on the critical path:
4441// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
4442// signaling answer (with DTLS fingerprint).
4443// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
4444// using TURN<->TURN pair, and DTLS exchange is 4 packets,
4445// the first of which should have arrived before the answer.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004446TEST_P(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07004447 rtc::ScopedFakeClock fake_clock;
4448 // Some things use a time of "0" as a special value, so we need to start out
4449 // the fake clock at a nonzero time.
4450 // TODO(deadbeef): Fix this.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +02004451 fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
deadbeef1dcb1642017-03-29 21:08:16 -07004452
4453 static constexpr int media_hop_delay_ms = 50;
4454 static constexpr int signaling_trip_delay_ms = 500;
4455 // For explanation of these values, see comment above.
4456 static constexpr int required_media_hops = 9;
4457 static constexpr int required_signaling_trips = 2;
4458 // For internal delays (such as posting an event asychronously).
4459 static constexpr int allowed_internal_delay_ms = 20;
4460 static constexpr int total_connection_time_ms =
4461 media_hop_delay_ms * required_media_hops +
4462 signaling_trip_delay_ms * required_signaling_trips +
4463 allowed_internal_delay_ms;
4464
4465 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4466 3478};
4467 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4468 0};
4469 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4470 3478};
4471 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4472 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004473 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
4474 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004475
Seth Hampsonaed71642018-06-11 07:41:32 -07004476 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
4477 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07004478 // Bypass permission check on received packets so media can be sent before
4479 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07004480 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
4481 turn_server_1->set_enable_permission_checks(false);
4482 });
4483 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
4484 turn_server_2->set_enable_permission_checks(false);
4485 });
deadbeef1dcb1642017-03-29 21:08:16 -07004486
4487 PeerConnectionInterface::RTCConfiguration client_1_config;
4488 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4489 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4490 ice_server_1.username = "test";
4491 ice_server_1.password = "test";
4492 client_1_config.servers.push_back(ice_server_1);
4493 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4494 client_1_config.presume_writable_when_fully_relayed = true;
4495
4496 PeerConnectionInterface::RTCConfiguration client_2_config;
4497 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4498 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4499 ice_server_2.username = "test";
4500 ice_server_2.password = "test";
4501 client_2_config.servers.push_back(ice_server_2);
4502 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4503 client_2_config.presume_writable_when_fully_relayed = true;
4504
4505 ASSERT_TRUE(
4506 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4507 // Set up the simulated delays.
4508 SetSignalingDelayMs(signaling_trip_delay_ms);
4509 ConnectFakeSignaling();
4510 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
4511 virtual_socket_server()->UpdateDelayDistribution();
4512
4513 // Set "offer to receive audio/video" without adding any tracks, so we just
4514 // set up ICE/DTLS with no media.
4515 PeerConnectionInterface::RTCOfferAnswerOptions options;
4516 options.offer_to_receive_audio = 1;
4517 options.offer_to_receive_video = 1;
4518 caller()->SetOfferAnswerOptions(options);
4519 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07004520 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
4521 fake_clock);
Seth Hampson1d4a76d2018-06-19 14:31:41 -07004522 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
4523 // If this is not done a DCHECK can be hit in ports.cc, because a large
4524 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07004525 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07004526}
4527
Jonas Orelandbdcee282017-10-10 14:01:40 +02004528// Verify that a TurnCustomizer passed in through RTCConfiguration
4529// is actually used by the underlying TURN candidate pair.
4530// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004531TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02004532 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
4533 3478};
4534 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
4535 0};
4536 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
4537 3478};
4538 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
4539 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07004540 CreateTurnServer(turn_server_1_internal_address,
4541 turn_server_1_external_address);
4542 CreateTurnServer(turn_server_2_internal_address,
4543 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004544
4545 PeerConnectionInterface::RTCConfiguration client_1_config;
4546 webrtc::PeerConnectionInterface::IceServer ice_server_1;
4547 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
4548 ice_server_1.username = "test";
4549 ice_server_1.password = "test";
4550 client_1_config.servers.push_back(ice_server_1);
4551 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004552 auto* customizer1 = CreateTurnCustomizer();
4553 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004554
4555 PeerConnectionInterface::RTCConfiguration client_2_config;
4556 webrtc::PeerConnectionInterface::IceServer ice_server_2;
4557 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
4558 ice_server_2.username = "test";
4559 ice_server_2.password = "test";
4560 client_2_config.servers.push_back(ice_server_2);
4561 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07004562 auto* customizer2 = CreateTurnCustomizer();
4563 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02004564
4565 ASSERT_TRUE(
4566 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4567 ConnectFakeSignaling();
4568
4569 // Set "offer to receive audio/video" without adding any tracks, so we just
4570 // set up ICE/DTLS with no media.
4571 PeerConnectionInterface::RTCOfferAnswerOptions options;
4572 options.offer_to_receive_audio = 1;
4573 options.offer_to_receive_video = 1;
4574 caller()->SetOfferAnswerOptions(options);
4575 caller()->CreateAndSetAndSignalOffer();
4576 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4577
Seth Hampsonaed71642018-06-11 07:41:32 -07004578 ExpectTurnCustomizerCountersIncremented(customizer1);
4579 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02004580}
4581
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004582// Verifies that you can use TCP instead of UDP to connect to a TURN server and
4583// send media between the caller and the callee.
4584TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
4585 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4586 3478};
4587 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4588
4589 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07004590 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4591 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07004592
4593 webrtc::PeerConnectionInterface::IceServer ice_server;
4594 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
4595 ice_server.username = "test";
4596 ice_server.password = "test";
4597
4598 PeerConnectionInterface::RTCConfiguration client_1_config;
4599 client_1_config.servers.push_back(ice_server);
4600 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4601
4602 PeerConnectionInterface::RTCConfiguration client_2_config;
4603 client_2_config.servers.push_back(ice_server);
4604 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4605
4606 ASSERT_TRUE(
4607 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
4608
4609 // Do normal offer/answer and wait for ICE to complete.
4610 ConnectFakeSignaling();
4611 caller()->AddAudioVideoTracks();
4612 callee()->AddAudioVideoTracks();
4613 caller()->CreateAndSetAndSignalOffer();
4614 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4615 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
4616 callee()->ice_connection_state(), kMaxWaitForFramesMs);
4617
4618 MediaExpectations media_expectations;
4619 media_expectations.ExpectBidirectionalAudioAndVideo();
4620 EXPECT_TRUE(ExpectNewFrames(media_expectations));
4621}
4622
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004623// Verify that a SSLCertificateVerifier passed in through
4624// PeerConnectionDependencies is actually used by the underlying SSL
4625// implementation to determine whether a certificate presented by the TURN
4626// server is accepted by the client. Note that openssladapter_unittest.cc
4627// contains more detailed, lower-level tests.
4628TEST_P(PeerConnectionIntegrationTest,
4629 SSLCertificateVerifierUsedForTurnConnections) {
4630 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4631 3478};
4632 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4633
4634 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4635 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004636 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4637 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004638
4639 webrtc::PeerConnectionInterface::IceServer ice_server;
4640 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4641 ice_server.username = "test";
4642 ice_server.password = "test";
4643
4644 PeerConnectionInterface::RTCConfiguration client_1_config;
4645 client_1_config.servers.push_back(ice_server);
4646 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4647
4648 PeerConnectionInterface::RTCConfiguration client_2_config;
4649 client_2_config.servers.push_back(ice_server);
4650 // Setting the type to kRelay forces the connection to go through a TURN
4651 // server.
4652 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4653
4654 // Get a copy to the pointer so we can verify calls later.
4655 rtc::TestCertificateVerifier* client_1_cert_verifier =
4656 new rtc::TestCertificateVerifier();
4657 client_1_cert_verifier->verify_certificate_ = true;
4658 rtc::TestCertificateVerifier* client_2_cert_verifier =
4659 new rtc::TestCertificateVerifier();
4660 client_2_cert_verifier->verify_certificate_ = true;
4661
4662 // Create the dependencies with the test certificate verifier.
4663 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4664 client_1_deps.tls_cert_verifier =
4665 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4666 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4667 client_2_deps.tls_cert_verifier =
4668 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4669
4670 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4671 client_1_config, std::move(client_1_deps), client_2_config,
4672 std::move(client_2_deps)));
4673 ConnectFakeSignaling();
4674
4675 // Set "offer to receive audio/video" without adding any tracks, so we just
4676 // set up ICE/DTLS with no media.
4677 PeerConnectionInterface::RTCOfferAnswerOptions options;
4678 options.offer_to_receive_audio = 1;
4679 options.offer_to_receive_video = 1;
4680 caller()->SetOfferAnswerOptions(options);
4681 caller()->CreateAndSetAndSignalOffer();
4682 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
4683
4684 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4685 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004686}
4687
4688TEST_P(PeerConnectionIntegrationTest,
4689 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
4690 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
4691 3478};
4692 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
4693
4694 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
4695 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07004696 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
4697 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004698
4699 webrtc::PeerConnectionInterface::IceServer ice_server;
4700 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
4701 ice_server.username = "test";
4702 ice_server.password = "test";
4703
4704 PeerConnectionInterface::RTCConfiguration client_1_config;
4705 client_1_config.servers.push_back(ice_server);
4706 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
4707
4708 PeerConnectionInterface::RTCConfiguration client_2_config;
4709 client_2_config.servers.push_back(ice_server);
4710 // Setting the type to kRelay forces the connection to go through a TURN
4711 // server.
4712 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
4713
4714 // Get a copy to the pointer so we can verify calls later.
4715 rtc::TestCertificateVerifier* client_1_cert_verifier =
4716 new rtc::TestCertificateVerifier();
4717 client_1_cert_verifier->verify_certificate_ = false;
4718 rtc::TestCertificateVerifier* client_2_cert_verifier =
4719 new rtc::TestCertificateVerifier();
4720 client_2_cert_verifier->verify_certificate_ = false;
4721
4722 // Create the dependencies with the test certificate verifier.
4723 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
4724 client_1_deps.tls_cert_verifier =
4725 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
4726 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
4727 client_2_deps.tls_cert_verifier =
4728 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
4729
4730 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
4731 client_1_config, std::move(client_1_deps), client_2_config,
4732 std::move(client_2_deps)));
4733 ConnectFakeSignaling();
4734
4735 // Set "offer to receive audio/video" without adding any tracks, so we just
4736 // set up ICE/DTLS with no media.
4737 PeerConnectionInterface::RTCOfferAnswerOptions options;
4738 options.offer_to_receive_audio = 1;
4739 options.offer_to_receive_video = 1;
4740 caller()->SetOfferAnswerOptions(options);
4741 caller()->CreateAndSetAndSignalOffer();
4742 bool wait_res = true;
4743 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
4744 // properly, should be able to just wait for a state of "failed" instead of
4745 // waiting a fixed 10 seconds.
4746 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
4747 ASSERT_FALSE(wait_res);
4748
4749 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
4750 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07004751}
4752
deadbeefc964d0b2017-04-03 10:03:35 -07004753// Test that audio and video flow end-to-end when codec names don't use the
4754// expected casing, given that they're supposed to be case insensitive. To test
4755// this, all but one codec is removed from each media description, and its
4756// casing is changed.
4757//
4758// In the past, this has regressed and caused crashes/black video, due to the
4759// fact that code at some layers was doing case-insensitive comparisons and
4760// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004761TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07004762 ASSERT_TRUE(CreatePeerConnectionWrappers());
4763 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004764 caller()->AddAudioVideoTracks();
4765 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07004766
4767 // Remove all but one audio/video codec (opus and VP8), and change the
4768 // casing of the caller's generated offer.
4769 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
4770 cricket::AudioContentDescription* audio =
4771 GetFirstAudioContentDescription(description);
4772 ASSERT_NE(nullptr, audio);
4773 auto audio_codecs = audio->codecs();
4774 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
4775 [](const cricket::AudioCodec& codec) {
4776 return codec.name != "opus";
4777 }),
4778 audio_codecs.end());
4779 ASSERT_EQ(1u, audio_codecs.size());
4780 audio_codecs[0].name = "OpUs";
4781 audio->set_codecs(audio_codecs);
4782
4783 cricket::VideoContentDescription* video =
4784 GetFirstVideoContentDescription(description);
4785 ASSERT_NE(nullptr, video);
4786 auto video_codecs = video->codecs();
4787 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
4788 [](const cricket::VideoCodec& codec) {
4789 return codec.name != "VP8";
4790 }),
4791 video_codecs.end());
4792 ASSERT_EQ(1u, video_codecs.size());
4793 video_codecs[0].name = "vP8";
4794 video->set_codecs(video_codecs);
4795 });
4796
4797 caller()->CreateAndSetAndSignalOffer();
4798 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4799
4800 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004801 MediaExpectations media_expectations;
4802 media_expectations.ExpectBidirectionalAudioAndVideo();
4803 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07004804}
4805
Jonas Oreland49ac5952018-09-26 16:04:32 +02004806TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07004807 ASSERT_TRUE(CreatePeerConnectionWrappers());
4808 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08004809 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07004810 caller()->CreateAndSetAndSignalOffer();
4811 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07004812 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004813 MediaExpectations media_expectations;
4814 media_expectations.CalleeExpectsSomeAudio(1);
4815 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02004816 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07004817 auto receiver = callee()->pc()->GetReceivers()[0];
4818 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02004819 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07004820 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4821 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02004822 sources[0].source_id());
4823 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
4824}
4825
4826TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
4827 ASSERT_TRUE(CreatePeerConnectionWrappers());
4828 ConnectFakeSignaling();
4829 caller()->AddVideoTrack();
4830 caller()->CreateAndSetAndSignalOffer();
4831 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4832 // Wait for one video frame to be received by the callee.
4833 MediaExpectations media_expectations;
4834 media_expectations.CalleeExpectsSomeVideo(1);
4835 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4836 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
4837 auto receiver = callee()->pc()->GetReceivers()[0];
4838 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
4839 auto sources = receiver->GetSources();
4840 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
4841 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
4842 sources[0].source_id());
4843 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07004844}
4845
deadbeef2f425aa2017-04-14 10:41:32 -07004846// Test that if a track is removed and added again with a different stream ID,
4847// the new stream ID is successfully communicated in SDP and media continues to
4848// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004849// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
4850// it will not reuse a transceiver that has already been sending. After creating
4851// a new transceiver it tries to create an offer with two senders of the same
4852// track ids and it fails.
4853TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07004854 ASSERT_TRUE(CreatePeerConnectionWrappers());
4855 ConnectFakeSignaling();
4856
deadbeef2f425aa2017-04-14 10:41:32 -07004857 // Add track using stream 1, do offer/answer.
4858 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
4859 caller()->CreateLocalAudioTrack();
4860 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07004861 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07004862 caller()->CreateAndSetAndSignalOffer();
4863 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004864 {
4865 MediaExpectations media_expectations;
4866 media_expectations.CalleeExpectsSomeAudio(1);
4867 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4868 }
deadbeef2f425aa2017-04-14 10:41:32 -07004869 // Remove the sender, and create a new one with the new stream.
4870 caller()->pc()->RemoveTrack(sender);
Steve Antond78323f2018-07-11 11:13:44 -07004871 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07004872 caller()->CreateAndSetAndSignalOffer();
4873 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4874 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004875 {
4876 MediaExpectations media_expectations;
4877 media_expectations.CalleeExpectsSomeAudio();
4878 ASSERT_TRUE(ExpectNewFrames(media_expectations));
4879 }
deadbeef2f425aa2017-04-14 10:41:32 -07004880}
4881
Seth Hampson2f0d7022018-02-20 11:54:42 -08004882TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02004883 ASSERT_TRUE(CreatePeerConnectionWrappers());
4884 ConnectFakeSignaling();
4885
Karl Wiberg918f50c2018-07-05 11:40:33 +02004886 auto output = absl::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02004887 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
4888 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02004889 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01004890 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
4891 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02004892
Steve Anton15324772018-01-16 10:26:49 -08004893 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02004894 caller()->CreateAndSetAndSignalOffer();
4895 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4896}
4897
Steve Antonede9ca52017-10-16 13:04:27 -07004898// Test that if candidates are only signaled by applying full session
4899// descriptions (instead of using AddIceCandidate), the peers can connect to
4900// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004901TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07004902 ASSERT_TRUE(CreatePeerConnectionWrappers());
4903 // Each side will signal the session descriptions but not candidates.
4904 ConnectFakeSignalingForSdpOnly();
4905
4906 // Add audio video track and exchange the initial offer/answer with media
4907 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08004908 caller()->AddAudioVideoTracks();
4909 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07004910 caller()->CreateAndSetAndSignalOffer();
4911
4912 // Wait for all candidates to be gathered on both the caller and callee.
4913 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4914 caller()->ice_gathering_state(), kDefaultTimeout);
4915 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
4916 callee()->ice_gathering_state(), kDefaultTimeout);
4917
4918 // The candidates will now be included in the session description, so
4919 // signaling them will start the ICE connection.
4920 caller()->CreateAndSetAndSignalOffer();
4921 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4922
4923 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004924 MediaExpectations media_expectations;
4925 media_expectations.ExpectBidirectionalAudioAndVideo();
4926 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07004927}
4928
henrika5f6bf242017-11-01 11:06:56 +01004929// Test that SetAudioPlayout can be used to disable audio playout from the
4930// start, then later enable it. This may be useful, for example, if the caller
4931// needs to play a local ringtone until some event occurs, after which it
4932// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004933TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01004934 ASSERT_TRUE(CreatePeerConnectionWrappers());
4935 ConnectFakeSignaling();
4936
4937 // Set up audio-only call where audio playout is disabled on caller's side.
4938 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08004939 caller()->AddAudioTrack();
4940 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004941 caller()->CreateAndSetAndSignalOffer();
4942 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4943
4944 // Pump messages for a second.
4945 WAIT(false, 1000);
4946 // Since audio playout is disabled, the caller shouldn't have received
4947 // anything (at the playout level, at least).
4948 EXPECT_EQ(0, caller()->audio_frames_received());
4949 // As a sanity check, make sure the callee (for which playout isn't disabled)
4950 // did still see frames on its audio level.
4951 ASSERT_GT(callee()->audio_frames_received(), 0);
4952
4953 // Enable playout again, and ensure audio starts flowing.
4954 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08004955 MediaExpectations media_expectations;
4956 media_expectations.ExpectBidirectionalAudio();
4957 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01004958}
4959
4960double GetAudioEnergyStat(PeerConnectionWrapper* pc) {
4961 auto report = pc->NewGetStats();
4962 auto track_stats_list =
4963 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
4964 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
4965 for (const auto* track_stats : track_stats_list) {
4966 if (track_stats->remote_source.is_defined() &&
4967 *track_stats->remote_source) {
4968 remote_track_stats = track_stats;
4969 break;
4970 }
4971 }
4972
4973 if (!remote_track_stats->total_audio_energy.is_defined()) {
4974 return 0.0;
4975 }
4976 return *remote_track_stats->total_audio_energy;
4977}
4978
4979// Test that if audio playout is disabled via the SetAudioPlayout() method, then
4980// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08004981TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01004982 DisableAudioPlayoutStillGeneratesAudioStats) {
4983 ASSERT_TRUE(CreatePeerConnectionWrappers());
4984 ConnectFakeSignaling();
4985
4986 // Set up audio-only call where playout is disabled but audio-processing is
4987 // still active.
Steve Anton15324772018-01-16 10:26:49 -08004988 caller()->AddAudioTrack();
4989 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01004990 caller()->pc()->SetAudioPlayout(false);
4991
4992 caller()->CreateAndSetAndSignalOffer();
4993 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
4994
4995 // Wait for the callee to receive audio stats.
4996 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
4997}
4998
henrika4f167df2017-11-01 14:45:55 +01004999// Test that SetAudioRecording can be used to disable audio recording from the
5000// start, then later enable it. This may be useful, for example, if the caller
5001// wants to ensure that no audio resources are active before a certain state
5002// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08005003TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01005004 ASSERT_TRUE(CreatePeerConnectionWrappers());
5005 ConnectFakeSignaling();
5006
5007 // Set up audio-only call where audio recording is disabled on caller's side.
5008 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08005009 caller()->AddAudioTrack();
5010 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01005011 caller()->CreateAndSetAndSignalOffer();
5012 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5013
5014 // Pump messages for a second.
5015 WAIT(false, 1000);
5016 // Since caller has disabled audio recording, the callee shouldn't have
5017 // received anything.
5018 EXPECT_EQ(0, callee()->audio_frames_received());
5019 // As a sanity check, make sure the caller did still see frames on its
5020 // audio level since audio recording is enabled on the calle side.
5021 ASSERT_GT(caller()->audio_frames_received(), 0);
5022
5023 // Enable audio recording again, and ensure audio starts flowing.
5024 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005025 MediaExpectations media_expectations;
5026 media_expectations.ExpectBidirectionalAudio();
5027 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01005028}
5029
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005030// Test that after closing PeerConnections, they stop sending any packets (ICE,
5031// DTLS, RTP...).
Seth Hampson2f0d7022018-02-20 11:54:42 -08005032TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) {
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005033 // Set up audio/video/data, wait for some frames to be received.
5034 ASSERT_TRUE(CreatePeerConnectionWrappers());
5035 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08005036 caller()->AddAudioVideoTracks();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005037#ifdef HAVE_SCTP
5038 caller()->CreateDataChannel();
5039#endif
5040 caller()->CreateAndSetAndSignalOffer();
5041 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08005042 MediaExpectations media_expectations;
5043 media_expectations.CalleeExpectsSomeAudioAndVideo();
5044 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005045 // Close PeerConnections.
Steve Antond91969e2019-05-30 12:27:03 -07005046 ClosePeerConnections();
Taylor Brandstetter389a97c2018-01-03 16:26:06 -08005047 // Pump messages for a second, and ensure no new packets end up sent.
5048 uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
5049 WAIT(false, 1000);
5050 uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
5051 EXPECT_EQ(sent_packets_a, sent_packets_b);
5052}
5053
Steve Anton7eca0932018-03-30 15:18:41 -07005054// Test that transport stats are generated by the RTCStatsCollector for a
5055// connection that only involves data channels. This is a regression test for
5056// crbug.com/826972.
5057#ifdef HAVE_SCTP
5058TEST_P(PeerConnectionIntegrationTest,
5059 TransportStatsReportedForDataChannelOnlyConnection) {
5060 ASSERT_TRUE(CreatePeerConnectionWrappers());
5061 ConnectFakeSignaling();
5062 caller()->CreateDataChannel();
5063
5064 caller()->CreateAndSetAndSignalOffer();
5065 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5066 ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
5067
5068 auto caller_report = caller()->NewGetStats();
5069 EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
5070 auto callee_report = callee()->NewGetStats();
5071 EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
5072}
5073#endif // HAVE_SCTP
5074
Qingsi Wang7685e862018-06-11 20:15:46 -07005075TEST_P(PeerConnectionIntegrationTest,
5076 IceEventsGeneratedAndLoggedInRtcEventLog) {
5077 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
5078 ConnectFakeSignaling();
5079 PeerConnectionInterface::RTCOfferAnswerOptions options;
5080 options.offer_to_receive_audio = 1;
5081 caller()->SetOfferAnswerOptions(options);
5082 caller()->CreateAndSetAndSignalOffer();
5083 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
5084 ASSERT_NE(nullptr, caller()->event_log_factory());
5085 ASSERT_NE(nullptr, callee()->event_log_factory());
5086 webrtc::FakeRtcEventLog* caller_event_log =
5087 static_cast<webrtc::FakeRtcEventLog*>(
5088 caller()->event_log_factory()->last_log_created());
5089 webrtc::FakeRtcEventLog* callee_event_log =
5090 static_cast<webrtc::FakeRtcEventLog*>(
5091 callee()->event_log_factory()->last_log_created());
5092 ASSERT_NE(nullptr, caller_event_log);
5093 ASSERT_NE(nullptr, callee_event_log);
5094 int caller_ice_config_count = caller_event_log->GetEventCount(
5095 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5096 int caller_ice_event_count = caller_event_log->GetEventCount(
5097 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5098 int callee_ice_config_count = callee_event_log->GetEventCount(
5099 webrtc::RtcEvent::Type::IceCandidatePairConfig);
5100 int callee_ice_event_count = callee_event_log->GetEventCount(
5101 webrtc::RtcEvent::Type::IceCandidatePairEvent);
5102 EXPECT_LT(0, caller_ice_config_count);
5103 EXPECT_LT(0, caller_ice_event_count);
5104 EXPECT_LT(0, callee_ice_config_count);
5105 EXPECT_LT(0, callee_ice_event_count);
5106}
5107
Qingsi Wangc129c352019-04-18 10:41:58 -07005108TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07005109 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5110 3478};
5111 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5112
5113 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5114
5115 webrtc::PeerConnectionInterface::IceServer ice_server;
5116 ice_server.urls.push_back("turn:88.88.88.0:3478");
5117 ice_server.username = "test";
5118 ice_server.password = "test";
5119
5120 PeerConnectionInterface::RTCConfiguration caller_config;
5121 caller_config.servers.push_back(ice_server);
5122 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5123 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005124 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005125
5126 PeerConnectionInterface::RTCConfiguration callee_config;
5127 callee_config.servers.push_back(ice_server);
5128 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5129 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07005130 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07005131
5132 ASSERT_TRUE(
5133 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5134
5135 // Do normal offer/answer and wait for ICE to complete.
5136 ConnectFakeSignaling();
5137 caller()->AddAudioVideoTracks();
5138 callee()->AddAudioVideoTracks();
5139 caller()->CreateAndSetAndSignalOffer();
5140 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5141 // Since we are doing continual gathering, the ICE transport does not reach
5142 // kIceGatheringComplete (see
5143 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
5144 // kIceConnectionComplete.
5145 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5146 caller()->ice_connection_state(), kDefaultTimeout);
5147 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
5148 callee()->ice_connection_state(), kDefaultTimeout);
5149 // Note that we cannot use the metric
5150 // |WebRTC.PeerConnection.CandidatePairType_UDP| in this test since this
5151 // metric is only populated when we reach kIceConnectionComplete in the
5152 // current implementation.
5153 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5154 caller()->last_candidate_gathered().type());
5155 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
5156 callee()->last_candidate_gathered().type());
5157
5158 // Loosen the caller's candidate filter.
5159 caller_config = caller()->pc()->GetConfiguration();
5160 caller_config.type = webrtc::PeerConnectionInterface::kAll;
5161 caller()->pc()->SetConfiguration(caller_config);
5162 // We should have gathered a new host candidate.
5163 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5164 caller()->last_candidate_gathered().type(), kDefaultTimeout);
5165
5166 // Loosen the callee's candidate filter.
5167 callee_config = callee()->pc()->GetConfiguration();
5168 callee_config.type = webrtc::PeerConnectionInterface::kAll;
5169 callee()->pc()->SetConfiguration(callee_config);
5170 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
5171 callee()->last_candidate_gathered().type(), kDefaultTimeout);
5172}
5173
Eldar Relloda13ea22019-06-01 12:23:43 +03005174TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03005175 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
5176 3478};
5177 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
5178
5179 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
5180
5181 webrtc::PeerConnectionInterface::IceServer ice_server;
5182 ice_server.urls.push_back("turn:88.88.88.0:3478");
5183 ice_server.username = "test";
5184 ice_server.password = "123";
5185
5186 PeerConnectionInterface::RTCConfiguration caller_config;
5187 caller_config.servers.push_back(ice_server);
5188 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
5189 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5190
5191 PeerConnectionInterface::RTCConfiguration callee_config;
5192 callee_config.servers.push_back(ice_server);
5193 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
5194 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
5195
5196 ASSERT_TRUE(
5197 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
5198
5199 // Do normal offer/answer and wait for ICE to complete.
5200 ConnectFakeSignaling();
5201 caller()->AddAudioVideoTracks();
5202 callee()->AddAudioVideoTracks();
5203 caller()->CreateAndSetAndSignalOffer();
5204 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5205 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
5206 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
5207 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
5208 EXPECT_NE(std::string::npos,
5209 caller()->error_event().host_candidate.find(":"));
5210}
5211
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005212INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest,
5213 PeerConnectionIntegrationTest,
5214 Values(SdpSemantics::kPlanB,
5215 SdpSemantics::kUnifiedPlan));
Steve Antond3679212018-01-17 17:41:02 -08005216
Steve Anton74255ff2018-01-24 18:32:57 -08005217// Tests that verify interoperability between Plan B and Unified Plan
5218// PeerConnections.
5219class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08005220 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08005221 public ::testing::WithParamInterface<
5222 std::tuple<SdpSemantics, SdpSemantics>> {
5223 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08005224 // Setting the SdpSemantics for the base test to kDefault does not matter
5225 // because we specify not to use the test semantics when creating
5226 // PeerConnectionWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08005227 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07005228 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08005229 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08005230 callee_semantics_(std::get<1>(GetParam())) {}
5231
5232 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07005233 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
5234 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08005235 }
5236
5237 const SdpSemantics caller_semantics_;
5238 const SdpSemantics callee_semantics_;
5239};
5240
5241TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
5242 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5243 ConnectFakeSignaling();
5244
5245 caller()->CreateAndSetAndSignalOffer();
5246 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5247}
5248
5249TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
5250 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5251 ConnectFakeSignaling();
5252 auto audio_sender = caller()->AddAudioTrack();
5253
5254 caller()->CreateAndSetAndSignalOffer();
5255 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5256
5257 // Verify that one audio receiver has been created on the remote and that it
5258 // has the same track ID as the sending track.
5259 auto receivers = callee()->pc()->GetReceivers();
5260 ASSERT_EQ(1u, receivers.size());
5261 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
5262 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
5263
Seth Hampson2f0d7022018-02-20 11:54:42 -08005264 MediaExpectations media_expectations;
5265 media_expectations.CalleeExpectsSomeAudio();
5266 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005267}
5268
5269TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
5270 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5271 ConnectFakeSignaling();
5272 auto video_sender = caller()->AddVideoTrack();
5273 auto audio_sender = caller()->AddAudioTrack();
5274
5275 caller()->CreateAndSetAndSignalOffer();
5276 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5277
5278 // Verify that one audio and one video receiver have been created on the
5279 // remote and that they have the same track IDs as the sending tracks.
5280 auto audio_receivers =
5281 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
5282 ASSERT_EQ(1u, audio_receivers.size());
5283 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
5284 auto video_receivers =
5285 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
5286 ASSERT_EQ(1u, video_receivers.size());
5287 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
5288
Seth Hampson2f0d7022018-02-20 11:54:42 -08005289 MediaExpectations media_expectations;
5290 media_expectations.CalleeExpectsSomeAudioAndVideo();
5291 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005292}
5293
5294TEST_P(PeerConnectionIntegrationInteropTest,
5295 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
5296 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5297 ConnectFakeSignaling();
5298 caller()->AddAudioVideoTracks();
5299 callee()->AddAudioVideoTracks();
5300
5301 caller()->CreateAndSetAndSignalOffer();
5302 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5303
Seth Hampson2f0d7022018-02-20 11:54:42 -08005304 MediaExpectations media_expectations;
5305 media_expectations.ExpectBidirectionalAudioAndVideo();
5306 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005307}
5308
5309TEST_P(PeerConnectionIntegrationInteropTest,
5310 ReverseRolesOneAudioLocalToOneVideoRemote) {
5311 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
5312 ConnectFakeSignaling();
5313 caller()->AddAudioTrack();
5314 callee()->AddVideoTrack();
5315
5316 caller()->CreateAndSetAndSignalOffer();
5317 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5318
5319 // Verify that only the audio track has been negotiated.
5320 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
5321 // Might also check that the callee's NegotiationNeeded flag is set.
5322
5323 // Reverse roles.
5324 callee()->CreateAndSetAndSignalOffer();
5325 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5326
Seth Hampson2f0d7022018-02-20 11:54:42 -08005327 MediaExpectations media_expectations;
5328 media_expectations.CallerExpectsSomeVideo();
5329 media_expectations.CalleeExpectsSomeAudio();
5330 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005331}
5332
Mirko Bonadeic84f6612019-01-31 12:20:57 +01005333INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07005334 PeerConnectionIntegrationTest,
5335 PeerConnectionIntegrationInteropTest,
5336 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
5337 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
5338
5339// Test that if the Unified Plan side offers two video tracks then the Plan B
5340// side will only see the first one and ignore the second.
5341TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07005342 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
5343 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08005344 ConnectFakeSignaling();
5345 auto first_sender = caller()->AddVideoTrack();
5346 caller()->AddVideoTrack();
5347
5348 caller()->CreateAndSetAndSignalOffer();
5349 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5350
5351 // Verify that there is only one receiver and it corresponds to the first
5352 // added track.
5353 auto receivers = callee()->pc()->GetReceivers();
5354 ASSERT_EQ(1u, receivers.size());
5355 EXPECT_TRUE(receivers[0]->track()->enabled());
5356 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
5357
Seth Hampson2f0d7022018-02-20 11:54:42 -08005358 MediaExpectations media_expectations;
5359 media_expectations.CalleeExpectsSomeVideo();
5360 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08005361}
5362
Steve Anton2bed3972019-01-04 17:04:30 -08005363// Test that if the initial offer tagged BUNDLE section is rejected due to its
5364// associated RtpTransceiver being stopped and another transceiver is added,
5365// then renegotiation causes the callee to receive the new video track without
5366// error.
5367// This is a regression test for bugs.webrtc.org/9954
5368TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5369 ReOfferWithStoppedBundleTaggedTransceiver) {
5370 RTCConfiguration config;
5371 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
5372 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
5373 ConnectFakeSignaling();
5374 auto audio_transceiver_or_error =
5375 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
5376 ASSERT_TRUE(audio_transceiver_or_error.ok());
5377 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
5378
5379 caller()->CreateAndSetAndSignalOffer();
5380 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5381 {
5382 MediaExpectations media_expectations;
5383 media_expectations.CalleeExpectsSomeAudio();
5384 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5385 }
5386
5387 audio_transceiver->Stop();
5388 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
5389
5390 caller()->CreateAndSetAndSignalOffer();
5391 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5392 {
5393 MediaExpectations media_expectations;
5394 media_expectations.CalleeExpectsSomeVideo();
5395 ASSERT_TRUE(ExpectNewFrames(media_expectations));
5396 }
5397}
5398
Harald Alvestrandd61f2a72019-05-08 20:20:59 +02005399#ifdef HAVE_SCTP
5400
5401TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
5402 EndToEndCallWithBundledSctpDataChannel) {
5403 ASSERT_TRUE(CreatePeerConnectionWrappers());
5404 ConnectFakeSignaling();
5405 caller()->CreateDataChannel();
5406 caller()->AddAudioVideoTracks();
5407 callee()->AddAudioVideoTracks();
5408 caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
5409 caller()->CreateAndSetAndSignalOffer();
5410 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
5411 // Ensure that media and data are multiplexed on the same DTLS transport.
5412 // This only works on Unified Plan, because transports are not exposed in plan
5413 // B.
5414 auto sctp_info = caller()->pc()->GetSctpTransport()->Information();
5415 EXPECT_EQ(sctp_info.dtls_transport(),
5416 caller()->pc()->GetSenders()[0]->dtls_transport());
5417}
5418
5419#endif // HAVE_SCTP
5420
deadbeef1dcb1642017-03-29 21:08:16 -07005421} // namespace
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01005422} // namespace webrtc
deadbeef1dcb1642017-03-29 21:08:16 -07005423
5424#endif // if !defined(THREAD_SANITIZER)