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.
8 #include "base/location.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/values.h"
15 #include "content/child/child_process.h"
16 #include "content/renderer/media/media_stream.h"
17 #include "content/renderer/media/media_stream_audio_source.h"
18 #include "content/renderer/media/media_stream_source.h"
19 #include "content/renderer/media/media_stream_video_track.h"
20 #include "content/renderer/media/mock_media_constraint_factory.h"
21 #include "content/renderer/media/mock_media_stream_video_source.h"
22 #include "content/renderer/media/mock_peer_connection_impl.h"
23 #include "content/renderer/media/mock_web_rtc_peer_connection_handler_client.h"
24 #include "content/renderer/media/peer_connection_tracker.h"
25 #include "content/renderer/media/rtc_media_constraints.h"
26 #include "content/renderer/media/rtc_peer_connection_handler.h"
27 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
28 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
29 #include "content/renderer/media/webrtc_local_audio_track.h"
30 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
33 #include "third_party/WebKit/public/platform/WebMediaStream.h"
34 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
35 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
36 #include "third_party/WebKit/public/platform/WebRTCConfiguration.h"
37 #include "third_party/WebKit/public/platform/WebRTCDTMFSenderHandler.h"
38 #include "third_party/WebKit/public/platform/WebRTCDataChannelHandler.h"
39 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
40 #include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
41 #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h"
42 #include "third_party/WebKit/public/platform/WebRTCSessionDescription.h"
43 #include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h"
44 #include "third_party/WebKit/public/platform/WebRTCStatsRequest.h"
45 #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h"
46 #include "third_party/WebKit/public/platform/WebURL.h"
47 #include "third_party/WebKit/public/web/WebHeap.h"
48 #include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h"
50 static const char kDummySdp
[] = "dummy sdp";
51 static const char kDummySdpType
[] = "dummy type";
53 using blink::WebRTCPeerConnectionHandlerClient
;
54 using testing::NiceMock
;
57 using testing::SaveArg
;
61 ACTION_P2(ExitMessageLoop
, message_loop
, quit_closure
) {
62 message_loop
->task_runner()->PostTask(FROM_HERE
, quit_closure
);
65 class MockRTCStatsResponse
: public LocalRTCStatsResponse
{
67 MockRTCStatsResponse()
72 size_t addReport(blink::WebString type
,
74 double timestamp
) override
{
79 void addStatistic(size_t report
,
80 blink::WebString name
,
81 blink::WebString value
) override
{
84 int report_count() const { return report_count_
; }
91 // Mocked wrapper for blink::WebRTCStatsRequest
92 class MockRTCStatsRequest
: public LocalRTCStatsRequest
{
95 : has_selector_(false),
96 request_succeeded_called_(false) {}
98 bool hasSelector() const override
{ return has_selector_
; }
99 blink::WebMediaStreamTrack
component() const override
{ return component_
; }
100 scoped_refptr
<LocalRTCStatsResponse
> createResponse() override
{
101 DCHECK(!response_
.get());
102 response_
= new rtc::RefCountedObject
<MockRTCStatsResponse
>();
106 void requestSucceeded(const LocalRTCStatsResponse
* response
) override
{
107 EXPECT_EQ(response
, response_
.get());
108 request_succeeded_called_
= true;
111 // Function for setting whether or not a selector is available.
112 void setSelector(const blink::WebMediaStreamTrack
& component
) {
113 has_selector_
= true;
114 component_
= component
;
117 // Function for inspecting the result of a stats request.
118 MockRTCStatsResponse
* result() {
119 if (request_succeeded_called_
) {
120 return response_
.get();
128 blink::WebMediaStreamTrack component_
;
129 scoped_refptr
<MockRTCStatsResponse
> response_
;
130 bool request_succeeded_called_
;
133 class MockPeerConnectionTracker
: public PeerConnectionTracker
{
135 MOCK_METHOD1(UnregisterPeerConnection
,
136 void(RTCPeerConnectionHandler
* pc_handler
));
137 // TODO(jiayl): add coverage for the following methods
138 MOCK_METHOD2(TrackCreateOffer
,
139 void(RTCPeerConnectionHandler
* pc_handler
,
140 const RTCMediaConstraints
& constraints
));
141 MOCK_METHOD2(TrackCreateAnswer
,
142 void(RTCPeerConnectionHandler
* pc_handler
,
143 const RTCMediaConstraints
& constraints
));
144 MOCK_METHOD4(TrackSetSessionDescription
,
145 void(RTCPeerConnectionHandler
* pc_handler
,
146 const std::string
& sdp
, const std::string
& type
,
150 void(RTCPeerConnectionHandler
* pc_handler
,
151 const webrtc::PeerConnectionInterface::RTCConfiguration
& config
,
152 const RTCMediaConstraints
& options
));
153 MOCK_METHOD4(TrackAddIceCandidate
,
154 void(RTCPeerConnectionHandler
* pc_handler
,
155 const blink::WebRTCICECandidate
& candidate
,
158 MOCK_METHOD3(TrackAddStream
,
159 void(RTCPeerConnectionHandler
* pc_handler
,
160 const blink::WebMediaStream
& stream
,
162 MOCK_METHOD3(TrackRemoveStream
,
163 void(RTCPeerConnectionHandler
* pc_handler
,
164 const blink::WebMediaStream
& stream
,
166 MOCK_METHOD1(TrackOnIceComplete
,
167 void(RTCPeerConnectionHandler
* pc_handler
));
168 MOCK_METHOD3(TrackCreateDataChannel
,
169 void(RTCPeerConnectionHandler
* pc_handler
,
170 const webrtc::DataChannelInterface
* data_channel
,
172 MOCK_METHOD1(TrackStop
, void(RTCPeerConnectionHandler
* pc_handler
));
173 MOCK_METHOD2(TrackSignalingStateChange
,
174 void(RTCPeerConnectionHandler
* pc_handler
,
175 WebRTCPeerConnectionHandlerClient::SignalingState state
));
177 TrackIceConnectionStateChange
,
178 void(RTCPeerConnectionHandler
* pc_handler
,
179 WebRTCPeerConnectionHandlerClient::ICEConnectionState state
));
181 TrackIceGatheringStateChange
,
182 void(RTCPeerConnectionHandler
* pc_handler
,
183 WebRTCPeerConnectionHandlerClient::ICEGatheringState state
));
184 MOCK_METHOD1(TrackOnRenegotiationNeeded
,
185 void(RTCPeerConnectionHandler
* pc_handler
));
186 MOCK_METHOD2(TrackCreateDTMFSender
,
187 void(RTCPeerConnectionHandler
* pc_handler
,
188 const blink::WebMediaStreamTrack
& track
));
191 class RTCPeerConnectionHandlerUnderTest
: public RTCPeerConnectionHandler
{
193 RTCPeerConnectionHandlerUnderTest(
194 WebRTCPeerConnectionHandlerClient
* client
,
195 PeerConnectionDependencyFactory
* dependency_factory
)
196 : RTCPeerConnectionHandler(client
, dependency_factory
) {
199 MockPeerConnectionImpl
* native_peer_connection() {
200 return static_cast<MockPeerConnectionImpl
*>(
201 RTCPeerConnectionHandler::native_peer_connection());
204 webrtc::PeerConnectionObserver
* observer() {
205 return native_peer_connection()->observer();
208 scoped_refptr
<base::SingleThreadTaskRunner
>
209 signaling_thread() const override
{
210 return base::ThreadTaskRunnerHandle::Get();
214 class RTCPeerConnectionHandlerTest
: public ::testing::Test
{
216 RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL
) {
217 child_process_
.reset(new ChildProcess());
220 void SetUp() override
{
221 mock_client_
.reset(new NiceMock
<MockWebRTCPeerConnectionHandlerClient
>());
222 mock_dependency_factory_
.reset(new MockPeerConnectionDependencyFactory());
224 new RTCPeerConnectionHandlerUnderTest(
225 mock_client_
.get(), mock_dependency_factory_
.get()));
226 mock_tracker_
.reset(new NiceMock
<MockPeerConnectionTracker
>());
227 blink::WebRTCConfiguration config
;
228 blink::WebMediaConstraints constraints
;
229 EXPECT_TRUE(pc_handler_
->InitializeForTest(
230 config
, constraints
, mock_tracker_
.get()->AsWeakPtr()));
232 mock_peer_connection_
= pc_handler_
->native_peer_connection();
233 ASSERT_TRUE(mock_peer_connection_
);
236 void TearDown() override
{
238 mock_tracker_
.reset();
239 mock_dependency_factory_
.reset();
240 mock_client_
.reset();
241 blink::WebHeap::collectAllGarbageForTesting();
244 // Creates a WebKit local MediaStream.
245 blink::WebMediaStream
CreateLocalMediaStream(
246 const std::string
& stream_label
) {
247 std::string
video_track_label("video-label");
248 std::string
audio_track_label("audio-label");
249 blink::WebMediaStreamSource audio_source
;
250 audio_source
.initialize(blink::WebString::fromUTF8(audio_track_label
),
251 blink::WebMediaStreamSource::TypeAudio
,
252 blink::WebString::fromUTF8("audio_track"),
253 false /* remote */, true /* readonly */);
254 audio_source
.setExtraData(new MediaStreamAudioSource());
255 blink::WebMediaStreamSource video_source
;
256 video_source
.initialize(blink::WebString::fromUTF8(video_track_label
),
257 blink::WebMediaStreamSource::TypeVideo
,
258 blink::WebString::fromUTF8("video_track"),
259 false /* remote */, true /* readonly */);
260 MockMediaStreamVideoSource
* native_video_source
=
261 new MockMediaStreamVideoSource(false);
262 video_source
.setExtraData(native_video_source
);
264 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks(
265 static_cast<size_t>(1));
266 audio_tracks
[0].initialize(audio_source
.id(), audio_source
);
267 StreamDeviceInfo
device_info(MEDIA_DEVICE_AUDIO_CAPTURE
, "Mock device",
269 MockMediaConstraintFactory constraint_factory
;
270 const blink::WebMediaConstraints constraints
=
271 constraint_factory
.CreateWebMediaConstraints();
272 scoped_refptr
<WebRtcAudioCapturer
> capturer(
273 WebRtcAudioCapturer::CreateCapturer(-1, device_info
, constraints
,
275 scoped_refptr
<WebRtcLocalAudioTrackAdapter
> adapter(
276 WebRtcLocalAudioTrackAdapter::Create(audio_track_label
, nullptr));
277 scoped_ptr
<WebRtcLocalAudioTrack
> native_track(
278 new WebRtcLocalAudioTrack(adapter
.get(), capturer
, nullptr));
279 audio_tracks
[0].setExtraData(native_track
.release());
280 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks(
281 static_cast<size_t>(1));
282 blink::WebMediaConstraints video_constraints
;
283 video_constraints
.initialize();
284 video_tracks
[0] = MediaStreamVideoTrack::CreateVideoTrack(
285 native_video_source
, video_constraints
,
286 MediaStreamVideoSource::ConstraintsCallback(), true);
288 blink::WebMediaStream local_stream
;
289 local_stream
.initialize(base::UTF8ToUTF16(stream_label
), audio_tracks
,
291 local_stream
.setExtraData(
292 new MediaStream(local_stream
));
296 // Creates a remote MediaStream and adds it to the mocked native
298 scoped_refptr
<webrtc::MediaStreamInterface
>
299 AddRemoteMockMediaStream(const std::string
& stream_label
,
300 const std::string
& video_track_label
,
301 const std::string
& audio_track_label
) {
302 scoped_refptr
<webrtc::MediaStreamInterface
> stream(
303 mock_dependency_factory_
->CreateLocalMediaStream(stream_label
));
304 if (!video_track_label
.empty()) {
305 webrtc::VideoSourceInterface
* source
= NULL
;
306 scoped_refptr
<webrtc::VideoTrackInterface
> video_track(
307 mock_dependency_factory_
->CreateLocalVideoTrack(
308 video_track_label
, source
));
309 stream
->AddTrack(video_track
.get());
311 if (!audio_track_label
.empty()) {
312 scoped_refptr
<webrtc::AudioTrackInterface
> audio_track(
313 WebRtcLocalAudioTrackAdapter::Create(audio_track_label
, NULL
));
314 stream
->AddTrack(audio_track
.get());
316 mock_peer_connection_
->AddRemoteStream(stream
.get());
320 base::MessageLoop message_loop_
;
321 scoped_ptr
<ChildProcess
> child_process_
;
322 scoped_ptr
<MockWebRTCPeerConnectionHandlerClient
> mock_client_
;
323 scoped_ptr
<MockPeerConnectionDependencyFactory
> mock_dependency_factory_
;
324 scoped_ptr
<NiceMock
<MockPeerConnectionTracker
> > mock_tracker_
;
325 scoped_ptr
<RTCPeerConnectionHandlerUnderTest
> pc_handler_
;
327 // Weak reference to the mocked native peer connection implementation.
328 MockPeerConnectionImpl
* mock_peer_connection_
;
331 TEST_F(RTCPeerConnectionHandlerTest
, Destruct
) {
332 EXPECT_CALL(*mock_tracker_
.get(), UnregisterPeerConnection(pc_handler_
.get()))
334 pc_handler_
.reset(NULL
);
337 TEST_F(RTCPeerConnectionHandlerTest
, CreateOffer
) {
338 blink::WebRTCSessionDescriptionRequest request
;
339 blink::WebMediaConstraints options
;
340 EXPECT_CALL(*mock_tracker_
.get(), TrackCreateOffer(pc_handler_
.get(), _
));
342 // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
343 // the |reqest| requestSucceeded can be tested? Currently the |request| object
344 // can not be initialized from a unit test.
345 EXPECT_FALSE(mock_peer_connection_
->created_session_description() != NULL
);
346 pc_handler_
->createOffer(request
, options
);
347 EXPECT_TRUE(mock_peer_connection_
->created_session_description() != NULL
);
350 TEST_F(RTCPeerConnectionHandlerTest
, CreateAnswer
) {
351 blink::WebRTCSessionDescriptionRequest request
;
352 blink::WebMediaConstraints options
;
353 EXPECT_CALL(*mock_tracker_
.get(), TrackCreateAnswer(pc_handler_
.get(), _
));
354 // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
355 // the |reqest| requestSucceeded can be tested? Currently the |request| object
356 // can not be initialized from a unit test.
357 EXPECT_FALSE(mock_peer_connection_
->created_session_description() != NULL
);
358 pc_handler_
->createAnswer(request
, options
);
359 EXPECT_TRUE(mock_peer_connection_
->created_session_description() != NULL
);
362 TEST_F(RTCPeerConnectionHandlerTest
, setLocalDescription
) {
363 blink::WebRTCVoidRequest request
;
364 blink::WebRTCSessionDescription description
;
365 description
.initialize(kDummySdpType
, kDummySdp
);
366 // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
367 // before |mock_peer_connection| is called.
368 testing::InSequence sequence
;
369 EXPECT_CALL(*mock_tracker_
.get(),
370 TrackSetSessionDescription(pc_handler_
.get(), kDummySdp
,
372 PeerConnectionTracker::SOURCE_LOCAL
));
373 EXPECT_CALL(*mock_peer_connection_
, SetLocalDescription(_
, _
));
375 pc_handler_
->setLocalDescription(request
, description
);
376 base::RunLoop().RunUntilIdle();
377 EXPECT_EQ(description
.type(), pc_handler_
->localDescription().type());
378 EXPECT_EQ(description
.sdp(), pc_handler_
->localDescription().sdp());
380 std::string sdp_string
;
381 ASSERT_TRUE(mock_peer_connection_
->local_description() != NULL
);
382 EXPECT_EQ(kDummySdpType
, mock_peer_connection_
->local_description()->type());
383 mock_peer_connection_
->local_description()->ToString(&sdp_string
);
384 EXPECT_EQ(kDummySdp
, sdp_string
);
387 TEST_F(RTCPeerConnectionHandlerTest
, setRemoteDescription
) {
388 blink::WebRTCVoidRequest request
;
389 blink::WebRTCSessionDescription description
;
390 description
.initialize(kDummySdpType
, kDummySdp
);
392 // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
393 // before |mock_peer_connection| is called.
394 testing::InSequence sequence
;
395 EXPECT_CALL(*mock_tracker_
.get(),
396 TrackSetSessionDescription(pc_handler_
.get(), kDummySdp
,
398 PeerConnectionTracker::SOURCE_REMOTE
));
399 EXPECT_CALL(*mock_peer_connection_
, SetRemoteDescription(_
, _
));
401 pc_handler_
->setRemoteDescription(request
, description
);
402 base::RunLoop().RunUntilIdle();
403 EXPECT_EQ(description
.type(), pc_handler_
->remoteDescription().type());
404 EXPECT_EQ(description
.sdp(), pc_handler_
->remoteDescription().sdp());
406 std::string sdp_string
;
407 ASSERT_TRUE(mock_peer_connection_
->remote_description() != NULL
);
408 EXPECT_EQ(kDummySdpType
, mock_peer_connection_
->remote_description()->type());
409 mock_peer_connection_
->remote_description()->ToString(&sdp_string
);
410 EXPECT_EQ(kDummySdp
, sdp_string
);
413 TEST_F(RTCPeerConnectionHandlerTest
, updateICE
) {
414 blink::WebRTCConfiguration config
;
415 blink::WebMediaConstraints constraints
;
417 EXPECT_CALL(*mock_tracker_
.get(), TrackUpdateIce(pc_handler_
.get(), _
, _
));
418 // TODO(perkj): Test that the parameters in |config| can be translated when a
419 // WebRTCConfiguration can be constructed. It's WebKit class and can't be
420 // initialized from a test.
421 EXPECT_TRUE(pc_handler_
->updateICE(config
, constraints
));
424 TEST_F(RTCPeerConnectionHandlerTest
, addICECandidate
) {
425 blink::WebRTCICECandidate candidate
;
426 candidate
.initialize(kDummySdp
, "sdpMid", 1);
428 EXPECT_CALL(*mock_tracker_
.get(),
429 TrackAddIceCandidate(pc_handler_
.get(),
430 testing::Ref(candidate
),
431 PeerConnectionTracker::SOURCE_REMOTE
,
433 EXPECT_TRUE(pc_handler_
->addICECandidate(candidate
));
434 EXPECT_EQ(kDummySdp
, mock_peer_connection_
->ice_sdp());
435 EXPECT_EQ(1, mock_peer_connection_
->sdp_mline_index());
436 EXPECT_EQ("sdpMid", mock_peer_connection_
->sdp_mid());
439 TEST_F(RTCPeerConnectionHandlerTest
, addAndRemoveStream
) {
440 std::string stream_label
= "local_stream";
441 blink::WebMediaStream
local_stream(
442 CreateLocalMediaStream(stream_label
));
443 blink::WebMediaConstraints constraints
;
445 EXPECT_CALL(*mock_tracker_
.get(),
446 TrackAddStream(pc_handler_
.get(),
447 testing::Ref(local_stream
),
448 PeerConnectionTracker::SOURCE_LOCAL
));
449 EXPECT_CALL(*mock_tracker_
.get(),
450 TrackRemoveStream(pc_handler_
.get(),
451 testing::Ref(local_stream
),
452 PeerConnectionTracker::SOURCE_LOCAL
));
453 EXPECT_TRUE(pc_handler_
->addStream(local_stream
, constraints
));
454 EXPECT_EQ(stream_label
, mock_peer_connection_
->stream_label());
456 mock_peer_connection_
->local_streams()->at(0)->GetAudioTracks().size());
458 mock_peer_connection_
->local_streams()->at(0)->GetVideoTracks().size());
460 EXPECT_FALSE(pc_handler_
->addStream(local_stream
, constraints
));
462 pc_handler_
->removeStream(local_stream
);
463 EXPECT_EQ(0u, mock_peer_connection_
->local_streams()->count());
466 TEST_F(RTCPeerConnectionHandlerTest
, addStreamWithStoppedAudioAndVideoTrack
) {
467 std::string stream_label
= "local_stream";
468 blink::WebMediaStream
local_stream(
469 CreateLocalMediaStream(stream_label
));
470 blink::WebMediaConstraints constraints
;
472 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
473 local_stream
.audioTracks(audio_tracks
);
474 MediaStreamAudioSource
* native_audio_source
=
475 static_cast<MediaStreamAudioSource
*>(
476 audio_tracks
[0].source().extraData());
477 native_audio_source
->StopSource();
479 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
480 local_stream
.videoTracks(video_tracks
);
481 MediaStreamVideoSource
* native_video_source
=
482 static_cast<MediaStreamVideoSource
*>(
483 video_tracks
[0].source().extraData());
484 native_video_source
->StopSource();
486 EXPECT_TRUE(pc_handler_
->addStream(local_stream
, constraints
));
487 EXPECT_EQ(stream_label
, mock_peer_connection_
->stream_label());
490 mock_peer_connection_
->local_streams()->at(0)->GetAudioTracks().size());
493 mock_peer_connection_
->local_streams()->at(0)->GetVideoTracks().size());
496 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsNoSelector
) {
497 scoped_refptr
<MockRTCStatsRequest
> request(
498 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
499 pc_handler_
->getStats(request
.get());
500 base::RunLoop().RunUntilIdle();
501 ASSERT_TRUE(request
->result());
502 EXPECT_LT(1, request
->result()->report_count());
505 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsAfterClose
) {
506 scoped_refptr
<MockRTCStatsRequest
> request(
507 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
509 base::RunLoop().RunUntilIdle();
510 pc_handler_
->getStats(request
.get());
511 base::RunLoop().RunUntilIdle();
512 ASSERT_TRUE(request
->result());
513 EXPECT_LT(1, request
->result()->report_count());
516 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsWithLocalSelector
) {
517 blink::WebMediaStream
local_stream(
518 CreateLocalMediaStream("local_stream"));
519 blink::WebMediaConstraints constraints
;
520 pc_handler_
->addStream(local_stream
, constraints
);
521 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
522 local_stream
.audioTracks(tracks
);
523 ASSERT_LE(1ul, tracks
.size());
525 scoped_refptr
<MockRTCStatsRequest
> request(
526 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
527 request
->setSelector(tracks
[0]);
528 pc_handler_
->getStats(request
.get());
529 base::RunLoop().RunUntilIdle();
530 EXPECT_EQ(1, request
->result()->report_count());
533 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsWithRemoteSelector
) {
534 scoped_refptr
<webrtc::MediaStreamInterface
> stream(
535 AddRemoteMockMediaStream("remote_stream", "video", "audio"));
536 pc_handler_
->observer()->OnAddStream(stream
.get());
537 base::RunLoop().RunUntilIdle();
538 const blink::WebMediaStream
& remote_stream
= mock_client_
->remote_stream();
540 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
541 remote_stream
.audioTracks(tracks
);
542 ASSERT_LE(1ul, tracks
.size());
544 scoped_refptr
<MockRTCStatsRequest
> request(
545 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
546 request
->setSelector(tracks
[0]);
547 pc_handler_
->getStats(request
.get());
548 base::RunLoop().RunUntilIdle();
549 EXPECT_EQ(1, request
->result()->report_count());
552 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsWithBadSelector
) {
553 // The setup is the same as GetStatsWithLocalSelector, but the stream is not
554 // added to the PeerConnection.
555 blink::WebMediaStream
local_stream(
556 CreateLocalMediaStream("local_stream_2"));
557 blink::WebMediaConstraints constraints
;
558 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
560 local_stream
.audioTracks(tracks
);
561 blink::WebMediaStreamTrack component
= tracks
[0];
562 mock_peer_connection_
->SetGetStatsResult(false);
564 scoped_refptr
<MockRTCStatsRequest
> request(
565 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
566 request
->setSelector(component
);
567 pc_handler_
->getStats(request
.get());
568 base::RunLoop().RunUntilIdle();
569 EXPECT_EQ(0, request
->result()->report_count());
572 TEST_F(RTCPeerConnectionHandlerTest
, OnSignalingChange
) {
573 testing::InSequence sequence
;
575 webrtc::PeerConnectionInterface::SignalingState new_state
=
576 webrtc::PeerConnectionInterface::kHaveRemoteOffer
;
577 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
579 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer
));
580 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
581 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer
));
582 pc_handler_
->observer()->OnSignalingChange(new_state
);
584 new_state
= webrtc::PeerConnectionInterface::kHaveLocalPrAnswer
;
585 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
587 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer
));
588 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
589 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer
));
590 pc_handler_
->observer()->OnSignalingChange(new_state
);
592 new_state
= webrtc::PeerConnectionInterface::kHaveLocalOffer
;
593 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
595 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer
));
596 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
597 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer
));
598 pc_handler_
->observer()->OnSignalingChange(new_state
);
600 new_state
= webrtc::PeerConnectionInterface::kHaveRemotePrAnswer
;
601 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
603 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer
));
604 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
605 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer
));
606 pc_handler_
->observer()->OnSignalingChange(new_state
);
608 new_state
= webrtc::PeerConnectionInterface::kClosed
;
609 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
611 WebRTCPeerConnectionHandlerClient::SignalingStateClosed
));
612 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
613 WebRTCPeerConnectionHandlerClient::SignalingStateClosed
));
614 pc_handler_
->observer()->OnSignalingChange(new_state
);
617 TEST_F(RTCPeerConnectionHandlerTest
, OnIceConnectionChange
) {
618 testing::InSequence sequence
;
620 webrtc::PeerConnectionInterface::IceConnectionState new_state
=
621 webrtc::PeerConnectionInterface::kIceConnectionNew
;
622 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
624 WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting
));
625 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
626 WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting
));
627 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
629 new_state
= webrtc::PeerConnectionInterface::kIceConnectionChecking
;
630 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
632 WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking
));
633 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
634 WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking
));
635 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
637 new_state
= webrtc::PeerConnectionInterface::kIceConnectionConnected
;
638 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
640 WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected
));
641 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
642 WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected
));
643 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
645 new_state
= webrtc::PeerConnectionInterface::kIceConnectionCompleted
;
646 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
648 WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted
));
649 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
650 WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted
));
651 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
653 new_state
= webrtc::PeerConnectionInterface::kIceConnectionFailed
;
654 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
656 WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed
));
657 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
658 WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed
));
659 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
661 new_state
= webrtc::PeerConnectionInterface::kIceConnectionDisconnected
;
662 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
664 WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected
));
665 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
666 WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected
));
667 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
669 new_state
= webrtc::PeerConnectionInterface::kIceConnectionClosed
;
670 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
672 WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed
));
673 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
674 WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed
));
675 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
678 TEST_F(RTCPeerConnectionHandlerTest
, OnIceGatheringChange
) {
679 testing::InSequence sequence
;
680 EXPECT_CALL(*mock_tracker_
.get(), TrackIceGatheringStateChange(
682 WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew
));
683 EXPECT_CALL(*mock_client_
.get(), didChangeICEGatheringState(
684 WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew
));
685 EXPECT_CALL(*mock_tracker_
.get(), TrackIceGatheringStateChange(
687 WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering
));
688 EXPECT_CALL(*mock_client_
.get(), didChangeICEGatheringState(
689 WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering
));
690 EXPECT_CALL(*mock_tracker_
.get(), TrackIceGatheringStateChange(
692 WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete
));
693 EXPECT_CALL(*mock_client_
.get(), didChangeICEGatheringState(
694 WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete
));
696 webrtc::PeerConnectionInterface::IceGatheringState new_state
=
697 webrtc::PeerConnectionInterface::kIceGatheringNew
;
698 pc_handler_
->observer()->OnIceGatheringChange(new_state
);
700 new_state
= webrtc::PeerConnectionInterface::kIceGatheringGathering
;
701 pc_handler_
->observer()->OnIceGatheringChange(new_state
);
703 new_state
= webrtc::PeerConnectionInterface::kIceGatheringComplete
;
704 pc_handler_
->observer()->OnIceGatheringChange(new_state
);
706 // Check NULL candidate after ice gathering is completed.
707 EXPECT_EQ("", mock_client_
->candidate_mid());
708 EXPECT_EQ(-1, mock_client_
->candidate_mlineindex());
709 EXPECT_EQ("", mock_client_
->candidate_sdp());
712 TEST_F(RTCPeerConnectionHandlerTest
, OnAddAndOnRemoveStream
) {
713 std::string
remote_stream_label("remote_stream");
714 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
715 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
717 testing::InSequence sequence
;
718 EXPECT_CALL(*mock_tracker_
.get(), TrackAddStream(
720 testing::Property(&blink::WebMediaStream::id
,
721 base::UTF8ToUTF16(remote_stream_label
)),
722 PeerConnectionTracker::SOURCE_REMOTE
));
723 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
724 testing::Property(&blink::WebMediaStream::id
,
725 base::UTF8ToUTF16(remote_stream_label
))));
727 EXPECT_CALL(*mock_tracker_
.get(), TrackRemoveStream(
729 testing::Property(&blink::WebMediaStream::id
,
730 base::UTF8ToUTF16(remote_stream_label
)),
731 PeerConnectionTracker::SOURCE_REMOTE
));
732 EXPECT_CALL(*mock_client_
.get(), didRemoveRemoteStream(
733 testing::Property(&blink::WebMediaStream::id
,
734 base::UTF8ToUTF16(remote_stream_label
))));
736 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
737 base::RunLoop().RunUntilIdle();
738 pc_handler_
->observer()->OnRemoveStream(remote_stream
.get());
739 base::RunLoop().RunUntilIdle();
742 // This test that WebKit is notified about remote track state changes.
743 TEST_F(RTCPeerConnectionHandlerTest
, RemoteTrackState
) {
744 std::string
remote_stream_label("remote_stream");
745 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
746 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
748 testing::InSequence sequence
;
749 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
750 testing::Property(&blink::WebMediaStream::id
,
751 base::UTF8ToUTF16(remote_stream_label
))));
752 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
753 base::RunLoop().RunUntilIdle();
754 const blink::WebMediaStream
& webkit_stream
= mock_client_
->remote_stream();
756 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
757 webkit_stream
.audioTracks(audio_tracks
);
758 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive
,
759 audio_tracks
[0].source().readyState());
761 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
762 webkit_stream
.videoTracks(video_tracks
);
763 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive
,
764 video_tracks
[0].source().readyState());
766 remote_stream
->GetAudioTracks()[0]->set_state(
767 webrtc::MediaStreamTrackInterface::kEnded
);
768 base::RunLoop().RunUntilIdle();
769 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded
,
770 audio_tracks
[0].source().readyState());
772 remote_stream
->GetVideoTracks()[0]->set_state(
773 webrtc::MediaStreamTrackInterface::kEnded
);
774 base::RunLoop().RunUntilIdle();
775 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded
,
776 video_tracks
[0].source().readyState());
779 TEST_F(RTCPeerConnectionHandlerTest
, RemoveAndAddAudioTrackFromRemoteStream
) {
780 std::string
remote_stream_label("remote_stream");
781 base::RunLoop run_loop
;
783 // Grab the added media stream when it's been successfully added to the PC.
784 blink::WebMediaStream webkit_stream
;
785 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
786 testing::Property(&blink::WebMediaStream::id
,
787 base::UTF8ToUTF16(remote_stream_label
))))
789 DoAll(SaveArg
<0>(&webkit_stream
),
790 ExitMessageLoop(&message_loop_
, run_loop
.QuitClosure())));
792 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
793 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
794 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
798 // Test in a small scope so that |audio_tracks| don't hold on to destroyed
800 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
801 webkit_stream
.audioTracks(audio_tracks
);
802 EXPECT_EQ(1u, audio_tracks
.size());
805 // Remove the Webrtc audio track from the Webrtc MediaStream.
806 scoped_refptr
<webrtc::AudioTrackInterface
> webrtc_track
=
807 remote_stream
->GetAudioTracks()[0].get();
808 remote_stream
->RemoveTrack(webrtc_track
.get());
809 base::RunLoop().RunUntilIdle();
812 blink::WebVector
<blink::WebMediaStreamTrack
> modified_audio_tracks1
;
813 webkit_stream
.audioTracks(modified_audio_tracks1
);
814 EXPECT_EQ(0u, modified_audio_tracks1
.size());
817 blink::WebHeap::collectGarbageForTesting();
819 // Add the WebRtc audio track again.
820 remote_stream
->AddTrack(webrtc_track
.get());
821 base::RunLoop().RunUntilIdle();
822 blink::WebVector
<blink::WebMediaStreamTrack
> modified_audio_tracks2
;
823 webkit_stream
.audioTracks(modified_audio_tracks2
);
824 EXPECT_EQ(1u, modified_audio_tracks2
.size());
827 TEST_F(RTCPeerConnectionHandlerTest
, RemoveAndAddVideoTrackFromRemoteStream
) {
828 std::string
remote_stream_label("remote_stream");
829 base::RunLoop run_loop
;
831 // Grab the added media stream when it's been successfully added to the PC.
832 blink::WebMediaStream webkit_stream
;
833 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
834 testing::Property(&blink::WebMediaStream::id
,
835 base::UTF8ToUTF16(remote_stream_label
))))
837 DoAll(SaveArg
<0>(&webkit_stream
),
838 ExitMessageLoop(&message_loop_
, run_loop
.QuitClosure())));
840 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
841 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
842 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
846 // Test in a small scope so that |video_tracks| don't hold on to destroyed
848 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
849 webkit_stream
.videoTracks(video_tracks
);
850 EXPECT_EQ(1u, video_tracks
.size());
853 // Remove the Webrtc video track from the Webrtc MediaStream.
854 scoped_refptr
<webrtc::VideoTrackInterface
> webrtc_track
=
855 remote_stream
->GetVideoTracks()[0].get();
856 remote_stream
->RemoveTrack(webrtc_track
.get());
857 base::RunLoop().RunUntilIdle();
859 blink::WebVector
<blink::WebMediaStreamTrack
> modified_video_tracks1
;
860 webkit_stream
.videoTracks(modified_video_tracks1
);
861 EXPECT_EQ(0u, modified_video_tracks1
.size());
864 blink::WebHeap::collectGarbageForTesting();
866 // Add the WebRtc video track again.
867 remote_stream
->AddTrack(webrtc_track
.get());
868 base::RunLoop().RunUntilIdle();
869 blink::WebVector
<blink::WebMediaStreamTrack
> modified_video_tracks2
;
870 webkit_stream
.videoTracks(modified_video_tracks2
);
871 EXPECT_EQ(1u, modified_video_tracks2
.size());
874 TEST_F(RTCPeerConnectionHandlerTest
, RemoveAndAddTracksFromRemoteStream
) {
875 std::string
remote_stream_label("remote_stream");
876 base::RunLoop run_loop
;
878 // Grab the added media stream when it's been successfully added to the PC.
879 blink::WebMediaStream webkit_stream
;
880 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
881 testing::Property(&blink::WebMediaStream::id
,
882 base::UTF8ToUTF16(remote_stream_label
))))
884 DoAll(SaveArg
<0>(&webkit_stream
),
885 ExitMessageLoop(&message_loop_
, run_loop
.QuitClosure())));
887 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
888 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
889 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
893 // Test in a small scope so that |audio_tracks| don't hold on to destroyed
895 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
896 webkit_stream
.audioTracks(audio_tracks
);
897 EXPECT_EQ(1u, audio_tracks
.size());
898 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
899 webkit_stream
.videoTracks(video_tracks
);
900 EXPECT_EQ(1u, video_tracks
.size());
903 // Remove the Webrtc tracks from the MediaStream.
904 auto audio_track
= remote_stream
->GetAudioTracks()[0];
905 EXPECT_TRUE(remote_stream
->RemoveTrack(audio_track
.get()));
906 auto video_track
= remote_stream
->GetVideoTracks()[0];
907 EXPECT_TRUE(remote_stream
->RemoveTrack(video_track
.get()));
908 base::RunLoop().RunUntilIdle();
911 blink::WebVector
<blink::WebMediaStreamTrack
> modified_audio_tracks
;
912 webkit_stream
.audioTracks(modified_audio_tracks
);
913 EXPECT_EQ(0u, modified_audio_tracks
.size());
914 blink::WebVector
<blink::WebMediaStreamTrack
> modified_video_tracks
;
915 webkit_stream
.videoTracks(modified_video_tracks
);
916 EXPECT_EQ(0u, modified_video_tracks
.size());
919 blink::WebHeap::collectGarbageForTesting();
921 // Add the tracks again.
922 remote_stream
->AddTrack(audio_track
.get());
923 base::RunLoop().RunUntilIdle();
924 remote_stream
->AddTrack(video_track
.get());
925 base::RunLoop().RunUntilIdle();
927 blink::WebHeap::collectGarbageForTesting();
929 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
930 webkit_stream
.audioTracks(audio_tracks
);
931 EXPECT_EQ(1u, audio_tracks
.size());
932 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
933 webkit_stream
.videoTracks(video_tracks
);
934 EXPECT_EQ(1u, video_tracks
.size());
937 TEST_F(RTCPeerConnectionHandlerTest
, OnIceCandidate
) {
938 testing::InSequence sequence
;
939 EXPECT_CALL(*mock_tracker_
.get(),
940 TrackAddIceCandidate(pc_handler_
.get(), _
,
941 PeerConnectionTracker::SOURCE_LOCAL
, true));
942 EXPECT_CALL(*mock_client_
.get(), didGenerateICECandidate(_
));
944 scoped_ptr
<webrtc::IceCandidateInterface
> native_candidate(
945 mock_dependency_factory_
->CreateIceCandidate("sdpMid", 1, kDummySdp
));
946 pc_handler_
->observer()->OnIceCandidate(native_candidate
.get());
947 base::RunLoop().RunUntilIdle();
948 EXPECT_EQ("sdpMid", mock_client_
->candidate_mid());
949 EXPECT_EQ(1, mock_client_
->candidate_mlineindex());
950 EXPECT_EQ(kDummySdp
, mock_client_
->candidate_sdp());
953 TEST_F(RTCPeerConnectionHandlerTest
, OnRenegotiationNeeded
) {
954 testing::InSequence sequence
;
955 EXPECT_CALL(*mock_tracker_
.get(),
956 TrackOnRenegotiationNeeded(pc_handler_
.get()));
957 EXPECT_CALL(*mock_client_
.get(), negotiationNeeded());
958 pc_handler_
->observer()->OnRenegotiationNeeded();
961 TEST_F(RTCPeerConnectionHandlerTest
, CreateDataChannel
) {
962 blink::WebString label
= "d1";
963 EXPECT_CALL(*mock_tracker_
.get(),
964 TrackCreateDataChannel(pc_handler_
.get(),
966 PeerConnectionTracker::SOURCE_LOCAL
));
967 scoped_ptr
<blink::WebRTCDataChannelHandler
> channel(
968 pc_handler_
->createDataChannel("d1", blink::WebRTCDataChannelInit()));
969 EXPECT_TRUE(channel
.get() != NULL
);
970 EXPECT_EQ(label
, channel
->label());
971 channel
->setClient(nullptr);
974 TEST_F(RTCPeerConnectionHandlerTest
, CreateDtmfSender
) {
975 std::string stream_label
= "local_stream";
976 blink::WebMediaStream
local_stream(CreateLocalMediaStream(stream_label
));
977 blink::WebMediaConstraints constraints
;
978 pc_handler_
->addStream(local_stream
, constraints
);
980 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
981 local_stream
.videoTracks(tracks
);
983 ASSERT_LE(1ul, tracks
.size());
984 EXPECT_FALSE(pc_handler_
->createDTMFSender(tracks
[0]));
986 local_stream
.audioTracks(tracks
);
987 ASSERT_LE(1ul, tracks
.size());
989 EXPECT_CALL(*mock_tracker_
.get(),
990 TrackCreateDTMFSender(pc_handler_
.get(),
991 testing::Ref(tracks
[0])));
993 scoped_ptr
<blink::WebRTCDTMFSenderHandler
> sender(
994 pc_handler_
->createDTMFSender(tracks
[0]));
995 EXPECT_TRUE(sender
.get());
998 } // namespace content