blob: 831571b870373d86da09fa0476d7280f04e84068 [file] [log] [blame]
// 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"));
std::vector<webrtc::StatsReport> 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