// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/renderer/media/mock_peer_connection_impl.h" #include #include "base/logging.h" #include "content/renderer/media/mock_data_channel_impl.h" #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" using testing::_; using webrtc::AudioTrackInterface; using webrtc::CreateSessionDescriptionObserver; using webrtc::DtmfSenderInterface; using webrtc::DtmfSenderObserverInterface; using webrtc::IceCandidateInterface; using webrtc::MediaConstraintsInterface; using webrtc::MediaStreamInterface; using webrtc::PeerConnectionInterface; using webrtc::SessionDescriptionInterface; using webrtc::SetSessionDescriptionObserver; namespace content { class MockStreamCollection : public webrtc::StreamCollectionInterface { public: size_t count() override { return streams_.size(); } MediaStreamInterface* at(size_t index) override { return streams_[index]; } MediaStreamInterface* find(const std::string& label) override { for (size_t i = 0; i < streams_.size(); ++i) { if (streams_[i]->label() == label) return streams_[i]; } return NULL; } webrtc::MediaStreamTrackInterface* FindAudioTrack( const std::string& id) override { for (size_t i = 0; i < streams_.size(); ++i) { webrtc::MediaStreamTrackInterface* track = streams_.at(i)->FindAudioTrack(id); if (track) return track; } return NULL; } webrtc::MediaStreamTrackInterface* FindVideoTrack( const std::string& id) override { for (size_t i = 0; i < streams_.size(); ++i) { webrtc::MediaStreamTrackInterface* track = streams_.at(i)->FindVideoTrack(id); if (track) return track; } return NULL; } void AddStream(MediaStreamInterface* stream) { streams_.push_back(stream); } void RemoveStream(MediaStreamInterface* stream) { StreamVector::iterator it = streams_.begin(); for (; it != streams_.end(); ++it) { if (it->get() == stream) { streams_.erase(it); break; } } } protected: ~MockStreamCollection() override {} private: typedef std::vector > StreamVector; StreamVector streams_; }; class MockDtmfSender : public DtmfSenderInterface { public: explicit MockDtmfSender(AudioTrackInterface* track) : track_(track), observer_(NULL), duration_(0), inter_tone_gap_(0) {} void RegisterObserver(DtmfSenderObserverInterface* observer) override { observer_ = observer; } void UnregisterObserver() override { observer_ = NULL; } bool CanInsertDtmf() override { return true; } bool InsertDtmf(const std::string& tones, int duration, int inter_tone_gap) override { tones_ = tones; duration_ = duration; inter_tone_gap_ = inter_tone_gap; return true; } const AudioTrackInterface* track() const override { return track_.get(); } std::string tones() const override { return tones_; } int duration() const override { return duration_; } int inter_tone_gap() const override { return inter_tone_gap_; } protected: ~MockDtmfSender() override {} private: rtc::scoped_refptr track_; DtmfSenderObserverInterface* observer_; std::string tones_; int duration_; int inter_tone_gap_; }; const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer"; const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; MockPeerConnectionImpl::MockPeerConnectionImpl( MockPeerConnectionDependencyFactory* factory, webrtc::PeerConnectionObserver* observer) : dependency_factory_(factory), local_streams_(new rtc::RefCountedObject), remote_streams_(new rtc::RefCountedObject), hint_audio_(false), hint_video_(false), getstats_result_(true), sdp_mline_index_(-1), observer_(observer) { ON_CALL(*this, SetLocalDescription(_, _)).WillByDefault(testing::Invoke( this, &MockPeerConnectionImpl::SetLocalDescriptionWorker)); ON_CALL(*this, SetRemoteDescription(_, _)).WillByDefault(testing::Invoke( this, &MockPeerConnectionImpl::SetRemoteDescriptionWorker)); } MockPeerConnectionImpl::~MockPeerConnectionImpl() {} rtc::scoped_refptr MockPeerConnectionImpl::local_streams() { return local_streams_; } rtc::scoped_refptr MockPeerConnectionImpl::remote_streams() { return remote_streams_; } bool MockPeerConnectionImpl::AddStream(MediaStreamInterface* local_stream) { DCHECK(stream_label_.empty()); stream_label_ = local_stream->label(); local_streams_->AddStream(local_stream); return true; } void MockPeerConnectionImpl::RemoveStream( MediaStreamInterface* local_stream) { DCHECK_EQ(stream_label_, local_stream->label()); stream_label_.clear(); local_streams_->RemoveStream(local_stream); } rtc::scoped_refptr MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) { if (!track) { return NULL; } return new rtc::RefCountedObject(track); } rtc::scoped_refptr MockPeerConnectionImpl::CreateDataChannel(const std::string& label, const webrtc::DataChannelInit* config) { return new rtc::RefCountedObject(label, config); } bool MockPeerConnectionImpl::GetStats( webrtc::StatsObserver* observer, webrtc::MediaStreamTrackInterface* track, StatsOutputLevel level) { if (!getstats_result_) return false; DCHECK_EQ(kStatsOutputLevelStandard, level); webrtc::StatsReport report1("1234"), report2("nontrack"); report1.type = webrtc::StatsReport::kStatsReportTypeSsrc; report1.timestamp = 42; report1.values.push_back( webrtc::StatsReport::Value( webrtc::StatsReport::kStatsValueNameFingerprint, "trackvalue")); webrtc::StatsReports reports; reports.push_back(&report1); // If selector is given, we pass back one report. // If selector is not given, we pass back two. if (!track) { report2.type = webrtc::StatsReport::kStatsReportTypeSession; report2.timestamp = 44; report2.values.push_back( webrtc::StatsReport::Value( webrtc::StatsReport::kStatsValueNameFingerprintAlgorithm, "somevalue")); reports.push_back(&report2); } // Note that the callback is synchronous, not asynchronous; it will // happen before the request call completes. observer->OnComplete(reports); return true; } const webrtc::SessionDescriptionInterface* MockPeerConnectionImpl::local_description() const { return local_desc_.get(); } const webrtc::SessionDescriptionInterface* MockPeerConnectionImpl::remote_description() const { return remote_desc_.get(); } void MockPeerConnectionImpl::AddRemoteStream(MediaStreamInterface* stream) { remote_streams_->AddStream(stream); } void MockPeerConnectionImpl::CreateOffer( CreateSessionDescriptionObserver* observer, const MediaConstraintsInterface* constraints) { DCHECK(observer); created_sessiondescription_.reset( dependency_factory_->CreateSessionDescription("unknown", kDummyOffer, NULL)); } void MockPeerConnectionImpl::CreateAnswer( CreateSessionDescriptionObserver* observer, const MediaConstraintsInterface* constraints) { DCHECK(observer); created_sessiondescription_.reset( dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer, NULL)); } void MockPeerConnectionImpl::SetLocalDescriptionWorker( SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc) { desc->ToString(&description_sdp_); local_desc_.reset(desc); } void MockPeerConnectionImpl::SetRemoteDescriptionWorker( SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc) { desc->ToString(&description_sdp_); remote_desc_.reset(desc); } bool MockPeerConnectionImpl::UpdateIce( const IceServers& configuration, const MediaConstraintsInterface* constraints) { return true; } bool MockPeerConnectionImpl::AddIceCandidate( const IceCandidateInterface* candidate) { sdp_mid_ = candidate->sdp_mid(); sdp_mline_index_ = candidate->sdp_mline_index(); return candidate->ToString(&ice_sdp_); } void MockPeerConnectionImpl::RegisterUMAObserver( webrtc::UMAObserver* observer) { NOTIMPLEMENTED(); } } // namespace content