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
38 static const char kDummySdp[] = "dummy sdp";
39 static const char kDummySdpType[] = "dummy type";
40
41 using blink::WebRTCPeerConnectionHandlerClient;
42 using testing::NiceMock;
43 using testing::_;
44 using testing::Ref;
45
46 namespace content {
47
48 class MockRTCStatsResponse : public LocalRTCStatsResponse {
49 public:
MockRTCStatsResponse()50 MockRTCStatsResponse()
51 : report_count_(0),
52 statistic_count_(0) {
53 }
54
addReport(blink::WebString type,blink::WebString id,double timestamp)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
addStatistic(size_t report,blink::WebString name,blink::WebString value)62 virtual void addStatistic(size_t report,
63 blink::WebString name, blink::WebString value)
64 OVERRIDE {
65 ++statistic_count_;
66 }
report_count() const67 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
75 class MockRTCStatsRequest : public LocalRTCStatsRequest {
76 public:
MockRTCStatsRequest()77 MockRTCStatsRequest()
78 : has_selector_(false),
79 request_succeeded_called_(false) {}
80
hasSelector() const81 virtual bool hasSelector() const OVERRIDE {
82 return has_selector_;
83 }
component() const84 virtual blink::WebMediaStreamTrack component() const OVERRIDE {
85 return component_;
86 }
createResponse()87 virtual scoped_refptr<LocalRTCStatsResponse> createResponse() OVERRIDE {
88 DCHECK(!response_.get());
89 response_ = new talk_base::RefCountedObject<MockRTCStatsResponse>();
90 return response_;
91 }
92
requestSucceeded(const LocalRTCStatsResponse * response)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.
setSelector(const blink::WebMediaStreamTrack & component)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.
result()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
121 class 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
179 class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler {
180 public:
RTCPeerConnectionHandlerUnderTest(WebRTCPeerConnectionHandlerClient * client,MediaStreamDependencyFactory * dependency_factory)181 RTCPeerConnectionHandlerUnderTest(
182 WebRTCPeerConnectionHandlerClient* client,
183 MediaStreamDependencyFactory* dependency_factory)
184 : RTCPeerConnectionHandler(client, dependency_factory) {
185 }
186
native_peer_connection()187 MockPeerConnectionImpl* native_peer_connection() {
188 return static_cast<MockPeerConnectionImpl*>(native_peer_connection_.get());
189 }
190 };
191
192 class RTCPeerConnectionHandlerTest : public ::testing::Test {
193 public:
RTCPeerConnectionHandlerTest()194 RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL) {
195 }
196
SetUp()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.
CreateLocalMediaStream(const std::string & stream_label)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>
AddRemoteMockMediaStream(const std::string & stream_label,const std::string & video_track_label,const std::string & audio_track_label)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
TEST_F(RTCPeerConnectionHandlerTest,Destruct)308 TEST_F(RTCPeerConnectionHandlerTest, Destruct) {
309 EXPECT_CALL(*mock_tracker_.get(), UnregisterPeerConnection(pc_handler_.get()))
310 .Times(1);
311 pc_handler_.reset(NULL);
312 }
313
TEST_F(RTCPeerConnectionHandlerTest,CreateOffer)314 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,CreateAnswer)327 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,setLocalDescription)339 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,setRemoteDescription)362 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,updateICE)386 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,addICECandidate)397 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,addAndRemoveStream)411 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,GetStatsNoSelector)436 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,GetStatsAfterClose)445 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,GetStatsWithLocalSelector)455 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,GetStatsWithRemoteSelector)471 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,GetStatsWithBadSelector)488 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,OnSignalingChange)507 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,OnIceConnectionChange)552 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,OnIceGatheringChange)613 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,OnAddAndOnRemoveStream)647 TEST_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.
TEST_F(RTCPeerConnectionHandlerTest,RemoteTrackState)676 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,RemoveAndAddAudioTrackFromRemoteStream)709 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,RemoveAndAddVideoTrackFromRemoteStream)739 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,OnIceCandidate)769 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,OnRenegotiationNeeded)784 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,CreateDataChannel)792 TEST_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
TEST_F(RTCPeerConnectionHandlerTest,CreateDtmfSender)804 TEST_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