| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 #include <stdio.h> | |
| 12 | |
| 13 #include <algorithm> | |
| 14 #include <list> | |
| 15 #include <map> | |
| 16 #include <memory> | |
| 17 #include <utility> | |
| 18 #include <vector> | |
| 19 | |
| 20 #include "webrtc/api/dtmfsender.h" | |
| 21 #include "webrtc/api/fakemetricsobserver.h" | |
| 22 #include "webrtc/api/localaudiosource.h" | |
| 23 #include "webrtc/api/mediastreaminterface.h" | |
| 24 #include "webrtc/api/peerconnection.h" | |
| 25 #include "webrtc/api/peerconnectionfactory.h" | |
| 26 #include "webrtc/api/peerconnectioninterface.h" | |
| 27 #include "webrtc/api/test/fakeaudiocapturemodule.h" | |
| 28 #include "webrtc/api/test/fakeconstraints.h" | |
| 29 #include "webrtc/api/test/fakeperiodicvideocapturer.h" | |
| 30 #include "webrtc/api/test/fakertccertificategenerator.h" | |
| 31 #include "webrtc/api/test/fakevideotrackrenderer.h" | |
| 32 #include "webrtc/api/test/mockpeerconnectionobservers.h" | |
| 33 #include "webrtc/base/fakenetwork.h" | |
| 34 #include "webrtc/base/gunit.h" | |
| 35 #include "webrtc/base/helpers.h" | |
| 36 #include "webrtc/base/physicalsocketserver.h" | |
| 37 #include "webrtc/base/ssladapter.h" | |
| 38 #include "webrtc/base/sslstreamadapter.h" | |
| 39 #include "webrtc/base/thread.h" | |
| 40 #include "webrtc/base/virtualsocketserver.h" | |
| 41 #include "webrtc/media/engine/fakewebrtcvideoengine.h" | |
| 42 #include "webrtc/p2p/base/p2pconstants.h" | |
| 43 #include "webrtc/p2p/base/portinterface.h" | |
| 44 #include "webrtc/p2p/base/sessiondescription.h" | |
| 45 #include "webrtc/p2p/base/testturnserver.h" | |
| 46 #include "webrtc/p2p/client/basicportallocator.h" | |
| 47 #include "webrtc/pc/mediasession.h" | |
| 48 | |
| 49 #define MAYBE_SKIP_TEST(feature) \ | |
| 50 if (!(feature())) { \ | |
| 51 LOG(LS_INFO) << "Feature disabled... skipping"; \ | |
| 52 return; \ | |
| 53 } | |
| 54 | |
| 55 using cricket::ContentInfo; | |
| 56 using cricket::FakeWebRtcVideoDecoder; | |
| 57 using cricket::FakeWebRtcVideoDecoderFactory; | |
| 58 using cricket::FakeWebRtcVideoEncoder; | |
| 59 using cricket::FakeWebRtcVideoEncoderFactory; | |
| 60 using cricket::MediaContentDescription; | |
| 61 using webrtc::DataBuffer; | |
| 62 using webrtc::DataChannelInterface; | |
| 63 using webrtc::DtmfSender; | |
| 64 using webrtc::DtmfSenderInterface; | |
| 65 using webrtc::DtmfSenderObserverInterface; | |
| 66 using webrtc::FakeConstraints; | |
| 67 using webrtc::MediaConstraintsInterface; | |
| 68 using webrtc::MediaStreamInterface; | |
| 69 using webrtc::MediaStreamTrackInterface; | |
| 70 using webrtc::MockCreateSessionDescriptionObserver; | |
| 71 using webrtc::MockDataChannelObserver; | |
| 72 using webrtc::MockSetSessionDescriptionObserver; | |
| 73 using webrtc::MockStatsObserver; | |
| 74 using webrtc::ObserverInterface; | |
| 75 using webrtc::PeerConnectionInterface; | |
| 76 using webrtc::PeerConnectionFactory; | |
| 77 using webrtc::SessionDescriptionInterface; | |
| 78 using webrtc::StreamCollectionInterface; | |
| 79 | |
| 80 namespace { | |
| 81 | |
| 82 static const int kMaxWaitMs = 10000; | |
| 83 // Disable for TSan v2, see | |
| 84 // https://code.google.com/p/webrtc/issues/detail?id=1205 for details. | |
| 85 // This declaration is also #ifdef'd as it causes uninitialized-variable | |
| 86 // warnings. | |
| 87 #if !defined(THREAD_SANITIZER) | |
| 88 static const int kMaxWaitForStatsMs = 3000; | |
| 89 #endif | |
| 90 static const int kMaxWaitForActivationMs = 5000; | |
| 91 static const int kMaxWaitForFramesMs = 10000; | |
| 92 static const int kEndAudioFrameCount = 3; | |
| 93 static const int kEndVideoFrameCount = 3; | |
| 94 | |
| 95 static const char kStreamLabelBase[] = "stream_label"; | |
| 96 static const char kVideoTrackLabelBase[] = "video_track"; | |
| 97 static const char kAudioTrackLabelBase[] = "audio_track"; | |
| 98 static const char kDataChannelLabel[] = "data_channel"; | |
| 99 | |
| 100 // Disable for TSan v2, see | |
| 101 // https://code.google.com/p/webrtc/issues/detail?id=1205 for details. | |
| 102 // This declaration is also #ifdef'd as it causes unused-variable errors. | |
| 103 #if !defined(THREAD_SANITIZER) | |
| 104 // SRTP cipher name negotiated by the tests. This must be updated if the | |
| 105 // default changes. | |
| 106 static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_32; | |
| 107 static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM; | |
| 108 #endif | |
| 109 | |
| 110 // Used to simulate signaling ICE/SDP between two PeerConnections. | |
| 111 enum Message { MSG_SDP_MESSAGE, MSG_ICE_MESSAGE }; | |
| 112 | |
| 113 struct SdpMessage { | |
| 114 std::string type; | |
| 115 std::string msg; | |
| 116 }; | |
| 117 | |
| 118 struct IceMessage { | |
| 119 std::string sdp_mid; | |
| 120 int sdp_mline_index; | |
| 121 std::string msg; | |
| 122 }; | |
| 123 | |
| 124 static void RemoveLinesFromSdp(const std::string& line_start, | |
| 125 std::string* sdp) { | |
| 126 const char kSdpLineEnd[] = "\r\n"; | |
| 127 size_t ssrc_pos = 0; | |
| 128 while ((ssrc_pos = sdp->find(line_start, ssrc_pos)) != | |
| 129 std::string::npos) { | |
| 130 size_t end_ssrc = sdp->find(kSdpLineEnd, ssrc_pos); | |
| 131 sdp->erase(ssrc_pos, end_ssrc - ssrc_pos + strlen(kSdpLineEnd)); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 bool StreamsHaveAudioTrack(StreamCollectionInterface* streams) { | |
| 136 for (size_t idx = 0; idx < streams->count(); idx++) { | |
| 137 auto stream = streams->at(idx); | |
| 138 if (stream->GetAudioTracks().size() > 0) { | |
| 139 return true; | |
| 140 } | |
| 141 } | |
| 142 return false; | |
| 143 } | |
| 144 | |
| 145 bool StreamsHaveVideoTrack(StreamCollectionInterface* streams) { | |
| 146 for (size_t idx = 0; idx < streams->count(); idx++) { | |
| 147 auto stream = streams->at(idx); | |
| 148 if (stream->GetVideoTracks().size() > 0) { | |
| 149 return true; | |
| 150 } | |
| 151 } | |
| 152 return false; | |
| 153 } | |
| 154 | |
| 155 class SignalingMessageReceiver { | |
| 156 public: | |
| 157 virtual void ReceiveSdpMessage(const std::string& type, | |
| 158 std::string& msg) = 0; | |
| 159 virtual void ReceiveIceMessage(const std::string& sdp_mid, | |
| 160 int sdp_mline_index, | |
| 161 const std::string& msg) = 0; | |
| 162 | |
| 163 protected: | |
| 164 SignalingMessageReceiver() {} | |
| 165 virtual ~SignalingMessageReceiver() {} | |
| 166 }; | |
| 167 | |
| 168 class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface { | |
| 169 public: | |
| 170 MockRtpReceiverObserver(cricket::MediaType media_type) | |
| 171 : expected_media_type_(media_type) {} | |
| 172 | |
| 173 void OnFirstPacketReceived(cricket::MediaType media_type) override { | |
| 174 ASSERT_EQ(expected_media_type_, media_type); | |
| 175 first_packet_received_ = true; | |
| 176 } | |
| 177 | |
| 178 bool first_packet_received() { return first_packet_received_; } | |
| 179 | |
| 180 virtual ~MockRtpReceiverObserver() {} | |
| 181 | |
| 182 private: | |
| 183 bool first_packet_received_ = false; | |
| 184 cricket::MediaType expected_media_type_; | |
| 185 }; | |
| 186 | |
| 187 class PeerConnectionTestClient : public webrtc::PeerConnectionObserver, | |
| 188 public SignalingMessageReceiver, | |
| 189 public ObserverInterface, | |
| 190 public rtc::MessageHandler { | |
| 191 public: | |
| 192 // We need these using declarations because there are two versions of each of | |
| 193 // the below methods and we only override one of them. | |
| 194 // TODO(deadbeef): Remove once there's only one version of the methods. | |
| 195 using PeerConnectionObserver::OnAddStream; | |
| 196 using PeerConnectionObserver::OnRemoveStream; | |
| 197 using PeerConnectionObserver::OnDataChannel; | |
| 198 | |
| 199 // If |config| is not provided, uses a default constructed RTCConfiguration. | |
| 200 static PeerConnectionTestClient* CreateClientWithDtlsIdentityStore( | |
| 201 const std::string& id, | |
| 202 const MediaConstraintsInterface* constraints, | |
| 203 const PeerConnectionFactory::Options* options, | |
| 204 const PeerConnectionInterface::RTCConfiguration* config, | |
| 205 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator, | |
| 206 bool prefer_constraint_apis, | |
| 207 rtc::Thread* network_thread, | |
| 208 rtc::Thread* worker_thread) { | |
| 209 PeerConnectionTestClient* client(new PeerConnectionTestClient(id)); | |
| 210 if (!client->Init(constraints, options, config, std::move(cert_generator), | |
| 211 prefer_constraint_apis, network_thread, worker_thread)) { | |
| 212 delete client; | |
| 213 return nullptr; | |
| 214 } | |
| 215 return client; | |
| 216 } | |
| 217 | |
| 218 static PeerConnectionTestClient* CreateClient( | |
| 219 const std::string& id, | |
| 220 const MediaConstraintsInterface* constraints, | |
| 221 const PeerConnectionFactory::Options* options, | |
| 222 const PeerConnectionInterface::RTCConfiguration* config, | |
| 223 rtc::Thread* network_thread, | |
| 224 rtc::Thread* worker_thread) { | |
| 225 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator( | |
| 226 rtc::SSLStreamAdapter::HaveDtlsSrtp() ? | |
| 227 new FakeRTCCertificateGenerator() : nullptr); | |
| 228 | |
| 229 return CreateClientWithDtlsIdentityStore(id, constraints, options, config, | |
| 230 std::move(cert_generator), true, | |
| 231 network_thread, worker_thread); | |
| 232 } | |
| 233 | |
| 234 static PeerConnectionTestClient* CreateClientPreferNoConstraints( | |
| 235 const std::string& id, | |
| 236 const PeerConnectionFactory::Options* options, | |
| 237 rtc::Thread* network_thread, | |
| 238 rtc::Thread* worker_thread) { | |
| 239 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator( | |
| 240 rtc::SSLStreamAdapter::HaveDtlsSrtp() ? | |
| 241 new FakeRTCCertificateGenerator() : nullptr); | |
| 242 | |
| 243 return CreateClientWithDtlsIdentityStore(id, nullptr, options, nullptr, | |
| 244 std::move(cert_generator), false, | |
| 245 network_thread, worker_thread); | |
| 246 } | |
| 247 | |
| 248 ~PeerConnectionTestClient() { | |
| 249 } | |
| 250 | |
| 251 void Negotiate() { Negotiate(true, true); } | |
| 252 | |
| 253 void Negotiate(bool audio, bool video) { | |
| 254 std::unique_ptr<SessionDescriptionInterface> offer; | |
| 255 ASSERT_TRUE(DoCreateOffer(&offer)); | |
| 256 | |
| 257 if (offer->description()->GetContentByName("audio")) { | |
| 258 offer->description()->GetContentByName("audio")->rejected = !audio; | |
| 259 } | |
| 260 if (offer->description()->GetContentByName("video")) { | |
| 261 offer->description()->GetContentByName("video")->rejected = !video; | |
| 262 } | |
| 263 | |
| 264 std::string sdp; | |
| 265 EXPECT_TRUE(offer->ToString(&sdp)); | |
| 266 EXPECT_TRUE(DoSetLocalDescription(offer.release())); | |
| 267 SendSdpMessage(webrtc::SessionDescriptionInterface::kOffer, sdp); | |
| 268 } | |
| 269 | |
| 270 void SendSdpMessage(const std::string& type, std::string& msg) { | |
| 271 if (signaling_delay_ms_ == 0) { | |
| 272 if (signaling_message_receiver_) { | |
| 273 signaling_message_receiver_->ReceiveSdpMessage(type, msg); | |
| 274 } | |
| 275 } else { | |
| 276 rtc::Thread::Current()->PostDelayed( | |
| 277 RTC_FROM_HERE, signaling_delay_ms_, this, MSG_SDP_MESSAGE, | |
| 278 new rtc::TypedMessageData<SdpMessage>({type, msg})); | |
| 279 } | |
| 280 } | |
| 281 | |
| 282 void SendIceMessage(const std::string& sdp_mid, | |
| 283 int sdp_mline_index, | |
| 284 const std::string& msg) { | |
| 285 if (signaling_delay_ms_ == 0) { | |
| 286 if (signaling_message_receiver_) { | |
| 287 signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index, | |
| 288 msg); | |
| 289 } | |
| 290 } else { | |
| 291 rtc::Thread::Current()->PostDelayed(RTC_FROM_HERE, signaling_delay_ms_, | |
| 292 this, MSG_ICE_MESSAGE, | |
| 293 new rtc::TypedMessageData<IceMessage>( | |
| 294 {sdp_mid, sdp_mline_index, msg})); | |
| 295 } | |
| 296 } | |
| 297 | |
| 298 // MessageHandler callback. | |
| 299 void OnMessage(rtc::Message* msg) override { | |
| 300 switch (msg->message_id) { | |
| 301 case MSG_SDP_MESSAGE: { | |
| 302 auto sdp_message = | |
| 303 static_cast<rtc::TypedMessageData<SdpMessage>*>(msg->pdata); | |
| 304 if (signaling_message_receiver_) { | |
| 305 signaling_message_receiver_->ReceiveSdpMessage( | |
| 306 sdp_message->data().type, sdp_message->data().msg); | |
| 307 } | |
| 308 delete sdp_message; | |
| 309 break; | |
| 310 } | |
| 311 case MSG_ICE_MESSAGE: { | |
| 312 auto ice_message = | |
| 313 static_cast<rtc::TypedMessageData<IceMessage>*>(msg->pdata); | |
| 314 if (signaling_message_receiver_) { | |
| 315 signaling_message_receiver_->ReceiveIceMessage( | |
| 316 ice_message->data().sdp_mid, ice_message->data().sdp_mline_index, | |
| 317 ice_message->data().msg); | |
| 318 } | |
| 319 delete ice_message; | |
| 320 break; | |
| 321 } | |
| 322 default: | |
| 323 RTC_CHECK(false); | |
| 324 } | |
| 325 } | |
| 326 | |
| 327 // SignalingMessageReceiver callback. | |
| 328 void ReceiveSdpMessage(const std::string& type, std::string& msg) override { | |
| 329 FilterIncomingSdpMessage(&msg); | |
| 330 if (type == webrtc::SessionDescriptionInterface::kOffer) { | |
| 331 HandleIncomingOffer(msg); | |
| 332 } else { | |
| 333 HandleIncomingAnswer(msg); | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 // SignalingMessageReceiver callback. | |
| 338 void ReceiveIceMessage(const std::string& sdp_mid, | |
| 339 int sdp_mline_index, | |
| 340 const std::string& msg) override { | |
| 341 LOG(INFO) << id_ << "ReceiveIceMessage"; | |
| 342 std::unique_ptr<webrtc::IceCandidateInterface> candidate( | |
| 343 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr)); | |
| 344 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get())); | |
| 345 } | |
| 346 | |
| 347 // PeerConnectionObserver callbacks. | |
| 348 void OnSignalingChange( | |
| 349 webrtc::PeerConnectionInterface::SignalingState new_state) override { | |
| 350 EXPECT_EQ(pc()->signaling_state(), new_state); | |
| 351 } | |
| 352 void OnAddStream( | |
| 353 rtc::scoped_refptr<MediaStreamInterface> media_stream) override { | |
| 354 media_stream->RegisterObserver(this); | |
| 355 for (size_t i = 0; i < media_stream->GetVideoTracks().size(); ++i) { | |
| 356 const std::string id = media_stream->GetVideoTracks()[i]->id(); | |
| 357 ASSERT_TRUE(fake_video_renderers_.find(id) == | |
| 358 fake_video_renderers_.end()); | |
| 359 fake_video_renderers_[id].reset(new webrtc::FakeVideoTrackRenderer( | |
| 360 media_stream->GetVideoTracks()[i])); | |
| 361 } | |
| 362 } | |
| 363 void OnRemoveStream( | |
| 364 rtc::scoped_refptr<MediaStreamInterface> media_stream) override {} | |
| 365 void OnRenegotiationNeeded() override {} | |
| 366 void OnIceConnectionChange( | |
| 367 webrtc::PeerConnectionInterface::IceConnectionState new_state) override { | |
| 368 EXPECT_EQ(pc()->ice_connection_state(), new_state); | |
| 369 } | |
| 370 void OnIceGatheringChange( | |
| 371 webrtc::PeerConnectionInterface::IceGatheringState new_state) override { | |
| 372 EXPECT_EQ(pc()->ice_gathering_state(), new_state); | |
| 373 } | |
| 374 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { | |
| 375 LOG(INFO) << id_ << "OnIceCandidate"; | |
| 376 | |
| 377 std::string ice_sdp; | |
| 378 EXPECT_TRUE(candidate->ToString(&ice_sdp)); | |
| 379 if (signaling_message_receiver_ == nullptr) { | |
| 380 // Remote party may be deleted. | |
| 381 return; | |
| 382 } | |
| 383 SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp); | |
| 384 } | |
| 385 | |
| 386 // MediaStreamInterface callback | |
| 387 void OnChanged() override { | |
| 388 // Track added or removed from MediaStream, so update our renderers. | |
| 389 rtc::scoped_refptr<StreamCollectionInterface> remote_streams = | |
| 390 pc()->remote_streams(); | |
| 391 // Remove renderers for tracks that were removed. | |
| 392 for (auto it = fake_video_renderers_.begin(); | |
| 393 it != fake_video_renderers_.end();) { | |
| 394 if (remote_streams->FindVideoTrack(it->first) == nullptr) { | |
| 395 auto to_remove = it++; | |
| 396 removed_fake_video_renderers_.push_back(std::move(to_remove->second)); | |
| 397 fake_video_renderers_.erase(to_remove); | |
| 398 } else { | |
| 399 ++it; | |
| 400 } | |
| 401 } | |
| 402 // Create renderers for new video tracks. | |
| 403 for (size_t stream_index = 0; stream_index < remote_streams->count(); | |
| 404 ++stream_index) { | |
| 405 MediaStreamInterface* remote_stream = remote_streams->at(stream_index); | |
| 406 for (size_t track_index = 0; | |
| 407 track_index < remote_stream->GetVideoTracks().size(); | |
| 408 ++track_index) { | |
| 409 const std::string id = | |
| 410 remote_stream->GetVideoTracks()[track_index]->id(); | |
| 411 if (fake_video_renderers_.find(id) != fake_video_renderers_.end()) { | |
| 412 continue; | |
| 413 } | |
| 414 fake_video_renderers_[id].reset(new webrtc::FakeVideoTrackRenderer( | |
| 415 remote_stream->GetVideoTracks()[track_index])); | |
| 416 } | |
| 417 } | |
| 418 } | |
| 419 | |
| 420 void SetVideoConstraints(const webrtc::FakeConstraints& video_constraint) { | |
| 421 video_constraints_ = video_constraint; | |
| 422 } | |
| 423 | |
| 424 void AddMediaStream(bool audio, bool video) { | |
| 425 std::string stream_label = | |
| 426 kStreamLabelBase + | |
| 427 rtc::ToString<int>(static_cast<int>(pc()->local_streams()->count())); | |
| 428 rtc::scoped_refptr<MediaStreamInterface> stream = | |
| 429 peer_connection_factory_->CreateLocalMediaStream(stream_label); | |
| 430 | |
| 431 if (audio && can_receive_audio()) { | |
| 432 stream->AddTrack(CreateLocalAudioTrack(stream_label)); | |
| 433 } | |
| 434 if (video && can_receive_video()) { | |
| 435 stream->AddTrack(CreateLocalVideoTrack(stream_label)); | |
| 436 } | |
| 437 | |
| 438 EXPECT_TRUE(pc()->AddStream(stream)); | |
| 439 } | |
| 440 | |
| 441 size_t NumberOfLocalMediaStreams() { return pc()->local_streams()->count(); } | |
| 442 | |
| 443 bool SessionActive() { | |
| 444 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable; | |
| 445 } | |
| 446 | |
| 447 // Automatically add a stream when receiving an offer, if we don't have one. | |
| 448 // Defaults to true. | |
| 449 void set_auto_add_stream(bool auto_add_stream) { | |
| 450 auto_add_stream_ = auto_add_stream; | |
| 451 } | |
| 452 | |
| 453 void set_signaling_message_receiver( | |
| 454 SignalingMessageReceiver* signaling_message_receiver) { | |
| 455 signaling_message_receiver_ = signaling_message_receiver; | |
| 456 } | |
| 457 | |
| 458 void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; } | |
| 459 | |
| 460 void EnableVideoDecoderFactory() { | |
| 461 video_decoder_factory_enabled_ = true; | |
| 462 fake_video_decoder_factory_->AddSupportedVideoCodecType( | |
| 463 webrtc::kVideoCodecVP8); | |
| 464 } | |
| 465 | |
| 466 void IceRestart() { | |
| 467 offer_answer_constraints_.SetMandatoryIceRestart(true); | |
| 468 offer_answer_options_.ice_restart = true; | |
| 469 SetExpectIceRestart(true); | |
| 470 } | |
| 471 | |
| 472 void SetExpectIceRestart(bool expect_restart) { | |
| 473 expect_ice_restart_ = expect_restart; | |
| 474 } | |
| 475 | |
| 476 bool ExpectIceRestart() const { return expect_ice_restart_; } | |
| 477 | |
| 478 void SetExpectIceRenomination(bool expect_renomination) { | |
| 479 expect_ice_renomination_ = expect_renomination; | |
| 480 } | |
| 481 void SetExpectRemoteIceRenomination(bool expect_renomination) { | |
| 482 expect_remote_ice_renomination_ = expect_renomination; | |
| 483 } | |
| 484 bool ExpectIceRenomination() { return expect_ice_renomination_; } | |
| 485 bool ExpectRemoteIceRenomination() { return expect_remote_ice_renomination_; } | |
| 486 | |
| 487 // The below 3 methods assume streams will be offered. | |
| 488 // Thus they'll only set the "offer to receive" flag to true if it's | |
| 489 // currently false, not if it's just unset. | |
| 490 void SetReceiveAudioVideo(bool audio, bool video) { | |
| 491 SetReceiveAudio(audio); | |
| 492 SetReceiveVideo(video); | |
| 493 ASSERT_EQ(audio, can_receive_audio()); | |
| 494 ASSERT_EQ(video, can_receive_video()); | |
| 495 } | |
| 496 | |
| 497 void SetReceiveAudio(bool audio) { | |
| 498 if (audio && can_receive_audio()) { | |
| 499 return; | |
| 500 } | |
| 501 offer_answer_constraints_.SetMandatoryReceiveAudio(audio); | |
| 502 offer_answer_options_.offer_to_receive_audio = audio ? 1 : 0; | |
| 503 } | |
| 504 | |
| 505 void SetReceiveVideo(bool video) { | |
| 506 if (video && can_receive_video()) { | |
| 507 return; | |
| 508 } | |
| 509 offer_answer_constraints_.SetMandatoryReceiveVideo(video); | |
| 510 offer_answer_options_.offer_to_receive_video = video ? 1 : 0; | |
| 511 } | |
| 512 | |
| 513 void SetOfferToReceiveAudioVideo(bool audio, bool video) { | |
| 514 offer_answer_constraints_.SetMandatoryReceiveAudio(audio); | |
| 515 offer_answer_options_.offer_to_receive_audio = audio ? 1 : 0; | |
| 516 offer_answer_constraints_.SetMandatoryReceiveVideo(video); | |
| 517 offer_answer_options_.offer_to_receive_video = video ? 1 : 0; | |
| 518 } | |
| 519 | |
| 520 void RemoveMsidFromReceivedSdp(bool remove) { remove_msid_ = remove; } | |
| 521 | |
| 522 void RemoveSdesCryptoFromReceivedSdp(bool remove) { remove_sdes_ = remove; } | |
| 523 | |
| 524 void RemoveBundleFromReceivedSdp(bool remove) { remove_bundle_ = remove; } | |
| 525 | |
| 526 void RemoveCvoFromReceivedSdp(bool remove) { remove_cvo_ = remove; } | |
| 527 | |
| 528 bool can_receive_audio() { | |
| 529 bool value; | |
| 530 if (prefer_constraint_apis_) { | |
| 531 if (webrtc::FindConstraint( | |
| 532 &offer_answer_constraints_, | |
| 533 MediaConstraintsInterface::kOfferToReceiveAudio, &value, | |
| 534 nullptr)) { | |
| 535 return value; | |
| 536 } | |
| 537 return true; | |
| 538 } | |
| 539 return offer_answer_options_.offer_to_receive_audio > 0 || | |
| 540 offer_answer_options_.offer_to_receive_audio == | |
| 541 PeerConnectionInterface::RTCOfferAnswerOptions::kUndefined; | |
| 542 } | |
| 543 | |
| 544 bool can_receive_video() { | |
| 545 bool value; | |
| 546 if (prefer_constraint_apis_) { | |
| 547 if (webrtc::FindConstraint( | |
| 548 &offer_answer_constraints_, | |
| 549 MediaConstraintsInterface::kOfferToReceiveVideo, &value, | |
| 550 nullptr)) { | |
| 551 return value; | |
| 552 } | |
| 553 return true; | |
| 554 } | |
| 555 return offer_answer_options_.offer_to_receive_video > 0 || | |
| 556 offer_answer_options_.offer_to_receive_video == | |
| 557 PeerConnectionInterface::RTCOfferAnswerOptions::kUndefined; | |
| 558 } | |
| 559 | |
| 560 void OnDataChannel( | |
| 561 rtc::scoped_refptr<DataChannelInterface> data_channel) override { | |
| 562 LOG(INFO) << id_ << "OnDataChannel"; | |
| 563 data_channel_ = data_channel; | |
| 564 data_observer_.reset(new MockDataChannelObserver(data_channel)); | |
| 565 } | |
| 566 | |
| 567 void CreateDataChannel() { CreateDataChannel(nullptr); } | |
| 568 | |
| 569 void CreateDataChannel(const webrtc::DataChannelInit* init) { | |
| 570 data_channel_ = pc()->CreateDataChannel(kDataChannelLabel, init); | |
| 571 ASSERT_TRUE(data_channel_.get() != nullptr); | |
| 572 data_observer_.reset(new MockDataChannelObserver(data_channel_)); | |
| 573 } | |
| 574 | |
| 575 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack( | |
| 576 const std::string& stream_label) { | |
| 577 FakeConstraints constraints; | |
| 578 // Disable highpass filter so that we can get all the test audio frames. | |
| 579 constraints.AddMandatory(MediaConstraintsInterface::kHighpassFilter, false); | |
| 580 rtc::scoped_refptr<webrtc::AudioSourceInterface> source = | |
| 581 peer_connection_factory_->CreateAudioSource(&constraints); | |
| 582 // TODO(perkj): Test audio source when it is implemented. Currently audio | |
| 583 // always use the default input. | |
| 584 std::string label = stream_label + kAudioTrackLabelBase; | |
| 585 return peer_connection_factory_->CreateAudioTrack(label, source); | |
| 586 } | |
| 587 | |
| 588 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack( | |
| 589 const std::string& stream_label) { | |
| 590 // Set max frame rate to 10fps to reduce the risk of the tests to be flaky. | |
| 591 FakeConstraints source_constraints = video_constraints_; | |
| 592 source_constraints.SetMandatoryMaxFrameRate(10); | |
| 593 | |
| 594 cricket::FakeVideoCapturer* fake_capturer = | |
| 595 new webrtc::FakePeriodicVideoCapturer(); | |
| 596 fake_capturer->SetRotation(capture_rotation_); | |
| 597 video_capturers_.push_back(fake_capturer); | |
| 598 rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source = | |
| 599 peer_connection_factory_->CreateVideoSource(fake_capturer, | |
| 600 &source_constraints); | |
| 601 std::string label = stream_label + kVideoTrackLabelBase; | |
| 602 | |
| 603 rtc::scoped_refptr<webrtc::VideoTrackInterface> track( | |
| 604 peer_connection_factory_->CreateVideoTrack(label, source)); | |
| 605 if (!local_video_renderer_) { | |
| 606 local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track)); | |
| 607 } | |
| 608 return track; | |
| 609 } | |
| 610 | |
| 611 DataChannelInterface* data_channel() { return data_channel_; } | |
| 612 const MockDataChannelObserver* data_observer() const { | |
| 613 return data_observer_.get(); | |
| 614 } | |
| 615 | |
| 616 webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); } | |
| 617 | |
| 618 void StopVideoCapturers() { | |
| 619 for (auto* capturer : video_capturers_) { | |
| 620 capturer->Stop(); | |
| 621 } | |
| 622 } | |
| 623 | |
| 624 void SetCaptureRotation(webrtc::VideoRotation rotation) { | |
| 625 ASSERT_TRUE(video_capturers_.empty()); | |
| 626 capture_rotation_ = rotation; | |
| 627 } | |
| 628 | |
| 629 bool AudioFramesReceivedCheck(int number_of_frames) const { | |
| 630 return number_of_frames <= fake_audio_capture_module_->frames_received(); | |
| 631 } | |
| 632 | |
| 633 int audio_frames_received() const { | |
| 634 return fake_audio_capture_module_->frames_received(); | |
| 635 } | |
| 636 | |
| 637 bool VideoFramesReceivedCheck(int number_of_frames) { | |
| 638 if (video_decoder_factory_enabled_) { | |
| 639 const std::vector<FakeWebRtcVideoDecoder*>& decoders | |
| 640 = fake_video_decoder_factory_->decoders(); | |
| 641 if (decoders.empty()) { | |
| 642 return number_of_frames <= 0; | |
| 643 } | |
| 644 // Note - this checks that EACH decoder has the requisite number | |
| 645 // of frames. The video_frames_received() function sums them. | |
| 646 for (FakeWebRtcVideoDecoder* decoder : decoders) { | |
| 647 if (number_of_frames > decoder->GetNumFramesReceived()) { | |
| 648 return false; | |
| 649 } | |
| 650 } | |
| 651 return true; | |
| 652 } else { | |
| 653 if (fake_video_renderers_.empty()) { | |
| 654 return number_of_frames <= 0; | |
| 655 } | |
| 656 | |
| 657 for (const auto& pair : fake_video_renderers_) { | |
| 658 if (number_of_frames > pair.second->num_rendered_frames()) { | |
| 659 return false; | |
| 660 } | |
| 661 } | |
| 662 return true; | |
| 663 } | |
| 664 } | |
| 665 | |
| 666 int video_frames_received() const { | |
| 667 int total = 0; | |
| 668 if (video_decoder_factory_enabled_) { | |
| 669 const std::vector<FakeWebRtcVideoDecoder*>& decoders = | |
| 670 fake_video_decoder_factory_->decoders(); | |
| 671 for (const FakeWebRtcVideoDecoder* decoder : decoders) { | |
| 672 total += decoder->GetNumFramesReceived(); | |
| 673 } | |
| 674 } else { | |
| 675 for (const auto& pair : fake_video_renderers_) { | |
| 676 total += pair.second->num_rendered_frames(); | |
| 677 } | |
| 678 for (const auto& renderer : removed_fake_video_renderers_) { | |
| 679 total += renderer->num_rendered_frames(); | |
| 680 } | |
| 681 } | |
| 682 return total; | |
| 683 } | |
| 684 | |
| 685 // Verify the CreateDtmfSender interface | |
| 686 void VerifyDtmf() { | |
| 687 std::unique_ptr<DummyDtmfObserver> observer(new DummyDtmfObserver()); | |
| 688 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender; | |
| 689 | |
| 690 // We can't create a DTMF sender with an invalid audio track or a non local | |
| 691 // track. | |
| 692 EXPECT_TRUE(peer_connection_->CreateDtmfSender(nullptr) == nullptr); | |
| 693 rtc::scoped_refptr<webrtc::AudioTrackInterface> non_localtrack( | |
| 694 peer_connection_factory_->CreateAudioTrack("dummy_track", nullptr)); | |
| 695 EXPECT_TRUE(peer_connection_->CreateDtmfSender(non_localtrack) == nullptr); | |
| 696 | |
| 697 // We should be able to create a DTMF sender from a local track. | |
| 698 webrtc::AudioTrackInterface* localtrack = | |
| 699 peer_connection_->local_streams()->at(0)->GetAudioTracks()[0]; | |
| 700 dtmf_sender = peer_connection_->CreateDtmfSender(localtrack); | |
| 701 EXPECT_TRUE(dtmf_sender.get() != nullptr); | |
| 702 dtmf_sender->RegisterObserver(observer.get()); | |
| 703 | |
| 704 // Test the DtmfSender object just created. | |
| 705 EXPECT_TRUE(dtmf_sender->CanInsertDtmf()); | |
| 706 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50)); | |
| 707 | |
| 708 // We don't need to verify that the DTMF tones are actually sent out because | |
| 709 // that is already covered by the tests of the lower level components. | |
| 710 | |
| 711 EXPECT_TRUE_WAIT(observer->completed(), kMaxWaitMs); | |
| 712 std::vector<std::string> tones; | |
| 713 tones.push_back("1"); | |
| 714 tones.push_back("a"); | |
| 715 tones.push_back(""); | |
| 716 observer->Verify(tones); | |
| 717 | |
| 718 dtmf_sender->UnregisterObserver(); | |
| 719 } | |
| 720 | |
| 721 // Verifies that the SessionDescription have rejected the appropriate media | |
| 722 // content. | |
| 723 void VerifyRejectedMediaInSessionDescription() { | |
| 724 ASSERT_TRUE(peer_connection_->remote_description() != nullptr); | |
| 725 ASSERT_TRUE(peer_connection_->local_description() != nullptr); | |
| 726 const cricket::SessionDescription* remote_desc = | |
| 727 peer_connection_->remote_description()->description(); | |
| 728 const cricket::SessionDescription* local_desc = | |
| 729 peer_connection_->local_description()->description(); | |
| 730 | |
| 731 const ContentInfo* remote_audio_content = GetFirstAudioContent(remote_desc); | |
| 732 if (remote_audio_content) { | |
| 733 const ContentInfo* audio_content = | |
| 734 GetFirstAudioContent(local_desc); | |
| 735 EXPECT_EQ(can_receive_audio(), !audio_content->rejected); | |
| 736 } | |
| 737 | |
| 738 const ContentInfo* remote_video_content = GetFirstVideoContent(remote_desc); | |
| 739 if (remote_video_content) { | |
| 740 const ContentInfo* video_content = | |
| 741 GetFirstVideoContent(local_desc); | |
| 742 EXPECT_EQ(can_receive_video(), !video_content->rejected); | |
| 743 } | |
| 744 } | |
| 745 | |
| 746 void VerifyLocalIceUfragAndPassword() { | |
| 747 ASSERT_TRUE(peer_connection_->local_description() != nullptr); | |
| 748 const cricket::SessionDescription* desc = | |
| 749 peer_connection_->local_description()->description(); | |
| 750 const cricket::ContentInfos& contents = desc->contents(); | |
| 751 | |
| 752 for (size_t index = 0; index < contents.size(); ++index) { | |
| 753 if (contents[index].rejected) | |
| 754 continue; | |
| 755 const cricket::TransportDescription* transport_desc = | |
| 756 desc->GetTransportDescriptionByName(contents[index].name); | |
| 757 | |
| 758 std::map<int, IceUfragPwdPair>::const_iterator ufragpair_it = | |
| 759 ice_ufrag_pwd_.find(static_cast<int>(index)); | |
| 760 if (ufragpair_it == ice_ufrag_pwd_.end()) { | |
| 761 ASSERT_FALSE(ExpectIceRestart()); | |
| 762 ice_ufrag_pwd_[static_cast<int>(index)] = | |
| 763 IceUfragPwdPair(transport_desc->ice_ufrag, transport_desc->ice_pwd); | |
| 764 } else if (ExpectIceRestart()) { | |
| 765 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second; | |
| 766 EXPECT_NE(ufrag_pwd.first, transport_desc->ice_ufrag); | |
| 767 EXPECT_NE(ufrag_pwd.second, transport_desc->ice_pwd); | |
| 768 } else { | |
| 769 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second; | |
| 770 EXPECT_EQ(ufrag_pwd.first, transport_desc->ice_ufrag); | |
| 771 EXPECT_EQ(ufrag_pwd.second, transport_desc->ice_pwd); | |
| 772 } | |
| 773 } | |
| 774 } | |
| 775 | |
| 776 void VerifyLocalIceRenomination() { | |
| 777 ASSERT_TRUE(peer_connection_->local_description() != nullptr); | |
| 778 const cricket::SessionDescription* desc = | |
| 779 peer_connection_->local_description()->description(); | |
| 780 const cricket::ContentInfos& contents = desc->contents(); | |
| 781 | |
| 782 for (auto content : contents) { | |
| 783 if (content.rejected) | |
| 784 continue; | |
| 785 const cricket::TransportDescription* transport_desc = | |
| 786 desc->GetTransportDescriptionByName(content.name); | |
| 787 const auto& options = transport_desc->transport_options; | |
| 788 auto iter = std::find(options.begin(), options.end(), | |
| 789 cricket::ICE_RENOMINATION_STR); | |
| 790 EXPECT_EQ(ExpectIceRenomination(), iter != options.end()); | |
| 791 } | |
| 792 } | |
| 793 | |
| 794 void VerifyRemoteIceRenomination() { | |
| 795 ASSERT_TRUE(peer_connection_->remote_description() != nullptr); | |
| 796 const cricket::SessionDescription* desc = | |
| 797 peer_connection_->remote_description()->description(); | |
| 798 const cricket::ContentInfos& contents = desc->contents(); | |
| 799 | |
| 800 for (auto content : contents) { | |
| 801 if (content.rejected) | |
| 802 continue; | |
| 803 const cricket::TransportDescription* transport_desc = | |
| 804 desc->GetTransportDescriptionByName(content.name); | |
| 805 const auto& options = transport_desc->transport_options; | |
| 806 auto iter = std::find(options.begin(), options.end(), | |
| 807 cricket::ICE_RENOMINATION_STR); | |
| 808 EXPECT_EQ(ExpectRemoteIceRenomination(), iter != options.end()); | |
| 809 } | |
| 810 } | |
| 811 | |
| 812 int GetAudioOutputLevelStats(webrtc::MediaStreamTrackInterface* track) { | |
| 813 rtc::scoped_refptr<MockStatsObserver> | |
| 814 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
| 815 EXPECT_TRUE(peer_connection_->GetStats( | |
| 816 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
| 817 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 818 EXPECT_NE(0, observer->timestamp()); | |
| 819 return observer->AudioOutputLevel(); | |
| 820 } | |
| 821 | |
| 822 int GetAudioInputLevelStats() { | |
| 823 rtc::scoped_refptr<MockStatsObserver> | |
| 824 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
| 825 EXPECT_TRUE(peer_connection_->GetStats( | |
| 826 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
| 827 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 828 EXPECT_NE(0, observer->timestamp()); | |
| 829 return observer->AudioInputLevel(); | |
| 830 } | |
| 831 | |
| 832 int GetBytesReceivedStats(webrtc::MediaStreamTrackInterface* track) { | |
| 833 rtc::scoped_refptr<MockStatsObserver> | |
| 834 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
| 835 EXPECT_TRUE(peer_connection_->GetStats( | |
| 836 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
| 837 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 838 EXPECT_NE(0, observer->timestamp()); | |
| 839 return observer->BytesReceived(); | |
| 840 } | |
| 841 | |
| 842 int GetBytesSentStats(webrtc::MediaStreamTrackInterface* track) { | |
| 843 rtc::scoped_refptr<MockStatsObserver> | |
| 844 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
| 845 EXPECT_TRUE(peer_connection_->GetStats( | |
| 846 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
| 847 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 848 EXPECT_NE(0, observer->timestamp()); | |
| 849 return observer->BytesSent(); | |
| 850 } | |
| 851 | |
| 852 int GetAvailableReceivedBandwidthStats() { | |
| 853 rtc::scoped_refptr<MockStatsObserver> | |
| 854 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
| 855 EXPECT_TRUE(peer_connection_->GetStats( | |
| 856 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
| 857 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 858 EXPECT_NE(0, observer->timestamp()); | |
| 859 int bw = observer->AvailableReceiveBandwidth(); | |
| 860 return bw; | |
| 861 } | |
| 862 | |
| 863 std::string GetDtlsCipherStats() { | |
| 864 rtc::scoped_refptr<MockStatsObserver> | |
| 865 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
| 866 EXPECT_TRUE(peer_connection_->GetStats( | |
| 867 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
| 868 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 869 EXPECT_NE(0, observer->timestamp()); | |
| 870 return observer->DtlsCipher(); | |
| 871 } | |
| 872 | |
| 873 std::string GetSrtpCipherStats() { | |
| 874 rtc::scoped_refptr<MockStatsObserver> | |
| 875 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
| 876 EXPECT_TRUE(peer_connection_->GetStats( | |
| 877 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
| 878 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 879 EXPECT_NE(0, observer->timestamp()); | |
| 880 return observer->SrtpCipher(); | |
| 881 } | |
| 882 | |
| 883 int rendered_width() { | |
| 884 EXPECT_FALSE(fake_video_renderers_.empty()); | |
| 885 return fake_video_renderers_.empty() ? 1 : | |
| 886 fake_video_renderers_.begin()->second->width(); | |
| 887 } | |
| 888 | |
| 889 int rendered_height() { | |
| 890 EXPECT_FALSE(fake_video_renderers_.empty()); | |
| 891 return fake_video_renderers_.empty() ? 1 : | |
| 892 fake_video_renderers_.begin()->second->height(); | |
| 893 } | |
| 894 | |
| 895 webrtc::VideoRotation rendered_rotation() { | |
| 896 EXPECT_FALSE(fake_video_renderers_.empty()); | |
| 897 return fake_video_renderers_.empty() | |
| 898 ? webrtc::kVideoRotation_0 | |
| 899 : fake_video_renderers_.begin()->second->rotation(); | |
| 900 } | |
| 901 | |
| 902 int local_rendered_width() { | |
| 903 return local_video_renderer_ ? local_video_renderer_->width() : 1; | |
| 904 } | |
| 905 | |
| 906 int local_rendered_height() { | |
| 907 return local_video_renderer_ ? local_video_renderer_->height() : 1; | |
| 908 } | |
| 909 | |
| 910 size_t number_of_remote_streams() { | |
| 911 if (!pc()) | |
| 912 return 0; | |
| 913 return pc()->remote_streams()->count(); | |
| 914 } | |
| 915 | |
| 916 StreamCollectionInterface* remote_streams() const { | |
| 917 if (!pc()) { | |
| 918 ADD_FAILURE(); | |
| 919 return nullptr; | |
| 920 } | |
| 921 return pc()->remote_streams(); | |
| 922 } | |
| 923 | |
| 924 StreamCollectionInterface* local_streams() { | |
| 925 if (!pc()) { | |
| 926 ADD_FAILURE(); | |
| 927 return nullptr; | |
| 928 } | |
| 929 return pc()->local_streams(); | |
| 930 } | |
| 931 | |
| 932 bool HasLocalAudioTrack() { return StreamsHaveAudioTrack(local_streams()); } | |
| 933 | |
| 934 bool HasLocalVideoTrack() { return StreamsHaveVideoTrack(local_streams()); } | |
| 935 | |
| 936 webrtc::PeerConnectionInterface::SignalingState signaling_state() { | |
| 937 return pc()->signaling_state(); | |
| 938 } | |
| 939 | |
| 940 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() { | |
| 941 return pc()->ice_connection_state(); | |
| 942 } | |
| 943 | |
| 944 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() { | |
| 945 return pc()->ice_gathering_state(); | |
| 946 } | |
| 947 | |
| 948 std::vector<std::unique_ptr<MockRtpReceiverObserver>> const& | |
| 949 rtp_receiver_observers() { | |
| 950 return rtp_receiver_observers_; | |
| 951 } | |
| 952 | |
| 953 void SetRtpReceiverObservers() { | |
| 954 rtp_receiver_observers_.clear(); | |
| 955 for (auto receiver : pc()->GetReceivers()) { | |
| 956 std::unique_ptr<MockRtpReceiverObserver> observer( | |
| 957 new MockRtpReceiverObserver(receiver->media_type())); | |
| 958 receiver->SetObserver(observer.get()); | |
| 959 rtp_receiver_observers_.push_back(std::move(observer)); | |
| 960 } | |
| 961 } | |
| 962 | |
| 963 private: | |
| 964 class DummyDtmfObserver : public DtmfSenderObserverInterface { | |
| 965 public: | |
| 966 DummyDtmfObserver() : completed_(false) {} | |
| 967 | |
| 968 // Implements DtmfSenderObserverInterface. | |
| 969 void OnToneChange(const std::string& tone) override { | |
| 970 tones_.push_back(tone); | |
| 971 if (tone.empty()) { | |
| 972 completed_ = true; | |
| 973 } | |
| 974 } | |
| 975 | |
| 976 void Verify(const std::vector<std::string>& tones) const { | |
| 977 ASSERT_TRUE(tones_.size() == tones.size()); | |
| 978 EXPECT_TRUE(std::equal(tones.begin(), tones.end(), tones_.begin())); | |
| 979 } | |
| 980 | |
| 981 bool completed() const { return completed_; } | |
| 982 | |
| 983 private: | |
| 984 bool completed_; | |
| 985 std::vector<std::string> tones_; | |
| 986 }; | |
| 987 | |
| 988 explicit PeerConnectionTestClient(const std::string& id) : id_(id) {} | |
| 989 | |
| 990 bool Init( | |
| 991 const MediaConstraintsInterface* constraints, | |
| 992 const PeerConnectionFactory::Options* options, | |
| 993 const PeerConnectionInterface::RTCConfiguration* config, | |
| 994 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator, | |
| 995 bool prefer_constraint_apis, | |
| 996 rtc::Thread* network_thread, | |
| 997 rtc::Thread* worker_thread) { | |
| 998 EXPECT_TRUE(!peer_connection_); | |
| 999 EXPECT_TRUE(!peer_connection_factory_); | |
| 1000 if (!prefer_constraint_apis) { | |
| 1001 EXPECT_TRUE(!constraints); | |
| 1002 } | |
| 1003 prefer_constraint_apis_ = prefer_constraint_apis; | |
| 1004 | |
| 1005 fake_network_manager_.reset(new rtc::FakeNetworkManager()); | |
| 1006 fake_network_manager_->AddInterface(rtc::SocketAddress("192.168.1.1", 0)); | |
| 1007 | |
| 1008 std::unique_ptr<cricket::PortAllocator> port_allocator( | |
| 1009 new cricket::BasicPortAllocator(fake_network_manager_.get())); | |
| 1010 fake_audio_capture_module_ = FakeAudioCaptureModule::Create(); | |
| 1011 | |
| 1012 if (fake_audio_capture_module_ == nullptr) { | |
| 1013 return false; | |
| 1014 } | |
| 1015 fake_video_decoder_factory_ = new FakeWebRtcVideoDecoderFactory(); | |
| 1016 fake_video_encoder_factory_ = new FakeWebRtcVideoEncoderFactory(); | |
| 1017 rtc::Thread* const signaling_thread = rtc::Thread::Current(); | |
| 1018 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( | |
| 1019 network_thread, worker_thread, signaling_thread, | |
| 1020 fake_audio_capture_module_, fake_video_encoder_factory_, | |
| 1021 fake_video_decoder_factory_); | |
| 1022 if (!peer_connection_factory_) { | |
| 1023 return false; | |
| 1024 } | |
| 1025 if (options) { | |
| 1026 peer_connection_factory_->SetOptions(*options); | |
| 1027 } | |
| 1028 peer_connection_ = | |
| 1029 CreatePeerConnection(std::move(port_allocator), constraints, config, | |
| 1030 std::move(cert_generator)); | |
| 1031 return peer_connection_.get() != nullptr; | |
| 1032 } | |
| 1033 | |
| 1034 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection( | |
| 1035 std::unique_ptr<cricket::PortAllocator> port_allocator, | |
| 1036 const MediaConstraintsInterface* constraints, | |
| 1037 const PeerConnectionInterface::RTCConfiguration* config, | |
| 1038 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) { | |
| 1039 // CreatePeerConnection with RTCConfiguration. | |
| 1040 PeerConnectionInterface::RTCConfiguration default_config; | |
| 1041 | |
| 1042 if (!config) { | |
| 1043 config = &default_config; | |
| 1044 } | |
| 1045 | |
| 1046 return peer_connection_factory_->CreatePeerConnection( | |
| 1047 *config, constraints, std::move(port_allocator), | |
| 1048 std::move(cert_generator), this); | |
| 1049 } | |
| 1050 | |
| 1051 void HandleIncomingOffer(const std::string& msg) { | |
| 1052 LOG(INFO) << id_ << "HandleIncomingOffer "; | |
| 1053 if (NumberOfLocalMediaStreams() == 0 && auto_add_stream_) { | |
| 1054 // If we are not sending any streams ourselves it is time to add some. | |
| 1055 AddMediaStream(true, true); | |
| 1056 } | |
| 1057 std::unique_ptr<SessionDescriptionInterface> desc( | |
| 1058 webrtc::CreateSessionDescription("offer", msg, nullptr)); | |
| 1059 EXPECT_TRUE(DoSetRemoteDescription(desc.release())); | |
| 1060 // Set the RtpReceiverObserver after receivers are created. | |
| 1061 SetRtpReceiverObservers(); | |
| 1062 std::unique_ptr<SessionDescriptionInterface> answer; | |
| 1063 EXPECT_TRUE(DoCreateAnswer(&answer)); | |
| 1064 std::string sdp; | |
| 1065 EXPECT_TRUE(answer->ToString(&sdp)); | |
| 1066 EXPECT_TRUE(DoSetLocalDescription(answer.release())); | |
| 1067 SendSdpMessage(webrtc::SessionDescriptionInterface::kAnswer, sdp); | |
| 1068 } | |
| 1069 | |
| 1070 void HandleIncomingAnswer(const std::string& msg) { | |
| 1071 LOG(INFO) << id_ << "HandleIncomingAnswer"; | |
| 1072 std::unique_ptr<SessionDescriptionInterface> desc( | |
| 1073 webrtc::CreateSessionDescription("answer", msg, nullptr)); | |
| 1074 EXPECT_TRUE(DoSetRemoteDescription(desc.release())); | |
| 1075 // Set the RtpReceiverObserver after receivers are created. | |
| 1076 SetRtpReceiverObservers(); | |
| 1077 } | |
| 1078 | |
| 1079 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc, | |
| 1080 bool offer) { | |
| 1081 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> | |
| 1082 observer(new rtc::RefCountedObject< | |
| 1083 MockCreateSessionDescriptionObserver>()); | |
| 1084 if (prefer_constraint_apis_) { | |
| 1085 if (offer) { | |
| 1086 pc()->CreateOffer(observer, &offer_answer_constraints_); | |
| 1087 } else { | |
| 1088 pc()->CreateAnswer(observer, &offer_answer_constraints_); | |
| 1089 } | |
| 1090 } else { | |
| 1091 if (offer) { | |
| 1092 pc()->CreateOffer(observer, offer_answer_options_); | |
| 1093 } else { | |
| 1094 pc()->CreateAnswer(observer, offer_answer_options_); | |
| 1095 } | |
| 1096 } | |
| 1097 EXPECT_EQ_WAIT(true, observer->called(), kMaxWaitMs); | |
| 1098 desc->reset(observer->release_desc()); | |
| 1099 if (observer->result() && ExpectIceRestart()) { | |
| 1100 EXPECT_EQ(0u, (*desc)->candidates(0)->count()); | |
| 1101 } | |
| 1102 return observer->result(); | |
| 1103 } | |
| 1104 | |
| 1105 bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc) { | |
| 1106 return DoCreateOfferAnswer(desc, true); | |
| 1107 } | |
| 1108 | |
| 1109 bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc) { | |
| 1110 return DoCreateOfferAnswer(desc, false); | |
| 1111 } | |
| 1112 | |
| 1113 bool DoSetLocalDescription(SessionDescriptionInterface* desc) { | |
| 1114 rtc::scoped_refptr<MockSetSessionDescriptionObserver> | |
| 1115 observer(new rtc::RefCountedObject< | |
| 1116 MockSetSessionDescriptionObserver>()); | |
| 1117 LOG(INFO) << id_ << "SetLocalDescription "; | |
| 1118 pc()->SetLocalDescription(observer, desc); | |
| 1119 // Ignore the observer result. If we wait for the result with | |
| 1120 // EXPECT_TRUE_WAIT, local ice candidates might be sent to the remote peer | |
| 1121 // before the offer which is an error. | |
| 1122 // The reason is that EXPECT_TRUE_WAIT uses | |
| 1123 // rtc::Thread::Current()->ProcessMessages(1); | |
| 1124 // ProcessMessages waits at least 1ms but processes all messages before | |
| 1125 // returning. Since this test is synchronous and send messages to the remote | |
| 1126 // peer whenever a callback is invoked, this can lead to messages being | |
| 1127 // sent to the remote peer in the wrong order. | |
| 1128 // TODO(perkj): Find a way to check the result without risking that the | |
| 1129 // order of sent messages are changed. Ex- by posting all messages that are | |
| 1130 // sent to the remote peer. | |
| 1131 return true; | |
| 1132 } | |
| 1133 | |
| 1134 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) { | |
| 1135 rtc::scoped_refptr<MockSetSessionDescriptionObserver> | |
| 1136 observer(new rtc::RefCountedObject< | |
| 1137 MockSetSessionDescriptionObserver>()); | |
| 1138 LOG(INFO) << id_ << "SetRemoteDescription "; | |
| 1139 pc()->SetRemoteDescription(observer, desc); | |
| 1140 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
| 1141 return observer->result(); | |
| 1142 } | |
| 1143 | |
| 1144 // This modifies all received SDP messages before they are processed. | |
| 1145 void FilterIncomingSdpMessage(std::string* sdp) { | |
| 1146 if (remove_msid_) { | |
| 1147 const char kSdpSsrcAttribute[] = "a=ssrc:"; | |
| 1148 RemoveLinesFromSdp(kSdpSsrcAttribute, sdp); | |
| 1149 const char kSdpMsidSupportedAttribute[] = "a=msid-semantic:"; | |
| 1150 RemoveLinesFromSdp(kSdpMsidSupportedAttribute, sdp); | |
| 1151 } | |
| 1152 if (remove_bundle_) { | |
| 1153 const char kSdpBundleAttribute[] = "a=group:BUNDLE"; | |
| 1154 RemoveLinesFromSdp(kSdpBundleAttribute, sdp); | |
| 1155 } | |
| 1156 if (remove_sdes_) { | |
| 1157 const char kSdpSdesCryptoAttribute[] = "a=crypto"; | |
| 1158 RemoveLinesFromSdp(kSdpSdesCryptoAttribute, sdp); | |
| 1159 } | |
| 1160 if (remove_cvo_) { | |
| 1161 const char kSdpCvoExtenstion[] = "urn:3gpp:video-orientation"; | |
| 1162 RemoveLinesFromSdp(kSdpCvoExtenstion, sdp); | |
| 1163 } | |
| 1164 } | |
| 1165 | |
| 1166 std::string id_; | |
| 1167 | |
| 1168 std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_; | |
| 1169 | |
| 1170 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; | |
| 1171 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> | |
| 1172 peer_connection_factory_; | |
| 1173 | |
| 1174 bool prefer_constraint_apis_ = true; | |
| 1175 bool auto_add_stream_ = true; | |
| 1176 | |
| 1177 typedef std::pair<std::string, std::string> IceUfragPwdPair; | |
| 1178 std::map<int, IceUfragPwdPair> ice_ufrag_pwd_; | |
| 1179 bool expect_ice_restart_ = false; | |
| 1180 bool expect_ice_renomination_ = false; | |
| 1181 bool expect_remote_ice_renomination_ = false; | |
| 1182 | |
| 1183 // Needed to keep track of number of frames sent. | |
| 1184 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_; | |
| 1185 // Needed to keep track of number of frames received. | |
| 1186 std::map<std::string, std::unique_ptr<webrtc::FakeVideoTrackRenderer>> | |
| 1187 fake_video_renderers_; | |
| 1188 // Needed to ensure frames aren't received for removed tracks. | |
| 1189 std::vector<std::unique_ptr<webrtc::FakeVideoTrackRenderer>> | |
| 1190 removed_fake_video_renderers_; | |
| 1191 // Needed to keep track of number of frames received when external decoder | |
| 1192 // used. | |
| 1193 FakeWebRtcVideoDecoderFactory* fake_video_decoder_factory_ = nullptr; | |
| 1194 FakeWebRtcVideoEncoderFactory* fake_video_encoder_factory_ = nullptr; | |
| 1195 bool video_decoder_factory_enabled_ = false; | |
| 1196 webrtc::FakeConstraints video_constraints_; | |
| 1197 | |
| 1198 // For remote peer communication. | |
| 1199 SignalingMessageReceiver* signaling_message_receiver_ = nullptr; | |
| 1200 int signaling_delay_ms_ = 0; | |
| 1201 | |
| 1202 // Store references to the video capturers we've created, so that we can stop | |
| 1203 // them, if required. | |
| 1204 std::vector<cricket::FakeVideoCapturer*> video_capturers_; | |
| 1205 webrtc::VideoRotation capture_rotation_ = webrtc::kVideoRotation_0; | |
| 1206 // |local_video_renderer_| attached to the first created local video track. | |
| 1207 std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_; | |
| 1208 | |
| 1209 webrtc::FakeConstraints offer_answer_constraints_; | |
| 1210 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_; | |
| 1211 bool remove_msid_ = false; // True if MSID should be removed in received SDP. | |
| 1212 bool remove_bundle_ = | |
| 1213 false; // True if bundle should be removed in received SDP. | |
| 1214 bool remove_sdes_ = | |
| 1215 false; // True if a=crypto should be removed in received SDP. | |
| 1216 // |remove_cvo_| is true if extension urn:3gpp:video-orientation should be | |
| 1217 // removed in the received SDP. | |
| 1218 bool remove_cvo_ = false; | |
| 1219 | |
| 1220 rtc::scoped_refptr<DataChannelInterface> data_channel_; | |
| 1221 std::unique_ptr<MockDataChannelObserver> data_observer_; | |
| 1222 | |
| 1223 std::vector<std::unique_ptr<MockRtpReceiverObserver>> rtp_receiver_observers_; | |
| 1224 }; | |
| 1225 | |
| 1226 class P2PTestConductor : public testing::Test { | |
| 1227 public: | |
| 1228 P2PTestConductor() | |
| 1229 : pss_(new rtc::PhysicalSocketServer), | |
| 1230 ss_(new rtc::VirtualSocketServer(pss_.get())), | |
| 1231 network_thread_(new rtc::Thread(ss_.get())), | |
| 1232 worker_thread_(rtc::Thread::Create()) { | |
| 1233 RTC_CHECK(network_thread_->Start()); | |
| 1234 RTC_CHECK(worker_thread_->Start()); | |
| 1235 } | |
| 1236 | |
| 1237 bool SessionActive() { | |
| 1238 return initiating_client_->SessionActive() && | |
| 1239 receiving_client_->SessionActive(); | |
| 1240 } | |
| 1241 | |
| 1242 // Return true if the number of frames provided have been received | |
| 1243 // on the video and audio tracks provided. | |
| 1244 bool FramesHaveArrived(int audio_frames_to_receive, | |
| 1245 int video_frames_to_receive) { | |
| 1246 bool all_good = true; | |
| 1247 if (initiating_client_->HasLocalAudioTrack() && | |
| 1248 receiving_client_->can_receive_audio()) { | |
| 1249 all_good &= | |
| 1250 receiving_client_->AudioFramesReceivedCheck(audio_frames_to_receive); | |
| 1251 } | |
| 1252 if (initiating_client_->HasLocalVideoTrack() && | |
| 1253 receiving_client_->can_receive_video()) { | |
| 1254 all_good &= | |
| 1255 receiving_client_->VideoFramesReceivedCheck(video_frames_to_receive); | |
| 1256 } | |
| 1257 if (receiving_client_->HasLocalAudioTrack() && | |
| 1258 initiating_client_->can_receive_audio()) { | |
| 1259 all_good &= | |
| 1260 initiating_client_->AudioFramesReceivedCheck(audio_frames_to_receive); | |
| 1261 } | |
| 1262 if (receiving_client_->HasLocalVideoTrack() && | |
| 1263 initiating_client_->can_receive_video()) { | |
| 1264 all_good &= | |
| 1265 initiating_client_->VideoFramesReceivedCheck(video_frames_to_receive); | |
| 1266 } | |
| 1267 return all_good; | |
| 1268 } | |
| 1269 | |
| 1270 void VerifyDtmf() { | |
| 1271 initiating_client_->VerifyDtmf(); | |
| 1272 receiving_client_->VerifyDtmf(); | |
| 1273 } | |
| 1274 | |
| 1275 void TestUpdateOfferWithRejectedContent() { | |
| 1276 // Renegotiate, rejecting the video m-line. | |
| 1277 initiating_client_->Negotiate(true, false); | |
| 1278 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); | |
| 1279 | |
| 1280 int pc1_audio_received = initiating_client_->audio_frames_received(); | |
| 1281 int pc1_video_received = initiating_client_->video_frames_received(); | |
| 1282 int pc2_audio_received = receiving_client_->audio_frames_received(); | |
| 1283 int pc2_video_received = receiving_client_->video_frames_received(); | |
| 1284 | |
| 1285 // Wait for some additional audio frames to be received. | |
| 1286 EXPECT_TRUE_WAIT(initiating_client_->AudioFramesReceivedCheck( | |
| 1287 pc1_audio_received + kEndAudioFrameCount) && | |
| 1288 receiving_client_->AudioFramesReceivedCheck( | |
| 1289 pc2_audio_received + kEndAudioFrameCount), | |
| 1290 kMaxWaitForFramesMs); | |
| 1291 | |
| 1292 // During this time, we shouldn't have received any additional video frames | |
| 1293 // for the rejected video tracks. | |
| 1294 EXPECT_EQ(pc1_video_received, initiating_client_->video_frames_received()); | |
| 1295 EXPECT_EQ(pc2_video_received, receiving_client_->video_frames_received()); | |
| 1296 } | |
| 1297 | |
| 1298 void VerifyRenderedAspectRatio(int width, int height) { | |
| 1299 VerifyRenderedAspectRatio(width, height, webrtc::kVideoRotation_0); | |
| 1300 } | |
| 1301 | |
| 1302 void VerifyRenderedAspectRatio(int width, | |
| 1303 int height, | |
| 1304 webrtc::VideoRotation rotation) { | |
| 1305 double expected_aspect_ratio = static_cast<double>(width) / height; | |
| 1306 double receiving_client_rendered_aspect_ratio = | |
| 1307 static_cast<double>(receiving_client()->rendered_width()) / | |
| 1308 receiving_client()->rendered_height(); | |
| 1309 double initializing_client_rendered_aspect_ratio = | |
| 1310 static_cast<double>(initializing_client()->rendered_width()) / | |
| 1311 initializing_client()->rendered_height(); | |
| 1312 double initializing_client_local_rendered_aspect_ratio = | |
| 1313 static_cast<double>(initializing_client()->local_rendered_width()) / | |
| 1314 initializing_client()->local_rendered_height(); | |
| 1315 // Verify end-to-end rendered aspect ratio. | |
| 1316 EXPECT_EQ(expected_aspect_ratio, receiving_client_rendered_aspect_ratio); | |
| 1317 EXPECT_EQ(expected_aspect_ratio, initializing_client_rendered_aspect_ratio); | |
| 1318 // Verify aspect ratio of the local preview. | |
| 1319 EXPECT_EQ(expected_aspect_ratio, | |
| 1320 initializing_client_local_rendered_aspect_ratio); | |
| 1321 | |
| 1322 // Verify rotation. | |
| 1323 EXPECT_EQ(rotation, receiving_client()->rendered_rotation()); | |
| 1324 EXPECT_EQ(rotation, initializing_client()->rendered_rotation()); | |
| 1325 } | |
| 1326 | |
| 1327 void VerifySessionDescriptions() { | |
| 1328 initiating_client_->VerifyRejectedMediaInSessionDescription(); | |
| 1329 receiving_client_->VerifyRejectedMediaInSessionDescription(); | |
| 1330 initiating_client_->VerifyLocalIceUfragAndPassword(); | |
| 1331 receiving_client_->VerifyLocalIceUfragAndPassword(); | |
| 1332 } | |
| 1333 | |
| 1334 ~P2PTestConductor() { | |
| 1335 if (initiating_client_) { | |
| 1336 initiating_client_->set_signaling_message_receiver(nullptr); | |
| 1337 } | |
| 1338 if (receiving_client_) { | |
| 1339 receiving_client_->set_signaling_message_receiver(nullptr); | |
| 1340 } | |
| 1341 } | |
| 1342 | |
| 1343 bool CreateTestClients() { return CreateTestClients(nullptr, nullptr); } | |
| 1344 | |
| 1345 bool CreateTestClients(MediaConstraintsInterface* init_constraints, | |
| 1346 MediaConstraintsInterface* recv_constraints) { | |
| 1347 return CreateTestClients(init_constraints, nullptr, nullptr, | |
| 1348 recv_constraints, nullptr, nullptr); | |
| 1349 } | |
| 1350 | |
| 1351 bool CreateTestClients( | |
| 1352 const PeerConnectionInterface::RTCConfiguration& init_config, | |
| 1353 const PeerConnectionInterface::RTCConfiguration& recv_config) { | |
| 1354 return CreateTestClients(nullptr, nullptr, &init_config, nullptr, nullptr, | |
| 1355 &recv_config); | |
| 1356 } | |
| 1357 | |
| 1358 bool CreateTestClientsThatPreferNoConstraints() { | |
| 1359 initiating_client_.reset( | |
| 1360 PeerConnectionTestClient::CreateClientPreferNoConstraints( | |
| 1361 "Caller: ", nullptr, network_thread_.get(), worker_thread_.get())); | |
| 1362 receiving_client_.reset( | |
| 1363 PeerConnectionTestClient::CreateClientPreferNoConstraints( | |
| 1364 "Callee: ", nullptr, network_thread_.get(), worker_thread_.get())); | |
| 1365 if (!initiating_client_ || !receiving_client_) { | |
| 1366 return false; | |
| 1367 } | |
| 1368 // Remember the choice for possible later resets of the clients. | |
| 1369 prefer_constraint_apis_ = false; | |
| 1370 SetSignalingReceivers(); | |
| 1371 return true; | |
| 1372 } | |
| 1373 | |
| 1374 bool CreateTestClients( | |
| 1375 MediaConstraintsInterface* init_constraints, | |
| 1376 PeerConnectionFactory::Options* init_options, | |
| 1377 const PeerConnectionInterface::RTCConfiguration* init_config, | |
| 1378 MediaConstraintsInterface* recv_constraints, | |
| 1379 PeerConnectionFactory::Options* recv_options, | |
| 1380 const PeerConnectionInterface::RTCConfiguration* recv_config) { | |
| 1381 initiating_client_.reset(PeerConnectionTestClient::CreateClient( | |
| 1382 "Caller: ", init_constraints, init_options, init_config, | |
| 1383 network_thread_.get(), worker_thread_.get())); | |
| 1384 receiving_client_.reset(PeerConnectionTestClient::CreateClient( | |
| 1385 "Callee: ", recv_constraints, recv_options, recv_config, | |
| 1386 network_thread_.get(), worker_thread_.get())); | |
| 1387 if (!initiating_client_ || !receiving_client_) { | |
| 1388 return false; | |
| 1389 } | |
| 1390 SetSignalingReceivers(); | |
| 1391 return true; | |
| 1392 } | |
| 1393 | |
| 1394 void SetSignalingReceivers() { | |
| 1395 initiating_client_->set_signaling_message_receiver(receiving_client_.get()); | |
| 1396 receiving_client_->set_signaling_message_receiver(initiating_client_.get()); | |
| 1397 } | |
| 1398 | |
| 1399 void SetSignalingDelayMs(int delay_ms) { | |
| 1400 initiating_client_->set_signaling_delay_ms(delay_ms); | |
| 1401 receiving_client_->set_signaling_delay_ms(delay_ms); | |
| 1402 } | |
| 1403 | |
| 1404 void SetVideoConstraints(const webrtc::FakeConstraints& init_constraints, | |
| 1405 const webrtc::FakeConstraints& recv_constraints) { | |
| 1406 initiating_client_->SetVideoConstraints(init_constraints); | |
| 1407 receiving_client_->SetVideoConstraints(recv_constraints); | |
| 1408 } | |
| 1409 | |
| 1410 void SetCaptureRotation(webrtc::VideoRotation rotation) { | |
| 1411 initiating_client_->SetCaptureRotation(rotation); | |
| 1412 receiving_client_->SetCaptureRotation(rotation); | |
| 1413 } | |
| 1414 | |
| 1415 void EnableVideoDecoderFactory() { | |
| 1416 initiating_client_->EnableVideoDecoderFactory(); | |
| 1417 receiving_client_->EnableVideoDecoderFactory(); | |
| 1418 } | |
| 1419 | |
| 1420 // This test sets up a call between two parties. Both parties send static | |
| 1421 // frames to each other. Once the test is finished the number of sent frames | |
| 1422 // is compared to the number of received frames. | |
| 1423 void LocalP2PTest() { | |
| 1424 if (initiating_client_->NumberOfLocalMediaStreams() == 0) { | |
| 1425 initiating_client_->AddMediaStream(true, true); | |
| 1426 } | |
| 1427 initiating_client_->Negotiate(); | |
| 1428 // Assert true is used here since next tests are guaranteed to fail and | |
| 1429 // would eat up 5 seconds. | |
| 1430 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); | |
| 1431 VerifySessionDescriptions(); | |
| 1432 | |
| 1433 int audio_frame_count = kEndAudioFrameCount; | |
| 1434 int video_frame_count = kEndVideoFrameCount; | |
| 1435 // TODO(ronghuawu): Add test to cover the case of sendonly and recvonly. | |
| 1436 | |
| 1437 if ((!initiating_client_->can_receive_audio() && | |
| 1438 !initiating_client_->can_receive_video()) || | |
| 1439 (!receiving_client_->can_receive_audio() && | |
| 1440 !receiving_client_->can_receive_video())) { | |
| 1441 // Neither audio nor video will flow, so connections won't be | |
| 1442 // established. There's nothing more to check. | |
| 1443 // TODO(hta): Check connection if there's a data channel. | |
| 1444 return; | |
| 1445 } | |
| 1446 | |
| 1447 // Audio or video is expected to flow, so both clients should reach the | |
| 1448 // Connected state, and the offerer (ICE controller) should proceed to | |
| 1449 // Completed. | |
| 1450 // Note: These tests have been observed to fail under heavy load at | |
| 1451 // shorter timeouts, so they may be flaky. | |
| 1452 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, | |
| 1453 initiating_client_->ice_connection_state(), | |
| 1454 kMaxWaitForFramesMs); | |
| 1455 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, | |
| 1456 receiving_client_->ice_connection_state(), | |
| 1457 kMaxWaitForFramesMs); | |
| 1458 | |
| 1459 // The ICE gathering state should end up in kIceGatheringComplete, | |
| 1460 // but there's a bug that prevents this at the moment, and the state | |
| 1461 // machine is being updated by the WEBRTC WG. | |
| 1462 // TODO(hta): Update this check when spec revisions finish. | |
| 1463 EXPECT_NE(webrtc::PeerConnectionInterface::kIceGatheringNew, | |
| 1464 initiating_client_->ice_gathering_state()); | |
| 1465 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete, | |
| 1466 receiving_client_->ice_gathering_state(), | |
| 1467 kMaxWaitForFramesMs); | |
| 1468 | |
| 1469 // Check that the expected number of frames have arrived. | |
| 1470 EXPECT_TRUE_WAIT(FramesHaveArrived(audio_frame_count, video_frame_count), | |
| 1471 kMaxWaitForFramesMs); | |
| 1472 } | |
| 1473 | |
| 1474 void SetupAndVerifyDtlsCall() { | |
| 1475 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
| 1476 FakeConstraints setup_constraints; | |
| 1477 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1478 true); | |
| 1479 // Disable resolution adaptation, we don't want it interfering with the | |
| 1480 // test results. | |
| 1481 webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; | |
| 1482 rtc_config.set_cpu_adaptation(false); | |
| 1483 | |
| 1484 ASSERT_TRUE(CreateTestClients(&setup_constraints, nullptr, &rtc_config, | |
| 1485 &setup_constraints, nullptr, &rtc_config)); | |
| 1486 LocalP2PTest(); | |
| 1487 VerifyRenderedAspectRatio(640, 480); | |
| 1488 } | |
| 1489 | |
| 1490 PeerConnectionTestClient* CreateDtlsClientWithAlternateKey() { | |
| 1491 FakeConstraints setup_constraints; | |
| 1492 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1493 true); | |
| 1494 // Disable resolution adaptation, we don't want it interfering with the | |
| 1495 // test results. | |
| 1496 webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; | |
| 1497 rtc_config.set_cpu_adaptation(false); | |
| 1498 | |
| 1499 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator( | |
| 1500 rtc::SSLStreamAdapter::HaveDtlsSrtp() ? | |
| 1501 new FakeRTCCertificateGenerator() : nullptr); | |
| 1502 cert_generator->use_alternate_key(); | |
| 1503 | |
| 1504 // Make sure the new client is using a different certificate. | |
| 1505 return PeerConnectionTestClient::CreateClientWithDtlsIdentityStore( | |
| 1506 "New Peer: ", &setup_constraints, nullptr, &rtc_config, | |
| 1507 std::move(cert_generator), prefer_constraint_apis_, | |
| 1508 network_thread_.get(), worker_thread_.get()); | |
| 1509 } | |
| 1510 | |
| 1511 void SendRtpData(webrtc::DataChannelInterface* dc, const std::string& data) { | |
| 1512 // Messages may get lost on the unreliable DataChannel, so we send multiple | |
| 1513 // times to avoid test flakiness. | |
| 1514 static const size_t kSendAttempts = 5; | |
| 1515 | |
| 1516 for (size_t i = 0; i < kSendAttempts; ++i) { | |
| 1517 dc->Send(DataBuffer(data)); | |
| 1518 } | |
| 1519 } | |
| 1520 | |
| 1521 rtc::Thread* network_thread() { return network_thread_.get(); } | |
| 1522 | |
| 1523 rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); } | |
| 1524 | |
| 1525 PeerConnectionTestClient* initializing_client() { | |
| 1526 return initiating_client_.get(); | |
| 1527 } | |
| 1528 | |
| 1529 // Set the |initiating_client_| to the |client| passed in and return the | |
| 1530 // original |initiating_client_|. | |
| 1531 PeerConnectionTestClient* set_initializing_client( | |
| 1532 PeerConnectionTestClient* client) { | |
| 1533 PeerConnectionTestClient* old = initiating_client_.release(); | |
| 1534 initiating_client_.reset(client); | |
| 1535 return old; | |
| 1536 } | |
| 1537 | |
| 1538 PeerConnectionTestClient* receiving_client() { | |
| 1539 return receiving_client_.get(); | |
| 1540 } | |
| 1541 | |
| 1542 // Set the |receiving_client_| to the |client| passed in and return the | |
| 1543 // original |receiving_client_|. | |
| 1544 PeerConnectionTestClient* set_receiving_client( | |
| 1545 PeerConnectionTestClient* client) { | |
| 1546 PeerConnectionTestClient* old = receiving_client_.release(); | |
| 1547 receiving_client_.reset(client); | |
| 1548 return old; | |
| 1549 } | |
| 1550 | |
| 1551 bool AllObserversReceived( | |
| 1552 const std::vector<std::unique_ptr<MockRtpReceiverObserver>>& observers) { | |
| 1553 for (auto& observer : observers) { | |
| 1554 if (!observer->first_packet_received()) { | |
| 1555 return false; | |
| 1556 } | |
| 1557 } | |
| 1558 return true; | |
| 1559 } | |
| 1560 | |
| 1561 void TestGcmNegotiation(bool local_gcm_enabled, bool remote_gcm_enabled, | |
| 1562 int expected_cipher_suite) { | |
| 1563 PeerConnectionFactory::Options init_options; | |
| 1564 init_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled; | |
| 1565 PeerConnectionFactory::Options recv_options; | |
| 1566 recv_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled; | |
| 1567 ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr, | |
| 1568 &recv_options, nullptr)); | |
| 1569 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
| 1570 init_observer = | |
| 1571 new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
| 1572 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
| 1573 LocalP2PTest(); | |
| 1574 | |
| 1575 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite), | |
| 1576 initializing_client()->GetSrtpCipherStats(), | |
| 1577 kMaxWaitMs); | |
| 1578 EXPECT_EQ(1, | |
| 1579 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
| 1580 expected_cipher_suite)); | |
| 1581 } | |
| 1582 | |
| 1583 private: | |
| 1584 // |ss_| is used by |network_thread_| so it must be destroyed later. | |
| 1585 std::unique_ptr<rtc::PhysicalSocketServer> pss_; | |
| 1586 std::unique_ptr<rtc::VirtualSocketServer> ss_; | |
| 1587 // |network_thread_| and |worker_thread_| are used by both | |
| 1588 // |initiating_client_| and |receiving_client_| so they must be destroyed | |
| 1589 // later. | |
| 1590 std::unique_ptr<rtc::Thread> network_thread_; | |
| 1591 std::unique_ptr<rtc::Thread> worker_thread_; | |
| 1592 std::unique_ptr<PeerConnectionTestClient> initiating_client_; | |
| 1593 std::unique_ptr<PeerConnectionTestClient> receiving_client_; | |
| 1594 bool prefer_constraint_apis_ = true; | |
| 1595 }; | |
| 1596 | |
| 1597 // Disable for TSan v2, see | |
| 1598 // https://code.google.com/p/webrtc/issues/detail?id=1205 for details. | |
| 1599 #if !defined(THREAD_SANITIZER) | |
| 1600 | |
| 1601 TEST_F(P2PTestConductor, TestRtpReceiverObserverCallbackFunction) { | |
| 1602 ASSERT_TRUE(CreateTestClients()); | |
| 1603 LocalP2PTest(); | |
| 1604 EXPECT_TRUE_WAIT( | |
| 1605 AllObserversReceived(initializing_client()->rtp_receiver_observers()), | |
| 1606 kMaxWaitForFramesMs); | |
| 1607 EXPECT_TRUE_WAIT( | |
| 1608 AllObserversReceived(receiving_client()->rtp_receiver_observers()), | |
| 1609 kMaxWaitForFramesMs); | |
| 1610 } | |
| 1611 | |
| 1612 // The observers are expected to fire the signal even if they are set after the | |
| 1613 // first packet is received. | |
| 1614 TEST_F(P2PTestConductor, TestSetRtpReceiverObserverAfterFirstPacketIsReceived) { | |
| 1615 ASSERT_TRUE(CreateTestClients()); | |
| 1616 LocalP2PTest(); | |
| 1617 // Reset the RtpReceiverObservers. | |
| 1618 initializing_client()->SetRtpReceiverObservers(); | |
| 1619 receiving_client()->SetRtpReceiverObservers(); | |
| 1620 EXPECT_TRUE_WAIT( | |
| 1621 AllObserversReceived(initializing_client()->rtp_receiver_observers()), | |
| 1622 kMaxWaitForFramesMs); | |
| 1623 EXPECT_TRUE_WAIT( | |
| 1624 AllObserversReceived(receiving_client()->rtp_receiver_observers()), | |
| 1625 kMaxWaitForFramesMs); | |
| 1626 } | |
| 1627 | |
| 1628 // This test sets up a Jsep call between two parties and test Dtmf. | |
| 1629 // TODO(holmer): Disabled due to sometimes crashing on buildbots. | |
| 1630 // See issue webrtc/2378. | |
| 1631 TEST_F(P2PTestConductor, DISABLED_LocalP2PTestDtmf) { | |
| 1632 ASSERT_TRUE(CreateTestClients()); | |
| 1633 LocalP2PTest(); | |
| 1634 VerifyDtmf(); | |
| 1635 } | |
| 1636 | |
| 1637 // This test sets up a Jsep call between two parties and test that we can get a | |
| 1638 // video aspect ratio of 16:9. | |
| 1639 TEST_F(P2PTestConductor, LocalP2PTest16To9) { | |
| 1640 ASSERT_TRUE(CreateTestClients()); | |
| 1641 FakeConstraints constraint; | |
| 1642 double requested_ratio = 640.0/360; | |
| 1643 constraint.SetMandatoryMinAspectRatio(requested_ratio); | |
| 1644 SetVideoConstraints(constraint, constraint); | |
| 1645 LocalP2PTest(); | |
| 1646 | |
| 1647 ASSERT_LE(0, initializing_client()->rendered_height()); | |
| 1648 double initiating_video_ratio = | |
| 1649 static_cast<double>(initializing_client()->rendered_width()) / | |
| 1650 initializing_client()->rendered_height(); | |
| 1651 EXPECT_LE(requested_ratio, initiating_video_ratio); | |
| 1652 | |
| 1653 ASSERT_LE(0, receiving_client()->rendered_height()); | |
| 1654 double receiving_video_ratio = | |
| 1655 static_cast<double>(receiving_client()->rendered_width()) / | |
| 1656 receiving_client()->rendered_height(); | |
| 1657 EXPECT_LE(requested_ratio, receiving_video_ratio); | |
| 1658 } | |
| 1659 | |
| 1660 // This test sets up a Jsep call between two parties and test that the | |
| 1661 // received video has a resolution of 1280*720. | |
| 1662 // TODO(mallinath): Enable when | |
| 1663 // http://code.google.com/p/webrtc/issues/detail?id=981 is fixed. | |
| 1664 TEST_F(P2PTestConductor, DISABLED_LocalP2PTest1280By720) { | |
| 1665 ASSERT_TRUE(CreateTestClients()); | |
| 1666 FakeConstraints constraint; | |
| 1667 constraint.SetMandatoryMinWidth(1280); | |
| 1668 constraint.SetMandatoryMinHeight(720); | |
| 1669 SetVideoConstraints(constraint, constraint); | |
| 1670 LocalP2PTest(); | |
| 1671 VerifyRenderedAspectRatio(1280, 720); | |
| 1672 } | |
| 1673 | |
| 1674 // This test sets up a call between two endpoints that are configured to use | |
| 1675 // DTLS key agreement. As a result, DTLS is negotiated and used for transport. | |
| 1676 TEST_F(P2PTestConductor, LocalP2PTestDtls) { | |
| 1677 SetupAndVerifyDtlsCall(); | |
| 1678 } | |
| 1679 | |
| 1680 // This test sets up an one-way call, with media only from initiator to | |
| 1681 // responder. | |
| 1682 TEST_F(P2PTestConductor, OneWayMediaCall) { | |
| 1683 ASSERT_TRUE(CreateTestClients()); | |
| 1684 receiving_client()->set_auto_add_stream(false); | |
| 1685 LocalP2PTest(); | |
| 1686 } | |
| 1687 | |
| 1688 TEST_F(P2PTestConductor, OneWayMediaCallWithoutConstraints) { | |
| 1689 ASSERT_TRUE(CreateTestClientsThatPreferNoConstraints()); | |
| 1690 receiving_client()->set_auto_add_stream(false); | |
| 1691 LocalP2PTest(); | |
| 1692 } | |
| 1693 | |
| 1694 // This test sets up a audio call initially and then upgrades to audio/video, | |
| 1695 // using DTLS. | |
| 1696 TEST_F(P2PTestConductor, LocalP2PTestDtlsRenegotiate) { | |
| 1697 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
| 1698 FakeConstraints setup_constraints; | |
| 1699 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1700 true); | |
| 1701 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
| 1702 receiving_client()->SetReceiveAudioVideo(true, false); | |
| 1703 LocalP2PTest(); | |
| 1704 receiving_client()->SetReceiveAudioVideo(true, true); | |
| 1705 receiving_client()->Negotiate(); | |
| 1706 } | |
| 1707 | |
| 1708 // This test sets up a call transfer to a new caller with a different DTLS | |
| 1709 // fingerprint. | |
| 1710 TEST_F(P2PTestConductor, LocalP2PTestDtlsTransferCallee) { | |
| 1711 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
| 1712 SetupAndVerifyDtlsCall(); | |
| 1713 | |
| 1714 // Keeping the original peer around which will still send packets to the | |
| 1715 // receiving client. These SRTP packets will be dropped. | |
| 1716 std::unique_ptr<PeerConnectionTestClient> original_peer( | |
| 1717 set_initializing_client(CreateDtlsClientWithAlternateKey())); | |
| 1718 original_peer->pc()->Close(); | |
| 1719 | |
| 1720 SetSignalingReceivers(); | |
| 1721 receiving_client()->SetExpectIceRestart(true); | |
| 1722 LocalP2PTest(); | |
| 1723 VerifyRenderedAspectRatio(640, 480); | |
| 1724 } | |
| 1725 | |
| 1726 // This test sets up a non-bundle call and apply bundle during ICE restart. When | |
| 1727 // bundle is in effect in the restart, the channel can successfully reset its | |
| 1728 // DTLS-SRTP context. | |
| 1729 TEST_F(P2PTestConductor, LocalP2PTestDtlsBundleInIceRestart) { | |
| 1730 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
| 1731 FakeConstraints setup_constraints; | |
| 1732 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1733 true); | |
| 1734 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
| 1735 receiving_client()->RemoveBundleFromReceivedSdp(true); | |
| 1736 LocalP2PTest(); | |
| 1737 VerifyRenderedAspectRatio(640, 480); | |
| 1738 | |
| 1739 initializing_client()->IceRestart(); | |
| 1740 receiving_client()->SetExpectIceRestart(true); | |
| 1741 receiving_client()->RemoveBundleFromReceivedSdp(false); | |
| 1742 LocalP2PTest(); | |
| 1743 VerifyRenderedAspectRatio(640, 480); | |
| 1744 } | |
| 1745 | |
| 1746 // This test sets up a call transfer to a new callee with a different DTLS | |
| 1747 // fingerprint. | |
| 1748 TEST_F(P2PTestConductor, LocalP2PTestDtlsTransferCaller) { | |
| 1749 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
| 1750 SetupAndVerifyDtlsCall(); | |
| 1751 | |
| 1752 // Keeping the original peer around which will still send packets to the | |
| 1753 // receiving client. These SRTP packets will be dropped. | |
| 1754 std::unique_ptr<PeerConnectionTestClient> original_peer( | |
| 1755 set_receiving_client(CreateDtlsClientWithAlternateKey())); | |
| 1756 original_peer->pc()->Close(); | |
| 1757 | |
| 1758 SetSignalingReceivers(); | |
| 1759 initializing_client()->IceRestart(); | |
| 1760 LocalP2PTest(); | |
| 1761 VerifyRenderedAspectRatio(640, 480); | |
| 1762 } | |
| 1763 | |
| 1764 TEST_F(P2PTestConductor, LocalP2PTestCVO) { | |
| 1765 ASSERT_TRUE(CreateTestClients()); | |
| 1766 SetCaptureRotation(webrtc::kVideoRotation_90); | |
| 1767 LocalP2PTest(); | |
| 1768 VerifyRenderedAspectRatio(640, 480, webrtc::kVideoRotation_90); | |
| 1769 } | |
| 1770 | |
| 1771 TEST_F(P2PTestConductor, LocalP2PTestReceiverDoesntSupportCVO) { | |
| 1772 ASSERT_TRUE(CreateTestClients()); | |
| 1773 SetCaptureRotation(webrtc::kVideoRotation_90); | |
| 1774 receiving_client()->RemoveCvoFromReceivedSdp(true); | |
| 1775 LocalP2PTest(); | |
| 1776 VerifyRenderedAspectRatio(480, 640, webrtc::kVideoRotation_0); | |
| 1777 } | |
| 1778 | |
| 1779 // This test sets up a call between two endpoints that are configured to use | |
| 1780 // DTLS key agreement. The offerer don't support SDES. As a result, DTLS is | |
| 1781 // negotiated and used for transport. | |
| 1782 TEST_F(P2PTestConductor, LocalP2PTestOfferDtlsButNotSdes) { | |
| 1783 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
| 1784 FakeConstraints setup_constraints; | |
| 1785 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1786 true); | |
| 1787 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
| 1788 receiving_client()->RemoveSdesCryptoFromReceivedSdp(true); | |
| 1789 LocalP2PTest(); | |
| 1790 VerifyRenderedAspectRatio(640, 480); | |
| 1791 } | |
| 1792 | |
| 1793 #ifdef HAVE_SCTP | |
| 1794 // This test verifies that the negotiation will succeed with data channel only | |
| 1795 // in max-bundle mode. | |
| 1796 TEST_F(P2PTestConductor, LocalP2PTestOfferDataChannelOnly) { | |
| 1797 webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; | |
| 1798 rtc_config.bundle_policy = | |
| 1799 webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle; | |
| 1800 ASSERT_TRUE(CreateTestClients(rtc_config, rtc_config)); | |
| 1801 initializing_client()->CreateDataChannel(); | |
| 1802 initializing_client()->Negotiate(); | |
| 1803 } | |
| 1804 #endif | |
| 1805 | |
| 1806 // This test sets up a Jsep call between two parties, and the callee only | |
| 1807 // accept to receive video. | |
| 1808 TEST_F(P2PTestConductor, LocalP2PTestAnswerVideo) { | |
| 1809 ASSERT_TRUE(CreateTestClients()); | |
| 1810 receiving_client()->SetReceiveAudioVideo(false, true); | |
| 1811 LocalP2PTest(); | |
| 1812 } | |
| 1813 | |
| 1814 // This test sets up a Jsep call between two parties, and the callee only | |
| 1815 // accept to receive audio. | |
| 1816 TEST_F(P2PTestConductor, LocalP2PTestAnswerAudio) { | |
| 1817 ASSERT_TRUE(CreateTestClients()); | |
| 1818 receiving_client()->SetReceiveAudioVideo(true, false); | |
| 1819 LocalP2PTest(); | |
| 1820 } | |
| 1821 | |
| 1822 // This test sets up a Jsep call between two parties, and the callee reject both | |
| 1823 // audio and video. | |
| 1824 TEST_F(P2PTestConductor, LocalP2PTestAnswerNone) { | |
| 1825 ASSERT_TRUE(CreateTestClients()); | |
| 1826 receiving_client()->SetReceiveAudioVideo(false, false); | |
| 1827 LocalP2PTest(); | |
| 1828 } | |
| 1829 | |
| 1830 // This test sets up an audio and video call between two parties. After the call | |
| 1831 // runs for a while (10 frames), the caller sends an update offer with video | |
| 1832 // being rejected. Once the re-negotiation is done, the video flow should stop | |
| 1833 // and the audio flow should continue. | |
| 1834 TEST_F(P2PTestConductor, UpdateOfferWithRejectedContent) { | |
| 1835 ASSERT_TRUE(CreateTestClients()); | |
| 1836 LocalP2PTest(); | |
| 1837 TestUpdateOfferWithRejectedContent(); | |
| 1838 } | |
| 1839 | |
| 1840 // This test sets up a Jsep call between two parties. The MSID is removed from | |
| 1841 // the SDP strings from the caller. | |
| 1842 TEST_F(P2PTestConductor, LocalP2PTestWithoutMsid) { | |
| 1843 ASSERT_TRUE(CreateTestClients()); | |
| 1844 receiving_client()->RemoveMsidFromReceivedSdp(true); | |
| 1845 // TODO(perkj): Currently there is a bug that cause audio to stop playing if | |
| 1846 // audio and video is muxed when MSID is disabled. Remove | |
| 1847 // SetRemoveBundleFromSdp once | |
| 1848 // https://code.google.com/p/webrtc/issues/detail?id=1193 is fixed. | |
| 1849 receiving_client()->RemoveBundleFromReceivedSdp(true); | |
| 1850 LocalP2PTest(); | |
| 1851 } | |
| 1852 | |
| 1853 TEST_F(P2PTestConductor, LocalP2PTestTwoStreams) { | |
| 1854 ASSERT_TRUE(CreateTestClients()); | |
| 1855 // Set optional video constraint to max 320pixels to decrease CPU usage. | |
| 1856 FakeConstraints constraint; | |
| 1857 constraint.SetOptionalMaxWidth(320); | |
| 1858 SetVideoConstraints(constraint, constraint); | |
| 1859 initializing_client()->AddMediaStream(true, true); | |
| 1860 initializing_client()->AddMediaStream(false, true); | |
| 1861 ASSERT_EQ(2u, initializing_client()->NumberOfLocalMediaStreams()); | |
| 1862 LocalP2PTest(); | |
| 1863 EXPECT_EQ(2u, receiving_client()->number_of_remote_streams()); | |
| 1864 } | |
| 1865 | |
| 1866 // Test that we can receive the audio output level from a remote audio track. | |
| 1867 TEST_F(P2PTestConductor, GetAudioOutputLevelStats) { | |
| 1868 ASSERT_TRUE(CreateTestClients()); | |
| 1869 LocalP2PTest(); | |
| 1870 | |
| 1871 StreamCollectionInterface* remote_streams = | |
| 1872 initializing_client()->remote_streams(); | |
| 1873 ASSERT_GT(remote_streams->count(), 0u); | |
| 1874 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u); | |
| 1875 MediaStreamTrackInterface* remote_audio_track = | |
| 1876 remote_streams->at(0)->GetAudioTracks()[0]; | |
| 1877 | |
| 1878 // Get the audio output level stats. Note that the level is not available | |
| 1879 // until a RTCP packet has been received. | |
| 1880 EXPECT_TRUE_WAIT( | |
| 1881 initializing_client()->GetAudioOutputLevelStats(remote_audio_track) > 0, | |
| 1882 kMaxWaitForStatsMs); | |
| 1883 } | |
| 1884 | |
| 1885 // Test that an audio input level is reported. | |
| 1886 TEST_F(P2PTestConductor, GetAudioInputLevelStats) { | |
| 1887 ASSERT_TRUE(CreateTestClients()); | |
| 1888 LocalP2PTest(); | |
| 1889 | |
| 1890 // Get the audio input level stats. The level should be available very | |
| 1891 // soon after the test starts. | |
| 1892 EXPECT_TRUE_WAIT(initializing_client()->GetAudioInputLevelStats() > 0, | |
| 1893 kMaxWaitForStatsMs); | |
| 1894 } | |
| 1895 | |
| 1896 // Test that we can get incoming byte counts from both audio and video tracks. | |
| 1897 TEST_F(P2PTestConductor, GetBytesReceivedStats) { | |
| 1898 ASSERT_TRUE(CreateTestClients()); | |
| 1899 LocalP2PTest(); | |
| 1900 | |
| 1901 StreamCollectionInterface* remote_streams = | |
| 1902 initializing_client()->remote_streams(); | |
| 1903 ASSERT_GT(remote_streams->count(), 0u); | |
| 1904 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u); | |
| 1905 MediaStreamTrackInterface* remote_audio_track = | |
| 1906 remote_streams->at(0)->GetAudioTracks()[0]; | |
| 1907 EXPECT_TRUE_WAIT( | |
| 1908 initializing_client()->GetBytesReceivedStats(remote_audio_track) > 0, | |
| 1909 kMaxWaitForStatsMs); | |
| 1910 | |
| 1911 MediaStreamTrackInterface* remote_video_track = | |
| 1912 remote_streams->at(0)->GetVideoTracks()[0]; | |
| 1913 EXPECT_TRUE_WAIT( | |
| 1914 initializing_client()->GetBytesReceivedStats(remote_video_track) > 0, | |
| 1915 kMaxWaitForStatsMs); | |
| 1916 } | |
| 1917 | |
| 1918 // Test that we can get outgoing byte counts from both audio and video tracks. | |
| 1919 TEST_F(P2PTestConductor, GetBytesSentStats) { | |
| 1920 ASSERT_TRUE(CreateTestClients()); | |
| 1921 LocalP2PTest(); | |
| 1922 | |
| 1923 StreamCollectionInterface* local_streams = | |
| 1924 initializing_client()->local_streams(); | |
| 1925 ASSERT_GT(local_streams->count(), 0u); | |
| 1926 ASSERT_GT(local_streams->at(0)->GetAudioTracks().size(), 0u); | |
| 1927 MediaStreamTrackInterface* local_audio_track = | |
| 1928 local_streams->at(0)->GetAudioTracks()[0]; | |
| 1929 EXPECT_TRUE_WAIT( | |
| 1930 initializing_client()->GetBytesSentStats(local_audio_track) > 0, | |
| 1931 kMaxWaitForStatsMs); | |
| 1932 | |
| 1933 MediaStreamTrackInterface* local_video_track = | |
| 1934 local_streams->at(0)->GetVideoTracks()[0]; | |
| 1935 EXPECT_TRUE_WAIT( | |
| 1936 initializing_client()->GetBytesSentStats(local_video_track) > 0, | |
| 1937 kMaxWaitForStatsMs); | |
| 1938 } | |
| 1939 | |
| 1940 // Test that DTLS 1.0 is used if both sides only support DTLS 1.0. | |
| 1941 TEST_F(P2PTestConductor, GetDtls12None) { | |
| 1942 PeerConnectionFactory::Options init_options; | |
| 1943 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
| 1944 PeerConnectionFactory::Options recv_options; | |
| 1945 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
| 1946 ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr, | |
| 1947 &recv_options, nullptr)); | |
| 1948 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
| 1949 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
| 1950 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
| 1951 LocalP2PTest(); | |
| 1952 | |
| 1953 EXPECT_TRUE_WAIT( | |
| 1954 rtc::SSLStreamAdapter::IsAcceptableCipher( | |
| 1955 initializing_client()->GetDtlsCipherStats(), rtc::KT_DEFAULT), | |
| 1956 kMaxWaitForStatsMs); | |
| 1957 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
| 1958 initializing_client()->GetSrtpCipherStats(), | |
| 1959 kMaxWaitForStatsMs); | |
| 1960 EXPECT_EQ(1, | |
| 1961 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
| 1962 kDefaultSrtpCryptoSuite)); | |
| 1963 } | |
| 1964 | |
| 1965 // Test that DTLS 1.2 is used if both ends support it. | |
| 1966 TEST_F(P2PTestConductor, GetDtls12Both) { | |
| 1967 PeerConnectionFactory::Options init_options; | |
| 1968 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
| 1969 PeerConnectionFactory::Options recv_options; | |
| 1970 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
| 1971 ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr, | |
| 1972 &recv_options, nullptr)); | |
| 1973 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
| 1974 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
| 1975 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
| 1976 LocalP2PTest(); | |
| 1977 | |
| 1978 EXPECT_TRUE_WAIT( | |
| 1979 rtc::SSLStreamAdapter::IsAcceptableCipher( | |
| 1980 initializing_client()->GetDtlsCipherStats(), rtc::KT_DEFAULT), | |
| 1981 kMaxWaitForStatsMs); | |
| 1982 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
| 1983 initializing_client()->GetSrtpCipherStats(), | |
| 1984 kMaxWaitForStatsMs); | |
| 1985 EXPECT_EQ(1, | |
| 1986 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
| 1987 kDefaultSrtpCryptoSuite)); | |
| 1988 } | |
| 1989 | |
| 1990 // Test that DTLS 1.0 is used if the initator supports DTLS 1.2 and the | |
| 1991 // received supports 1.0. | |
| 1992 TEST_F(P2PTestConductor, GetDtls12Init) { | |
| 1993 PeerConnectionFactory::Options init_options; | |
| 1994 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
| 1995 PeerConnectionFactory::Options recv_options; | |
| 1996 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
| 1997 ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr, | |
| 1998 &recv_options, nullptr)); | |
| 1999 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
| 2000 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
| 2001 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
| 2002 LocalP2PTest(); | |
| 2003 | |
| 2004 EXPECT_TRUE_WAIT( | |
| 2005 rtc::SSLStreamAdapter::IsAcceptableCipher( | |
| 2006 initializing_client()->GetDtlsCipherStats(), rtc::KT_DEFAULT), | |
| 2007 kMaxWaitForStatsMs); | |
| 2008 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
| 2009 initializing_client()->GetSrtpCipherStats(), | |
| 2010 kMaxWaitForStatsMs); | |
| 2011 EXPECT_EQ(1, | |
| 2012 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
| 2013 kDefaultSrtpCryptoSuite)); | |
| 2014 } | |
| 2015 | |
| 2016 // Test that DTLS 1.0 is used if the initator supports DTLS 1.0 and the | |
| 2017 // received supports 1.2. | |
| 2018 TEST_F(P2PTestConductor, GetDtls12Recv) { | |
| 2019 PeerConnectionFactory::Options init_options; | |
| 2020 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
| 2021 PeerConnectionFactory::Options recv_options; | |
| 2022 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
| 2023 ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr, | |
| 2024 &recv_options, nullptr)); | |
| 2025 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
| 2026 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
| 2027 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
| 2028 LocalP2PTest(); | |
| 2029 | |
| 2030 EXPECT_TRUE_WAIT( | |
| 2031 rtc::SSLStreamAdapter::IsAcceptableCipher( | |
| 2032 initializing_client()->GetDtlsCipherStats(), rtc::KT_DEFAULT), | |
| 2033 kMaxWaitForStatsMs); | |
| 2034 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
| 2035 initializing_client()->GetSrtpCipherStats(), | |
| 2036 kMaxWaitForStatsMs); | |
| 2037 EXPECT_EQ(1, | |
| 2038 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
| 2039 kDefaultSrtpCryptoSuite)); | |
| 2040 } | |
| 2041 | |
| 2042 // Test that a non-GCM cipher is used if both sides only support non-GCM. | |
| 2043 TEST_F(P2PTestConductor, GetGcmNone) { | |
| 2044 TestGcmNegotiation(false, false, kDefaultSrtpCryptoSuite); | |
| 2045 } | |
| 2046 | |
| 2047 // Test that a GCM cipher is used if both ends support it. | |
| 2048 TEST_F(P2PTestConductor, GetGcmBoth) { | |
| 2049 TestGcmNegotiation(true, true, kDefaultSrtpCryptoSuiteGcm); | |
| 2050 } | |
| 2051 | |
| 2052 // Test that GCM isn't used if only the initiator supports it. | |
| 2053 TEST_F(P2PTestConductor, GetGcmInit) { | |
| 2054 TestGcmNegotiation(true, false, kDefaultSrtpCryptoSuite); | |
| 2055 } | |
| 2056 | |
| 2057 // Test that GCM isn't used if only the receiver supports it. | |
| 2058 TEST_F(P2PTestConductor, GetGcmRecv) { | |
| 2059 TestGcmNegotiation(false, true, kDefaultSrtpCryptoSuite); | |
| 2060 } | |
| 2061 | |
| 2062 // This test sets up a call between two parties with audio, video and an RTP | |
| 2063 // data channel. | |
| 2064 TEST_F(P2PTestConductor, LocalP2PTestRtpDataChannel) { | |
| 2065 FakeConstraints setup_constraints; | |
| 2066 setup_constraints.SetAllowRtpDataChannels(); | |
| 2067 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
| 2068 initializing_client()->CreateDataChannel(); | |
| 2069 LocalP2PTest(); | |
| 2070 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
| 2071 ASSERT_TRUE(receiving_client()->data_channel() != nullptr); | |
| 2072 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
| 2073 kMaxWaitMs); | |
| 2074 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), | |
| 2075 kMaxWaitMs); | |
| 2076 | |
| 2077 std::string data = "hello world"; | |
| 2078 | |
| 2079 SendRtpData(initializing_client()->data_channel(), data); | |
| 2080 EXPECT_EQ_WAIT(data, receiving_client()->data_observer()->last_message(), | |
| 2081 kMaxWaitMs); | |
| 2082 | |
| 2083 SendRtpData(receiving_client()->data_channel(), data); | |
| 2084 EXPECT_EQ_WAIT(data, initializing_client()->data_observer()->last_message(), | |
| 2085 kMaxWaitMs); | |
| 2086 | |
| 2087 receiving_client()->data_channel()->Close(); | |
| 2088 // Send new offer and answer. | |
| 2089 receiving_client()->Negotiate(); | |
| 2090 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen()); | |
| 2091 EXPECT_FALSE(receiving_client()->data_observer()->IsOpen()); | |
| 2092 } | |
| 2093 | |
| 2094 #ifdef HAVE_SCTP | |
| 2095 // This test sets up a call between two parties with audio, video and an SCTP | |
| 2096 // data channel. | |
| 2097 TEST_F(P2PTestConductor, LocalP2PTestSctpDataChannel) { | |
| 2098 ASSERT_TRUE(CreateTestClients()); | |
| 2099 initializing_client()->CreateDataChannel(); | |
| 2100 LocalP2PTest(); | |
| 2101 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
| 2102 EXPECT_TRUE_WAIT(receiving_client()->data_channel() != nullptr, kMaxWaitMs); | |
| 2103 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
| 2104 kMaxWaitMs); | |
| 2105 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), kMaxWaitMs); | |
| 2106 | |
| 2107 std::string data = "hello world"; | |
| 2108 | |
| 2109 initializing_client()->data_channel()->Send(DataBuffer(data)); | |
| 2110 EXPECT_EQ_WAIT(data, receiving_client()->data_observer()->last_message(), | |
| 2111 kMaxWaitMs); | |
| 2112 | |
| 2113 receiving_client()->data_channel()->Send(DataBuffer(data)); | |
| 2114 EXPECT_EQ_WAIT(data, initializing_client()->data_observer()->last_message(), | |
| 2115 kMaxWaitMs); | |
| 2116 | |
| 2117 receiving_client()->data_channel()->Close(); | |
| 2118 EXPECT_TRUE_WAIT(!initializing_client()->data_observer()->IsOpen(), | |
| 2119 kMaxWaitMs); | |
| 2120 EXPECT_TRUE_WAIT(!receiving_client()->data_observer()->IsOpen(), kMaxWaitMs); | |
| 2121 } | |
| 2122 | |
| 2123 TEST_F(P2PTestConductor, UnorderedSctpDataChannel) { | |
| 2124 ASSERT_TRUE(CreateTestClients()); | |
| 2125 webrtc::DataChannelInit init; | |
| 2126 init.ordered = false; | |
| 2127 initializing_client()->CreateDataChannel(&init); | |
| 2128 | |
| 2129 // Introduce random network delays. | |
| 2130 // Otherwise it's not a true "unordered" test. | |
| 2131 virtual_socket_server()->set_delay_mean(20); | |
| 2132 virtual_socket_server()->set_delay_stddev(5); | |
| 2133 virtual_socket_server()->UpdateDelayDistribution(); | |
| 2134 | |
| 2135 initializing_client()->Negotiate(); | |
| 2136 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
| 2137 EXPECT_TRUE_WAIT(receiving_client()->data_channel() != nullptr, kMaxWaitMs); | |
| 2138 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
| 2139 kMaxWaitMs); | |
| 2140 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), kMaxWaitMs); | |
| 2141 | |
| 2142 static constexpr int kNumMessages = 100; | |
| 2143 // Deliberately chosen to be larger than the MTU so messages get fragmented. | |
| 2144 static constexpr size_t kMaxMessageSize = 4096; | |
| 2145 // Create and send random messages. | |
| 2146 std::vector<std::string> sent_messages; | |
| 2147 for (int i = 0; i < kNumMessages; ++i) { | |
| 2148 size_t length = (rand() % kMaxMessageSize) + 1; | |
| 2149 std::string message; | |
| 2150 ASSERT_TRUE(rtc::CreateRandomString(length, &message)); | |
| 2151 initializing_client()->data_channel()->Send(DataBuffer(message)); | |
| 2152 receiving_client()->data_channel()->Send(DataBuffer(message)); | |
| 2153 sent_messages.push_back(message); | |
| 2154 } | |
| 2155 | |
| 2156 EXPECT_EQ_WAIT( | |
| 2157 kNumMessages, | |
| 2158 initializing_client()->data_observer()->received_message_count(), | |
| 2159 kMaxWaitMs); | |
| 2160 EXPECT_EQ_WAIT(kNumMessages, | |
| 2161 receiving_client()->data_observer()->received_message_count(), | |
| 2162 kMaxWaitMs); | |
| 2163 | |
| 2164 // Sort and compare to make sure none of the messages were corrupted. | |
| 2165 std::vector<std::string> initializing_client_received_messages = | |
| 2166 initializing_client()->data_observer()->messages(); | |
| 2167 std::vector<std::string> receiving_client_received_messages = | |
| 2168 receiving_client()->data_observer()->messages(); | |
| 2169 std::sort(sent_messages.begin(), sent_messages.end()); | |
| 2170 std::sort(initializing_client_received_messages.begin(), | |
| 2171 initializing_client_received_messages.end()); | |
| 2172 std::sort(receiving_client_received_messages.begin(), | |
| 2173 receiving_client_received_messages.end()); | |
| 2174 EXPECT_EQ(sent_messages, initializing_client_received_messages); | |
| 2175 EXPECT_EQ(sent_messages, receiving_client_received_messages); | |
| 2176 | |
| 2177 receiving_client()->data_channel()->Close(); | |
| 2178 EXPECT_TRUE_WAIT(!initializing_client()->data_observer()->IsOpen(), | |
| 2179 kMaxWaitMs); | |
| 2180 EXPECT_TRUE_WAIT(!receiving_client()->data_observer()->IsOpen(), kMaxWaitMs); | |
| 2181 } | |
| 2182 #endif // HAVE_SCTP | |
| 2183 | |
| 2184 // This test sets up a call between two parties and creates a data channel. | |
| 2185 // The test tests that received data is buffered unless an observer has been | |
| 2186 // registered. | |
| 2187 // Rtp data channels can receive data before the underlying | |
| 2188 // transport has detected that a channel is writable and thus data can be | |
| 2189 // received before the data channel state changes to open. That is hard to test | |
| 2190 // but the same buffering is used in that case. | |
| 2191 TEST_F(P2PTestConductor, RegisterDataChannelObserver) { | |
| 2192 FakeConstraints setup_constraints; | |
| 2193 setup_constraints.SetAllowRtpDataChannels(); | |
| 2194 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
| 2195 initializing_client()->CreateDataChannel(); | |
| 2196 initializing_client()->Negotiate(); | |
| 2197 | |
| 2198 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
| 2199 ASSERT_TRUE(receiving_client()->data_channel() != nullptr); | |
| 2200 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
| 2201 kMaxWaitMs); | |
| 2202 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, | |
| 2203 receiving_client()->data_channel()->state(), kMaxWaitMs); | |
| 2204 | |
| 2205 // Unregister the existing observer. | |
| 2206 receiving_client()->data_channel()->UnregisterObserver(); | |
| 2207 | |
| 2208 std::string data = "hello world"; | |
| 2209 SendRtpData(initializing_client()->data_channel(), data); | |
| 2210 | |
| 2211 // Wait a while to allow the sent data to arrive before an observer is | |
| 2212 // registered.. | |
| 2213 rtc::Thread::Current()->ProcessMessages(100); | |
| 2214 | |
| 2215 MockDataChannelObserver new_observer(receiving_client()->data_channel()); | |
| 2216 EXPECT_EQ_WAIT(data, new_observer.last_message(), kMaxWaitMs); | |
| 2217 } | |
| 2218 | |
| 2219 // This test sets up a call between two parties with audio, video and but only | |
| 2220 // the initiating client support data. | |
| 2221 TEST_F(P2PTestConductor, LocalP2PTestReceiverDoesntSupportData) { | |
| 2222 FakeConstraints setup_constraints_1; | |
| 2223 setup_constraints_1.SetAllowRtpDataChannels(); | |
| 2224 // Must disable DTLS to make negotiation succeed. | |
| 2225 setup_constraints_1.SetMandatory( | |
| 2226 MediaConstraintsInterface::kEnableDtlsSrtp, false); | |
| 2227 FakeConstraints setup_constraints_2; | |
| 2228 setup_constraints_2.SetMandatory( | |
| 2229 MediaConstraintsInterface::kEnableDtlsSrtp, false); | |
| 2230 ASSERT_TRUE(CreateTestClients(&setup_constraints_1, &setup_constraints_2)); | |
| 2231 initializing_client()->CreateDataChannel(); | |
| 2232 LocalP2PTest(); | |
| 2233 EXPECT_TRUE(initializing_client()->data_channel() != nullptr); | |
| 2234 EXPECT_FALSE(receiving_client()->data_channel()); | |
| 2235 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen()); | |
| 2236 } | |
| 2237 | |
| 2238 // This test sets up a call between two parties with audio, video. When audio | |
| 2239 // and video is setup and flowing and data channel is negotiated. | |
| 2240 TEST_F(P2PTestConductor, AddDataChannelAfterRenegotiation) { | |
| 2241 FakeConstraints setup_constraints; | |
| 2242 setup_constraints.SetAllowRtpDataChannels(); | |
| 2243 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
| 2244 LocalP2PTest(); | |
| 2245 initializing_client()->CreateDataChannel(); | |
| 2246 // Send new offer and answer. | |
| 2247 initializing_client()->Negotiate(); | |
| 2248 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
| 2249 ASSERT_TRUE(receiving_client()->data_channel() != nullptr); | |
| 2250 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
| 2251 kMaxWaitMs); | |
| 2252 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), | |
| 2253 kMaxWaitMs); | |
| 2254 } | |
| 2255 | |
| 2256 // This test sets up a Jsep call with SCTP DataChannel and verifies the | |
| 2257 // negotiation is completed without error. | |
| 2258 #ifdef HAVE_SCTP | |
| 2259 TEST_F(P2PTestConductor, CreateOfferWithSctpDataChannel) { | |
| 2260 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
| 2261 FakeConstraints constraints; | |
| 2262 constraints.SetMandatory( | |
| 2263 MediaConstraintsInterface::kEnableDtlsSrtp, true); | |
| 2264 ASSERT_TRUE(CreateTestClients(&constraints, &constraints)); | |
| 2265 initializing_client()->CreateDataChannel(); | |
| 2266 initializing_client()->Negotiate(false, false); | |
| 2267 } | |
| 2268 #endif | |
| 2269 | |
| 2270 // This test sets up a call between two parties with audio, and video. | |
| 2271 // During the call, the initializing side restart ice and the test verifies that | |
| 2272 // new ice candidates are generated and audio and video still can flow. | |
| 2273 TEST_F(P2PTestConductor, IceRestart) { | |
| 2274 ASSERT_TRUE(CreateTestClients()); | |
| 2275 | |
| 2276 // Negotiate and wait for ice completion and make sure audio and video plays. | |
| 2277 LocalP2PTest(); | |
| 2278 | |
| 2279 // Create a SDP string of the first audio candidate for both clients. | |
| 2280 const webrtc::IceCandidateCollection* audio_candidates_initiator = | |
| 2281 initializing_client()->pc()->local_description()->candidates(0); | |
| 2282 const webrtc::IceCandidateCollection* audio_candidates_receiver = | |
| 2283 receiving_client()->pc()->local_description()->candidates(0); | |
| 2284 ASSERT_GT(audio_candidates_initiator->count(), 0u); | |
| 2285 ASSERT_GT(audio_candidates_receiver->count(), 0u); | |
| 2286 std::string initiator_candidate; | |
| 2287 EXPECT_TRUE( | |
| 2288 audio_candidates_initiator->at(0)->ToString(&initiator_candidate)); | |
| 2289 std::string receiver_candidate; | |
| 2290 EXPECT_TRUE(audio_candidates_receiver->at(0)->ToString(&receiver_candidate)); | |
| 2291 | |
| 2292 // Restart ice on the initializing client. | |
| 2293 receiving_client()->SetExpectIceRestart(true); | |
| 2294 initializing_client()->IceRestart(); | |
| 2295 | |
| 2296 // Negotiate and wait for ice completion again and make sure audio and video | |
| 2297 // plays. | |
| 2298 LocalP2PTest(); | |
| 2299 | |
| 2300 // Create a SDP string of the first audio candidate for both clients again. | |
| 2301 const webrtc::IceCandidateCollection* audio_candidates_initiator_restart = | |
| 2302 initializing_client()->pc()->local_description()->candidates(0); | |
| 2303 const webrtc::IceCandidateCollection* audio_candidates_reciever_restart = | |
| 2304 receiving_client()->pc()->local_description()->candidates(0); | |
| 2305 ASSERT_GT(audio_candidates_initiator_restart->count(), 0u); | |
| 2306 ASSERT_GT(audio_candidates_reciever_restart->count(), 0u); | |
| 2307 std::string initiator_candidate_restart; | |
| 2308 EXPECT_TRUE(audio_candidates_initiator_restart->at(0)->ToString( | |
| 2309 &initiator_candidate_restart)); | |
| 2310 std::string receiver_candidate_restart; | |
| 2311 EXPECT_TRUE(audio_candidates_reciever_restart->at(0)->ToString( | |
| 2312 &receiver_candidate_restart)); | |
| 2313 | |
| 2314 // Verify that the first candidates in the local session descriptions has | |
| 2315 // changed. | |
| 2316 EXPECT_NE(initiator_candidate, initiator_candidate_restart); | |
| 2317 EXPECT_NE(receiver_candidate, receiver_candidate_restart); | |
| 2318 } | |
| 2319 | |
| 2320 TEST_F(P2PTestConductor, IceRenominationDisabled) { | |
| 2321 PeerConnectionInterface::RTCConfiguration config; | |
| 2322 config.enable_ice_renomination = false; | |
| 2323 ASSERT_TRUE(CreateTestClients(config, config)); | |
| 2324 LocalP2PTest(); | |
| 2325 | |
| 2326 initializing_client()->VerifyLocalIceRenomination(); | |
| 2327 receiving_client()->VerifyLocalIceRenomination(); | |
| 2328 initializing_client()->VerifyRemoteIceRenomination(); | |
| 2329 receiving_client()->VerifyRemoteIceRenomination(); | |
| 2330 } | |
| 2331 | |
| 2332 TEST_F(P2PTestConductor, IceRenominationEnabled) { | |
| 2333 PeerConnectionInterface::RTCConfiguration config; | |
| 2334 config.enable_ice_renomination = true; | |
| 2335 ASSERT_TRUE(CreateTestClients(config, config)); | |
| 2336 initializing_client()->SetExpectIceRenomination(true); | |
| 2337 initializing_client()->SetExpectRemoteIceRenomination(true); | |
| 2338 receiving_client()->SetExpectIceRenomination(true); | |
| 2339 receiving_client()->SetExpectRemoteIceRenomination(true); | |
| 2340 LocalP2PTest(); | |
| 2341 | |
| 2342 initializing_client()->VerifyLocalIceRenomination(); | |
| 2343 receiving_client()->VerifyLocalIceRenomination(); | |
| 2344 initializing_client()->VerifyRemoteIceRenomination(); | |
| 2345 receiving_client()->VerifyRemoteIceRenomination(); | |
| 2346 } | |
| 2347 | |
| 2348 // This test sets up a call between two parties with audio, and video. | |
| 2349 // It then renegotiates setting the video m-line to "port 0", then later | |
| 2350 // renegotiates again, enabling video. | |
| 2351 TEST_F(P2PTestConductor, LocalP2PTestVideoDisableEnable) { | |
| 2352 ASSERT_TRUE(CreateTestClients()); | |
| 2353 | |
| 2354 // Do initial negotiation. Will result in video and audio sendonly m-lines. | |
| 2355 receiving_client()->set_auto_add_stream(false); | |
| 2356 initializing_client()->AddMediaStream(true, true); | |
| 2357 initializing_client()->Negotiate(); | |
| 2358 | |
| 2359 // Negotiate again, disabling the video m-line (receiving client will | |
| 2360 // set port to 0 due to mandatory "OfferToReceiveVideo: false" constraint). | |
| 2361 receiving_client()->SetReceiveVideo(false); | |
| 2362 initializing_client()->Negotiate(); | |
| 2363 | |
| 2364 // Enable video and do negotiation again, making sure video is received | |
| 2365 // end-to-end. | |
| 2366 receiving_client()->SetReceiveVideo(true); | |
| 2367 receiving_client()->AddMediaStream(true, true); | |
| 2368 LocalP2PTest(); | |
| 2369 } | |
| 2370 | |
| 2371 // This test sets up a Jsep call between two parties with external | |
| 2372 // VideoDecoderFactory. | |
| 2373 // TODO(holmer): Disabled due to sometimes crashing on buildbots. | |
| 2374 // See issue webrtc/2378. | |
| 2375 TEST_F(P2PTestConductor, DISABLED_LocalP2PTestWithVideoDecoderFactory) { | |
| 2376 ASSERT_TRUE(CreateTestClients()); | |
| 2377 EnableVideoDecoderFactory(); | |
| 2378 LocalP2PTest(); | |
| 2379 } | |
| 2380 | |
| 2381 // This tests that if we negotiate after calling CreateSender but before we | |
| 2382 // have a track, then set a track later, frames from the newly-set track are | |
| 2383 // received end-to-end. | |
| 2384 TEST_F(P2PTestConductor, EarlyWarmupTest) { | |
| 2385 ASSERT_TRUE(CreateTestClients()); | |
| 2386 auto audio_sender = | |
| 2387 initializing_client()->pc()->CreateSender("audio", "stream_id"); | |
| 2388 auto video_sender = | |
| 2389 initializing_client()->pc()->CreateSender("video", "stream_id"); | |
| 2390 initializing_client()->Negotiate(); | |
| 2391 // Wait for ICE connection to complete, without any tracks. | |
| 2392 // Note that the receiving client WILL (in HandleIncomingOffer) create | |
| 2393 // tracks, so it's only the initiator here that's doing early warmup. | |
| 2394 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); | |
| 2395 VerifySessionDescriptions(); | |
| 2396 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, | |
| 2397 initializing_client()->ice_connection_state(), | |
| 2398 kMaxWaitForFramesMs); | |
| 2399 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, | |
| 2400 receiving_client()->ice_connection_state(), | |
| 2401 kMaxWaitForFramesMs); | |
| 2402 // Now set the tracks, and expect frames to immediately start flowing. | |
| 2403 EXPECT_TRUE( | |
| 2404 audio_sender->SetTrack(initializing_client()->CreateLocalAudioTrack(""))); | |
| 2405 EXPECT_TRUE( | |
| 2406 video_sender->SetTrack(initializing_client()->CreateLocalVideoTrack(""))); | |
| 2407 EXPECT_TRUE_WAIT(FramesHaveArrived(kEndAudioFrameCount, kEndVideoFrameCount), | |
| 2408 kMaxWaitForFramesMs); | |
| 2409 } | |
| 2410 | |
| 2411 #ifdef HAVE_QUIC | |
| 2412 // This test sets up a call between two parties using QUIC instead of DTLS for | |
| 2413 // audio and video, and a QUIC data channel. | |
| 2414 TEST_F(P2PTestConductor, LocalP2PTestQuicDataChannel) { | |
| 2415 PeerConnectionInterface::RTCConfiguration quic_config; | |
| 2416 quic_config.enable_quic = true; | |
| 2417 ASSERT_TRUE(CreateTestClients(quic_config, quic_config)); | |
| 2418 webrtc::DataChannelInit init; | |
| 2419 init.ordered = false; | |
| 2420 init.reliable = true; | |
| 2421 init.id = 1; | |
| 2422 initializing_client()->CreateDataChannel(&init); | |
| 2423 receiving_client()->CreateDataChannel(&init); | |
| 2424 LocalP2PTest(); | |
| 2425 ASSERT_NE(nullptr, initializing_client()->data_channel()); | |
| 2426 ASSERT_NE(nullptr, receiving_client()->data_channel()); | |
| 2427 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
| 2428 kMaxWaitMs); | |
| 2429 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), kMaxWaitMs); | |
| 2430 | |
| 2431 std::string data = "hello world"; | |
| 2432 | |
| 2433 initializing_client()->data_channel()->Send(DataBuffer(data)); | |
| 2434 EXPECT_EQ_WAIT(data, receiving_client()->data_observer()->last_message(), | |
| 2435 kMaxWaitMs); | |
| 2436 | |
| 2437 receiving_client()->data_channel()->Send(DataBuffer(data)); | |
| 2438 EXPECT_EQ_WAIT(data, initializing_client()->data_observer()->last_message(), | |
| 2439 kMaxWaitMs); | |
| 2440 } | |
| 2441 | |
| 2442 // Tests that negotiation of QUIC data channels is completed without error. | |
| 2443 TEST_F(P2PTestConductor, NegotiateQuicDataChannel) { | |
| 2444 PeerConnectionInterface::RTCConfiguration quic_config; | |
| 2445 quic_config.enable_quic = true; | |
| 2446 ASSERT_TRUE(CreateTestClients(quic_config, quic_config)); | |
| 2447 FakeConstraints constraints; | |
| 2448 constraints.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, true); | |
| 2449 ASSERT_TRUE(CreateTestClients(&constraints, &constraints)); | |
| 2450 webrtc::DataChannelInit init; | |
| 2451 init.ordered = false; | |
| 2452 init.reliable = true; | |
| 2453 init.id = 1; | |
| 2454 initializing_client()->CreateDataChannel(&init); | |
| 2455 initializing_client()->Negotiate(false, false); | |
| 2456 } | |
| 2457 | |
| 2458 // This test sets up a JSEP call using QUIC. The callee only receives video. | |
| 2459 TEST_F(P2PTestConductor, LocalP2PTestVideoOnlyWithQuic) { | |
| 2460 PeerConnectionInterface::RTCConfiguration quic_config; | |
| 2461 quic_config.enable_quic = true; | |
| 2462 ASSERT_TRUE(CreateTestClients(quic_config, quic_config)); | |
| 2463 receiving_client()->SetReceiveAudioVideo(false, true); | |
| 2464 LocalP2PTest(); | |
| 2465 } | |
| 2466 | |
| 2467 // This test sets up a JSEP call using QUIC. The callee only receives audio. | |
| 2468 TEST_F(P2PTestConductor, LocalP2PTestAudioOnlyWithQuic) { | |
| 2469 PeerConnectionInterface::RTCConfiguration quic_config; | |
| 2470 quic_config.enable_quic = true; | |
| 2471 ASSERT_TRUE(CreateTestClients(quic_config, quic_config)); | |
| 2472 receiving_client()->SetReceiveAudioVideo(true, false); | |
| 2473 LocalP2PTest(); | |
| 2474 } | |
| 2475 | |
| 2476 // This test sets up a JSEP call using QUIC. The callee rejects both audio and | |
| 2477 // video. | |
| 2478 TEST_F(P2PTestConductor, LocalP2PTestNoVideoAudioWithQuic) { | |
| 2479 PeerConnectionInterface::RTCConfiguration quic_config; | |
| 2480 quic_config.enable_quic = true; | |
| 2481 ASSERT_TRUE(CreateTestClients(quic_config, quic_config)); | |
| 2482 receiving_client()->SetReceiveAudioVideo(false, false); | |
| 2483 LocalP2PTest(); | |
| 2484 } | |
| 2485 | |
| 2486 #endif // HAVE_QUIC | |
| 2487 | |
| 2488 TEST_F(P2PTestConductor, ForwardVideoOnlyStream) { | |
| 2489 ASSERT_TRUE(CreateTestClients()); | |
| 2490 // One-way stream | |
| 2491 receiving_client()->set_auto_add_stream(false); | |
| 2492 // Video only, audio forwarding not expected to work. | |
| 2493 initializing_client()->AddMediaStream(false, true); | |
| 2494 initializing_client()->Negotiate(); | |
| 2495 | |
| 2496 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); | |
| 2497 VerifySessionDescriptions(); | |
| 2498 | |
| 2499 ASSERT_TRUE(initializing_client()->can_receive_video()); | |
| 2500 ASSERT_TRUE(receiving_client()->can_receive_video()); | |
| 2501 | |
| 2502 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, | |
| 2503 initializing_client()->ice_connection_state(), | |
| 2504 kMaxWaitForFramesMs); | |
| 2505 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, | |
| 2506 receiving_client()->ice_connection_state(), | |
| 2507 kMaxWaitForFramesMs); | |
| 2508 | |
| 2509 ASSERT_TRUE(receiving_client()->remote_streams()->count() == 1); | |
| 2510 | |
| 2511 // Echo the stream back. | |
| 2512 receiving_client()->pc()->AddStream( | |
| 2513 receiving_client()->remote_streams()->at(0)); | |
| 2514 receiving_client()->Negotiate(); | |
| 2515 | |
| 2516 EXPECT_TRUE_WAIT( | |
| 2517 initializing_client()->VideoFramesReceivedCheck(kEndVideoFrameCount), | |
| 2518 kMaxWaitForFramesMs); | |
| 2519 } | |
| 2520 | |
| 2521 // Test that we achieve the expected end-to-end connection time, using a | |
| 2522 // fake clock and simulated latency on the media and signaling paths. | |
| 2523 // We use a TURN<->TURN connection because this is usually the quickest to | |
| 2524 // set up initially, especially when we're confident the connection will work | |
| 2525 // and can start sending media before we get a STUN response. | |
| 2526 // | |
| 2527 // With various optimizations enabled, here are the network delays we expect to | |
| 2528 // be on the critical path: | |
| 2529 // 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then | |
| 2530 // signaling answer (with DTLS fingerprint). | |
| 2531 // 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when | |
| 2532 // using TURN<->TURN pair, and DTLS exchange is 4 packets, | |
| 2533 // the first of which should have arrived before the answer. | |
| 2534 TEST_F(P2PTestConductor, EndToEndConnectionTimeWithTurnTurnPair) { | |
| 2535 rtc::ScopedFakeClock fake_clock; | |
| 2536 // Some things use a time of "0" as a special value, so we need to start out | |
| 2537 // the fake clock at a nonzero time. | |
| 2538 // TODO(deadbeef): Fix this. | |
| 2539 fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1)); | |
| 2540 | |
| 2541 static constexpr int media_hop_delay_ms = 50; | |
| 2542 static constexpr int signaling_trip_delay_ms = 500; | |
| 2543 // For explanation of these values, see comment above. | |
| 2544 static constexpr int required_media_hops = 9; | |
| 2545 static constexpr int required_signaling_trips = 2; | |
| 2546 // For internal delays (such as posting an event asychronously). | |
| 2547 static constexpr int allowed_internal_delay_ms = 20; | |
| 2548 static constexpr int total_connection_time_ms = | |
| 2549 media_hop_delay_ms * required_media_hops + | |
| 2550 signaling_trip_delay_ms * required_signaling_trips + | |
| 2551 allowed_internal_delay_ms; | |
| 2552 | |
| 2553 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0", | |
| 2554 3478}; | |
| 2555 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1", | |
| 2556 0}; | |
| 2557 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0", | |
| 2558 3478}; | |
| 2559 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1", | |
| 2560 0}; | |
| 2561 cricket::TestTurnServer turn_server_1(network_thread(), | |
| 2562 turn_server_1_internal_address, | |
| 2563 turn_server_1_external_address); | |
| 2564 cricket::TestTurnServer turn_server_2(network_thread(), | |
| 2565 turn_server_2_internal_address, | |
| 2566 turn_server_2_external_address); | |
| 2567 // Bypass permission check on received packets so media can be sent before | |
| 2568 // the candidate is signaled. | |
| 2569 turn_server_1.set_enable_permission_checks(false); | |
| 2570 turn_server_2.set_enable_permission_checks(false); | |
| 2571 | |
| 2572 PeerConnectionInterface::RTCConfiguration client_1_config; | |
| 2573 webrtc::PeerConnectionInterface::IceServer ice_server_1; | |
| 2574 ice_server_1.urls.push_back("turn:88.88.88.0:3478"); | |
| 2575 ice_server_1.username = "test"; | |
| 2576 ice_server_1.password = "test"; | |
| 2577 client_1_config.servers.push_back(ice_server_1); | |
| 2578 client_1_config.type = webrtc::PeerConnectionInterface::kRelay; | |
| 2579 client_1_config.presume_writable_when_fully_relayed = true; | |
| 2580 | |
| 2581 PeerConnectionInterface::RTCConfiguration client_2_config; | |
| 2582 webrtc::PeerConnectionInterface::IceServer ice_server_2; | |
| 2583 ice_server_2.urls.push_back("turn:99.99.99.0:3478"); | |
| 2584 ice_server_2.username = "test"; | |
| 2585 ice_server_2.password = "test"; | |
| 2586 client_2_config.servers.push_back(ice_server_2); | |
| 2587 client_2_config.type = webrtc::PeerConnectionInterface::kRelay; | |
| 2588 client_2_config.presume_writable_when_fully_relayed = true; | |
| 2589 | |
| 2590 ASSERT_TRUE(CreateTestClients(client_1_config, client_2_config)); | |
| 2591 // Set up the simulated delays. | |
| 2592 SetSignalingDelayMs(signaling_trip_delay_ms); | |
| 2593 virtual_socket_server()->set_delay_mean(media_hop_delay_ms); | |
| 2594 virtual_socket_server()->UpdateDelayDistribution(); | |
| 2595 | |
| 2596 initializing_client()->SetOfferToReceiveAudioVideo(true, true); | |
| 2597 initializing_client()->Negotiate(); | |
| 2598 // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS | |
| 2599 // are connected. This is an important distinction. Once we have separate ICE | |
| 2600 // and DTLS state, this check needs to use the DTLS state. | |
| 2601 EXPECT_TRUE_SIMULATED_WAIT( | |
| 2602 (receiving_client()->ice_connection_state() == | |
| 2603 webrtc::PeerConnectionInterface::kIceConnectionConnected || | |
| 2604 receiving_client()->ice_connection_state() == | |
| 2605 webrtc::PeerConnectionInterface::kIceConnectionCompleted) && | |
| 2606 (initializing_client()->ice_connection_state() == | |
| 2607 webrtc::PeerConnectionInterface::kIceConnectionConnected || | |
| 2608 initializing_client()->ice_connection_state() == | |
| 2609 webrtc::PeerConnectionInterface::kIceConnectionCompleted), | |
| 2610 total_connection_time_ms, fake_clock); | |
| 2611 // Need to free the clients here since they're using things we created on | |
| 2612 // the stack. | |
| 2613 delete set_initializing_client(nullptr); | |
| 2614 delete set_receiving_client(nullptr); | |
| 2615 } | |
| 2616 | |
| 2617 class IceServerParsingTest : public testing::Test { | |
| 2618 public: | |
| 2619 // Convenience for parsing a single URL. | |
| 2620 bool ParseUrl(const std::string& url) { | |
| 2621 return ParseUrl(url, std::string(), std::string()); | |
| 2622 } | |
| 2623 | |
| 2624 bool ParseTurnUrl(const std::string& url) { | |
| 2625 return ParseUrl(url, "username", "password"); | |
| 2626 } | |
| 2627 | |
| 2628 bool ParseUrl(const std::string& url, | |
| 2629 const std::string& username, | |
| 2630 const std::string& password) { | |
| 2631 return ParseUrl( | |
| 2632 url, username, password, | |
| 2633 PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicySecure); | |
| 2634 } | |
| 2635 | |
| 2636 bool ParseUrl(const std::string& url, | |
| 2637 const std::string& username, | |
| 2638 const std::string& password, | |
| 2639 PeerConnectionInterface::TlsCertPolicy tls_certificate_policy) { | |
| 2640 PeerConnectionInterface::IceServers servers; | |
| 2641 PeerConnectionInterface::IceServer server; | |
| 2642 server.urls.push_back(url); | |
| 2643 server.username = username; | |
| 2644 server.password = password; | |
| 2645 server.tls_cert_policy = tls_certificate_policy; | |
| 2646 servers.push_back(server); | |
| 2647 return webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_) == | |
| 2648 webrtc::RTCErrorType::NONE; | |
| 2649 } | |
| 2650 | |
| 2651 protected: | |
| 2652 cricket::ServerAddresses stun_servers_; | |
| 2653 std::vector<cricket::RelayServerConfig> turn_servers_; | |
| 2654 }; | |
| 2655 | |
| 2656 // Make sure all STUN/TURN prefixes are parsed correctly. | |
| 2657 TEST_F(IceServerParsingTest, ParseStunPrefixes) { | |
| 2658 EXPECT_TRUE(ParseUrl("stun:hostname")); | |
| 2659 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2660 EXPECT_EQ(0U, turn_servers_.size()); | |
| 2661 stun_servers_.clear(); | |
| 2662 | |
| 2663 EXPECT_TRUE(ParseUrl("stuns:hostname")); | |
| 2664 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2665 EXPECT_EQ(0U, turn_servers_.size()); | |
| 2666 stun_servers_.clear(); | |
| 2667 | |
| 2668 EXPECT_TRUE(ParseTurnUrl("turn:hostname")); | |
| 2669 EXPECT_EQ(0U, stun_servers_.size()); | |
| 2670 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2671 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto); | |
| 2672 turn_servers_.clear(); | |
| 2673 | |
| 2674 EXPECT_TRUE(ParseTurnUrl("turns:hostname")); | |
| 2675 EXPECT_EQ(0U, stun_servers_.size()); | |
| 2676 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2677 EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto); | |
| 2678 EXPECT_TRUE(turn_servers_[0].tls_cert_policy == | |
| 2679 cricket::TlsCertPolicy::TLS_CERT_POLICY_SECURE); | |
| 2680 turn_servers_.clear(); | |
| 2681 | |
| 2682 EXPECT_TRUE(ParseUrl( | |
| 2683 "turns:hostname", "username", "password", | |
| 2684 PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicyInsecureNoCheck)); | |
| 2685 EXPECT_EQ(0U, stun_servers_.size()); | |
| 2686 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2687 EXPECT_TRUE(turn_servers_[0].tls_cert_policy == | |
| 2688 cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK); | |
| 2689 EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto); | |
| 2690 turn_servers_.clear(); | |
| 2691 | |
| 2692 // invalid prefixes | |
| 2693 EXPECT_FALSE(ParseUrl("stunn:hostname")); | |
| 2694 EXPECT_FALSE(ParseUrl(":hostname")); | |
| 2695 EXPECT_FALSE(ParseUrl(":")); | |
| 2696 EXPECT_FALSE(ParseUrl("")); | |
| 2697 } | |
| 2698 | |
| 2699 TEST_F(IceServerParsingTest, VerifyDefaults) { | |
| 2700 // TURNS defaults | |
| 2701 EXPECT_TRUE(ParseTurnUrl("turns:hostname")); | |
| 2702 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2703 EXPECT_EQ(5349, turn_servers_[0].ports[0].address.port()); | |
| 2704 EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto); | |
| 2705 turn_servers_.clear(); | |
| 2706 | |
| 2707 // TURN defaults | |
| 2708 EXPECT_TRUE(ParseTurnUrl("turn:hostname")); | |
| 2709 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2710 EXPECT_EQ(3478, turn_servers_[0].ports[0].address.port()); | |
| 2711 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto); | |
| 2712 turn_servers_.clear(); | |
| 2713 | |
| 2714 // STUN defaults | |
| 2715 EXPECT_TRUE(ParseUrl("stun:hostname")); | |
| 2716 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2717 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
| 2718 stun_servers_.clear(); | |
| 2719 } | |
| 2720 | |
| 2721 // Check that the 6 combinations of IPv4/IPv6/hostname and with/without port | |
| 2722 // can be parsed correctly. | |
| 2723 TEST_F(IceServerParsingTest, ParseHostnameAndPort) { | |
| 2724 EXPECT_TRUE(ParseUrl("stun:1.2.3.4:1234")); | |
| 2725 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2726 EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname()); | |
| 2727 EXPECT_EQ(1234, stun_servers_.begin()->port()); | |
| 2728 stun_servers_.clear(); | |
| 2729 | |
| 2730 EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]:4321")); | |
| 2731 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2732 EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname()); | |
| 2733 EXPECT_EQ(4321, stun_servers_.begin()->port()); | |
| 2734 stun_servers_.clear(); | |
| 2735 | |
| 2736 EXPECT_TRUE(ParseUrl("stun:hostname:9999")); | |
| 2737 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2738 EXPECT_EQ("hostname", stun_servers_.begin()->hostname()); | |
| 2739 EXPECT_EQ(9999, stun_servers_.begin()->port()); | |
| 2740 stun_servers_.clear(); | |
| 2741 | |
| 2742 EXPECT_TRUE(ParseUrl("stun:1.2.3.4")); | |
| 2743 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2744 EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname()); | |
| 2745 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
| 2746 stun_servers_.clear(); | |
| 2747 | |
| 2748 EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]")); | |
| 2749 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2750 EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname()); | |
| 2751 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
| 2752 stun_servers_.clear(); | |
| 2753 | |
| 2754 EXPECT_TRUE(ParseUrl("stun:hostname")); | |
| 2755 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2756 EXPECT_EQ("hostname", stun_servers_.begin()->hostname()); | |
| 2757 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
| 2758 stun_servers_.clear(); | |
| 2759 | |
| 2760 // Try some invalid hostname:port strings. | |
| 2761 EXPECT_FALSE(ParseUrl("stun:hostname:99a99")); | |
| 2762 EXPECT_FALSE(ParseUrl("stun:hostname:-1")); | |
| 2763 EXPECT_FALSE(ParseUrl("stun:hostname:port:more")); | |
| 2764 EXPECT_FALSE(ParseUrl("stun:hostname:port more")); | |
| 2765 EXPECT_FALSE(ParseUrl("stun:hostname:")); | |
| 2766 EXPECT_FALSE(ParseUrl("stun:[1:2:3:4:5:6:7:8]junk:1000")); | |
| 2767 EXPECT_FALSE(ParseUrl("stun::5555")); | |
| 2768 EXPECT_FALSE(ParseUrl("stun:")); | |
| 2769 } | |
| 2770 | |
| 2771 // Test parsing the "?transport=xxx" part of the URL. | |
| 2772 TEST_F(IceServerParsingTest, ParseTransport) { | |
| 2773 EXPECT_TRUE(ParseTurnUrl("turn:hostname:1234?transport=tcp")); | |
| 2774 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2775 EXPECT_EQ(cricket::PROTO_TCP, turn_servers_[0].ports[0].proto); | |
| 2776 turn_servers_.clear(); | |
| 2777 | |
| 2778 EXPECT_TRUE(ParseTurnUrl("turn:hostname?transport=udp")); | |
| 2779 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2780 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto); | |
| 2781 turn_servers_.clear(); | |
| 2782 | |
| 2783 EXPECT_FALSE(ParseTurnUrl("turn:hostname?transport=invalid")); | |
| 2784 EXPECT_FALSE(ParseTurnUrl("turn:hostname?transport=")); | |
| 2785 EXPECT_FALSE(ParseTurnUrl("turn:hostname?=")); | |
| 2786 EXPECT_FALSE(ParseTurnUrl("?")); | |
| 2787 } | |
| 2788 | |
| 2789 // Test parsing ICE username contained in URL. | |
| 2790 TEST_F(IceServerParsingTest, ParseUsername) { | |
| 2791 EXPECT_TRUE(ParseTurnUrl("turn:user@hostname")); | |
| 2792 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2793 EXPECT_EQ("user", turn_servers_[0].credentials.username); | |
| 2794 turn_servers_.clear(); | |
| 2795 | |
| 2796 EXPECT_FALSE(ParseTurnUrl("turn:@hostname")); | |
| 2797 EXPECT_FALSE(ParseTurnUrl("turn:username@")); | |
| 2798 EXPECT_FALSE(ParseTurnUrl("turn:@")); | |
| 2799 EXPECT_FALSE(ParseTurnUrl("turn:user@name@hostname")); | |
| 2800 } | |
| 2801 | |
| 2802 // Test that username and password from IceServer is copied into the resulting | |
| 2803 // RelayServerConfig. | |
| 2804 TEST_F(IceServerParsingTest, CopyUsernameAndPasswordFromIceServer) { | |
| 2805 EXPECT_TRUE(ParseUrl("turn:hostname", "username", "password")); | |
| 2806 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2807 EXPECT_EQ("username", turn_servers_[0].credentials.username); | |
| 2808 EXPECT_EQ("password", turn_servers_[0].credentials.password); | |
| 2809 } | |
| 2810 | |
| 2811 // Ensure that if a server has multiple URLs, each one is parsed. | |
| 2812 TEST_F(IceServerParsingTest, ParseMultipleUrls) { | |
| 2813 PeerConnectionInterface::IceServers servers; | |
| 2814 PeerConnectionInterface::IceServer server; | |
| 2815 server.urls.push_back("stun:hostname"); | |
| 2816 server.urls.push_back("turn:hostname"); | |
| 2817 server.username = "foo"; | |
| 2818 server.password = "bar"; | |
| 2819 servers.push_back(server); | |
| 2820 EXPECT_EQ(webrtc::RTCErrorType::NONE, | |
| 2821 webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_)); | |
| 2822 EXPECT_EQ(1U, stun_servers_.size()); | |
| 2823 EXPECT_EQ(1U, turn_servers_.size()); | |
| 2824 } | |
| 2825 | |
| 2826 // Ensure that TURN servers are given unique priorities, | |
| 2827 // so that their resulting candidates have unique priorities. | |
| 2828 TEST_F(IceServerParsingTest, TurnServerPrioritiesUnique) { | |
| 2829 PeerConnectionInterface::IceServers servers; | |
| 2830 PeerConnectionInterface::IceServer server; | |
| 2831 server.urls.push_back("turn:hostname"); | |
| 2832 server.urls.push_back("turn:hostname2"); | |
| 2833 server.username = "foo"; | |
| 2834 server.password = "bar"; | |
| 2835 servers.push_back(server); | |
| 2836 EXPECT_EQ(webrtc::RTCErrorType::NONE, | |
| 2837 webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_)); | |
| 2838 EXPECT_EQ(2U, turn_servers_.size()); | |
| 2839 EXPECT_NE(turn_servers_[0].priority, turn_servers_[1].priority); | |
| 2840 } | |
| 2841 | |
| 2842 #endif // if !defined(THREAD_SANITIZER) | |
| 2843 | |
| 2844 } // namespace | |
| OLD | NEW |