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.
5 #include "components/test_runner/mock_webrtc_peer_connection_handler.h"
7 #include "components/test_runner/mock_constraints.h"
8 #include "components/test_runner/mock_webrtc_data_channel_handler.h"
9 #include "components/test_runner/mock_webrtc_dtmf_sender_handler.h"
10 #include "components/test_runner/test_interfaces.h"
11 #include "components/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"
23 using namespace blink
;
25 namespace test_runner
{
27 class RTCSessionDescriptionRequestSuccededTask
28 : public WebMethodTask
<MockWebRTCPeerConnectionHandler
> {
30 RTCSessionDescriptionRequestSuccededTask(
31 MockWebRTCPeerConnectionHandler
* object
,
32 const WebRTCSessionDescriptionRequest
& request
,
33 const WebRTCSessionDescription
& result
)
34 : WebMethodTask
<MockWebRTCPeerConnectionHandler
>(object
),
38 void RunIfValid() override
{ request_
.requestSucceeded(result_
); }
41 WebRTCSessionDescriptionRequest request_
;
42 WebRTCSessionDescription result_
;
45 class RTCSessionDescriptionRequestFailedTask
46 : public WebMethodTask
<MockWebRTCPeerConnectionHandler
> {
48 RTCSessionDescriptionRequestFailedTask(
49 MockWebRTCPeerConnectionHandler
* object
,
50 const WebRTCSessionDescriptionRequest
& request
)
51 : WebMethodTask
<MockWebRTCPeerConnectionHandler
>(object
),
54 void RunIfValid() override
{ request_
.requestFailed("TEST_ERROR"); }
57 WebRTCSessionDescriptionRequest request_
;
60 class RTCStatsRequestSucceededTask
61 : public WebMethodTask
<MockWebRTCPeerConnectionHandler
> {
63 RTCStatsRequestSucceededTask(MockWebRTCPeerConnectionHandler
* object
,
64 const blink::WebRTCStatsRequest
& request
,
65 const blink::WebRTCStatsResponse
& response
)
66 : WebMethodTask
<MockWebRTCPeerConnectionHandler
>(object
),
68 response_(response
) {}
70 void RunIfValid() override
{ request_
.requestSucceeded(response_
); }
73 blink::WebRTCStatsRequest request_
;
74 blink::WebRTCStatsResponse response_
;
77 class RTCVoidRequestTask
78 : public WebMethodTask
<MockWebRTCPeerConnectionHandler
> {
80 RTCVoidRequestTask(MockWebRTCPeerConnectionHandler
* object
,
81 const WebRTCVoidRequest
& request
,
83 : WebMethodTask
<MockWebRTCPeerConnectionHandler
>(object
),
85 succeeded_(succeeded
) {}
87 void RunIfValid() override
{
89 request_
.requestSucceeded();
91 request_
.requestFailed("TEST_ERROR");
95 WebRTCVoidRequest request_
;
99 class RTCPeerConnectionStateTask
100 : public WebMethodTask
<MockWebRTCPeerConnectionHandler
> {
102 RTCPeerConnectionStateTask(
103 MockWebRTCPeerConnectionHandler
* object
,
104 WebRTCPeerConnectionHandlerClient
* client
,
105 WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state
,
106 WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state
)
107 : WebMethodTask
<MockWebRTCPeerConnectionHandler
>(object
),
109 connection_state_(connection_state
),
110 gathering_state_(gathering_state
) {}
112 void RunIfValid() override
{
113 client_
->didChangeICEGatheringState(gathering_state_
);
114 client_
->didChangeICEConnectionState(connection_state_
);
118 WebRTCPeerConnectionHandlerClient
* client_
;
119 WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state_
;
120 WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state_
;
123 class RemoteDataChannelTask
124 : public WebMethodTask
<MockWebRTCPeerConnectionHandler
> {
126 RemoteDataChannelTask(MockWebRTCPeerConnectionHandler
* object
,
127 WebRTCPeerConnectionHandlerClient
* client
,
128 WebTestDelegate
* delegate
)
129 : WebMethodTask
<MockWebRTCPeerConnectionHandler
>(object
),
131 delegate_(delegate
) {}
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
);
142 WebRTCPeerConnectionHandlerClient
* client_
;
143 WebTestDelegate
* delegate_
;
146 /////////////////////
148 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() {
151 MockWebRTCPeerConnectionHandler::~MockWebRTCPeerConnectionHandler() {
154 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler(
155 WebRTCPeerConnectionHandlerClient
* client
,
156 TestInterfaces
* interfaces
)
160 interfaces_(interfaces
) {
163 bool MockWebRTCPeerConnectionHandler::initialize(
164 const WebRTCConfiguration
& configuration
,
165 const WebMediaConstraints
& constraints
) {
166 if (MockConstraints::VerifyConstraints(constraints
)) {
167 interfaces_
->GetDelegate()->PostTask(new RTCPeerConnectionStateTask(
170 WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted
,
171 WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete
));
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
));
190 interfaces_
->GetDelegate()->PostTask(
191 new RTCSessionDescriptionRequestFailedTask(this, request
));
194 void MockWebRTCPeerConnectionHandler::createOffer(
195 const WebRTCSessionDescriptionRequest
& request
,
196 const blink::WebRTCOfferOptions
& options
) {
197 interfaces_
->GetDelegate()->PostTask(
198 new RTCSessionDescriptionRequestFailedTask(this, request
));
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
));
211 interfaces_
->GetDelegate()->PostTask(
212 new RTCSessionDescriptionRequestFailedTask(this, request
));
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));
223 interfaces_
->GetDelegate()->PostTask(
224 new RTCVoidRequestTask(this, request
, false));
227 void MockWebRTCPeerConnectionHandler::setRemoteDescription(
228 const WebRTCVoidRequest
& request
,
229 const WebRTCSessionDescription
& remote_description
) {
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));
237 interfaces_
->GetDelegate()->PostTask(
238 new RTCVoidRequestTask(this, request
, false));
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()) {
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
]);
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
]);
270 client_
->didRemoveRemoteStream(stream
);
271 remote_streams_
.erase(removed_it
++);
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()) {
283 const blink::WebMediaStream
& stream
= added_it
->second
;
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());
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
);
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
);
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
);
321 WebRTCSessionDescription
MockWebRTCPeerConnectionHandler::localDescription() {
322 return local_description_
;
325 WebRTCSessionDescription
MockWebRTCPeerConnectionHandler::remoteDescription() {
326 return remote_description_
;
329 bool MockWebRTCPeerConnectionHandler::updateICE(
330 const WebRTCConfiguration
& configuration
,
331 const WebMediaConstraints
& constraints
) {
335 bool MockWebRTCPeerConnectionHandler::addICECandidate(
336 const WebRTCICECandidate
& ice_candidate
) {
337 client_
->didGenerateICECandidate(ice_candidate
);
341 bool MockWebRTCPeerConnectionHandler::addICECandidate(
342 const WebRTCVoidRequest
& request
,
343 const WebRTCICECandidate
& ice_candidate
) {
344 interfaces_
->GetDelegate()->PostTask(
345 new RTCVoidRequestTask(this, request
, true));
349 bool MockWebRTCPeerConnectionHandler::addStream(
350 const WebMediaStream
& stream
,
351 const WebMediaConstraints
& constraints
) {
352 if (local_streams_
.find(stream
.id().utf8()) != local_streams_
.end())
355 client_
->negotiationNeeded();
356 local_streams_
[stream
.id().utf8()] = stream
;
360 void MockWebRTCPeerConnectionHandler::removeStream(
361 const WebMediaStream
& stream
) {
363 local_streams_
.erase(stream
.id().utf8());
364 client_
->negotiationNeeded();
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");
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");
386 interfaces_
->GetDelegate()->PostTask(
387 new RTCStatsRequestSucceededTask(this, request
, response
));
390 WebRTCDataChannelHandler
* MockWebRTCPeerConnectionHandler::createDataChannel(
391 const WebString
& label
,
392 const blink::WebRTCDataChannelInit
& init
) {
393 interfaces_
->GetDelegate()->PostTask(
394 new RemoteDataChannelTask(this, client_
, interfaces_
->GetDelegate()));
396 return new MockWebRTCDataChannelHandler(
397 label
, init
, interfaces_
->GetDelegate());
400 WebRTCDTMFSenderHandler
* MockWebRTCPeerConnectionHandler::createDTMFSender(
401 const WebMediaStreamTrack
& track
) {
402 return new MockWebRTCDTMFSenderHandler(track
, interfaces_
->GetDelegate());
405 void MockWebRTCPeerConnectionHandler::stop() {
407 task_list_
.RevokeAll();
410 } // namespace test_runner