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_peer_connection_impl.h" 6 7#include <vector> 8 9#include "base/logging.h" 10#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.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<rtc::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 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 160class 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 rtc::scoped_refptr<AudioTrackInterface> track_; 198 DtmfSenderObserverInterface* observer_; 199 std::string tones_; 200 int duration_; 201 int inter_tone_gap_; 202}; 203 204const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer"; 205const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; 206 207MockPeerConnectionImpl::MockPeerConnectionImpl( 208 MockPeerConnectionDependencyFactory* factory) 209 : dependency_factory_(factory), 210 local_streams_(new rtc::RefCountedObject<MockStreamCollection>), 211 remote_streams_(new rtc::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 222MockPeerConnectionImpl::~MockPeerConnectionImpl() {} 223 224rtc::scoped_refptr<webrtc::StreamCollectionInterface> 225MockPeerConnectionImpl::local_streams() { 226 return local_streams_; 227} 228 229rtc::scoped_refptr<webrtc::StreamCollectionInterface> 230MockPeerConnectionImpl::remote_streams() { 231 return remote_streams_; 232} 233 234bool 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 243void 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 250rtc::scoped_refptr<DtmfSenderInterface> 251MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) { 252 if (!track) { 253 return NULL; 254 } 255 return new rtc::RefCountedObject<MockDtmfSender>(track); 256} 257 258rtc::scoped_refptr<webrtc::DataChannelInterface> 259MockPeerConnectionImpl::CreateDataChannel(const std::string& label, 260 const webrtc::DataChannelInit* config) { 261 return new rtc::RefCountedObject<MockDataChannel>(label, config); 262} 263 264bool MockPeerConnectionImpl::GetStats( 265 webrtc::StatsObserver* observer, 266 webrtc::MediaStreamTrackInterface* track, 267 StatsOutputLevel level) { 268 if (!getstats_result_) 269 return false; 270 271 DCHECK_EQ(kStatsOutputLevelStandard, level); 272 webrtc::StatsReport report1, report2; 273 report1.id = "1234"; 274 report1.type = "ssrc"; 275 report1.timestamp = 42; 276 report1.values.push_back( 277 webrtc::StatsReport::Value( 278 webrtc::StatsReport::kStatsValueNameFingerprint, 279 "trackvalue")); 280 281 webrtc::StatsReports reports; 282 reports.push_back(&report1); 283 284 // If selector is given, we pass back one report. 285 // If selector is not given, we pass back two. 286 if (!track) { 287 report2.id = "nontrack"; 288 report2.type = "generic"; 289 report2.timestamp = 44; 290 report2.values.push_back( 291 webrtc::StatsReport::Value( 292 webrtc::StatsReport::kStatsValueNameFingerprintAlgorithm, 293 "somevalue")); 294 reports.push_back(&report2); 295 } 296 297 // Note that the callback is synchronous, not asynchronous; it will 298 // happen before the request call completes. 299 observer->OnComplete(reports); 300 301 return true; 302} 303 304const webrtc::SessionDescriptionInterface* 305MockPeerConnectionImpl::local_description() const { 306 return local_desc_.get(); 307} 308 309const webrtc::SessionDescriptionInterface* 310MockPeerConnectionImpl::remote_description() const { 311 return remote_desc_.get(); 312} 313 314void MockPeerConnectionImpl::AddRemoteStream(MediaStreamInterface* stream) { 315 remote_streams_->AddStream(stream); 316} 317 318void MockPeerConnectionImpl::CreateOffer( 319 CreateSessionDescriptionObserver* observer, 320 const MediaConstraintsInterface* constraints) { 321 DCHECK(observer); 322 created_sessiondescription_.reset( 323 dependency_factory_->CreateSessionDescription("unknown", kDummyOffer, 324 NULL)); 325} 326 327void MockPeerConnectionImpl::CreateAnswer( 328 CreateSessionDescriptionObserver* observer, 329 const MediaConstraintsInterface* constraints) { 330 DCHECK(observer); 331 created_sessiondescription_.reset( 332 dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer, 333 NULL)); 334} 335 336void MockPeerConnectionImpl::SetLocalDescriptionWorker( 337 SetSessionDescriptionObserver* observer, 338 SessionDescriptionInterface* desc) { 339 desc->ToString(&description_sdp_); 340 local_desc_.reset(desc); 341} 342 343void MockPeerConnectionImpl::SetRemoteDescriptionWorker( 344 SetSessionDescriptionObserver* observer, 345 SessionDescriptionInterface* desc) { 346 desc->ToString(&description_sdp_); 347 remote_desc_.reset(desc); 348} 349 350bool MockPeerConnectionImpl::UpdateIce( 351 const IceServers& configuration, 352 const MediaConstraintsInterface* constraints) { 353 return true; 354} 355 356bool MockPeerConnectionImpl::AddIceCandidate( 357 const IceCandidateInterface* candidate) { 358 sdp_mid_ = candidate->sdp_mid(); 359 sdp_mline_index_ = candidate->sdp_mline_index(); 360 return candidate->ToString(&ice_sdp_); 361} 362 363void MockPeerConnectionImpl::RegisterUMAObserver( 364 webrtc::UMAObserver* observer) { 365 NOTIMPLEMENTED(); 366} 367 368} // namespace content 369