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#include <utility> 30 31#include "talk/app/webrtc/audiotrack.h" 32#include "talk/app/webrtc/jsepsessiondescription.h" 33#include "talk/app/webrtc/mediastream.h" 34#include "talk/app/webrtc/mediastreaminterface.h" 35#include "talk/app/webrtc/peerconnection.h" 36#include "talk/app/webrtc/peerconnectioninterface.h" 37#include "talk/app/webrtc/rtpreceiverinterface.h" 38#include "talk/app/webrtc/rtpsenderinterface.h" 39#include "talk/app/webrtc/streamcollection.h" 40#ifdef WEBRTC_ANDROID 41#include "talk/app/webrtc/test/androidtestinitializer.h" 42#endif 43#include "talk/app/webrtc/test/fakeconstraints.h" 44#include "talk/app/webrtc/test/fakedtlsidentitystore.h" 45#include "talk/app/webrtc/test/mockpeerconnectionobservers.h" 46#include "talk/app/webrtc/test/testsdpstrings.h" 47#include "talk/app/webrtc/videosource.h" 48#include "talk/app/webrtc/videotrack.h" 49#include "talk/media/base/fakevideocapturer.h" 50#include "talk/media/sctp/sctpdataengine.h" 51#include "talk/session/media/mediasession.h" 52#include "webrtc/base/gunit.h" 53#include "webrtc/base/scoped_ptr.h" 54#include "webrtc/base/ssladapter.h" 55#include "webrtc/base/sslstreamadapter.h" 56#include "webrtc/base/stringutils.h" 57#include "webrtc/base/thread.h" 58#include "webrtc/p2p/client/fakeportallocator.h" 59 60static const char kStreamLabel1[] = "local_stream_1"; 61static const char kStreamLabel2[] = "local_stream_2"; 62static const char kStreamLabel3[] = "local_stream_3"; 63static const int kDefaultStunPort = 3478; 64static const char kStunAddressOnly[] = "stun:address"; 65static const char kStunInvalidPort[] = "stun:address:-1"; 66static const char kStunAddressPortAndMore1[] = "stun:address:port:more"; 67static const char kStunAddressPortAndMore2[] = "stun:address:port more"; 68static const char kTurnIceServerUri[] = "turn:user@turn.example.org"; 69static const char kTurnUsername[] = "user"; 70static const char kTurnPassword[] = "password"; 71static const char kTurnHostname[] = "turn.example.org"; 72static const uint32_t kTimeout = 10000U; 73 74static const char kStreams[][8] = {"stream1", "stream2"}; 75static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"}; 76static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"}; 77 78static const char kRecvonly[] = "recvonly"; 79static const char kSendrecv[] = "sendrecv"; 80 81// Reference SDP with a MediaStream with label "stream1" and audio track with 82// id "audio_1" and a video track with id "video_1; 83static const char kSdpStringWithStream1[] = 84 "v=0\r\n" 85 "o=- 0 0 IN IP4 127.0.0.1\r\n" 86 "s=-\r\n" 87 "t=0 0\r\n" 88 "a=ice-ufrag:e5785931\r\n" 89 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" 90 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" 91 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" 92 "m=audio 1 RTP/AVPF 103\r\n" 93 "a=mid:audio\r\n" 94 "a=sendrecv\r\n" 95 "a=rtpmap:103 ISAC/16000\r\n" 96 "a=ssrc:1 cname:stream1\r\n" 97 "a=ssrc:1 mslabel:stream1\r\n" 98 "a=ssrc:1 label:audiotrack0\r\n" 99 "m=video 1 RTP/AVPF 120\r\n" 100 "a=mid:video\r\n" 101 "a=sendrecv\r\n" 102 "a=rtpmap:120 VP8/90000\r\n" 103 "a=ssrc:2 cname:stream1\r\n" 104 "a=ssrc:2 mslabel:stream1\r\n" 105 "a=ssrc:2 label:videotrack0\r\n"; 106 107// Reference SDP with two MediaStreams with label "stream1" and "stream2. Each 108// MediaStreams have one audio track and one video track. 109// This uses MSID. 110static const char kSdpStringWithStream1And2[] = 111 "v=0\r\n" 112 "o=- 0 0 IN IP4 127.0.0.1\r\n" 113 "s=-\r\n" 114 "t=0 0\r\n" 115 "a=ice-ufrag:e5785931\r\n" 116 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" 117 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" 118 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" 119 "a=msid-semantic: WMS stream1 stream2\r\n" 120 "m=audio 1 RTP/AVPF 103\r\n" 121 "a=mid:audio\r\n" 122 "a=sendrecv\r\n" 123 "a=rtpmap:103 ISAC/16000\r\n" 124 "a=ssrc:1 cname:stream1\r\n" 125 "a=ssrc:1 msid:stream1 audiotrack0\r\n" 126 "a=ssrc:3 cname:stream2\r\n" 127 "a=ssrc:3 msid:stream2 audiotrack1\r\n" 128 "m=video 1 RTP/AVPF 120\r\n" 129 "a=mid:video\r\n" 130 "a=sendrecv\r\n" 131 "a=rtpmap:120 VP8/0\r\n" 132 "a=ssrc:2 cname:stream1\r\n" 133 "a=ssrc:2 msid:stream1 videotrack0\r\n" 134 "a=ssrc:4 cname:stream2\r\n" 135 "a=ssrc:4 msid:stream2 videotrack1\r\n"; 136 137// Reference SDP without MediaStreams. Msid is not supported. 138static const char kSdpStringWithoutStreams[] = 139 "v=0\r\n" 140 "o=- 0 0 IN IP4 127.0.0.1\r\n" 141 "s=-\r\n" 142 "t=0 0\r\n" 143 "a=ice-ufrag:e5785931\r\n" 144 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" 145 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" 146 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" 147 "m=audio 1 RTP/AVPF 103\r\n" 148 "a=mid:audio\r\n" 149 "a=sendrecv\r\n" 150 "a=rtpmap:103 ISAC/16000\r\n" 151 "m=video 1 RTP/AVPF 120\r\n" 152 "a=mid:video\r\n" 153 "a=sendrecv\r\n" 154 "a=rtpmap:120 VP8/90000\r\n"; 155 156// Reference SDP without MediaStreams. Msid is supported. 157static const char kSdpStringWithMsidWithoutStreams[] = 158 "v=0\r\n" 159 "o=- 0 0 IN IP4 127.0.0.1\r\n" 160 "s=-\r\n" 161 "t=0 0\r\n" 162 "a=ice-ufrag:e5785931\r\n" 163 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" 164 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" 165 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" 166 "a=msid-semantic: WMS\r\n" 167 "m=audio 1 RTP/AVPF 103\r\n" 168 "a=mid:audio\r\n" 169 "a=sendrecv\r\n" 170 "a=rtpmap:103 ISAC/16000\r\n" 171 "m=video 1 RTP/AVPF 120\r\n" 172 "a=mid:video\r\n" 173 "a=sendrecv\r\n" 174 "a=rtpmap:120 VP8/90000\r\n"; 175 176// Reference SDP without MediaStreams and audio only. 177static const char kSdpStringWithoutStreamsAudioOnly[] = 178 "v=0\r\n" 179 "o=- 0 0 IN IP4 127.0.0.1\r\n" 180 "s=-\r\n" 181 "t=0 0\r\n" 182 "a=ice-ufrag:e5785931\r\n" 183 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" 184 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" 185 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" 186 "m=audio 1 RTP/AVPF 103\r\n" 187 "a=mid:audio\r\n" 188 "a=sendrecv\r\n" 189 "a=rtpmap:103 ISAC/16000\r\n"; 190 191// Reference SENDONLY SDP without MediaStreams. Msid is not supported. 192static const char kSdpStringSendOnlyWithoutStreams[] = 193 "v=0\r\n" 194 "o=- 0 0 IN IP4 127.0.0.1\r\n" 195 "s=-\r\n" 196 "t=0 0\r\n" 197 "a=ice-ufrag:e5785931\r\n" 198 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" 199 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" 200 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" 201 "m=audio 1 RTP/AVPF 103\r\n" 202 "a=mid:audio\r\n" 203 "a=sendrecv\r\n" 204 "a=sendonly\r\n" 205 "a=rtpmap:103 ISAC/16000\r\n" 206 "m=video 1 RTP/AVPF 120\r\n" 207 "a=mid:video\r\n" 208 "a=sendrecv\r\n" 209 "a=sendonly\r\n" 210 "a=rtpmap:120 VP8/90000\r\n"; 211 212static const char kSdpStringInit[] = 213 "v=0\r\n" 214 "o=- 0 0 IN IP4 127.0.0.1\r\n" 215 "s=-\r\n" 216 "t=0 0\r\n" 217 "a=ice-ufrag:e5785931\r\n" 218 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" 219 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" 220 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" 221 "a=msid-semantic: WMS\r\n"; 222 223static const char kSdpStringAudio[] = 224 "m=audio 1 RTP/AVPF 103\r\n" 225 "a=mid:audio\r\n" 226 "a=sendrecv\r\n" 227 "a=rtpmap:103 ISAC/16000\r\n"; 228 229static const char kSdpStringVideo[] = 230 "m=video 1 RTP/AVPF 120\r\n" 231 "a=mid:video\r\n" 232 "a=sendrecv\r\n" 233 "a=rtpmap:120 VP8/90000\r\n"; 234 235static const char kSdpStringMs1Audio0[] = 236 "a=ssrc:1 cname:stream1\r\n" 237 "a=ssrc:1 msid:stream1 audiotrack0\r\n"; 238 239static const char kSdpStringMs1Video0[] = 240 "a=ssrc:2 cname:stream1\r\n" 241 "a=ssrc:2 msid:stream1 videotrack0\r\n"; 242 243static const char kSdpStringMs1Audio1[] = 244 "a=ssrc:3 cname:stream1\r\n" 245 "a=ssrc:3 msid:stream1 audiotrack1\r\n"; 246 247static const char kSdpStringMs1Video1[] = 248 "a=ssrc:4 cname:stream1\r\n" 249 "a=ssrc:4 msid:stream1 videotrack1\r\n"; 250 251#define MAYBE_SKIP_TEST(feature) \ 252 if (!(feature())) { \ 253 LOG(LS_INFO) << "Feature disabled... skipping"; \ 254 return; \ 255 } 256 257using rtc::scoped_ptr; 258using rtc::scoped_refptr; 259using webrtc::AudioSourceInterface; 260using webrtc::AudioTrack; 261using webrtc::AudioTrackInterface; 262using webrtc::DataBuffer; 263using webrtc::DataChannelInterface; 264using webrtc::FakeConstraints; 265using webrtc::IceCandidateInterface; 266using webrtc::MediaConstraintsInterface; 267using webrtc::MediaStream; 268using webrtc::MediaStreamInterface; 269using webrtc::MediaStreamTrackInterface; 270using webrtc::MockCreateSessionDescriptionObserver; 271using webrtc::MockDataChannelObserver; 272using webrtc::MockSetSessionDescriptionObserver; 273using webrtc::MockStatsObserver; 274using webrtc::PeerConnectionInterface; 275using webrtc::PeerConnectionObserver; 276using webrtc::RtpReceiverInterface; 277using webrtc::RtpSenderInterface; 278using webrtc::SdpParseError; 279using webrtc::SessionDescriptionInterface; 280using webrtc::StreamCollection; 281using webrtc::StreamCollectionInterface; 282using webrtc::VideoSourceInterface; 283using webrtc::VideoTrack; 284using webrtc::VideoTrackInterface; 285 286typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions; 287 288namespace { 289 290// Gets the first ssrc of given content type from the ContentInfo. 291bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) { 292 if (!content_info || !ssrc) { 293 return false; 294 } 295 const cricket::MediaContentDescription* media_desc = 296 static_cast<const cricket::MediaContentDescription*>( 297 content_info->description); 298 if (!media_desc || media_desc->streams().empty()) { 299 return false; 300 } 301 *ssrc = media_desc->streams().begin()->first_ssrc(); 302 return true; 303} 304 305void SetSsrcToZero(std::string* sdp) { 306 const char kSdpSsrcAtribute[] = "a=ssrc:"; 307 const char kSdpSsrcAtributeZero[] = "a=ssrc:0"; 308 size_t ssrc_pos = 0; 309 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) != 310 std::string::npos) { 311 size_t end_ssrc = sdp->find(" ", ssrc_pos); 312 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero); 313 ssrc_pos = end_ssrc; 314 } 315} 316 317// Check if |streams| contains the specified track. 318bool ContainsTrack(const std::vector<cricket::StreamParams>& streams, 319 const std::string& stream_label, 320 const std::string& track_id) { 321 for (const cricket::StreamParams& params : streams) { 322 if (params.sync_label == stream_label && params.id == track_id) { 323 return true; 324 } 325 } 326 return false; 327} 328 329// Check if |senders| contains the specified sender, by id. 330bool ContainsSender( 331 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders, 332 const std::string& id) { 333 for (const auto& sender : senders) { 334 if (sender->id() == id) { 335 return true; 336 } 337 } 338 return false; 339} 340 341// Create a collection of streams. 342// CreateStreamCollection(1) creates a collection that 343// correspond to kSdpStringWithStream1. 344// CreateStreamCollection(2) correspond to kSdpStringWithStream1And2. 345rtc::scoped_refptr<StreamCollection> CreateStreamCollection( 346 int number_of_streams) { 347 rtc::scoped_refptr<StreamCollection> local_collection( 348 StreamCollection::Create()); 349 350 for (int i = 0; i < number_of_streams; ++i) { 351 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream( 352 webrtc::MediaStream::Create(kStreams[i])); 353 354 // Add a local audio track. 355 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track( 356 webrtc::AudioTrack::Create(kAudioTracks[i], nullptr)); 357 stream->AddTrack(audio_track); 358 359 // Add a local video track. 360 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track( 361 webrtc::VideoTrack::Create(kVideoTracks[i], nullptr)); 362 stream->AddTrack(video_track); 363 364 local_collection->AddStream(stream); 365 } 366 return local_collection; 367} 368 369// Check equality of StreamCollections. 370bool CompareStreamCollections(StreamCollectionInterface* s1, 371 StreamCollectionInterface* s2) { 372 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) { 373 return false; 374 } 375 376 for (size_t i = 0; i != s1->count(); ++i) { 377 if (s1->at(i)->label() != s2->at(i)->label()) { 378 return false; 379 } 380 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks(); 381 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks(); 382 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks(); 383 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks(); 384 385 if (audio_tracks1.size() != audio_tracks2.size()) { 386 return false; 387 } 388 for (size_t j = 0; j != audio_tracks1.size(); ++j) { 389 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) { 390 return false; 391 } 392 } 393 if (video_tracks1.size() != video_tracks2.size()) { 394 return false; 395 } 396 for (size_t j = 0; j != video_tracks1.size(); ++j) { 397 if (video_tracks1[j]->id() != video_tracks2[j]->id()) { 398 return false; 399 } 400 } 401 } 402 return true; 403} 404 405class MockPeerConnectionObserver : public PeerConnectionObserver { 406 public: 407 MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {} 408 ~MockPeerConnectionObserver() { 409 } 410 void SetPeerConnectionInterface(PeerConnectionInterface* pc) { 411 pc_ = pc; 412 if (pc) { 413 state_ = pc_->signaling_state(); 414 } 415 } 416 virtual void OnSignalingChange( 417 PeerConnectionInterface::SignalingState new_state) { 418 EXPECT_EQ(pc_->signaling_state(), new_state); 419 state_ = new_state; 420 } 421 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange. 422 virtual void OnStateChange(StateType state_changed) { 423 if (pc_.get() == NULL) 424 return; 425 switch (state_changed) { 426 case kSignalingState: 427 // OnSignalingChange and OnStateChange(kSignalingState) should always 428 // be called approximately simultaneously. To ease testing, we require 429 // that they always be called in that order. This check verifies 430 // that OnSignalingChange has just been called. 431 EXPECT_EQ(pc_->signaling_state(), state_); 432 break; 433 case kIceState: 434 ADD_FAILURE(); 435 break; 436 default: 437 ADD_FAILURE(); 438 break; 439 } 440 } 441 442 MediaStreamInterface* RemoteStream(const std::string& label) { 443 return remote_streams_->find(label); 444 } 445 StreamCollectionInterface* remote_streams() const { return remote_streams_; } 446 virtual void OnAddStream(MediaStreamInterface* stream) { 447 last_added_stream_ = stream; 448 remote_streams_->AddStream(stream); 449 } 450 virtual void OnRemoveStream(MediaStreamInterface* stream) { 451 last_removed_stream_ = stream; 452 remote_streams_->RemoveStream(stream); 453 } 454 virtual void OnRenegotiationNeeded() { 455 renegotiation_needed_ = true; 456 } 457 virtual void OnDataChannel(DataChannelInterface* data_channel) { 458 last_datachannel_ = data_channel; 459 } 460 461 virtual void OnIceConnectionChange( 462 PeerConnectionInterface::IceConnectionState new_state) { 463 EXPECT_EQ(pc_->ice_connection_state(), new_state); 464 } 465 virtual void OnIceGatheringChange( 466 PeerConnectionInterface::IceGatheringState new_state) { 467 EXPECT_EQ(pc_->ice_gathering_state(), new_state); 468 } 469 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) { 470 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, 471 pc_->ice_gathering_state()); 472 473 std::string sdp; 474 EXPECT_TRUE(candidate->ToString(&sdp)); 475 EXPECT_LT(0u, sdp.size()); 476 last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(), 477 candidate->sdp_mline_index(), sdp, NULL)); 478 EXPECT_TRUE(last_candidate_.get() != NULL); 479 } 480 // TODO(bemasc): Remove this once callers transition to OnSignalingChange. 481 virtual void OnIceComplete() { 482 ice_complete_ = true; 483 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should 484 // be called approximately simultaneously. For ease of testing, this 485 // check additionally requires that they be called in the above order. 486 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, 487 pc_->ice_gathering_state()); 488 } 489 490 // Returns the label of the last added stream. 491 // Empty string if no stream have been added. 492 std::string GetLastAddedStreamLabel() { 493 if (last_added_stream_.get()) 494 return last_added_stream_->label(); 495 return ""; 496 } 497 std::string GetLastRemovedStreamLabel() { 498 if (last_removed_stream_.get()) 499 return last_removed_stream_->label(); 500 return ""; 501 } 502 503 scoped_refptr<PeerConnectionInterface> pc_; 504 PeerConnectionInterface::SignalingState state_; 505 scoped_ptr<IceCandidateInterface> last_candidate_; 506 scoped_refptr<DataChannelInterface> last_datachannel_; 507 rtc::scoped_refptr<StreamCollection> remote_streams_; 508 bool renegotiation_needed_ = false; 509 bool ice_complete_ = false; 510 511 private: 512 scoped_refptr<MediaStreamInterface> last_added_stream_; 513 scoped_refptr<MediaStreamInterface> last_removed_stream_; 514}; 515 516} // namespace 517 518class PeerConnectionInterfaceTest : public testing::Test { 519 protected: 520 PeerConnectionInterfaceTest() { 521#ifdef WEBRTC_ANDROID 522 webrtc::InitializeAndroidObjects(); 523#endif 524 } 525 526 virtual void SetUp() { 527 pc_factory_ = webrtc::CreatePeerConnectionFactory( 528 rtc::Thread::Current(), rtc::Thread::Current(), NULL, NULL, 529 NULL); 530 ASSERT_TRUE(pc_factory_.get() != NULL); 531 } 532 533 void CreatePeerConnection() { 534 CreatePeerConnection("", "", NULL); 535 } 536 537 void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) { 538 CreatePeerConnection("", "", constraints); 539 } 540 541 void CreatePeerConnection(const std::string& uri, 542 const std::string& password, 543 webrtc::MediaConstraintsInterface* constraints) { 544 PeerConnectionInterface::RTCConfiguration config; 545 PeerConnectionInterface::IceServer server; 546 if (!uri.empty()) { 547 server.uri = uri; 548 server.password = password; 549 config.servers.push_back(server); 550 } 551 552 rtc::scoped_ptr<cricket::FakePortAllocator> port_allocator( 553 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr)); 554 port_allocator_ = port_allocator.get(); 555 556 // DTLS does not work in a loopback call, so is disabled for most of the 557 // tests in this file. We only create a FakeIdentityService if the test 558 // explicitly sets the constraint. 559 FakeConstraints default_constraints; 560 if (!constraints) { 561 constraints = &default_constraints; 562 563 default_constraints.AddMandatory( 564 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false); 565 } 566 567 scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store; 568 bool dtls; 569 if (FindConstraint(constraints, 570 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 571 &dtls, 572 nullptr) && dtls) { 573 dtls_identity_store.reset(new FakeDtlsIdentityStore()); 574 } 575 pc_ = pc_factory_->CreatePeerConnection( 576 config, constraints, std::move(port_allocator), 577 std::move(dtls_identity_store), &observer_); 578 ASSERT_TRUE(pc_.get() != NULL); 579 observer_.SetPeerConnectionInterface(pc_.get()); 580 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 581 } 582 583 void CreatePeerConnectionExpectFail(const std::string& uri) { 584 PeerConnectionInterface::RTCConfiguration config; 585 PeerConnectionInterface::IceServer server; 586 server.uri = uri; 587 config.servers.push_back(server); 588 589 scoped_refptr<PeerConnectionInterface> pc; 590 pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr, nullptr, 591 &observer_); 592 EXPECT_EQ(nullptr, pc); 593 } 594 595 void CreatePeerConnectionWithDifferentConfigurations() { 596 CreatePeerConnection(kStunAddressOnly, "", NULL); 597 EXPECT_EQ(1u, port_allocator_->stun_servers().size()); 598 EXPECT_EQ(0u, port_allocator_->turn_servers().size()); 599 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname()); 600 EXPECT_EQ(kDefaultStunPort, 601 port_allocator_->stun_servers().begin()->port()); 602 603 CreatePeerConnectionExpectFail(kStunInvalidPort); 604 CreatePeerConnectionExpectFail(kStunAddressPortAndMore1); 605 CreatePeerConnectionExpectFail(kStunAddressPortAndMore2); 606 607 CreatePeerConnection(kTurnIceServerUri, kTurnPassword, NULL); 608 EXPECT_EQ(0u, port_allocator_->stun_servers().size()); 609 EXPECT_EQ(1u, port_allocator_->turn_servers().size()); 610 EXPECT_EQ(kTurnUsername, 611 port_allocator_->turn_servers()[0].credentials.username); 612 EXPECT_EQ(kTurnPassword, 613 port_allocator_->turn_servers()[0].credentials.password); 614 EXPECT_EQ(kTurnHostname, 615 port_allocator_->turn_servers()[0].ports[0].address.hostname()); 616 } 617 618 void ReleasePeerConnection() { 619 pc_ = NULL; 620 observer_.SetPeerConnectionInterface(NULL); 621 } 622 623 void AddVideoStream(const std::string& label) { 624 // Create a local stream. 625 scoped_refptr<MediaStreamInterface> stream( 626 pc_factory_->CreateLocalMediaStream(label)); 627 scoped_refptr<VideoSourceInterface> video_source( 628 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL)); 629 scoped_refptr<VideoTrackInterface> video_track( 630 pc_factory_->CreateVideoTrack(label + "v0", video_source)); 631 stream->AddTrack(video_track.get()); 632 EXPECT_TRUE(pc_->AddStream(stream)); 633 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 634 observer_.renegotiation_needed_ = false; 635 } 636 637 void AddVoiceStream(const std::string& label) { 638 // Create a local stream. 639 scoped_refptr<MediaStreamInterface> stream( 640 pc_factory_->CreateLocalMediaStream(label)); 641 scoped_refptr<AudioTrackInterface> audio_track( 642 pc_factory_->CreateAudioTrack(label + "a0", NULL)); 643 stream->AddTrack(audio_track.get()); 644 EXPECT_TRUE(pc_->AddStream(stream)); 645 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 646 observer_.renegotiation_needed_ = false; 647 } 648 649 void AddAudioVideoStream(const std::string& stream_label, 650 const std::string& audio_track_label, 651 const std::string& video_track_label) { 652 // Create a local stream. 653 scoped_refptr<MediaStreamInterface> stream( 654 pc_factory_->CreateLocalMediaStream(stream_label)); 655 scoped_refptr<AudioTrackInterface> audio_track( 656 pc_factory_->CreateAudioTrack( 657 audio_track_label, static_cast<AudioSourceInterface*>(NULL))); 658 stream->AddTrack(audio_track.get()); 659 scoped_refptr<VideoTrackInterface> video_track( 660 pc_factory_->CreateVideoTrack(video_track_label, NULL)); 661 stream->AddTrack(video_track.get()); 662 EXPECT_TRUE(pc_->AddStream(stream)); 663 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 664 observer_.renegotiation_needed_ = false; 665 } 666 667 bool DoCreateOfferAnswer(SessionDescriptionInterface** desc, 668 bool offer, 669 MediaConstraintsInterface* constraints) { 670 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> 671 observer(new rtc::RefCountedObject< 672 MockCreateSessionDescriptionObserver>()); 673 if (offer) { 674 pc_->CreateOffer(observer, constraints); 675 } else { 676 pc_->CreateAnswer(observer, constraints); 677 } 678 EXPECT_EQ_WAIT(true, observer->called(), kTimeout); 679 *desc = observer->release_desc(); 680 return observer->result(); 681 } 682 683 bool DoCreateOffer(SessionDescriptionInterface** desc, 684 MediaConstraintsInterface* constraints) { 685 return DoCreateOfferAnswer(desc, true, constraints); 686 } 687 688 bool DoCreateAnswer(SessionDescriptionInterface** desc, 689 MediaConstraintsInterface* constraints) { 690 return DoCreateOfferAnswer(desc, false, constraints); 691 } 692 693 bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) { 694 rtc::scoped_refptr<MockSetSessionDescriptionObserver> 695 observer(new rtc::RefCountedObject< 696 MockSetSessionDescriptionObserver>()); 697 if (local) { 698 pc_->SetLocalDescription(observer, desc); 699 } else { 700 pc_->SetRemoteDescription(observer, desc); 701 } 702 EXPECT_EQ_WAIT(true, observer->called(), kTimeout); 703 return observer->result(); 704 } 705 706 bool DoSetLocalDescription(SessionDescriptionInterface* desc) { 707 return DoSetSessionDescription(desc, true); 708 } 709 710 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) { 711 return DoSetSessionDescription(desc, false); 712 } 713 714 // Calls PeerConnection::GetStats and check the return value. 715 // It does not verify the values in the StatReports since a RTCP packet might 716 // be required. 717 bool DoGetStats(MediaStreamTrackInterface* track) { 718 rtc::scoped_refptr<MockStatsObserver> observer( 719 new rtc::RefCountedObject<MockStatsObserver>()); 720 if (!pc_->GetStats( 721 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)) 722 return false; 723 EXPECT_TRUE_WAIT(observer->called(), kTimeout); 724 return observer->called(); 725 } 726 727 void InitiateCall() { 728 CreatePeerConnection(); 729 // Create a local stream with audio&video tracks. 730 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 731 CreateOfferReceiveAnswer(); 732 } 733 734 // Verify that RTP Header extensions has been negotiated for audio and video. 735 void VerifyRemoteRtpHeaderExtensions() { 736 const cricket::MediaContentDescription* desc = 737 cricket::GetFirstAudioContentDescription( 738 pc_->remote_description()->description()); 739 ASSERT_TRUE(desc != NULL); 740 EXPECT_GT(desc->rtp_header_extensions().size(), 0u); 741 742 desc = cricket::GetFirstVideoContentDescription( 743 pc_->remote_description()->description()); 744 ASSERT_TRUE(desc != NULL); 745 EXPECT_GT(desc->rtp_header_extensions().size(), 0u); 746 } 747 748 void CreateOfferAsRemoteDescription() { 749 rtc::scoped_ptr<SessionDescriptionInterface> offer; 750 ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); 751 std::string sdp; 752 EXPECT_TRUE(offer->ToString(&sdp)); 753 SessionDescriptionInterface* remote_offer = 754 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 755 sdp, NULL); 756 EXPECT_TRUE(DoSetRemoteDescription(remote_offer)); 757 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_); 758 } 759 760 void CreateAndSetRemoteOffer(const std::string& sdp) { 761 SessionDescriptionInterface* remote_offer = 762 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 763 sdp, nullptr); 764 EXPECT_TRUE(DoSetRemoteDescription(remote_offer)); 765 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_); 766 } 767 768 void CreateAnswerAsLocalDescription() { 769 scoped_ptr<SessionDescriptionInterface> answer; 770 ASSERT_TRUE(DoCreateAnswer(answer.use(), nullptr)); 771 772 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an 773 // audio codec change, even if the parameter has nothing to do with 774 // receiving. Not all parameters are serialized to SDP. 775 // Since CreatePrAnswerAsLocalDescription serialize/deserialize 776 // the SessionDescription, it is necessary to do that here to in order to 777 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. 778 // https://code.google.com/p/webrtc/issues/detail?id=1356 779 std::string sdp; 780 EXPECT_TRUE(answer->ToString(&sdp)); 781 SessionDescriptionInterface* new_answer = 782 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, 783 sdp, NULL); 784 EXPECT_TRUE(DoSetLocalDescription(new_answer)); 785 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 786 } 787 788 void CreatePrAnswerAsLocalDescription() { 789 scoped_ptr<SessionDescriptionInterface> answer; 790 ASSERT_TRUE(DoCreateAnswer(answer.use(), nullptr)); 791 792 std::string sdp; 793 EXPECT_TRUE(answer->ToString(&sdp)); 794 SessionDescriptionInterface* pr_answer = 795 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer, 796 sdp, NULL); 797 EXPECT_TRUE(DoSetLocalDescription(pr_answer)); 798 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_); 799 } 800 801 void CreateOfferReceiveAnswer() { 802 CreateOfferAsLocalDescription(); 803 std::string sdp; 804 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 805 CreateAnswerAsRemoteDescription(sdp); 806 } 807 808 void CreateOfferAsLocalDescription() { 809 rtc::scoped_ptr<SessionDescriptionInterface> offer; 810 ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); 811 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an 812 // audio codec change, even if the parameter has nothing to do with 813 // receiving. Not all parameters are serialized to SDP. 814 // Since CreatePrAnswerAsLocalDescription serialize/deserialize 815 // the SessionDescription, it is necessary to do that here to in order to 816 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. 817 // https://code.google.com/p/webrtc/issues/detail?id=1356 818 std::string sdp; 819 EXPECT_TRUE(offer->ToString(&sdp)); 820 SessionDescriptionInterface* new_offer = 821 webrtc::CreateSessionDescription( 822 SessionDescriptionInterface::kOffer, 823 sdp, NULL); 824 825 EXPECT_TRUE(DoSetLocalDescription(new_offer)); 826 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_); 827 // Wait for the ice_complete message, so that SDP will have candidates. 828 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); 829 } 830 831 void CreateAnswerAsRemoteDescription(const std::string& sdp) { 832 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( 833 SessionDescriptionInterface::kAnswer); 834 EXPECT_TRUE(answer->Initialize(sdp, NULL)); 835 EXPECT_TRUE(DoSetRemoteDescription(answer)); 836 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 837 } 838 839 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) { 840 webrtc::JsepSessionDescription* pr_answer = 841 new webrtc::JsepSessionDescription( 842 SessionDescriptionInterface::kPrAnswer); 843 EXPECT_TRUE(pr_answer->Initialize(sdp, NULL)); 844 EXPECT_TRUE(DoSetRemoteDescription(pr_answer)); 845 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_); 846 webrtc::JsepSessionDescription* answer = 847 new webrtc::JsepSessionDescription( 848 SessionDescriptionInterface::kAnswer); 849 EXPECT_TRUE(answer->Initialize(sdp, NULL)); 850 EXPECT_TRUE(DoSetRemoteDescription(answer)); 851 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 852 } 853 854 // Help function used for waiting until a the last signaled remote stream has 855 // the same label as |stream_label|. In a few of the tests in this file we 856 // answer with the same session description as we offer and thus we can 857 // check if OnAddStream have been called with the same stream as we offer to 858 // send. 859 void WaitAndVerifyOnAddStream(const std::string& stream_label) { 860 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout); 861 } 862 863 // Creates an offer and applies it as a local session description. 864 // Creates an answer with the same SDP an the offer but removes all lines 865 // that start with a:ssrc" 866 void CreateOfferReceiveAnswerWithoutSsrc() { 867 CreateOfferAsLocalDescription(); 868 std::string sdp; 869 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 870 SetSsrcToZero(&sdp); 871 CreateAnswerAsRemoteDescription(sdp); 872 } 873 874 // This function creates a MediaStream with label kStreams[0] and 875 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the 876 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface 877 // is returned in |desc| and the MediaStream is stored in 878 // |reference_collection_| 879 void CreateSessionDescriptionAndReference( 880 size_t number_of_audio_tracks, 881 size_t number_of_video_tracks, 882 SessionDescriptionInterface** desc) { 883 ASSERT_TRUE(desc != nullptr); 884 ASSERT_LE(number_of_audio_tracks, 2u); 885 ASSERT_LE(number_of_video_tracks, 2u); 886 887 reference_collection_ = StreamCollection::Create(); 888 std::string sdp_ms1 = std::string(kSdpStringInit); 889 890 std::string mediastream_label = kStreams[0]; 891 892 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream( 893 webrtc::MediaStream::Create(mediastream_label)); 894 reference_collection_->AddStream(stream); 895 896 if (number_of_audio_tracks > 0) { 897 sdp_ms1 += std::string(kSdpStringAudio); 898 sdp_ms1 += std::string(kSdpStringMs1Audio0); 899 AddAudioTrack(kAudioTracks[0], stream); 900 } 901 if (number_of_audio_tracks > 1) { 902 sdp_ms1 += kSdpStringMs1Audio1; 903 AddAudioTrack(kAudioTracks[1], stream); 904 } 905 906 if (number_of_video_tracks > 0) { 907 sdp_ms1 += std::string(kSdpStringVideo); 908 sdp_ms1 += std::string(kSdpStringMs1Video0); 909 AddVideoTrack(kVideoTracks[0], stream); 910 } 911 if (number_of_video_tracks > 1) { 912 sdp_ms1 += kSdpStringMs1Video1; 913 AddVideoTrack(kVideoTracks[1], stream); 914 } 915 916 *desc = webrtc::CreateSessionDescription( 917 SessionDescriptionInterface::kOffer, sdp_ms1, nullptr); 918 } 919 920 void AddAudioTrack(const std::string& track_id, 921 MediaStreamInterface* stream) { 922 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track( 923 webrtc::AudioTrack::Create(track_id, nullptr)); 924 ASSERT_TRUE(stream->AddTrack(audio_track)); 925 } 926 927 void AddVideoTrack(const std::string& track_id, 928 MediaStreamInterface* stream) { 929 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track( 930 webrtc::VideoTrack::Create(track_id, nullptr)); 931 ASSERT_TRUE(stream->AddTrack(video_track)); 932 } 933 934 cricket::FakePortAllocator* port_allocator_ = nullptr; 935 scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; 936 scoped_refptr<PeerConnectionInterface> pc_; 937 MockPeerConnectionObserver observer_; 938 rtc::scoped_refptr<StreamCollection> reference_collection_; 939}; 940 941TEST_F(PeerConnectionInterfaceTest, 942 CreatePeerConnectionWithDifferentConfigurations) { 943 CreatePeerConnectionWithDifferentConfigurations(); 944} 945 946TEST_F(PeerConnectionInterfaceTest, AddStreams) { 947 CreatePeerConnection(); 948 AddVideoStream(kStreamLabel1); 949 AddVoiceStream(kStreamLabel2); 950 ASSERT_EQ(2u, pc_->local_streams()->count()); 951 952 // Test we can add multiple local streams to one peerconnection. 953 scoped_refptr<MediaStreamInterface> stream( 954 pc_factory_->CreateLocalMediaStream(kStreamLabel3)); 955 scoped_refptr<AudioTrackInterface> audio_track( 956 pc_factory_->CreateAudioTrack( 957 kStreamLabel3, static_cast<AudioSourceInterface*>(NULL))); 958 stream->AddTrack(audio_track.get()); 959 EXPECT_TRUE(pc_->AddStream(stream)); 960 EXPECT_EQ(3u, pc_->local_streams()->count()); 961 962 // Remove the third stream. 963 pc_->RemoveStream(pc_->local_streams()->at(2)); 964 EXPECT_EQ(2u, pc_->local_streams()->count()); 965 966 // Remove the second stream. 967 pc_->RemoveStream(pc_->local_streams()->at(1)); 968 EXPECT_EQ(1u, pc_->local_streams()->count()); 969 970 // Remove the first stream. 971 pc_->RemoveStream(pc_->local_streams()->at(0)); 972 EXPECT_EQ(0u, pc_->local_streams()->count()); 973} 974 975// Test that the created offer includes streams we added. 976TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) { 977 CreatePeerConnection(); 978 AddAudioVideoStream(kStreamLabel1, "audio_track", "video_track"); 979 scoped_ptr<SessionDescriptionInterface> offer; 980 ASSERT_TRUE(DoCreateOffer(offer.accept(), nullptr)); 981 982 const cricket::ContentInfo* audio_content = 983 cricket::GetFirstAudioContent(offer->description()); 984 const cricket::AudioContentDescription* audio_desc = 985 static_cast<const cricket::AudioContentDescription*>( 986 audio_content->description); 987 EXPECT_TRUE( 988 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track")); 989 990 const cricket::ContentInfo* video_content = 991 cricket::GetFirstVideoContent(offer->description()); 992 const cricket::VideoContentDescription* video_desc = 993 static_cast<const cricket::VideoContentDescription*>( 994 video_content->description); 995 EXPECT_TRUE( 996 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track")); 997 998 // Add another stream and ensure the offer includes both the old and new 999 // streams. 1000 AddAudioVideoStream(kStreamLabel2, "audio_track2", "video_track2"); 1001 ASSERT_TRUE(DoCreateOffer(offer.accept(), nullptr)); 1002 1003 audio_content = cricket::GetFirstAudioContent(offer->description()); 1004 audio_desc = static_cast<const cricket::AudioContentDescription*>( 1005 audio_content->description); 1006 EXPECT_TRUE( 1007 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track")); 1008 EXPECT_TRUE( 1009 ContainsTrack(audio_desc->streams(), kStreamLabel2, "audio_track2")); 1010 1011 video_content = cricket::GetFirstVideoContent(offer->description()); 1012 video_desc = static_cast<const cricket::VideoContentDescription*>( 1013 video_content->description); 1014 EXPECT_TRUE( 1015 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track")); 1016 EXPECT_TRUE( 1017 ContainsTrack(video_desc->streams(), kStreamLabel2, "video_track2")); 1018} 1019 1020TEST_F(PeerConnectionInterfaceTest, RemoveStream) { 1021 CreatePeerConnection(); 1022 AddVideoStream(kStreamLabel1); 1023 ASSERT_EQ(1u, pc_->local_streams()->count()); 1024 pc_->RemoveStream(pc_->local_streams()->at(0)); 1025 EXPECT_EQ(0u, pc_->local_streams()->count()); 1026} 1027 1028TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) { 1029 InitiateCall(); 1030 WaitAndVerifyOnAddStream(kStreamLabel1); 1031 VerifyRemoteRtpHeaderExtensions(); 1032} 1033 1034TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) { 1035 CreatePeerConnection(); 1036 AddVideoStream(kStreamLabel1); 1037 CreateOfferAsLocalDescription(); 1038 std::string offer; 1039 EXPECT_TRUE(pc_->local_description()->ToString(&offer)); 1040 CreatePrAnswerAndAnswerAsRemoteDescription(offer); 1041 WaitAndVerifyOnAddStream(kStreamLabel1); 1042} 1043 1044TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) { 1045 CreatePeerConnection(); 1046 AddVideoStream(kStreamLabel1); 1047 1048 CreateOfferAsRemoteDescription(); 1049 CreateAnswerAsLocalDescription(); 1050 1051 WaitAndVerifyOnAddStream(kStreamLabel1); 1052} 1053 1054TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) { 1055 CreatePeerConnection(); 1056 AddVideoStream(kStreamLabel1); 1057 1058 CreateOfferAsRemoteDescription(); 1059 CreatePrAnswerAsLocalDescription(); 1060 CreateAnswerAsLocalDescription(); 1061 1062 WaitAndVerifyOnAddStream(kStreamLabel1); 1063} 1064 1065TEST_F(PeerConnectionInterfaceTest, Renegotiate) { 1066 InitiateCall(); 1067 ASSERT_EQ(1u, pc_->remote_streams()->count()); 1068 pc_->RemoveStream(pc_->local_streams()->at(0)); 1069 CreateOfferReceiveAnswer(); 1070 EXPECT_EQ(0u, pc_->remote_streams()->count()); 1071 AddVideoStream(kStreamLabel1); 1072 CreateOfferReceiveAnswer(); 1073} 1074 1075// Tests that after negotiating an audio only call, the respondent can perform a 1076// renegotiation that removes the audio stream. 1077TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) { 1078 CreatePeerConnection(); 1079 AddVoiceStream(kStreamLabel1); 1080 CreateOfferAsRemoteDescription(); 1081 CreateAnswerAsLocalDescription(); 1082 1083 ASSERT_EQ(1u, pc_->remote_streams()->count()); 1084 pc_->RemoveStream(pc_->local_streams()->at(0)); 1085 CreateOfferReceiveAnswer(); 1086 EXPECT_EQ(0u, pc_->remote_streams()->count()); 1087} 1088 1089// Test that candidates are generated and that we can parse our own candidates. 1090TEST_F(PeerConnectionInterfaceTest, IceCandidates) { 1091 CreatePeerConnection(); 1092 1093 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get())); 1094 // SetRemoteDescription takes ownership of offer. 1095 SessionDescriptionInterface* offer = NULL; 1096 AddVideoStream(kStreamLabel1); 1097 EXPECT_TRUE(DoCreateOffer(&offer, nullptr)); 1098 EXPECT_TRUE(DoSetRemoteDescription(offer)); 1099 1100 // SetLocalDescription takes ownership of answer. 1101 SessionDescriptionInterface* answer = NULL; 1102 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr)); 1103 EXPECT_TRUE(DoSetLocalDescription(answer)); 1104 1105 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout); 1106 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); 1107 1108 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get())); 1109} 1110 1111// Test that CreateOffer and CreateAnswer will fail if the track labels are 1112// not unique. 1113TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) { 1114 CreatePeerConnection(); 1115 // Create a regular offer for the CreateAnswer test later. 1116 SessionDescriptionInterface* offer = NULL; 1117 EXPECT_TRUE(DoCreateOffer(&offer, nullptr)); 1118 EXPECT_TRUE(offer != NULL); 1119 delete offer; 1120 offer = NULL; 1121 1122 // Create a local stream with audio&video tracks having same label. 1123 AddAudioVideoStream(kStreamLabel1, "track_label", "track_label"); 1124 1125 // Test CreateOffer 1126 EXPECT_FALSE(DoCreateOffer(&offer, nullptr)); 1127 1128 // Test CreateAnswer 1129 SessionDescriptionInterface* answer = NULL; 1130 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr)); 1131} 1132 1133// Test that we will get different SSRCs for each tracks in the offer and answer 1134// we created. 1135TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) { 1136 CreatePeerConnection(); 1137 // Create a local stream with audio&video tracks having different labels. 1138 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1139 1140 // Test CreateOffer 1141 scoped_ptr<SessionDescriptionInterface> offer; 1142 ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); 1143 int audio_ssrc = 0; 1144 int video_ssrc = 0; 1145 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()), 1146 &audio_ssrc)); 1147 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(offer->description()), 1148 &video_ssrc)); 1149 EXPECT_NE(audio_ssrc, video_ssrc); 1150 1151 // Test CreateAnswer 1152 EXPECT_TRUE(DoSetRemoteDescription(offer.release())); 1153 scoped_ptr<SessionDescriptionInterface> answer; 1154 ASSERT_TRUE(DoCreateAnswer(answer.use(), nullptr)); 1155 audio_ssrc = 0; 1156 video_ssrc = 0; 1157 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()), 1158 &audio_ssrc)); 1159 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(answer->description()), 1160 &video_ssrc)); 1161 EXPECT_NE(audio_ssrc, video_ssrc); 1162} 1163 1164// Test that it's possible to call AddTrack on a MediaStream after adding 1165// the stream to a PeerConnection. 1166// TODO(deadbeef): Remove this test once this behavior is no longer supported. 1167TEST_F(PeerConnectionInterfaceTest, AddTrackAfterAddStream) { 1168 CreatePeerConnection(); 1169 // Create audio stream and add to PeerConnection. 1170 AddVoiceStream(kStreamLabel1); 1171 MediaStreamInterface* stream = pc_->local_streams()->at(0); 1172 1173 // Add video track to the audio-only stream. 1174 scoped_refptr<VideoTrackInterface> video_track( 1175 pc_factory_->CreateVideoTrack("video_label", nullptr)); 1176 stream->AddTrack(video_track.get()); 1177 1178 scoped_ptr<SessionDescriptionInterface> offer; 1179 ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); 1180 1181 const cricket::MediaContentDescription* video_desc = 1182 cricket::GetFirstVideoContentDescription(offer->description()); 1183 EXPECT_TRUE(video_desc != nullptr); 1184} 1185 1186// Test that it's possible to call RemoveTrack on a MediaStream after adding 1187// the stream to a PeerConnection. 1188// TODO(deadbeef): Remove this test once this behavior is no longer supported. 1189TEST_F(PeerConnectionInterfaceTest, RemoveTrackAfterAddStream) { 1190 CreatePeerConnection(); 1191 // Create audio/video stream and add to PeerConnection. 1192 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1193 MediaStreamInterface* stream = pc_->local_streams()->at(0); 1194 1195 // Remove the video track. 1196 stream->RemoveTrack(stream->GetVideoTracks()[0]); 1197 1198 scoped_ptr<SessionDescriptionInterface> offer; 1199 ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); 1200 1201 const cricket::MediaContentDescription* video_desc = 1202 cricket::GetFirstVideoContentDescription(offer->description()); 1203 EXPECT_TRUE(video_desc == nullptr); 1204} 1205 1206// Test creating a sender with a stream ID, and ensure the ID is populated 1207// in the offer. 1208TEST_F(PeerConnectionInterfaceTest, CreateSenderWithStream) { 1209 CreatePeerConnection(); 1210 pc_->CreateSender("video", kStreamLabel1); 1211 1212 scoped_ptr<SessionDescriptionInterface> offer; 1213 ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr)); 1214 1215 const cricket::MediaContentDescription* video_desc = 1216 cricket::GetFirstVideoContentDescription(offer->description()); 1217 ASSERT_TRUE(video_desc != nullptr); 1218 ASSERT_EQ(1u, video_desc->streams().size()); 1219 EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label); 1220} 1221 1222// Test that we can specify a certain track that we want statistics about. 1223TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) { 1224 InitiateCall(); 1225 ASSERT_LT(0u, pc_->remote_streams()->count()); 1226 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size()); 1227 scoped_refptr<MediaStreamTrackInterface> remote_audio = 1228 pc_->remote_streams()->at(0)->GetAudioTracks()[0]; 1229 EXPECT_TRUE(DoGetStats(remote_audio)); 1230 1231 // Remove the stream. Since we are sending to our selves the local 1232 // and the remote stream is the same. 1233 pc_->RemoveStream(pc_->local_streams()->at(0)); 1234 // Do a re-negotiation. 1235 CreateOfferReceiveAnswer(); 1236 1237 ASSERT_EQ(0u, pc_->remote_streams()->count()); 1238 1239 // Test that we still can get statistics for the old track. Even if it is not 1240 // sent any longer. 1241 EXPECT_TRUE(DoGetStats(remote_audio)); 1242} 1243 1244// Test that we can get stats on a video track. 1245TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) { 1246 InitiateCall(); 1247 ASSERT_LT(0u, pc_->remote_streams()->count()); 1248 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size()); 1249 scoped_refptr<MediaStreamTrackInterface> remote_video = 1250 pc_->remote_streams()->at(0)->GetVideoTracks()[0]; 1251 EXPECT_TRUE(DoGetStats(remote_video)); 1252} 1253 1254// Test that we don't get statistics for an invalid track. 1255// TODO(tommi): Fix this test. DoGetStats will return true 1256// for the unknown track (since GetStats is async), but no 1257// data is returned for the track. 1258TEST_F(PeerConnectionInterfaceTest, DISABLED_GetStatsForInvalidTrack) { 1259 InitiateCall(); 1260 scoped_refptr<AudioTrackInterface> unknown_audio_track( 1261 pc_factory_->CreateAudioTrack("unknown track", NULL)); 1262 EXPECT_FALSE(DoGetStats(unknown_audio_track)); 1263} 1264 1265// This test setup two RTP data channels in loop back. 1266TEST_F(PeerConnectionInterfaceTest, TestDataChannel) { 1267 FakeConstraints constraints; 1268 constraints.SetAllowRtpDataChannels(); 1269 CreatePeerConnection(&constraints); 1270 scoped_refptr<DataChannelInterface> data1 = 1271 pc_->CreateDataChannel("test1", NULL); 1272 scoped_refptr<DataChannelInterface> data2 = 1273 pc_->CreateDataChannel("test2", NULL); 1274 ASSERT_TRUE(data1 != NULL); 1275 rtc::scoped_ptr<MockDataChannelObserver> observer1( 1276 new MockDataChannelObserver(data1)); 1277 rtc::scoped_ptr<MockDataChannelObserver> observer2( 1278 new MockDataChannelObserver(data2)); 1279 1280 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); 1281 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); 1282 std::string data_to_send1 = "testing testing"; 1283 std::string data_to_send2 = "testing something else"; 1284 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1))); 1285 1286 CreateOfferReceiveAnswer(); 1287 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 1288 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 1289 1290 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); 1291 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); 1292 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1))); 1293 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2))); 1294 1295 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout); 1296 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); 1297 1298 data1->Close(); 1299 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); 1300 CreateOfferReceiveAnswer(); 1301 EXPECT_FALSE(observer1->IsOpen()); 1302 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 1303 EXPECT_TRUE(observer2->IsOpen()); 1304 1305 data_to_send2 = "testing something else again"; 1306 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2))); 1307 1308 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); 1309} 1310 1311// This test verifies that sendnig binary data over RTP data channels should 1312// fail. 1313TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) { 1314 FakeConstraints constraints; 1315 constraints.SetAllowRtpDataChannels(); 1316 CreatePeerConnection(&constraints); 1317 scoped_refptr<DataChannelInterface> data1 = 1318 pc_->CreateDataChannel("test1", NULL); 1319 scoped_refptr<DataChannelInterface> data2 = 1320 pc_->CreateDataChannel("test2", NULL); 1321 ASSERT_TRUE(data1 != NULL); 1322 rtc::scoped_ptr<MockDataChannelObserver> observer1( 1323 new MockDataChannelObserver(data1)); 1324 rtc::scoped_ptr<MockDataChannelObserver> observer2( 1325 new MockDataChannelObserver(data2)); 1326 1327 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); 1328 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); 1329 1330 CreateOfferReceiveAnswer(); 1331 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 1332 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 1333 1334 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); 1335 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); 1336 1337 rtc::Buffer buffer("test", 4); 1338 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true))); 1339} 1340 1341// This test setup a RTP data channels in loop back and test that a channel is 1342// opened even if the remote end answer with a zero SSRC. 1343TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) { 1344 FakeConstraints constraints; 1345 constraints.SetAllowRtpDataChannels(); 1346 CreatePeerConnection(&constraints); 1347 scoped_refptr<DataChannelInterface> data1 = 1348 pc_->CreateDataChannel("test1", NULL); 1349 rtc::scoped_ptr<MockDataChannelObserver> observer1( 1350 new MockDataChannelObserver(data1)); 1351 1352 CreateOfferReceiveAnswerWithoutSsrc(); 1353 1354 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 1355 1356 data1->Close(); 1357 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); 1358 CreateOfferReceiveAnswerWithoutSsrc(); 1359 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 1360 EXPECT_FALSE(observer1->IsOpen()); 1361} 1362 1363// This test that if a data channel is added in an answer a receive only channel 1364// channel is created. 1365TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) { 1366 FakeConstraints constraints; 1367 constraints.SetAllowRtpDataChannels(); 1368 CreatePeerConnection(&constraints); 1369 1370 std::string offer_label = "offer_channel"; 1371 scoped_refptr<DataChannelInterface> offer_channel = 1372 pc_->CreateDataChannel(offer_label, NULL); 1373 1374 CreateOfferAsLocalDescription(); 1375 1376 // Replace the data channel label in the offer and apply it as an answer. 1377 std::string receive_label = "answer_channel"; 1378 std::string sdp; 1379 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 1380 rtc::replace_substrs(offer_label.c_str(), offer_label.length(), 1381 receive_label.c_str(), receive_label.length(), 1382 &sdp); 1383 CreateAnswerAsRemoteDescription(sdp); 1384 1385 // Verify that a new incoming data channel has been created and that 1386 // it is open but can't we written to. 1387 ASSERT_TRUE(observer_.last_datachannel_ != NULL); 1388 DataChannelInterface* received_channel = observer_.last_datachannel_; 1389 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state()); 1390 EXPECT_EQ(receive_label, received_channel->label()); 1391 EXPECT_FALSE(received_channel->Send(DataBuffer("something"))); 1392 1393 // Verify that the channel we initially offered has been rejected. 1394 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state()); 1395 1396 // Do another offer / answer exchange and verify that the data channel is 1397 // opened. 1398 CreateOfferReceiveAnswer(); 1399 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(), 1400 kTimeout); 1401} 1402 1403// This test that no data channel is returned if a reliable channel is 1404// requested. 1405// TODO(perkj): Remove this test once reliable channels are implemented. 1406TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) { 1407 FakeConstraints constraints; 1408 constraints.SetAllowRtpDataChannels(); 1409 CreatePeerConnection(&constraints); 1410 1411 std::string label = "test"; 1412 webrtc::DataChannelInit config; 1413 config.reliable = true; 1414 scoped_refptr<DataChannelInterface> channel = 1415 pc_->CreateDataChannel(label, &config); 1416 EXPECT_TRUE(channel == NULL); 1417} 1418 1419// Verifies that duplicated label is not allowed for RTP data channel. 1420TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) { 1421 FakeConstraints constraints; 1422 constraints.SetAllowRtpDataChannels(); 1423 CreatePeerConnection(&constraints); 1424 1425 std::string label = "test"; 1426 scoped_refptr<DataChannelInterface> channel = 1427 pc_->CreateDataChannel(label, nullptr); 1428 EXPECT_NE(channel, nullptr); 1429 1430 scoped_refptr<DataChannelInterface> dup_channel = 1431 pc_->CreateDataChannel(label, nullptr); 1432 EXPECT_EQ(dup_channel, nullptr); 1433} 1434 1435// This tests that a SCTP data channel is returned using different 1436// DataChannelInit configurations. 1437TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) { 1438 FakeConstraints constraints; 1439 constraints.SetAllowDtlsSctpDataChannels(); 1440 CreatePeerConnection(&constraints); 1441 1442 webrtc::DataChannelInit config; 1443 1444 scoped_refptr<DataChannelInterface> channel = 1445 pc_->CreateDataChannel("1", &config); 1446 EXPECT_TRUE(channel != NULL); 1447 EXPECT_TRUE(channel->reliable()); 1448 EXPECT_TRUE(observer_.renegotiation_needed_); 1449 observer_.renegotiation_needed_ = false; 1450 1451 config.ordered = false; 1452 channel = pc_->CreateDataChannel("2", &config); 1453 EXPECT_TRUE(channel != NULL); 1454 EXPECT_TRUE(channel->reliable()); 1455 EXPECT_FALSE(observer_.renegotiation_needed_); 1456 1457 config.ordered = true; 1458 config.maxRetransmits = 0; 1459 channel = pc_->CreateDataChannel("3", &config); 1460 EXPECT_TRUE(channel != NULL); 1461 EXPECT_FALSE(channel->reliable()); 1462 EXPECT_FALSE(observer_.renegotiation_needed_); 1463 1464 config.maxRetransmits = -1; 1465 config.maxRetransmitTime = 0; 1466 channel = pc_->CreateDataChannel("4", &config); 1467 EXPECT_TRUE(channel != NULL); 1468 EXPECT_FALSE(channel->reliable()); 1469 EXPECT_FALSE(observer_.renegotiation_needed_); 1470} 1471 1472// This tests that no data channel is returned if both maxRetransmits and 1473// maxRetransmitTime are set for SCTP data channels. 1474TEST_F(PeerConnectionInterfaceTest, 1475 CreateSctpDataChannelShouldFailForInvalidConfig) { 1476 FakeConstraints constraints; 1477 constraints.SetAllowDtlsSctpDataChannels(); 1478 CreatePeerConnection(&constraints); 1479 1480 std::string label = "test"; 1481 webrtc::DataChannelInit config; 1482 config.maxRetransmits = 0; 1483 config.maxRetransmitTime = 0; 1484 1485 scoped_refptr<DataChannelInterface> channel = 1486 pc_->CreateDataChannel(label, &config); 1487 EXPECT_TRUE(channel == NULL); 1488} 1489 1490// The test verifies that creating a SCTP data channel with an id already in use 1491// or out of range should fail. 1492TEST_F(PeerConnectionInterfaceTest, 1493 CreateSctpDataChannelWithInvalidIdShouldFail) { 1494 FakeConstraints constraints; 1495 constraints.SetAllowDtlsSctpDataChannels(); 1496 CreatePeerConnection(&constraints); 1497 1498 webrtc::DataChannelInit config; 1499 scoped_refptr<DataChannelInterface> channel; 1500 1501 config.id = 1; 1502 channel = pc_->CreateDataChannel("1", &config); 1503 EXPECT_TRUE(channel != NULL); 1504 EXPECT_EQ(1, channel->id()); 1505 1506 channel = pc_->CreateDataChannel("x", &config); 1507 EXPECT_TRUE(channel == NULL); 1508 1509 config.id = cricket::kMaxSctpSid; 1510 channel = pc_->CreateDataChannel("max", &config); 1511 EXPECT_TRUE(channel != NULL); 1512 EXPECT_EQ(config.id, channel->id()); 1513 1514 config.id = cricket::kMaxSctpSid + 1; 1515 channel = pc_->CreateDataChannel("x", &config); 1516 EXPECT_TRUE(channel == NULL); 1517} 1518 1519// Verifies that duplicated label is allowed for SCTP data channel. 1520TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) { 1521 FakeConstraints constraints; 1522 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1523 true); 1524 CreatePeerConnection(&constraints); 1525 1526 std::string label = "test"; 1527 scoped_refptr<DataChannelInterface> channel = 1528 pc_->CreateDataChannel(label, nullptr); 1529 EXPECT_NE(channel, nullptr); 1530 1531 scoped_refptr<DataChannelInterface> dup_channel = 1532 pc_->CreateDataChannel(label, nullptr); 1533 EXPECT_NE(dup_channel, nullptr); 1534} 1535 1536// This test verifies that OnRenegotiationNeeded is fired for every new RTP 1537// DataChannel. 1538TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) { 1539 FakeConstraints constraints; 1540 constraints.SetAllowRtpDataChannels(); 1541 CreatePeerConnection(&constraints); 1542 1543 scoped_refptr<DataChannelInterface> dc1 = 1544 pc_->CreateDataChannel("test1", NULL); 1545 EXPECT_TRUE(observer_.renegotiation_needed_); 1546 observer_.renegotiation_needed_ = false; 1547 1548 scoped_refptr<DataChannelInterface> dc2 = 1549 pc_->CreateDataChannel("test2", NULL); 1550 EXPECT_TRUE(observer_.renegotiation_needed_); 1551} 1552 1553// This test that a data channel closes when a PeerConnection is deleted/closed. 1554TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) { 1555 FakeConstraints constraints; 1556 constraints.SetAllowRtpDataChannels(); 1557 CreatePeerConnection(&constraints); 1558 1559 scoped_refptr<DataChannelInterface> data1 = 1560 pc_->CreateDataChannel("test1", NULL); 1561 scoped_refptr<DataChannelInterface> data2 = 1562 pc_->CreateDataChannel("test2", NULL); 1563 ASSERT_TRUE(data1 != NULL); 1564 rtc::scoped_ptr<MockDataChannelObserver> observer1( 1565 new MockDataChannelObserver(data1)); 1566 rtc::scoped_ptr<MockDataChannelObserver> observer2( 1567 new MockDataChannelObserver(data2)); 1568 1569 CreateOfferReceiveAnswer(); 1570 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 1571 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 1572 1573 ReleasePeerConnection(); 1574 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 1575 EXPECT_EQ(DataChannelInterface::kClosed, data2->state()); 1576} 1577 1578// This test that data channels can be rejected in an answer. 1579TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) { 1580 FakeConstraints constraints; 1581 constraints.SetAllowRtpDataChannels(); 1582 CreatePeerConnection(&constraints); 1583 1584 scoped_refptr<DataChannelInterface> offer_channel( 1585 pc_->CreateDataChannel("offer_channel", NULL)); 1586 1587 CreateOfferAsLocalDescription(); 1588 1589 // Create an answer where the m-line for data channels are rejected. 1590 std::string sdp; 1591 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 1592 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( 1593 SessionDescriptionInterface::kAnswer); 1594 EXPECT_TRUE(answer->Initialize(sdp, NULL)); 1595 cricket::ContentInfo* data_info = 1596 answer->description()->GetContentByName("data"); 1597 data_info->rejected = true; 1598 1599 DoSetRemoteDescription(answer); 1600 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state()); 1601} 1602 1603// Test that we can create a session description from an SDP string from 1604// FireFox, use it as a remote session description, generate an answer and use 1605// the answer as a local description. 1606TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) { 1607 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); 1608 FakeConstraints constraints; 1609 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1610 true); 1611 CreatePeerConnection(&constraints); 1612 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1613 SessionDescriptionInterface* desc = 1614 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1615 webrtc::kFireFoxSdpOffer, nullptr); 1616 EXPECT_TRUE(DoSetSessionDescription(desc, false)); 1617 CreateAnswerAsLocalDescription(); 1618 ASSERT_TRUE(pc_->local_description() != NULL); 1619 ASSERT_TRUE(pc_->remote_description() != NULL); 1620 1621 const cricket::ContentInfo* content = 1622 cricket::GetFirstAudioContent(pc_->local_description()->description()); 1623 ASSERT_TRUE(content != NULL); 1624 EXPECT_FALSE(content->rejected); 1625 1626 content = 1627 cricket::GetFirstVideoContent(pc_->local_description()->description()); 1628 ASSERT_TRUE(content != NULL); 1629 EXPECT_FALSE(content->rejected); 1630#ifdef HAVE_SCTP 1631 content = 1632 cricket::GetFirstDataContent(pc_->local_description()->description()); 1633 ASSERT_TRUE(content != NULL); 1634 EXPECT_TRUE(content->rejected); 1635#endif 1636} 1637 1638// Test that we can create an audio only offer and receive an answer with a 1639// limited set of audio codecs and receive an updated offer with more audio 1640// codecs, where the added codecs are not supported. 1641TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) { 1642 CreatePeerConnection(); 1643 AddVoiceStream("audio_label"); 1644 CreateOfferAsLocalDescription(); 1645 1646 SessionDescriptionInterface* answer = 1647 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, 1648 webrtc::kAudioSdp, nullptr); 1649 EXPECT_TRUE(DoSetSessionDescription(answer, false)); 1650 1651 SessionDescriptionInterface* updated_offer = 1652 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1653 webrtc::kAudioSdpWithUnsupportedCodecs, 1654 nullptr); 1655 EXPECT_TRUE(DoSetSessionDescription(updated_offer, false)); 1656 CreateAnswerAsLocalDescription(); 1657} 1658 1659// Test that if we're receiving (but not sending) a track, subsequent offers 1660// will have m-lines with a=recvonly. 1661TEST_F(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) { 1662 FakeConstraints constraints; 1663 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1664 true); 1665 CreatePeerConnection(&constraints); 1666 CreateAndSetRemoteOffer(kSdpStringWithStream1); 1667 CreateAnswerAsLocalDescription(); 1668 1669 // At this point we should be receiving stream 1, but not sending anything. 1670 // A new offer should be recvonly. 1671 SessionDescriptionInterface* offer; 1672 DoCreateOffer(&offer, nullptr); 1673 1674 const cricket::ContentInfo* video_content = 1675 cricket::GetFirstVideoContent(offer->description()); 1676 const cricket::VideoContentDescription* video_desc = 1677 static_cast<const cricket::VideoContentDescription*>( 1678 video_content->description); 1679 ASSERT_EQ(cricket::MD_RECVONLY, video_desc->direction()); 1680 1681 const cricket::ContentInfo* audio_content = 1682 cricket::GetFirstAudioContent(offer->description()); 1683 const cricket::AudioContentDescription* audio_desc = 1684 static_cast<const cricket::AudioContentDescription*>( 1685 audio_content->description); 1686 ASSERT_EQ(cricket::MD_RECVONLY, audio_desc->direction()); 1687} 1688 1689// Test that if we're receiving (but not sending) a track, and the 1690// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to 1691// false, the generated m-lines will be a=inactive. 1692TEST_F(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) { 1693 FakeConstraints constraints; 1694 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1695 true); 1696 CreatePeerConnection(&constraints); 1697 CreateAndSetRemoteOffer(kSdpStringWithStream1); 1698 CreateAnswerAsLocalDescription(); 1699 1700 // At this point we should be receiving stream 1, but not sending anything. 1701 // A new offer would be recvonly, but we'll set the "no receive" constraints 1702 // to make it inactive. 1703 SessionDescriptionInterface* offer; 1704 FakeConstraints offer_constraints; 1705 offer_constraints.AddMandatory( 1706 webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, false); 1707 offer_constraints.AddMandatory( 1708 webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, false); 1709 DoCreateOffer(&offer, &offer_constraints); 1710 1711 const cricket::ContentInfo* video_content = 1712 cricket::GetFirstVideoContent(offer->description()); 1713 const cricket::VideoContentDescription* video_desc = 1714 static_cast<const cricket::VideoContentDescription*>( 1715 video_content->description); 1716 ASSERT_EQ(cricket::MD_INACTIVE, video_desc->direction()); 1717 1718 const cricket::ContentInfo* audio_content = 1719 cricket::GetFirstAudioContent(offer->description()); 1720 const cricket::AudioContentDescription* audio_desc = 1721 static_cast<const cricket::AudioContentDescription*>( 1722 audio_content->description); 1723 ASSERT_EQ(cricket::MD_INACTIVE, audio_desc->direction()); 1724} 1725 1726// Test that we can use SetConfiguration to change the ICE servers of the 1727// PortAllocator. 1728TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) { 1729 CreatePeerConnection(); 1730 1731 PeerConnectionInterface::RTCConfiguration config; 1732 PeerConnectionInterface::IceServer server; 1733 server.uri = "stun:test_hostname"; 1734 config.servers.push_back(server); 1735 EXPECT_TRUE(pc_->SetConfiguration(config)); 1736 1737 EXPECT_EQ(1u, port_allocator_->stun_servers().size()); 1738 EXPECT_EQ("test_hostname", 1739 port_allocator_->stun_servers().begin()->hostname()); 1740} 1741 1742// Test that PeerConnection::Close changes the states to closed and all remote 1743// tracks change state to ended. 1744TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) { 1745 // Initialize a PeerConnection and negotiate local and remote session 1746 // description. 1747 InitiateCall(); 1748 ASSERT_EQ(1u, pc_->local_streams()->count()); 1749 ASSERT_EQ(1u, pc_->remote_streams()->count()); 1750 1751 pc_->Close(); 1752 1753 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state()); 1754 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed, 1755 pc_->ice_connection_state()); 1756 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, 1757 pc_->ice_gathering_state()); 1758 1759 EXPECT_EQ(1u, pc_->local_streams()->count()); 1760 EXPECT_EQ(1u, pc_->remote_streams()->count()); 1761 1762 scoped_refptr<MediaStreamInterface> remote_stream = 1763 pc_->remote_streams()->at(0); 1764 EXPECT_EQ(MediaStreamTrackInterface::kEnded, 1765 remote_stream->GetVideoTracks()[0]->state()); 1766 EXPECT_EQ(MediaStreamTrackInterface::kEnded, 1767 remote_stream->GetAudioTracks()[0]->state()); 1768} 1769 1770// Test that PeerConnection methods fails gracefully after 1771// PeerConnection::Close has been called. 1772TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) { 1773 CreatePeerConnection(); 1774 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1775 CreateOfferAsRemoteDescription(); 1776 CreateAnswerAsLocalDescription(); 1777 1778 ASSERT_EQ(1u, pc_->local_streams()->count()); 1779 scoped_refptr<MediaStreamInterface> local_stream = 1780 pc_->local_streams()->at(0); 1781 1782 pc_->Close(); 1783 1784 pc_->RemoveStream(local_stream); 1785 EXPECT_FALSE(pc_->AddStream(local_stream)); 1786 1787 ASSERT_FALSE(local_stream->GetAudioTracks().empty()); 1788 rtc::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender( 1789 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0])); 1790 EXPECT_TRUE(NULL == dtmf_sender); // local stream has been removed. 1791 1792 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL); 1793 1794 EXPECT_TRUE(pc_->local_description() != NULL); 1795 EXPECT_TRUE(pc_->remote_description() != NULL); 1796 1797 rtc::scoped_ptr<SessionDescriptionInterface> offer; 1798 EXPECT_TRUE(DoCreateOffer(offer.use(), nullptr)); 1799 rtc::scoped_ptr<SessionDescriptionInterface> answer; 1800 EXPECT_TRUE(DoCreateAnswer(answer.use(), nullptr)); 1801 1802 std::string sdp; 1803 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp)); 1804 SessionDescriptionInterface* remote_offer = 1805 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1806 sdp, NULL); 1807 EXPECT_FALSE(DoSetRemoteDescription(remote_offer)); 1808 1809 ASSERT_TRUE(pc_->local_description()->ToString(&sdp)); 1810 SessionDescriptionInterface* local_offer = 1811 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1812 sdp, NULL); 1813 EXPECT_FALSE(DoSetLocalDescription(local_offer)); 1814} 1815 1816// Test that GetStats can still be called after PeerConnection::Close. 1817TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) { 1818 InitiateCall(); 1819 pc_->Close(); 1820 DoGetStats(NULL); 1821} 1822 1823// NOTE: The series of tests below come from what used to be 1824// mediastreamsignaling_unittest.cc, and are mostly aimed at testing that 1825// setting a remote or local description has the expected effects. 1826 1827// This test verifies that the remote MediaStreams corresponding to a received 1828// SDP string is created. In this test the two separate MediaStreams are 1829// signaled. 1830TEST_F(PeerConnectionInterfaceTest, UpdateRemoteStreams) { 1831 FakeConstraints constraints; 1832 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1833 true); 1834 CreatePeerConnection(&constraints); 1835 CreateAndSetRemoteOffer(kSdpStringWithStream1); 1836 1837 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1)); 1838 EXPECT_TRUE( 1839 CompareStreamCollections(observer_.remote_streams(), reference.get())); 1840 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 1841 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr); 1842 1843 // Create a session description based on another SDP with another 1844 // MediaStream. 1845 CreateAndSetRemoteOffer(kSdpStringWithStream1And2); 1846 1847 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2)); 1848 EXPECT_TRUE( 1849 CompareStreamCollections(observer_.remote_streams(), reference2.get())); 1850} 1851 1852// This test verifies that when remote tracks are added/removed from SDP, the 1853// created remote streams are updated appropriately. 1854TEST_F(PeerConnectionInterfaceTest, 1855 AddRemoveTrackFromExistingRemoteMediaStream) { 1856 FakeConstraints constraints; 1857 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1858 true); 1859 CreatePeerConnection(&constraints); 1860 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms1; 1861 CreateSessionDescriptionAndReference(1, 1, desc_ms1.accept()); 1862 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release())); 1863 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), 1864 reference_collection_)); 1865 1866 // Add extra audio and video tracks to the same MediaStream. 1867 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms1_two_tracks; 1868 CreateSessionDescriptionAndReference(2, 2, desc_ms1_two_tracks.accept()); 1869 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release())); 1870 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), 1871 reference_collection_)); 1872 1873 // Remove the extra audio and video tracks. 1874 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms2; 1875 CreateSessionDescriptionAndReference(1, 1, desc_ms2.accept()); 1876 EXPECT_TRUE(DoSetRemoteDescription(desc_ms2.release())); 1877 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), 1878 reference_collection_)); 1879} 1880 1881// This tests that remote tracks are ended if a local session description is set 1882// that rejects the media content type. 1883TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) { 1884 FakeConstraints constraints; 1885 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1886 true); 1887 CreatePeerConnection(&constraints); 1888 // First create and set a remote offer, then reject its video content in our 1889 // answer. 1890 CreateAndSetRemoteOffer(kSdpStringWithStream1); 1891 ASSERT_EQ(1u, observer_.remote_streams()->count()); 1892 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 1893 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size()); 1894 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size()); 1895 1896 rtc::scoped_refptr<webrtc::VideoTrackInterface> remote_video = 1897 remote_stream->GetVideoTracks()[0]; 1898 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_video->state()); 1899 rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_audio = 1900 remote_stream->GetAudioTracks()[0]; 1901 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state()); 1902 1903 rtc::scoped_ptr<SessionDescriptionInterface> local_answer; 1904 EXPECT_TRUE(DoCreateAnswer(local_answer.accept(), nullptr)); 1905 cricket::ContentInfo* video_info = 1906 local_answer->description()->GetContentByName("video"); 1907 video_info->rejected = true; 1908 EXPECT_TRUE(DoSetLocalDescription(local_answer.release())); 1909 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state()); 1910 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state()); 1911 1912 // Now create an offer where we reject both video and audio. 1913 rtc::scoped_ptr<SessionDescriptionInterface> local_offer; 1914 EXPECT_TRUE(DoCreateOffer(local_offer.accept(), nullptr)); 1915 video_info = local_offer->description()->GetContentByName("video"); 1916 ASSERT_TRUE(video_info != nullptr); 1917 video_info->rejected = true; 1918 cricket::ContentInfo* audio_info = 1919 local_offer->description()->GetContentByName("audio"); 1920 ASSERT_TRUE(audio_info != nullptr); 1921 audio_info->rejected = true; 1922 EXPECT_TRUE(DoSetLocalDescription(local_offer.release())); 1923 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state()); 1924 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_audio->state()); 1925} 1926 1927// This tests that we won't crash if the remote track has been removed outside 1928// of PeerConnection and then PeerConnection tries to reject the track. 1929TEST_F(PeerConnectionInterfaceTest, RemoveTrackThenRejectMediaContent) { 1930 FakeConstraints constraints; 1931 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1932 true); 1933 CreatePeerConnection(&constraints); 1934 CreateAndSetRemoteOffer(kSdpStringWithStream1); 1935 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 1936 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]); 1937 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]); 1938 1939 rtc::scoped_ptr<SessionDescriptionInterface> local_answer( 1940 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, 1941 kSdpStringWithStream1, nullptr)); 1942 cricket::ContentInfo* video_info = 1943 local_answer->description()->GetContentByName("video"); 1944 video_info->rejected = true; 1945 cricket::ContentInfo* audio_info = 1946 local_answer->description()->GetContentByName("audio"); 1947 audio_info->rejected = true; 1948 EXPECT_TRUE(DoSetLocalDescription(local_answer.release())); 1949 1950 // No crash is a pass. 1951} 1952 1953// This tests that if a recvonly remote description is set, no remote streams 1954// will be created, even if the description contains SSRCs/MSIDs. 1955// See: https://code.google.com/p/webrtc/issues/detail?id=5054 1956TEST_F(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) { 1957 FakeConstraints constraints; 1958 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1959 true); 1960 CreatePeerConnection(&constraints); 1961 1962 std::string recvonly_offer = kSdpStringWithStream1; 1963 rtc::replace_substrs(kSendrecv, strlen(kSendrecv), kRecvonly, 1964 strlen(kRecvonly), &recvonly_offer); 1965 CreateAndSetRemoteOffer(recvonly_offer); 1966 1967 EXPECT_EQ(0u, observer_.remote_streams()->count()); 1968} 1969 1970// This tests that a default MediaStream is created if a remote session 1971// description doesn't contain any streams and no MSID support. 1972// It also tests that the default stream is updated if a video m-line is added 1973// in a subsequent session description. 1974TEST_F(PeerConnectionInterfaceTest, SdpWithoutMsidCreatesDefaultStream) { 1975 FakeConstraints constraints; 1976 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1977 true); 1978 CreatePeerConnection(&constraints); 1979 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly); 1980 1981 ASSERT_EQ(1u, observer_.remote_streams()->count()); 1982 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 1983 1984 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size()); 1985 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size()); 1986 EXPECT_EQ("default", remote_stream->label()); 1987 1988 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); 1989 ASSERT_EQ(1u, observer_.remote_streams()->count()); 1990 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size()); 1991 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id()); 1992 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size()); 1993 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id()); 1994} 1995 1996// This tests that a default MediaStream is created if a remote session 1997// description doesn't contain any streams and media direction is send only. 1998TEST_F(PeerConnectionInterfaceTest, 1999 SendOnlySdpWithoutMsidCreatesDefaultStream) { 2000 FakeConstraints constraints; 2001 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2002 true); 2003 CreatePeerConnection(&constraints); 2004 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams); 2005 2006 ASSERT_EQ(1u, observer_.remote_streams()->count()); 2007 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 2008 2009 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size()); 2010 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size()); 2011 EXPECT_EQ("default", remote_stream->label()); 2012} 2013 2014// This tests that it won't crash when PeerConnection tries to remove 2015// a remote track that as already been removed from the MediaStream. 2016TEST_F(PeerConnectionInterfaceTest, RemoveAlreadyGoneRemoteStream) { 2017 FakeConstraints constraints; 2018 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2019 true); 2020 CreatePeerConnection(&constraints); 2021 CreateAndSetRemoteOffer(kSdpStringWithStream1); 2022 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 2023 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]); 2024 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]); 2025 2026 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); 2027 2028 // No crash is a pass. 2029} 2030 2031// This tests that a default MediaStream is created if the remote session 2032// description doesn't contain any streams and don't contain an indication if 2033// MSID is supported. 2034TEST_F(PeerConnectionInterfaceTest, 2035 SdpWithoutMsidAndStreamsCreatesDefaultStream) { 2036 FakeConstraints constraints; 2037 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2038 true); 2039 CreatePeerConnection(&constraints); 2040 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); 2041 2042 ASSERT_EQ(1u, observer_.remote_streams()->count()); 2043 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 2044 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size()); 2045 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size()); 2046} 2047 2048// This tests that a default MediaStream is not created if the remote session 2049// description doesn't contain any streams but does support MSID. 2050TEST_F(PeerConnectionInterfaceTest, SdpWithMsidDontCreatesDefaultStream) { 2051 FakeConstraints constraints; 2052 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2053 true); 2054 CreatePeerConnection(&constraints); 2055 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams); 2056 EXPECT_EQ(0u, observer_.remote_streams()->count()); 2057} 2058 2059// This tests that when setting a new description, the old default tracks are 2060// not destroyed and recreated. 2061// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250 2062TEST_F(PeerConnectionInterfaceTest, DefaultTracksNotDestroyedAndRecreated) { 2063 FakeConstraints constraints; 2064 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2065 true); 2066 CreatePeerConnection(&constraints); 2067 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly); 2068 2069 ASSERT_EQ(1u, observer_.remote_streams()->count()); 2070 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); 2071 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size()); 2072 2073 // Set the track to "disabled", then set a new description and ensure the 2074 // track is still disabled, which ensures it hasn't been recreated. 2075 remote_stream->GetAudioTracks()[0]->set_enabled(false); 2076 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly); 2077 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size()); 2078 EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled()); 2079} 2080 2081// This tests that a default MediaStream is not created if a remote session 2082// description is updated to not have any MediaStreams. 2083TEST_F(PeerConnectionInterfaceTest, VerifyDefaultStreamIsNotCreated) { 2084 FakeConstraints constraints; 2085 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2086 true); 2087 CreatePeerConnection(&constraints); 2088 CreateAndSetRemoteOffer(kSdpStringWithStream1); 2089 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1)); 2090 EXPECT_TRUE( 2091 CompareStreamCollections(observer_.remote_streams(), reference.get())); 2092 2093 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); 2094 EXPECT_EQ(0u, observer_.remote_streams()->count()); 2095} 2096 2097// This tests that an RtpSender is created when the local description is set 2098// after adding a local stream. 2099// TODO(deadbeef): This test and the one below it need to be updated when 2100// an RtpSender's lifetime isn't determined by when a local description is set. 2101TEST_F(PeerConnectionInterfaceTest, LocalDescriptionChanged) { 2102 FakeConstraints constraints; 2103 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2104 true); 2105 CreatePeerConnection(&constraints); 2106 // Create an offer just to ensure we have an identity before we manually 2107 // call SetLocalDescription. 2108 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; 2109 ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); 2110 2111 rtc::scoped_ptr<SessionDescriptionInterface> desc_1; 2112 CreateSessionDescriptionAndReference(2, 2, desc_1.accept()); 2113 2114 pc_->AddStream(reference_collection_->at(0)); 2115 EXPECT_TRUE(DoSetLocalDescription(desc_1.release())); 2116 auto senders = pc_->GetSenders(); 2117 EXPECT_EQ(4u, senders.size()); 2118 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); 2119 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); 2120 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1])); 2121 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1])); 2122 2123 // Remove an audio and video track. 2124 pc_->RemoveStream(reference_collection_->at(0)); 2125 rtc::scoped_ptr<SessionDescriptionInterface> desc_2; 2126 CreateSessionDescriptionAndReference(1, 1, desc_2.accept()); 2127 pc_->AddStream(reference_collection_->at(0)); 2128 EXPECT_TRUE(DoSetLocalDescription(desc_2.release())); 2129 senders = pc_->GetSenders(); 2130 EXPECT_EQ(2u, senders.size()); 2131 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); 2132 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); 2133 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1])); 2134 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1])); 2135} 2136 2137// This tests that an RtpSender is created when the local description is set 2138// before adding a local stream. 2139TEST_F(PeerConnectionInterfaceTest, 2140 AddLocalStreamAfterLocalDescriptionChanged) { 2141 FakeConstraints constraints; 2142 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2143 true); 2144 CreatePeerConnection(&constraints); 2145 // Create an offer just to ensure we have an identity before we manually 2146 // call SetLocalDescription. 2147 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; 2148 ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); 2149 2150 rtc::scoped_ptr<SessionDescriptionInterface> desc_1; 2151 CreateSessionDescriptionAndReference(2, 2, desc_1.accept()); 2152 2153 EXPECT_TRUE(DoSetLocalDescription(desc_1.release())); 2154 auto senders = pc_->GetSenders(); 2155 EXPECT_EQ(0u, senders.size()); 2156 2157 pc_->AddStream(reference_collection_->at(0)); 2158 senders = pc_->GetSenders(); 2159 EXPECT_EQ(4u, senders.size()); 2160 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); 2161 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); 2162 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1])); 2163 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1])); 2164} 2165 2166// This tests that the expected behavior occurs if the SSRC on a local track is 2167// changed when SetLocalDescription is called. 2168TEST_F(PeerConnectionInterfaceTest, 2169 ChangeSsrcOnTrackInLocalSessionDescription) { 2170 FakeConstraints constraints; 2171 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2172 true); 2173 CreatePeerConnection(&constraints); 2174 // Create an offer just to ensure we have an identity before we manually 2175 // call SetLocalDescription. 2176 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; 2177 ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); 2178 2179 rtc::scoped_ptr<SessionDescriptionInterface> desc; 2180 CreateSessionDescriptionAndReference(1, 1, desc.accept()); 2181 std::string sdp; 2182 desc->ToString(&sdp); 2183 2184 pc_->AddStream(reference_collection_->at(0)); 2185 EXPECT_TRUE(DoSetLocalDescription(desc.release())); 2186 auto senders = pc_->GetSenders(); 2187 EXPECT_EQ(2u, senders.size()); 2188 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); 2189 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); 2190 2191 // Change the ssrc of the audio and video track. 2192 std::string ssrc_org = "a=ssrc:1"; 2193 std::string ssrc_to = "a=ssrc:97"; 2194 rtc::replace_substrs(ssrc_org.c_str(), ssrc_org.length(), ssrc_to.c_str(), 2195 ssrc_to.length(), &sdp); 2196 ssrc_org = "a=ssrc:2"; 2197 ssrc_to = "a=ssrc:98"; 2198 rtc::replace_substrs(ssrc_org.c_str(), ssrc_org.length(), ssrc_to.c_str(), 2199 ssrc_to.length(), &sdp); 2200 rtc::scoped_ptr<SessionDescriptionInterface> updated_desc( 2201 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, sdp, 2202 nullptr)); 2203 2204 EXPECT_TRUE(DoSetLocalDescription(updated_desc.release())); 2205 senders = pc_->GetSenders(); 2206 EXPECT_EQ(2u, senders.size()); 2207 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); 2208 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); 2209 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC 2210 // changed. 2211} 2212 2213// This tests that the expected behavior occurs if a new session description is 2214// set with the same tracks, but on a different MediaStream. 2215TEST_F(PeerConnectionInterfaceTest, SignalSameTracksInSeparateMediaStream) { 2216 FakeConstraints constraints; 2217 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 2218 true); 2219 CreatePeerConnection(&constraints); 2220 // Create an offer just to ensure we have an identity before we manually 2221 // call SetLocalDescription. 2222 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; 2223 ASSERT_TRUE(DoCreateOffer(throwaway.accept(), nullptr)); 2224 2225 rtc::scoped_ptr<SessionDescriptionInterface> desc; 2226 CreateSessionDescriptionAndReference(1, 1, desc.accept()); 2227 std::string sdp; 2228 desc->ToString(&sdp); 2229 2230 pc_->AddStream(reference_collection_->at(0)); 2231 EXPECT_TRUE(DoSetLocalDescription(desc.release())); 2232 auto senders = pc_->GetSenders(); 2233 EXPECT_EQ(2u, senders.size()); 2234 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); 2235 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); 2236 2237 // Add a new MediaStream but with the same tracks as in the first stream. 2238 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1( 2239 webrtc::MediaStream::Create(kStreams[1])); 2240 stream_1->AddTrack(reference_collection_->at(0)->GetVideoTracks()[0]); 2241 stream_1->AddTrack(reference_collection_->at(0)->GetAudioTracks()[0]); 2242 pc_->AddStream(stream_1); 2243 2244 // Replace msid in the original SDP. 2245 rtc::replace_substrs(kStreams[0], strlen(kStreams[0]), kStreams[1], 2246 strlen(kStreams[1]), &sdp); 2247 2248 rtc::scoped_ptr<SessionDescriptionInterface> updated_desc( 2249 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, sdp, 2250 nullptr)); 2251 2252 EXPECT_TRUE(DoSetLocalDescription(updated_desc.release())); 2253 senders = pc_->GetSenders(); 2254 EXPECT_EQ(2u, senders.size()); 2255 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); 2256 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); 2257} 2258 2259// The following tests verify that session options are created correctly. 2260// TODO(deadbeef): Convert these tests to be more end-to-end. Instead of 2261// "verify options are converted correctly", should be "pass options into 2262// CreateOffer and verify the correct offer is produced." 2263 2264TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidAudioOption) { 2265 RTCOfferAnswerOptions rtc_options; 2266 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1; 2267 2268 cricket::MediaSessionOptions options; 2269 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2270 2271 rtc_options.offer_to_receive_audio = 2272 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1; 2273 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2274} 2275 2276TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) { 2277 RTCOfferAnswerOptions rtc_options; 2278 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1; 2279 2280 cricket::MediaSessionOptions options; 2281 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2282 2283 rtc_options.offer_to_receive_video = 2284 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1; 2285 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2286} 2287 2288// Test that a MediaSessionOptions is created for an offer if 2289// OfferToReceiveAudio and OfferToReceiveVideo options are set. 2290TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) { 2291 RTCOfferAnswerOptions rtc_options; 2292 rtc_options.offer_to_receive_audio = 1; 2293 rtc_options.offer_to_receive_video = 1; 2294 2295 cricket::MediaSessionOptions options; 2296 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2297 EXPECT_TRUE(options.has_audio()); 2298 EXPECT_TRUE(options.has_video()); 2299 EXPECT_TRUE(options.bundle_enabled); 2300} 2301 2302// Test that a correct MediaSessionOptions is created for an offer if 2303// OfferToReceiveAudio is set. 2304TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) { 2305 RTCOfferAnswerOptions rtc_options; 2306 rtc_options.offer_to_receive_audio = 1; 2307 2308 cricket::MediaSessionOptions options; 2309 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2310 EXPECT_TRUE(options.has_audio()); 2311 EXPECT_FALSE(options.has_video()); 2312 EXPECT_TRUE(options.bundle_enabled); 2313} 2314 2315// Test that a correct MediaSessionOptions is created for an offer if 2316// the default OfferOptions are used. 2317TEST(CreateSessionOptionsTest, GetDefaultMediaSessionOptionsForOffer) { 2318 RTCOfferAnswerOptions rtc_options; 2319 2320 cricket::MediaSessionOptions options; 2321 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2322 EXPECT_TRUE(options.has_audio()); 2323 EXPECT_FALSE(options.has_video()); 2324 EXPECT_TRUE(options.bundle_enabled); 2325 EXPECT_TRUE(options.vad_enabled); 2326 EXPECT_FALSE(options.audio_transport_options.ice_restart); 2327 EXPECT_FALSE(options.video_transport_options.ice_restart); 2328 EXPECT_FALSE(options.data_transport_options.ice_restart); 2329} 2330 2331// Test that a correct MediaSessionOptions is created for an offer if 2332// OfferToReceiveVideo is set. 2333TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithVideo) { 2334 RTCOfferAnswerOptions rtc_options; 2335 rtc_options.offer_to_receive_audio = 0; 2336 rtc_options.offer_to_receive_video = 1; 2337 2338 cricket::MediaSessionOptions options; 2339 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2340 EXPECT_FALSE(options.has_audio()); 2341 EXPECT_TRUE(options.has_video()); 2342 EXPECT_TRUE(options.bundle_enabled); 2343} 2344 2345// Test that a correct MediaSessionOptions is created for an offer if 2346// UseRtpMux is set to false. 2347TEST(CreateSessionOptionsTest, 2348 GetMediaSessionOptionsForOfferWithBundleDisabled) { 2349 RTCOfferAnswerOptions rtc_options; 2350 rtc_options.offer_to_receive_audio = 1; 2351 rtc_options.offer_to_receive_video = 1; 2352 rtc_options.use_rtp_mux = false; 2353 2354 cricket::MediaSessionOptions options; 2355 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2356 EXPECT_TRUE(options.has_audio()); 2357 EXPECT_TRUE(options.has_video()); 2358 EXPECT_FALSE(options.bundle_enabled); 2359} 2360 2361// Test that a correct MediaSessionOptions is created to restart ice if 2362// IceRestart is set. It also tests that subsequent MediaSessionOptions don't 2363// have |audio_transport_options.ice_restart| etc. set. 2364TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithIceRestart) { 2365 RTCOfferAnswerOptions rtc_options; 2366 rtc_options.ice_restart = true; 2367 2368 cricket::MediaSessionOptions options; 2369 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2370 EXPECT_TRUE(options.audio_transport_options.ice_restart); 2371 EXPECT_TRUE(options.video_transport_options.ice_restart); 2372 EXPECT_TRUE(options.data_transport_options.ice_restart); 2373 2374 rtc_options = RTCOfferAnswerOptions(); 2375 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); 2376 EXPECT_FALSE(options.audio_transport_options.ice_restart); 2377 EXPECT_FALSE(options.video_transport_options.ice_restart); 2378 EXPECT_FALSE(options.data_transport_options.ice_restart); 2379} 2380 2381// Test that the MediaConstraints in an answer don't affect if audio and video 2382// is offered in an offer but that if kOfferToReceiveAudio or 2383// kOfferToReceiveVideo constraints are true in an offer, the media type will be 2384// included in subsequent answers. 2385TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) { 2386 FakeConstraints answer_c; 2387 answer_c.SetMandatoryReceiveAudio(true); 2388 answer_c.SetMandatoryReceiveVideo(true); 2389 2390 cricket::MediaSessionOptions answer_options; 2391 EXPECT_TRUE(ParseConstraintsForAnswer(&answer_c, &answer_options)); 2392 EXPECT_TRUE(answer_options.has_audio()); 2393 EXPECT_TRUE(answer_options.has_video()); 2394 2395 RTCOfferAnswerOptions rtc_offer_options; 2396 2397 cricket::MediaSessionOptions offer_options; 2398 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_offer_options, &offer_options)); 2399 EXPECT_TRUE(offer_options.has_audio()); 2400 EXPECT_FALSE(offer_options.has_video()); 2401 2402 RTCOfferAnswerOptions updated_rtc_offer_options; 2403 updated_rtc_offer_options.offer_to_receive_audio = 1; 2404 updated_rtc_offer_options.offer_to_receive_video = 1; 2405 2406 cricket::MediaSessionOptions updated_offer_options; 2407 EXPECT_TRUE(ConvertRtcOptionsForOffer(updated_rtc_offer_options, 2408 &updated_offer_options)); 2409 EXPECT_TRUE(updated_offer_options.has_audio()); 2410 EXPECT_TRUE(updated_offer_options.has_video()); 2411 2412 // Since an offer has been created with both audio and video, subsequent 2413 // offers and answers should contain both audio and video. 2414 // Answers will only contain the media types that exist in the offer 2415 // regardless of the value of |updated_answer_options.has_audio| and 2416 // |updated_answer_options.has_video|. 2417 FakeConstraints updated_answer_c; 2418 answer_c.SetMandatoryReceiveAudio(false); 2419 answer_c.SetMandatoryReceiveVideo(false); 2420 2421 cricket::MediaSessionOptions updated_answer_options; 2422 EXPECT_TRUE( 2423 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options)); 2424 EXPECT_TRUE(updated_answer_options.has_audio()); 2425 EXPECT_TRUE(updated_answer_options.has_video()); 2426} 2427