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/WebMediaStreamTrack.h" 15 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h" 16 #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h" 17 #include "third_party/WebKit/public/platform/WebRTCStatsResponse.h" 18 #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h" 19 #include "third_party/WebKit/public/platform/WebString.h" 20 #include "third_party/WebKit/public/platform/WebVector.h" 21 22 using namespace blink; 23 24 namespace content { 25 26 class RTCSessionDescriptionRequestSuccededTask 27 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 28 public: 29 RTCSessionDescriptionRequestSuccededTask( 30 MockWebRTCPeerConnectionHandler* object, 31 const WebRTCSessionDescriptionRequest& request, 32 const WebRTCSessionDescription& result) 33 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), 34 request_(request), 35 result_(result) {} 36 37 virtual void RunIfValid() OVERRIDE { request_.requestSucceeded(result_); } 38 39 private: 40 WebRTCSessionDescriptionRequest request_; 41 WebRTCSessionDescription result_; 42 }; 43 44 class RTCSessionDescriptionRequestFailedTask 45 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 46 public: 47 RTCSessionDescriptionRequestFailedTask( 48 MockWebRTCPeerConnectionHandler* object, 49 const WebRTCSessionDescriptionRequest& request) 50 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), 51 request_(request) {} 52 53 virtual void RunIfValid() OVERRIDE { request_.requestFailed("TEST_ERROR"); } 54 55 private: 56 WebRTCSessionDescriptionRequest request_; 57 }; 58 59 class RTCStatsRequestSucceededTask 60 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 61 public: 62 RTCStatsRequestSucceededTask(MockWebRTCPeerConnectionHandler* object, 63 const blink::WebRTCStatsRequest& request, 64 const blink::WebRTCStatsResponse& response) 65 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), 66 request_(request), 67 response_(response) {} 68 69 virtual void RunIfValid() OVERRIDE { request_.requestSucceeded(response_); } 70 71 private: 72 blink::WebRTCStatsRequest request_; 73 blink::WebRTCStatsResponse response_; 74 }; 75 76 class RTCVoidRequestTask 77 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 78 public: 79 RTCVoidRequestTask(MockWebRTCPeerConnectionHandler* object, 80 const WebRTCVoidRequest& request, 81 bool succeeded) 82 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), 83 request_(request), 84 succeeded_(succeeded) {} 85 86 virtual void RunIfValid() OVERRIDE { 87 if (succeeded_) 88 request_.requestSucceeded(); 89 else 90 request_.requestFailed("TEST_ERROR"); 91 } 92 93 private: 94 WebRTCVoidRequest request_; 95 bool succeeded_; 96 }; 97 98 class RTCPeerConnectionStateTask 99 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 100 public: 101 RTCPeerConnectionStateTask( 102 MockWebRTCPeerConnectionHandler* object, 103 WebRTCPeerConnectionHandlerClient* client, 104 WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state, 105 WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state) 106 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), 107 client_(client), 108 connection_state_(connection_state), 109 gathering_state_(gathering_state) {} 110 111 virtual void RunIfValid() OVERRIDE { 112 client_->didChangeICEGatheringState(gathering_state_); 113 client_->didChangeICEConnectionState(connection_state_); 114 } 115 116 private: 117 WebRTCPeerConnectionHandlerClient* client_; 118 WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state_; 119 WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state_; 120 }; 121 122 class RemoteDataChannelTask 123 : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 124 public: 125 RemoteDataChannelTask(MockWebRTCPeerConnectionHandler* object, 126 WebRTCPeerConnectionHandlerClient* client, 127 WebTestDelegate* delegate) 128 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object), 129 client_(client), 130 delegate_(delegate) {} 131 132 virtual void RunIfValid() OVERRIDE { 133 WebRTCDataChannelInit init; 134 WebRTCDataChannelHandler* remote_data_channel = 135 new MockWebRTCDataChannelHandler( 136 "MockRemoteDataChannel", init, delegate_); 137 client_->didAddRemoteDataChannel(remote_data_channel); 138 } 139 140 private: 141 WebRTCPeerConnectionHandlerClient* client_; 142 WebTestDelegate* delegate_; 143 }; 144 145 ///////////////////// 146 147 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() { 148 } 149 150 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler( 151 WebRTCPeerConnectionHandlerClient* client, 152 TestInterfaces* interfaces) 153 : client_(client), 154 stopped_(false), 155 stream_count_(0), 156 interfaces_(interfaces) { 157 } 158 159 bool MockWebRTCPeerConnectionHandler::initialize( 160 const WebRTCConfiguration& configuration, 161 const WebMediaConstraints& constraints) { 162 if (MockConstraints::VerifyConstraints(constraints)) { 163 interfaces_->GetDelegate()->PostTask(new RTCPeerConnectionStateTask( 164 this, 165 client_, 166 WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted, 167 WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete)); 168 return true; 169 } 170 171 return false; 172 } 173 174 void MockWebRTCPeerConnectionHandler::createOffer( 175 const WebRTCSessionDescriptionRequest& request, 176 const WebMediaConstraints& constraints) { 177 WebString should_succeed; 178 if (constraints.getMandatoryConstraintValue("succeed", should_succeed) && 179 should_succeed == "true") { 180 WebRTCSessionDescription session_description; 181 session_description.initialize("offer", "local"); 182 interfaces_->GetDelegate()->PostTask( 183 new RTCSessionDescriptionRequestSuccededTask( 184 this, request, session_description)); 185 } else 186 interfaces_->GetDelegate()->PostTask( 187 new RTCSessionDescriptionRequestFailedTask(this, request)); 188 } 189 190 void MockWebRTCPeerConnectionHandler::createOffer( 191 const WebRTCSessionDescriptionRequest& request, 192 const blink::WebRTCOfferOptions& options) { 193 interfaces_->GetDelegate()->PostTask( 194 new RTCSessionDescriptionRequestFailedTask(this, request)); 195 } 196 197 void MockWebRTCPeerConnectionHandler::createAnswer( 198 const WebRTCSessionDescriptionRequest& request, 199 const WebMediaConstraints& constraints) { 200 if (!remote_description_.isNull()) { 201 WebRTCSessionDescription session_description; 202 session_description.initialize("answer", "local"); 203 interfaces_->GetDelegate()->PostTask( 204 new RTCSessionDescriptionRequestSuccededTask( 205 this, request, session_description)); 206 } else 207 interfaces_->GetDelegate()->PostTask( 208 new RTCSessionDescriptionRequestFailedTask(this, request)); 209 } 210 211 void MockWebRTCPeerConnectionHandler::setLocalDescription( 212 const WebRTCVoidRequest& request, 213 const WebRTCSessionDescription& local_description) { 214 if (!local_description.isNull() && local_description.sdp() == "local") { 215 local_description_ = local_description; 216 interfaces_->GetDelegate()->PostTask( 217 new RTCVoidRequestTask(this, request, true)); 218 } else 219 interfaces_->GetDelegate()->PostTask( 220 new RTCVoidRequestTask(this, request, false)); 221 } 222 223 void MockWebRTCPeerConnectionHandler::setRemoteDescription( 224 const WebRTCVoidRequest& request, 225 const WebRTCSessionDescription& remote_description) { 226 if (!remote_description.isNull() && remote_description.sdp() == "remote") { 227 remote_description_ = remote_description; 228 interfaces_->GetDelegate()->PostTask( 229 new RTCVoidRequestTask(this, request, true)); 230 } else 231 interfaces_->GetDelegate()->PostTask( 232 new RTCVoidRequestTask(this, request, false)); 233 } 234 235 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::localDescription() { 236 return local_description_; 237 } 238 239 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::remoteDescription() { 240 return remote_description_; 241 } 242 243 bool MockWebRTCPeerConnectionHandler::updateICE( 244 const WebRTCConfiguration& configuration, 245 const WebMediaConstraints& constraints) { 246 return true; 247 } 248 249 bool MockWebRTCPeerConnectionHandler::addICECandidate( 250 const WebRTCICECandidate& ice_candidate) { 251 client_->didGenerateICECandidate(ice_candidate); 252 return true; 253 } 254 255 bool MockWebRTCPeerConnectionHandler::addICECandidate( 256 const WebRTCVoidRequest& request, 257 const WebRTCICECandidate& ice_candidate) { 258 interfaces_->GetDelegate()->PostTask( 259 new RTCVoidRequestTask(this, request, true)); 260 return true; 261 } 262 263 bool MockWebRTCPeerConnectionHandler::addStream( 264 const WebMediaStream& stream, 265 const WebMediaConstraints& constraints) { 266 ++stream_count_; 267 client_->negotiationNeeded(); 268 return true; 269 } 270 271 void MockWebRTCPeerConnectionHandler::removeStream( 272 const WebMediaStream& stream) { 273 --stream_count_; 274 client_->negotiationNeeded(); 275 } 276 277 void MockWebRTCPeerConnectionHandler::getStats( 278 const WebRTCStatsRequest& request) { 279 WebRTCStatsResponse response = request.createResponse(); 280 double current_date = 281 interfaces_->GetDelegate()->GetCurrentTimeInMillisecond(); 282 if (request.hasSelector()) { 283 // FIXME: There is no check that the fetched values are valid. 284 size_t report_index = 285 response.addReport("Mock video", "ssrc", current_date); 286 response.addStatistic(report_index, "type", "video"); 287 } else { 288 for (int i = 0; i < stream_count_; ++i) { 289 size_t report_index = 290 response.addReport("Mock audio", "ssrc", current_date); 291 response.addStatistic(report_index, "type", "audio"); 292 report_index = response.addReport("Mock video", "ssrc", current_date); 293 response.addStatistic(report_index, "type", "video"); 294 } 295 } 296 interfaces_->GetDelegate()->PostTask( 297 new RTCStatsRequestSucceededTask(this, request, response)); 298 } 299 300 WebRTCDataChannelHandler* MockWebRTCPeerConnectionHandler::createDataChannel( 301 const WebString& label, 302 const blink::WebRTCDataChannelInit& init) { 303 interfaces_->GetDelegate()->PostTask( 304 new RemoteDataChannelTask(this, client_, interfaces_->GetDelegate())); 305 306 return new MockWebRTCDataChannelHandler( 307 label, init, interfaces_->GetDelegate()); 308 } 309 310 WebRTCDTMFSenderHandler* MockWebRTCPeerConnectionHandler::createDTMFSender( 311 const WebMediaStreamTrack& track) { 312 return new MockWebRTCDTMFSenderHandler(track, interfaces_->GetDelegate()); 313 } 314 315 void MockWebRTCPeerConnectionHandler::stop() { 316 stopped_ = true; 317 task_list_.RevokeAll(); 318 } 319 320 } // namespace content 321