1 /* 2 * libjingle 3 * Copyright 2012, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <stdio.h> 29 30 #include <algorithm> 31 #include <list> 32 #include <map> 33 #include <vector> 34 35 #include "talk/app/webrtc/dtmfsender.h" 36 #include "talk/app/webrtc/fakeportallocatorfactory.h" 37 #include "talk/app/webrtc/localaudiosource.h" 38 #include "talk/app/webrtc/mediastreaminterface.h" 39 #include "talk/app/webrtc/peerconnectionfactory.h" 40 #include "talk/app/webrtc/peerconnectioninterface.h" 41 #include "talk/app/webrtc/test/fakeaudiocapturemodule.h" 42 #include "talk/app/webrtc/test/fakeconstraints.h" 43 #include "talk/app/webrtc/test/fakevideotrackrenderer.h" 44 #include "talk/app/webrtc/test/fakeperiodicvideocapturer.h" 45 #include "talk/app/webrtc/test/mockpeerconnectionobservers.h" 46 #include "talk/app/webrtc/videosourceinterface.h" 47 #include "talk/base/gunit.h" 48 #include "talk/base/scoped_ptr.h" 49 #include "talk/base/ssladapter.h" 50 #include "talk/base/sslstreamadapter.h" 51 #include "talk/base/thread.h" 52 #include "talk/media/webrtc/fakewebrtcvideoengine.h" 53 #include "talk/p2p/base/constants.h" 54 #include "talk/p2p/base/sessiondescription.h" 55 #include "talk/session/media/mediasession.h" 56 57 #define MAYBE_SKIP_TEST(feature) \ 58 if (!(feature())) { \ 59 LOG(LS_INFO) << "Feature disabled... skipping"; \ 60 return; \ 61 } 62 63 using cricket::ContentInfo; 64 using cricket::FakeWebRtcVideoDecoder; 65 using cricket::FakeWebRtcVideoDecoderFactory; 66 using cricket::FakeWebRtcVideoEncoder; 67 using cricket::FakeWebRtcVideoEncoderFactory; 68 using cricket::MediaContentDescription; 69 using webrtc::DataBuffer; 70 using webrtc::DataChannelInterface; 71 using webrtc::DtmfSender; 72 using webrtc::DtmfSenderInterface; 73 using webrtc::DtmfSenderObserverInterface; 74 using webrtc::FakeConstraints; 75 using webrtc::MediaConstraintsInterface; 76 using webrtc::MediaStreamTrackInterface; 77 using webrtc::MockCreateSessionDescriptionObserver; 78 using webrtc::MockDataChannelObserver; 79 using webrtc::MockSetSessionDescriptionObserver; 80 using webrtc::MockStatsObserver; 81 using webrtc::SessionDescriptionInterface; 82 using webrtc::StreamCollectionInterface; 83 84 static const int kMaxWaitMs = 1000; 85 static const int kMaxWaitForStatsMs = 3000; 86 static const int kMaxWaitForFramesMs = 5000; 87 static const int kEndAudioFrameCount = 3; 88 static const int kEndVideoFrameCount = 3; 89 90 static const char kStreamLabelBase[] = "stream_label"; 91 static const char kVideoTrackLabelBase[] = "video_track"; 92 static const char kAudioTrackLabelBase[] = "audio_track"; 93 static const char kDataChannelLabel[] = "data_channel"; 94 95 static void RemoveLinesFromSdp(const std::string& line_start, 96 std::string* sdp) { 97 const char kSdpLineEnd[] = "\r\n"; 98 size_t ssrc_pos = 0; 99 while ((ssrc_pos = sdp->find(line_start, ssrc_pos)) != 100 std::string::npos) { 101 size_t end_ssrc = sdp->find(kSdpLineEnd, ssrc_pos); 102 sdp->erase(ssrc_pos, end_ssrc - ssrc_pos + strlen(kSdpLineEnd)); 103 } 104 } 105 106 class SignalingMessageReceiver { 107 public: 108 protected: 109 SignalingMessageReceiver() {} 110 virtual ~SignalingMessageReceiver() {} 111 }; 112 113 class JsepMessageReceiver : public SignalingMessageReceiver { 114 public: 115 virtual void ReceiveSdpMessage(const std::string& type, 116 std::string& msg) = 0; 117 virtual void ReceiveIceMessage(const std::string& sdp_mid, 118 int sdp_mline_index, 119 const std::string& msg) = 0; 120 121 protected: 122 JsepMessageReceiver() {} 123 virtual ~JsepMessageReceiver() {} 124 }; 125 126 template <typename MessageReceiver> 127 class PeerConnectionTestClientBase 128 : public webrtc::PeerConnectionObserver, 129 public MessageReceiver { 130 public: 131 ~PeerConnectionTestClientBase() { 132 while (!fake_video_renderers_.empty()) { 133 RenderMap::iterator it = fake_video_renderers_.begin(); 134 delete it->second; 135 fake_video_renderers_.erase(it); 136 } 137 } 138 139 virtual void Negotiate() = 0; 140 141 virtual void Negotiate(bool audio, bool video) = 0; 142 143 virtual void SetVideoConstraints( 144 const webrtc::FakeConstraints& video_constraint) { 145 video_constraints_ = video_constraint; 146 } 147 148 void AddMediaStream(bool audio, bool video) { 149 std::string label = kStreamLabelBase + 150 talk_base::ToString<int>( 151 static_cast<int>(peer_connection_->local_streams()->count())); 152 talk_base::scoped_refptr<webrtc::MediaStreamInterface> stream = 153 peer_connection_factory_->CreateLocalMediaStream(label); 154 155 if (audio && can_receive_audio()) { 156 FakeConstraints constraints; 157 // Disable highpass filter so that we can get all the test audio frames. 158 constraints.AddMandatory( 159 MediaConstraintsInterface::kHighpassFilter, false); 160 talk_base::scoped_refptr<webrtc::LocalAudioSource> source = 161 webrtc::LocalAudioSource::Create(&constraints); 162 // TODO(perkj): Test audio source when it is implemented. Currently audio 163 // always use the default input. 164 talk_base::scoped_refptr<webrtc::AudioTrackInterface> audio_track( 165 peer_connection_factory_->CreateAudioTrack(kAudioTrackLabelBase, 166 source)); 167 stream->AddTrack(audio_track); 168 } 169 if (video && can_receive_video()) { 170 stream->AddTrack(CreateLocalVideoTrack(label)); 171 } 172 173 EXPECT_TRUE(peer_connection_->AddStream(stream, NULL)); 174 } 175 176 size_t NumberOfLocalMediaStreams() { 177 return peer_connection_->local_streams()->count(); 178 } 179 180 bool SessionActive() { 181 return peer_connection_->signaling_state() == 182 webrtc::PeerConnectionInterface::kStable; 183 } 184 185 void set_signaling_message_receiver( 186 MessageReceiver* signaling_message_receiver) { 187 signaling_message_receiver_ = signaling_message_receiver; 188 } 189 190 void EnableVideoDecoderFactory() { 191 video_decoder_factory_enabled_ = true; 192 fake_video_decoder_factory_->AddSupportedVideoCodecType( 193 webrtc::kVideoCodecVP8); 194 } 195 196 bool AudioFramesReceivedCheck(int number_of_frames) const { 197 return number_of_frames <= fake_audio_capture_module_->frames_received(); 198 } 199 200 bool VideoFramesReceivedCheck(int number_of_frames) { 201 if (video_decoder_factory_enabled_) { 202 const std::vector<FakeWebRtcVideoDecoder*>& decoders 203 = fake_video_decoder_factory_->decoders(); 204 if (decoders.empty()) { 205 return number_of_frames <= 0; 206 } 207 208 for (std::vector<FakeWebRtcVideoDecoder*>::const_iterator 209 it = decoders.begin(); it != decoders.end(); ++it) { 210 if (number_of_frames > (*it)->GetNumFramesReceived()) { 211 return false; 212 } 213 } 214 return true; 215 } else { 216 if (fake_video_renderers_.empty()) { 217 return number_of_frames <= 0; 218 } 219 220 for (RenderMap::const_iterator it = fake_video_renderers_.begin(); 221 it != fake_video_renderers_.end(); ++it) { 222 if (number_of_frames > it->second->num_rendered_frames()) { 223 return false; 224 } 225 } 226 return true; 227 } 228 } 229 // Verify the CreateDtmfSender interface 230 void VerifyDtmf() { 231 talk_base::scoped_ptr<DummyDtmfObserver> observer(new DummyDtmfObserver()); 232 talk_base::scoped_refptr<DtmfSenderInterface> dtmf_sender; 233 234 // We can't create a DTMF sender with an invalid audio track or a non local 235 // track. 236 EXPECT_TRUE(peer_connection_->CreateDtmfSender(NULL) == NULL); 237 talk_base::scoped_refptr<webrtc::AudioTrackInterface> non_localtrack( 238 peer_connection_factory_->CreateAudioTrack("dummy_track", 239 NULL)); 240 EXPECT_TRUE(peer_connection_->CreateDtmfSender(non_localtrack) == NULL); 241 242 // We should be able to create a DTMF sender from a local track. 243 webrtc::AudioTrackInterface* localtrack = 244 peer_connection_->local_streams()->at(0)->GetAudioTracks()[0]; 245 dtmf_sender = peer_connection_->CreateDtmfSender(localtrack); 246 EXPECT_TRUE(dtmf_sender.get() != NULL); 247 dtmf_sender->RegisterObserver(observer.get()); 248 249 // Test the DtmfSender object just created. 250 EXPECT_TRUE(dtmf_sender->CanInsertDtmf()); 251 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50)); 252 253 // We don't need to verify that the DTMF tones are actually sent out because 254 // that is already covered by the tests of the lower level components. 255 256 EXPECT_TRUE_WAIT(observer->completed(), kMaxWaitMs); 257 std::vector<std::string> tones; 258 tones.push_back("1"); 259 tones.push_back("a"); 260 tones.push_back(""); 261 observer->Verify(tones); 262 263 dtmf_sender->UnregisterObserver(); 264 } 265 266 // Verifies that the SessionDescription have rejected the appropriate media 267 // content. 268 void VerifyRejectedMediaInSessionDescription() { 269 ASSERT_TRUE(peer_connection_->remote_description() != NULL); 270 ASSERT_TRUE(peer_connection_->local_description() != NULL); 271 const cricket::SessionDescription* remote_desc = 272 peer_connection_->remote_description()->description(); 273 const cricket::SessionDescription* local_desc = 274 peer_connection_->local_description()->description(); 275 276 const ContentInfo* remote_audio_content = GetFirstAudioContent(remote_desc); 277 if (remote_audio_content) { 278 const ContentInfo* audio_content = 279 GetFirstAudioContent(local_desc); 280 EXPECT_EQ(can_receive_audio(), !audio_content->rejected); 281 } 282 283 const ContentInfo* remote_video_content = GetFirstVideoContent(remote_desc); 284 if (remote_video_content) { 285 const ContentInfo* video_content = 286 GetFirstVideoContent(local_desc); 287 EXPECT_EQ(can_receive_video(), !video_content->rejected); 288 } 289 } 290 291 void SetExpectIceRestart(bool expect_restart) { 292 expect_ice_restart_ = expect_restart; 293 } 294 295 bool ExpectIceRestart() const { return expect_ice_restart_; } 296 297 void VerifyLocalIceUfragAndPassword() { 298 ASSERT_TRUE(peer_connection_->local_description() != NULL); 299 const cricket::SessionDescription* desc = 300 peer_connection_->local_description()->description(); 301 const cricket::ContentInfos& contents = desc->contents(); 302 303 for (size_t index = 0; index < contents.size(); ++index) { 304 if (contents[index].rejected) 305 continue; 306 const cricket::TransportDescription* transport_desc = 307 desc->GetTransportDescriptionByName(contents[index].name); 308 309 std::map<int, IceUfragPwdPair>::const_iterator ufragpair_it = 310 ice_ufrag_pwd_.find(static_cast<int>(index)); 311 if (ufragpair_it == ice_ufrag_pwd_.end()) { 312 ASSERT_FALSE(ExpectIceRestart()); 313 ice_ufrag_pwd_[static_cast<int>(index)] = 314 IceUfragPwdPair(transport_desc->ice_ufrag, transport_desc->ice_pwd); 315 } else if (ExpectIceRestart()) { 316 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second; 317 EXPECT_NE(ufrag_pwd.first, transport_desc->ice_ufrag); 318 EXPECT_NE(ufrag_pwd.second, transport_desc->ice_pwd); 319 } else { 320 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second; 321 EXPECT_EQ(ufrag_pwd.first, transport_desc->ice_ufrag); 322 EXPECT_EQ(ufrag_pwd.second, transport_desc->ice_pwd); 323 } 324 } 325 } 326 327 int GetAudioOutputLevelStats(webrtc::MediaStreamTrackInterface* track) { 328 talk_base::scoped_refptr<MockStatsObserver> 329 observer(new talk_base::RefCountedObject<MockStatsObserver>()); 330 EXPECT_TRUE(peer_connection_->GetStats(observer, track)); 331 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); 332 return observer->AudioOutputLevel(); 333 } 334 335 int GetAudioInputLevelStats() { 336 talk_base::scoped_refptr<MockStatsObserver> 337 observer(new talk_base::RefCountedObject<MockStatsObserver>()); 338 EXPECT_TRUE(peer_connection_->GetStats(observer, NULL)); 339 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); 340 return observer->AudioInputLevel(); 341 } 342 343 int GetBytesReceivedStats(webrtc::MediaStreamTrackInterface* track) { 344 talk_base::scoped_refptr<MockStatsObserver> 345 observer(new talk_base::RefCountedObject<MockStatsObserver>()); 346 EXPECT_TRUE(peer_connection_->GetStats(observer, track)); 347 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); 348 return observer->BytesReceived(); 349 } 350 351 int GetBytesSentStats(webrtc::MediaStreamTrackInterface* track) { 352 talk_base::scoped_refptr<MockStatsObserver> 353 observer(new talk_base::RefCountedObject<MockStatsObserver>()); 354 EXPECT_TRUE(peer_connection_->GetStats(observer, track)); 355 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); 356 return observer->BytesSent(); 357 } 358 359 int rendered_width() { 360 EXPECT_FALSE(fake_video_renderers_.empty()); 361 return fake_video_renderers_.empty() ? 1 : 362 fake_video_renderers_.begin()->second->width(); 363 } 364 365 int rendered_height() { 366 EXPECT_FALSE(fake_video_renderers_.empty()); 367 return fake_video_renderers_.empty() ? 1 : 368 fake_video_renderers_.begin()->second->height(); 369 } 370 371 size_t number_of_remote_streams() { 372 if (!pc()) 373 return 0; 374 return pc()->remote_streams()->count(); 375 } 376 377 StreamCollectionInterface* remote_streams() { 378 if (!pc()) { 379 ADD_FAILURE(); 380 return NULL; 381 } 382 return pc()->remote_streams(); 383 } 384 385 StreamCollectionInterface* local_streams() { 386 if (!pc()) { 387 ADD_FAILURE(); 388 return NULL; 389 } 390 return pc()->local_streams(); 391 } 392 393 webrtc::PeerConnectionInterface::SignalingState signaling_state() { 394 return pc()->signaling_state(); 395 } 396 397 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() { 398 return pc()->ice_connection_state(); 399 } 400 401 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() { 402 return pc()->ice_gathering_state(); 403 } 404 405 // PeerConnectionObserver callbacks. 406 virtual void OnError() {} 407 virtual void OnMessage(const std::string&) {} 408 virtual void OnSignalingMessage(const std::string& /*msg*/) {} 409 virtual void OnSignalingChange( 410 webrtc::PeerConnectionInterface::SignalingState new_state) { 411 EXPECT_EQ(peer_connection_->signaling_state(), new_state); 412 } 413 virtual void OnAddStream(webrtc::MediaStreamInterface* media_stream) { 414 for (size_t i = 0; i < media_stream->GetVideoTracks().size(); ++i) { 415 const std::string id = media_stream->GetVideoTracks()[i]->id(); 416 ASSERT_TRUE(fake_video_renderers_.find(id) == 417 fake_video_renderers_.end()); 418 fake_video_renderers_[id] = new webrtc::FakeVideoTrackRenderer( 419 media_stream->GetVideoTracks()[i]); 420 } 421 } 422 virtual void OnRemoveStream(webrtc::MediaStreamInterface* media_stream) {} 423 virtual void OnRenegotiationNeeded() {} 424 virtual void OnIceConnectionChange( 425 webrtc::PeerConnectionInterface::IceConnectionState new_state) { 426 EXPECT_EQ(peer_connection_->ice_connection_state(), new_state); 427 } 428 virtual void OnIceGatheringChange( 429 webrtc::PeerConnectionInterface::IceGatheringState new_state) { 430 EXPECT_EQ(peer_connection_->ice_gathering_state(), new_state); 431 } 432 virtual void OnIceCandidate( 433 const webrtc::IceCandidateInterface* /*candidate*/) {} 434 435 webrtc::PeerConnectionInterface* pc() { 436 return peer_connection_.get(); 437 } 438 439 protected: 440 explicit PeerConnectionTestClientBase(const std::string& id) 441 : id_(id), 442 expect_ice_restart_(false), 443 fake_video_decoder_factory_(NULL), 444 fake_video_encoder_factory_(NULL), 445 video_decoder_factory_enabled_(false), 446 signaling_message_receiver_(NULL) { 447 } 448 bool Init(const MediaConstraintsInterface* constraints) { 449 EXPECT_TRUE(!peer_connection_); 450 EXPECT_TRUE(!peer_connection_factory_); 451 allocator_factory_ = webrtc::FakePortAllocatorFactory::Create(); 452 if (!allocator_factory_) { 453 return false; 454 } 455 audio_thread_.Start(); 456 fake_audio_capture_module_ = FakeAudioCaptureModule::Create( 457 &audio_thread_); 458 459 if (fake_audio_capture_module_ == NULL) { 460 return false; 461 } 462 fake_video_decoder_factory_ = new FakeWebRtcVideoDecoderFactory(); 463 fake_video_encoder_factory_ = new FakeWebRtcVideoEncoderFactory(); 464 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( 465 talk_base::Thread::Current(), talk_base::Thread::Current(), 466 fake_audio_capture_module_, fake_video_encoder_factory_, 467 fake_video_decoder_factory_); 468 if (!peer_connection_factory_) { 469 return false; 470 } 471 peer_connection_ = CreatePeerConnection(allocator_factory_.get(), 472 constraints); 473 return peer_connection_.get() != NULL; 474 } 475 virtual talk_base::scoped_refptr<webrtc::PeerConnectionInterface> 476 CreatePeerConnection(webrtc::PortAllocatorFactoryInterface* factory, 477 const MediaConstraintsInterface* constraints) = 0; 478 MessageReceiver* signaling_message_receiver() { 479 return signaling_message_receiver_; 480 } 481 webrtc::PeerConnectionFactoryInterface* peer_connection_factory() { 482 return peer_connection_factory_.get(); 483 } 484 485 virtual bool can_receive_audio() = 0; 486 virtual bool can_receive_video() = 0; 487 const std::string& id() const { return id_; } 488 489 private: 490 class DummyDtmfObserver : public DtmfSenderObserverInterface { 491 public: 492 DummyDtmfObserver() : completed_(false) {} 493 494 // Implements DtmfSenderObserverInterface. 495 void OnToneChange(const std::string& tone) { 496 tones_.push_back(tone); 497 if (tone.empty()) { 498 completed_ = true; 499 } 500 } 501 502 void Verify(const std::vector<std::string>& tones) const { 503 ASSERT_TRUE(tones_.size() == tones.size()); 504 EXPECT_TRUE(std::equal(tones.begin(), tones.end(), tones_.begin())); 505 } 506 507 bool completed() const { return completed_; } 508 509 private: 510 bool completed_; 511 std::vector<std::string> tones_; 512 }; 513 514 talk_base::scoped_refptr<webrtc::VideoTrackInterface> 515 CreateLocalVideoTrack(const std::string stream_label) { 516 // Set max frame rate to 10fps to reduce the risk of the tests to be flaky. 517 FakeConstraints source_constraints = video_constraints_; 518 source_constraints.SetMandatoryMaxFrameRate(10); 519 520 talk_base::scoped_refptr<webrtc::VideoSourceInterface> source = 521 peer_connection_factory_->CreateVideoSource( 522 new webrtc::FakePeriodicVideoCapturer(), 523 &source_constraints); 524 std::string label = stream_label + kVideoTrackLabelBase; 525 return peer_connection_factory_->CreateVideoTrack(label, source); 526 } 527 528 std::string id_; 529 // Separate thread for executing |fake_audio_capture_module_| tasks. Audio 530 // processing must not be performed on the same thread as signaling due to 531 // signaling time constraints and relative complexity of the audio pipeline. 532 // This is consistent with the video pipeline that us a a separate thread for 533 // encoding and decoding. 534 talk_base::Thread audio_thread_; 535 536 talk_base::scoped_refptr<webrtc::PortAllocatorFactoryInterface> 537 allocator_factory_; 538 talk_base::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; 539 talk_base::scoped_refptr<webrtc::PeerConnectionFactoryInterface> 540 peer_connection_factory_; 541 542 typedef std::pair<std::string, std::string> IceUfragPwdPair; 543 std::map<int, IceUfragPwdPair> ice_ufrag_pwd_; 544 bool expect_ice_restart_; 545 546 // Needed to keep track of number of frames send. 547 talk_base::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_; 548 // Needed to keep track of number of frames received. 549 typedef std::map<std::string, webrtc::FakeVideoTrackRenderer*> RenderMap; 550 RenderMap fake_video_renderers_; 551 // Needed to keep track of number of frames received when external decoder 552 // used. 553 FakeWebRtcVideoDecoderFactory* fake_video_decoder_factory_; 554 FakeWebRtcVideoEncoderFactory* fake_video_encoder_factory_; 555 bool video_decoder_factory_enabled_; 556 webrtc::FakeConstraints video_constraints_; 557 558 // For remote peer communication. 559 MessageReceiver* signaling_message_receiver_; 560 }; 561 562 class JsepTestClient 563 : public PeerConnectionTestClientBase<JsepMessageReceiver> { 564 public: 565 static JsepTestClient* CreateClient( 566 const std::string& id, 567 const MediaConstraintsInterface* constraints) { 568 JsepTestClient* client(new JsepTestClient(id)); 569 if (!client->Init(constraints)) { 570 delete client; 571 return NULL; 572 } 573 return client; 574 } 575 ~JsepTestClient() {} 576 577 virtual void Negotiate() { 578 Negotiate(true, true); 579 } 580 virtual void Negotiate(bool audio, bool video) { 581 talk_base::scoped_ptr<SessionDescriptionInterface> offer; 582 EXPECT_TRUE(DoCreateOffer(offer.use())); 583 584 if (offer->description()->GetContentByName("audio")) { 585 offer->description()->GetContentByName("audio")->rejected = !audio; 586 } 587 if (offer->description()->GetContentByName("video")) { 588 offer->description()->GetContentByName("video")->rejected = !video; 589 } 590 591 std::string sdp; 592 EXPECT_TRUE(offer->ToString(&sdp)); 593 EXPECT_TRUE(DoSetLocalDescription(offer.release())); 594 signaling_message_receiver()->ReceiveSdpMessage( 595 webrtc::SessionDescriptionInterface::kOffer, sdp); 596 } 597 // JsepMessageReceiver callback. 598 virtual void ReceiveSdpMessage(const std::string& type, 599 std::string& msg) { 600 FilterIncomingSdpMessage(&msg); 601 if (type == webrtc::SessionDescriptionInterface::kOffer) { 602 HandleIncomingOffer(msg); 603 } else { 604 HandleIncomingAnswer(msg); 605 } 606 } 607 // JsepMessageReceiver callback. 608 virtual void ReceiveIceMessage(const std::string& sdp_mid, 609 int sdp_mline_index, 610 const std::string& msg) { 611 LOG(INFO) << id() << "ReceiveIceMessage"; 612 talk_base::scoped_ptr<webrtc::IceCandidateInterface> candidate( 613 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, NULL)); 614 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get())); 615 } 616 // Implements PeerConnectionObserver functions needed by Jsep. 617 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) { 618 LOG(INFO) << id() << "OnIceCandidate"; 619 620 std::string ice_sdp; 621 EXPECT_TRUE(candidate->ToString(&ice_sdp)); 622 if (signaling_message_receiver() == NULL) { 623 // Remote party may be deleted. 624 return; 625 } 626 signaling_message_receiver()->ReceiveIceMessage(candidate->sdp_mid(), 627 candidate->sdp_mline_index(), ice_sdp); 628 } 629 630 void IceRestart() { 631 session_description_constraints_.SetMandatoryIceRestart(true); 632 SetExpectIceRestart(true); 633 } 634 635 void SetReceiveAudioVideo(bool audio, bool video) { 636 session_description_constraints_.SetMandatoryReceiveAudio(audio); 637 session_description_constraints_.SetMandatoryReceiveVideo(video); 638 ASSERT_EQ(audio, can_receive_audio()); 639 ASSERT_EQ(video, can_receive_video()); 640 } 641 642 void RemoveMsidFromReceivedSdp(bool remove) { 643 remove_msid_ = remove; 644 } 645 646 void RemoveSdesCryptoFromReceivedSdp(bool remove) { 647 remove_sdes_ = remove; 648 } 649 650 void RemoveBundleFromReceivedSdp(bool remove) { 651 remove_bundle_ = remove; 652 } 653 654 virtual bool can_receive_audio() { 655 bool value; 656 if (webrtc::FindConstraint(&session_description_constraints_, 657 MediaConstraintsInterface::kOfferToReceiveAudio, &value, NULL)) { 658 return value; 659 } 660 return true; 661 } 662 663 virtual bool can_receive_video() { 664 bool value; 665 if (webrtc::FindConstraint(&session_description_constraints_, 666 MediaConstraintsInterface::kOfferToReceiveVideo, &value, NULL)) { 667 return value; 668 } 669 return true; 670 } 671 672 virtual void OnIceComplete() { 673 LOG(INFO) << id() << "OnIceComplete"; 674 } 675 676 virtual void OnDataChannel(DataChannelInterface* data_channel) { 677 LOG(INFO) << id() << "OnDataChannel"; 678 data_channel_ = data_channel; 679 data_observer_.reset(new MockDataChannelObserver(data_channel)); 680 } 681 682 void CreateDataChannel() { 683 data_channel_ = pc()->CreateDataChannel(kDataChannelLabel, 684 NULL); 685 ASSERT_TRUE(data_channel_.get() != NULL); 686 data_observer_.reset(new MockDataChannelObserver(data_channel_)); 687 } 688 689 DataChannelInterface* data_channel() { return data_channel_; } 690 const MockDataChannelObserver* data_observer() const { 691 return data_observer_.get(); 692 } 693 694 protected: 695 explicit JsepTestClient(const std::string& id) 696 : PeerConnectionTestClientBase<JsepMessageReceiver>(id), 697 remove_msid_(false), 698 remove_bundle_(false), 699 remove_sdes_(false) { 700 } 701 702 virtual talk_base::scoped_refptr<webrtc::PeerConnectionInterface> 703 CreatePeerConnection(webrtc::PortAllocatorFactoryInterface* factory, 704 const MediaConstraintsInterface* constraints) { 705 // CreatePeerConnection with IceServers. 706 webrtc::PeerConnectionInterface::IceServers ice_servers; 707 webrtc::PeerConnectionInterface::IceServer ice_server; 708 ice_server.uri = "stun:stun.l.google.com:19302"; 709 ice_servers.push_back(ice_server); 710 return peer_connection_factory()->CreatePeerConnection( 711 ice_servers, constraints, factory, NULL, this); 712 } 713 714 void HandleIncomingOffer(const std::string& msg) { 715 LOG(INFO) << id() << "HandleIncomingOffer "; 716 if (NumberOfLocalMediaStreams() == 0) { 717 // If we are not sending any streams ourselves it is time to add some. 718 AddMediaStream(true, true); 719 } 720 talk_base::scoped_ptr<SessionDescriptionInterface> desc( 721 webrtc::CreateSessionDescription("offer", msg, NULL)); 722 EXPECT_TRUE(DoSetRemoteDescription(desc.release())); 723 talk_base::scoped_ptr<SessionDescriptionInterface> answer; 724 EXPECT_TRUE(DoCreateAnswer(answer.use())); 725 std::string sdp; 726 EXPECT_TRUE(answer->ToString(&sdp)); 727 EXPECT_TRUE(DoSetLocalDescription(answer.release())); 728 if (signaling_message_receiver()) { 729 signaling_message_receiver()->ReceiveSdpMessage( 730 webrtc::SessionDescriptionInterface::kAnswer, sdp); 731 } 732 } 733 734 void HandleIncomingAnswer(const std::string& msg) { 735 LOG(INFO) << id() << "HandleIncomingAnswer"; 736 talk_base::scoped_ptr<SessionDescriptionInterface> desc( 737 webrtc::CreateSessionDescription("answer", msg, NULL)); 738 EXPECT_TRUE(DoSetRemoteDescription(desc.release())); 739 } 740 741 bool DoCreateOfferAnswer(SessionDescriptionInterface** desc, 742 bool offer) { 743 talk_base::scoped_refptr<MockCreateSessionDescriptionObserver> 744 observer(new talk_base::RefCountedObject< 745 MockCreateSessionDescriptionObserver>()); 746 if (offer) { 747 pc()->CreateOffer(observer, &session_description_constraints_); 748 } else { 749 pc()->CreateAnswer(observer, &session_description_constraints_); 750 } 751 EXPECT_EQ_WAIT(true, observer->called(), kMaxWaitMs); 752 *desc = observer->release_desc(); 753 if (observer->result() && ExpectIceRestart()) { 754 EXPECT_EQ(0u, (*desc)->candidates(0)->count()); 755 } 756 return observer->result(); 757 } 758 759 bool DoCreateOffer(SessionDescriptionInterface** desc) { 760 return DoCreateOfferAnswer(desc, true); 761 } 762 763 bool DoCreateAnswer(SessionDescriptionInterface** desc) { 764 return DoCreateOfferAnswer(desc, false); 765 } 766 767 bool DoSetLocalDescription(SessionDescriptionInterface* desc) { 768 talk_base::scoped_refptr<MockSetSessionDescriptionObserver> 769 observer(new talk_base::RefCountedObject< 770 MockSetSessionDescriptionObserver>()); 771 LOG(INFO) << id() << "SetLocalDescription "; 772 pc()->SetLocalDescription(observer, desc); 773 // Ignore the observer result. If we wait for the result with 774 // EXPECT_TRUE_WAIT, local ice candidates might be sent to the remote peer 775 // before the offer which is an error. 776 // The reason is that EXPECT_TRUE_WAIT uses 777 // talk_base::Thread::Current()->ProcessMessages(1); 778 // ProcessMessages waits at least 1ms but processes all messages before 779 // returning. Since this test is synchronous and send messages to the remote 780 // peer whenever a callback is invoked, this can lead to messages being 781 // sent to the remote peer in the wrong order. 782 // TODO(perkj): Find a way to check the result without risking that the 783 // order of sent messages are changed. Ex- by posting all messages that are 784 // sent to the remote peer. 785 return true; 786 } 787 788 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) { 789 talk_base::scoped_refptr<MockSetSessionDescriptionObserver> 790 observer(new talk_base::RefCountedObject< 791 MockSetSessionDescriptionObserver>()); 792 LOG(INFO) << id() << "SetRemoteDescription "; 793 pc()->SetRemoteDescription(observer, desc); 794 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); 795 return observer->result(); 796 } 797 798 // This modifies all received SDP messages before they are processed. 799 void FilterIncomingSdpMessage(std::string* sdp) { 800 if (remove_msid_) { 801 const char kSdpSsrcAttribute[] = "a=ssrc:"; 802 RemoveLinesFromSdp(kSdpSsrcAttribute, sdp); 803 const char kSdpMsidSupportedAttribute[] = "a=msid-semantic:"; 804 RemoveLinesFromSdp(kSdpMsidSupportedAttribute, sdp); 805 } 806 if (remove_bundle_) { 807 const char kSdpBundleAttribute[] = "a=group:BUNDLE"; 808 RemoveLinesFromSdp(kSdpBundleAttribute, sdp); 809 } 810 if (remove_sdes_) { 811 const char kSdpSdesCryptoAttribute[] = "a=crypto"; 812 RemoveLinesFromSdp(kSdpSdesCryptoAttribute, sdp); 813 } 814 } 815 816 private: 817 webrtc::FakeConstraints session_description_constraints_; 818 bool remove_msid_; // True if MSID should be removed in received SDP. 819 bool remove_bundle_; // True if bundle should be removed in received SDP. 820 bool remove_sdes_; // True if a=crypto should be removed in received SDP. 821 822 talk_base::scoped_refptr<DataChannelInterface> data_channel_; 823 talk_base::scoped_ptr<MockDataChannelObserver> data_observer_; 824 }; 825 826 template <typename SignalingClass> 827 class P2PTestConductor : public testing::Test { 828 public: 829 bool SessionActive() { 830 return initiating_client_->SessionActive() && 831 receiving_client_->SessionActive(); 832 } 833 // Return true if the number of frames provided have been received or it is 834 // known that that will never occur (e.g. no frames will be sent or 835 // captured). 836 bool FramesNotPending(int audio_frames_to_receive, 837 int video_frames_to_receive) { 838 return VideoFramesReceivedCheck(video_frames_to_receive) && 839 AudioFramesReceivedCheck(audio_frames_to_receive); 840 } 841 bool AudioFramesReceivedCheck(int frames_received) { 842 return initiating_client_->AudioFramesReceivedCheck(frames_received) && 843 receiving_client_->AudioFramesReceivedCheck(frames_received); 844 } 845 bool VideoFramesReceivedCheck(int frames_received) { 846 return initiating_client_->VideoFramesReceivedCheck(frames_received) && 847 receiving_client_->VideoFramesReceivedCheck(frames_received); 848 } 849 void VerifyDtmf() { 850 initiating_client_->VerifyDtmf(); 851 receiving_client_->VerifyDtmf(); 852 } 853 854 void TestUpdateOfferWithRejectedContent() { 855 initiating_client_->Negotiate(true, false); 856 EXPECT_TRUE_WAIT( 857 FramesNotPending(kEndAudioFrameCount * 2, kEndVideoFrameCount), 858 kMaxWaitForFramesMs); 859 // There shouldn't be any more video frame after the new offer is 860 // negotiated. 861 EXPECT_FALSE(VideoFramesReceivedCheck(kEndVideoFrameCount + 1)); 862 } 863 864 void VerifyRenderedSize(int width, int height) { 865 EXPECT_EQ(width, receiving_client()->rendered_width()); 866 EXPECT_EQ(height, receiving_client()->rendered_height()); 867 EXPECT_EQ(width, initializing_client()->rendered_width()); 868 EXPECT_EQ(height, initializing_client()->rendered_height()); 869 } 870 871 void VerifySessionDescriptions() { 872 initiating_client_->VerifyRejectedMediaInSessionDescription(); 873 receiving_client_->VerifyRejectedMediaInSessionDescription(); 874 initiating_client_->VerifyLocalIceUfragAndPassword(); 875 receiving_client_->VerifyLocalIceUfragAndPassword(); 876 } 877 878 P2PTestConductor() { 879 talk_base::InitializeSSL(NULL); 880 } 881 ~P2PTestConductor() { 882 if (initiating_client_) { 883 initiating_client_->set_signaling_message_receiver(NULL); 884 } 885 if (receiving_client_) { 886 receiving_client_->set_signaling_message_receiver(NULL); 887 } 888 talk_base::CleanupSSL(); 889 } 890 891 bool CreateTestClients() { 892 return CreateTestClients(NULL, NULL); 893 } 894 895 bool CreateTestClients(MediaConstraintsInterface* init_constraints, 896 MediaConstraintsInterface* recv_constraints) { 897 initiating_client_.reset(SignalingClass::CreateClient("Caller: ", 898 init_constraints)); 899 receiving_client_.reset(SignalingClass::CreateClient("Callee: ", 900 recv_constraints)); 901 if (!initiating_client_ || !receiving_client_) { 902 return false; 903 } 904 initiating_client_->set_signaling_message_receiver(receiving_client_.get()); 905 receiving_client_->set_signaling_message_receiver(initiating_client_.get()); 906 return true; 907 } 908 909 void SetVideoConstraints(const webrtc::FakeConstraints& init_constraints, 910 const webrtc::FakeConstraints& recv_constraints) { 911 initiating_client_->SetVideoConstraints(init_constraints); 912 receiving_client_->SetVideoConstraints(recv_constraints); 913 } 914 915 void EnableVideoDecoderFactory() { 916 initiating_client_->EnableVideoDecoderFactory(); 917 receiving_client_->EnableVideoDecoderFactory(); 918 } 919 920 // This test sets up a call between two parties. Both parties send static 921 // frames to each other. Once the test is finished the number of sent frames 922 // is compared to the number of received frames. 923 void LocalP2PTest() { 924 if (initiating_client_->NumberOfLocalMediaStreams() == 0) { 925 initiating_client_->AddMediaStream(true, true); 926 } 927 initiating_client_->Negotiate(); 928 const int kMaxWaitForActivationMs = 5000; 929 // Assert true is used here since next tests are guaranteed to fail and 930 // would eat up 5 seconds. 931 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); 932 VerifySessionDescriptions(); 933 934 935 int audio_frame_count = kEndAudioFrameCount; 936 // TODO(ronghuawu): Add test to cover the case of sendonly and recvonly. 937 if (!initiating_client_->can_receive_audio() || 938 !receiving_client_->can_receive_audio()) { 939 audio_frame_count = -1; 940 } 941 int video_frame_count = kEndVideoFrameCount; 942 if (!initiating_client_->can_receive_video() || 943 !receiving_client_->can_receive_video()) { 944 video_frame_count = -1; 945 } 946 947 if (audio_frame_count != -1 || video_frame_count != -1) { 948 // Audio or video is expected to flow, so both sides should get to the 949 // Connected state. 950 // Note: These tests have been observed to fail under heavy load at 951 // shorter timeouts, so they may be flaky. 952 EXPECT_EQ_WAIT( 953 webrtc::PeerConnectionInterface::kIceConnectionConnected, 954 initiating_client_->ice_connection_state(), 955 kMaxWaitForFramesMs); 956 EXPECT_EQ_WAIT( 957 webrtc::PeerConnectionInterface::kIceConnectionConnected, 958 receiving_client_->ice_connection_state(), 959 kMaxWaitForFramesMs); 960 } 961 962 if (initiating_client_->can_receive_audio() || 963 initiating_client_->can_receive_video()) { 964 // The initiating client can receive media, so it must produce candidates 965 // that will serve as destinations for that media. 966 // TODO(bemasc): Understand why the state is not already Complete here, as 967 // seems to be the case for the receiving client. This may indicate a bug 968 // in the ICE gathering system. 969 EXPECT_NE(webrtc::PeerConnectionInterface::kIceGatheringNew, 970 initiating_client_->ice_gathering_state()); 971 } 972 if (receiving_client_->can_receive_audio() || 973 receiving_client_->can_receive_video()) { 974 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete, 975 receiving_client_->ice_gathering_state(), 976 kMaxWaitForFramesMs); 977 } 978 979 EXPECT_TRUE_WAIT(FramesNotPending(audio_frame_count, video_frame_count), 980 kMaxWaitForFramesMs); 981 } 982 983 SignalingClass* initializing_client() { return initiating_client_.get(); } 984 SignalingClass* receiving_client() { return receiving_client_.get(); } 985 986 private: 987 talk_base::scoped_ptr<SignalingClass> initiating_client_; 988 talk_base::scoped_ptr<SignalingClass> receiving_client_; 989 }; 990 typedef P2PTestConductor<JsepTestClient> JsepPeerConnectionP2PTestClient; 991 992 // This test sets up a Jsep call between two parties and test Dtmf. 993 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDtmf) { 994 ASSERT_TRUE(CreateTestClients()); 995 LocalP2PTest(); 996 VerifyDtmf(); 997 } 998 999 // This test sets up a Jsep call between two parties and test that we can get a 1000 // video aspect ratio of 16:9. 1001 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTest16To9) { 1002 ASSERT_TRUE(CreateTestClients()); 1003 FakeConstraints constraint; 1004 double requested_ratio = 640.0/360; 1005 constraint.SetMandatoryMinAspectRatio(requested_ratio); 1006 SetVideoConstraints(constraint, constraint); 1007 LocalP2PTest(); 1008 1009 ASSERT_LE(0, initializing_client()->rendered_height()); 1010 double initiating_video_ratio = 1011 static_cast<double>(initializing_client()->rendered_width()) / 1012 initializing_client()->rendered_height(); 1013 EXPECT_LE(requested_ratio, initiating_video_ratio); 1014 1015 ASSERT_LE(0, receiving_client()->rendered_height()); 1016 double receiving_video_ratio = 1017 static_cast<double>(receiving_client()->rendered_width()) / 1018 receiving_client()->rendered_height(); 1019 EXPECT_LE(requested_ratio, receiving_video_ratio); 1020 } 1021 1022 // This test sets up a Jsep call between two parties and test that the 1023 // received video has a resolution of 1280*720. 1024 // TODO(mallinath): Enable when 1025 // http://code.google.com/p/webrtc/issues/detail?id=981 is fixed. 1026 TEST_F(JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTest1280By720) { 1027 ASSERT_TRUE(CreateTestClients()); 1028 FakeConstraints constraint; 1029 constraint.SetMandatoryMinWidth(1280); 1030 constraint.SetMandatoryMinHeight(720); 1031 SetVideoConstraints(constraint, constraint); 1032 LocalP2PTest(); 1033 VerifyRenderedSize(1280, 720); 1034 } 1035 1036 // This test sets up a call between two endpoints that are configured to use 1037 // DTLS key agreement. As a result, DTLS is negotiated and used for transport. 1038 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDtls) { 1039 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp); 1040 FakeConstraints setup_constraints; 1041 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, 1042 true); 1043 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); 1044 LocalP2PTest(); 1045 VerifyRenderedSize(640, 480); 1046 } 1047 1048 // This test sets up a call between an endpoint configured to use either SDES or 1049 // DTLS (the offerer) and just SDES (the answerer). As a result, SDES is used 1050 // instead of DTLS. 1051 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestOfferDtlsToSdes) { 1052 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp); 1053 FakeConstraints setup_constraints; 1054 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, 1055 true); 1056 ASSERT_TRUE(CreateTestClients(&setup_constraints, NULL)); 1057 LocalP2PTest(); 1058 VerifyRenderedSize(640, 480); 1059 } 1060 1061 // This test sets up a call between an endpoint configured to use SDES 1062 // (the offerer) and either SDES or DTLS (the answerer). As a result, SDES is 1063 // used instead of DTLS. 1064 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestOfferSdesToDtls) { 1065 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp); 1066 FakeConstraints setup_constraints; 1067 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, 1068 true); 1069 ASSERT_TRUE(CreateTestClients(NULL, &setup_constraints)); 1070 LocalP2PTest(); 1071 VerifyRenderedSize(640, 480); 1072 } 1073 1074 // This test sets up a call between two endpoints that are configured to use 1075 // DTLS key agreement. The offerer don't support SDES. As a result, DTLS is 1076 // negotiated and used for transport. 1077 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestOfferDtlsButNotSdes) { 1078 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp); 1079 FakeConstraints setup_constraints; 1080 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, 1081 true); 1082 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); 1083 receiving_client()->RemoveSdesCryptoFromReceivedSdp(true); 1084 LocalP2PTest(); 1085 VerifyRenderedSize(640, 480); 1086 } 1087 1088 // This test sets up a Jsep call between two parties, and the callee only 1089 // accept to receive video. 1090 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestAnswerVideo) { 1091 ASSERT_TRUE(CreateTestClients()); 1092 receiving_client()->SetReceiveAudioVideo(false, true); 1093 LocalP2PTest(); 1094 } 1095 1096 // This test sets up a Jsep call between two parties, and the callee only 1097 // accept to receive audio. 1098 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestAnswerAudio) { 1099 ASSERT_TRUE(CreateTestClients()); 1100 receiving_client()->SetReceiveAudioVideo(true, false); 1101 LocalP2PTest(); 1102 } 1103 1104 // This test sets up a Jsep call between two parties, and the callee reject both 1105 // audio and video. 1106 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestAnswerNone) { 1107 ASSERT_TRUE(CreateTestClients()); 1108 receiving_client()->SetReceiveAudioVideo(false, false); 1109 LocalP2PTest(); 1110 } 1111 1112 // This test sets up an audio and video call between two parties. After the call 1113 // runs for a while (10 frames), the caller sends an update offer with video 1114 // being rejected. Once the re-negotiation is done, the video flow should stop 1115 // and the audio flow should continue. 1116 TEST_F(JsepPeerConnectionP2PTestClient, UpdateOfferWithRejectedContent) { 1117 ASSERT_TRUE(CreateTestClients()); 1118 LocalP2PTest(); 1119 TestUpdateOfferWithRejectedContent(); 1120 } 1121 1122 // This test sets up a Jsep call between two parties. The MSID is removed from 1123 // the SDP strings from the caller. 1124 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestWithoutMsid) { 1125 ASSERT_TRUE(CreateTestClients()); 1126 receiving_client()->RemoveMsidFromReceivedSdp(true); 1127 // TODO(perkj): Currently there is a bug that cause audio to stop playing if 1128 // audio and video is muxed when MSID is disabled. Remove 1129 // SetRemoveBundleFromSdp once 1130 // https://code.google.com/p/webrtc/issues/detail?id=1193 is fixed. 1131 receiving_client()->RemoveBundleFromReceivedSdp(true); 1132 LocalP2PTest(); 1133 } 1134 1135 // This test sets up a Jsep call between two parties and the initiating peer 1136 // sends two steams. 1137 // TODO(perkj): Disabled due to 1138 // https://code.google.com/p/webrtc/issues/detail?id=1454 1139 TEST_F(JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTestTwoStreams) { 1140 ASSERT_TRUE(CreateTestClients()); 1141 // Set optional video constraint to max 320pixels to decrease CPU usage. 1142 FakeConstraints constraint; 1143 constraint.SetOptionalMaxWidth(320); 1144 SetVideoConstraints(constraint, constraint); 1145 initializing_client()->AddMediaStream(true, true); 1146 initializing_client()->AddMediaStream(false, true); 1147 ASSERT_EQ(2u, initializing_client()->NumberOfLocalMediaStreams()); 1148 LocalP2PTest(); 1149 EXPECT_EQ(2u, receiving_client()->number_of_remote_streams()); 1150 } 1151 1152 // Test that we can receive the audio output level from a remote audio track. 1153 TEST_F(JsepPeerConnectionP2PTestClient, GetAudioOutputLevelStats) { 1154 ASSERT_TRUE(CreateTestClients()); 1155 LocalP2PTest(); 1156 1157 StreamCollectionInterface* remote_streams = 1158 initializing_client()->remote_streams(); 1159 ASSERT_GT(remote_streams->count(), 0u); 1160 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u); 1161 MediaStreamTrackInterface* remote_audio_track = 1162 remote_streams->at(0)->GetAudioTracks()[0]; 1163 1164 // Get the audio output level stats. Note that the level is not available 1165 // until a RTCP packet has been received. 1166 EXPECT_TRUE_WAIT( 1167 initializing_client()->GetAudioOutputLevelStats(remote_audio_track) > 0, 1168 kMaxWaitForStatsMs); 1169 } 1170 1171 // Test that an audio input level is reported. 1172 TEST_F(JsepPeerConnectionP2PTestClient, GetAudioInputLevelStats) { 1173 ASSERT_TRUE(CreateTestClients()); 1174 LocalP2PTest(); 1175 1176 // Get the audio input level stats. The level should be available very 1177 // soon after the test starts. 1178 EXPECT_TRUE_WAIT(initializing_client()->GetAudioInputLevelStats() > 0, 1179 kMaxWaitForStatsMs); 1180 } 1181 1182 // Test that we can get incoming byte counts from both audio and video tracks. 1183 TEST_F(JsepPeerConnectionP2PTestClient, GetBytesReceivedStats) { 1184 ASSERT_TRUE(CreateTestClients()); 1185 LocalP2PTest(); 1186 1187 StreamCollectionInterface* remote_streams = 1188 initializing_client()->remote_streams(); 1189 ASSERT_GT(remote_streams->count(), 0u); 1190 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u); 1191 MediaStreamTrackInterface* remote_audio_track = 1192 remote_streams->at(0)->GetAudioTracks()[0]; 1193 EXPECT_TRUE_WAIT( 1194 initializing_client()->GetBytesReceivedStats(remote_audio_track) > 0, 1195 kMaxWaitForStatsMs); 1196 1197 MediaStreamTrackInterface* remote_video_track = 1198 remote_streams->at(0)->GetVideoTracks()[0]; 1199 EXPECT_TRUE_WAIT( 1200 initializing_client()->GetBytesReceivedStats(remote_video_track) > 0, 1201 kMaxWaitForStatsMs); 1202 } 1203 1204 // Test that we can get outgoing byte counts from both audio and video tracks. 1205 TEST_F(JsepPeerConnectionP2PTestClient, GetBytesSentStats) { 1206 ASSERT_TRUE(CreateTestClients()); 1207 LocalP2PTest(); 1208 1209 StreamCollectionInterface* local_streams = 1210 initializing_client()->local_streams(); 1211 ASSERT_GT(local_streams->count(), 0u); 1212 ASSERT_GT(local_streams->at(0)->GetAudioTracks().size(), 0u); 1213 MediaStreamTrackInterface* local_audio_track = 1214 local_streams->at(0)->GetAudioTracks()[0]; 1215 EXPECT_TRUE_WAIT( 1216 initializing_client()->GetBytesSentStats(local_audio_track) > 0, 1217 kMaxWaitForStatsMs); 1218 1219 MediaStreamTrackInterface* local_video_track = 1220 local_streams->at(0)->GetVideoTracks()[0]; 1221 EXPECT_TRUE_WAIT( 1222 initializing_client()->GetBytesSentStats(local_video_track) > 0, 1223 kMaxWaitForStatsMs); 1224 } 1225 1226 // This test sets up a call between two parties with audio, video and data. 1227 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDataChannel) { 1228 FakeConstraints setup_constraints; 1229 setup_constraints.SetAllowRtpDataChannels(); 1230 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); 1231 initializing_client()->CreateDataChannel(); 1232 LocalP2PTest(); 1233 ASSERT_TRUE(initializing_client()->data_channel() != NULL); 1234 ASSERT_TRUE(receiving_client()->data_channel() != NULL); 1235 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), 1236 kMaxWaitMs); 1237 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), 1238 kMaxWaitMs); 1239 1240 std::string data = "hello world"; 1241 initializing_client()->data_channel()->Send(DataBuffer(data)); 1242 EXPECT_EQ_WAIT(data, receiving_client()->data_observer()->last_message(), 1243 kMaxWaitMs); 1244 receiving_client()->data_channel()->Send(DataBuffer(data)); 1245 EXPECT_EQ_WAIT(data, initializing_client()->data_observer()->last_message(), 1246 kMaxWaitMs); 1247 1248 receiving_client()->data_channel()->Close(); 1249 // Send new offer and answer. 1250 receiving_client()->Negotiate(); 1251 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen()); 1252 EXPECT_FALSE(receiving_client()->data_observer()->IsOpen()); 1253 } 1254 1255 // This test sets up a call between two parties and creates a data channel. 1256 // The test tests that received data is buffered unless an observer has been 1257 // registered. 1258 // Rtp data channels can receive data before the underlying 1259 // transport has detected that a channel is writable and thus data can be 1260 // received before the data channel state changes to open. That is hard to test 1261 // but the same buffering is used in that case. 1262 TEST_F(JsepPeerConnectionP2PTestClient, RegisterDataChannelObserver) { 1263 FakeConstraints setup_constraints; 1264 setup_constraints.SetAllowRtpDataChannels(); 1265 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); 1266 initializing_client()->CreateDataChannel(); 1267 initializing_client()->Negotiate(); 1268 1269 ASSERT_TRUE(initializing_client()->data_channel() != NULL); 1270 ASSERT_TRUE(receiving_client()->data_channel() != NULL); 1271 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), 1272 kMaxWaitMs); 1273 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, 1274 receiving_client()->data_channel()->state(), kMaxWaitMs); 1275 1276 // Unregister the existing observer. 1277 receiving_client()->data_channel()->UnregisterObserver(); 1278 std::string data = "hello world"; 1279 initializing_client()->data_channel()->Send(DataBuffer(data)); 1280 // Wait a while to allow the sent data to arrive before an observer is 1281 // registered.. 1282 talk_base::Thread::Current()->ProcessMessages(100); 1283 1284 MockDataChannelObserver new_observer(receiving_client()->data_channel()); 1285 EXPECT_EQ_WAIT(data, new_observer.last_message(), kMaxWaitMs); 1286 } 1287 1288 // This test sets up a call between two parties with audio, video and but only 1289 // the initiating client support data. 1290 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestReceiverDoesntSupportData) { 1291 FakeConstraints setup_constraints; 1292 setup_constraints.SetAllowRtpDataChannels(); 1293 ASSERT_TRUE(CreateTestClients(&setup_constraints, NULL)); 1294 initializing_client()->CreateDataChannel(); 1295 LocalP2PTest(); 1296 EXPECT_TRUE(initializing_client()->data_channel() != NULL); 1297 EXPECT_FALSE(receiving_client()->data_channel()); 1298 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen()); 1299 } 1300 1301 // This test sets up a call between two parties with audio, video. When audio 1302 // and video is setup and flowing and data channel is negotiated. 1303 TEST_F(JsepPeerConnectionP2PTestClient, AddDataChannelAfterRenegotiation) { 1304 FakeConstraints setup_constraints; 1305 setup_constraints.SetAllowRtpDataChannels(); 1306 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); 1307 LocalP2PTest(); 1308 initializing_client()->CreateDataChannel(); 1309 // Send new offer and answer. 1310 initializing_client()->Negotiate(); 1311 ASSERT_TRUE(initializing_client()->data_channel() != NULL); 1312 ASSERT_TRUE(receiving_client()->data_channel() != NULL); 1313 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), 1314 kMaxWaitMs); 1315 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), 1316 kMaxWaitMs); 1317 } 1318 1319 // This test sets up a call between two parties with audio, and video. 1320 // During the call, the initializing side restart ice and the test verifies that 1321 // new ice candidates are generated and audio and video still can flow. 1322 TEST_F(JsepPeerConnectionP2PTestClient, IceRestart) { 1323 ASSERT_TRUE(CreateTestClients()); 1324 1325 // Negotiate and wait for ice completion and make sure audio and video plays. 1326 LocalP2PTest(); 1327 1328 // Create a SDP string of the first audio candidate for both clients. 1329 const webrtc::IceCandidateCollection* audio_candidates_initiator = 1330 initializing_client()->pc()->local_description()->candidates(0); 1331 const webrtc::IceCandidateCollection* audio_candidates_receiver = 1332 receiving_client()->pc()->local_description()->candidates(0); 1333 ASSERT_GT(audio_candidates_initiator->count(), 0u); 1334 ASSERT_GT(audio_candidates_receiver->count(), 0u); 1335 std::string initiator_candidate; 1336 EXPECT_TRUE( 1337 audio_candidates_initiator->at(0)->ToString(&initiator_candidate)); 1338 std::string receiver_candidate; 1339 EXPECT_TRUE(audio_candidates_receiver->at(0)->ToString(&receiver_candidate)); 1340 1341 // Restart ice on the initializing client. 1342 receiving_client()->SetExpectIceRestart(true); 1343 initializing_client()->IceRestart(); 1344 1345 // Negotiate and wait for ice completion again and make sure audio and video 1346 // plays. 1347 LocalP2PTest(); 1348 1349 // Create a SDP string of the first audio candidate for both clients again. 1350 const webrtc::IceCandidateCollection* audio_candidates_initiator_restart = 1351 initializing_client()->pc()->local_description()->candidates(0); 1352 const webrtc::IceCandidateCollection* audio_candidates_reciever_restart = 1353 receiving_client()->pc()->local_description()->candidates(0); 1354 ASSERT_GT(audio_candidates_initiator_restart->count(), 0u); 1355 ASSERT_GT(audio_candidates_reciever_restart->count(), 0u); 1356 std::string initiator_candidate_restart; 1357 EXPECT_TRUE(audio_candidates_initiator_restart->at(0)->ToString( 1358 &initiator_candidate_restart)); 1359 std::string receiver_candidate_restart; 1360 EXPECT_TRUE(audio_candidates_reciever_restart->at(0)->ToString( 1361 &receiver_candidate_restart)); 1362 1363 // Verify that the first candidates in the local session descriptions has 1364 // changed. 1365 EXPECT_NE(initiator_candidate, initiator_candidate_restart); 1366 EXPECT_NE(receiver_candidate, receiver_candidate_restart); 1367 } 1368 1369 1370 // This test sets up a Jsep call between two parties with external 1371 // VideoDecoderFactory. 1372 TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestWithVideoDecoderFactory) { 1373 ASSERT_TRUE(CreateTestClients()); 1374 EnableVideoDecoderFactory(); 1375 LocalP2PTest(); 1376 } 1377