2bd05e7cf6cf3d8335161c56c05ecf1107e14e1e
[platform/framework/web/crosswalk.git] / src / content / renderer / media / rtc_peer_connection_handler_unittest.cc
1 // Copyright (c) 2012 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 <string>
6 #include <vector>
7
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "content/child/child_process.h"
13 #include "content/renderer/media/media_stream.h"
14 #include "content/renderer/media/media_stream_audio_source.h"
15 #include "content/renderer/media/media_stream_source.h"
16 #include "content/renderer/media/media_stream_video_track.h"
17 #include "content/renderer/media/mock_media_stream_video_source.h"
18 #include "content/renderer/media/mock_peer_connection_impl.h"
19 #include "content/renderer/media/mock_web_rtc_peer_connection_handler_client.h"
20 #include "content/renderer/media/peer_connection_tracker.h"
21 #include "content/renderer/media/rtc_media_constraints.h"
22 #include "content/renderer/media/rtc_peer_connection_handler.h"
23 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
24 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
25 #include "content/renderer/media/webrtc_audio_capturer.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
29 #include "third_party/WebKit/public/platform/WebMediaStream.h"
30 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
31 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
32 #include "third_party/WebKit/public/platform/WebRTCConfiguration.h"
33 #include "third_party/WebKit/public/platform/WebRTCDTMFSenderHandler.h"
34 #include "third_party/WebKit/public/platform/WebRTCDataChannelHandler.h"
35 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
36 #include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
37 #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h"
38 #include "third_party/WebKit/public/platform/WebRTCSessionDescription.h"
39 #include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h"
40 #include "third_party/WebKit/public/platform/WebRTCStatsRequest.h"
41 #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h"
42 #include "third_party/WebKit/public/platform/WebURL.h"
43 #include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h"
44
45 static const char kDummySdp[] = "dummy sdp";
46 static const char kDummySdpType[] = "dummy type";
47
48 using blink::WebRTCPeerConnectionHandlerClient;
49 using testing::NiceMock;
50 using testing::_;
51 using testing::Ref;
52
53 namespace content {
54
55 class MockRTCStatsResponse : public LocalRTCStatsResponse {
56  public:
57   MockRTCStatsResponse()
58       : report_count_(0),
59         statistic_count_(0) {
60   }
61
62   virtual size_t addReport(blink::WebString type,
63                            blink::WebString id,
64                            double timestamp) OVERRIDE {
65     ++report_count_;
66     return report_count_;
67   }
68
69   virtual void addStatistic(size_t report,
70                             blink::WebString name, blink::WebString value)
71       OVERRIDE {
72     ++statistic_count_;
73   }
74   int report_count() const { return report_count_; }
75
76  private:
77   int report_count_;
78   int statistic_count_;
79 };
80
81 // Mocked wrapper for blink::WebRTCStatsRequest
82 class MockRTCStatsRequest : public LocalRTCStatsRequest {
83  public:
84   MockRTCStatsRequest()
85       : has_selector_(false),
86         request_succeeded_called_(false) {}
87
88   virtual bool hasSelector() const OVERRIDE {
89     return has_selector_;
90   }
91   virtual blink::WebMediaStreamTrack component() const OVERRIDE {
92     return component_;
93   }
94   virtual scoped_refptr<LocalRTCStatsResponse> createResponse() OVERRIDE {
95     DCHECK(!response_.get());
96     response_ = new rtc::RefCountedObject<MockRTCStatsResponse>();
97     return response_;
98   }
99
100   virtual void requestSucceeded(const LocalRTCStatsResponse* response)
101       OVERRIDE {
102     EXPECT_EQ(response, response_.get());
103     request_succeeded_called_ = true;
104   }
105
106   // Function for setting whether or not a selector is available.
107   void setSelector(const blink::WebMediaStreamTrack& component) {
108     has_selector_ = true;
109     component_ = component;
110   }
111
112   // Function for inspecting the result of a stats request.
113   MockRTCStatsResponse* result() {
114     if (request_succeeded_called_) {
115       return response_.get();
116     } else {
117       return NULL;
118     }
119   }
120
121  private:
122   bool has_selector_;
123   blink::WebMediaStreamTrack component_;
124   scoped_refptr<MockRTCStatsResponse> response_;
125   bool request_succeeded_called_;
126 };
127
128 class MockPeerConnectionTracker : public PeerConnectionTracker {
129  public:
130   MOCK_METHOD1(UnregisterPeerConnection,
131                void(RTCPeerConnectionHandler* pc_handler));
132   // TODO(jiayl): add coverage for the following methods
133   MOCK_METHOD2(TrackCreateOffer,
134                void(RTCPeerConnectionHandler* pc_handler,
135                     const RTCMediaConstraints& constraints));
136   MOCK_METHOD2(TrackCreateAnswer,
137                void(RTCPeerConnectionHandler* pc_handler,
138                     const RTCMediaConstraints& constraints));
139   MOCK_METHOD3(TrackSetSessionDescription,
140                void(RTCPeerConnectionHandler* pc_handler,
141                     const blink::WebRTCSessionDescription& desc,
142                     Source source));
143   MOCK_METHOD3(
144       TrackUpdateIce,
145       void(RTCPeerConnectionHandler* pc_handler,
146            const webrtc::PeerConnectionInterface::RTCConfiguration& config,
147            const RTCMediaConstraints& options));
148   MOCK_METHOD3(TrackAddIceCandidate,
149                void(RTCPeerConnectionHandler* pc_handler,
150                     const blink::WebRTCICECandidate& candidate,
151                     Source source));
152   MOCK_METHOD3(TrackAddStream,
153                void(RTCPeerConnectionHandler* pc_handler,
154                     const blink::WebMediaStream& stream,
155                     Source source));
156   MOCK_METHOD3(TrackRemoveStream,
157                void(RTCPeerConnectionHandler* pc_handler,
158                     const blink::WebMediaStream& stream,
159                     Source source));
160   MOCK_METHOD1(TrackOnIceComplete,
161                void(RTCPeerConnectionHandler* pc_handler));
162   MOCK_METHOD3(TrackCreateDataChannel,
163                void(RTCPeerConnectionHandler* pc_handler,
164                     const webrtc::DataChannelInterface* data_channel,
165                     Source source));
166   MOCK_METHOD1(TrackStop, void(RTCPeerConnectionHandler* pc_handler));
167   MOCK_METHOD2(TrackSignalingStateChange,
168                void(RTCPeerConnectionHandler* pc_handler,
169                     WebRTCPeerConnectionHandlerClient::SignalingState state));
170   MOCK_METHOD2(
171       TrackIceConnectionStateChange,
172       void(RTCPeerConnectionHandler* pc_handler,
173            WebRTCPeerConnectionHandlerClient::ICEConnectionState state));
174   MOCK_METHOD2(
175       TrackIceGatheringStateChange,
176       void(RTCPeerConnectionHandler* pc_handler,
177            WebRTCPeerConnectionHandlerClient::ICEGatheringState state));
178   MOCK_METHOD1(TrackOnRenegotiationNeeded,
179                void(RTCPeerConnectionHandler* pc_handler));
180   MOCK_METHOD2(TrackCreateDTMFSender,
181                void(RTCPeerConnectionHandler* pc_handler,
182                      const blink::WebMediaStreamTrack& track));
183 };
184
185 class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler {
186  public:
187   RTCPeerConnectionHandlerUnderTest(
188       WebRTCPeerConnectionHandlerClient* client,
189       PeerConnectionDependencyFactory* dependency_factory)
190       : RTCPeerConnectionHandler(client, dependency_factory) {
191   }
192
193   MockPeerConnectionImpl* native_peer_connection() {
194     return static_cast<MockPeerConnectionImpl*>(
195         RTCPeerConnectionHandler::native_peer_connection());
196   }
197 };
198
199 class RTCPeerConnectionHandlerTest : public ::testing::Test {
200  public:
201   RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL) {
202     child_process_.reset(new ChildProcess());
203   }
204
205   virtual void SetUp() {
206     mock_client_.reset(new NiceMock<MockWebRTCPeerConnectionHandlerClient>());
207     mock_dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
208     pc_handler_.reset(
209         new RTCPeerConnectionHandlerUnderTest(mock_client_.get(),
210                                               mock_dependency_factory_.get()));
211     mock_tracker_.reset(new NiceMock<MockPeerConnectionTracker>());
212     blink::WebRTCConfiguration config;
213     blink::WebMediaConstraints constraints;
214     EXPECT_TRUE(pc_handler_->InitializeForTest(config, constraints,
215                                                mock_tracker_.get()));
216
217     mock_peer_connection_ = pc_handler_->native_peer_connection();
218     ASSERT_TRUE(mock_peer_connection_);
219   }
220
221   // Creates a WebKit local MediaStream.
222   blink::WebMediaStream CreateLocalMediaStream(
223       const std::string& stream_label) {
224     std::string video_track_label("video-label");
225     std::string audio_track_label("audio-label");
226
227     blink::WebMediaStreamSource audio_source;
228     audio_source.initialize(blink::WebString::fromUTF8(audio_track_label),
229                             blink::WebMediaStreamSource::TypeAudio,
230                             blink::WebString::fromUTF8("audio_track"));
231     audio_source.setExtraData(new MediaStreamAudioSource());
232     blink::WebMediaStreamSource video_source;
233     video_source.initialize(blink::WebString::fromUTF8(video_track_label),
234                             blink::WebMediaStreamSource::TypeVideo,
235                             blink::WebString::fromUTF8("video_track"));
236     MockMediaStreamVideoSource* native_video_source =
237         new MockMediaStreamVideoSource(false);
238     video_source.setExtraData(native_video_source);
239
240     blink::WebVector<blink::WebMediaStreamTrack> audio_tracks(
241         static_cast<size_t>(1));
242     audio_tracks[0].initialize(audio_source.id(), audio_source);
243     audio_tracks[0].setExtraData(
244         new MediaStreamTrack(
245             WebRtcLocalAudioTrackAdapter::Create(audio_track_label,
246                                                  NULL),
247                                                  true));
248     blink::WebVector<blink::WebMediaStreamTrack> video_tracks(
249         static_cast<size_t>(1));
250     blink::WebMediaConstraints constraints;
251     constraints.initialize();
252     video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack(
253         native_video_source, constraints,
254         MediaStreamVideoSource::ConstraintsCallback(), true);
255
256     blink::WebMediaStream local_stream;
257     local_stream.initialize(base::UTF8ToUTF16(stream_label), audio_tracks,
258                             video_tracks);
259     local_stream.setExtraData(
260         new MediaStream(local_stream));
261     return local_stream;
262   }
263
264   // Creates a remote MediaStream and adds it to the mocked native
265   // peer connection.
266   scoped_refptr<webrtc::MediaStreamInterface>
267   AddRemoteMockMediaStream(const std::string& stream_label,
268                            const std::string& video_track_label,
269                            const std::string& audio_track_label) {
270     scoped_refptr<webrtc::MediaStreamInterface> stream(
271         mock_dependency_factory_->CreateLocalMediaStream(stream_label));
272     if (!video_track_label.empty()) {
273       webrtc::VideoSourceInterface* source = NULL;
274       scoped_refptr<webrtc::VideoTrackInterface> video_track(
275           mock_dependency_factory_->CreateLocalVideoTrack(
276               video_track_label, source));
277       stream->AddTrack(video_track.get());
278     }
279     if (!audio_track_label.empty()) {
280       scoped_refptr<WebRtcAudioCapturer> capturer;
281       scoped_refptr<webrtc::AudioTrackInterface> audio_track(
282           WebRtcLocalAudioTrackAdapter::Create(audio_track_label, NULL));
283       stream->AddTrack(audio_track.get());
284     }
285     mock_peer_connection_->AddRemoteStream(stream.get());
286     return stream;
287   }
288
289   base::MessageLoop message_loop_;
290   scoped_ptr<ChildProcess> child_process_;
291   scoped_ptr<MockWebRTCPeerConnectionHandlerClient> mock_client_;
292   scoped_ptr<MockPeerConnectionDependencyFactory> mock_dependency_factory_;
293   scoped_ptr<NiceMock<MockPeerConnectionTracker> > mock_tracker_;
294   scoped_ptr<RTCPeerConnectionHandlerUnderTest> pc_handler_;
295
296   // Weak reference to the mocked native peer connection implementation.
297   MockPeerConnectionImpl* mock_peer_connection_;
298 };
299
300 TEST_F(RTCPeerConnectionHandlerTest, Destruct) {
301   EXPECT_CALL(*mock_tracker_.get(), UnregisterPeerConnection(pc_handler_.get()))
302       .Times(1);
303   pc_handler_.reset(NULL);
304 }
305
306 TEST_F(RTCPeerConnectionHandlerTest, CreateOffer) {
307   blink::WebRTCSessionDescriptionRequest request;
308   blink::WebMediaConstraints options;
309   EXPECT_CALL(*mock_tracker_.get(), TrackCreateOffer(pc_handler_.get(), _));
310
311   // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
312   // the |reqest| requestSucceeded can be tested? Currently the |request| object
313   // can not be initialized from a unit test.
314   EXPECT_FALSE(mock_peer_connection_->created_session_description() != NULL);
315   pc_handler_->createOffer(request, options);
316   EXPECT_TRUE(mock_peer_connection_->created_session_description() != NULL);
317 }
318
319 TEST_F(RTCPeerConnectionHandlerTest, CreateAnswer) {
320   blink::WebRTCSessionDescriptionRequest request;
321   blink::WebMediaConstraints options;
322   EXPECT_CALL(*mock_tracker_.get(), TrackCreateAnswer(pc_handler_.get(), _));
323   // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
324   // the |reqest| requestSucceeded can be tested? Currently the |request| object
325   // can not be initialized from a unit test.
326   EXPECT_FALSE(mock_peer_connection_->created_session_description() != NULL);
327   pc_handler_->createAnswer(request, options);
328   EXPECT_TRUE(mock_peer_connection_->created_session_description() != NULL);
329 }
330
331 TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) {
332   blink::WebRTCVoidRequest request;
333   blink::WebRTCSessionDescription description;
334   description.initialize(kDummySdpType, kDummySdp);
335   // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
336   // before |mock_peer_connection| is called.
337   testing::InSequence sequence;
338   EXPECT_CALL(*mock_tracker_.get(),
339               TrackSetSessionDescription(pc_handler_.get(), Ref(description),
340                                          PeerConnectionTracker::SOURCE_LOCAL));
341   EXPECT_CALL(*mock_peer_connection_, SetLocalDescription(_, _));
342
343   pc_handler_->setLocalDescription(request, description);
344   EXPECT_EQ(description.type(), pc_handler_->localDescription().type());
345   EXPECT_EQ(description.sdp(), pc_handler_->localDescription().sdp());
346
347   std::string sdp_string;
348   ASSERT_TRUE(mock_peer_connection_->local_description() != NULL);
349   EXPECT_EQ(kDummySdpType, mock_peer_connection_->local_description()->type());
350   mock_peer_connection_->local_description()->ToString(&sdp_string);
351   EXPECT_EQ(kDummySdp, sdp_string);
352 }
353
354 TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) {
355   blink::WebRTCVoidRequest request;
356   blink::WebRTCSessionDescription description;
357   description.initialize(kDummySdpType, kDummySdp);
358
359   // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
360   // before |mock_peer_connection| is called.
361   testing::InSequence sequence;
362   EXPECT_CALL(*mock_tracker_.get(),
363               TrackSetSessionDescription(pc_handler_.get(), Ref(description),
364                                          PeerConnectionTracker::SOURCE_REMOTE));
365   EXPECT_CALL(*mock_peer_connection_, SetRemoteDescription(_, _));
366
367   pc_handler_->setRemoteDescription(request, description);
368   EXPECT_EQ(description.type(), pc_handler_->remoteDescription().type());
369   EXPECT_EQ(description.sdp(), pc_handler_->remoteDescription().sdp());
370
371   std::string sdp_string;
372   ASSERT_TRUE(mock_peer_connection_->remote_description() != NULL);
373   EXPECT_EQ(kDummySdpType, mock_peer_connection_->remote_description()->type());
374   mock_peer_connection_->remote_description()->ToString(&sdp_string);
375   EXPECT_EQ(kDummySdp, sdp_string);
376 }
377
378 TEST_F(RTCPeerConnectionHandlerTest, updateICE) {
379   blink::WebRTCConfiguration config;
380   blink::WebMediaConstraints constraints;
381
382   EXPECT_CALL(*mock_tracker_.get(), TrackUpdateIce(pc_handler_.get(), _, _));
383   // TODO(perkj): Test that the parameters in |config| can be translated when a
384   // WebRTCConfiguration can be constructed. It's WebKit class and can't be
385   // initialized from a test.
386   EXPECT_TRUE(pc_handler_->updateICE(config, constraints));
387 }
388
389 TEST_F(RTCPeerConnectionHandlerTest, addICECandidate) {
390   blink::WebRTCICECandidate candidate;
391   candidate.initialize(kDummySdp, "mid", 1);
392
393   EXPECT_CALL(*mock_tracker_.get(),
394               TrackAddIceCandidate(pc_handler_.get(),
395                                    testing::Ref(candidate),
396                                    PeerConnectionTracker::SOURCE_REMOTE));
397   EXPECT_TRUE(pc_handler_->addICECandidate(candidate));
398   EXPECT_EQ(kDummySdp, mock_peer_connection_->ice_sdp());
399   EXPECT_EQ(1, mock_peer_connection_->sdp_mline_index());
400   EXPECT_EQ("mid", mock_peer_connection_->sdp_mid());
401 }
402
403 TEST_F(RTCPeerConnectionHandlerTest, addAndRemoveStream) {
404   std::string stream_label = "local_stream";
405   blink::WebMediaStream local_stream(
406       CreateLocalMediaStream(stream_label));
407   blink::WebMediaConstraints constraints;
408
409   EXPECT_CALL(*mock_tracker_.get(),
410               TrackAddStream(pc_handler_.get(),
411                              testing::Ref(local_stream),
412                              PeerConnectionTracker::SOURCE_LOCAL));
413   EXPECT_CALL(*mock_tracker_.get(),
414               TrackRemoveStream(pc_handler_.get(),
415                                 testing::Ref(local_stream),
416                                 PeerConnectionTracker::SOURCE_LOCAL));
417   EXPECT_TRUE(pc_handler_->addStream(local_stream, constraints));
418   EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
419   EXPECT_EQ(1u,
420       mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
421   EXPECT_EQ(1u,
422       mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());
423
424   EXPECT_FALSE(pc_handler_->addStream(local_stream, constraints));
425
426   pc_handler_->removeStream(local_stream);
427   EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count());
428 }
429
430 TEST_F(RTCPeerConnectionHandlerTest, addStreamWithStoppedAudioAndVideoTrack) {
431   std::string stream_label = "local_stream";
432   blink::WebMediaStream local_stream(
433       CreateLocalMediaStream(stream_label));
434   blink::WebMediaConstraints constraints;
435
436   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
437   local_stream.audioTracks(audio_tracks);
438   MediaStreamAudioSource* native_audio_source =
439       static_cast<MediaStreamAudioSource*>(
440           audio_tracks[0].source().extraData());
441   native_audio_source->StopSource();
442
443   blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
444   local_stream.videoTracks(video_tracks);
445   MediaStreamVideoSource* native_video_source =
446       static_cast<MediaStreamVideoSource*>(
447           video_tracks[0].source().extraData());
448   native_video_source->StopSource();
449
450   EXPECT_TRUE(pc_handler_->addStream(local_stream, constraints));
451   EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
452   EXPECT_EQ(
453       1u,
454       mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
455   EXPECT_EQ(
456       1u,
457       mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());
458 }
459
460 TEST_F(RTCPeerConnectionHandlerTest, GetStatsNoSelector) {
461   scoped_refptr<MockRTCStatsRequest> request(
462       new rtc::RefCountedObject<MockRTCStatsRequest>());
463   pc_handler_->getStats(request.get());
464   // Note that callback gets executed synchronously by mock.
465   ASSERT_TRUE(request->result());
466   EXPECT_LT(1, request->result()->report_count());
467 }
468
469 TEST_F(RTCPeerConnectionHandlerTest, GetStatsAfterClose) {
470   scoped_refptr<MockRTCStatsRequest> request(
471       new rtc::RefCountedObject<MockRTCStatsRequest>());
472   pc_handler_->stop();
473   pc_handler_->getStats(request.get());
474   // Note that callback gets executed synchronously by mock.
475   ASSERT_TRUE(request->result());
476   EXPECT_LT(1, request->result()->report_count());
477 }
478
479 TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
480   blink::WebMediaStream local_stream(
481       CreateLocalMediaStream("local_stream"));
482   blink::WebMediaConstraints constraints;
483   pc_handler_->addStream(local_stream, constraints);
484   blink::WebVector<blink::WebMediaStreamTrack> tracks;
485   local_stream.audioTracks(tracks);
486   ASSERT_LE(1ul, tracks.size());
487
488   scoped_refptr<MockRTCStatsRequest> request(
489       new rtc::RefCountedObject<MockRTCStatsRequest>());
490   request->setSelector(tracks[0]);
491   pc_handler_->getStats(request.get());
492   EXPECT_EQ(1, request->result()->report_count());
493 }
494
495 TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithRemoteSelector) {
496   scoped_refptr<webrtc::MediaStreamInterface> stream(
497       AddRemoteMockMediaStream("remote_stream", "video", "audio"));
498   pc_handler_->OnAddStream(stream.get());
499   const blink::WebMediaStream& remote_stream = mock_client_->remote_stream();
500
501   blink::WebVector<blink::WebMediaStreamTrack> tracks;
502   remote_stream.audioTracks(tracks);
503   ASSERT_LE(1ul, tracks.size());
504
505   scoped_refptr<MockRTCStatsRequest> request(
506       new rtc::RefCountedObject<MockRTCStatsRequest>());
507   request->setSelector(tracks[0]);
508   pc_handler_->getStats(request.get());
509   EXPECT_EQ(1, request->result()->report_count());
510 }
511
512 TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) {
513   // The setup is the same as GetStatsWithLocalSelector, but the stream is not
514   // added to the PeerConnection.
515   blink::WebMediaStream local_stream(
516       CreateLocalMediaStream("local_stream_2"));
517   blink::WebMediaConstraints constraints;
518   blink::WebVector<blink::WebMediaStreamTrack> tracks;
519
520   local_stream.audioTracks(tracks);
521   blink::WebMediaStreamTrack component = tracks[0];
522   mock_peer_connection_->SetGetStatsResult(false);
523
524   scoped_refptr<MockRTCStatsRequest> request(
525       new rtc::RefCountedObject<MockRTCStatsRequest>());
526   request->setSelector(component);
527   pc_handler_->getStats(request.get());
528   EXPECT_EQ(0, request->result()->report_count());
529 }
530
531 TEST_F(RTCPeerConnectionHandlerTest, OnSignalingChange) {
532   testing::InSequence sequence;
533
534   webrtc::PeerConnectionInterface::SignalingState new_state =
535       webrtc::PeerConnectionInterface::kHaveRemoteOffer;
536   EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
537       pc_handler_.get(),
538       WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer));
539   EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
540       WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer));
541   pc_handler_->OnSignalingChange(new_state);
542
543   new_state = webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
544   EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
545       pc_handler_.get(),
546       WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer));
547   EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
548       WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer));
549   pc_handler_->OnSignalingChange(new_state);
550
551   new_state = webrtc::PeerConnectionInterface::kHaveLocalOffer;
552   EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
553       pc_handler_.get(),
554       WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer));
555   EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
556       WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer));
557   pc_handler_->OnSignalingChange(new_state);
558
559   new_state = webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
560   EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
561       pc_handler_.get(),
562       WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer));
563   EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
564       WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer));
565   pc_handler_->OnSignalingChange(new_state);
566
567   new_state = webrtc::PeerConnectionInterface::kClosed;
568   EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
569       pc_handler_.get(),
570       WebRTCPeerConnectionHandlerClient::SignalingStateClosed));
571   EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
572       WebRTCPeerConnectionHandlerClient::SignalingStateClosed));
573   pc_handler_->OnSignalingChange(new_state);
574 }
575
576 TEST_F(RTCPeerConnectionHandlerTest, OnIceConnectionChange) {
577   testing::InSequence sequence;
578
579   webrtc::PeerConnectionInterface::IceConnectionState new_state =
580       webrtc::PeerConnectionInterface::kIceConnectionNew;
581   EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
582       pc_handler_.get(),
583       WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting));
584   EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
585       WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting));
586   pc_handler_->OnIceConnectionChange(new_state);
587
588   new_state = webrtc::PeerConnectionInterface::kIceConnectionChecking;
589   EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
590       pc_handler_.get(),
591       WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking));
592   EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
593       WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking));
594   pc_handler_->OnIceConnectionChange(new_state);
595
596   new_state = webrtc::PeerConnectionInterface::kIceConnectionConnected;
597   EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
598       pc_handler_.get(),
599       WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected));
600   EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
601       WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected));
602   pc_handler_->OnIceConnectionChange(new_state);
603
604   new_state = webrtc::PeerConnectionInterface::kIceConnectionCompleted;
605   EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
606       pc_handler_.get(),
607       WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted));
608   EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
609       WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted));
610   pc_handler_->OnIceConnectionChange(new_state);
611
612   new_state = webrtc::PeerConnectionInterface::kIceConnectionFailed;
613   EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
614       pc_handler_.get(),
615       WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed));
616   EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
617       WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed));
618   pc_handler_->OnIceConnectionChange(new_state);
619
620   new_state = webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
621   EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
622       pc_handler_.get(),
623       WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected));
624   EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
625       WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected));
626   pc_handler_->OnIceConnectionChange(new_state);
627
628   new_state = webrtc::PeerConnectionInterface::kIceConnectionClosed;
629   EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
630       pc_handler_.get(),
631       WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed));
632   EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
633       WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed));
634   pc_handler_->OnIceConnectionChange(new_state);
635 }
636
637 TEST_F(RTCPeerConnectionHandlerTest, OnIceGatheringChange) {
638   testing::InSequence sequence;
639   EXPECT_CALL(*mock_tracker_.get(), TrackIceGatheringStateChange(
640       pc_handler_.get(),
641       WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew));
642   EXPECT_CALL(*mock_client_.get(), didChangeICEGatheringState(
643       WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew));
644   EXPECT_CALL(*mock_tracker_.get(), TrackIceGatheringStateChange(
645       pc_handler_.get(),
646       WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering));
647   EXPECT_CALL(*mock_client_.get(), didChangeICEGatheringState(
648       WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering));
649   EXPECT_CALL(*mock_tracker_.get(), TrackIceGatheringStateChange(
650       pc_handler_.get(),
651       WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete));
652   EXPECT_CALL(*mock_client_.get(), didChangeICEGatheringState(
653       WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete));
654
655   webrtc::PeerConnectionInterface::IceGatheringState new_state =
656         webrtc::PeerConnectionInterface::kIceGatheringNew;
657   pc_handler_->OnIceGatheringChange(new_state);
658
659   new_state = webrtc::PeerConnectionInterface::kIceGatheringGathering;
660   pc_handler_->OnIceGatheringChange(new_state);
661
662   new_state = webrtc::PeerConnectionInterface::kIceGatheringComplete;
663   pc_handler_->OnIceGatheringChange(new_state);
664
665   // Check NULL candidate after ice gathering is completed.
666   EXPECT_EQ("", mock_client_->candidate_mid());
667   EXPECT_EQ(-1, mock_client_->candidate_mlineindex());
668   EXPECT_EQ("", mock_client_->candidate_sdp());
669 }
670
671 TEST_F(RTCPeerConnectionHandlerTest, OnAddAndOnRemoveStream) {
672   std::string remote_stream_label("remote_stream");
673   scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
674       AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
675
676   testing::InSequence sequence;
677   EXPECT_CALL(*mock_tracker_.get(), TrackAddStream(
678       pc_handler_.get(),
679       testing::Property(&blink::WebMediaStream::id,
680                         base::UTF8ToUTF16(remote_stream_label)),
681       PeerConnectionTracker::SOURCE_REMOTE));
682   EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
683       testing::Property(&blink::WebMediaStream::id,
684                         base::UTF8ToUTF16(remote_stream_label))));
685
686   EXPECT_CALL(*mock_tracker_.get(), TrackRemoveStream(
687       pc_handler_.get(),
688       testing::Property(&blink::WebMediaStream::id,
689                         base::UTF8ToUTF16(remote_stream_label)),
690       PeerConnectionTracker::SOURCE_REMOTE));
691   EXPECT_CALL(*mock_client_.get(), didRemoveRemoteStream(
692       testing::Property(&blink::WebMediaStream::id,
693                         base::UTF8ToUTF16(remote_stream_label))));
694
695   pc_handler_->OnAddStream(remote_stream.get());
696   pc_handler_->OnRemoveStream(remote_stream.get());
697 }
698
699 // This test that WebKit is notified about remote track state changes.
700 TEST_F(RTCPeerConnectionHandlerTest, RemoteTrackState) {
701   std::string remote_stream_label("remote_stream");
702   scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
703       AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
704
705   testing::InSequence sequence;
706   EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
707       testing::Property(&blink::WebMediaStream::id,
708                         base::UTF8ToUTF16(remote_stream_label))));
709   pc_handler_->OnAddStream(remote_stream.get());
710   const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();
711
712   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
713   webkit_stream.audioTracks(audio_tracks);
714   EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
715             audio_tracks[0].source().readyState());
716
717   blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
718     webkit_stream.videoTracks(video_tracks);
719   EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
720             video_tracks[0].source().readyState());
721
722   remote_stream->GetAudioTracks()[0]->set_state(
723       webrtc::MediaStreamTrackInterface::kEnded);
724   EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
725             audio_tracks[0].source().readyState());
726
727   remote_stream->GetVideoTracks()[0]->set_state(
728       webrtc::MediaStreamTrackInterface::kEnded);
729   EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
730             video_tracks[0].source().readyState());
731 }
732
733 TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddAudioTrackFromRemoteStream) {
734   std::string remote_stream_label("remote_stream");
735   scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
736       AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
737
738   EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
739       testing::Property(&blink::WebMediaStream::id,
740                         base::UTF8ToUTF16(remote_stream_label))));
741   pc_handler_->OnAddStream(remote_stream.get());
742   const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();
743
744   {
745     // Test in a small scope so that  |audio_tracks| don't hold on to destroyed
746     // source later.
747     blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
748     webkit_stream.audioTracks(audio_tracks);
749     EXPECT_EQ(1u, audio_tracks.size());
750   }
751
752   // Remove the Webrtc audio track from the Webrtc MediaStream.
753   scoped_refptr<webrtc::AudioTrackInterface> webrtc_track =
754       remote_stream->GetAudioTracks()[0].get();
755   remote_stream->RemoveTrack(webrtc_track.get());
756
757   {
758     blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks1;
759     webkit_stream.audioTracks(modified_audio_tracks1);
760     EXPECT_EQ(0u, modified_audio_tracks1.size());
761   }
762
763   // Add the WebRtc audio track again.
764   remote_stream->AddTrack(webrtc_track.get());
765   blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks2;
766   webkit_stream.audioTracks(modified_audio_tracks2);
767   EXPECT_EQ(1u, modified_audio_tracks2.size());
768 }
769
770 TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddVideoTrackFromRemoteStream) {
771   std::string remote_stream_label("remote_stream");
772   scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
773       AddRemoteMockMediaStream(remote_stream_label, "video", "video"));
774
775   EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
776       testing::Property(&blink::WebMediaStream::id,
777                         base::UTF8ToUTF16(remote_stream_label))));
778   pc_handler_->OnAddStream(remote_stream.get());
779   const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();
780
781   {
782     // Test in a small scope so that  |video_tracks| don't hold on to destroyed
783     // source later.
784     blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
785     webkit_stream.videoTracks(video_tracks);
786     EXPECT_EQ(1u, video_tracks.size());
787   }
788
789   // Remove the Webrtc video track from the Webrtc MediaStream.
790   scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
791       remote_stream->GetVideoTracks()[0].get();
792   remote_stream->RemoveTrack(webrtc_track.get());
793   {
794     blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks1;
795     webkit_stream.videoTracks(modified_video_tracks1);
796     EXPECT_EQ(0u, modified_video_tracks1.size());
797   }
798
799   // Add the WebRtc video track again.
800   remote_stream->AddTrack(webrtc_track.get());
801   blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks2;
802   webkit_stream.videoTracks(modified_video_tracks2);
803   EXPECT_EQ(1u, modified_video_tracks2.size());
804 }
805
806 TEST_F(RTCPeerConnectionHandlerTest, OnIceCandidate) {
807   testing::InSequence sequence;
808   EXPECT_CALL(*mock_tracker_.get(),
809               TrackAddIceCandidate(pc_handler_.get(), _,
810                                    PeerConnectionTracker::SOURCE_LOCAL));
811   EXPECT_CALL(*mock_client_.get(), didGenerateICECandidate(_));
812
813   scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
814       mock_dependency_factory_->CreateIceCandidate("mid", 1, kDummySdp));
815   pc_handler_->OnIceCandidate(native_candidate.get());
816   EXPECT_EQ("mid", mock_client_->candidate_mid());
817   EXPECT_EQ(1, mock_client_->candidate_mlineindex());
818   EXPECT_EQ(kDummySdp, mock_client_->candidate_sdp());
819 }
820
821 TEST_F(RTCPeerConnectionHandlerTest, OnRenegotiationNeeded) {
822   testing::InSequence sequence;
823   EXPECT_CALL(*mock_tracker_.get(),
824               TrackOnRenegotiationNeeded(pc_handler_.get()));
825   EXPECT_CALL(*mock_client_.get(), negotiationNeeded());
826   pc_handler_->OnRenegotiationNeeded();
827 }
828
829 TEST_F(RTCPeerConnectionHandlerTest, CreateDataChannel) {
830   blink::WebString label = "d1";
831   EXPECT_CALL(*mock_tracker_.get(),
832               TrackCreateDataChannel(pc_handler_.get(),
833                                      testing::NotNull(),
834                                      PeerConnectionTracker::SOURCE_LOCAL));
835   scoped_ptr<blink::WebRTCDataChannelHandler> channel(
836       pc_handler_->createDataChannel("d1", blink::WebRTCDataChannelInit()));
837   EXPECT_TRUE(channel.get() != NULL);
838   EXPECT_EQ(label, channel->label());
839 }
840
841 TEST_F(RTCPeerConnectionHandlerTest, CreateDtmfSender) {
842   std::string stream_label = "local_stream";
843   blink::WebMediaStream local_stream(CreateLocalMediaStream(stream_label));
844   blink::WebMediaConstraints constraints;
845   pc_handler_->addStream(local_stream, constraints);
846
847   blink::WebVector<blink::WebMediaStreamTrack> tracks;
848   local_stream.videoTracks(tracks);
849
850   ASSERT_LE(1ul, tracks.size());
851   EXPECT_FALSE(pc_handler_->createDTMFSender(tracks[0]));
852
853   local_stream.audioTracks(tracks);
854   ASSERT_LE(1ul, tracks.size());
855
856   EXPECT_CALL(*mock_tracker_.get(),
857               TrackCreateDTMFSender(pc_handler_.get(),
858                                     testing::Ref(tracks[0])));
859
860   scoped_ptr<blink::WebRTCDTMFSenderHandler> sender(
861       pc_handler_->createDTMFSender(tracks[0]));
862   EXPECT_TRUE(sender.get());
863 }
864
865 }  // namespace content