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:
RTCSessionDescriptionRequestSuccededTask(MockWebRTCPeerConnectionHandler * object,const WebRTCSessionDescriptionRequest & request,const WebRTCSessionDescription & result)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
runIfValid()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:
RTCSessionDescriptionRequestFailedTask(MockWebRTCPeerConnectionHandler * object,const WebRTCSessionDescriptionRequest & request)73 RTCSessionDescriptionRequestFailedTask(MockWebRTCPeerConnectionHandler* object, const WebRTCSessionDescriptionRequest& request)
74 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object)
75 , m_request(request)
76 {
77 }
78
runIfValid()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:
RTCStatsRequestSucceededTask(MockWebRTCPeerConnectionHandler * object,const blink::WebRTCStatsRequest & request,const blink::WebRTCStatsResponse & response)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
runIfValid()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:
RTCVoidRequestTask(MockWebRTCPeerConnectionHandler * object,const WebRTCVoidRequest & request,bool succeeded)109 RTCVoidRequestTask(MockWebRTCPeerConnectionHandler* object, const WebRTCVoidRequest& request, bool succeeded)
110 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object)
111 , m_request(request)
112 , m_succeeded(succeeded)
113 {
114 }
115
runIfValid()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:
RTCPeerConnectionStateTask(MockWebRTCPeerConnectionHandler * object,WebRTCPeerConnectionHandlerClient * client,WebRTCPeerConnectionHandlerClient::ICEConnectionState connectionState,WebRTCPeerConnectionHandlerClient::ICEGatheringState gatheringState)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
runIfValid()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:
RemoteDataChannelTask(MockWebRTCPeerConnectionHandler * object,WebRTCPeerConnectionHandlerClient * client,WebTestDelegate * delegate)153 RemoteDataChannelTask(MockWebRTCPeerConnectionHandler* object, WebRTCPeerConnectionHandlerClient* client, WebTestDelegate* delegate)
154 : WebMethodTask<MockWebRTCPeerConnectionHandler>(object)
155 , m_client(client)
156 , m_delegate(delegate)
157 {
158 }
159
runIfValid()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
MockWebRTCPeerConnectionHandler(WebRTCPeerConnectionHandlerClient * client,TestInterfaces * interfaces)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
initialize(const WebRTCConfiguration &,const WebMediaConstraints & constraints)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
createOffer(const WebRTCSessionDescriptionRequest & request,const WebMediaConstraints & constraints)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
createAnswer(const WebRTCSessionDescriptionRequest & request,const WebMediaConstraints &)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
setLocalDescription(const WebRTCVoidRequest & request,const WebRTCSessionDescription & localDescription)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
setRemoteDescription(const WebRTCVoidRequest & request,const WebRTCSessionDescription & remoteDescription)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
localDescription()231 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::localDescription()
232 {
233 return m_localDescription;
234 }
235
remoteDescription()236 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::remoteDescription()
237 {
238 return m_remoteDescription;
239 }
240
updateICE(const WebRTCConfiguration &,const WebMediaConstraints &)241 bool MockWebRTCPeerConnectionHandler::updateICE(const WebRTCConfiguration&, const WebMediaConstraints&)
242 {
243 return true;
244 }
245
addICECandidate(const WebRTCICECandidate & iceCandidate)246 bool MockWebRTCPeerConnectionHandler::addICECandidate(const WebRTCICECandidate& iceCandidate)
247 {
248 m_client->didGenerateICECandidate(iceCandidate);
249 return true;
250 }
251
addICECandidate(const WebRTCVoidRequest & request,const WebRTCICECandidate & iceCandidate)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
addStream(const WebMediaStream & stream,const WebMediaConstraints &)258 bool MockWebRTCPeerConnectionHandler::addStream(const WebMediaStream& stream, const WebMediaConstraints&)
259 {
260 ++m_streamCount;
261 m_client->negotiationNeeded();
262 return true;
263 }
264
removeStream(const WebMediaStream & stream)265 void MockWebRTCPeerConnectionHandler::removeStream(const WebMediaStream& stream)
266 {
267 --m_streamCount;
268 m_client->negotiationNeeded();
269 }
270
getStats(const WebRTCStatsRequest & request)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
createDataChannel(const WebString & label,const blink::WebRTCDataChannelInit & init)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
createDTMFSender(const WebMediaStreamTrack & track)297 WebRTCDTMFSenderHandler* MockWebRTCPeerConnectionHandler::createDTMFSender(const WebMediaStreamTrack& track)
298 {
299 return new MockWebRTCDTMFSenderHandler(track, m_interfaces->delegate());
300 }
301
stop()302 void MockWebRTCPeerConnectionHandler::stop()
303 {
304 m_stopped = true;
305 }
306
307 }
308