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/WebRTCStatsResponse.h" 43 #include "public/platform/WebRTCVoidRequest.h" 44 #include "public/platform/WebString.h" 45 #include "public/platform/WebVector.h" 46 #include "public/testing/WebTestDelegate.h" 47 48 using namespace blink; 49 50 namespace WebTestRunner { 51 52 class RTCSessionDescriptionRequestSuccededTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 53 public: 54 RTCSessionDescriptionRequestSuccededTask(MockWebRTCPeerConnectionHandler* object, const WebRTCSessionDescriptionRequest& request, const WebRTCSessionDescription& result) 55 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 56 , m_request(request) 57 , m_result(result) 58 { 59 } 60 61 virtual void runIfValid() OVERRIDE 62 { 63 m_request.requestSucceeded(m_result); 64 } 65 66 private: 67 WebRTCSessionDescriptionRequest m_request; 68 WebRTCSessionDescription m_result; 69 }; 70 71 class RTCSessionDescriptionRequestFailedTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 72 public: 73 RTCSessionDescriptionRequestFailedTask(MockWebRTCPeerConnectionHandler* object, const WebRTCSessionDescriptionRequest& request) 74 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 75 , m_request(request) 76 { 77 } 78 79 virtual void runIfValid() OVERRIDE 80 { 81 m_request.requestFailed("TEST_ERROR"); 82 } 83 84 private: 85 WebRTCSessionDescriptionRequest m_request; 86 }; 87 88 class RTCStatsRequestSucceededTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 89 public: 90 RTCStatsRequestSucceededTask(MockWebRTCPeerConnectionHandler* object, const blink::WebRTCStatsRequest& request, const blink::WebRTCStatsResponse& response) 91 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 92 , m_request(request) 93 , m_response(response) 94 { 95 } 96 97 virtual void runIfValid() OVERRIDE 98 { 99 m_request.requestSucceeded(m_response); 100 } 101 102 private: 103 blink::WebRTCStatsRequest m_request; 104 blink::WebRTCStatsResponse m_response; 105 }; 106 107 class RTCVoidRequestTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 108 public: 109 RTCVoidRequestTask(MockWebRTCPeerConnectionHandler* object, const WebRTCVoidRequest& request, bool succeeded) 110 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 111 , m_request(request) 112 , m_succeeded(succeeded) 113 { 114 } 115 116 virtual void runIfValid() OVERRIDE 117 { 118 if (m_succeeded) 119 m_request.requestSucceeded(); 120 else 121 m_request.requestFailed("TEST_ERROR"); 122 } 123 124 private: 125 WebRTCVoidRequest m_request; 126 bool m_succeeded; 127 }; 128 129 class RTCPeerConnectionStateTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 130 public: 131 RTCPeerConnectionStateTask(MockWebRTCPeerConnectionHandler* object, WebRTCPeerConnectionHandlerClient* client, WebRTCPeerConnectionHandlerClient::ICEConnectionState connectionState, WebRTCPeerConnectionHandlerClient::ICEGatheringState gatheringState) 132 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 133 , m_client(client) 134 , m_connectionState(connectionState) 135 , m_gatheringState(gatheringState) 136 { 137 } 138 139 virtual void runIfValid() OVERRIDE 140 { 141 m_client->didChangeICEGatheringState(m_gatheringState); 142 m_client->didChangeICEConnectionState(m_connectionState); 143 } 144 145 private: 146 WebRTCPeerConnectionHandlerClient* m_client; 147 WebRTCPeerConnectionHandlerClient::ICEConnectionState m_connectionState; 148 WebRTCPeerConnectionHandlerClient::ICEGatheringState m_gatheringState; 149 }; 150 151 class RemoteDataChannelTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> { 152 public: 153 RemoteDataChannelTask(MockWebRTCPeerConnectionHandler* object, WebRTCPeerConnectionHandlerClient* client, WebTestDelegate* delegate) 154 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object) 155 , m_client(client) 156 , m_delegate(delegate) 157 { 158 } 159 160 virtual void runIfValid() OVERRIDE 161 { 162 WebRTCDataChannelInit init; 163 WebRTCDataChannelHandler* remoteDataChannel = new MockWebRTCDataChannelHandler("MockRemoteDataChannel", init, m_delegate); 164 m_client->didAddRemoteDataChannel(remoteDataChannel); 165 } 166 167 private: 168 WebRTCPeerConnectionHandlerClient* m_client; 169 WebTestDelegate* m_delegate; 170 }; 171 172 ///////////////////// 173 174 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler(WebRTCPeerConnectionHandlerClient* client, TestInterfaces* interfaces) 175 : m_client(client) 176 , m_stopped(false) 177 , m_streamCount(0) 178 , m_interfaces(interfaces) 179 { 180 } 181 182 bool MockWebRTCPeerConnectionHandler::initialize(const WebRTCConfiguration&, const WebMediaConstraints& constraints) 183 { 184 if (MockConstraints::verifyConstraints(constraints)) { 185 m_interfaces->delegate()->postTask(new RTCPeerConnectionStateTask(this, m_client, WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted, WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete)); 186 return true; 187 } 188 189 return false; 190 } 191 192 void MockWebRTCPeerConnectionHandler::createOffer(const WebRTCSessionDescriptionRequest& request, const WebMediaConstraints& constraints) 193 { 194 WebString shouldSucceed; 195 if (constraints.getMandatoryConstraintValue("succeed", shouldSucceed) && shouldSucceed == "true") { 196 WebRTCSessionDescription sessionDescription; 197 sessionDescription.initialize("offer", "local"); 198 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestSuccededTask(this, request, sessionDescription)); 199 } else 200 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestFailedTask(this, request)); 201 } 202 203 void MockWebRTCPeerConnectionHandler::createAnswer(const WebRTCSessionDescriptionRequest& request, const WebMediaConstraints&) 204 { 205 if (!m_remoteDescription.isNull()) { 206 WebRTCSessionDescription sessionDescription; 207 sessionDescription.initialize("answer", "local"); 208 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestSuccededTask(this, request, sessionDescription)); 209 } else 210 m_interfaces->delegate()->postTask(new RTCSessionDescriptionRequestFailedTask(this, request)); 211 } 212 213 void MockWebRTCPeerConnectionHandler::setLocalDescription(const WebRTCVoidRequest& request, const WebRTCSessionDescription& localDescription) 214 { 215 if (!localDescription.isNull() && localDescription.sdp() == "local") { 216 m_localDescription = localDescription; 217 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, true)); 218 } else 219 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, false)); 220 } 221 222 void MockWebRTCPeerConnectionHandler::setRemoteDescription(const WebRTCVoidRequest& request, const WebRTCSessionDescription& remoteDescription) 223 { 224 if (!remoteDescription.isNull() && remoteDescription.sdp() == "remote") { 225 m_remoteDescription = remoteDescription; 226 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, true)); 227 } else 228 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, false)); 229 } 230 231 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::localDescription() 232 { 233 return m_localDescription; 234 } 235 236 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::remoteDescription() 237 { 238 return m_remoteDescription; 239 } 240 241 bool MockWebRTCPeerConnectionHandler::updateICE(const WebRTCConfiguration&, const WebMediaConstraints&) 242 { 243 return true; 244 } 245 246 bool MockWebRTCPeerConnectionHandler::addICECandidate(const WebRTCICECandidate& iceCandidate) 247 { 248 m_client->didGenerateICECandidate(iceCandidate); 249 return true; 250 } 251 252 bool MockWebRTCPeerConnectionHandler::addICECandidate(const WebRTCVoidRequest& request, const WebRTCICECandidate& iceCandidate) 253 { 254 m_interfaces->delegate()->postTask(new RTCVoidRequestTask(this, request, true)); 255 return true; 256 } 257 258 bool MockWebRTCPeerConnectionHandler::addStream(const WebMediaStream& stream, const WebMediaConstraints&) 259 { 260 ++m_streamCount; 261 m_client->negotiationNeeded(); 262 return true; 263 } 264 265 void MockWebRTCPeerConnectionHandler::removeStream(const WebMediaStream& stream) 266 { 267 --m_streamCount; 268 m_client->negotiationNeeded(); 269 } 270 271 void MockWebRTCPeerConnectionHandler::getStats(const WebRTCStatsRequest& request) 272 { 273 WebRTCStatsResponse response = request.createResponse(); 274 double currentDate = m_interfaces->delegate()->getCurrentTimeInMillisecond(); 275 if (request.hasSelector()) { 276 // FIXME: There is no check that the fetched values are valid. 277 size_t reportIndex = response.addReport("Mock video", "ssrc", currentDate); 278 response.addStatistic(reportIndex, "type", "video"); 279 } else { 280 for (int i = 0; i < m_streamCount; ++i) { 281 size_t reportIndex = response.addReport("Mock audio", "ssrc", currentDate); 282 response.addStatistic(reportIndex, "type", "audio"); 283 reportIndex = response.addReport("Mock video", "ssrc", currentDate); 284 response.addStatistic(reportIndex, "type", "video"); 285 } 286 } 287 m_interfaces->delegate()->postTask(new RTCStatsRequestSucceededTask(this, request, response)); 288 } 289 290 WebRTCDataChannelHandler* MockWebRTCPeerConnectionHandler::createDataChannel(const WebString& label, const blink::WebRTCDataChannelInit& init) 291 { 292 m_interfaces->delegate()->postTask(new RemoteDataChannelTask(this, m_client, m_interfaces->delegate())); 293 294 return new MockWebRTCDataChannelHandler(label, init, m_interfaces->delegate()); 295 } 296 297 WebRTCDTMFSenderHandler* MockWebRTCPeerConnectionHandler::createDTMFSender(const WebMediaStreamTrack& track) 298 { 299 return new MockWebRTCDTMFSenderHandler(track, m_interfaces->delegate()); 300 } 301 302 void MockWebRTCPeerConnectionHandler::stop() 303 { 304 m_stopped = true; 305 } 306 307 } 308