OLD | NEW |
---|---|
(Empty) | |
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/rtc_peer_connection_handler.h" | |
6 | |
7 #include <string> | |
8 #include <utility> | |
9 | |
10 #include "base/logging.h" | |
11 #include "base/utf_string_conversions.h" | |
12 #include "content/renderer/media/media_stream_dependency_factory.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCICECandidateD escriptor.h" | |
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCConfiguration .h" | |
wjia(left Chromium)
2012/08/12 17:06:52
a-z order.
perkj_chrome
2012/08/13 07:35:46
Done.
| |
16 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints .h" | |
wjia(left Chromium)
2012/08/12 17:06:52
ditto
perkj_chrome
2012/08/13 07:35:46
Done.
| |
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectio nHandlerClient.h" | |
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescri ptionDescriptor.h" | |
19 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescri ptionRequest.h" | |
20 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCVoidRequest.h " | |
21 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" | |
22 | |
23 // Converter functions from libjingle types to WebKit types. | |
24 | |
25 static WebKit::WebRTCPeerConnectionHandlerClient::ICEState | |
26 GetWebKitIceState(webrtc::PeerConnectionInterface::IceState ice_state) { | |
27 switch (ice_state) { | |
28 case webrtc::PeerConnectionInterface::kIceNew: | |
29 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateNew; | |
30 case webrtc::PeerConnectionInterface::kIceGathering: | |
31 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateGathering; | |
32 case webrtc::PeerConnectionInterface::kIceWaiting: | |
33 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateWaiting; | |
34 case webrtc::PeerConnectionInterface::kIceChecking: | |
35 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateChecking; | |
36 case webrtc::PeerConnectionInterface::kIceConnected: | |
37 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateConnected; | |
38 case webrtc::PeerConnectionInterface::kIceCompleted: | |
39 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateCompleted; | |
40 case webrtc::PeerConnectionInterface::kIceFailed: | |
41 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateFailed; | |
42 case webrtc::PeerConnectionInterface::kIceClosed: | |
43 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateClosed; | |
44 } | |
45 NOTREACHED(); | |
46 } | |
47 | |
48 static WebKit::WebRTCPeerConnectionHandlerClient::ReadyState | |
49 GetWebKitReadyState(webrtc::PeerConnectionInterface::ReadyState ready_state) { | |
50 switch (ready_state) { | |
51 case webrtc::PeerConnectionInterface::kNew: | |
52 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateNew; | |
53 case webrtc::PeerConnectionInterface::kOpening: | |
54 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateOpening; | |
55 case webrtc::PeerConnectionInterface::kActive: | |
56 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateActive; | |
57 case webrtc::PeerConnectionInterface::kClosing: | |
58 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosing; | |
59 case webrtc::PeerConnectionInterface::kClosed: | |
60 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed; | |
61 default: | |
62 NOTREACHED(); | |
63 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed; | |
64 } | |
65 NOTREACHED(); | |
66 } | |
67 | |
68 static WebKit::WebRTCSessionDescriptionDescriptor | |
69 CreateWebKitSessionDescription( | |
70 const webrtc::SessionDescriptionInterface* native_desc) { | |
71 WebKit::WebRTCSessionDescriptionDescriptor description; | |
72 if (!native_desc) { | |
73 VLOG(1) << "Native session description is null"; | |
74 return description; | |
75 } | |
76 | |
77 std::string sdp; | |
78 if (!native_desc->ToString(&sdp)) { | |
79 LOG(ERROR) << "Failed to get SDP string of native session description"; | |
80 return description; | |
81 } | |
82 | |
83 description.initialize(UTF8ToUTF16(native_desc->type()), UTF8ToUTF16(sdp)); | |
84 return description; | |
85 } | |
86 | |
87 // Converter functions from WebKit types to libjingle types. | |
88 | |
89 static void GetNativeIceServers( | |
90 const WebKit::WebRTCConfiguration& server_configuration, | |
91 webrtc::JsepInterface::IceServers* servers) { | |
92 if (server_configuration.isNull()) | |
93 return; | |
94 for (size_t i = 0; i < server_configuration.numberOfServers(); ++i) { | |
95 webrtc::JsepInterface::IceServer server; | |
96 const WebKit::WebRTCICEServer& webkit_server = | |
97 server_configuration.server(i); | |
98 server.password = UTF16ToUTF8(webkit_server.credential()); | |
99 server.uri = webkit_server.uri().spec(); | |
100 servers->push_back(server); | |
101 } | |
102 } | |
103 | |
104 // Class mapping responses from calls to libjingle CreateOffer/Answer and | |
105 // the WebKit::WebRTCSessionDescriptionRequest. | |
106 class CreateSessionDescriptionRequest | |
107 : public webrtc::CreateSessionDescriptionObserver { | |
108 public: | |
109 explicit CreateSessionDescriptionRequest( | |
110 const WebKit::WebRTCSessionDescriptionRequest& request) | |
111 : webkit_request_(request) {} | |
112 | |
113 virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE { | |
114 webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc)); | |
115 } | |
116 virtual void OnFailure(const std::string& error) OVERRIDE { | |
117 webkit_request_.requestFailed(UTF8ToUTF16(error)); | |
118 } | |
119 | |
120 protected: | |
121 virtual ~CreateSessionDescriptionRequest() {} | |
122 | |
123 private: | |
124 WebKit::WebRTCSessionDescriptionRequest webkit_request_; | |
125 }; | |
126 | |
127 // Class mapping responses from calls to libjingle | |
128 // SetLocalDescription/SetRemoteDescription and a WebKit::WebRTCVoidRequest. | |
129 class SetSessionDescriptionRequest | |
130 : public webrtc::SetSessionDescriptionObserver { | |
131 public: | |
132 explicit SetSessionDescriptionRequest( | |
133 const WebKit::WebRTCVoidRequest& request) | |
134 : webkit_request_(request) {} | |
135 | |
136 virtual void OnSuccess() OVERRIDE { | |
137 webkit_request_.requestSucceeded(); | |
138 } | |
139 virtual void OnFailure(const std::string& error) OVERRIDE { | |
140 webkit_request_.requestFailed(UTF8ToUTF16(error)); | |
141 } | |
142 | |
143 protected: | |
144 virtual ~SetSessionDescriptionRequest() {} | |
145 | |
146 private: | |
147 WebKit::WebRTCVoidRequest webkit_request_; | |
148 }; | |
149 | |
150 // TODO(perkj): Implement MediaConstraints when WebKit have done so. | |
151 class RTCMediaConstraints : public webrtc::MediaConstraintsInterface { | |
152 public: | |
153 explicit RTCMediaConstraints( | |
154 const WebKit::WebMediaConstraints& /*constraints*/){ | |
155 } | |
156 ~RTCMediaConstraints() {} | |
157 | |
158 private: | |
159 }; | |
160 | |
161 RTCPeerConnectionHandler::RTCPeerConnectionHandler( | |
162 WebKit::WebRTCPeerConnectionHandlerClient* client, | |
163 MediaStreamDependencyFactory* dependency_factory) | |
164 : PeerConnectionHandlerBase(dependency_factory), | |
165 client_(client) { | |
166 } | |
167 | |
168 RTCPeerConnectionHandler::~RTCPeerConnectionHandler() { | |
169 } | |
170 | |
171 bool RTCPeerConnectionHandler::initialize( | |
172 const WebKit::WebRTCConfiguration& server_configuration, | |
173 const WebKit::WebMediaConstraints& options ) { | |
174 webrtc::JsepInterface::IceServers servers; | |
175 GetNativeIceServers(server_configuration, &servers); | |
176 | |
177 RTCMediaConstraints constraints(options); | |
178 native_peer_connection_ = | |
179 dependency_factory_->CreatePeerConnection( | |
180 servers, &constraints, this); | |
181 if (!native_peer_connection_) { | |
182 LOG(ERROR) << "Failed to initialize native PeerConnection"; | |
183 return false; | |
184 } | |
185 return true; | |
186 } | |
187 | |
188 void RTCPeerConnectionHandler::createOffer( | |
189 const WebKit::WebRTCSessionDescriptionRequest& request, | |
190 const WebKit::WebMediaConstraints& options) { | |
191 talk_base::scoped_refptr<CreateSessionDescriptionRequest> description_request( | |
192 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>( | |
193 request)); | |
194 RTCMediaConstraints constraints(options); | |
195 native_peer_connection_->CreateOffer( | |
196 description_request.get(), &constraints); | |
197 } | |
198 | |
199 void RTCPeerConnectionHandler::createAnswer( | |
200 const WebKit::WebRTCSessionDescriptionRequest& request, | |
201 const WebKit::WebMediaConstraints& options) { | |
202 talk_base::scoped_refptr<CreateSessionDescriptionRequest> description_request( | |
203 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>( | |
204 request)); | |
205 RTCMediaConstraints constraints(options); | |
206 native_peer_connection_->CreateAnswer(description_request.get(), | |
207 &constraints); | |
208 } | |
209 | |
210 void RTCPeerConnectionHandler::setLocalDescription( | |
211 const WebKit::WebRTCVoidRequest& request, | |
212 const WebKit::WebRTCSessionDescriptionDescriptor& description) { | |
213 webrtc::SessionDescriptionInterface* native_desc = | |
214 CreateNativeSessionDescription(description); | |
215 if (!native_desc) { | |
216 WebKit::WebString reason("Failed to parse SessionDescription"); | |
217 request.requestFailed(reason); | |
218 return; | |
219 } | |
220 talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request( | |
221 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request)); | |
222 native_peer_connection_->SetLocalDescription(set_request.get(), native_desc); | |
223 } | |
224 | |
225 void RTCPeerConnectionHandler::setRemoteDescription( | |
226 const WebKit::WebRTCVoidRequest& request, | |
227 const WebKit::WebRTCSessionDescriptionDescriptor& description) { | |
228 webrtc::SessionDescriptionInterface* native_desc = | |
229 CreateNativeSessionDescription(description); | |
230 if (!native_desc) { | |
231 WebKit::WebString reason("Failed to parse SessionDescription"); | |
232 request.requestFailed(reason); | |
233 return; | |
234 } | |
235 talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request( | |
236 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request)); | |
wjia(left Chromium)
2012/08/12 17:06:52
indent.
perkj_chrome
2012/08/13 07:35:46
Done.
| |
237 native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc); | |
238 } | |
239 | |
240 WebKit::WebRTCSessionDescriptionDescriptor | |
241 RTCPeerConnectionHandler::localDescription() { | |
242 const webrtc::SessionDescriptionInterface* native_desc = | |
243 native_peer_connection_->local_description(); | |
244 WebKit::WebRTCSessionDescriptionDescriptor description = | |
245 CreateWebKitSessionDescription(native_desc); | |
246 return description; | |
247 } | |
248 | |
249 WebKit::WebRTCSessionDescriptionDescriptor | |
250 RTCPeerConnectionHandler::remoteDescription() { | |
251 const webrtc::SessionDescriptionInterface* native_desc = | |
252 native_peer_connection_->remote_description(); | |
253 WebKit::WebRTCSessionDescriptionDescriptor description = | |
254 CreateWebKitSessionDescription(native_desc); | |
255 return description; | |
256 } | |
257 | |
258 bool RTCPeerConnectionHandler::updateICE( | |
259 const WebKit::WebRTCConfiguration& server_configuration, | |
260 const WebKit::WebMediaConstraints& options) { | |
261 webrtc::JsepInterface::IceServers servers; | |
262 GetNativeIceServers(server_configuration, &servers); | |
263 RTCMediaConstraints constraints(options); | |
264 return native_peer_connection_->UpdateIce(servers, | |
265 &constraints); | |
266 } | |
267 | |
268 bool RTCPeerConnectionHandler::addICECandidate( | |
269 const WebKit::WebRTCICECandidateDescriptor& candidate) { | |
270 scoped_ptr<webrtc::IceCandidateInterface> native_candidate( | |
271 dependency_factory_->CreateIceCandidate( | |
272 UTF16ToUTF8(candidate.sdpMid()), | |
273 candidate.sdpMLineIndex(), | |
274 UTF16ToUTF8(candidate.candidate()))); | |
275 if (!native_candidate.get()) { | |
276 LOG(ERROR) << "Could not create native ICE candidate"; | |
277 return false; | |
278 } | |
279 | |
280 bool return_value = | |
281 native_peer_connection_->AddIceCandidate(native_candidate.get()); | |
282 if (!return_value) | |
283 LOG(ERROR) << "Error processing ICE message"; | |
284 return return_value; | |
285 } | |
286 | |
287 bool RTCPeerConnectionHandler::addStream( | |
288 const WebKit::WebMediaStreamDescriptor& stream, | |
289 const WebKit::WebMediaConstraints& options) { | |
290 RTCMediaConstraints constraints(options); | |
291 return AddStream(stream, &constraints); | |
292 } | |
293 | |
294 void RTCPeerConnectionHandler::removeStream( | |
295 const WebKit::WebMediaStreamDescriptor& stream) { | |
296 RemoveStream(stream); | |
297 } | |
298 | |
299 void RTCPeerConnectionHandler::stop() { | |
300 DVLOG(1) << "RTCPeerConnectionHandler::stop"; | |
301 native_peer_connection_ = NULL; | |
302 } | |
303 | |
304 void RTCPeerConnectionHandler::OnError() { | |
305 // TODO(perkj): Implement. | |
306 NOTIMPLEMENTED(); | |
307 } | |
308 | |
309 void RTCPeerConnectionHandler::OnStateChange(StateType state_changed) { | |
310 switch (state_changed) { | |
311 case kReadyState: { | |
312 WebKit::WebRTCPeerConnectionHandlerClient::ReadyState ready_state = | |
313 GetWebKitReadyState(native_peer_connection_->ready_state()); | |
314 client_->didChangeReadyState(ready_state); | |
315 break; | |
316 } | |
317 case kIceState: { | |
318 WebKit::WebRTCPeerConnectionHandlerClient::ICEState ice_state = | |
319 GetWebKitIceState(native_peer_connection_->ice_state()); | |
320 client_->didChangeICEState(ice_state); | |
321 break; | |
322 } | |
323 default: | |
324 NOTREACHED(); | |
325 break; | |
326 } | |
327 } | |
328 | |
329 void RTCPeerConnectionHandler::OnAddStream( | |
330 webrtc::MediaStreamInterface* stream) { | |
331 if (!stream) | |
332 return; | |
333 | |
334 DCHECK(remote_streams_.find(stream) == remote_streams_.end()); | |
335 WebKit::WebMediaStreamDescriptor descriptor = | |
336 CreateWebKitStreamDescriptor(stream); | |
337 remote_streams_.insert( | |
338 std::pair<webrtc::MediaStreamInterface*, | |
339 WebKit::WebMediaStreamDescriptor>(stream, descriptor)); | |
340 client_->didAddRemoteStream(descriptor); | |
341 } | |
342 | |
343 void RTCPeerConnectionHandler::OnRemoveStream( | |
344 webrtc::MediaStreamInterface* stream) { | |
345 if (!stream) | |
346 return; | |
347 | |
348 RemoteStreamMap::iterator it = remote_streams_.find(stream); | |
349 if (it == remote_streams_.end()) { | |
350 NOTREACHED() << "Stream not found"; | |
351 return; | |
352 } | |
353 WebKit::WebMediaStreamDescriptor descriptor = it->second; | |
354 DCHECK(!descriptor.isNull()); | |
355 remote_streams_.erase(it); | |
356 client_->didRemoveRemoteStream(descriptor); | |
357 } | |
358 | |
359 void RTCPeerConnectionHandler::OnIceCandidate( | |
360 const webrtc::IceCandidateInterface* candidate) { | |
361 WebKit::WebRTCICECandidateDescriptor web_candidate; | |
362 | |
363 std::string sdp; | |
364 if (!candidate->ToString(&sdp)) { | |
365 LOG(ERROR) << "Could not get SDP string"; | |
366 return; | |
367 } | |
368 | |
369 web_candidate.initialize(UTF8ToUTF16(sdp), | |
370 UTF8ToUTF16(candidate->sdp_mid()), | |
371 candidate->sdp_mline_index()); | |
372 client_->didGenerateICECandidate(web_candidate); | |
373 } | |
374 | |
375 void RTCPeerConnectionHandler::OnIceComplete() { | |
376 // Generates a NULL ice candidate object. | |
377 WebKit::WebRTCICECandidateDescriptor web_candidate; | |
378 client_->didGenerateICECandidate(web_candidate); | |
379 } | |
380 | |
381 void RTCPeerConnectionHandler::OnRenegotiationNeeded() { | |
382 client_->doRenegotiate(); | |
383 } | |
384 | |
385 webrtc::SessionDescriptionInterface* | |
386 RTCPeerConnectionHandler::CreateNativeSessionDescription( | |
387 const WebKit::WebRTCSessionDescriptionDescriptor& description) { | |
388 std::string sdp = UTF16ToUTF8(description.sdp()); | |
389 std::string type = UTF16ToUTF8(description.type()); | |
390 webrtc::SessionDescriptionInterface* native_desc = | |
391 dependency_factory_->CreateSessionDescription(type, sdp); | |
392 if (!native_desc) { | |
393 LOG(ERROR) << "Failed to create native session description"; | |
394 return NULL; | |
395 } | |
396 | |
397 return native_desc; | |
398 } | |
OLD | NEW |