Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / shell / renderer / test_runner / mock_webrtc_peer_connection_handler.cc
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/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"
22
23 using namespace blink;
24
25 namespace content {
26
27 class RTCSessionDescriptionRequestSuccededTask
28     : public WebMethodTask<MockWebRTCPeerConnectionHandler> {
29  public:
30   RTCSessionDescriptionRequestSuccededTask(
31       MockWebRTCPeerConnectionHandler* object,
32       const WebRTCSessionDescriptionRequest& request,
33       const WebRTCSessionDescription& result)
34       : WebMethodTask<MockWebRTCPeerConnectionHandler>(object),
35         request_(request),
36         result_(result) {}
37
38   void RunIfValid() override { request_.requestSucceeded(result_); }
39
40  private:
41   WebRTCSessionDescriptionRequest request_;
42   WebRTCSessionDescription result_;
43 };
44
45 class RTCSessionDescriptionRequestFailedTask
46     : public WebMethodTask<MockWebRTCPeerConnectionHandler> {
47  public:
48   RTCSessionDescriptionRequestFailedTask(
49       MockWebRTCPeerConnectionHandler* object,
50       const WebRTCSessionDescriptionRequest& request)
51       : WebMethodTask<MockWebRTCPeerConnectionHandler>(object),
52         request_(request) {}
53
54   void RunIfValid() override { request_.requestFailed("TEST_ERROR"); }
55
56  private:
57   WebRTCSessionDescriptionRequest request_;
58 };
59
60 class RTCStatsRequestSucceededTask
61     : public WebMethodTask<MockWebRTCPeerConnectionHandler> {
62  public:
63   RTCStatsRequestSucceededTask(MockWebRTCPeerConnectionHandler* object,
64                                const blink::WebRTCStatsRequest& request,
65                                const blink::WebRTCStatsResponse& response)
66       : WebMethodTask<MockWebRTCPeerConnectionHandler>(object),
67         request_(request),
68         response_(response) {}
69
70   void RunIfValid() override { request_.requestSucceeded(response_); }
71
72  private:
73   blink::WebRTCStatsRequest request_;
74   blink::WebRTCStatsResponse response_;
75 };
76
77 class RTCVoidRequestTask
78     : public WebMethodTask<MockWebRTCPeerConnectionHandler> {
79  public:
80   RTCVoidRequestTask(MockWebRTCPeerConnectionHandler* object,
81                      const WebRTCVoidRequest& request,
82                      bool succeeded)
83       : WebMethodTask<MockWebRTCPeerConnectionHandler>(object),
84         request_(request),
85         succeeded_(succeeded) {}
86
87   void RunIfValid() override {
88     if (succeeded_)
89       request_.requestSucceeded();
90     else
91       request_.requestFailed("TEST_ERROR");
92   }
93
94  private:
95   WebRTCVoidRequest request_;
96   bool succeeded_;
97 };
98
99 class RTCPeerConnectionStateTask
100     : public WebMethodTask<MockWebRTCPeerConnectionHandler> {
101  public:
102   RTCPeerConnectionStateTask(
103       MockWebRTCPeerConnectionHandler* object,
104       WebRTCPeerConnectionHandlerClient* client,
105       WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state,
106       WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state)
107       : WebMethodTask<MockWebRTCPeerConnectionHandler>(object),
108         client_(client),
109         connection_state_(connection_state),
110         gathering_state_(gathering_state) {}
111
112   void RunIfValid() override {
113     client_->didChangeICEGatheringState(gathering_state_);
114     client_->didChangeICEConnectionState(connection_state_);
115   }
116
117  private:
118   WebRTCPeerConnectionHandlerClient* client_;
119   WebRTCPeerConnectionHandlerClient::ICEConnectionState connection_state_;
120   WebRTCPeerConnectionHandlerClient::ICEGatheringState gathering_state_;
121 };
122
123 class RemoteDataChannelTask
124     : public WebMethodTask<MockWebRTCPeerConnectionHandler> {
125  public:
126   RemoteDataChannelTask(MockWebRTCPeerConnectionHandler* object,
127                         WebRTCPeerConnectionHandlerClient* client,
128                         WebTestDelegate* delegate)
129       : WebMethodTask<MockWebRTCPeerConnectionHandler>(object),
130         client_(client),
131         delegate_(delegate) {}
132
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);
139   }
140
141  private:
142   WebRTCPeerConnectionHandlerClient* client_;
143   WebTestDelegate* delegate_;
144 };
145
146 /////////////////////
147
148 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() {
149 }
150
151 MockWebRTCPeerConnectionHandler::~MockWebRTCPeerConnectionHandler() {
152 }
153
154 MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler(
155     WebRTCPeerConnectionHandlerClient* client,
156     TestInterfaces* interfaces)
157     : client_(client),
158       stopped_(false),
159       stream_count_(0),
160       interfaces_(interfaces) {
161 }
162
163 bool MockWebRTCPeerConnectionHandler::initialize(
164     const WebRTCConfiguration& configuration,
165     const WebMediaConstraints& constraints) {
166   if (MockConstraints::VerifyConstraints(constraints)) {
167     interfaces_->GetDelegate()->PostTask(new RTCPeerConnectionStateTask(
168         this,
169         client_,
170         WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted,
171         WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete));
172     return true;
173   }
174
175   return false;
176 }
177
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));
189   } else
190     interfaces_->GetDelegate()->PostTask(
191         new RTCSessionDescriptionRequestFailedTask(this, request));
192 }
193
194 void MockWebRTCPeerConnectionHandler::createOffer(
195     const WebRTCSessionDescriptionRequest& request,
196     const blink::WebRTCOfferOptions& options) {
197   interfaces_->GetDelegate()->PostTask(
198       new RTCSessionDescriptionRequestFailedTask(this, request));
199 }
200
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));
210   } else
211     interfaces_->GetDelegate()->PostTask(
212         new RTCSessionDescriptionRequestFailedTask(this, request));
213 }
214
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));
222   } else
223     interfaces_->GetDelegate()->PostTask(
224         new RTCVoidRequestTask(this, request, false));
225 }
226
227 void MockWebRTCPeerConnectionHandler::setRemoteDescription(
228     const WebRTCVoidRequest& request,
229     const WebRTCSessionDescription& remote_description) {
230
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));
236   } else
237     interfaces_->GetDelegate()->PostTask(
238         new RTCVoidRequestTask(this, request, false));
239 }
240
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()) {
248       removed_it++;
249       continue;
250     }
251
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]);
261     }
262
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]);
269     }
270     client_->didRemoveRemoteStream(stream);
271     remote_streams_.erase(removed_it++);
272   }
273
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()) {
279       added_it++;
280       continue;
281     }
282
283     const blink::WebMediaStream& stream = added_it->second;
284
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());
289
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       remote_audio_tracks[i].initialize(webkit_source);
296     }
297
298     blink::WebVector<blink::WebMediaStreamTrack> local_video_tracks;
299     stream.videoTracks(local_video_tracks);
300     blink::WebVector<blink::WebMediaStreamTrack>
301         remote_video_tracks(local_video_tracks.size());
302     for (size_t i = 0; i < local_video_tracks.size(); ++i) {
303       blink::WebMediaStreamSource webkit_source;
304       webkit_source.initialize(local_video_tracks[i].id(),
305                                blink::WebMediaStreamSource::TypeVideo,
306                                local_video_tracks[i].id());
307       remote_video_tracks[i].initialize(webkit_source);
308     }
309
310     blink::WebMediaStream new_remote_stream;
311     new_remote_stream.initialize(remote_audio_tracks,
312                                  remote_video_tracks);
313     remote_streams_[added_it->first] = new_remote_stream;
314     client_->didAddRemoteStream(new_remote_stream);
315     ++added_it;
316   }
317 }
318
319 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::localDescription() {
320   return local_description_;
321 }
322
323 WebRTCSessionDescription MockWebRTCPeerConnectionHandler::remoteDescription() {
324   return remote_description_;
325 }
326
327 bool MockWebRTCPeerConnectionHandler::updateICE(
328     const WebRTCConfiguration& configuration,
329     const WebMediaConstraints& constraints) {
330   return true;
331 }
332
333 bool MockWebRTCPeerConnectionHandler::addICECandidate(
334     const WebRTCICECandidate& ice_candidate) {
335   client_->didGenerateICECandidate(ice_candidate);
336   return true;
337 }
338
339 bool MockWebRTCPeerConnectionHandler::addICECandidate(
340     const WebRTCVoidRequest& request,
341     const WebRTCICECandidate& ice_candidate) {
342   interfaces_->GetDelegate()->PostTask(
343       new RTCVoidRequestTask(this, request, true));
344   return true;
345 }
346
347 bool MockWebRTCPeerConnectionHandler::addStream(
348     const WebMediaStream& stream,
349     const WebMediaConstraints& constraints) {
350   if (local_streams_.find(stream.id().utf8()) != local_streams_.end())
351     return false;
352   ++stream_count_;
353   client_->negotiationNeeded();
354   local_streams_[stream.id().utf8()] = stream;
355   return true;
356 }
357
358 void MockWebRTCPeerConnectionHandler::removeStream(
359     const WebMediaStream& stream) {
360   --stream_count_;
361   local_streams_.erase(stream.id().utf8());
362   client_->negotiationNeeded();
363 }
364
365 void MockWebRTCPeerConnectionHandler::getStats(
366     const WebRTCStatsRequest& request) {
367   WebRTCStatsResponse response = request.createResponse();
368   double current_date =
369       interfaces_->GetDelegate()->GetCurrentTimeInMillisecond();
370   if (request.hasSelector()) {
371     // FIXME: There is no check that the fetched values are valid.
372     size_t report_index =
373         response.addReport("Mock video", "ssrc", current_date);
374     response.addStatistic(report_index, "type", "video");
375   } else {
376     for (int i = 0; i < stream_count_; ++i) {
377       size_t report_index =
378           response.addReport("Mock audio", "ssrc", current_date);
379       response.addStatistic(report_index, "type", "audio");
380       report_index = response.addReport("Mock video", "ssrc", current_date);
381       response.addStatistic(report_index, "type", "video");
382     }
383   }
384   interfaces_->GetDelegate()->PostTask(
385       new RTCStatsRequestSucceededTask(this, request, response));
386 }
387
388 WebRTCDataChannelHandler* MockWebRTCPeerConnectionHandler::createDataChannel(
389     const WebString& label,
390     const blink::WebRTCDataChannelInit& init) {
391   interfaces_->GetDelegate()->PostTask(
392       new RemoteDataChannelTask(this, client_, interfaces_->GetDelegate()));
393
394   return new MockWebRTCDataChannelHandler(
395       label, init, interfaces_->GetDelegate());
396 }
397
398 WebRTCDTMFSenderHandler* MockWebRTCPeerConnectionHandler::createDTMFSender(
399     const WebMediaStreamTrack& track) {
400   return new MockWebRTCDTMFSenderHandler(track, interfaces_->GetDelegate());
401 }
402
403 void MockWebRTCPeerConnectionHandler::stop() {
404   stopped_ = true;
405   task_list_.RevokeAll();
406 }
407
408 }  // namespace content