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 <string> 29 30#include "talk/app/webrtc/fakeportallocatorfactory.h" 31#include "talk/app/webrtc/jsepsessiondescription.h" 32#include "talk/app/webrtc/mediastreaminterface.h" 33#include "talk/app/webrtc/peerconnectioninterface.h" 34#include "talk/app/webrtc/test/fakeconstraints.h" 35#include "talk/app/webrtc/test/mockpeerconnectionobservers.h" 36#include "talk/app/webrtc/test/testsdpstrings.h" 37#include "talk/app/webrtc/videosource.h" 38#include "talk/base/gunit.h" 39#include "talk/base/scoped_ptr.h" 40#include "talk/base/ssladapter.h" 41#include "talk/base/sslstreamadapter.h" 42#include "talk/base/stringutils.h" 43#include "talk/base/thread.h" 44#include "talk/media/base/fakevideocapturer.h" 45#include "talk/media/sctp/sctpdataengine.h" 46#include "talk/session/media/mediasession.h" 47 48static const char kStreamLabel1[] = "local_stream_1"; 49static const char kStreamLabel2[] = "local_stream_2"; 50static const char kStreamLabel3[] = "local_stream_3"; 51static const int kDefaultStunPort = 3478; 52static const char kStunAddressOnly[] = "stun:address"; 53static const char kStunInvalidPort[] = "stun:address:-1"; 54static const char kStunAddressPortAndMore1[] = "stun:address:port:more"; 55static const char kStunAddressPortAndMore2[] = "stun:address:port more"; 56static const char kTurnIceServerUri[] = "turn:user@turn.example.org"; 57static const char kTurnUsername[] = "user"; 58static const char kTurnPassword[] = "password"; 59static const char kTurnHostname[] = "turn.example.org"; 60static const uint32 kTimeout = 5000U; 61 62#define MAYBE_SKIP_TEST(feature) \ 63 if (!(feature())) { \ 64 LOG(LS_INFO) << "Feature disabled... skipping"; \ 65 return; \ 66 } 67 68using talk_base::scoped_ptr; 69using talk_base::scoped_refptr; 70using webrtc::AudioSourceInterface; 71using webrtc::AudioTrackInterface; 72using webrtc::DataBuffer; 73using webrtc::DataChannelInterface; 74using webrtc::FakeConstraints; 75using webrtc::FakePortAllocatorFactory; 76using webrtc::IceCandidateInterface; 77using webrtc::MediaStreamInterface; 78using webrtc::MediaStreamTrackInterface; 79using webrtc::MockCreateSessionDescriptionObserver; 80using webrtc::MockDataChannelObserver; 81using webrtc::MockSetSessionDescriptionObserver; 82using webrtc::MockStatsObserver; 83using webrtc::PeerConnectionInterface; 84using webrtc::PeerConnectionObserver; 85using webrtc::PortAllocatorFactoryInterface; 86using webrtc::SdpParseError; 87using webrtc::SessionDescriptionInterface; 88using webrtc::VideoSourceInterface; 89using webrtc::VideoTrackInterface; 90 91namespace { 92 93// Gets the first ssrc of given content type from the ContentInfo. 94bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) { 95 if (!content_info || !ssrc) { 96 return false; 97 } 98 const cricket::MediaContentDescription* media_desc = 99 static_cast<const cricket::MediaContentDescription*>( 100 content_info->description); 101 if (!media_desc || media_desc->streams().empty()) { 102 return false; 103 } 104 *ssrc = media_desc->streams().begin()->first_ssrc(); 105 return true; 106} 107 108void SetSsrcToZero(std::string* sdp) { 109 const char kSdpSsrcAtribute[] = "a=ssrc:"; 110 const char kSdpSsrcAtributeZero[] = "a=ssrc:0"; 111 size_t ssrc_pos = 0; 112 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) != 113 std::string::npos) { 114 size_t end_ssrc = sdp->find(" ", ssrc_pos); 115 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero); 116 ssrc_pos = end_ssrc; 117 } 118} 119 120class MockPeerConnectionObserver : public PeerConnectionObserver { 121 public: 122 MockPeerConnectionObserver() 123 : renegotiation_needed_(false), 124 ice_complete_(false) { 125 } 126 ~MockPeerConnectionObserver() { 127 } 128 void SetPeerConnectionInterface(PeerConnectionInterface* pc) { 129 pc_ = pc; 130 if (pc) { 131 state_ = pc_->signaling_state(); 132 } 133 } 134 virtual void OnError() {} 135 virtual void OnSignalingChange( 136 PeerConnectionInterface::SignalingState new_state) { 137 EXPECT_EQ(pc_->signaling_state(), new_state); 138 state_ = new_state; 139 } 140 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange. 141 virtual void OnStateChange(StateType state_changed) { 142 if (pc_.get() == NULL) 143 return; 144 switch (state_changed) { 145 case kSignalingState: 146 // OnSignalingChange and OnStateChange(kSignalingState) should always 147 // be called approximately simultaneously. To ease testing, we require 148 // that they always be called in that order. This check verifies 149 // that OnSignalingChange has just been called. 150 EXPECT_EQ(pc_->signaling_state(), state_); 151 break; 152 case kIceState: 153 ADD_FAILURE(); 154 break; 155 default: 156 ADD_FAILURE(); 157 break; 158 } 159 } 160 virtual void OnAddStream(MediaStreamInterface* stream) { 161 last_added_stream_ = stream; 162 } 163 virtual void OnRemoveStream(MediaStreamInterface* stream) { 164 last_removed_stream_ = stream; 165 } 166 virtual void OnRenegotiationNeeded() { 167 renegotiation_needed_ = true; 168 } 169 virtual void OnDataChannel(DataChannelInterface* data_channel) { 170 last_datachannel_ = data_channel; 171 } 172 173 virtual void OnIceConnectionChange( 174 PeerConnectionInterface::IceConnectionState new_state) { 175 EXPECT_EQ(pc_->ice_connection_state(), new_state); 176 } 177 virtual void OnIceGatheringChange( 178 PeerConnectionInterface::IceGatheringState new_state) { 179 EXPECT_EQ(pc_->ice_gathering_state(), new_state); 180 } 181 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) { 182 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, 183 pc_->ice_gathering_state()); 184 185 std::string sdp; 186 EXPECT_TRUE(candidate->ToString(&sdp)); 187 EXPECT_LT(0u, sdp.size()); 188 last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(), 189 candidate->sdp_mline_index(), sdp, NULL)); 190 EXPECT_TRUE(last_candidate_.get() != NULL); 191 } 192 // TODO(bemasc): Remove this once callers transition to OnSignalingChange. 193 virtual void OnIceComplete() { 194 ice_complete_ = true; 195 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should 196 // be called approximately simultaneously. For ease of testing, this 197 // check additionally requires that they be called in the above order. 198 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, 199 pc_->ice_gathering_state()); 200 } 201 202 // Returns the label of the last added stream. 203 // Empty string if no stream have been added. 204 std::string GetLastAddedStreamLabel() { 205 if (last_added_stream_.get()) 206 return last_added_stream_->label(); 207 return ""; 208 } 209 std::string GetLastRemovedStreamLabel() { 210 if (last_removed_stream_.get()) 211 return last_removed_stream_->label(); 212 return ""; 213 } 214 215 scoped_refptr<PeerConnectionInterface> pc_; 216 PeerConnectionInterface::SignalingState state_; 217 scoped_ptr<IceCandidateInterface> last_candidate_; 218 scoped_refptr<DataChannelInterface> last_datachannel_; 219 bool renegotiation_needed_; 220 bool ice_complete_; 221 222 private: 223 scoped_refptr<MediaStreamInterface> last_added_stream_; 224 scoped_refptr<MediaStreamInterface> last_removed_stream_; 225}; 226 227} // namespace 228class PeerConnectionInterfaceTest : public testing::Test { 229 protected: 230 virtual void SetUp() { 231 talk_base::InitializeSSL(NULL); 232 pc_factory_ = webrtc::CreatePeerConnectionFactory( 233 talk_base::Thread::Current(), talk_base::Thread::Current(), NULL, NULL, 234 NULL); 235 ASSERT_TRUE(pc_factory_.get() != NULL); 236 } 237 238 virtual void TearDown() { 239 talk_base::CleanupSSL(); 240 } 241 242 void CreatePeerConnection() { 243 CreatePeerConnection("", "", NULL); 244 } 245 246 void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) { 247 CreatePeerConnection("", "", constraints); 248 } 249 250 void CreatePeerConnection(const std::string& uri, 251 const std::string& password, 252 webrtc::MediaConstraintsInterface* constraints) { 253 PeerConnectionInterface::IceServer server; 254 PeerConnectionInterface::IceServers servers; 255 server.uri = uri; 256 server.password = password; 257 servers.push_back(server); 258 259 port_allocator_factory_ = FakePortAllocatorFactory::Create(); 260 pc_ = pc_factory_->CreatePeerConnection(servers, constraints, 261 port_allocator_factory_.get(), 262 NULL, 263 &observer_); 264 ASSERT_TRUE(pc_.get() != NULL); 265 observer_.SetPeerConnectionInterface(pc_.get()); 266 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 267 } 268 269 void CreatePeerConnectionWithDifferentConfigurations() { 270 CreatePeerConnection(kStunAddressOnly, "", NULL); 271 EXPECT_EQ(1u, port_allocator_factory_->stun_configs().size()); 272 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 273 EXPECT_EQ("address", 274 port_allocator_factory_->stun_configs()[0].server.hostname()); 275 EXPECT_EQ(kDefaultStunPort, 276 port_allocator_factory_->stun_configs()[0].server.port()); 277 278 CreatePeerConnection(kStunInvalidPort, "", NULL); 279 EXPECT_EQ(0u, port_allocator_factory_->stun_configs().size()); 280 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 281 282 CreatePeerConnection(kStunAddressPortAndMore1, "", NULL); 283 EXPECT_EQ(0u, port_allocator_factory_->stun_configs().size()); 284 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 285 286 CreatePeerConnection(kStunAddressPortAndMore2, "", NULL); 287 EXPECT_EQ(0u, port_allocator_factory_->stun_configs().size()); 288 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 289 290 CreatePeerConnection(kTurnIceServerUri, kTurnPassword, NULL); 291 EXPECT_EQ(1u, port_allocator_factory_->stun_configs().size()); 292 EXPECT_EQ(1u, port_allocator_factory_->turn_configs().size()); 293 EXPECT_EQ(kTurnUsername, 294 port_allocator_factory_->turn_configs()[0].username); 295 EXPECT_EQ(kTurnPassword, 296 port_allocator_factory_->turn_configs()[0].password); 297 EXPECT_EQ(kTurnHostname, 298 port_allocator_factory_->turn_configs()[0].server.hostname()); 299 EXPECT_EQ(kTurnHostname, 300 port_allocator_factory_->stun_configs()[0].server.hostname()); 301 } 302 303 void ReleasePeerConnection() { 304 pc_ = NULL; 305 observer_.SetPeerConnectionInterface(NULL); 306 } 307 308 void AddStream(const std::string& label) { 309 // Create a local stream. 310 scoped_refptr<MediaStreamInterface> stream( 311 pc_factory_->CreateLocalMediaStream(label)); 312 scoped_refptr<VideoSourceInterface> video_source( 313 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL)); 314 scoped_refptr<VideoTrackInterface> video_track( 315 pc_factory_->CreateVideoTrack(label + "v0", video_source)); 316 stream->AddTrack(video_track.get()); 317 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 318 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 319 observer_.renegotiation_needed_ = false; 320 } 321 322 void AddVoiceStream(const std::string& label) { 323 // Create a local stream. 324 scoped_refptr<MediaStreamInterface> stream( 325 pc_factory_->CreateLocalMediaStream(label)); 326 scoped_refptr<AudioTrackInterface> audio_track( 327 pc_factory_->CreateAudioTrack(label + "a0", NULL)); 328 stream->AddTrack(audio_track.get()); 329 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 330 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 331 observer_.renegotiation_needed_ = false; 332 } 333 334 void AddAudioVideoStream(const std::string& stream_label, 335 const std::string& audio_track_label, 336 const std::string& video_track_label) { 337 // Create a local stream. 338 scoped_refptr<MediaStreamInterface> stream( 339 pc_factory_->CreateLocalMediaStream(stream_label)); 340 scoped_refptr<AudioTrackInterface> audio_track( 341 pc_factory_->CreateAudioTrack( 342 audio_track_label, static_cast<AudioSourceInterface*>(NULL))); 343 stream->AddTrack(audio_track.get()); 344 scoped_refptr<VideoTrackInterface> video_track( 345 pc_factory_->CreateVideoTrack(video_track_label, NULL)); 346 stream->AddTrack(video_track.get()); 347 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 348 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 349 observer_.renegotiation_needed_ = false; 350 } 351 352 bool DoCreateOfferAnswer(SessionDescriptionInterface** desc, bool offer) { 353 talk_base::scoped_refptr<MockCreateSessionDescriptionObserver> 354 observer(new talk_base::RefCountedObject< 355 MockCreateSessionDescriptionObserver>()); 356 if (offer) { 357 pc_->CreateOffer(observer, NULL); 358 } else { 359 pc_->CreateAnswer(observer, NULL); 360 } 361 EXPECT_EQ_WAIT(true, observer->called(), kTimeout); 362 *desc = observer->release_desc(); 363 return observer->result(); 364 } 365 366 bool DoCreateOffer(SessionDescriptionInterface** desc) { 367 return DoCreateOfferAnswer(desc, true); 368 } 369 370 bool DoCreateAnswer(SessionDescriptionInterface** desc) { 371 return DoCreateOfferAnswer(desc, false); 372 } 373 374 bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) { 375 talk_base::scoped_refptr<MockSetSessionDescriptionObserver> 376 observer(new talk_base::RefCountedObject< 377 MockSetSessionDescriptionObserver>()); 378 if (local) { 379 pc_->SetLocalDescription(observer, desc); 380 } else { 381 pc_->SetRemoteDescription(observer, desc); 382 } 383 EXPECT_EQ_WAIT(true, observer->called(), kTimeout); 384 return observer->result(); 385 } 386 387 bool DoSetLocalDescription(SessionDescriptionInterface* desc) { 388 return DoSetSessionDescription(desc, true); 389 } 390 391 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) { 392 return DoSetSessionDescription(desc, false); 393 } 394 395 // Calls PeerConnection::GetStats and check the return value. 396 // It does not verify the values in the StatReports since a RTCP packet might 397 // be required. 398 bool DoGetStats(MediaStreamTrackInterface* track) { 399 talk_base::scoped_refptr<MockStatsObserver> observer( 400 new talk_base::RefCountedObject<MockStatsObserver>()); 401 if (!pc_->GetStats(observer, track)) 402 return false; 403 EXPECT_TRUE_WAIT(observer->called(), kTimeout); 404 return observer->called(); 405 } 406 407 void InitiateCall() { 408 CreatePeerConnection(); 409 // Create a local stream with audio&video tracks. 410 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 411 CreateOfferReceiveAnswer(); 412 } 413 414 // Verify that RTP Header extensions has been negotiated for audio and video. 415 void VerifyRemoteRtpHeaderExtensions() { 416 const cricket::MediaContentDescription* desc = 417 cricket::GetFirstAudioContentDescription( 418 pc_->remote_description()->description()); 419 ASSERT_TRUE(desc != NULL); 420 EXPECT_GT(desc->rtp_header_extensions().size(), 0u); 421 422 desc = cricket::GetFirstVideoContentDescription( 423 pc_->remote_description()->description()); 424 ASSERT_TRUE(desc != NULL); 425 EXPECT_GT(desc->rtp_header_extensions().size(), 0u); 426 } 427 428 void CreateOfferAsRemoteDescription() { 429 talk_base::scoped_ptr<SessionDescriptionInterface> offer; 430 EXPECT_TRUE(DoCreateOffer(offer.use())); 431 std::string sdp; 432 EXPECT_TRUE(offer->ToString(&sdp)); 433 SessionDescriptionInterface* remote_offer = 434 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 435 sdp, NULL); 436 EXPECT_TRUE(DoSetRemoteDescription(remote_offer)); 437 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_); 438 } 439 440 void CreateAnswerAsLocalDescription() { 441 scoped_ptr<SessionDescriptionInterface> answer; 442 EXPECT_TRUE(DoCreateAnswer(answer.use())); 443 444 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an 445 // audio codec change, even if the parameter has nothing to do with 446 // receiving. Not all parameters are serialized to SDP. 447 // Since CreatePrAnswerAsLocalDescription serialize/deserialize 448 // the SessionDescription, it is necessary to do that here to in order to 449 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. 450 // https://code.google.com/p/webrtc/issues/detail?id=1356 451 std::string sdp; 452 EXPECT_TRUE(answer->ToString(&sdp)); 453 SessionDescriptionInterface* new_answer = 454 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, 455 sdp, NULL); 456 EXPECT_TRUE(DoSetLocalDescription(new_answer)); 457 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 458 } 459 460 void CreatePrAnswerAsLocalDescription() { 461 scoped_ptr<SessionDescriptionInterface> answer; 462 EXPECT_TRUE(DoCreateAnswer(answer.use())); 463 464 std::string sdp; 465 EXPECT_TRUE(answer->ToString(&sdp)); 466 SessionDescriptionInterface* pr_answer = 467 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer, 468 sdp, NULL); 469 EXPECT_TRUE(DoSetLocalDescription(pr_answer)); 470 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_); 471 } 472 473 void CreateOfferReceiveAnswer() { 474 CreateOfferAsLocalDescription(); 475 std::string sdp; 476 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 477 CreateAnswerAsRemoteDescription(sdp); 478 } 479 480 void CreateOfferAsLocalDescription() { 481 talk_base::scoped_ptr<SessionDescriptionInterface> offer; 482 ASSERT_TRUE(DoCreateOffer(offer.use())); 483 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an 484 // audio codec change, even if the parameter has nothing to do with 485 // receiving. Not all parameters are serialized to SDP. 486 // Since CreatePrAnswerAsLocalDescription serialize/deserialize 487 // the SessionDescription, it is necessary to do that here to in order to 488 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. 489 // https://code.google.com/p/webrtc/issues/detail?id=1356 490 std::string sdp; 491 EXPECT_TRUE(offer->ToString(&sdp)); 492 SessionDescriptionInterface* new_offer = 493 webrtc::CreateSessionDescription( 494 SessionDescriptionInterface::kOffer, 495 sdp, NULL); 496 497 EXPECT_TRUE(DoSetLocalDescription(new_offer)); 498 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_); 499 } 500 501 void CreateAnswerAsRemoteDescription(const std::string& offer) { 502 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( 503 SessionDescriptionInterface::kAnswer); 504 EXPECT_TRUE(answer->Initialize(offer, NULL)); 505 EXPECT_TRUE(DoSetRemoteDescription(answer)); 506 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 507 } 508 509 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& offer) { 510 webrtc::JsepSessionDescription* pr_answer = 511 new webrtc::JsepSessionDescription( 512 SessionDescriptionInterface::kPrAnswer); 513 EXPECT_TRUE(pr_answer->Initialize(offer, NULL)); 514 EXPECT_TRUE(DoSetRemoteDescription(pr_answer)); 515 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_); 516 webrtc::JsepSessionDescription* answer = 517 new webrtc::JsepSessionDescription( 518 SessionDescriptionInterface::kAnswer); 519 EXPECT_TRUE(answer->Initialize(offer, NULL)); 520 EXPECT_TRUE(DoSetRemoteDescription(answer)); 521 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 522 } 523 524 // Help function used for waiting until a the last signaled remote stream has 525 // the same label as |stream_label|. In a few of the tests in this file we 526 // answer with the same session description as we offer and thus we can 527 // check if OnAddStream have been called with the same stream as we offer to 528 // send. 529 void WaitAndVerifyOnAddStream(const std::string& stream_label) { 530 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout); 531 } 532 533 // Creates an offer and applies it as a local session description. 534 // Creates an answer with the same SDP an the offer but removes all lines 535 // that start with a:ssrc" 536 void CreateOfferReceiveAnswerWithoutSsrc() { 537 CreateOfferAsLocalDescription(); 538 std::string sdp; 539 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 540 SetSsrcToZero(&sdp); 541 CreateAnswerAsRemoteDescription(sdp); 542 } 543 544 scoped_refptr<FakePortAllocatorFactory> port_allocator_factory_; 545 scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; 546 scoped_refptr<PeerConnectionInterface> pc_; 547 MockPeerConnectionObserver observer_; 548}; 549 550TEST_F(PeerConnectionInterfaceTest, 551 CreatePeerConnectionWithDifferentConfigurations) { 552 CreatePeerConnectionWithDifferentConfigurations(); 553} 554 555TEST_F(PeerConnectionInterfaceTest, AddStreams) { 556 CreatePeerConnection(); 557 AddStream(kStreamLabel1); 558 AddVoiceStream(kStreamLabel2); 559 ASSERT_EQ(2u, pc_->local_streams()->count()); 560 561 // Test we can add multiple local streams to one peerconnection. 562 scoped_refptr<MediaStreamInterface> stream( 563 pc_factory_->CreateLocalMediaStream(kStreamLabel3)); 564 scoped_refptr<AudioTrackInterface> audio_track( 565 pc_factory_->CreateAudioTrack( 566 kStreamLabel3, static_cast<AudioSourceInterface*>(NULL))); 567 stream->AddTrack(audio_track.get()); 568 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 569 EXPECT_EQ(3u, pc_->local_streams()->count()); 570 571 // Remove the third stream. 572 pc_->RemoveStream(pc_->local_streams()->at(2)); 573 EXPECT_EQ(2u, pc_->local_streams()->count()); 574 575 // Remove the second stream. 576 pc_->RemoveStream(pc_->local_streams()->at(1)); 577 EXPECT_EQ(1u, pc_->local_streams()->count()); 578 579 // Remove the first stream. 580 pc_->RemoveStream(pc_->local_streams()->at(0)); 581 EXPECT_EQ(0u, pc_->local_streams()->count()); 582} 583 584TEST_F(PeerConnectionInterfaceTest, RemoveStream) { 585 CreatePeerConnection(); 586 AddStream(kStreamLabel1); 587 ASSERT_EQ(1u, pc_->local_streams()->count()); 588 pc_->RemoveStream(pc_->local_streams()->at(0)); 589 EXPECT_EQ(0u, pc_->local_streams()->count()); 590} 591 592TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) { 593 InitiateCall(); 594 WaitAndVerifyOnAddStream(kStreamLabel1); 595 VerifyRemoteRtpHeaderExtensions(); 596} 597 598TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) { 599 CreatePeerConnection(); 600 AddStream(kStreamLabel1); 601 CreateOfferAsLocalDescription(); 602 std::string offer; 603 EXPECT_TRUE(pc_->local_description()->ToString(&offer)); 604 CreatePrAnswerAndAnswerAsRemoteDescription(offer); 605 WaitAndVerifyOnAddStream(kStreamLabel1); 606} 607 608TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) { 609 CreatePeerConnection(); 610 AddStream(kStreamLabel1); 611 612 CreateOfferAsRemoteDescription(); 613 CreateAnswerAsLocalDescription(); 614 615 WaitAndVerifyOnAddStream(kStreamLabel1); 616} 617 618TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) { 619 CreatePeerConnection(); 620 AddStream(kStreamLabel1); 621 622 CreateOfferAsRemoteDescription(); 623 CreatePrAnswerAsLocalDescription(); 624 CreateAnswerAsLocalDescription(); 625 626 WaitAndVerifyOnAddStream(kStreamLabel1); 627} 628 629TEST_F(PeerConnectionInterfaceTest, Renegotiate) { 630 InitiateCall(); 631 ASSERT_EQ(1u, pc_->remote_streams()->count()); 632 pc_->RemoveStream(pc_->local_streams()->at(0)); 633 CreateOfferReceiveAnswer(); 634 EXPECT_EQ(0u, pc_->remote_streams()->count()); 635 AddStream(kStreamLabel1); 636 CreateOfferReceiveAnswer(); 637} 638 639// Tests that after negotiating an audio only call, the respondent can perform a 640// renegotiation that removes the audio stream. 641TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) { 642 CreatePeerConnection(); 643 AddVoiceStream(kStreamLabel1); 644 CreateOfferAsRemoteDescription(); 645 CreateAnswerAsLocalDescription(); 646 647 ASSERT_EQ(1u, pc_->remote_streams()->count()); 648 pc_->RemoveStream(pc_->local_streams()->at(0)); 649 CreateOfferReceiveAnswer(); 650 EXPECT_EQ(0u, pc_->remote_streams()->count()); 651} 652 653// Test that candidates are generated and that we can parse our own candidates. 654TEST_F(PeerConnectionInterfaceTest, IceCandidates) { 655 CreatePeerConnection(); 656 657 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get())); 658 // SetRemoteDescription takes ownership of offer. 659 SessionDescriptionInterface* offer = NULL; 660 AddStream(kStreamLabel1); 661 EXPECT_TRUE(DoCreateOffer(&offer)); 662 EXPECT_TRUE(DoSetRemoteDescription(offer)); 663 664 // SetLocalDescription takes ownership of answer. 665 SessionDescriptionInterface* answer = NULL; 666 EXPECT_TRUE(DoCreateAnswer(&answer)); 667 EXPECT_TRUE(DoSetLocalDescription(answer)); 668 669 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout); 670 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); 671 672 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get())); 673} 674 675// Test that the CreateOffer and CreatAnswer will fail if the track labels are 676// not unique. 677TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) { 678 CreatePeerConnection(); 679 // Create a regular offer for the CreateAnswer test later. 680 SessionDescriptionInterface* offer = NULL; 681 EXPECT_TRUE(DoCreateOffer(&offer)); 682 EXPECT_TRUE(offer != NULL); 683 delete offer; 684 offer = NULL; 685 686 // Create a local stream with audio&video tracks having same label. 687 AddAudioVideoStream(kStreamLabel1, "track_label", "track_label"); 688 689 // Test CreateOffer 690 EXPECT_FALSE(DoCreateOffer(&offer)); 691 692 // Test CreateAnswer 693 SessionDescriptionInterface* answer = NULL; 694 EXPECT_FALSE(DoCreateAnswer(&answer)); 695} 696 697// Test that we will get different SSRCs for each tracks in the offer and answer 698// we created. 699TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) { 700 CreatePeerConnection(); 701 // Create a local stream with audio&video tracks having different labels. 702 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 703 704 // Test CreateOffer 705 scoped_ptr<SessionDescriptionInterface> offer; 706 EXPECT_TRUE(DoCreateOffer(offer.use())); 707 int audio_ssrc = 0; 708 int video_ssrc = 0; 709 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()), 710 &audio_ssrc)); 711 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(offer->description()), 712 &video_ssrc)); 713 EXPECT_NE(audio_ssrc, video_ssrc); 714 715 // Test CreateAnswer 716 EXPECT_TRUE(DoSetRemoteDescription(offer.release())); 717 scoped_ptr<SessionDescriptionInterface> answer; 718 EXPECT_TRUE(DoCreateAnswer(answer.use())); 719 audio_ssrc = 0; 720 video_ssrc = 0; 721 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()), 722 &audio_ssrc)); 723 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(answer->description()), 724 &video_ssrc)); 725 EXPECT_NE(audio_ssrc, video_ssrc); 726} 727 728// Test that we can specify a certain track that we want statistics about. 729TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) { 730 InitiateCall(); 731 ASSERT_LT(0u, pc_->remote_streams()->count()); 732 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size()); 733 scoped_refptr<MediaStreamTrackInterface> remote_audio = 734 pc_->remote_streams()->at(0)->GetAudioTracks()[0]; 735 EXPECT_TRUE(DoGetStats(remote_audio)); 736 737 // Remove the stream. Since we are sending to our selves the local 738 // and the remote stream is the same. 739 pc_->RemoveStream(pc_->local_streams()->at(0)); 740 // Do a re-negotiation. 741 CreateOfferReceiveAnswer(); 742 743 ASSERT_EQ(0u, pc_->remote_streams()->count()); 744 745 // Test that we still can get statistics for the old track. Even if it is not 746 // sent any longer. 747 EXPECT_TRUE(DoGetStats(remote_audio)); 748} 749 750// Test that we can get stats on a video track. 751TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) { 752 InitiateCall(); 753 ASSERT_LT(0u, pc_->remote_streams()->count()); 754 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size()); 755 scoped_refptr<MediaStreamTrackInterface> remote_video = 756 pc_->remote_streams()->at(0)->GetVideoTracks()[0]; 757 EXPECT_TRUE(DoGetStats(remote_video)); 758} 759 760// Test that we don't get statistics for an invalid track. 761TEST_F(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) { 762 InitiateCall(); 763 scoped_refptr<AudioTrackInterface> unknown_audio_track( 764 pc_factory_->CreateAudioTrack("unknown track", NULL)); 765 EXPECT_FALSE(DoGetStats(unknown_audio_track)); 766} 767 768// This test setup two RTP data channels in loop back. 769#ifdef WIN32 770// TODO(perkj): Investigate why the transport channel sometimes don't become 771// writable on Windows when we try to connect in loop back. 772TEST_F(PeerConnectionInterfaceTest, DISABLED_TestDataChannel) { 773#else 774TEST_F(PeerConnectionInterfaceTest, TestDataChannel) { 775#endif 776 FakeConstraints constraints; 777 constraints.SetAllowRtpDataChannels(); 778 CreatePeerConnection(&constraints); 779 scoped_refptr<DataChannelInterface> data1 = 780 pc_->CreateDataChannel("test1", NULL); 781 scoped_refptr<DataChannelInterface> data2 = 782 pc_->CreateDataChannel("test2", NULL); 783 ASSERT_TRUE(data1 != NULL); 784 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 785 new MockDataChannelObserver(data1)); 786 talk_base::scoped_ptr<MockDataChannelObserver> observer2( 787 new MockDataChannelObserver(data2)); 788 789 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); 790 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); 791 std::string data_to_send1 = "testing testing"; 792 std::string data_to_send2 = "testing something else"; 793 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1))); 794 795 CreateOfferReceiveAnswer(); 796 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 797 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 798 799 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); 800 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); 801 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1))); 802 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2))); 803 804 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout); 805 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); 806 807 data1->Close(); 808 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); 809 CreateOfferReceiveAnswer(); 810 EXPECT_FALSE(observer1->IsOpen()); 811 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 812 EXPECT_TRUE(observer2->IsOpen()); 813 814 data_to_send2 = "testing something else again"; 815 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2))); 816 817 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); 818} 819 820// This test verifies that sendnig binary data over RTP data channels should 821// fail. 822#ifdef WIN32 823// TODO(perkj): Investigate why the transport channel sometimes don't become 824// writable on Windows when we try to connect in loop back. 825TEST_F(PeerConnectionInterfaceTest, DISABLED_TestSendBinaryOnRtpDataChannel) { 826#else 827TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) { 828#endif 829 FakeConstraints constraints; 830 constraints.SetAllowRtpDataChannels(); 831 CreatePeerConnection(&constraints); 832 scoped_refptr<DataChannelInterface> data1 = 833 pc_->CreateDataChannel("test1", NULL); 834 scoped_refptr<DataChannelInterface> data2 = 835 pc_->CreateDataChannel("test2", NULL); 836 ASSERT_TRUE(data1 != NULL); 837 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 838 new MockDataChannelObserver(data1)); 839 talk_base::scoped_ptr<MockDataChannelObserver> observer2( 840 new MockDataChannelObserver(data2)); 841 842 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); 843 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); 844 845 CreateOfferReceiveAnswer(); 846 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 847 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 848 849 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); 850 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); 851 852 talk_base::Buffer buffer("test", 4); 853 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true))); 854} 855 856// This test setup a RTP data channels in loop back and test that a channel is 857// opened even if the remote end answer with a zero SSRC. 858#ifdef WIN32 859// TODO(perkj): Investigate why the transport channel sometimes don't become 860// writable on Windows when we try to connect in loop back. 861TEST_F(PeerConnectionInterfaceTest, DISABLED_TestSendOnlyDataChannel) { 862#else 863TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) { 864#endif 865 FakeConstraints constraints; 866 constraints.SetAllowRtpDataChannels(); 867 CreatePeerConnection(&constraints); 868 scoped_refptr<DataChannelInterface> data1 = 869 pc_->CreateDataChannel("test1", NULL); 870 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 871 new MockDataChannelObserver(data1)); 872 873 CreateOfferReceiveAnswerWithoutSsrc(); 874 875 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 876 877 data1->Close(); 878 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); 879 CreateOfferReceiveAnswerWithoutSsrc(); 880 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 881 EXPECT_FALSE(observer1->IsOpen()); 882} 883 884// This test that if a data channel is added in an answer a receive only channel 885// channel is created. 886TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) { 887 FakeConstraints constraints; 888 constraints.SetAllowRtpDataChannels(); 889 CreatePeerConnection(&constraints); 890 891 std::string offer_label = "offer_channel"; 892 scoped_refptr<DataChannelInterface> offer_channel = 893 pc_->CreateDataChannel(offer_label, NULL); 894 895 CreateOfferAsLocalDescription(); 896 897 // Replace the data channel label in the offer and apply it as an answer. 898 std::string receive_label = "answer_channel"; 899 std::string sdp; 900 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 901 talk_base::replace_substrs(offer_label.c_str(), offer_label.length(), 902 receive_label.c_str(), receive_label.length(), 903 &sdp); 904 CreateAnswerAsRemoteDescription(sdp); 905 906 // Verify that a new incoming data channel has been created and that 907 // it is open but can't we written to. 908 ASSERT_TRUE(observer_.last_datachannel_ != NULL); 909 DataChannelInterface* received_channel = observer_.last_datachannel_; 910 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state()); 911 EXPECT_EQ(receive_label, received_channel->label()); 912 EXPECT_FALSE(received_channel->Send(DataBuffer("something"))); 913 914 // Verify that the channel we initially offered has been rejected. 915 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state()); 916 917 // Do another offer / answer exchange and verify that the data channel is 918 // opened. 919 CreateOfferReceiveAnswer(); 920 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(), 921 kTimeout); 922} 923 924// This test that no data channel is returned if a reliable channel is 925// requested. 926// TODO(perkj): Remove this test once reliable channels are implemented. 927TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) { 928 FakeConstraints constraints; 929 constraints.SetAllowRtpDataChannels(); 930 CreatePeerConnection(&constraints); 931 932 std::string label = "test"; 933 webrtc::DataChannelInit config; 934 config.reliable = true; 935 scoped_refptr<DataChannelInterface> channel = 936 pc_->CreateDataChannel(label, &config); 937 EXPECT_TRUE(channel == NULL); 938} 939 940// This tests that a SCTP data channel is returned using different 941// DataChannelInit configurations. 942TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) { 943 FakeConstraints constraints; 944 constraints.SetAllowDtlsSctpDataChannels(); 945 CreatePeerConnection(&constraints); 946 947 webrtc::DataChannelInit config; 948 949 scoped_refptr<DataChannelInterface> channel = 950 pc_->CreateDataChannel("1", &config); 951 EXPECT_TRUE(channel != NULL); 952 EXPECT_TRUE(channel->reliable()); 953 954 config.ordered = false; 955 channel = pc_->CreateDataChannel("2", &config); 956 EXPECT_TRUE(channel != NULL); 957 EXPECT_TRUE(channel->reliable()); 958 959 config.ordered = true; 960 config.maxRetransmits = 0; 961 channel = pc_->CreateDataChannel("3", &config); 962 EXPECT_TRUE(channel != NULL); 963 EXPECT_FALSE(channel->reliable()); 964 965 config.maxRetransmits = -1; 966 config.maxRetransmitTime = 0; 967 channel = pc_->CreateDataChannel("4", &config); 968 EXPECT_TRUE(channel != NULL); 969 EXPECT_FALSE(channel->reliable()); 970} 971 972// This tests that no data channel is returned if both maxRetransmits and 973// maxRetransmitTime are set for SCTP data channels. 974TEST_F(PeerConnectionInterfaceTest, 975 CreateSctpDataChannelShouldFailForInvalidConfig) { 976 FakeConstraints constraints; 977 constraints.SetAllowDtlsSctpDataChannels(); 978 CreatePeerConnection(&constraints); 979 980 std::string label = "test"; 981 webrtc::DataChannelInit config; 982 config.maxRetransmits = 0; 983 config.maxRetransmitTime = 0; 984 985 scoped_refptr<DataChannelInterface> channel = 986 pc_->CreateDataChannel(label, &config); 987 EXPECT_TRUE(channel == NULL); 988} 989 990// The test verifies that creating a SCTP data channel with an id already in use 991// or out of range should fail. 992TEST_F(PeerConnectionInterfaceTest, 993 CreateSctpDataChannelWithInvalidIdShouldFail) { 994 FakeConstraints constraints; 995 constraints.SetAllowDtlsSctpDataChannels(); 996 CreatePeerConnection(&constraints); 997 998 webrtc::DataChannelInit config; 999 scoped_refptr<DataChannelInterface> channel; 1000 1001 config.id = 1; 1002 channel = pc_->CreateDataChannel("1", &config); 1003 EXPECT_TRUE(channel != NULL); 1004 EXPECT_EQ(1, channel->id()); 1005 1006 channel = pc_->CreateDataChannel("x", &config); 1007 EXPECT_TRUE(channel == NULL); 1008 1009 config.id = cricket::kMaxSctpSid; 1010 channel = pc_->CreateDataChannel("max", &config); 1011 EXPECT_TRUE(channel != NULL); 1012 EXPECT_EQ(config.id, channel->id()); 1013 1014 config.id = cricket::kMaxSctpSid + 1; 1015 channel = pc_->CreateDataChannel("x", &config); 1016 EXPECT_TRUE(channel == NULL); 1017} 1018 1019// This test that a data channel closes when a PeerConnection is deleted/closed. 1020#ifdef WIN32 1021// TODO(perkj): Investigate why the transport channel sometimes don't become 1022// writable on Windows when we try to connect in loop back. 1023TEST_F(PeerConnectionInterfaceTest, 1024 DISABLED_DataChannelCloseWhenPeerConnectionClose) { 1025#else 1026TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) { 1027#endif 1028 FakeConstraints constraints; 1029 constraints.SetAllowRtpDataChannels(); 1030 CreatePeerConnection(&constraints); 1031 1032 scoped_refptr<DataChannelInterface> data1 = 1033 pc_->CreateDataChannel("test1", NULL); 1034 scoped_refptr<DataChannelInterface> data2 = 1035 pc_->CreateDataChannel("test2", NULL); 1036 ASSERT_TRUE(data1 != NULL); 1037 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 1038 new MockDataChannelObserver(data1)); 1039 talk_base::scoped_ptr<MockDataChannelObserver> observer2( 1040 new MockDataChannelObserver(data2)); 1041 1042 CreateOfferReceiveAnswer(); 1043 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 1044 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 1045 1046 ReleasePeerConnection(); 1047 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 1048 EXPECT_EQ(DataChannelInterface::kClosed, data2->state()); 1049} 1050 1051// This test that data channels can be rejected in an answer. 1052TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) { 1053 FakeConstraints constraints; 1054 constraints.SetAllowRtpDataChannels(); 1055 CreatePeerConnection(&constraints); 1056 1057 scoped_refptr<DataChannelInterface> offer_channel( 1058 pc_->CreateDataChannel("offer_channel", NULL)); 1059 1060 CreateOfferAsLocalDescription(); 1061 1062 // Create an answer where the m-line for data channels are rejected. 1063 std::string sdp; 1064 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 1065 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( 1066 SessionDescriptionInterface::kAnswer); 1067 EXPECT_TRUE(answer->Initialize(sdp, NULL)); 1068 cricket::ContentInfo* data_info = 1069 answer->description()->GetContentByName("data"); 1070 data_info->rejected = true; 1071 1072 DoSetRemoteDescription(answer); 1073 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state()); 1074} 1075 1076// Test that we can create a session description from an SDP string from 1077// FireFox, use it as a remote session description, generate an answer and use 1078// the answer as a local description. 1079TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) { 1080 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp); 1081 FakeConstraints constraints; 1082 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1083 true); 1084 CreatePeerConnection(&constraints); 1085 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1086 SessionDescriptionInterface* desc = 1087 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1088 webrtc::kFireFoxSdpOffer); 1089 EXPECT_TRUE(DoSetSessionDescription(desc, false)); 1090 CreateAnswerAsLocalDescription(); 1091 ASSERT_TRUE(pc_->local_description() != NULL); 1092 ASSERT_TRUE(pc_->remote_description() != NULL); 1093 1094 const cricket::ContentInfo* content = 1095 cricket::GetFirstAudioContent(pc_->local_description()->description()); 1096 ASSERT_TRUE(content != NULL); 1097 EXPECT_FALSE(content->rejected); 1098 1099 content = 1100 cricket::GetFirstVideoContent(pc_->local_description()->description()); 1101 ASSERT_TRUE(content != NULL); 1102 EXPECT_FALSE(content->rejected); 1103#ifdef HAVE_SCTP 1104 content = 1105 cricket::GetFirstDataContent(pc_->local_description()->description()); 1106 ASSERT_TRUE(content != NULL); 1107 EXPECT_TRUE(content->rejected); 1108#endif 1109} 1110 1111// Test that we can create an audio only offer and receive an answer with a 1112// limited set of audio codecs and receive an updated offer with more audio 1113// codecs, where the added codecs are not supported. 1114TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) { 1115 CreatePeerConnection(); 1116 AddVoiceStream("audio_label"); 1117 CreateOfferAsLocalDescription(); 1118 1119 SessionDescriptionInterface* answer = 1120 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, 1121 webrtc::kAudioSdp); 1122 EXPECT_TRUE(DoSetSessionDescription(answer, false)); 1123 1124 SessionDescriptionInterface* updated_offer = 1125 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1126 webrtc::kAudioSdpWithUnsupportedCodecs); 1127 EXPECT_TRUE(DoSetSessionDescription(updated_offer, false)); 1128 CreateAnswerAsLocalDescription(); 1129} 1130 1131// Test that PeerConnection::Close changes the states to closed and all remote 1132// tracks change state to ended. 1133TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) { 1134 // Initialize a PeerConnection and negotiate local and remote session 1135 // description. 1136 InitiateCall(); 1137 ASSERT_EQ(1u, pc_->local_streams()->count()); 1138 ASSERT_EQ(1u, pc_->remote_streams()->count()); 1139 1140 pc_->Close(); 1141 1142 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state()); 1143 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed, 1144 pc_->ice_connection_state()); 1145 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, 1146 pc_->ice_gathering_state()); 1147 1148 EXPECT_EQ(1u, pc_->local_streams()->count()); 1149 EXPECT_EQ(1u, pc_->remote_streams()->count()); 1150 1151 scoped_refptr<MediaStreamInterface> remote_stream = 1152 pc_->remote_streams()->at(0); 1153 EXPECT_EQ(MediaStreamTrackInterface::kEnded, 1154 remote_stream->GetVideoTracks()[0]->state()); 1155 EXPECT_EQ(MediaStreamTrackInterface::kEnded, 1156 remote_stream->GetAudioTracks()[0]->state()); 1157} 1158 1159// Test that PeerConnection methods fails gracefully after 1160// PeerConnection::Close has been called. 1161TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) { 1162 CreatePeerConnection(); 1163 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1164 CreateOfferAsRemoteDescription(); 1165 CreateAnswerAsLocalDescription(); 1166 1167 ASSERT_EQ(1u, pc_->local_streams()->count()); 1168 scoped_refptr<MediaStreamInterface> local_stream = 1169 pc_->local_streams()->at(0); 1170 1171 pc_->Close(); 1172 1173 pc_->RemoveStream(local_stream); 1174 EXPECT_FALSE(pc_->AddStream(local_stream, NULL)); 1175 1176 ASSERT_FALSE(local_stream->GetAudioTracks().empty()); 1177 talk_base::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender( 1178 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0])); 1179 EXPECT_TRUE(NULL == dtmf_sender); // local stream has been removed. 1180 1181 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL); 1182 1183 EXPECT_TRUE(pc_->local_description() != NULL); 1184 EXPECT_TRUE(pc_->remote_description() != NULL); 1185 1186 talk_base::scoped_ptr<SessionDescriptionInterface> offer; 1187 EXPECT_TRUE(DoCreateOffer(offer.use())); 1188 talk_base::scoped_ptr<SessionDescriptionInterface> answer; 1189 EXPECT_TRUE(DoCreateAnswer(answer.use())); 1190 1191 std::string sdp; 1192 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp)); 1193 SessionDescriptionInterface* remote_offer = 1194 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1195 sdp, NULL); 1196 EXPECT_FALSE(DoSetRemoteDescription(remote_offer)); 1197 1198 ASSERT_TRUE(pc_->local_description()->ToString(&sdp)); 1199 SessionDescriptionInterface* local_offer = 1200 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1201 sdp, NULL); 1202 EXPECT_FALSE(DoSetLocalDescription(local_offer)); 1203} 1204 1205// Test that GetStats can still be called after PeerConnection::Close. 1206TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) { 1207 InitiateCall(); 1208 pc_->Close(); 1209 DoGetStats(NULL); 1210} 1211