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 12 using testing::_; 13 using webrtc::AudioTrackInterface; 14 using webrtc::CreateSessionDescriptionObserver; 15 using webrtc::DtmfSenderInterface; 16 using webrtc::DtmfSenderObserverInterface; 17 using webrtc::IceCandidateInterface; 18 using webrtc::MediaConstraintsInterface; 19 using webrtc::MediaStreamInterface; 20 using webrtc::PeerConnectionInterface; 21 using webrtc::SessionDescriptionInterface; 22 using webrtc::SetSessionDescriptionObserver; 23 24 namespace content { 25 26 class 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 83 class 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 config_(*config) { 91 } 92 93 virtual void RegisterObserver( 94 webrtc::DataChannelObserver* observer) OVERRIDE { 95 } 96 97 virtual void UnregisterObserver() OVERRIDE { 98 } 99 100 virtual std::string label() const OVERRIDE { 101 return label_; 102 } 103 104 virtual bool reliable() const OVERRIDE { 105 return reliable_; 106 } 107 108 virtual bool ordered() const OVERRIDE { 109 return config_.ordered; 110 } 111 112 virtual unsigned short maxRetransmitTime() const OVERRIDE { 113 return config_.maxRetransmitTime; 114 } 115 116 virtual unsigned short maxRetransmits() const OVERRIDE { 117 return config_.maxRetransmits; 118 } 119 120 virtual std::string protocol() const OVERRIDE { 121 return config_.protocol; 122 } 123 124 virtual bool negotiated() const OVERRIDE { 125 return config_.negotiated; 126 } 127 128 virtual int id() const OVERRIDE { 129 NOTIMPLEMENTED(); 130 return 0; 131 } 132 133 virtual DataState state() const OVERRIDE { 134 return state_; 135 } 136 137 virtual uint64 buffered_amount() const OVERRIDE { 138 NOTIMPLEMENTED(); 139 return 0; 140 } 141 142 virtual void Close() OVERRIDE { 143 state_ = webrtc::DataChannelInterface::kClosing; 144 } 145 146 virtual bool Send(const webrtc::DataBuffer& buffer) OVERRIDE { 147 return state_ == webrtc::DataChannelInterface::kOpen; 148 } 149 150 protected: 151 virtual ~MockDataChannel() {} 152 153 private: 154 std::string label_; 155 bool reliable_; 156 webrtc::DataChannelInterface::DataState state_; 157 webrtc::DataChannelInit config_; 158 }; 159 160 class MockDtmfSender : public DtmfSenderInterface { 161 public: 162 explicit MockDtmfSender(AudioTrackInterface* track) 163 : track_(track), 164 observer_(NULL), 165 duration_(0), 166 inter_tone_gap_(0) {} 167 virtual void RegisterObserver( 168 DtmfSenderObserverInterface* observer) OVERRIDE { 169 observer_ = observer; 170 } 171 virtual void UnregisterObserver() OVERRIDE { 172 observer_ = NULL; 173 } 174 virtual bool CanInsertDtmf() OVERRIDE { 175 return true; 176 } 177 virtual bool InsertDtmf(const std::string& tones, int duration, 178 int inter_tone_gap) OVERRIDE { 179 tones_ = tones; 180 duration_ = duration; 181 inter_tone_gap_ = inter_tone_gap; 182 return true; 183 } 184 virtual const AudioTrackInterface* track() const OVERRIDE { 185 return track_.get(); 186 } 187 virtual std::string tones() const OVERRIDE { 188 return tones_; 189 } 190 virtual int duration() const OVERRIDE { return duration_; } 191 virtual int inter_tone_gap() const OVERRIDE { return inter_tone_gap_; } 192 193 protected: 194 virtual ~MockDtmfSender() {} 195 196 private: 197 talk_base::scoped_refptr<AudioTrackInterface> track_; 198 DtmfSenderObserverInterface* observer_; 199 std::string tones_; 200 int duration_; 201 int inter_tone_gap_; 202 }; 203 204 const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer"; 205 const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; 206 207 MockPeerConnectionImpl::MockPeerConnectionImpl( 208 MockMediaStreamDependencyFactory* factory) 209 : dependency_factory_(factory), 210 local_streams_(new talk_base::RefCountedObject<MockStreamCollection>), 211 remote_streams_(new talk_base::RefCountedObject<MockStreamCollection>), 212 hint_audio_(false), 213 hint_video_(false), 214 getstats_result_(true), 215 sdp_mline_index_(-1) { 216 ON_CALL(*this, SetLocalDescription(_, _)).WillByDefault(testing::Invoke( 217 this, &MockPeerConnectionImpl::SetLocalDescriptionWorker)); 218 ON_CALL(*this, SetRemoteDescription(_, _)).WillByDefault(testing::Invoke( 219 this, &MockPeerConnectionImpl::SetRemoteDescriptionWorker)); 220 } 221 222 MockPeerConnectionImpl::~MockPeerConnectionImpl() {} 223 224 talk_base::scoped_refptr<webrtc::StreamCollectionInterface> 225 MockPeerConnectionImpl::local_streams() { 226 return local_streams_; 227 } 228 229 talk_base::scoped_refptr<webrtc::StreamCollectionInterface> 230 MockPeerConnectionImpl::remote_streams() { 231 return remote_streams_; 232 } 233 234 bool MockPeerConnectionImpl::AddStream( 235 MediaStreamInterface* local_stream, 236 const MediaConstraintsInterface* constraints) { 237 DCHECK(stream_label_.empty()); 238 stream_label_ = local_stream->label(); 239 local_streams_->AddStream(local_stream); 240 return true; 241 } 242 243 void MockPeerConnectionImpl::RemoveStream( 244 MediaStreamInterface* local_stream) { 245 DCHECK_EQ(stream_label_, local_stream->label()); 246 stream_label_.clear(); 247 local_streams_->RemoveStream(local_stream); 248 } 249 250 talk_base::scoped_refptr<DtmfSenderInterface> 251 MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) { 252 if (!track) { 253 return NULL; 254 } 255 return new talk_base::RefCountedObject<MockDtmfSender>(track); 256 } 257 258 talk_base::scoped_refptr<webrtc::DataChannelInterface> 259 MockPeerConnectionImpl::CreateDataChannel(const std::string& label, 260 const webrtc::DataChannelInit* config) { 261 return new talk_base::RefCountedObject<MockDataChannel>(label, config); 262 } 263 264 bool MockPeerConnectionImpl::GetStats( 265 webrtc::StatsObserver* observer, 266 webrtc::MediaStreamTrackInterface* track) { 267 if (!getstats_result_) 268 return false; 269 270 std::vector<webrtc::StatsReport> reports; 271 webrtc::StatsReport report; 272 report.id = "1234"; 273 report.type = "ssrc"; 274 report.timestamp = 42; 275 webrtc::StatsReport::Value value; 276 value.name = "trackname"; 277 value.value = "trackvalue"; 278 report.values.push_back(value); 279 reports.push_back(report); 280 // If selector is given, we pass back one report. 281 // If selector is not given, we pass back two. 282 if (!track) { 283 report.id = "nontrack"; 284 report.type = "generic"; 285 report.timestamp = 44; 286 value.name = "somename"; 287 value.value = "somevalue"; 288 report.values.push_back(value); 289 reports.push_back(report); 290 } 291 // Note that the callback is synchronous, not asynchronous; it will 292 // happen before the request call completes. 293 observer->OnComplete(reports); 294 return true; 295 } 296 297 const webrtc::SessionDescriptionInterface* 298 MockPeerConnectionImpl::local_description() const { 299 return local_desc_.get(); 300 } 301 302 const webrtc::SessionDescriptionInterface* 303 MockPeerConnectionImpl::remote_description() const { 304 return remote_desc_.get(); 305 } 306 307 void MockPeerConnectionImpl::AddRemoteStream(MediaStreamInterface* stream) { 308 remote_streams_->AddStream(stream); 309 } 310 311 void MockPeerConnectionImpl::CreateOffer( 312 CreateSessionDescriptionObserver* observer, 313 const MediaConstraintsInterface* constraints) { 314 DCHECK(observer); 315 created_sessiondescription_.reset( 316 dependency_factory_->CreateSessionDescription("unknown", kDummyOffer, 317 NULL)); 318 } 319 320 void MockPeerConnectionImpl::CreateAnswer( 321 CreateSessionDescriptionObserver* observer, 322 const MediaConstraintsInterface* constraints) { 323 DCHECK(observer); 324 created_sessiondescription_.reset( 325 dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer, 326 NULL)); 327 } 328 329 void MockPeerConnectionImpl::SetLocalDescriptionWorker( 330 SetSessionDescriptionObserver* observer, 331 SessionDescriptionInterface* desc) { 332 desc->ToString(&description_sdp_); 333 local_desc_.reset(desc); 334 } 335 336 void MockPeerConnectionImpl::SetRemoteDescriptionWorker( 337 SetSessionDescriptionObserver* observer, 338 SessionDescriptionInterface* desc) { 339 desc->ToString(&description_sdp_); 340 remote_desc_.reset(desc); 341 } 342 343 bool MockPeerConnectionImpl::UpdateIce( 344 const IceServers& configuration, 345 const MediaConstraintsInterface* constraints) { 346 return true; 347 } 348 349 bool MockPeerConnectionImpl::AddIceCandidate( 350 const IceCandidateInterface* candidate) { 351 sdp_mid_ = candidate->sdp_mid(); 352 sdp_mline_index_ = candidate->sdp_mline_index(); 353 return candidate->ToString(&ice_sdp_); 354 } 355 356 } // namespace content 357