OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 "a=ssrc:4 msid:stream1 videotrack1\r\n"; | 235 "a=ssrc:4 msid:stream1 videotrack1\r\n"; |
236 | 236 |
237 #define MAYBE_SKIP_TEST(feature) \ | 237 #define MAYBE_SKIP_TEST(feature) \ |
238 if (!(feature())) { \ | 238 if (!(feature())) { \ |
239 LOG(LS_INFO) << "Feature disabled... skipping"; \ | 239 LOG(LS_INFO) << "Feature disabled... skipping"; \ |
240 return; \ | 240 return; \ |
241 } | 241 } |
242 | 242 |
243 using ::testing::Exactly; | 243 using ::testing::Exactly; |
244 using cricket::StreamParams; | 244 using cricket::StreamParams; |
| 245 using rtc::scoped_refptr; |
245 using webrtc::AudioSourceInterface; | 246 using webrtc::AudioSourceInterface; |
246 using webrtc::AudioTrack; | 247 using webrtc::AudioTrack; |
247 using webrtc::AudioTrackInterface; | 248 using webrtc::AudioTrackInterface; |
248 using webrtc::DataBuffer; | 249 using webrtc::DataBuffer; |
249 using webrtc::DataChannelInterface; | 250 using webrtc::DataChannelInterface; |
250 using webrtc::FakeConstraints; | 251 using webrtc::FakeConstraints; |
251 using webrtc::IceCandidateInterface; | 252 using webrtc::IceCandidateInterface; |
252 using webrtc::JsepSessionDescription; | 253 using webrtc::JsepSessionDescription; |
253 using webrtc::MediaConstraintsInterface; | 254 using webrtc::MediaConstraintsInterface; |
254 using webrtc::MediaStream; | 255 using webrtc::MediaStream; |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 if (last_added_stream_.get()) | 528 if (last_added_stream_.get()) |
528 return last_added_stream_->label(); | 529 return last_added_stream_->label(); |
529 return ""; | 530 return ""; |
530 } | 531 } |
531 std::string GetLastRemovedStreamLabel() { | 532 std::string GetLastRemovedStreamLabel() { |
532 if (last_removed_stream_.get()) | 533 if (last_removed_stream_.get()) |
533 return last_removed_stream_->label(); | 534 return last_removed_stream_->label(); |
534 return ""; | 535 return ""; |
535 } | 536 } |
536 | 537 |
537 rtc::scoped_refptr<PeerConnectionInterface> pc_; | 538 scoped_refptr<PeerConnectionInterface> pc_; |
538 PeerConnectionInterface::SignalingState state_; | 539 PeerConnectionInterface::SignalingState state_; |
539 std::unique_ptr<IceCandidateInterface> last_candidate_; | 540 std::unique_ptr<IceCandidateInterface> last_candidate_; |
540 rtc::scoped_refptr<DataChannelInterface> last_datachannel_; | 541 scoped_refptr<DataChannelInterface> last_datachannel_; |
541 rtc::scoped_refptr<StreamCollection> remote_streams_; | 542 rtc::scoped_refptr<StreamCollection> remote_streams_; |
542 bool renegotiation_needed_ = false; | 543 bool renegotiation_needed_ = false; |
543 bool ice_complete_ = false; | 544 bool ice_complete_ = false; |
544 bool callback_triggered = false; | 545 bool callback_triggered = false; |
545 | 546 |
546 private: | 547 private: |
547 rtc::scoped_refptr<MediaStreamInterface> last_added_stream_; | 548 scoped_refptr<MediaStreamInterface> last_added_stream_; |
548 rtc::scoped_refptr<MediaStreamInterface> last_removed_stream_; | 549 scoped_refptr<MediaStreamInterface> last_removed_stream_; |
549 }; | 550 }; |
550 | 551 |
551 } // namespace | 552 } // namespace |
552 | 553 |
553 // The PeerConnectionMediaConfig tests below verify that configuration | 554 // The PeerConnectionMediaConfig tests below verify that configuration |
554 // and constraints are propagated into the MediaConfig passed to | 555 // and constraints are propagated into the MediaConfig passed to |
555 // CreateMediaController. These settings are intended for MediaChannel | 556 // CreateMediaController. These settings are intended for MediaChannel |
556 // constructors, but that is not exercised by these unittest. | 557 // constructors, but that is not exercised by these unittest. |
557 class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory { | 558 class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory { |
558 public: | 559 public: |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 observer_.SetPeerConnectionInterface(pc_.get()); | 657 observer_.SetPeerConnectionInterface(pc_.get()); |
657 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); | 658 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); |
658 } | 659 } |
659 | 660 |
660 void CreatePeerConnectionExpectFail(const std::string& uri) { | 661 void CreatePeerConnectionExpectFail(const std::string& uri) { |
661 PeerConnectionInterface::RTCConfiguration config; | 662 PeerConnectionInterface::RTCConfiguration config; |
662 PeerConnectionInterface::IceServer server; | 663 PeerConnectionInterface::IceServer server; |
663 server.uri = uri; | 664 server.uri = uri; |
664 config.servers.push_back(server); | 665 config.servers.push_back(server); |
665 | 666 |
666 rtc::scoped_refptr<PeerConnectionInterface> pc; | 667 scoped_refptr<PeerConnectionInterface> pc; |
667 pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr, nullptr, | 668 pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr, nullptr, |
668 &observer_); | 669 &observer_); |
669 EXPECT_EQ(nullptr, pc); | 670 EXPECT_EQ(nullptr, pc); |
670 } | 671 } |
671 | 672 |
672 void CreatePeerConnectionWithDifferentConfigurations() { | 673 void CreatePeerConnectionWithDifferentConfigurations() { |
673 CreatePeerConnectionWithIceServer(kStunAddressOnly, ""); | 674 CreatePeerConnectionWithIceServer(kStunAddressOnly, ""); |
674 EXPECT_EQ(1u, port_allocator_->stun_servers().size()); | 675 EXPECT_EQ(1u, port_allocator_->stun_servers().size()); |
675 EXPECT_EQ(0u, port_allocator_->turn_servers().size()); | 676 EXPECT_EQ(0u, port_allocator_->turn_servers().size()); |
676 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname()); | 677 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname()); |
(...skipping 15 matching lines...) Expand all Loading... |
692 port_allocator_->turn_servers()[0].ports[0].address.hostname()); | 693 port_allocator_->turn_servers()[0].ports[0].address.hostname()); |
693 } | 694 } |
694 | 695 |
695 void ReleasePeerConnection() { | 696 void ReleasePeerConnection() { |
696 pc_ = NULL; | 697 pc_ = NULL; |
697 observer_.SetPeerConnectionInterface(NULL); | 698 observer_.SetPeerConnectionInterface(NULL); |
698 } | 699 } |
699 | 700 |
700 void AddVideoStream(const std::string& label) { | 701 void AddVideoStream(const std::string& label) { |
701 // Create a local stream. | 702 // Create a local stream. |
702 rtc::scoped_refptr<MediaStreamInterface> stream( | 703 scoped_refptr<MediaStreamInterface> stream( |
703 pc_factory_->CreateLocalMediaStream(label)); | 704 pc_factory_->CreateLocalMediaStream(label)); |
704 rtc::scoped_refptr<VideoTrackSourceInterface> video_source( | 705 scoped_refptr<VideoTrackSourceInterface> video_source( |
705 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL)); | 706 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL)); |
706 rtc::scoped_refptr<VideoTrackInterface> video_track( | 707 scoped_refptr<VideoTrackInterface> video_track( |
707 pc_factory_->CreateVideoTrack(label + "v0", video_source)); | 708 pc_factory_->CreateVideoTrack(label + "v0", video_source)); |
708 stream->AddTrack(video_track.get()); | 709 stream->AddTrack(video_track.get()); |
709 EXPECT_TRUE(pc_->AddStream(stream)); | 710 EXPECT_TRUE(pc_->AddStream(stream)); |
710 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); | 711 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); |
711 observer_.renegotiation_needed_ = false; | 712 observer_.renegotiation_needed_ = false; |
712 } | 713 } |
713 | 714 |
714 void AddVoiceStream(const std::string& label) { | 715 void AddVoiceStream(const std::string& label) { |
715 // Create a local stream. | 716 // Create a local stream. |
716 rtc::scoped_refptr<MediaStreamInterface> stream( | 717 scoped_refptr<MediaStreamInterface> stream( |
717 pc_factory_->CreateLocalMediaStream(label)); | 718 pc_factory_->CreateLocalMediaStream(label)); |
718 rtc::scoped_refptr<AudioTrackInterface> audio_track( | 719 scoped_refptr<AudioTrackInterface> audio_track( |
719 pc_factory_->CreateAudioTrack(label + "a0", NULL)); | 720 pc_factory_->CreateAudioTrack(label + "a0", NULL)); |
720 stream->AddTrack(audio_track.get()); | 721 stream->AddTrack(audio_track.get()); |
721 EXPECT_TRUE(pc_->AddStream(stream)); | 722 EXPECT_TRUE(pc_->AddStream(stream)); |
722 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); | 723 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); |
723 observer_.renegotiation_needed_ = false; | 724 observer_.renegotiation_needed_ = false; |
724 } | 725 } |
725 | 726 |
726 void AddAudioVideoStream(const std::string& stream_label, | 727 void AddAudioVideoStream(const std::string& stream_label, |
727 const std::string& audio_track_label, | 728 const std::string& audio_track_label, |
728 const std::string& video_track_label) { | 729 const std::string& video_track_label) { |
729 // Create a local stream. | 730 // Create a local stream. |
730 rtc::scoped_refptr<MediaStreamInterface> stream( | 731 scoped_refptr<MediaStreamInterface> stream( |
731 pc_factory_->CreateLocalMediaStream(stream_label)); | 732 pc_factory_->CreateLocalMediaStream(stream_label)); |
732 rtc::scoped_refptr<AudioTrackInterface> audio_track( | 733 scoped_refptr<AudioTrackInterface> audio_track( |
733 pc_factory_->CreateAudioTrack( | 734 pc_factory_->CreateAudioTrack( |
734 audio_track_label, static_cast<AudioSourceInterface*>(NULL))); | 735 audio_track_label, static_cast<AudioSourceInterface*>(NULL))); |
735 stream->AddTrack(audio_track.get()); | 736 stream->AddTrack(audio_track.get()); |
736 rtc::scoped_refptr<VideoTrackInterface> video_track( | 737 scoped_refptr<VideoTrackInterface> video_track( |
737 pc_factory_->CreateVideoTrack( | 738 pc_factory_->CreateVideoTrack( |
738 video_track_label, | 739 video_track_label, |
739 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); | 740 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); |
740 stream->AddTrack(video_track.get()); | 741 stream->AddTrack(video_track.get()); |
741 EXPECT_TRUE(pc_->AddStream(stream)); | 742 EXPECT_TRUE(pc_->AddStream(stream)); |
742 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); | 743 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); |
743 observer_.renegotiation_needed_ = false; | 744 observer_.renegotiation_needed_ = false; |
744 } | 745 } |
745 | 746 |
746 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc, | 747 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc, |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 const SessionDescriptionInterface* desc) { | 1035 const SessionDescriptionInterface* desc) { |
1035 const cricket::ContentInfo* audio_content = | 1036 const cricket::ContentInfo* audio_content = |
1036 cricket::GetFirstAudioContent(desc->description()); | 1037 cricket::GetFirstAudioContent(desc->description()); |
1037 const cricket::AudioContentDescription* audio_desc = | 1038 const cricket::AudioContentDescription* audio_desc = |
1038 static_cast<const cricket::AudioContentDescription*>( | 1039 static_cast<const cricket::AudioContentDescription*>( |
1039 audio_content->description); | 1040 audio_content->description); |
1040 return audio_desc->streams()[0].cname; | 1041 return audio_desc->streams()[0].cname; |
1041 } | 1042 } |
1042 | 1043 |
1043 cricket::FakePortAllocator* port_allocator_ = nullptr; | 1044 cricket::FakePortAllocator* port_allocator_ = nullptr; |
1044 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; | 1045 scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; |
1045 rtc::scoped_refptr<PeerConnectionFactoryForTest> pc_factory_for_test_; | 1046 scoped_refptr<PeerConnectionFactoryForTest> pc_factory_for_test_; |
1046 rtc::scoped_refptr<PeerConnectionInterface> pc_; | 1047 scoped_refptr<PeerConnectionInterface> pc_; |
1047 MockPeerConnectionObserver observer_; | 1048 MockPeerConnectionObserver observer_; |
1048 rtc::scoped_refptr<StreamCollection> reference_collection_; | 1049 rtc::scoped_refptr<StreamCollection> reference_collection_; |
1049 }; | 1050 }; |
1050 | 1051 |
1051 // Test that no callbacks on the PeerConnectionObserver are called after the | 1052 // Test that no callbacks on the PeerConnectionObserver are called after the |
1052 // PeerConnection is closed. | 1053 // PeerConnection is closed. |
1053 TEST_F(PeerConnectionInterfaceTest, CloseAndTestCallbackFunctions) { | 1054 TEST_F(PeerConnectionInterfaceTest, CloseAndTestCallbackFunctions) { |
1054 rtc::scoped_refptr<PeerConnectionInterface> pc( | 1055 scoped_refptr<PeerConnectionInterface> pc( |
1055 pc_factory_for_test_->CreatePeerConnection( | 1056 pc_factory_for_test_->CreatePeerConnection( |
1056 PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr, | 1057 PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr, |
1057 nullptr, &observer_)); | 1058 nullptr, &observer_)); |
1058 observer_.SetPeerConnectionInterface(pc.get()); | 1059 observer_.SetPeerConnectionInterface(pc.get()); |
1059 pc->Close(); | 1060 pc->Close(); |
1060 | 1061 |
1061 // No callbacks is expected to be called. | 1062 // No callbacks is expected to be called. |
1062 observer_.callback_triggered = false; | 1063 observer_.callback_triggered = false; |
1063 std::vector<cricket::Candidate> candidates; | 1064 std::vector<cricket::Candidate> candidates; |
1064 pc_factory_for_test_->transport_controller->SignalGatheringState( | 1065 pc_factory_for_test_->transport_controller->SignalGatheringState( |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 EXPECT_TRUE(raw_port_allocator->initialized()); | 1163 EXPECT_TRUE(raw_port_allocator->initialized()); |
1163 } | 1164 } |
1164 | 1165 |
1165 TEST_F(PeerConnectionInterfaceTest, AddStreams) { | 1166 TEST_F(PeerConnectionInterfaceTest, AddStreams) { |
1166 CreatePeerConnection(); | 1167 CreatePeerConnection(); |
1167 AddVideoStream(kStreamLabel1); | 1168 AddVideoStream(kStreamLabel1); |
1168 AddVoiceStream(kStreamLabel2); | 1169 AddVoiceStream(kStreamLabel2); |
1169 ASSERT_EQ(2u, pc_->local_streams()->count()); | 1170 ASSERT_EQ(2u, pc_->local_streams()->count()); |
1170 | 1171 |
1171 // Test we can add multiple local streams to one peerconnection. | 1172 // Test we can add multiple local streams to one peerconnection. |
1172 rtc::scoped_refptr<MediaStreamInterface> stream( | 1173 scoped_refptr<MediaStreamInterface> stream( |
1173 pc_factory_->CreateLocalMediaStream(kStreamLabel3)); | 1174 pc_factory_->CreateLocalMediaStream(kStreamLabel3)); |
1174 rtc::scoped_refptr<AudioTrackInterface> audio_track( | 1175 scoped_refptr<AudioTrackInterface> audio_track( |
1175 pc_factory_->CreateAudioTrack(kStreamLabel3, | 1176 pc_factory_->CreateAudioTrack( |
1176 static_cast<AudioSourceInterface*>(NULL))); | 1177 kStreamLabel3, static_cast<AudioSourceInterface*>(NULL))); |
1177 stream->AddTrack(audio_track.get()); | 1178 stream->AddTrack(audio_track.get()); |
1178 EXPECT_TRUE(pc_->AddStream(stream)); | 1179 EXPECT_TRUE(pc_->AddStream(stream)); |
1179 EXPECT_EQ(3u, pc_->local_streams()->count()); | 1180 EXPECT_EQ(3u, pc_->local_streams()->count()); |
1180 | 1181 |
1181 // Remove the third stream. | 1182 // Remove the third stream. |
1182 pc_->RemoveStream(pc_->local_streams()->at(2)); | 1183 pc_->RemoveStream(pc_->local_streams()->at(2)); |
1183 EXPECT_EQ(2u, pc_->local_streams()->count()); | 1184 EXPECT_EQ(2u, pc_->local_streams()->count()); |
1184 | 1185 |
1185 // Remove the second stream. | 1186 // Remove the second stream. |
1186 pc_->RemoveStream(pc_->local_streams()->at(1)); | 1187 pc_->RemoveStream(pc_->local_streams()->at(1)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 EXPECT_EQ(0u, pc_->local_streams()->count()); | 1245 EXPECT_EQ(0u, pc_->local_streams()->count()); |
1245 } | 1246 } |
1246 | 1247 |
1247 // Test for AddTrack and RemoveTrack methods. | 1248 // Test for AddTrack and RemoveTrack methods. |
1248 // Tests that the created offer includes tracks we added, | 1249 // Tests that the created offer includes tracks we added, |
1249 // and that the RtpSenders are created correctly. | 1250 // and that the RtpSenders are created correctly. |
1250 // Also tests that RemoveTrack removes the tracks from subsequent offers. | 1251 // Also tests that RemoveTrack removes the tracks from subsequent offers. |
1251 TEST_F(PeerConnectionInterfaceTest, AddTrackRemoveTrack) { | 1252 TEST_F(PeerConnectionInterfaceTest, AddTrackRemoveTrack) { |
1252 CreatePeerConnection(); | 1253 CreatePeerConnection(); |
1253 // Create a dummy stream, so tracks share a stream label. | 1254 // Create a dummy stream, so tracks share a stream label. |
1254 rtc::scoped_refptr<MediaStreamInterface> stream( | 1255 scoped_refptr<MediaStreamInterface> stream( |
1255 pc_factory_->CreateLocalMediaStream(kStreamLabel1)); | 1256 pc_factory_->CreateLocalMediaStream(kStreamLabel1)); |
1256 std::vector<MediaStreamInterface*> stream_list; | 1257 std::vector<MediaStreamInterface*> stream_list; |
1257 stream_list.push_back(stream.get()); | 1258 stream_list.push_back(stream.get()); |
1258 rtc::scoped_refptr<AudioTrackInterface> audio_track( | 1259 scoped_refptr<AudioTrackInterface> audio_track( |
1259 pc_factory_->CreateAudioTrack("audio_track", nullptr)); | 1260 pc_factory_->CreateAudioTrack("audio_track", nullptr)); |
1260 rtc::scoped_refptr<VideoTrackInterface> video_track( | 1261 scoped_refptr<VideoTrackInterface> video_track(pc_factory_->CreateVideoTrack( |
1261 pc_factory_->CreateVideoTrack( | 1262 "video_track", |
1262 "video_track", | 1263 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); |
1263 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); | |
1264 auto audio_sender = pc_->AddTrack(audio_track, stream_list); | 1264 auto audio_sender = pc_->AddTrack(audio_track, stream_list); |
1265 auto video_sender = pc_->AddTrack(video_track, stream_list); | 1265 auto video_sender = pc_->AddTrack(video_track, stream_list); |
1266 EXPECT_EQ(1UL, audio_sender->stream_ids().size()); | 1266 EXPECT_EQ(1UL, audio_sender->stream_ids().size()); |
1267 EXPECT_EQ(kStreamLabel1, audio_sender->stream_ids()[0]); | 1267 EXPECT_EQ(kStreamLabel1, audio_sender->stream_ids()[0]); |
1268 EXPECT_EQ("audio_track", audio_sender->id()); | 1268 EXPECT_EQ("audio_track", audio_sender->id()); |
1269 EXPECT_EQ(audio_track, audio_sender->track()); | 1269 EXPECT_EQ(audio_track, audio_sender->track()); |
1270 EXPECT_EQ(1UL, video_sender->stream_ids().size()); | 1270 EXPECT_EQ(1UL, video_sender->stream_ids().size()); |
1271 EXPECT_EQ(kStreamLabel1, video_sender->stream_ids()[0]); | 1271 EXPECT_EQ(kStreamLabel1, video_sender->stream_ids()[0]); |
1272 EXPECT_EQ("video_track", video_sender->id()); | 1272 EXPECT_EQ("video_track", video_sender->id()); |
1273 EXPECT_EQ(video_track, video_sender->track()); | 1273 EXPECT_EQ(video_track, video_sender->track()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1319 // should return false. | 1319 // should return false. |
1320 EXPECT_FALSE(pc_->RemoveTrack(audio_sender)); | 1320 EXPECT_FALSE(pc_->RemoveTrack(audio_sender)); |
1321 EXPECT_FALSE(pc_->RemoveTrack(video_sender)); | 1321 EXPECT_FALSE(pc_->RemoveTrack(video_sender)); |
1322 } | 1322 } |
1323 | 1323 |
1324 // Test creating senders without a stream specified, | 1324 // Test creating senders without a stream specified, |
1325 // expecting a random stream ID to be generated. | 1325 // expecting a random stream ID to be generated. |
1326 TEST_F(PeerConnectionInterfaceTest, AddTrackWithoutStream) { | 1326 TEST_F(PeerConnectionInterfaceTest, AddTrackWithoutStream) { |
1327 CreatePeerConnection(); | 1327 CreatePeerConnection(); |
1328 // Create a dummy stream, so tracks share a stream label. | 1328 // Create a dummy stream, so tracks share a stream label. |
1329 rtc::scoped_refptr<AudioTrackInterface> audio_track( | 1329 scoped_refptr<AudioTrackInterface> audio_track( |
1330 pc_factory_->CreateAudioTrack("audio_track", nullptr)); | 1330 pc_factory_->CreateAudioTrack("audio_track", nullptr)); |
1331 rtc::scoped_refptr<VideoTrackInterface> video_track( | 1331 scoped_refptr<VideoTrackInterface> video_track(pc_factory_->CreateVideoTrack( |
1332 pc_factory_->CreateVideoTrack( | 1332 "video_track", |
1333 "video_track", | 1333 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); |
1334 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); | |
1335 auto audio_sender = | 1334 auto audio_sender = |
1336 pc_->AddTrack(audio_track, std::vector<MediaStreamInterface*>()); | 1335 pc_->AddTrack(audio_track, std::vector<MediaStreamInterface*>()); |
1337 auto video_sender = | 1336 auto video_sender = |
1338 pc_->AddTrack(video_track, std::vector<MediaStreamInterface*>()); | 1337 pc_->AddTrack(video_track, std::vector<MediaStreamInterface*>()); |
1339 EXPECT_EQ("audio_track", audio_sender->id()); | 1338 EXPECT_EQ("audio_track", audio_sender->id()); |
1340 EXPECT_EQ(audio_track, audio_sender->track()); | 1339 EXPECT_EQ(audio_track, audio_sender->track()); |
1341 EXPECT_EQ("video_track", video_sender->id()); | 1340 EXPECT_EQ("video_track", video_sender->id()); |
1342 EXPECT_EQ(video_track, video_sender->track()); | 1341 EXPECT_EQ(video_track, video_sender->track()); |
1343 // If the ID is truly a random GUID, it should be infinitely unlikely they | 1342 // If the ID is truly a random GUID, it should be infinitely unlikely they |
1344 // will be the same. | 1343 // will be the same. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 // Test that it's possible to call AddTrack on a MediaStream after adding | 1482 // Test that it's possible to call AddTrack on a MediaStream after adding |
1484 // the stream to a PeerConnection. | 1483 // the stream to a PeerConnection. |
1485 // TODO(deadbeef): Remove this test once this behavior is no longer supported. | 1484 // TODO(deadbeef): Remove this test once this behavior is no longer supported. |
1486 TEST_F(PeerConnectionInterfaceTest, AddTrackAfterAddStream) { | 1485 TEST_F(PeerConnectionInterfaceTest, AddTrackAfterAddStream) { |
1487 CreatePeerConnection(); | 1486 CreatePeerConnection(); |
1488 // Create audio stream and add to PeerConnection. | 1487 // Create audio stream and add to PeerConnection. |
1489 AddVoiceStream(kStreamLabel1); | 1488 AddVoiceStream(kStreamLabel1); |
1490 MediaStreamInterface* stream = pc_->local_streams()->at(0); | 1489 MediaStreamInterface* stream = pc_->local_streams()->at(0); |
1491 | 1490 |
1492 // Add video track to the audio-only stream. | 1491 // Add video track to the audio-only stream. |
1493 rtc::scoped_refptr<VideoTrackInterface> video_track( | 1492 scoped_refptr<VideoTrackInterface> video_track(pc_factory_->CreateVideoTrack( |
1494 pc_factory_->CreateVideoTrack( | 1493 "video_label", |
1495 "video_label", | 1494 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); |
1496 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer()))); | |
1497 stream->AddTrack(video_track.get()); | 1495 stream->AddTrack(video_track.get()); |
1498 | 1496 |
1499 std::unique_ptr<SessionDescriptionInterface> offer; | 1497 std::unique_ptr<SessionDescriptionInterface> offer; |
1500 ASSERT_TRUE(DoCreateOffer(&offer, nullptr)); | 1498 ASSERT_TRUE(DoCreateOffer(&offer, nullptr)); |
1501 | 1499 |
1502 const cricket::MediaContentDescription* video_desc = | 1500 const cricket::MediaContentDescription* video_desc = |
1503 cricket::GetFirstVideoContentDescription(offer->description()); | 1501 cricket::GetFirstVideoContentDescription(offer->description()); |
1504 EXPECT_TRUE(video_desc != nullptr); | 1502 EXPECT_TRUE(video_desc != nullptr); |
1505 } | 1503 } |
1506 | 1504 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 ASSERT_TRUE(video_desc != nullptr); | 1536 ASSERT_TRUE(video_desc != nullptr); |
1539 ASSERT_EQ(1u, video_desc->streams().size()); | 1537 ASSERT_EQ(1u, video_desc->streams().size()); |
1540 EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label); | 1538 EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label); |
1541 } | 1539 } |
1542 | 1540 |
1543 // Test that we can specify a certain track that we want statistics about. | 1541 // Test that we can specify a certain track that we want statistics about. |
1544 TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) { | 1542 TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) { |
1545 InitiateCall(); | 1543 InitiateCall(); |
1546 ASSERT_LT(0u, pc_->remote_streams()->count()); | 1544 ASSERT_LT(0u, pc_->remote_streams()->count()); |
1547 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size()); | 1545 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size()); |
1548 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio = | 1546 scoped_refptr<MediaStreamTrackInterface> remote_audio = |
1549 pc_->remote_streams()->at(0)->GetAudioTracks()[0]; | 1547 pc_->remote_streams()->at(0)->GetAudioTracks()[0]; |
1550 EXPECT_TRUE(DoGetStats(remote_audio)); | 1548 EXPECT_TRUE(DoGetStats(remote_audio)); |
1551 | 1549 |
1552 // Remove the stream. Since we are sending to our selves the local | 1550 // Remove the stream. Since we are sending to our selves the local |
1553 // and the remote stream is the same. | 1551 // and the remote stream is the same. |
1554 pc_->RemoveStream(pc_->local_streams()->at(0)); | 1552 pc_->RemoveStream(pc_->local_streams()->at(0)); |
1555 // Do a re-negotiation. | 1553 // Do a re-negotiation. |
1556 CreateOfferReceiveAnswer(); | 1554 CreateOfferReceiveAnswer(); |
1557 | 1555 |
1558 ASSERT_EQ(0u, pc_->remote_streams()->count()); | 1556 ASSERT_EQ(0u, pc_->remote_streams()->count()); |
1559 | 1557 |
1560 // Test that we still can get statistics for the old track. Even if it is not | 1558 // Test that we still can get statistics for the old track. Even if it is not |
1561 // sent any longer. | 1559 // sent any longer. |
1562 EXPECT_TRUE(DoGetStats(remote_audio)); | 1560 EXPECT_TRUE(DoGetStats(remote_audio)); |
1563 } | 1561 } |
1564 | 1562 |
1565 // Test that we can get stats on a video track. | 1563 // Test that we can get stats on a video track. |
1566 TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) { | 1564 TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) { |
1567 InitiateCall(); | 1565 InitiateCall(); |
1568 ASSERT_LT(0u, pc_->remote_streams()->count()); | 1566 ASSERT_LT(0u, pc_->remote_streams()->count()); |
1569 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size()); | 1567 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size()); |
1570 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video = | 1568 scoped_refptr<MediaStreamTrackInterface> remote_video = |
1571 pc_->remote_streams()->at(0)->GetVideoTracks()[0]; | 1569 pc_->remote_streams()->at(0)->GetVideoTracks()[0]; |
1572 EXPECT_TRUE(DoGetStats(remote_video)); | 1570 EXPECT_TRUE(DoGetStats(remote_video)); |
1573 } | 1571 } |
1574 | 1572 |
1575 // Test that we don't get statistics for an invalid track. | 1573 // Test that we don't get statistics for an invalid track. |
1576 // TODO(tommi): Fix this test. DoGetStats will return true | 1574 // TODO(tommi): Fix this test. DoGetStats will return true |
1577 // for the unknown track (since GetStats is async), but no | 1575 // for the unknown track (since GetStats is async), but no |
1578 // data is returned for the track. | 1576 // data is returned for the track. |
1579 TEST_F(PeerConnectionInterfaceTest, DISABLED_GetStatsForInvalidTrack) { | 1577 TEST_F(PeerConnectionInterfaceTest, DISABLED_GetStatsForInvalidTrack) { |
1580 InitiateCall(); | 1578 InitiateCall(); |
1581 rtc::scoped_refptr<AudioTrackInterface> unknown_audio_track( | 1579 scoped_refptr<AudioTrackInterface> unknown_audio_track( |
1582 pc_factory_->CreateAudioTrack("unknown track", NULL)); | 1580 pc_factory_->CreateAudioTrack("unknown track", NULL)); |
1583 EXPECT_FALSE(DoGetStats(unknown_audio_track)); | 1581 EXPECT_FALSE(DoGetStats(unknown_audio_track)); |
1584 } | 1582 } |
1585 | 1583 |
1586 // This test setup two RTP data channels in loop back. | 1584 // This test setup two RTP data channels in loop back. |
1587 TEST_F(PeerConnectionInterfaceTest, TestDataChannel) { | 1585 TEST_F(PeerConnectionInterfaceTest, TestDataChannel) { |
1588 FakeConstraints constraints; | 1586 FakeConstraints constraints; |
1589 constraints.SetAllowRtpDataChannels(); | 1587 constraints.SetAllowRtpDataChannels(); |
1590 CreatePeerConnection(&constraints); | 1588 CreatePeerConnection(&constraints); |
1591 rtc::scoped_refptr<DataChannelInterface> data1 = | 1589 scoped_refptr<DataChannelInterface> data1 = |
1592 pc_->CreateDataChannel("test1", NULL); | 1590 pc_->CreateDataChannel("test1", NULL); |
1593 rtc::scoped_refptr<DataChannelInterface> data2 = | 1591 scoped_refptr<DataChannelInterface> data2 = |
1594 pc_->CreateDataChannel("test2", NULL); | 1592 pc_->CreateDataChannel("test2", NULL); |
1595 ASSERT_TRUE(data1 != NULL); | 1593 ASSERT_TRUE(data1 != NULL); |
1596 std::unique_ptr<MockDataChannelObserver> observer1( | 1594 std::unique_ptr<MockDataChannelObserver> observer1( |
1597 new MockDataChannelObserver(data1)); | 1595 new MockDataChannelObserver(data1)); |
1598 std::unique_ptr<MockDataChannelObserver> observer2( | 1596 std::unique_ptr<MockDataChannelObserver> observer2( |
1599 new MockDataChannelObserver(data2)); | 1597 new MockDataChannelObserver(data2)); |
1600 | 1598 |
1601 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); | 1599 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); |
1602 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); | 1600 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); |
1603 std::string data_to_send1 = "testing testing"; | 1601 std::string data_to_send1 = "testing testing"; |
(...skipping 24 matching lines...) Expand all Loading... |
1628 | 1626 |
1629 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); | 1627 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); |
1630 } | 1628 } |
1631 | 1629 |
1632 // This test verifies that sendnig binary data over RTP data channels should | 1630 // This test verifies that sendnig binary data over RTP data channels should |
1633 // fail. | 1631 // fail. |
1634 TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) { | 1632 TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) { |
1635 FakeConstraints constraints; | 1633 FakeConstraints constraints; |
1636 constraints.SetAllowRtpDataChannels(); | 1634 constraints.SetAllowRtpDataChannels(); |
1637 CreatePeerConnection(&constraints); | 1635 CreatePeerConnection(&constraints); |
1638 rtc::scoped_refptr<DataChannelInterface> data1 = | 1636 scoped_refptr<DataChannelInterface> data1 = |
1639 pc_->CreateDataChannel("test1", NULL); | 1637 pc_->CreateDataChannel("test1", NULL); |
1640 rtc::scoped_refptr<DataChannelInterface> data2 = | 1638 scoped_refptr<DataChannelInterface> data2 = |
1641 pc_->CreateDataChannel("test2", NULL); | 1639 pc_->CreateDataChannel("test2", NULL); |
1642 ASSERT_TRUE(data1 != NULL); | 1640 ASSERT_TRUE(data1 != NULL); |
1643 std::unique_ptr<MockDataChannelObserver> observer1( | 1641 std::unique_ptr<MockDataChannelObserver> observer1( |
1644 new MockDataChannelObserver(data1)); | 1642 new MockDataChannelObserver(data1)); |
1645 std::unique_ptr<MockDataChannelObserver> observer2( | 1643 std::unique_ptr<MockDataChannelObserver> observer2( |
1646 new MockDataChannelObserver(data2)); | 1644 new MockDataChannelObserver(data2)); |
1647 | 1645 |
1648 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); | 1646 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); |
1649 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); | 1647 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); |
1650 | 1648 |
1651 CreateOfferReceiveAnswer(); | 1649 CreateOfferReceiveAnswer(); |
1652 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); | 1650 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); |
1653 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); | 1651 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); |
1654 | 1652 |
1655 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); | 1653 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); |
1656 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); | 1654 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); |
1657 | 1655 |
1658 rtc::CopyOnWriteBuffer buffer("test", 4); | 1656 rtc::CopyOnWriteBuffer buffer("test", 4); |
1659 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true))); | 1657 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true))); |
1660 } | 1658 } |
1661 | 1659 |
1662 // This test setup a RTP data channels in loop back and test that a channel is | 1660 // This test setup a RTP data channels in loop back and test that a channel is |
1663 // opened even if the remote end answer with a zero SSRC. | 1661 // opened even if the remote end answer with a zero SSRC. |
1664 TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) { | 1662 TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) { |
1665 FakeConstraints constraints; | 1663 FakeConstraints constraints; |
1666 constraints.SetAllowRtpDataChannels(); | 1664 constraints.SetAllowRtpDataChannels(); |
1667 CreatePeerConnection(&constraints); | 1665 CreatePeerConnection(&constraints); |
1668 rtc::scoped_refptr<DataChannelInterface> data1 = | 1666 scoped_refptr<DataChannelInterface> data1 = |
1669 pc_->CreateDataChannel("test1", NULL); | 1667 pc_->CreateDataChannel("test1", NULL); |
1670 std::unique_ptr<MockDataChannelObserver> observer1( | 1668 std::unique_ptr<MockDataChannelObserver> observer1( |
1671 new MockDataChannelObserver(data1)); | 1669 new MockDataChannelObserver(data1)); |
1672 | 1670 |
1673 CreateOfferReceiveAnswerWithoutSsrc(); | 1671 CreateOfferReceiveAnswerWithoutSsrc(); |
1674 | 1672 |
1675 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); | 1673 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); |
1676 | 1674 |
1677 data1->Close(); | 1675 data1->Close(); |
1678 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); | 1676 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); |
1679 CreateOfferReceiveAnswerWithoutSsrc(); | 1677 CreateOfferReceiveAnswerWithoutSsrc(); |
1680 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); | 1678 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); |
1681 EXPECT_FALSE(observer1->IsOpen()); | 1679 EXPECT_FALSE(observer1->IsOpen()); |
1682 } | 1680 } |
1683 | 1681 |
1684 // This test that if a data channel is added in an answer a receive only channel | 1682 // This test that if a data channel is added in an answer a receive only channel |
1685 // channel is created. | 1683 // channel is created. |
1686 TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) { | 1684 TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) { |
1687 FakeConstraints constraints; | 1685 FakeConstraints constraints; |
1688 constraints.SetAllowRtpDataChannels(); | 1686 constraints.SetAllowRtpDataChannels(); |
1689 CreatePeerConnection(&constraints); | 1687 CreatePeerConnection(&constraints); |
1690 | 1688 |
1691 std::string offer_label = "offer_channel"; | 1689 std::string offer_label = "offer_channel"; |
1692 rtc::scoped_refptr<DataChannelInterface> offer_channel = | 1690 scoped_refptr<DataChannelInterface> offer_channel = |
1693 pc_->CreateDataChannel(offer_label, NULL); | 1691 pc_->CreateDataChannel(offer_label, NULL); |
1694 | 1692 |
1695 CreateOfferAsLocalDescription(); | 1693 CreateOfferAsLocalDescription(); |
1696 | 1694 |
1697 // Replace the data channel label in the offer and apply it as an answer. | 1695 // Replace the data channel label in the offer and apply it as an answer. |
1698 std::string receive_label = "answer_channel"; | 1696 std::string receive_label = "answer_channel"; |
1699 std::string sdp; | 1697 std::string sdp; |
1700 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); | 1698 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); |
1701 rtc::replace_substrs(offer_label.c_str(), offer_label.length(), | 1699 rtc::replace_substrs(offer_label.c_str(), offer_label.length(), |
1702 receive_label.c_str(), receive_label.length(), | 1700 receive_label.c_str(), receive_label.length(), |
(...skipping 22 matching lines...) Expand all Loading... |
1725 // requested. | 1723 // requested. |
1726 // TODO(perkj): Remove this test once reliable channels are implemented. | 1724 // TODO(perkj): Remove this test once reliable channels are implemented. |
1727 TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) { | 1725 TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) { |
1728 FakeConstraints constraints; | 1726 FakeConstraints constraints; |
1729 constraints.SetAllowRtpDataChannels(); | 1727 constraints.SetAllowRtpDataChannels(); |
1730 CreatePeerConnection(&constraints); | 1728 CreatePeerConnection(&constraints); |
1731 | 1729 |
1732 std::string label = "test"; | 1730 std::string label = "test"; |
1733 webrtc::DataChannelInit config; | 1731 webrtc::DataChannelInit config; |
1734 config.reliable = true; | 1732 config.reliable = true; |
1735 rtc::scoped_refptr<DataChannelInterface> channel = | 1733 scoped_refptr<DataChannelInterface> channel = |
1736 pc_->CreateDataChannel(label, &config); | 1734 pc_->CreateDataChannel(label, &config); |
1737 EXPECT_TRUE(channel == NULL); | 1735 EXPECT_TRUE(channel == NULL); |
1738 } | 1736 } |
1739 | 1737 |
1740 // Verifies that duplicated label is not allowed for RTP data channel. | 1738 // Verifies that duplicated label is not allowed for RTP data channel. |
1741 TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) { | 1739 TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) { |
1742 FakeConstraints constraints; | 1740 FakeConstraints constraints; |
1743 constraints.SetAllowRtpDataChannels(); | 1741 constraints.SetAllowRtpDataChannels(); |
1744 CreatePeerConnection(&constraints); | 1742 CreatePeerConnection(&constraints); |
1745 | 1743 |
1746 std::string label = "test"; | 1744 std::string label = "test"; |
1747 rtc::scoped_refptr<DataChannelInterface> channel = | 1745 scoped_refptr<DataChannelInterface> channel = |
1748 pc_->CreateDataChannel(label, nullptr); | 1746 pc_->CreateDataChannel(label, nullptr); |
1749 EXPECT_NE(channel, nullptr); | 1747 EXPECT_NE(channel, nullptr); |
1750 | 1748 |
1751 rtc::scoped_refptr<DataChannelInterface> dup_channel = | 1749 scoped_refptr<DataChannelInterface> dup_channel = |
1752 pc_->CreateDataChannel(label, nullptr); | 1750 pc_->CreateDataChannel(label, nullptr); |
1753 EXPECT_EQ(dup_channel, nullptr); | 1751 EXPECT_EQ(dup_channel, nullptr); |
1754 } | 1752 } |
1755 | 1753 |
1756 // This tests that a SCTP data channel is returned using different | 1754 // This tests that a SCTP data channel is returned using different |
1757 // DataChannelInit configurations. | 1755 // DataChannelInit configurations. |
1758 TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) { | 1756 TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) { |
1759 FakeConstraints constraints; | 1757 FakeConstraints constraints; |
1760 constraints.SetAllowDtlsSctpDataChannels(); | 1758 constraints.SetAllowDtlsSctpDataChannels(); |
1761 CreatePeerConnection(&constraints); | 1759 CreatePeerConnection(&constraints); |
1762 | 1760 |
1763 webrtc::DataChannelInit config; | 1761 webrtc::DataChannelInit config; |
1764 | 1762 |
1765 rtc::scoped_refptr<DataChannelInterface> channel = | 1763 scoped_refptr<DataChannelInterface> channel = |
1766 pc_->CreateDataChannel("1", &config); | 1764 pc_->CreateDataChannel("1", &config); |
1767 EXPECT_TRUE(channel != NULL); | 1765 EXPECT_TRUE(channel != NULL); |
1768 EXPECT_TRUE(channel->reliable()); | 1766 EXPECT_TRUE(channel->reliable()); |
1769 EXPECT_TRUE(observer_.renegotiation_needed_); | 1767 EXPECT_TRUE(observer_.renegotiation_needed_); |
1770 observer_.renegotiation_needed_ = false; | 1768 observer_.renegotiation_needed_ = false; |
1771 | 1769 |
1772 config.ordered = false; | 1770 config.ordered = false; |
1773 channel = pc_->CreateDataChannel("2", &config); | 1771 channel = pc_->CreateDataChannel("2", &config); |
1774 EXPECT_TRUE(channel != NULL); | 1772 EXPECT_TRUE(channel != NULL); |
1775 EXPECT_TRUE(channel->reliable()); | 1773 EXPECT_TRUE(channel->reliable()); |
(...skipping 20 matching lines...) Expand all Loading... |
1796 CreateSctpDataChannelShouldFailForInvalidConfig) { | 1794 CreateSctpDataChannelShouldFailForInvalidConfig) { |
1797 FakeConstraints constraints; | 1795 FakeConstraints constraints; |
1798 constraints.SetAllowDtlsSctpDataChannels(); | 1796 constraints.SetAllowDtlsSctpDataChannels(); |
1799 CreatePeerConnection(&constraints); | 1797 CreatePeerConnection(&constraints); |
1800 | 1798 |
1801 std::string label = "test"; | 1799 std::string label = "test"; |
1802 webrtc::DataChannelInit config; | 1800 webrtc::DataChannelInit config; |
1803 config.maxRetransmits = 0; | 1801 config.maxRetransmits = 0; |
1804 config.maxRetransmitTime = 0; | 1802 config.maxRetransmitTime = 0; |
1805 | 1803 |
1806 rtc::scoped_refptr<DataChannelInterface> channel = | 1804 scoped_refptr<DataChannelInterface> channel = |
1807 pc_->CreateDataChannel(label, &config); | 1805 pc_->CreateDataChannel(label, &config); |
1808 EXPECT_TRUE(channel == NULL); | 1806 EXPECT_TRUE(channel == NULL); |
1809 } | 1807 } |
1810 | 1808 |
1811 // The test verifies that creating a SCTP data channel with an id already in use | 1809 // The test verifies that creating a SCTP data channel with an id already in use |
1812 // or out of range should fail. | 1810 // or out of range should fail. |
1813 TEST_F(PeerConnectionInterfaceTest, | 1811 TEST_F(PeerConnectionInterfaceTest, |
1814 CreateSctpDataChannelWithInvalidIdShouldFail) { | 1812 CreateSctpDataChannelWithInvalidIdShouldFail) { |
1815 FakeConstraints constraints; | 1813 FakeConstraints constraints; |
1816 constraints.SetAllowDtlsSctpDataChannels(); | 1814 constraints.SetAllowDtlsSctpDataChannels(); |
1817 CreatePeerConnection(&constraints); | 1815 CreatePeerConnection(&constraints); |
1818 | 1816 |
1819 webrtc::DataChannelInit config; | 1817 webrtc::DataChannelInit config; |
1820 rtc::scoped_refptr<DataChannelInterface> channel; | 1818 scoped_refptr<DataChannelInterface> channel; |
1821 | 1819 |
1822 config.id = 1; | 1820 config.id = 1; |
1823 channel = pc_->CreateDataChannel("1", &config); | 1821 channel = pc_->CreateDataChannel("1", &config); |
1824 EXPECT_TRUE(channel != NULL); | 1822 EXPECT_TRUE(channel != NULL); |
1825 EXPECT_EQ(1, channel->id()); | 1823 EXPECT_EQ(1, channel->id()); |
1826 | 1824 |
1827 channel = pc_->CreateDataChannel("x", &config); | 1825 channel = pc_->CreateDataChannel("x", &config); |
1828 EXPECT_TRUE(channel == NULL); | 1826 EXPECT_TRUE(channel == NULL); |
1829 | 1827 |
1830 config.id = cricket::kMaxSctpSid; | 1828 config.id = cricket::kMaxSctpSid; |
1831 channel = pc_->CreateDataChannel("max", &config); | 1829 channel = pc_->CreateDataChannel("max", &config); |
1832 EXPECT_TRUE(channel != NULL); | 1830 EXPECT_TRUE(channel != NULL); |
1833 EXPECT_EQ(config.id, channel->id()); | 1831 EXPECT_EQ(config.id, channel->id()); |
1834 | 1832 |
1835 config.id = cricket::kMaxSctpSid + 1; | 1833 config.id = cricket::kMaxSctpSid + 1; |
1836 channel = pc_->CreateDataChannel("x", &config); | 1834 channel = pc_->CreateDataChannel("x", &config); |
1837 EXPECT_TRUE(channel == NULL); | 1835 EXPECT_TRUE(channel == NULL); |
1838 } | 1836 } |
1839 | 1837 |
1840 // Verifies that duplicated label is allowed for SCTP data channel. | 1838 // Verifies that duplicated label is allowed for SCTP data channel. |
1841 TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) { | 1839 TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) { |
1842 FakeConstraints constraints; | 1840 FakeConstraints constraints; |
1843 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | 1841 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
1844 true); | 1842 true); |
1845 CreatePeerConnection(&constraints); | 1843 CreatePeerConnection(&constraints); |
1846 | 1844 |
1847 std::string label = "test"; | 1845 std::string label = "test"; |
1848 rtc::scoped_refptr<DataChannelInterface> channel = | 1846 scoped_refptr<DataChannelInterface> channel = |
1849 pc_->CreateDataChannel(label, nullptr); | 1847 pc_->CreateDataChannel(label, nullptr); |
1850 EXPECT_NE(channel, nullptr); | 1848 EXPECT_NE(channel, nullptr); |
1851 | 1849 |
1852 rtc::scoped_refptr<DataChannelInterface> dup_channel = | 1850 scoped_refptr<DataChannelInterface> dup_channel = |
1853 pc_->CreateDataChannel(label, nullptr); | 1851 pc_->CreateDataChannel(label, nullptr); |
1854 EXPECT_NE(dup_channel, nullptr); | 1852 EXPECT_NE(dup_channel, nullptr); |
1855 } | 1853 } |
1856 | 1854 |
1857 // This test verifies that OnRenegotiationNeeded is fired for every new RTP | 1855 // This test verifies that OnRenegotiationNeeded is fired for every new RTP |
1858 // DataChannel. | 1856 // DataChannel. |
1859 TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) { | 1857 TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) { |
1860 FakeConstraints constraints; | 1858 FakeConstraints constraints; |
1861 constraints.SetAllowRtpDataChannels(); | 1859 constraints.SetAllowRtpDataChannels(); |
1862 CreatePeerConnection(&constraints); | 1860 CreatePeerConnection(&constraints); |
1863 | 1861 |
1864 rtc::scoped_refptr<DataChannelInterface> dc1 = | 1862 scoped_refptr<DataChannelInterface> dc1 = |
1865 pc_->CreateDataChannel("test1", NULL); | 1863 pc_->CreateDataChannel("test1", NULL); |
1866 EXPECT_TRUE(observer_.renegotiation_needed_); | 1864 EXPECT_TRUE(observer_.renegotiation_needed_); |
1867 observer_.renegotiation_needed_ = false; | 1865 observer_.renegotiation_needed_ = false; |
1868 | 1866 |
1869 rtc::scoped_refptr<DataChannelInterface> dc2 = | 1867 scoped_refptr<DataChannelInterface> dc2 = |
1870 pc_->CreateDataChannel("test2", NULL); | 1868 pc_->CreateDataChannel("test2", NULL); |
1871 EXPECT_TRUE(observer_.renegotiation_needed_); | 1869 EXPECT_TRUE(observer_.renegotiation_needed_); |
1872 } | 1870 } |
1873 | 1871 |
1874 // This test that a data channel closes when a PeerConnection is deleted/closed. | 1872 // This test that a data channel closes when a PeerConnection is deleted/closed. |
1875 TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) { | 1873 TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) { |
1876 FakeConstraints constraints; | 1874 FakeConstraints constraints; |
1877 constraints.SetAllowRtpDataChannels(); | 1875 constraints.SetAllowRtpDataChannels(); |
1878 CreatePeerConnection(&constraints); | 1876 CreatePeerConnection(&constraints); |
1879 | 1877 |
1880 rtc::scoped_refptr<DataChannelInterface> data1 = | 1878 scoped_refptr<DataChannelInterface> data1 = |
1881 pc_->CreateDataChannel("test1", NULL); | 1879 pc_->CreateDataChannel("test1", NULL); |
1882 rtc::scoped_refptr<DataChannelInterface> data2 = | 1880 scoped_refptr<DataChannelInterface> data2 = |
1883 pc_->CreateDataChannel("test2", NULL); | 1881 pc_->CreateDataChannel("test2", NULL); |
1884 ASSERT_TRUE(data1 != NULL); | 1882 ASSERT_TRUE(data1 != NULL); |
1885 std::unique_ptr<MockDataChannelObserver> observer1( | 1883 std::unique_ptr<MockDataChannelObserver> observer1( |
1886 new MockDataChannelObserver(data1)); | 1884 new MockDataChannelObserver(data1)); |
1887 std::unique_ptr<MockDataChannelObserver> observer2( | 1885 std::unique_ptr<MockDataChannelObserver> observer2( |
1888 new MockDataChannelObserver(data2)); | 1886 new MockDataChannelObserver(data2)); |
1889 | 1887 |
1890 CreateOfferReceiveAnswer(); | 1888 CreateOfferReceiveAnswer(); |
1891 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); | 1889 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); |
1892 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); | 1890 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); |
1893 | 1891 |
1894 ReleasePeerConnection(); | 1892 ReleasePeerConnection(); |
1895 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); | 1893 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); |
1896 EXPECT_EQ(DataChannelInterface::kClosed, data2->state()); | 1894 EXPECT_EQ(DataChannelInterface::kClosed, data2->state()); |
1897 } | 1895 } |
1898 | 1896 |
1899 // This test that data channels can be rejected in an answer. | 1897 // This test that data channels can be rejected in an answer. |
1900 TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) { | 1898 TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) { |
1901 FakeConstraints constraints; | 1899 FakeConstraints constraints; |
1902 constraints.SetAllowRtpDataChannels(); | 1900 constraints.SetAllowRtpDataChannels(); |
1903 CreatePeerConnection(&constraints); | 1901 CreatePeerConnection(&constraints); |
1904 | 1902 |
1905 rtc::scoped_refptr<DataChannelInterface> offer_channel( | 1903 scoped_refptr<DataChannelInterface> offer_channel( |
1906 pc_->CreateDataChannel("offer_channel", NULL)); | 1904 pc_->CreateDataChannel("offer_channel", NULL)); |
1907 | 1905 |
1908 CreateOfferAsLocalDescription(); | 1906 CreateOfferAsLocalDescription(); |
1909 | 1907 |
1910 // Create an answer where the m-line for data channels are rejected. | 1908 // Create an answer where the m-line for data channels are rejected. |
1911 std::string sdp; | 1909 std::string sdp; |
1912 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); | 1910 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); |
1913 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( | 1911 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( |
1914 SessionDescriptionInterface::kAnswer); | 1912 SessionDescriptionInterface::kAnswer); |
1915 EXPECT_TRUE(answer->Initialize(sdp, NULL)); | 1913 EXPECT_TRUE(answer->Initialize(sdp, NULL)); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2101 | 2099 |
2102 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state()); | 2100 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state()); |
2103 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed, | 2101 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed, |
2104 pc_->ice_connection_state()); | 2102 pc_->ice_connection_state()); |
2105 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, | 2103 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, |
2106 pc_->ice_gathering_state()); | 2104 pc_->ice_gathering_state()); |
2107 | 2105 |
2108 EXPECT_EQ(1u, pc_->local_streams()->count()); | 2106 EXPECT_EQ(1u, pc_->local_streams()->count()); |
2109 EXPECT_EQ(1u, pc_->remote_streams()->count()); | 2107 EXPECT_EQ(1u, pc_->remote_streams()->count()); |
2110 | 2108 |
2111 rtc::scoped_refptr<MediaStreamInterface> remote_stream = | 2109 scoped_refptr<MediaStreamInterface> remote_stream = |
2112 pc_->remote_streams()->at(0); | 2110 pc_->remote_streams()->at(0); |
2113 // Track state may be updated asynchronously. | 2111 // Track state may be updated asynchronously. |
2114 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, | 2112 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, |
2115 remote_stream->GetAudioTracks()[0]->state(), kTimeout); | 2113 remote_stream->GetAudioTracks()[0]->state(), kTimeout); |
2116 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, | 2114 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, |
2117 remote_stream->GetVideoTracks()[0]->state(), kTimeout); | 2115 remote_stream->GetVideoTracks()[0]->state(), kTimeout); |
2118 } | 2116 } |
2119 | 2117 |
2120 // Test that PeerConnection methods fails gracefully after | 2118 // Test that PeerConnection methods fails gracefully after |
2121 // PeerConnection::Close has been called. | 2119 // PeerConnection::Close has been called. |
2122 TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) { | 2120 TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) { |
2123 CreatePeerConnection(); | 2121 CreatePeerConnection(); |
2124 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); | 2122 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); |
2125 CreateOfferAsRemoteDescription(); | 2123 CreateOfferAsRemoteDescription(); |
2126 CreateAnswerAsLocalDescription(); | 2124 CreateAnswerAsLocalDescription(); |
2127 | 2125 |
2128 ASSERT_EQ(1u, pc_->local_streams()->count()); | 2126 ASSERT_EQ(1u, pc_->local_streams()->count()); |
2129 rtc::scoped_refptr<MediaStreamInterface> local_stream = | 2127 scoped_refptr<MediaStreamInterface> local_stream = |
2130 pc_->local_streams()->at(0); | 2128 pc_->local_streams()->at(0); |
2131 | 2129 |
2132 pc_->Close(); | 2130 pc_->Close(); |
2133 | 2131 |
2134 pc_->RemoveStream(local_stream); | 2132 pc_->RemoveStream(local_stream); |
2135 EXPECT_FALSE(pc_->AddStream(local_stream)); | 2133 EXPECT_FALSE(pc_->AddStream(local_stream)); |
2136 | 2134 |
2137 ASSERT_FALSE(local_stream->GetAudioTracks().empty()); | 2135 ASSERT_FALSE(local_stream->GetAudioTracks().empty()); |
2138 rtc::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender( | 2136 rtc::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender( |
2139 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0])); | 2137 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0])); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2212 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release())); | 2210 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release())); |
2213 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), | 2211 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), |
2214 reference_collection_)); | 2212 reference_collection_)); |
2215 | 2213 |
2216 // Add extra audio and video tracks to the same MediaStream. | 2214 // Add extra audio and video tracks to the same MediaStream. |
2217 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks = | 2215 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks = |
2218 CreateSessionDescriptionAndReference(2, 2); | 2216 CreateSessionDescriptionAndReference(2, 2); |
2219 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release())); | 2217 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release())); |
2220 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), | 2218 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), |
2221 reference_collection_)); | 2219 reference_collection_)); |
2222 rtc::scoped_refptr<AudioTrackInterface> audio_track2 = | 2220 scoped_refptr<AudioTrackInterface> audio_track2 = |
2223 observer_.remote_streams()->at(0)->GetAudioTracks()[1]; | 2221 observer_.remote_streams()->at(0)->GetAudioTracks()[1]; |
2224 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state()); | 2222 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state()); |
2225 rtc::scoped_refptr<VideoTrackInterface> video_track2 = | 2223 scoped_refptr<VideoTrackInterface> video_track2 = |
2226 observer_.remote_streams()->at(0)->GetVideoTracks()[1]; | 2224 observer_.remote_streams()->at(0)->GetVideoTracks()[1]; |
2227 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state()); | 2225 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state()); |
2228 | 2226 |
2229 // Remove the extra audio and video tracks. | 2227 // Remove the extra audio and video tracks. |
2230 std::unique_ptr<SessionDescriptionInterface> desc_ms2 = | 2228 std::unique_ptr<SessionDescriptionInterface> desc_ms2 = |
2231 CreateSessionDescriptionAndReference(1, 1); | 2229 CreateSessionDescriptionAndReference(1, 1); |
2232 MockTrackObserver audio_track_observer(audio_track2); | 2230 MockTrackObserver audio_track_observer(audio_track2); |
2233 MockTrackObserver video_track_observer(video_track2); | 2231 MockTrackObserver video_track_observer(video_track2); |
2234 | 2232 |
2235 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1)); | 2233 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1)); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 protected: | 2634 protected: |
2637 void SetUp() override { | 2635 void SetUp() override { |
2638 pcf_ = new rtc::RefCountedObject<PeerConnectionFactoryForTest>(); | 2636 pcf_ = new rtc::RefCountedObject<PeerConnectionFactoryForTest>(); |
2639 pcf_->Initialize(); | 2637 pcf_->Initialize(); |
2640 } | 2638 } |
2641 const cricket::MediaConfig& TestCreatePeerConnection( | 2639 const cricket::MediaConfig& TestCreatePeerConnection( |
2642 const PeerConnectionInterface::RTCConfiguration& config, | 2640 const PeerConnectionInterface::RTCConfiguration& config, |
2643 const MediaConstraintsInterface *constraints) { | 2641 const MediaConstraintsInterface *constraints) { |
2644 pcf_->create_media_controller_called_ = false; | 2642 pcf_->create_media_controller_called_ = false; |
2645 | 2643 |
2646 rtc::scoped_refptr<PeerConnectionInterface> pc(pcf_->CreatePeerConnection( | 2644 scoped_refptr<PeerConnectionInterface> pc( |
2647 config, constraints, nullptr, nullptr, &observer_)); | 2645 pcf_->CreatePeerConnection(config, constraints, nullptr, nullptr, |
| 2646 &observer_)); |
2648 EXPECT_TRUE(pc.get()); | 2647 EXPECT_TRUE(pc.get()); |
2649 EXPECT_TRUE(pcf_->create_media_controller_called_); | 2648 EXPECT_TRUE(pcf_->create_media_controller_called_); |
2650 return pcf_->create_media_controller_config_; | 2649 return pcf_->create_media_controller_config_; |
2651 } | 2650 } |
2652 | 2651 |
2653 rtc::scoped_refptr<PeerConnectionFactoryForTest> pcf_; | 2652 scoped_refptr<PeerConnectionFactoryForTest> pcf_; |
2654 MockPeerConnectionObserver observer_; | 2653 MockPeerConnectionObserver observer_; |
2655 }; | 2654 }; |
2656 | 2655 |
2657 // This test verifies the default behaviour with no constraints and a | 2656 // This test verifies the default behaviour with no constraints and a |
2658 // default RTCConfiguration. | 2657 // default RTCConfiguration. |
2659 TEST_F(PeerConnectionMediaConfigTest, TestDefaults) { | 2658 TEST_F(PeerConnectionMediaConfigTest, TestDefaults) { |
2660 PeerConnectionInterface::RTCConfiguration config; | 2659 PeerConnectionInterface::RTCConfiguration config; |
2661 FakeConstraints constraints; | 2660 FakeConstraints constraints; |
2662 | 2661 |
2663 const cricket::MediaConfig& media_config = | 2662 const cricket::MediaConfig& media_config = |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2888 FakeConstraints updated_answer_c; | 2887 FakeConstraints updated_answer_c; |
2889 answer_c.SetMandatoryReceiveAudio(false); | 2888 answer_c.SetMandatoryReceiveAudio(false); |
2890 answer_c.SetMandatoryReceiveVideo(false); | 2889 answer_c.SetMandatoryReceiveVideo(false); |
2891 | 2890 |
2892 cricket::MediaSessionOptions updated_answer_options; | 2891 cricket::MediaSessionOptions updated_answer_options; |
2893 EXPECT_TRUE( | 2892 EXPECT_TRUE( |
2894 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options)); | 2893 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options)); |
2895 EXPECT_TRUE(updated_answer_options.has_audio()); | 2894 EXPECT_TRUE(updated_answer_options.has_audio()); |
2896 EXPECT_TRUE(updated_answer_options.has_video()); | 2895 EXPECT_TRUE(updated_answer_options.has_video()); |
2897 } | 2896 } |
OLD | NEW |