| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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/shell/renderer/test_runner/mock_webrtc_peer_connection_handler
.h" | |
| 6 | |
| 7 #include "content/shell/renderer/test_runner/mock_constraints.h" | |
| 8 #include "content/shell/renderer/test_runner/mock_webrtc_data_channel_handler.h" | |
| 9 #include "content/shell/renderer/test_runner/mock_webrtc_dtmf_sender_handler.h" | |
| 10 #include "content/shell/renderer/test_runner/test_interfaces.h" | |
| 11 #include "content/shell/renderer/test_runner/web_test_delegate.h" | |
| 12 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | |
| 13 #include "third_party/WebKit/public/platform/WebMediaStream.h" | |
| 14 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" | |
| 15 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | |
| 16 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h" | |
| 17 #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h
" | |
| 18 #include "third_party/WebKit/public/platform/WebRTCStatsResponse.h" | |
| 19 #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h" | |
| 20 #include "third_party/WebKit/public/platform/WebString.h" | |
| 21 #include "third_party/WebKit/public/platform/WebVector.h" | |
| 22 | |
| 23 using namespace blink; | |
| 24 | |
| 25 namespace content { | |
| 26 | |
| 27 class RTCSessionDescriptionRequestSuccededTask | |
| 28 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { | |
| 29 public: | |
| 30 RTCSessionDescriptionRequestSuccededTask( | |
| 31 MockWebRTCPeerConnectionHandler* object, | |
| 32 const WebRTCSessionDescriptionRequest& request, | |
| 33 const WebRTCSessionDescription& result) | |
| 34 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), | |
| 35 request_(request), | |
| 36 result_(result) {} | |
| 37 | |
| 38 void RunIfValid() override { request_.requestSucceeded(result_); } | |
| 39 | |
| 40 private: | |
| 41 WebRTCSessionDescriptionRequest request_; | |
| 42 WebRTCSessionDescription result_; | |
| 43 }; | |
| 44 | |
| 45 class RTCSessionDescriptionRequestFailedTask | |
| 46 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { | |
| 47 public: | |
| 48 RTCSessionDescriptionRequestFailedTask( | |
| 49 MockWebRTCPeerConnectionHandler* object, | |
| 50 const WebRTCSessionDescriptionRequest& request) | |
| 51 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), | |
| 52 request_(request) {} | |
| 53 | |
| 54 void RunIfValid() override { request_.requestFailed("TEST_ERROR"); } | |
| 55 | |
| 56 private: | |
| 57 WebRTCSessionDescriptionRequest request_; | |
| 58 }; | |
| 59 | |
| 60 class RTCStatsRequestSucceededTask | |
| 61 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { | |
| 62 public: | |
| 63 RTCStatsRequestSucceededTask(MockWebRTCPeerConnectionHandler* object, | |
| 64 const blink::WebRTCStatsRequest& request, | |
| 65 const blink::WebRTCStatsResponse& response) | |
| 66 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), | |
| 67 request_(request), | |
| 68 response_(response) {} | |
| 69 | |
| 70 void RunIfValid() override { request_.requestSucceeded(response_); } | |
| 71 | |
| 72 private: | |
| 73 blink::WebRTCStatsRequest request_; | |
| 74 blink::WebRTCStatsResponse response_; | |
| 75 }; | |
| 76 | |
| 77 class RTCVoidRequestTask | |
| 78 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { | |
| 79 public: | |
| 80 RTCVoidRequestTask(MockWebRTCPeerConnectionHandler* object, | |
| 81 const WebRTCVoidRequest& request, | |
| 82 bool succeeded) | |
| 83 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), | |
| 84 request_(request), | |
| 85 succeeded_(succeeded) {} | |
| 86 | |
| 87 void RunIfValid() override { | |
| 88 if (succeeded_) | |
| 89 request_.requestSucceeded(); | |
| 90 else | |
| 91 request_.requestFailed("TEST_ERROR"); | |
| 92 } | |
| 93 | |
| 94 private: | |
| 95 WebRTCVoidRequest request_; | |
| 96 bool succeeded_; | |
| 97 }; | |
| 98 | |
| 99 class RTCPeerConnectionStateTask | |
| 100 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { | |
| 101 public: | |
| 102 RTCPeerConnectionStateTask( | |
| 103 MockWebRTCPeerConnectionHandler* object, | |
| 104 WebRTCPeerConnectionHandlerClient* client, | |
| 105 WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state, | |
| 106 WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state) | |
| 107 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), | |
| 108 client_(client), | |
| 109 connection_state_(connection_state), | |
| 110 gathering_state_(gathering_state) {} | |
| 111 | |
| 112 void RunIfValid() override { | |
| 113 client_->didChangeICEGatheringState(gathering_state_); | |
| 114 client_->didChangeICEConnectionState(connection_state_); | |
| 115 } | |
| 116 | |
| 117 private: | |
| 118 WebRTCPeerConnectionHandlerClient* client_; | |
| 119 WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state_; | |
| 120 WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state_; | |
| 121 }; | |
| 122 | |
| 123 class RemoteDataChannelTask | |
| 124 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { | |
| 125 public: | |
| 126 RemoteDataChannelTask(MockWebRTCPeerConnectionHandler* object, | |
| 127 WebRTCPeerConnectionHandlerClient* client, | |
| 128 WebTestDelegate* delegate) | |
| 129 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), | |
| 130 client_(client), | |
| 131 delegate_(delegate) {} | |
| 132 | |
| 133 void RunIfValid() override { | |
| 134 WebRTCDataChannelInit init; | |
| 135 WebRTCDataChannelHandler* remote_data_channel = | |
| 136 new MockWebRTCDataChannelHandler( | |
| 137 "MockRemoteDataChannel", init, delegate_); | |
| 138 client_->didAddRemoteDataChannel(remote_data_channel); | |
| 139 } | |
| 140 | |
| 141 private: | |
| 142 WebRTCPeerConnectionHandlerClient* client_; | |
| 143 WebTestDelegate* delegate_; | |
| 144 }; | |
| 145 | |
| 146 ///////////////////// | |
| 147 | |
| 148 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() { | |
| 149 } | |
| 150 | |
| 151 MockWebRTCPeerConnectionHandler::~MockWebRTCPeerConnectionHandler() { | |
| 152 } | |
| 153 | |
| 154 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler( | |
| 155 WebRTCPeerConnectionHandlerClient* client, | |
| 156 TestInterfaces* interfaces) | |
| 157 : client_(client), | |
| 158 stopped_(false), | |
| 159 stream_count_(0), | |
| 160 interfaces_(interfaces) { | |
| 161 } | |
| 162 | |
| 163 bool MockWebRTCPeerConnectionHandler::initialize( | |
| 164 const WebRTCConfiguration& configuration, | |
| 165 const WebMediaConstraints& constraints) { | |
| 166 if (MockConstraints::VerifyConstraints(constraints)) { | |
| 167 interfaces_->GetDelegate()->PostTask(new RTCPeerConnectionStateTask( | |
| 168 this, | |
| 169 client_, | |
| 170 WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted, | |
| 171 WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete)); | |
| 172 return true; | |
| 173 } | |
| 174 | |
| 175 return false; | |
| 176 } | |
| 177 | |
| 178 void MockWebRTCPeerConnectionHandler::createOffer( | |
| 179 const WebRTCSessionDescriptionRequest& request, | |
| 180 const WebMediaConstraints& constraints) { | |
| 181 WebString should_succeed; | |
| 182 if (constraints.getMandatoryConstraintValue("succeed", should_succeed) && | |
| 183 should_succeed == "true") { | |
| 184 WebRTCSessionDescription session_description; | |
| 185 session_description.initialize("offer", "local"); | |
| 186 interfaces_->GetDelegate()->PostTask( | |
| 187 new RTCSessionDescriptionRequestSuccededTask( | |
| 188 this, request, session_description)); | |
| 189 } else | |
| 190 interfaces_->GetDelegate()->PostTask( | |
| 191 new RTCSessionDescriptionRequestFailedTask(this, request)); | |
| 192 } | |
| 193 | |
| 194 void MockWebRTCPeerConnectionHandler::createOffer( | |
| 195 const WebRTCSessionDescriptionRequest& request, | |
| 196 const blink::WebRTCOfferOptions& options) { | |
| 197 interfaces_->GetDelegate()->PostTask( | |
| 198 new RTCSessionDescriptionRequestFailedTask(this, request)); | |
| 199 } | |
| 200 | |
| 201 void MockWebRTCPeerConnectionHandler::createAnswer( | |
| 202 const WebRTCSessionDescriptionRequest& request, | |
| 203 const WebMediaConstraints& constraints) { | |
| 204 if (!remote_description_.isNull()) { | |
| 205 WebRTCSessionDescription session_description; | |
| 206 session_description.initialize("answer", "local"); | |
| 207 interfaces_->GetDelegate()->PostTask( | |
| 208 new RTCSessionDescriptionRequestSuccededTask( | |
| 209 this, request, session_description)); | |
| 210 } else | |
| 211 interfaces_->GetDelegate()->PostTask( | |
| 212 new RTCSessionDescriptionRequestFailedTask(this, request)); | |
| 213 } | |
| 214 | |
| 215 void MockWebRTCPeerConnectionHandler::setLocalDescription( | |
| 216 const WebRTCVoidRequest& request, | |
| 217 const WebRTCSessionDescription& local_description) { | |
| 218 if (!local_description.isNull() && local_description.sdp() == "local") { | |
| 219 local_description_ = local_description; | |
| 220 interfaces_->GetDelegate()->PostTask( | |
| 221 new RTCVoidRequestTask(this, request, true)); | |
| 222 } else | |
| 223 interfaces_->GetDelegate()->PostTask( | |
| 224 new RTCVoidRequestTask(this, request, false)); | |
| 225 } | |
| 226 | |
| 227 void MockWebRTCPeerConnectionHandler::setRemoteDescription( | |
| 228 const WebRTCVoidRequest& request, | |
| 229 const WebRTCSessionDescription& remote_description) { | |
| 230 | |
| 231 if (!remote_description.isNull() && remote_description.sdp() == "remote") { | |
| 232 UpdateRemoteStreams(); | |
| 233 remote_description_ = remote_description; | |
| 234 interfaces_->GetDelegate()->PostTask( | |
| 235 new RTCVoidRequestTask(this, request, true)); | |
| 236 } else | |
| 237 interfaces_->GetDelegate()->PostTask( | |
| 238 new RTCVoidRequestTask(this, request, false)); | |
| 239 } | |
| 240 | |
| 241 void MockWebRTCPeerConnectionHandler::UpdateRemoteStreams() { | |
| 242 // Find all removed streams. | |
| 243 // Set the readyState of the remote tracks to ended, remove them from the | |
| 244 // stream and notify the client. | |
| 245 StreamMap::iterator removed_it = remote_streams_.begin(); | |
| 246 while (removed_it != remote_streams_.end()) { | |
| 247 if (local_streams_.find(removed_it->first) != local_streams_.end()) { | |
| 248 removed_it++; | |
| 249 continue; | |
| 250 } | |
| 251 | |
| 252 // The stream have been removed. Loop through all tracks and set the | |
| 253 // source as ended and remove them from the stream. | |
| 254 blink::WebMediaStream stream = removed_it->second; | |
| 255 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; | |
| 256 stream.audioTracks(audio_tracks); | |
| 257 for (size_t i = 0; i < audio_tracks.size(); ++i) { | |
| 258 audio_tracks[i].source().setReadyState( | |
| 259 blink::WebMediaStreamSource::ReadyStateEnded); | |
| 260 stream.removeTrack(audio_tracks[i]); | |
| 261 } | |
| 262 | |
| 263 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; | |
| 264 stream.videoTracks(video_tracks); | |
| 265 for (size_t i = 0; i < video_tracks.size(); ++i) { | |
| 266 video_tracks[i].source().setReadyState( | |
| 267 blink::WebMediaStreamSource::ReadyStateEnded); | |
| 268 stream.removeTrack(video_tracks[i]); | |
| 269 } | |
| 270 client_->didRemoveRemoteStream(stream); | |
| 271 remote_streams_.erase(removed_it++); | |
| 272 } | |
| 273 | |
| 274 // Find all new streams; | |
| 275 // Create new sources and tracks and notify the client about the new stream. | |
| 276 StreamMap::iterator added_it = local_streams_.begin(); | |
| 277 while (added_it != local_streams_.end()) { | |
| 278 if (remote_streams_.find(added_it->first) != remote_streams_.end()) { | |
| 279 added_it++; | |
| 280 continue; | |
| 281 } | |
| 282 | |
| 283 const blink::WebMediaStream& stream = added_it->second; | |
| 284 | |
| 285 blink::WebVector<blink::WebMediaStreamTrack> local_audio_tracks; | |
| 286 stream.audioTracks(local_audio_tracks); | |
| 287 blink::WebVector<blink::WebMediaStreamTrack> | |
| 288 remote_audio_tracks(local_audio_tracks.size()); | |
| 289 | |
| 290 for (size_t i = 0; i < local_audio_tracks.size(); ++i) { | |
| 291 blink::WebMediaStreamSource webkit_source; | |
| 292 webkit_source.initialize(local_audio_tracks[i].id(), | |
| 293 blink::WebMediaStreamSource::TypeAudio, | |
| 294 local_audio_tracks[i].id(), | |
| 295 true /* remote */, true /* readonly */); | |
| 296 remote_audio_tracks[i].initialize(webkit_source); | |
| 297 } | |
| 298 | |
| 299 blink::WebVector<blink::WebMediaStreamTrack> local_video_tracks; | |
| 300 stream.videoTracks(local_video_tracks); | |
| 301 blink::WebVector<blink::WebMediaStreamTrack> | |
| 302 remote_video_tracks(local_video_tracks.size()); | |
| 303 for (size_t i = 0; i < local_video_tracks.size(); ++i) { | |
| 304 blink::WebMediaStreamSource webkit_source; | |
| 305 webkit_source.initialize(local_video_tracks[i].id(), | |
| 306 blink::WebMediaStreamSource::TypeVideo, | |
| 307 local_video_tracks[i].id(), | |
| 308 true /* remote */, true /* readonly */); | |
| 309 remote_video_tracks[i].initialize(webkit_source); | |
| 310 } | |
| 311 | |
| 312 blink::WebMediaStream new_remote_stream; | |
| 313 new_remote_stream.initialize(remote_audio_tracks, | |
| 314 remote_video_tracks); | |
| 315 remote_streams_[added_it->first] = new_remote_stream; | |
| 316 client_->didAddRemoteStream(new_remote_stream); | |
| 317 ++added_it; | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::localDescription() { | |
| 322 return local_description_; | |
| 323 } | |
| 324 | |
| 325 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::remoteDescription() { | |
| 326 return remote_description_; | |
| 327 } | |
| 328 | |
| 329 bool MockWebRTCPeerConnectionHandler::updateICE( | |
| 330 const WebRTCConfiguration& configuration, | |
| 331 const WebMediaConstraints& constraints) { | |
| 332 return true; | |
| 333 } | |
| 334 | |
| 335 bool MockWebRTCPeerConnectionHandler::addICECandidate( | |
| 336 const WebRTCICECandidate& ice_candidate) { | |
| 337 client_->didGenerateICECandidate(ice_candidate); | |
| 338 return true; | |
| 339 } | |
| 340 | |
| 341 bool MockWebRTCPeerConnectionHandler::addICECandidate( | |
| 342 const WebRTCVoidRequest& request, | |
| 343 const WebRTCICECandidate& ice_candidate) { | |
| 344 interfaces_->GetDelegate()->PostTask( | |
| 345 new RTCVoidRequestTask(this, request, true)); | |
| 346 return true; | |
| 347 } | |
| 348 | |
| 349 bool MockWebRTCPeerConnectionHandler::addStream( | |
| 350 const WebMediaStream& stream, | |
| 351 const WebMediaConstraints& constraints) { | |
| 352 if (local_streams_.find(stream.id().utf8()) != local_streams_.end()) | |
| 353 return false; | |
| 354 ++stream_count_; | |
| 355 client_->negotiationNeeded(); | |
| 356 local_streams_[stream.id().utf8()] = stream; | |
| 357 return true; | |
| 358 } | |
| 359 | |
| 360 void MockWebRTCPeerConnectionHandler::removeStream( | |
| 361 const WebMediaStream& stream) { | |
| 362 --stream_count_; | |
| 363 local_streams_.erase(stream.id().utf8()); | |
| 364 client_->negotiationNeeded(); | |
| 365 } | |
| 366 | |
| 367 void MockWebRTCPeerConnectionHandler::getStats( | |
| 368 const WebRTCStatsRequest& request) { | |
| 369 WebRTCStatsResponse response = request.createResponse(); | |
| 370 double current_date = | |
| 371 interfaces_->GetDelegate()->GetCurrentTimeInMillisecond(); | |
| 372 if (request.hasSelector()) { | |
| 373 // FIXME: There is no check that the fetched values are valid. | |
| 374 size_t report_index = | |
| 375 response.addReport("Mock video", "ssrc", current_date); | |
| 376 response.addStatistic(report_index, "type", "video"); | |
| 377 } else { | |
| 378 for (int i = 0; i < stream_count_; ++i) { | |
| 379 size_t report_index = | |
| 380 response.addReport("Mock audio", "ssrc", current_date); | |
| 381 response.addStatistic(report_index, "type", "audio"); | |
| 382 report_index = response.addReport("Mock video", "ssrc", current_date); | |
| 383 response.addStatistic(report_index, "type", "video"); | |
| 384 } | |
| 385 } | |
| 386 interfaces_->GetDelegate()->PostTask( | |
| 387 new RTCStatsRequestSucceededTask(this, request, response)); | |
| 388 } | |
| 389 | |
| 390 WebRTCDataChannelHandler* MockWebRTCPeerConnectionHandler::createDataChannel( | |
| 391 const WebString& label, | |
| 392 const blink::WebRTCDataChannelInit& init) { | |
| 393 interfaces_->GetDelegate()->PostTask( | |
| 394 new RemoteDataChannelTask(this, client_, interfaces_->GetDelegate())); | |
| 395 | |
| 396 return new MockWebRTCDataChannelHandler( | |
| 397 label, init, interfaces_->GetDelegate()); | |
| 398 } | |
| 399 | |
| 400 WebRTCDTMFSenderHandler* MockWebRTCPeerConnectionHandler::createDTMFSender( | |
| 401 const WebMediaStreamTrack& track) { | |
| 402 return new MockWebRTCDTMFSenderHandler(track, interfaces_->GetDelegate()); | |
| 403 } | |
| 404 | |
| 405 void MockWebRTCPeerConnectionHandler::stop() { | |
| 406 stopped_ = true; | |
| 407 task_list_.RevokeAll(); | |
| 408 } | |
| 409 | |
| 410 } // namespace content | |
| OLD | NEW |