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