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