| // 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 <vector> |
| |
| #include "base/logging.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: |
| virtual size_t count() OVERRIDE { |
| return streams_.size(); |
| } |
| virtual MediaStreamInterface* at(size_t index) OVERRIDE { |
| return streams_[index]; |
| } |
| virtual 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; |
| } |
| virtual 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; |
| } |
| virtual 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: |
| virtual ~MockStreamCollection() {} |
| |
| private: |
| typedef std::vector<rtc::scoped_refptr<MediaStreamInterface> > |
| StreamVector; |
| StreamVector streams_; |
| }; |
| |
| class MockDataChannel : public webrtc::DataChannelInterface { |
| public: |
| MockDataChannel(const std::string& label, |
| const webrtc::DataChannelInit* config) |
| : label_(label), |
| reliable_(config->reliable), |
| state_(webrtc::DataChannelInterface::kConnecting), |
| config_(*config) { |
| } |
| |
| virtual void RegisterObserver( |
| webrtc::DataChannelObserver* observer) OVERRIDE { |
| } |
| |
| virtual void UnregisterObserver() OVERRIDE { |
| } |
| |
| virtual std::string label() const OVERRIDE { |
| return label_; |
| } |
| |
| virtual bool reliable() const OVERRIDE { |
| return reliable_; |
| } |
| |
| virtual bool ordered() const OVERRIDE { |
| return config_.ordered; |
| } |
| |
| virtual unsigned short maxRetransmitTime() const OVERRIDE { |
| return config_.maxRetransmitTime; |
| } |
| |
| virtual unsigned short maxRetransmits() const OVERRIDE { |
| return config_.maxRetransmits; |
| } |
| |
| virtual std::string protocol() const OVERRIDE { |
| return config_.protocol; |
| } |
| |
| virtual bool negotiated() const OVERRIDE { |
| return config_.negotiated; |
| } |
| |
| virtual int id() const OVERRIDE { |
| NOTIMPLEMENTED(); |
| return 0; |
| } |
| |
| virtual DataState state() const OVERRIDE { |
| return state_; |
| } |
| |
| virtual uint64 buffered_amount() const OVERRIDE { |
| NOTIMPLEMENTED(); |
| return 0; |
| } |
| |
| virtual void Close() OVERRIDE { |
| state_ = webrtc::DataChannelInterface::kClosing; |
| } |
| |
| virtual bool Send(const webrtc::DataBuffer& buffer) OVERRIDE { |
| return state_ == webrtc::DataChannelInterface::kOpen; |
| } |
| |
| protected: |
| virtual ~MockDataChannel() {} |
| |
| private: |
| std::string label_; |
| bool reliable_; |
| webrtc::DataChannelInterface::DataState state_; |
| webrtc::DataChannelInit config_; |
| }; |
| |
| class MockDtmfSender : public DtmfSenderInterface { |
| public: |
| explicit MockDtmfSender(AudioTrackInterface* track) |
| : track_(track), |
| observer_(NULL), |
| duration_(0), |
| inter_tone_gap_(0) {} |
| virtual void RegisterObserver( |
| DtmfSenderObserverInterface* observer) OVERRIDE { |
| observer_ = observer; |
| } |
| virtual void UnregisterObserver() OVERRIDE { |
| observer_ = NULL; |
| } |
| virtual bool CanInsertDtmf() OVERRIDE { |
| return true; |
| } |
| virtual 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; |
| } |
| virtual const AudioTrackInterface* track() const OVERRIDE { |
| return track_.get(); |
| } |
| virtual std::string tones() const OVERRIDE { |
| return tones_; |
| } |
| virtual int duration() const OVERRIDE { return duration_; } |
| virtual int inter_tone_gap() const OVERRIDE { return inter_tone_gap_; } |
| |
| protected: |
| virtual ~MockDtmfSender() {} |
| |
| private: |
| rtc::scoped_refptr<AudioTrackInterface> 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) |
| : dependency_factory_(factory), |
| local_streams_(new rtc::RefCountedObject<MockStreamCollection>), |
| remote_streams_(new rtc::RefCountedObject<MockStreamCollection>), |
| hint_audio_(false), |
| hint_video_(false), |
| getstats_result_(true), |
| sdp_mline_index_(-1) { |
| 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<webrtc::StreamCollectionInterface> |
| MockPeerConnectionImpl::local_streams() { |
| return local_streams_; |
| } |
| |
| rtc::scoped_refptr<webrtc::StreamCollectionInterface> |
| MockPeerConnectionImpl::remote_streams() { |
| return remote_streams_; |
| } |
| |
| bool MockPeerConnectionImpl::AddStream( |
| MediaStreamInterface* local_stream, |
| const MediaConstraintsInterface* constraints) { |
| 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<DtmfSenderInterface> |
| MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) { |
| if (!track) { |
| return NULL; |
| } |
| return new rtc::RefCountedObject<MockDtmfSender>(track); |
| } |
| |
| rtc::scoped_refptr<webrtc::DataChannelInterface> |
| MockPeerConnectionImpl::CreateDataChannel(const std::string& label, |
| const webrtc::DataChannelInit* config) { |
| return new rtc::RefCountedObject<MockDataChannel>(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, report2; |
| report1.id = "1234"; |
| report1.type = "ssrc"; |
| 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.id = "nontrack"; |
| report2.type = "generic"; |
| 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 |