1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/media/mock_media_stream_dependency_factory.h" 6#include "content/renderer/media/mock_peer_connection_impl.h" 7 8#include <vector> 9 10#include "base/logging.h" 11 12using testing::_; 13using webrtc::AudioTrackInterface; 14using webrtc::CreateSessionDescriptionObserver; 15using webrtc::DtmfSenderInterface; 16using webrtc::DtmfSenderObserverInterface; 17using webrtc::IceCandidateInterface; 18using webrtc::MediaConstraintsInterface; 19using webrtc::MediaStreamInterface; 20using webrtc::PeerConnectionInterface; 21using webrtc::SessionDescriptionInterface; 22using webrtc::SetSessionDescriptionObserver; 23 24namespace content { 25 26class MockStreamCollection : public webrtc::StreamCollectionInterface { 27 public: 28 virtual size_t count() OVERRIDE { 29 return streams_.size(); 30 } 31 virtual MediaStreamInterface* at(size_t index) OVERRIDE { 32 return streams_[index]; 33 } 34 virtual MediaStreamInterface* find(const std::string& label) OVERRIDE { 35 for (size_t i = 0; i < streams_.size(); ++i) { 36 if (streams_[i]->label() == label) 37 return streams_[i]; 38 } 39 return NULL; 40 } 41 virtual webrtc::MediaStreamTrackInterface* FindAudioTrack( 42 const std::string& id) OVERRIDE { 43 for (size_t i = 0; i < streams_.size(); ++i) { 44 webrtc::MediaStreamTrackInterface* track = 45 streams_.at(i)->FindAudioTrack(id); 46 if (track) 47 return track; 48 } 49 return NULL; 50 } 51 virtual webrtc::MediaStreamTrackInterface* FindVideoTrack( 52 const std::string& id) OVERRIDE { 53 for (size_t i = 0; i < streams_.size(); ++i) { 54 webrtc::MediaStreamTrackInterface* track = 55 streams_.at(i)->FindVideoTrack(id); 56 if (track) 57 return track; 58 } 59 return NULL; 60 } 61 void AddStream(MediaStreamInterface* stream) { 62 streams_.push_back(stream); 63 } 64 void RemoveStream(MediaStreamInterface* stream) { 65 StreamVector::iterator it = streams_.begin(); 66 for (; it != streams_.end(); ++it) { 67 if (it->get() == stream) { 68 streams_.erase(it); 69 break; 70 } 71 } 72 } 73 74 protected: 75 virtual ~MockStreamCollection() {} 76 77 private: 78 typedef std::vector<talk_base::scoped_refptr<MediaStreamInterface> > 79 StreamVector; 80 StreamVector streams_; 81}; 82 83class MockDataChannel : public webrtc::DataChannelInterface { 84 public: 85 MockDataChannel(const std::string& label, 86 const webrtc::DataChannelInit* config) 87 : label_(label), 88 reliable_(config->reliable), 89 state_(webrtc::DataChannelInterface::kConnecting) { 90 } 91 92 virtual void RegisterObserver( 93 webrtc::DataChannelObserver* observer) OVERRIDE { 94 } 95 96 virtual void UnregisterObserver() OVERRIDE { 97 } 98 99 virtual std::string label() const OVERRIDE { 100 return label_; 101 } 102 103 virtual bool reliable() const OVERRIDE { 104 return reliable_; 105 } 106 107 virtual int id() const OVERRIDE { 108 NOTIMPLEMENTED(); 109 return 0; 110 } 111 112 virtual DataState state() const OVERRIDE { 113 return state_; 114 } 115 116 virtual uint64 buffered_amount() const OVERRIDE { 117 NOTIMPLEMENTED(); 118 return 0; 119 } 120 121 virtual void Close() OVERRIDE { 122 state_ = webrtc::DataChannelInterface::kClosing; 123 } 124 125 virtual bool Send(const webrtc::DataBuffer& buffer) OVERRIDE { 126 return state_ == webrtc::DataChannelInterface::kOpen; 127 } 128 129 protected: 130 virtual ~MockDataChannel() {} 131 132 private: 133 std::string label_; 134 bool reliable_; 135 webrtc::DataChannelInterface::DataState state_; 136}; 137 138class MockDtmfSender : public DtmfSenderInterface { 139 public: 140 explicit MockDtmfSender(AudioTrackInterface* track) 141 : track_(track), 142 observer_(NULL), 143 duration_(0), 144 inter_tone_gap_(0) {} 145 virtual void RegisterObserver( 146 DtmfSenderObserverInterface* observer) OVERRIDE { 147 observer_ = observer; 148 } 149 virtual void UnregisterObserver() OVERRIDE { 150 observer_ = NULL; 151 } 152 virtual bool CanInsertDtmf() OVERRIDE { 153 return true; 154 } 155 virtual bool InsertDtmf(const std::string& tones, int duration, 156 int inter_tone_gap) OVERRIDE { 157 tones_ = tones; 158 duration_ = duration; 159 inter_tone_gap_ = inter_tone_gap; 160 return true; 161 } 162 virtual const AudioTrackInterface* track() const OVERRIDE { 163 return track_.get(); 164 } 165 virtual std::string tones() const OVERRIDE { 166 return tones_; 167 } 168 virtual int duration() const OVERRIDE { return duration_; } 169 virtual int inter_tone_gap() const OVERRIDE { return inter_tone_gap_; } 170 171 protected: 172 virtual ~MockDtmfSender() {} 173 174 private: 175 talk_base::scoped_refptr<AudioTrackInterface> track_; 176 DtmfSenderObserverInterface* observer_; 177 std::string tones_; 178 int duration_; 179 int inter_tone_gap_; 180}; 181 182const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer"; 183const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; 184 185MockPeerConnectionImpl::MockPeerConnectionImpl( 186 MockMediaStreamDependencyFactory* factory) 187 : dependency_factory_(factory), 188 local_streams_(new talk_base::RefCountedObject<MockStreamCollection>), 189 remote_streams_(new talk_base::RefCountedObject<MockStreamCollection>), 190 hint_audio_(false), 191 hint_video_(false), 192 getstats_result_(true), 193 sdp_mline_index_(-1) { 194 ON_CALL(*this, SetLocalDescription(_, _)).WillByDefault(testing::Invoke( 195 this, &MockPeerConnectionImpl::SetLocalDescriptionWorker)); 196 ON_CALL(*this, SetRemoteDescription(_, _)).WillByDefault(testing::Invoke( 197 this, &MockPeerConnectionImpl::SetRemoteDescriptionWorker)); 198} 199 200MockPeerConnectionImpl::~MockPeerConnectionImpl() {} 201 202talk_base::scoped_refptr<webrtc::StreamCollectionInterface> 203MockPeerConnectionImpl::local_streams() { 204 return local_streams_; 205} 206 207talk_base::scoped_refptr<webrtc::StreamCollectionInterface> 208MockPeerConnectionImpl::remote_streams() { 209 return remote_streams_; 210} 211 212bool MockPeerConnectionImpl::AddStream( 213 MediaStreamInterface* local_stream, 214 const MediaConstraintsInterface* constraints) { 215 DCHECK(stream_label_.empty()); 216 stream_label_ = local_stream->label(); 217 local_streams_->AddStream(local_stream); 218 return true; 219} 220 221void MockPeerConnectionImpl::RemoveStream( 222 MediaStreamInterface* local_stream) { 223 DCHECK_EQ(stream_label_, local_stream->label()); 224 stream_label_.clear(); 225 local_streams_->RemoveStream(local_stream); 226} 227 228talk_base::scoped_refptr<DtmfSenderInterface> 229MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) { 230 if (!track) { 231 return NULL; 232 } 233 return new talk_base::RefCountedObject<MockDtmfSender>(track); 234} 235 236talk_base::scoped_refptr<webrtc::DataChannelInterface> 237MockPeerConnectionImpl::CreateDataChannel(const std::string& label, 238 const webrtc::DataChannelInit* config) { 239 return new talk_base::RefCountedObject<MockDataChannel>(label, config); 240} 241 242bool MockPeerConnectionImpl::GetStats( 243 webrtc::StatsObserver* observer, 244 webrtc::MediaStreamTrackInterface* track) { 245 if (!getstats_result_) 246 return false; 247 248 std::vector<webrtc::StatsReport> reports; 249 webrtc::StatsReport report; 250 report.id = "1234"; 251 report.type = "ssrc"; 252 report.timestamp = 42; 253 webrtc::StatsReport::Value value; 254 value.name = "trackname"; 255 value.value = "trackvalue"; 256 report.values.push_back(value); 257 reports.push_back(report); 258 // If selector is given, we pass back one report. 259 // If selector is not given, we pass back two. 260 if (!track) { 261 report.id = "nontrack"; 262 report.type = "generic"; 263 report.timestamp = 44; 264 value.name = "somename"; 265 value.value = "somevalue"; 266 report.values.push_back(value); 267 reports.push_back(report); 268 } 269 // Note that the callback is synchronous, not asynchronous; it will 270 // happen before the request call completes. 271 observer->OnComplete(reports); 272 return true; 273} 274 275const webrtc::SessionDescriptionInterface* 276MockPeerConnectionImpl::local_description() const { 277 return local_desc_.get(); 278} 279 280const webrtc::SessionDescriptionInterface* 281MockPeerConnectionImpl::remote_description() const { 282 return remote_desc_.get(); 283} 284 285void MockPeerConnectionImpl::AddRemoteStream(MediaStreamInterface* stream) { 286 remote_streams_->AddStream(stream); 287} 288 289void MockPeerConnectionImpl::CreateOffer( 290 CreateSessionDescriptionObserver* observer, 291 const MediaConstraintsInterface* constraints) { 292 DCHECK(observer); 293 created_sessiondescription_.reset( 294 dependency_factory_->CreateSessionDescription("unknown", kDummyOffer, 295 NULL)); 296} 297 298void MockPeerConnectionImpl::CreateAnswer( 299 CreateSessionDescriptionObserver* observer, 300 const MediaConstraintsInterface* constraints) { 301 DCHECK(observer); 302 created_sessiondescription_.reset( 303 dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer, 304 NULL)); 305} 306 307void MockPeerConnectionImpl::SetLocalDescriptionWorker( 308 SetSessionDescriptionObserver* observer, 309 SessionDescriptionInterface* desc) { 310 desc->ToString(&description_sdp_); 311 local_desc_.reset(desc); 312} 313 314void MockPeerConnectionImpl::SetRemoteDescriptionWorker( 315 SetSessionDescriptionObserver* observer, 316 SessionDescriptionInterface* desc) { 317 desc->ToString(&description_sdp_); 318 remote_desc_.reset(desc); 319} 320 321bool MockPeerConnectionImpl::UpdateIce( 322 const IceServers& configuration, 323 const MediaConstraintsInterface* constraints) { 324 return true; 325} 326 327bool MockPeerConnectionImpl::AddIceCandidate( 328 const IceCandidateInterface* candidate) { 329 sdp_mid_ = candidate->sdp_mid(); 330 sdp_mline_index_ = candidate->sdp_mline_index(); 331 return candidate->ToString(&ice_sdp_); 332} 333 334} // namespace content 335