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.
5 #include "content/renderer/media/rtc_peer_connection_handler.h"
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/stl_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "content/public/common/content_switches.h"
17 #include "content/renderer/media/media_stream_dependency_factory.h"
18 #include "content/renderer/media/peer_connection_tracker.h"
19 #include "content/renderer/media/remote_media_stream_impl.h"
20 #include "content/renderer/media/rtc_data_channel_handler.h"
21 #include "content/renderer/media/rtc_dtmf_sender_handler.h"
22 #include "content/renderer/media/rtc_media_constraints.h"
23 #include "content/renderer/media/webrtc_audio_capturer.h"
24 #include "content/renderer/media/webrtc_audio_device_impl.h"
25 #include "content/renderer/render_thread_impl.h"
26 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
27 // TODO(hta): Move the following include to WebRTCStatsRequest.h file.
28 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
29 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
30 #include "third_party/WebKit/public/platform/WebRTCConfiguration.h"
31 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
32 #include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
33 #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h"
34 #include "third_party/WebKit/public/platform/WebRTCSessionDescription.h"
35 #include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h"
36 #include "third_party/WebKit/public/platform/WebRTCStatsRequest.h"
37 #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h"
38 #include "third_party/WebKit/public/platform/WebURL.h"
39 #include "third_party/WebKit/public/web/WebFrame.h"
43 // Converter functions from libjingle types to WebKit types.
44 WebKit::WebRTCPeerConnectionHandlerClient::ICEGatheringState
45 GetWebKitIceGatheringState(
46 webrtc::PeerConnectionInterface::IceGatheringState state) {
47 using WebKit::WebRTCPeerConnectionHandlerClient;
49 case webrtc::PeerConnectionInterface::kIceGatheringNew:
50 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew;
51 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
52 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering;
53 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
54 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete;
57 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew;
61 static WebKit::WebRTCPeerConnectionHandlerClient::ICEConnectionState
62 GetWebKitIceConnectionState(
63 webrtc::PeerConnectionInterface::IceConnectionState ice_state) {
64 using WebKit::WebRTCPeerConnectionHandlerClient;
66 case webrtc::PeerConnectionInterface::kIceConnectionNew:
67 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting;
68 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
69 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking;
70 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
71 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected;
72 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
73 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted;
74 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
75 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed;
76 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
77 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected;
78 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
79 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed;
82 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed;
86 static WebKit::WebRTCPeerConnectionHandlerClient::SignalingState
87 GetWebKitSignalingState(webrtc::PeerConnectionInterface::SignalingState state) {
88 using WebKit::WebRTCPeerConnectionHandlerClient;
90 case webrtc::PeerConnectionInterface::kStable:
91 return WebRTCPeerConnectionHandlerClient::SignalingStateStable;
92 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
93 return WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer;
94 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
95 return WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer;
96 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
97 return WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer;
98 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
100 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer;
101 case webrtc::PeerConnectionInterface::kClosed:
102 return WebRTCPeerConnectionHandlerClient::SignalingStateClosed;
105 return WebRTCPeerConnectionHandlerClient::SignalingStateClosed;
109 static WebKit::WebRTCSessionDescription
110 CreateWebKitSessionDescription(
111 const webrtc::SessionDescriptionInterface* native_desc) {
112 WebKit::WebRTCSessionDescription description;
114 LOG(ERROR) << "Native session description is null.";
119 if (!native_desc->ToString(&sdp)) {
120 LOG(ERROR) << "Failed to get SDP string of native session description.";
124 description.initialize(UTF8ToUTF16(native_desc->type()), UTF8ToUTF16(sdp));
128 // Converter functions from WebKit types to libjingle types.
130 static void GetNativeIceServers(
131 const WebKit::WebRTCConfiguration& server_configuration,
132 webrtc::PeerConnectionInterface::IceServers* servers) {
133 if (server_configuration.isNull() || !servers)
135 for (size_t i = 0; i < server_configuration.numberOfServers(); ++i) {
136 webrtc::PeerConnectionInterface::IceServer server;
137 const WebKit::WebRTCICEServer& webkit_server =
138 server_configuration.server(i);
139 server.username = UTF16ToUTF8(webkit_server.username());
140 server.password = UTF16ToUTF8(webkit_server.credential());
141 server.uri = webkit_server.uri().spec();
142 servers->push_back(server);
146 class SessionDescriptionRequestTracker {
148 SessionDescriptionRequestTracker(RTCPeerConnectionHandler* handler,
149 PeerConnectionTracker::Action action)
150 : handler_(handler), action_(action) {}
152 void TrackOnSuccess(const webrtc::SessionDescriptionInterface* desc) {
155 desc->ToString(&value);
156 value = "type: " + desc->type() + ", sdp: " + value;
158 if (handler_->peer_connection_tracker())
159 handler_->peer_connection_tracker()->TrackSessionDescriptionCallback(
160 handler_, action_, "OnSuccess", value);
163 void TrackOnFailure(const std::string& error) {
164 if (handler_->peer_connection_tracker())
165 handler_->peer_connection_tracker()->TrackSessionDescriptionCallback(
166 handler_, action_, "OnFailure", error);
170 RTCPeerConnectionHandler* handler_;
171 PeerConnectionTracker::Action action_;
174 // Class mapping responses from calls to libjingle CreateOffer/Answer and
175 // the WebKit::WebRTCSessionDescriptionRequest.
176 class CreateSessionDescriptionRequest
177 : public webrtc::CreateSessionDescriptionObserver {
179 explicit CreateSessionDescriptionRequest(
180 const WebKit::WebRTCSessionDescriptionRequest& request,
181 RTCPeerConnectionHandler* handler,
182 PeerConnectionTracker::Action action)
183 : webkit_request_(request), tracker_(handler, action) {}
185 virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE {
186 tracker_.TrackOnSuccess(desc);
187 webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc));
189 virtual void OnFailure(const std::string& error) OVERRIDE {
190 tracker_.TrackOnFailure(error);
191 webkit_request_.requestFailed(UTF8ToUTF16(error));
195 virtual ~CreateSessionDescriptionRequest() {}
198 WebKit::WebRTCSessionDescriptionRequest webkit_request_;
199 SessionDescriptionRequestTracker tracker_;
202 // Class mapping responses from calls to libjingle
203 // SetLocalDescription/SetRemoteDescription and a WebKit::WebRTCVoidRequest.
204 class SetSessionDescriptionRequest
205 : public webrtc::SetSessionDescriptionObserver {
207 explicit SetSessionDescriptionRequest(
208 const WebKit::WebRTCVoidRequest& request,
209 RTCPeerConnectionHandler* handler,
210 PeerConnectionTracker::Action action)
211 : webkit_request_(request), tracker_(handler, action) {}
213 virtual void OnSuccess() OVERRIDE {
214 tracker_.TrackOnSuccess(NULL);
215 webkit_request_.requestSucceeded();
217 virtual void OnFailure(const std::string& error) OVERRIDE {
218 tracker_.TrackOnFailure(error);
219 webkit_request_.requestFailed(UTF8ToUTF16(error));
223 virtual ~SetSessionDescriptionRequest() {}
226 WebKit::WebRTCVoidRequest webkit_request_;
227 SessionDescriptionRequestTracker tracker_;
230 // Class mapping responses from calls to libjingle
231 // GetStats into a WebKit::WebRTCStatsCallback.
232 class StatsResponse : public webrtc::StatsObserver {
234 explicit StatsResponse(const scoped_refptr<LocalRTCStatsRequest>& request)
235 : request_(request.get()), response_(request_->createResponse().get()) {}
237 virtual void OnComplete(
238 const std::vector<webrtc::StatsReport>& reports) OVERRIDE {
239 for (std::vector<webrtc::StatsReport>::const_iterator it = reports.begin();
240 it != reports.end(); ++it) {
241 if (it->values.size() > 0) {
245 request_->requestSucceeded(response_);
249 void AddReport(const webrtc::StatsReport& report) {
250 int idx = response_->addReport(WebKit::WebString::fromUTF8(report.id),
251 WebKit::WebString::fromUTF8(report.type),
253 for (webrtc::StatsReport::Values::const_iterator value_it =
254 report.values.begin();
255 value_it != report.values.end(); ++value_it) {
256 AddStatistic(idx, value_it->name, value_it->value);
260 void AddStatistic(int idx, const std::string& name,
261 const std::string& value) {
262 response_->addStatistic(idx,
263 WebKit::WebString::fromUTF8(name),
264 WebKit::WebString::fromUTF8(value));
267 talk_base::scoped_refptr<LocalRTCStatsRequest> request_;
268 talk_base::scoped_refptr<LocalRTCStatsResponse> response_;
271 // Implementation of LocalRTCStatsRequest.
272 LocalRTCStatsRequest::LocalRTCStatsRequest(WebKit::WebRTCStatsRequest impl)
277 LocalRTCStatsRequest::LocalRTCStatsRequest() {}
278 LocalRTCStatsRequest::~LocalRTCStatsRequest() {}
280 bool LocalRTCStatsRequest::hasSelector() const {
281 return impl_.hasSelector();
284 WebKit::WebMediaStreamTrack LocalRTCStatsRequest::component() const {
285 return impl_.component();
288 scoped_refptr<LocalRTCStatsResponse> LocalRTCStatsRequest::createResponse() {
290 response_ = new talk_base::RefCountedObject<LocalRTCStatsResponse>(
291 impl_.createResponse());
292 return response_.get();
295 void LocalRTCStatsRequest::requestSucceeded(
296 const LocalRTCStatsResponse* response) {
297 impl_.requestSucceeded(response->webKitStatsResponse());
300 // Implementation of LocalRTCStatsResponse.
301 WebKit::WebRTCStatsResponse LocalRTCStatsResponse::webKitStatsResponse() const {
305 size_t LocalRTCStatsResponse::addReport(WebKit::WebString type,
306 WebKit::WebString id,
308 return impl_.addReport(type, id, timestamp);
311 void LocalRTCStatsResponse::addStatistic(size_t report,
312 WebKit::WebString name,
313 WebKit::WebString value) {
314 impl_.addStatistic(report, name, value);
317 RTCPeerConnectionHandler::RTCPeerConnectionHandler(
318 WebKit::WebRTCPeerConnectionHandlerClient* client,
319 MediaStreamDependencyFactory* dependency_factory)
320 : PeerConnectionHandlerBase(dependency_factory),
323 peer_connection_tracker_(NULL) {
326 RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
327 if (peer_connection_tracker_)
328 peer_connection_tracker_->UnregisterPeerConnection(this);
329 STLDeleteValues(&remote_streams_);
332 void RTCPeerConnectionHandler::associateWithFrame(WebKit::WebFrame* frame) {
337 bool RTCPeerConnectionHandler::initialize(
338 const WebKit::WebRTCConfiguration& server_configuration,
339 const WebKit::WebMediaConstraints& options) {
342 peer_connection_tracker_ =
343 RenderThreadImpl::current()->peer_connection_tracker();
345 webrtc::PeerConnectionInterface::IceServers servers;
346 GetNativeIceServers(server_configuration, &servers);
348 RTCMediaConstraints constraints(options);
350 native_peer_connection_ =
351 dependency_factory_->CreatePeerConnection(
352 servers, &constraints, frame_, this);
353 if (!native_peer_connection_.get()) {
354 LOG(ERROR) << "Failed to initialize native PeerConnection.";
357 if (peer_connection_tracker_)
358 peer_connection_tracker_->RegisterPeerConnection(
359 this, servers, constraints, frame_);
364 bool RTCPeerConnectionHandler::InitializeForTest(
365 const WebKit::WebRTCConfiguration& server_configuration,
366 const WebKit::WebMediaConstraints& options,
367 PeerConnectionTracker* peer_connection_tracker) {
368 webrtc::PeerConnectionInterface::IceServers servers;
369 GetNativeIceServers(server_configuration, &servers);
371 RTCMediaConstraints constraints(options);
372 native_peer_connection_ =
373 dependency_factory_->CreatePeerConnection(
374 servers, &constraints, NULL, this);
375 if (!native_peer_connection_.get()) {
376 LOG(ERROR) << "Failed to initialize native PeerConnection.";
379 peer_connection_tracker_ = peer_connection_tracker;
383 void RTCPeerConnectionHandler::createOffer(
384 const WebKit::WebRTCSessionDescriptionRequest& request,
385 const WebKit::WebMediaConstraints& options) {
386 scoped_refptr<CreateSessionDescriptionRequest> description_request(
387 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
388 request, this, PeerConnectionTracker::ACTION_CREATE_OFFER));
389 RTCMediaConstraints constraints(options);
390 native_peer_connection_->CreateOffer(description_request.get(), &constraints);
392 if (peer_connection_tracker_)
393 peer_connection_tracker_->TrackCreateOffer(this, constraints);
396 void RTCPeerConnectionHandler::createAnswer(
397 const WebKit::WebRTCSessionDescriptionRequest& request,
398 const WebKit::WebMediaConstraints& options) {
399 scoped_refptr<CreateSessionDescriptionRequest> description_request(
400 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
401 request, this, PeerConnectionTracker::ACTION_CREATE_ANSWER));
402 RTCMediaConstraints constraints(options);
403 native_peer_connection_->CreateAnswer(description_request.get(),
406 if (peer_connection_tracker_)
407 peer_connection_tracker_->TrackCreateAnswer(this, constraints);
410 void RTCPeerConnectionHandler::setLocalDescription(
411 const WebKit::WebRTCVoidRequest& request,
412 const WebKit::WebRTCSessionDescription& description) {
413 webrtc::SdpParseError error;
414 webrtc::SessionDescriptionInterface* native_desc =
415 CreateNativeSessionDescription(description, &error);
417 std::string reason_str = "Failed to parse SessionDescription. ";
418 reason_str.append(error.line);
419 reason_str.append(" ");
420 reason_str.append(error.description);
421 LOG(ERROR) << reason_str;
422 request.requestFailed(WebKit::WebString::fromUTF8(reason_str));
425 if (peer_connection_tracker_)
426 peer_connection_tracker_->TrackSetSessionDescription(
427 this, description, PeerConnectionTracker::SOURCE_LOCAL);
429 scoped_refptr<SetSessionDescriptionRequest> set_request(
430 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(
431 request, this, PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
432 native_peer_connection_->SetLocalDescription(set_request.get(), native_desc);
435 void RTCPeerConnectionHandler::setRemoteDescription(
436 const WebKit::WebRTCVoidRequest& request,
437 const WebKit::WebRTCSessionDescription& description) {
438 webrtc::SdpParseError error;
439 webrtc::SessionDescriptionInterface* native_desc =
440 CreateNativeSessionDescription(description, &error);
442 std::string reason_str = "Failed to parse SessionDescription. ";
443 reason_str.append(error.line);
444 reason_str.append(" ");
445 reason_str.append(error.description);
446 LOG(ERROR) << reason_str;
447 request.requestFailed(WebKit::WebString::fromUTF8(reason_str));
450 if (peer_connection_tracker_)
451 peer_connection_tracker_->TrackSetSessionDescription(
452 this, description, PeerConnectionTracker::SOURCE_REMOTE);
454 scoped_refptr<SetSessionDescriptionRequest> set_request(
455 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(
456 request, this, PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION));
457 native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc);
460 WebKit::WebRTCSessionDescription
461 RTCPeerConnectionHandler::localDescription() {
462 const webrtc::SessionDescriptionInterface* native_desc =
463 native_peer_connection_->local_description();
464 WebKit::WebRTCSessionDescription description =
465 CreateWebKitSessionDescription(native_desc);
469 WebKit::WebRTCSessionDescription
470 RTCPeerConnectionHandler::remoteDescription() {
471 const webrtc::SessionDescriptionInterface* native_desc =
472 native_peer_connection_->remote_description();
473 WebKit::WebRTCSessionDescription description =
474 CreateWebKitSessionDescription(native_desc);
478 bool RTCPeerConnectionHandler::updateICE(
479 const WebKit::WebRTCConfiguration& server_configuration,
480 const WebKit::WebMediaConstraints& options) {
481 webrtc::PeerConnectionInterface::IceServers servers;
482 GetNativeIceServers(server_configuration, &servers);
483 RTCMediaConstraints constraints(options);
485 if (peer_connection_tracker_)
486 peer_connection_tracker_->TrackUpdateIce(this, servers, constraints);
488 return native_peer_connection_->UpdateIce(servers,
492 bool RTCPeerConnectionHandler::addICECandidate(
493 const WebKit::WebRTCICECandidate& candidate) {
494 scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
495 dependency_factory_->CreateIceCandidate(
496 UTF16ToUTF8(candidate.sdpMid()),
497 candidate.sdpMLineIndex(),
498 UTF16ToUTF8(candidate.candidate())));
499 if (!native_candidate) {
500 LOG(ERROR) << "Could not create native ICE candidate.";
505 native_peer_connection_->AddIceCandidate(native_candidate.get());
506 LOG_IF(ERROR, !return_value) << "Error processing ICE candidate.";
508 if (peer_connection_tracker_)
509 peer_connection_tracker_->TrackAddIceCandidate(
510 this, candidate, PeerConnectionTracker::SOURCE_REMOTE);
515 bool RTCPeerConnectionHandler::addStream(
516 const WebKit::WebMediaStream& stream,
517 const WebKit::WebMediaConstraints& options) {
518 RTCMediaConstraints constraints(options);
520 if (peer_connection_tracker_)
521 peer_connection_tracker_->TrackAddStream(
522 this, stream, PeerConnectionTracker::SOURCE_LOCAL);
524 // A media stream is connected to a peer connection, enable the
525 // peer connection mode for the capturer.
526 WebRtcAudioDeviceImpl* audio_device =
527 dependency_factory_->GetWebRtcAudioDevice();
529 WebRtcAudioCapturer* capturer = audio_device->GetDefaultCapturer();
531 capturer->EnablePeerConnectionMode();
534 return AddStream(stream, &constraints);
537 void RTCPeerConnectionHandler::removeStream(
538 const WebKit::WebMediaStream& stream) {
539 RemoveStream(stream);
540 if (peer_connection_tracker_)
541 peer_connection_tracker_->TrackRemoveStream(
542 this, stream, PeerConnectionTracker::SOURCE_LOCAL);
545 void RTCPeerConnectionHandler::getStats(
546 const WebKit::WebRTCStatsRequest& request) {
547 scoped_refptr<LocalRTCStatsRequest> inner_request(
548 new talk_base::RefCountedObject<LocalRTCStatsRequest>(request));
549 getStats(inner_request.get());
552 void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) {
553 talk_base::scoped_refptr<webrtc::StatsObserver> observer(
554 new talk_base::RefCountedObject<StatsResponse>(request));
555 webrtc::MediaStreamTrackInterface* track = NULL;
556 if (request->hasSelector()) {
557 track = MediaStreamDependencyFactory::GetNativeMediaStreamTrack(
558 request->component());
560 DVLOG(1) << "GetStats: Track not found.";
561 // TODO(hta): Consider how to get an error back.
562 std::vector<webrtc::StatsReport> no_reports;
563 observer->OnComplete(no_reports);
567 GetStats(observer, track);
570 void RTCPeerConnectionHandler::GetStats(
571 webrtc::StatsObserver* observer,
572 webrtc::MediaStreamTrackInterface* track) {
573 if (!native_peer_connection_->GetStats(observer, track)) {
574 DVLOG(1) << "GetStats failed.";
575 // TODO(hta): Consider how to get an error back.
576 std::vector<webrtc::StatsReport> no_reports;
577 observer->OnComplete(no_reports);
582 WebKit::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel(
583 const WebKit::WebString& label, const WebKit::WebRTCDataChannelInit& init) {
584 DVLOG(1) << "createDataChannel label " << UTF16ToUTF8(label);
586 webrtc::DataChannelInit config;
587 // TODO(jiayl): remove the deprecated reliable field once Libjingle is updated
589 config.reliable = false;
591 config.ordered = init.ordered;
592 config.negotiated = init.negotiated;
593 config.maxRetransmits = init.maxRetransmits;
594 config.maxRetransmitTime = init.maxRetransmitTime;
595 config.protocol = UTF16ToUTF8(init.protocol);
597 talk_base::scoped_refptr<webrtc::DataChannelInterface> webrtc_channel(
598 native_peer_connection_->CreateDataChannel(UTF16ToUTF8(label), &config));
599 if (!webrtc_channel) {
600 DLOG(ERROR) << "Could not create native data channel.";
603 if (peer_connection_tracker_)
604 peer_connection_tracker_->TrackCreateDataChannel(
605 this, webrtc_channel.get(), PeerConnectionTracker::SOURCE_LOCAL);
607 return new RtcDataChannelHandler(webrtc_channel);
610 WebKit::WebRTCDTMFSenderHandler* RTCPeerConnectionHandler::createDTMFSender(
611 const WebKit::WebMediaStreamTrack& track) {
612 DVLOG(1) << "createDTMFSender.";
614 if (track.source().type() != WebKit::WebMediaStreamSource::TypeAudio) {
615 DLOG(ERROR) << "Could not create DTMF sender from a non-audio track.";
619 webrtc::AudioTrackInterface* audio_track =
620 static_cast<webrtc::AudioTrackInterface*>(
621 MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track));
623 talk_base::scoped_refptr<webrtc::DtmfSenderInterface> sender(
624 native_peer_connection_->CreateDtmfSender(audio_track));
626 DLOG(ERROR) << "Could not create native DTMF sender.";
629 if (peer_connection_tracker_)
630 peer_connection_tracker_->TrackCreateDTMFSender(this, track);
632 return new RtcDtmfSenderHandler(sender);
635 void RTCPeerConnectionHandler::stop() {
636 DVLOG(1) << "RTCPeerConnectionHandler::stop";
638 if (peer_connection_tracker_)
639 peer_connection_tracker_->TrackStop(this);
640 native_peer_connection_->Close();
643 void RTCPeerConnectionHandler::OnError() {
644 // TODO(perkj): Implement.
648 void RTCPeerConnectionHandler::OnSignalingChange(
649 webrtc::PeerConnectionInterface::SignalingState new_state) {
650 WebKit::WebRTCPeerConnectionHandlerClient::SignalingState state =
651 GetWebKitSignalingState(new_state);
652 if (peer_connection_tracker_)
653 peer_connection_tracker_->TrackSignalingStateChange(this, state);
654 client_->didChangeSignalingState(state);
657 // Called any time the IceConnectionState changes
658 void RTCPeerConnectionHandler::OnIceConnectionChange(
659 webrtc::PeerConnectionInterface::IceConnectionState new_state) {
660 WebKit::WebRTCPeerConnectionHandlerClient::ICEConnectionState state =
661 GetWebKitIceConnectionState(new_state);
662 if (peer_connection_tracker_)
663 peer_connection_tracker_->TrackIceConnectionStateChange(this, state);
664 client_->didChangeICEConnectionState(state);
667 // Called any time the IceGatheringState changes
668 void RTCPeerConnectionHandler::OnIceGatheringChange(
669 webrtc::PeerConnectionInterface::IceGatheringState new_state) {
670 if (new_state == webrtc::PeerConnectionInterface::kIceGatheringComplete) {
671 // If ICE gathering is completed, generate a NULL ICE candidate,
672 // to signal end of candidates.
673 WebKit::WebRTCICECandidate null_candidate;
674 client_->didGenerateICECandidate(null_candidate);
677 WebKit::WebRTCPeerConnectionHandlerClient::ICEGatheringState state =
678 GetWebKitIceGatheringState(new_state);
679 if (peer_connection_tracker_)
680 peer_connection_tracker_->TrackIceGatheringStateChange(this, state);
681 client_->didChangeICEGatheringState(state);
684 void RTCPeerConnectionHandler::OnAddStream(
685 webrtc::MediaStreamInterface* stream_interface) {
686 DCHECK(stream_interface);
687 DCHECK(remote_streams_.find(stream_interface) == remote_streams_.end());
689 RemoteMediaStreamImpl* remote_stream =
690 new RemoteMediaStreamImpl(stream_interface);
691 remote_streams_.insert(
692 std::pair<webrtc::MediaStreamInterface*, RemoteMediaStreamImpl*> (
693 stream_interface, remote_stream));
695 if (peer_connection_tracker_)
696 peer_connection_tracker_->TrackAddStream(
697 this, remote_stream->webkit_stream(),
698 PeerConnectionTracker::SOURCE_REMOTE);
700 client_->didAddRemoteStream(remote_stream->webkit_stream());
703 void RTCPeerConnectionHandler::OnRemoveStream(
704 webrtc::MediaStreamInterface* stream_interface) {
705 DCHECK(stream_interface);
706 RemoteStreamMap::iterator it = remote_streams_.find(stream_interface);
707 if (it == remote_streams_.end()) {
708 NOTREACHED() << "Stream not found";
712 scoped_ptr<RemoteMediaStreamImpl> remote_stream(it->second);
713 const WebKit::WebMediaStream& webkit_stream = remote_stream->webkit_stream();
714 DCHECK(!webkit_stream.isNull());
715 remote_streams_.erase(it);
717 if (peer_connection_tracker_)
718 peer_connection_tracker_->TrackRemoveStream(
719 this, webkit_stream, PeerConnectionTracker::SOURCE_REMOTE);
721 client_->didRemoveRemoteStream(webkit_stream);
724 void RTCPeerConnectionHandler::OnIceCandidate(
725 const webrtc::IceCandidateInterface* candidate) {
728 if (!candidate->ToString(&sdp)) {
729 NOTREACHED() << "OnIceCandidate: Could not get SDP string.";
732 WebKit::WebRTCICECandidate web_candidate;
733 web_candidate.initialize(UTF8ToUTF16(sdp),
734 UTF8ToUTF16(candidate->sdp_mid()),
735 candidate->sdp_mline_index());
736 if (peer_connection_tracker_)
737 peer_connection_tracker_->TrackAddIceCandidate(
738 this, web_candidate, PeerConnectionTracker::SOURCE_LOCAL);
740 client_->didGenerateICECandidate(web_candidate);
743 void RTCPeerConnectionHandler::OnDataChannel(
744 webrtc::DataChannelInterface* data_channel) {
745 if (peer_connection_tracker_)
746 peer_connection_tracker_->TrackCreateDataChannel(
747 this, data_channel, PeerConnectionTracker::SOURCE_REMOTE);
749 DVLOG(1) << "RTCPeerConnectionHandler::OnDataChannel "
750 << data_channel->label();
751 client_->didAddRemoteDataChannel(new RtcDataChannelHandler(data_channel));
754 void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
755 if (peer_connection_tracker_)
756 peer_connection_tracker_->TrackOnRenegotiationNeeded(this);
757 client_->negotiationNeeded();
760 PeerConnectionTracker* RTCPeerConnectionHandler::peer_connection_tracker() {
761 return peer_connection_tracker_;
764 webrtc::SessionDescriptionInterface*
765 RTCPeerConnectionHandler::CreateNativeSessionDescription(
766 const WebKit::WebRTCSessionDescription& description,
767 webrtc::SdpParseError* error) {
768 std::string sdp = UTF16ToUTF8(description.sdp());
769 std::string type = UTF16ToUTF8(description.type());
770 webrtc::SessionDescriptionInterface* native_desc =
771 dependency_factory_->CreateSessionDescription(type, sdp, error);
773 LOG_IF(ERROR, !native_desc) << "Failed to create native session description."
774 << " Type: " << type << " SDP: " << sdp;
779 } // namespace content