Chromium Code Reviews| 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/memory/scoped_ptr.h" | |
| 12 #include "base/utf_string_conversions.h" | |
| 13 #include "content/renderer/media/media_stream_dependency_factory.h" | |
| 14 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints .h" | |
| 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCConfiguration .h" | |
| 16 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCICECandidateD escriptor.h" | |
| 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) { | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
indent
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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; | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
prefer to have a default like you have in the belo
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 44 } | |
| 45 NOTREACHED(); | |
| 46 } | |
| 47 | |
| 48 static WebKit::WebRTCPeerConnectionHandlerClient::ReadyState | |
| 49 GetWebKitReadyState(webrtc::PeerConnectionInterface::ReadyState ready_state) { | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
indent
perkj_chrome
2012/08/14 09:15:40
dito?
| |
| 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( | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
indent
perkj_chrome
2012/08/14 09:15:40
I think this is correct.
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 70 const webrtc::SessionDescriptionInterface* native_desc) { | |
| 71 WebKit::WebRTCSessionDescriptionDescriptor description; | |
| 72 if (!native_desc) { | |
| 73 VLOG(1) << "Native session description is null"; | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
LOG(ERROR) ?
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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()) | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
also check servers
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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) {} | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
How does this work? so the const pointer is conver
perkj_chrome
2012/08/14 09:15:40
It's not a pointer- its a reference.
webkit_reque
| |
| 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: | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
Remove
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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"); | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
LOG this as well
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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"); | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
LOG this error
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 232 request.requestFailed(reason); | |
| 233 return; | |
| 234 } | |
| 235 talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request( | |
| 236 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request)); | |
| 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"; | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
ICE candidate?
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 284 return return_value; | |
| 285 } | |
| 286 | |
| 287 bool RTCPeerConnectionHandler::addStream( | |
| 288 const WebKit::WebMediaStreamDescriptor& stream, | |
| 289 const WebKit::WebMediaConstraints& options) { | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
remove extra space after const
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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; | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
LOG error
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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; | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
shouldn't be null, log the error
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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; | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
nit: move this line to 368
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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( | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
indent
perkj_chrome
2012/08/14 09:15:40
dito
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 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"; | |
|
Ronghua Wu (Left Chromium)
2012/08/14 00:59:03
print the sdp and type in the log
perkj_chrome
2012/08/14 09:15:40
Done.
| |
| 394 return NULL; | |
| 395 } | |
| 396 | |
| 397 return native_desc; | |
| 398 } | |
| OLD | NEW |