1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "MockWebRTCPeerConnectionHandler.h" 32 33 #include "MockConstraints.h" 34 #include "MockWebRTCDTMFSenderHandler.h" 35 #include "MockWebRTCDataChannelHandler.h" 36 #include "TestInterfaces.h" 37 #include "public/platform/WebMediaConstraints.h" 38 #include "public/platform/WebMediaStream.h" 39 #include "public/platform/WebMediaStreamTrack.h" 40 #include "public/platform/WebRTCDataChannelInit.h" 41 #include "public/platform/WebRTCPeerConnectionHandlerClient.h" 42 #include "public/platform/WebRTCSessionDescription.h" 43 #include "public/platform/WebRTCSessionDescriptionRequest.h" 44 #include "public/platform/WebRTCStatsRequest.h" 45 #include "public/platform/WebRTCStatsResponse.h" 46 #include "public/platform/WebRTCVoidRequest.h" 47 #include "public/platform/WebString.h" 48 #include "public/platform/WebVector.h" 49 #include "public/testing/WebTestDelegate.h" 50 51 using namespace WebKit; 52 53 namespace WebTestRunner { 54 55 class RTCSessionDescriptionRequestSuccededTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 56 public: 57 RTCSessionDescriptionRequestSuccededTask(MockWebRTCPeerConnectionHandler* object, const WebRTCSessionDescriptionRequest& request, const WebRTCSessionDescription& result) 58 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 59 , m_request(request) 60 , m_result(result) 61 { 62 } 63 64 virtual void runIfValid() OVERRIDE 65 { 66 m_request.requestSucceeded(m_result); 67 } 68 69 private: 70 WebRTCSessionDescriptionRequest m_request; 71 WebRTCSessionDescription m_result; 72 }; 73 74 class RTCSessionDescriptionRequestFailedTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 75 public: 76 RTCSessionDescriptionRequestFailedTask(MockWebRTCPeerConnectionHandler* object, const WebRTCSessionDescriptionRequest& request) 77 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 78 , m_request(request) 79 { 80 } 81 82 virtual void runIfValid() OVERRIDE 83 { 84 m_request.requestFailed("TEST_ERROR"); 85 } 86 87 private: 88 WebRTCSessionDescriptionRequest m_request; 89 }; 90 91 class RTCStatsRequestSucceededTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 92 public: 93 RTCStatsRequestSucceededTask(MockWebRTCPeerConnectionHandler* object, const WebKit::WebRTCStatsRequest& request, const WebKit::WebRTCStatsResponse& response) 94 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 95 , m_request(request) 96 , m_response(response) 97 { 98 } 99 100 virtual void runIfValid() OVERRIDE 101 { 102 m_request.requestSucceeded(m_response); 103 } 104 105 private: 106 WebKit::WebRTCStatsRequest m_request; 107 WebKit::WebRTCStatsResponse m_response; 108 }; 109 110 class RTCVoidRequestTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 111 public: 112 RTCVoidRequestTask(MockWebRTCPeerConnectionHandler* object, const WebRTCVoidRequest& request, bool succeeded) 113 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 114 , m_request(request) 115 , m_succeeded(succeeded) 116 { 117 } 118 119 virtual void runIfValid() OVERRIDE 120 { 121 if (m_succeeded) 122 m_request.requestSucceeded(); 123 else 124 m_request.requestFailed("TEST_ERROR"); 125 } 126 127 private: 128 WebRTCVoidRequest m_request; 129 bool m_succeeded; 130 }; 131 132 class RTCPeerConnectionStateTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 133 public: 134 RTCPeerConnectionStateTask(MockWebRTCPeerConnectionHandler* object, WebRTCPeerConnectionHandlerClient* client, WebRTCPeerConnectionHandlerClient::ICEConnectionState connectionState, WebRTCPeerConnectionHandlerClient::ICEGatheringState gatheringState) 135 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 136 , m_client(client) 137 , m_connectionState(connectionState) 138 , m_gatheringState(gatheringState) 139 { 140 } 141 142 virtual void runIfValid() OVERRIDE 143 { 144 m_client->didChangeICEGatheringState(m_gatheringState); 145 m_client->didChangeICEConnectionState(m_connectionState); 146 } 147 148 private: 149 WebRTCPeerConnectionHandlerClient* m_client; 150 WebRTCPeerConnectionHandlerClient::ICEConnectionState m_connectionState; 151 WebRTCPeerConnectionHandlerClient::ICEGatheringState m_gatheringState; 152 }; 153 154 class RemoteDataChannelTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 155 public: 156 RemoteDataChannelTask(MockWebRTCPeerConnectionHandler* object, WebRTCPeerConnectionHandlerClient* client, WebTestDelegate* delegate) 157 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 158 , m_client(client) 159 , m_delegate(delegate) 160 { 161 } 162 163 virtual void runIfValid() OVERRIDE 164 { 165 WebRTCDataChannelInit init; 166 WebRTCDataChannelHandler* remoteDataChannel = new MockWebRTCDataChannelHandler("MockRemoteDataChannel", init, m_delegate); 167 m_client->didAddRemoteDataChannel(remoteDataChannel); 168 } 169 170 private: 171 WebRTCPeerConnectionHandlerClient* m_client; 172 WebTestDelegate* m_delegate; 173 }; 174 175 ///////////////////// 176 177 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler(WebRTCPeerConnectionHandlerClient* client, TestInterfaces* interfaces) 178 : m_client(client) 179 , m_stopped(false) 180 , m_streamCount(0) 181 , m_interfaces(interfaces) 182 { 183 } 184 185 bool MockWebRTCPeerConnectionHandler::initialize(const WebRTCConfiguration&, const WebMediaConstraints& constraints) 186 { 187 if (MockConstraints::verifyConstraints(constraints)) { 188 m_interfaces->delegate()->postTask(new RTCPeerConnectionStateTask(this, m_client, WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted, WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete)); 189 return true; 190 } 191 192 return false; 193 } 194 195 void MockWebRTCPeerConnectionHandler::createOffer(const WebRTCSessionDescriptionRequest& request, const WebMediaConstraints& constraints) 196 { 197 WebString shouldSucceed; 198 if (constraints.getMandatoryConstraintValue("succeed", shouldSucceed) && shouldSucceed == "true") { 199 WebRTCSessionDescription sessionDescription; 200 sessionDescription.initialize("offer", "local"); 201 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestSuccededTask(this, request, sessionDescription)); 202 } else 203 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestFailedTask(this, request)); 204 } 205 206 void MockWebRTCPeerConnectionHandler::createAnswer(const WebRTCSessionDescriptionRequest& request, const WebMediaConstraints&) 207 { 208 if (!m_remoteDescription.isNull()) { 209 WebRTCSessionDescription sessionDescription; 210 sessionDescription.initialize("answer", "local"); 211 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestSuccededTask(this, request, sessionDescription)); 212 } else 213 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestFailedTask(this, request)); 214 } 215 216 void MockWebRTCPeerConnectionHandler::setLocalDescription(const WebRTCVoidRequest& request, const WebRTCSessionDescription& localDescription) 217 { 218 if (!localDescription.isNull() && localDescription.sdp() == "local") { 219 m_localDescription = localDescription; 220 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, true)); 221 } else 222 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, false)); 223 } 224 225 void MockWebRTCPeerConnectionHandler::setRemoteDescription(const WebRTCVoidRequest& request, const WebRTCSessionDescription& remoteDescription) 226 { 227 if (!remoteDescription.isNull() && remoteDescription.sdp() == "remote") { 228 m_remoteDescription = remoteDescription; 229 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, true)); 230 } else 231 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, false)); 232 } 233 234 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::localDescription() 235 { 236 return m_localDescription; 237 } 238 239 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::remoteDescription() 240 { 241 return m_remoteDescription; 242 } 243 244 bool MockWebRTCPeerConnectionHandler::updateICE(const WebRTCConfiguration&, const WebMediaConstraints&) 245 { 246 return true; 247 } 248 249 bool MockWebRTCPeerConnectionHandler::addICECandidate(const WebRTCICECandidate& iceCandidate) 250 { 251 m_client->didGenerateICECandidate(iceCandidate); 252 return true; 253 } 254 255 bool MockWebRTCPeerConnectionHandler::addStream(const WebMediaStream& stream, const WebMediaConstraints&) 256 { 257 ++m_streamCount; 258 m_client->negotiationNeeded(); 259 return true; 260 } 261 262 void MockWebRTCPeerConnectionHandler::removeStream(const WebMediaStream& stream) 263 { 264 --m_streamCount; 265 m_client->negotiationNeeded(); 266 } 267 268 void MockWebRTCPeerConnectionHandler::getStats(const WebRTCStatsRequest& request) 269 { 270 WebRTCStatsResponse response = request.createResponse(); 271 double currentDate = m_interfaces->delegate()->getCurrentTimeInMillisecond(); 272 if (request.hasSelector()) { 273 WebMediaStream stream = request.stream(); 274 // FIXME: There is no check that the fetched values are valid. 275 size_t reportIndex = response.addReport("Mock video", "ssrc", currentDate); 276 response.addStatistic(reportIndex, "type", "video"); 277 } else { 278 for (int i = 0; i < m_streamCount; ++i) { 279 size_t reportIndex = response.addReport("Mock audio", "ssrc", currentDate); 280 response.addStatistic(reportIndex, "type", "audio"); 281 reportIndex = response.addReport("Mock video", "ssrc", currentDate); 282 response.addStatistic(reportIndex, "type", "video"); 283 } 284 } 285 m_interfaces->delegate()->postTask(new RTCStatsRequestSucceededTask(this, request, response)); 286 } 287 288 WebRTCDataChannelHandler* MockWebRTCPeerConnectionHandler::createDataChannel(const WebString& label, const WebKit::WebRTCDataChannelInit& init) 289 { 290 m_interfaces->delegate()->postTask(new RemoteDataChannelTask(this, m_client, m_interfaces->delegate())); 291 292 return new MockWebRTCDataChannelHandler(label, init, m_interfaces->delegate()); 293 } 294 295 WebRTCDTMFSenderHandler* MockWebRTCPeerConnectionHandler::createDTMFSender(const WebMediaStreamTrack& track) 296 { 297 return new MockWebRTCDTMFSenderHandler(track, m_interfaces->delegate()); 298 } 299 300 void MockWebRTCPeerConnectionHandler::stop() 301 { 302 m_stopped = true; 303 } 304 305 } 306