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/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/utf_string_conversions.h"
14 #include "content/renderer/media/media_stream_dependency_factory.h"
15 #include "content/renderer/media/peer_connection_tracker.h"
16 #include "content/renderer/media/rtc_data_channel_handler.h"
17 #include "content/renderer/media/rtc_dtmf_sender_handler.h"
18 #include "content/renderer/media/rtc_media_constraints.h"
19 #include "content/renderer/render_thread_impl.h"
20 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints.h"
21 // TODO(hta): Move the following include to WebRTCStatsRequest.h file.
22 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSource.h"
23 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamTrack.h"
24 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCConfiguration.h"
25 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCICECandidate.h"
26 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectionHandlerClient.h"
27 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescription.h"
28 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescriptionRequest.h"
29 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCStatsRequest.h"
30 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCVoidRequest.h"
31 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
36 // Converter functions from libjingle types to WebKit types.
37 WebKit::WebRTCPeerConnectionHandlerClient::ICEGatheringState
38 GetWebKitIceGatheringState(
39 webrtc::PeerConnectionInterface::IceGatheringState state
) {
40 using WebKit::WebRTCPeerConnectionHandlerClient
;
42 case webrtc::PeerConnectionInterface::kIceGatheringNew
:
43 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew
;
44 case webrtc::PeerConnectionInterface::kIceGatheringGathering
:
45 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering
;
46 case webrtc::PeerConnectionInterface::kIceGatheringComplete
:
47 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete
;
50 return WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew
;
54 static WebKit::WebRTCPeerConnectionHandlerClient::ICEConnectionState
55 GetWebKitIceConnectionState(
56 webrtc::PeerConnectionInterface::IceConnectionState ice_state
) {
57 using WebKit::WebRTCPeerConnectionHandlerClient
;
59 case webrtc::PeerConnectionInterface::kIceConnectionNew
:
60 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting
;
61 case webrtc::PeerConnectionInterface::kIceConnectionChecking
:
62 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking
;
63 case webrtc::PeerConnectionInterface::kIceConnectionConnected
:
64 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected
;
65 case webrtc::PeerConnectionInterface::kIceConnectionCompleted
:
66 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted
;
67 case webrtc::PeerConnectionInterface::kIceConnectionFailed
:
68 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed
;
69 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected
:
70 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected
;
71 case webrtc::PeerConnectionInterface::kIceConnectionClosed
:
72 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed
;
75 return WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed
;
79 static WebKit::WebRTCPeerConnectionHandlerClient::SignalingState
80 GetWebKitSignalingState(webrtc::PeerConnectionInterface::SignalingState state
) {
81 using WebKit::WebRTCPeerConnectionHandlerClient
;
83 case webrtc::PeerConnectionInterface::kStable
:
84 return WebRTCPeerConnectionHandlerClient::SignalingStateStable
;
85 case webrtc::PeerConnectionInterface::kHaveLocalOffer
:
86 return WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer
;
87 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer
:
88 return WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer
;
89 case webrtc::PeerConnectionInterface::kHaveRemoteOffer
:
90 return WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer
;
91 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer
:
93 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer
;
94 case webrtc::PeerConnectionInterface::kClosed
:
95 return WebRTCPeerConnectionHandlerClient::SignalingStateClosed
;
98 return WebRTCPeerConnectionHandlerClient::SignalingStateClosed
;
102 static WebKit::WebRTCSessionDescription
103 CreateWebKitSessionDescription(
104 const webrtc::SessionDescriptionInterface
* native_desc
) {
105 WebKit::WebRTCSessionDescription description
;
107 LOG(ERROR
) << "Native session description is null.";
112 if (!native_desc
->ToString(&sdp
)) {
113 LOG(ERROR
) << "Failed to get SDP string of native session description.";
117 description
.initialize(UTF8ToUTF16(native_desc
->type()), UTF8ToUTF16(sdp
));
121 // Converter functions from WebKit types to libjingle types.
123 static void GetNativeIceServers(
124 const WebKit::WebRTCConfiguration
& server_configuration
,
125 webrtc::PeerConnectionInterface::IceServers
* servers
) {
126 if (server_configuration
.isNull() || !servers
)
128 for (size_t i
= 0; i
< server_configuration
.numberOfServers(); ++i
) {
129 webrtc::PeerConnectionInterface::IceServer server
;
130 const WebKit::WebRTCICEServer
& webkit_server
=
131 server_configuration
.server(i
);
132 server
.password
= UTF16ToUTF8(webkit_server
.credential());
133 server
.uri
= webkit_server
.uri().spec();
134 servers
->push_back(server
);
138 class SessionDescriptionRequestTracker
{
140 SessionDescriptionRequestTracker(RTCPeerConnectionHandler
* handler
,
141 PeerConnectionTracker::Action action
)
142 : handler_(handler
), action_(action
) {}
144 void TrackOnSuccess(const webrtc::SessionDescriptionInterface
* desc
) {
147 desc
->ToString(&value
);
148 value
= "type: " + desc
->type() + ", sdp: " + value
;
150 if (handler_
->peer_connection_tracker())
151 handler_
->peer_connection_tracker()->TrackSessionDescriptionCallback(
152 handler_
, action_
, "OnSuccess", value
);
155 void TrackOnFailure(const std::string
& error
) {
156 if (handler_
->peer_connection_tracker())
157 handler_
->peer_connection_tracker()->TrackSessionDescriptionCallback(
158 handler_
, action_
, "OnFailure", error
);
162 RTCPeerConnectionHandler
* handler_
;
163 PeerConnectionTracker::Action action_
;
166 // Class mapping responses from calls to libjingle CreateOffer/Answer and
167 // the WebKit::WebRTCSessionDescriptionRequest.
168 class CreateSessionDescriptionRequest
169 : public webrtc::CreateSessionDescriptionObserver
{
171 explicit CreateSessionDescriptionRequest(
172 const WebKit::WebRTCSessionDescriptionRequest
& request
,
173 RTCPeerConnectionHandler
* handler
,
174 PeerConnectionTracker::Action action
)
175 : webkit_request_(request
), tracker_(handler
, action
) {}
177 virtual void OnSuccess(webrtc::SessionDescriptionInterface
* desc
) OVERRIDE
{
178 tracker_
.TrackOnSuccess(desc
);
179 webkit_request_
.requestSucceeded(CreateWebKitSessionDescription(desc
));
181 virtual void OnFailure(const std::string
& error
) OVERRIDE
{
182 tracker_
.TrackOnFailure(error
);
183 webkit_request_
.requestFailed(UTF8ToUTF16(error
));
187 virtual ~CreateSessionDescriptionRequest() {}
190 WebKit::WebRTCSessionDescriptionRequest webkit_request_
;
191 SessionDescriptionRequestTracker tracker_
;
194 // Class mapping responses from calls to libjingle
195 // SetLocalDescription/SetRemoteDescription and a WebKit::WebRTCVoidRequest.
196 class SetSessionDescriptionRequest
197 : public webrtc::SetSessionDescriptionObserver
{
199 explicit SetSessionDescriptionRequest(
200 const WebKit::WebRTCVoidRequest
& request
,
201 RTCPeerConnectionHandler
* handler
,
202 PeerConnectionTracker::Action action
)
203 : webkit_request_(request
), tracker_(handler
, action
) {}
205 virtual void OnSuccess() OVERRIDE
{
206 tracker_
.TrackOnSuccess(NULL
);
207 webkit_request_
.requestSucceeded();
209 virtual void OnFailure(const std::string
& error
) OVERRIDE
{
210 tracker_
.TrackOnFailure(error
);
211 webkit_request_
.requestFailed(UTF8ToUTF16(error
));
215 virtual ~SetSessionDescriptionRequest() {}
218 WebKit::WebRTCVoidRequest webkit_request_
;
219 SessionDescriptionRequestTracker tracker_
;
222 // Class mapping responses from calls to libjingle
223 // GetStats into a WebKit::WebRTCStatsCallback.
224 class StatsResponse
: public webrtc::StatsObserver
{
226 explicit StatsResponse(const scoped_refptr
<LocalRTCStatsRequest
>& request
)
228 response_(request_
->createResponse()) {}
230 virtual void OnComplete(
231 const std::vector
<webrtc::StatsReport
>& reports
) OVERRIDE
{
232 for (std::vector
<webrtc::StatsReport
>::const_iterator it
= reports
.begin();
233 it
!= reports
.end(); ++it
) {
234 if (it
->values
.size() > 0) {
238 request_
->requestSucceeded(response_
);
242 void AddReport(const webrtc::StatsReport
& report
) {
243 int idx
= response_
->addReport(WebKit::WebString::fromUTF8(report
.id
),
244 WebKit::WebString::fromUTF8(report
.type
),
246 for (webrtc::StatsReport::Values::const_iterator value_it
=
247 report
.values
.begin();
248 value_it
!= report
.values
.end(); ++value_it
) {
249 AddStatistic(idx
, value_it
->name
, value_it
->value
);
253 void AddStatistic(int idx
, const std::string
& name
,
254 const std::string
& value
) {
255 response_
->addStatistic(idx
,
256 WebKit::WebString::fromUTF8(name
),
257 WebKit::WebString::fromUTF8(value
));
260 talk_base::scoped_refptr
<LocalRTCStatsRequest
> request_
;
261 talk_base::scoped_refptr
<LocalRTCStatsResponse
> response_
;
264 // Implementation of LocalRTCStatsRequest.
265 LocalRTCStatsRequest::LocalRTCStatsRequest(WebKit::WebRTCStatsRequest impl
)
270 LocalRTCStatsRequest::LocalRTCStatsRequest() {}
271 LocalRTCStatsRequest::~LocalRTCStatsRequest() {}
273 bool LocalRTCStatsRequest::hasSelector() const {
274 return impl_
.hasSelector();
277 WebKit::WebMediaStream
LocalRTCStatsRequest::stream() const {
278 return impl_
.stream();
281 WebKit::WebMediaStreamTrack
LocalRTCStatsRequest::component() const {
282 return impl_
.component();
285 scoped_refptr
<LocalRTCStatsResponse
> LocalRTCStatsRequest::createResponse() {
287 response_
= new talk_base::RefCountedObject
<LocalRTCStatsResponse
>(
288 impl_
.createResponse());
289 return response_
.get();
292 void LocalRTCStatsRequest::requestSucceeded(
293 const LocalRTCStatsResponse
* response
) {
294 impl_
.requestSucceeded(response
->webKitStatsResponse());
297 // Implementation of LocalRTCStatsResponse.
298 WebKit::WebRTCStatsResponse
LocalRTCStatsResponse::webKitStatsResponse() const {
302 size_t LocalRTCStatsResponse::addReport(WebKit::WebString type
,
303 WebKit::WebString id
,
305 return impl_
.addReport(type
, id
, timestamp
);
308 void LocalRTCStatsResponse::addStatistic(size_t report
,
309 WebKit::WebString name
,
310 WebKit::WebString value
) {
311 impl_
.addStatistic(report
, name
, value
);
314 RTCPeerConnectionHandler::RTCPeerConnectionHandler(
315 WebKit::WebRTCPeerConnectionHandlerClient
* client
,
316 MediaStreamDependencyFactory
* dependency_factory
)
317 : PeerConnectionHandlerBase(dependency_factory
),
320 peer_connection_tracker_(NULL
) {
323 RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
324 if (peer_connection_tracker_
)
325 peer_connection_tracker_
->UnregisterPeerConnection(this);
328 void RTCPeerConnectionHandler::associateWithFrame(WebKit::WebFrame
* frame
) {
333 bool RTCPeerConnectionHandler::initialize(
334 const WebKit::WebRTCConfiguration
& server_configuration
,
335 const WebKit::WebMediaConstraints
& options
) {
338 peer_connection_tracker_
=
339 RenderThreadImpl::current()->peer_connection_tracker();
341 webrtc::PeerConnectionInterface::IceServers servers
;
342 GetNativeIceServers(server_configuration
, &servers
);
344 RTCMediaConstraints
constraints(options
);
345 native_peer_connection_
=
346 dependency_factory_
->CreatePeerConnection(
347 servers
, &constraints
, frame_
, this);
348 if (!native_peer_connection_
) {
349 LOG(ERROR
) << "Failed to initialize native PeerConnection.";
352 if (peer_connection_tracker_
)
353 peer_connection_tracker_
->RegisterPeerConnection(
354 this, servers
, constraints
, frame_
);
359 bool RTCPeerConnectionHandler::InitializeForTest(
360 const WebKit::WebRTCConfiguration
& server_configuration
,
361 const WebKit::WebMediaConstraints
& options
,
362 PeerConnectionTracker
* peer_connection_tracker
) {
363 webrtc::PeerConnectionInterface::IceServers servers
;
364 GetNativeIceServers(server_configuration
, &servers
);
366 RTCMediaConstraints
constraints(options
);
367 native_peer_connection_
=
368 dependency_factory_
->CreatePeerConnection(
369 servers
, &constraints
, NULL
, this);
370 if (!native_peer_connection_
) {
371 LOG(ERROR
) << "Failed to initialize native PeerConnection.";
374 peer_connection_tracker_
= peer_connection_tracker
;
378 void RTCPeerConnectionHandler::createOffer(
379 const WebKit::WebRTCSessionDescriptionRequest
& request
,
380 const WebKit::WebMediaConstraints
& options
) {
381 scoped_refptr
<CreateSessionDescriptionRequest
> description_request(
382 new talk_base::RefCountedObject
<CreateSessionDescriptionRequest
>(
383 request
, this, PeerConnectionTracker::ACTION_CREATE_OFFER
));
384 RTCMediaConstraints
constraints(options
);
385 native_peer_connection_
->CreateOffer(description_request
, &constraints
);
387 if (peer_connection_tracker_
)
388 peer_connection_tracker_
->TrackCreateOffer(this, constraints
);
391 void RTCPeerConnectionHandler::createAnswer(
392 const WebKit::WebRTCSessionDescriptionRequest
& request
,
393 const WebKit::WebMediaConstraints
& options
) {
394 scoped_refptr
<CreateSessionDescriptionRequest
> description_request(
395 new talk_base::RefCountedObject
<CreateSessionDescriptionRequest
>(
396 request
, this, PeerConnectionTracker::ACTION_CREATE_ANSWER
));
397 RTCMediaConstraints
constraints(options
);
398 native_peer_connection_
->CreateAnswer(description_request
, &constraints
);
400 if (peer_connection_tracker_
)
401 peer_connection_tracker_
->TrackCreateAnswer(this, constraints
);
404 void RTCPeerConnectionHandler::setLocalDescription(
405 const WebKit::WebRTCVoidRequest
& request
,
406 const WebKit::WebRTCSessionDescription
& description
) {
407 webrtc::SdpParseError error
;
408 webrtc::SessionDescriptionInterface
* native_desc
=
409 CreateNativeSessionDescription(description
, &error
);
411 std::string reason_str
= "Failed to parse SessionDescription. ";
412 reason_str
.append(error
.line
);
413 reason_str
.append(" ");
414 reason_str
.append(error
.description
);
415 LOG(ERROR
) << reason_str
;
416 request
.requestFailed(WebKit::WebString::fromUTF8(reason_str
));
419 if (peer_connection_tracker_
)
420 peer_connection_tracker_
->TrackSetSessionDescription(
421 this, native_desc
, PeerConnectionTracker::SOURCE_LOCAL
);
423 scoped_refptr
<SetSessionDescriptionRequest
> set_request(
424 new talk_base::RefCountedObject
<SetSessionDescriptionRequest
>(
425 request
, this, PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION
));
426 native_peer_connection_
->SetLocalDescription(set_request
, native_desc
);
429 void RTCPeerConnectionHandler::setRemoteDescription(
430 const WebKit::WebRTCVoidRequest
& request
,
431 const WebKit::WebRTCSessionDescription
& description
) {
432 webrtc::SdpParseError error
;
433 webrtc::SessionDescriptionInterface
* native_desc
=
434 CreateNativeSessionDescription(description
, &error
);
436 std::string reason_str
= "Failed to parse SessionDescription. ";
437 reason_str
.append(error
.line
);
438 reason_str
.append(" ");
439 reason_str
.append(error
.description
);
440 LOG(ERROR
) << reason_str
;
441 request
.requestFailed(WebKit::WebString::fromUTF8(reason_str
));
444 if (peer_connection_tracker_
)
445 peer_connection_tracker_
->TrackSetSessionDescription(
446 this, native_desc
, PeerConnectionTracker::SOURCE_REMOTE
);
448 scoped_refptr
<SetSessionDescriptionRequest
> set_request(
449 new talk_base::RefCountedObject
<SetSessionDescriptionRequest
>(
450 request
, this, PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION
));
451 native_peer_connection_
->SetRemoteDescription(set_request
, native_desc
);
454 WebKit::WebRTCSessionDescription
455 RTCPeerConnectionHandler::localDescription() {
456 const webrtc::SessionDescriptionInterface
* native_desc
=
457 native_peer_connection_
->local_description();
458 WebKit::WebRTCSessionDescription description
=
459 CreateWebKitSessionDescription(native_desc
);
463 WebKit::WebRTCSessionDescription
464 RTCPeerConnectionHandler::remoteDescription() {
465 const webrtc::SessionDescriptionInterface
* native_desc
=
466 native_peer_connection_
->remote_description();
467 WebKit::WebRTCSessionDescription description
=
468 CreateWebKitSessionDescription(native_desc
);
472 bool RTCPeerConnectionHandler::updateICE(
473 const WebKit::WebRTCConfiguration
& server_configuration
,
474 const WebKit::WebMediaConstraints
& options
) {
475 webrtc::PeerConnectionInterface::IceServers servers
;
476 GetNativeIceServers(server_configuration
, &servers
);
477 RTCMediaConstraints
constraints(options
);
479 if (peer_connection_tracker_
)
480 peer_connection_tracker_
->TrackUpdateIce(this, servers
, constraints
);
482 return native_peer_connection_
->UpdateIce(servers
,
486 bool RTCPeerConnectionHandler::addICECandidate(
487 const WebKit::WebRTCICECandidate
& candidate
) {
488 scoped_ptr
<webrtc::IceCandidateInterface
> native_candidate(
489 dependency_factory_
->CreateIceCandidate(
490 UTF16ToUTF8(candidate
.sdpMid()),
491 candidate
.sdpMLineIndex(),
492 UTF16ToUTF8(candidate
.candidate())));
493 if (!native_candidate
.get()) {
494 LOG(ERROR
) << "Could not create native ICE candidate.";
499 native_peer_connection_
->AddIceCandidate(native_candidate
.get());
500 LOG_IF(ERROR
, !return_value
) << "Error processing ICE candidate.";
502 if (peer_connection_tracker_
)
503 peer_connection_tracker_
->TrackAddIceCandidate(
504 this, candidate
, PeerConnectionTracker::SOURCE_REMOTE
);
509 bool RTCPeerConnectionHandler::addStream(
510 const WebKit::WebMediaStream
& stream
,
511 const WebKit::WebMediaConstraints
& options
) {
512 RTCMediaConstraints
constraints(options
);
514 if (peer_connection_tracker_
)
515 peer_connection_tracker_
->TrackAddStream(
516 this, stream
, PeerConnectionTracker::SOURCE_LOCAL
);
517 return AddStream(stream
, &constraints
);
520 void RTCPeerConnectionHandler::removeStream(
521 const WebKit::WebMediaStream
& stream
) {
522 RemoveStream(stream
);
523 if (peer_connection_tracker_
)
524 peer_connection_tracker_
->TrackRemoveStream(
525 this, stream
, PeerConnectionTracker::SOURCE_LOCAL
);
528 void RTCPeerConnectionHandler::getStats(
529 const WebKit::WebRTCStatsRequest
& request
) {
530 scoped_refptr
<LocalRTCStatsRequest
> inner_request(
531 new talk_base::RefCountedObject
<LocalRTCStatsRequest
>(request
));
532 getStats(inner_request
);
535 void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest
* request
) {
536 talk_base::scoped_refptr
<webrtc::StatsObserver
> observer(
537 new talk_base::RefCountedObject
<StatsResponse
>(request
));
538 webrtc::MediaStreamTrackInterface
* track
= NULL
;
539 if (request
->hasSelector()) {
540 track
= GetNativeMediaStreamTrack(request
->stream(),
541 request
->component());
543 DVLOG(1) << "GetStats: Track not found.";
544 // TODO(hta): Consider how to get an error back.
545 std::vector
<webrtc::StatsReport
> no_reports
;
546 observer
->OnComplete(no_reports
);
550 GetStats(observer
, track
);
553 void RTCPeerConnectionHandler::GetStats(
554 webrtc::StatsObserver
* observer
,
555 webrtc::MediaStreamTrackInterface
* track
) {
556 if (!native_peer_connection_
->GetStats(observer
, track
)) {
557 DVLOG(1) << "GetStats failed.";
558 // TODO(hta): Consider how to get an error back.
559 std::vector
<webrtc::StatsReport
> no_reports
;
560 observer
->OnComplete(no_reports
);
565 WebKit::WebRTCDataChannelHandler
* RTCPeerConnectionHandler::createDataChannel(
566 const WebKit::WebString
& label
, bool reliable
) {
567 DVLOG(1) << "createDataChannel label " << UTF16ToUTF8(label
);
569 webrtc::DataChannelInit config
;
570 config
.reliable
= reliable
;
572 talk_base::scoped_refptr
<webrtc::DataChannelInterface
> webrtc_channel(
573 native_peer_connection_
->CreateDataChannel(UTF16ToUTF8(label
), &config
));
574 if (!webrtc_channel
) {
575 DLOG(ERROR
) << "Could not create native data channel.";
578 if (peer_connection_tracker_
)
579 peer_connection_tracker_
->TrackCreateDataChannel(
580 this, webrtc_channel
.get(), PeerConnectionTracker::SOURCE_LOCAL
);
582 return new RtcDataChannelHandler(webrtc_channel
);
585 WebKit::WebRTCDTMFSenderHandler
* RTCPeerConnectionHandler::createDTMFSender(
586 const WebKit::WebMediaStreamTrack
& track
) {
587 DVLOG(1) << "createDTMFSender.";
589 if (track
.source().type() != WebKit::WebMediaStreamSource::TypeAudio
) {
590 DLOG(ERROR
) << "Could not create DTMF sender from a non-audio track.";
594 webrtc::AudioTrackInterface
* audio_track
=
595 static_cast<webrtc::AudioTrackInterface
*>(
596 GetNativeMediaStreamTrack(track
.stream(), track
));
598 talk_base::scoped_refptr
<webrtc::DtmfSenderInterface
> sender(
599 native_peer_connection_
->CreateDtmfSender(audio_track
));
601 DLOG(ERROR
) << "Could not create native DTMF sender.";
604 if (peer_connection_tracker_
)
605 peer_connection_tracker_
->TrackCreateDTMFSender(this, track
);
607 return new RtcDtmfSenderHandler(sender
);
610 void RTCPeerConnectionHandler::stop() {
611 DVLOG(1) << "RTCPeerConnectionHandler::stop";
613 if (peer_connection_tracker_
)
614 peer_connection_tracker_
->TrackStop(this);
615 native_peer_connection_
->Close();
618 void RTCPeerConnectionHandler::OnError() {
619 // TODO(perkj): Implement.
623 void RTCPeerConnectionHandler::OnSignalingChange(
624 webrtc::PeerConnectionInterface::SignalingState new_state
) {
625 WebKit::WebRTCPeerConnectionHandlerClient::SignalingState state
=
626 GetWebKitSignalingState(new_state
);
627 if (peer_connection_tracker_
)
628 peer_connection_tracker_
->TrackSignalingStateChange(this, state
);
629 client_
->didChangeSignalingState(state
);
632 // Called any time the IceConnectionState changes
633 void RTCPeerConnectionHandler::OnIceConnectionChange(
634 webrtc::PeerConnectionInterface::IceConnectionState new_state
) {
635 WebKit::WebRTCPeerConnectionHandlerClient::ICEConnectionState state
=
636 GetWebKitIceConnectionState(new_state
);
637 if (peer_connection_tracker_
)
638 peer_connection_tracker_
->TrackIceConnectionStateChange(this, state
);
639 client_
->didChangeICEConnectionState(state
);
642 // Called any time the IceGatheringState changes
643 void RTCPeerConnectionHandler::OnIceGatheringChange(
644 webrtc::PeerConnectionInterface::IceGatheringState new_state
) {
645 if (new_state
== webrtc::PeerConnectionInterface::kIceGatheringComplete
) {
646 // If ICE gathering is completed, generate a NULL ICE candidate,
647 // to signal end of candidates.
648 WebKit::WebRTCICECandidate null_candidate
;
649 client_
->didGenerateICECandidate(null_candidate
);
652 WebKit::WebRTCPeerConnectionHandlerClient::ICEGatheringState state
=
653 GetWebKitIceGatheringState(new_state
);
654 if (peer_connection_tracker_
)
655 peer_connection_tracker_
->TrackIceGatheringStateChange(this, state
);
656 client_
->didChangeICEGatheringState(state
);
659 void RTCPeerConnectionHandler::OnAddStream(
660 webrtc::MediaStreamInterface
* stream_interface
) {
661 DCHECK(stream_interface
);
662 DCHECK(remote_streams_
.find(stream_interface
) == remote_streams_
.end());
663 WebKit::WebMediaStream stream
=
664 CreateRemoteWebKitMediaStream(stream_interface
);
666 if (peer_connection_tracker_
)
667 peer_connection_tracker_
->TrackAddStream(
668 this, stream
, PeerConnectionTracker::SOURCE_REMOTE
);
670 remote_streams_
.insert(
671 std::pair
<webrtc::MediaStreamInterface
*,
672 WebKit::WebMediaStream
>(stream_interface
, stream
));
673 client_
->didAddRemoteStream(stream
);
676 void RTCPeerConnectionHandler::OnRemoveStream(
677 webrtc::MediaStreamInterface
* stream_interface
) {
678 DCHECK(stream_interface
);
679 RemoteStreamMap::iterator it
= remote_streams_
.find(stream_interface
);
680 if (it
== remote_streams_
.end()) {
681 NOTREACHED() << "Stream not found";
684 WebKit::WebMediaStream stream
= it
->second
;
685 DCHECK(!stream
.isNull());
686 remote_streams_
.erase(it
);
688 if (peer_connection_tracker_
)
689 peer_connection_tracker_
->TrackRemoveStream(
690 this, stream
, PeerConnectionTracker::SOURCE_REMOTE
);
692 client_
->didRemoveRemoteStream(stream
);
695 void RTCPeerConnectionHandler::OnIceCandidate(
696 const webrtc::IceCandidateInterface
* candidate
) {
699 if (!candidate
->ToString(&sdp
)) {
700 NOTREACHED() << "OnIceCandidate: Could not get SDP string.";
703 WebKit::WebRTCICECandidate web_candidate
;
704 web_candidate
.initialize(UTF8ToUTF16(sdp
),
705 UTF8ToUTF16(candidate
->sdp_mid()),
706 candidate
->sdp_mline_index());
707 if (peer_connection_tracker_
)
708 peer_connection_tracker_
->TrackAddIceCandidate(
709 this, web_candidate
, PeerConnectionTracker::SOURCE_LOCAL
);
711 client_
->didGenerateICECandidate(web_candidate
);
714 void RTCPeerConnectionHandler::OnDataChannel(
715 webrtc::DataChannelInterface
* data_channel
) {
716 if (peer_connection_tracker_
)
717 peer_connection_tracker_
->TrackCreateDataChannel(
718 this, data_channel
, PeerConnectionTracker::SOURCE_REMOTE
);
720 DVLOG(1) << "RTCPeerConnectionHandler::OnDataChannel "
721 << data_channel
->label();
722 client_
->didAddRemoteDataChannel(new RtcDataChannelHandler(data_channel
));
725 void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
726 if (peer_connection_tracker_
)
727 peer_connection_tracker_
->TrackOnRenegotiationNeeded(this);
728 client_
->negotiationNeeded();
731 PeerConnectionTracker
* RTCPeerConnectionHandler::peer_connection_tracker() {
732 return peer_connection_tracker_
;
735 webrtc::SessionDescriptionInterface
*
736 RTCPeerConnectionHandler::CreateNativeSessionDescription(
737 const WebKit::WebRTCSessionDescription
& description
,
738 webrtc::SdpParseError
* error
) {
739 std::string sdp
= UTF16ToUTF8(description
.sdp());
740 std::string type
= UTF16ToUTF8(description
.type());
741 webrtc::SessionDescriptionInterface
* native_desc
=
742 dependency_factory_
->CreateSessionDescription(type
, sdp
, error
);
744 LOG_IF(ERROR
, !native_desc
) << "Failed to create native session description."
745 << " Type: " << type
<< " SDP: " << sdp
;
750 } // namespace content