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