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