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/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "base/values.h"
14 #include "content/child/child_process.h"
15 #include "content/renderer/media/media_stream.h"
16 #include "content/renderer/media/media_stream_audio_source.h"
17 #include "content/renderer/media/media_stream_source.h"
18 #include "content/renderer/media/media_stream_video_track.h"
19 #include "content/renderer/media/mock_media_constraint_factory.h"
20 #include "content/renderer/media/mock_media_stream_video_source.h"
21 #include "content/renderer/media/mock_peer_connection_impl.h"
22 #include "content/renderer/media/mock_web_rtc_peer_connection_handler_client.h"
23 #include "content/renderer/media/peer_connection_tracker.h"
24 #include "content/renderer/media/rtc_media_constraints.h"
25 #include "content/renderer/media/rtc_peer_connection_handler.h"
26 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
27 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
28 #include "content/renderer/media/webrtc_local_audio_track.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
32 #include "third_party/WebKit/public/platform/WebMediaStream.h"
33 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
34 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
35 #include "third_party/WebKit/public/platform/WebRTCConfiguration.h"
36 #include "third_party/WebKit/public/platform/WebRTCDTMFSenderHandler.h"
37 #include "third_party/WebKit/public/platform/WebRTCDataChannelHandler.h"
38 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
39 #include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
40 #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h"
41 #include "third_party/WebKit/public/platform/WebRTCSessionDescription.h"
42 #include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h"
43 #include "third_party/WebKit/public/platform/WebRTCStatsRequest.h"
44 #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h"
45 #include "third_party/WebKit/public/platform/WebURL.h"
46 #include "third_party/WebKit/public/web/WebHeap.h"
47 #include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h"
49 static const char kDummySdp
[] = "dummy sdp";
50 static const char kDummySdpType
[] = "dummy type";
52 using blink::WebRTCPeerConnectionHandlerClient
;
53 using testing::NiceMock
;
56 using testing::SaveArg
;
60 ACTION_P2(ExitMessageLoop
, message_loop
, quit_closure
) {
61 message_loop
->PostTask(FROM_HERE
, quit_closure
);
64 class MockRTCStatsResponse
: public LocalRTCStatsResponse
{
66 MockRTCStatsResponse()
71 size_t addReport(blink::WebString type
,
73 double timestamp
) override
{
78 void addStatistic(size_t report
,
79 blink::WebString name
,
80 blink::WebString value
) override
{
83 int report_count() const { return report_count_
; }
90 // Mocked wrapper for blink::WebRTCStatsRequest
91 class MockRTCStatsRequest
: public LocalRTCStatsRequest
{
94 : has_selector_(false),
95 request_succeeded_called_(false) {}
97 bool hasSelector() const override
{ return has_selector_
; }
98 blink::WebMediaStreamTrack
component() const override
{ return component_
; }
99 scoped_refptr
<LocalRTCStatsResponse
> createResponse() override
{
100 DCHECK(!response_
.get());
101 response_
= new rtc::RefCountedObject
<MockRTCStatsResponse
>();
105 void requestSucceeded(const LocalRTCStatsResponse
* response
) override
{
106 EXPECT_EQ(response
, response_
.get());
107 request_succeeded_called_
= true;
110 // Function for setting whether or not a selector is available.
111 void setSelector(const blink::WebMediaStreamTrack
& component
) {
112 has_selector_
= true;
113 component_
= component
;
116 // Function for inspecting the result of a stats request.
117 MockRTCStatsResponse
* result() {
118 if (request_succeeded_called_
) {
119 return response_
.get();
127 blink::WebMediaStreamTrack component_
;
128 scoped_refptr
<MockRTCStatsResponse
> response_
;
129 bool request_succeeded_called_
;
132 class MockPeerConnectionTracker
: public PeerConnectionTracker
{
134 MOCK_METHOD1(UnregisterPeerConnection
,
135 void(RTCPeerConnectionHandler
* pc_handler
));
136 // TODO(jiayl): add coverage for the following methods
137 MOCK_METHOD2(TrackCreateOffer
,
138 void(RTCPeerConnectionHandler
* pc_handler
,
139 const RTCMediaConstraints
& constraints
));
140 MOCK_METHOD2(TrackCreateAnswer
,
141 void(RTCPeerConnectionHandler
* pc_handler
,
142 const RTCMediaConstraints
& constraints
));
143 MOCK_METHOD4(TrackSetSessionDescription
,
144 void(RTCPeerConnectionHandler
* pc_handler
,
145 const std::string
& sdp
, const std::string
& type
,
149 void(RTCPeerConnectionHandler
* pc_handler
,
150 const webrtc::PeerConnectionInterface::RTCConfiguration
& config
,
151 const RTCMediaConstraints
& options
));
152 MOCK_METHOD4(TrackAddIceCandidate
,
153 void(RTCPeerConnectionHandler
* pc_handler
,
154 const blink::WebRTCICECandidate
& candidate
,
157 MOCK_METHOD3(TrackAddStream
,
158 void(RTCPeerConnectionHandler
* pc_handler
,
159 const blink::WebMediaStream
& stream
,
161 MOCK_METHOD3(TrackRemoveStream
,
162 void(RTCPeerConnectionHandler
* pc_handler
,
163 const blink::WebMediaStream
& stream
,
165 MOCK_METHOD1(TrackOnIceComplete
,
166 void(RTCPeerConnectionHandler
* pc_handler
));
167 MOCK_METHOD3(TrackCreateDataChannel
,
168 void(RTCPeerConnectionHandler
* pc_handler
,
169 const webrtc::DataChannelInterface
* data_channel
,
171 MOCK_METHOD1(TrackStop
, void(RTCPeerConnectionHandler
* pc_handler
));
172 MOCK_METHOD2(TrackSignalingStateChange
,
173 void(RTCPeerConnectionHandler
* pc_handler
,
174 WebRTCPeerConnectionHandlerClient::SignalingState state
));
176 TrackIceConnectionStateChange
,
177 void(RTCPeerConnectionHandler
* pc_handler
,
178 WebRTCPeerConnectionHandlerClient::ICEConnectionState state
));
180 TrackIceGatheringStateChange
,
181 void(RTCPeerConnectionHandler
* pc_handler
,
182 WebRTCPeerConnectionHandlerClient::ICEGatheringState state
));
183 MOCK_METHOD1(TrackOnRenegotiationNeeded
,
184 void(RTCPeerConnectionHandler
* pc_handler
));
185 MOCK_METHOD2(TrackCreateDTMFSender
,
186 void(RTCPeerConnectionHandler
* pc_handler
,
187 const blink::WebMediaStreamTrack
& track
));
190 class RTCPeerConnectionHandlerUnderTest
: public RTCPeerConnectionHandler
{
192 RTCPeerConnectionHandlerUnderTest(
193 WebRTCPeerConnectionHandlerClient
* client
,
194 PeerConnectionDependencyFactory
* dependency_factory
)
195 : RTCPeerConnectionHandler(client
, dependency_factory
) {
198 MockPeerConnectionImpl
* native_peer_connection() {
199 return static_cast<MockPeerConnectionImpl
*>(
200 RTCPeerConnectionHandler::native_peer_connection());
203 webrtc::PeerConnectionObserver
* observer() {
204 return native_peer_connection()->observer();
207 scoped_refptr
<base::SingleThreadTaskRunner
>
208 signaling_thread() const override
{
209 return base::ThreadTaskRunnerHandle::Get();
213 class RTCPeerConnectionHandlerTest
: public ::testing::Test
{
215 RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL
) {
216 child_process_
.reset(new ChildProcess());
219 void SetUp() override
{
220 mock_client_
.reset(new NiceMock
<MockWebRTCPeerConnectionHandlerClient
>());
221 mock_dependency_factory_
.reset(new MockPeerConnectionDependencyFactory());
223 new RTCPeerConnectionHandlerUnderTest(
224 mock_client_
.get(), mock_dependency_factory_
.get()));
225 mock_tracker_
.reset(new NiceMock
<MockPeerConnectionTracker
>());
226 blink::WebRTCConfiguration config
;
227 blink::WebMediaConstraints constraints
;
228 EXPECT_TRUE(pc_handler_
->InitializeForTest(
229 config
, constraints
, mock_tracker_
.get()->AsWeakPtr()));
231 mock_peer_connection_
= pc_handler_
->native_peer_connection();
232 ASSERT_TRUE(mock_peer_connection_
);
235 void TearDown() override
{
237 mock_tracker_
.reset();
238 mock_dependency_factory_
.reset();
239 mock_client_
.reset();
240 blink::WebHeap::collectAllGarbageForTesting();
243 // Creates a WebKit local MediaStream.
244 blink::WebMediaStream
CreateLocalMediaStream(
245 const std::string
& stream_label
) {
246 std::string
video_track_label("video-label");
247 std::string
audio_track_label("audio-label");
248 blink::WebMediaStreamSource audio_source
;
249 audio_source
.initialize(blink::WebString::fromUTF8(audio_track_label
),
250 blink::WebMediaStreamSource::TypeAudio
,
251 blink::WebString::fromUTF8("audio_track"),
252 false /* remote */, true /* readonly */);
253 audio_source
.setExtraData(new MediaStreamAudioSource());
254 blink::WebMediaStreamSource video_source
;
255 video_source
.initialize(blink::WebString::fromUTF8(video_track_label
),
256 blink::WebMediaStreamSource::TypeVideo
,
257 blink::WebString::fromUTF8("video_track"),
258 false /* remote */, true /* readonly */);
259 MockMediaStreamVideoSource
* native_video_source
=
260 new MockMediaStreamVideoSource(false);
261 video_source
.setExtraData(native_video_source
);
263 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks(
264 static_cast<size_t>(1));
265 audio_tracks
[0].initialize(audio_source
.id(), audio_source
);
266 StreamDeviceInfo
device_info(MEDIA_DEVICE_AUDIO_CAPTURE
, "Mock device",
268 MockMediaConstraintFactory constraint_factory
;
269 const blink::WebMediaConstraints constraints
=
270 constraint_factory
.CreateWebMediaConstraints();
271 scoped_refptr
<WebRtcAudioCapturer
> capturer(
272 WebRtcAudioCapturer::CreateCapturer(
273 -1, device_info
, constraints
, nullptr, nullptr));
274 scoped_refptr
<WebRtcLocalAudioTrackAdapter
> adapter(
275 WebRtcLocalAudioTrackAdapter::Create(audio_track_label
, nullptr));
276 scoped_ptr
<WebRtcLocalAudioTrack
> native_track(
277 new WebRtcLocalAudioTrack(adapter
.get(), capturer
, nullptr));
278 audio_tracks
[0].setExtraData(native_track
.release());
279 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks(
280 static_cast<size_t>(1));
281 blink::WebMediaConstraints video_constraints
;
282 video_constraints
.initialize();
283 video_tracks
[0] = MediaStreamVideoTrack::CreateVideoTrack(
284 native_video_source
, video_constraints
,
285 MediaStreamVideoSource::ConstraintsCallback(), true);
287 blink::WebMediaStream local_stream
;
288 local_stream
.initialize(base::UTF8ToUTF16(stream_label
), audio_tracks
,
290 local_stream
.setExtraData(
291 new MediaStream(local_stream
));
295 // Creates a remote MediaStream and adds it to the mocked native
297 scoped_refptr
<webrtc::MediaStreamInterface
>
298 AddRemoteMockMediaStream(const std::string
& stream_label
,
299 const std::string
& video_track_label
,
300 const std::string
& audio_track_label
) {
301 scoped_refptr
<webrtc::MediaStreamInterface
> stream(
302 mock_dependency_factory_
->CreateLocalMediaStream(stream_label
));
303 if (!video_track_label
.empty()) {
304 webrtc::VideoSourceInterface
* source
= NULL
;
305 scoped_refptr
<webrtc::VideoTrackInterface
> video_track(
306 mock_dependency_factory_
->CreateLocalVideoTrack(
307 video_track_label
, source
));
308 stream
->AddTrack(video_track
.get());
310 if (!audio_track_label
.empty()) {
311 scoped_refptr
<webrtc::AudioTrackInterface
> audio_track(
312 WebRtcLocalAudioTrackAdapter::Create(audio_track_label
, NULL
));
313 stream
->AddTrack(audio_track
.get());
315 mock_peer_connection_
->AddRemoteStream(stream
.get());
319 base::MessageLoop message_loop_
;
320 scoped_ptr
<ChildProcess
> child_process_
;
321 scoped_ptr
<MockWebRTCPeerConnectionHandlerClient
> mock_client_
;
322 scoped_ptr
<MockPeerConnectionDependencyFactory
> mock_dependency_factory_
;
323 scoped_ptr
<NiceMock
<MockPeerConnectionTracker
> > mock_tracker_
;
324 scoped_ptr
<RTCPeerConnectionHandlerUnderTest
> pc_handler_
;
326 // Weak reference to the mocked native peer connection implementation.
327 MockPeerConnectionImpl
* mock_peer_connection_
;
330 TEST_F(RTCPeerConnectionHandlerTest
, Destruct
) {
331 EXPECT_CALL(*mock_tracker_
.get(), UnregisterPeerConnection(pc_handler_
.get()))
333 pc_handler_
.reset(NULL
);
336 TEST_F(RTCPeerConnectionHandlerTest
, CreateOffer
) {
337 blink::WebRTCSessionDescriptionRequest request
;
338 blink::WebMediaConstraints options
;
339 EXPECT_CALL(*mock_tracker_
.get(), TrackCreateOffer(pc_handler_
.get(), _
));
341 // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
342 // the |reqest| requestSucceeded can be tested? Currently the |request| object
343 // can not be initialized from a unit test.
344 EXPECT_FALSE(mock_peer_connection_
->created_session_description() != NULL
);
345 pc_handler_
->createOffer(request
, options
);
346 EXPECT_TRUE(mock_peer_connection_
->created_session_description() != NULL
);
349 TEST_F(RTCPeerConnectionHandlerTest
, CreateAnswer
) {
350 blink::WebRTCSessionDescriptionRequest request
;
351 blink::WebMediaConstraints options
;
352 EXPECT_CALL(*mock_tracker_
.get(), TrackCreateAnswer(pc_handler_
.get(), _
));
353 // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
354 // the |reqest| requestSucceeded can be tested? Currently the |request| object
355 // can not be initialized from a unit test.
356 EXPECT_FALSE(mock_peer_connection_
->created_session_description() != NULL
);
357 pc_handler_
->createAnswer(request
, options
);
358 EXPECT_TRUE(mock_peer_connection_
->created_session_description() != NULL
);
361 TEST_F(RTCPeerConnectionHandlerTest
, setLocalDescription
) {
362 blink::WebRTCVoidRequest request
;
363 blink::WebRTCSessionDescription description
;
364 description
.initialize(kDummySdpType
, kDummySdp
);
365 // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
366 // before |mock_peer_connection| is called.
367 testing::InSequence sequence
;
368 EXPECT_CALL(*mock_tracker_
.get(),
369 TrackSetSessionDescription(pc_handler_
.get(), kDummySdp
,
371 PeerConnectionTracker::SOURCE_LOCAL
));
372 EXPECT_CALL(*mock_peer_connection_
, SetLocalDescription(_
, _
));
374 pc_handler_
->setLocalDescription(request
, description
);
375 base::RunLoop().RunUntilIdle();
376 EXPECT_EQ(description
.type(), pc_handler_
->localDescription().type());
377 EXPECT_EQ(description
.sdp(), pc_handler_
->localDescription().sdp());
379 std::string sdp_string
;
380 ASSERT_TRUE(mock_peer_connection_
->local_description() != NULL
);
381 EXPECT_EQ(kDummySdpType
, mock_peer_connection_
->local_description()->type());
382 mock_peer_connection_
->local_description()->ToString(&sdp_string
);
383 EXPECT_EQ(kDummySdp
, sdp_string
);
386 TEST_F(RTCPeerConnectionHandlerTest
, setRemoteDescription
) {
387 blink::WebRTCVoidRequest request
;
388 blink::WebRTCSessionDescription description
;
389 description
.initialize(kDummySdpType
, kDummySdp
);
391 // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
392 // before |mock_peer_connection| is called.
393 testing::InSequence sequence
;
394 EXPECT_CALL(*mock_tracker_
.get(),
395 TrackSetSessionDescription(pc_handler_
.get(), kDummySdp
,
397 PeerConnectionTracker::SOURCE_REMOTE
));
398 EXPECT_CALL(*mock_peer_connection_
, SetRemoteDescription(_
, _
));
400 pc_handler_
->setRemoteDescription(request
, description
);
401 base::RunLoop().RunUntilIdle();
402 EXPECT_EQ(description
.type(), pc_handler_
->remoteDescription().type());
403 EXPECT_EQ(description
.sdp(), pc_handler_
->remoteDescription().sdp());
405 std::string sdp_string
;
406 ASSERT_TRUE(mock_peer_connection_
->remote_description() != NULL
);
407 EXPECT_EQ(kDummySdpType
, mock_peer_connection_
->remote_description()->type());
408 mock_peer_connection_
->remote_description()->ToString(&sdp_string
);
409 EXPECT_EQ(kDummySdp
, sdp_string
);
412 TEST_F(RTCPeerConnectionHandlerTest
, updateICE
) {
413 blink::WebRTCConfiguration config
;
414 blink::WebMediaConstraints constraints
;
416 EXPECT_CALL(*mock_tracker_
.get(), TrackUpdateIce(pc_handler_
.get(), _
, _
));
417 // TODO(perkj): Test that the parameters in |config| can be translated when a
418 // WebRTCConfiguration can be constructed. It's WebKit class and can't be
419 // initialized from a test.
420 EXPECT_TRUE(pc_handler_
->updateICE(config
, constraints
));
423 TEST_F(RTCPeerConnectionHandlerTest
, addICECandidate
) {
424 blink::WebRTCICECandidate candidate
;
425 candidate
.initialize(kDummySdp
, "sdpMid", 1);
427 EXPECT_CALL(*mock_tracker_
.get(),
428 TrackAddIceCandidate(pc_handler_
.get(),
429 testing::Ref(candidate
),
430 PeerConnectionTracker::SOURCE_REMOTE
,
432 EXPECT_TRUE(pc_handler_
->addICECandidate(candidate
));
433 EXPECT_EQ(kDummySdp
, mock_peer_connection_
->ice_sdp());
434 EXPECT_EQ(1, mock_peer_connection_
->sdp_mline_index());
435 EXPECT_EQ("sdpMid", mock_peer_connection_
->sdp_mid());
438 TEST_F(RTCPeerConnectionHandlerTest
, addAndRemoveStream
) {
439 std::string stream_label
= "local_stream";
440 blink::WebMediaStream
local_stream(
441 CreateLocalMediaStream(stream_label
));
442 blink::WebMediaConstraints constraints
;
444 EXPECT_CALL(*mock_tracker_
.get(),
445 TrackAddStream(pc_handler_
.get(),
446 testing::Ref(local_stream
),
447 PeerConnectionTracker::SOURCE_LOCAL
));
448 EXPECT_CALL(*mock_tracker_
.get(),
449 TrackRemoveStream(pc_handler_
.get(),
450 testing::Ref(local_stream
),
451 PeerConnectionTracker::SOURCE_LOCAL
));
452 EXPECT_TRUE(pc_handler_
->addStream(local_stream
, constraints
));
453 EXPECT_EQ(stream_label
, mock_peer_connection_
->stream_label());
455 mock_peer_connection_
->local_streams()->at(0)->GetAudioTracks().size());
457 mock_peer_connection_
->local_streams()->at(0)->GetVideoTracks().size());
459 EXPECT_FALSE(pc_handler_
->addStream(local_stream
, constraints
));
461 pc_handler_
->removeStream(local_stream
);
462 EXPECT_EQ(0u, mock_peer_connection_
->local_streams()->count());
465 TEST_F(RTCPeerConnectionHandlerTest
, addStreamWithStoppedAudioAndVideoTrack
) {
466 std::string stream_label
= "local_stream";
467 blink::WebMediaStream
local_stream(
468 CreateLocalMediaStream(stream_label
));
469 blink::WebMediaConstraints constraints
;
471 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
472 local_stream
.audioTracks(audio_tracks
);
473 MediaStreamAudioSource
* native_audio_source
=
474 static_cast<MediaStreamAudioSource
*>(
475 audio_tracks
[0].source().extraData());
476 native_audio_source
->StopSource();
478 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
479 local_stream
.videoTracks(video_tracks
);
480 MediaStreamVideoSource
* native_video_source
=
481 static_cast<MediaStreamVideoSource
*>(
482 video_tracks
[0].source().extraData());
483 native_video_source
->StopSource();
485 EXPECT_TRUE(pc_handler_
->addStream(local_stream
, constraints
));
486 EXPECT_EQ(stream_label
, mock_peer_connection_
->stream_label());
489 mock_peer_connection_
->local_streams()->at(0)->GetAudioTracks().size());
492 mock_peer_connection_
->local_streams()->at(0)->GetVideoTracks().size());
495 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsNoSelector
) {
496 scoped_refptr
<MockRTCStatsRequest
> request(
497 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
498 pc_handler_
->getStats(request
.get());
499 base::RunLoop().RunUntilIdle();
500 ASSERT_TRUE(request
->result());
501 EXPECT_LT(1, request
->result()->report_count());
504 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsAfterClose
) {
505 scoped_refptr
<MockRTCStatsRequest
> request(
506 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
508 base::RunLoop().RunUntilIdle();
509 pc_handler_
->getStats(request
.get());
510 base::RunLoop().RunUntilIdle();
511 ASSERT_TRUE(request
->result());
512 EXPECT_LT(1, request
->result()->report_count());
515 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsWithLocalSelector
) {
516 blink::WebMediaStream
local_stream(
517 CreateLocalMediaStream("local_stream"));
518 blink::WebMediaConstraints constraints
;
519 pc_handler_
->addStream(local_stream
, constraints
);
520 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
521 local_stream
.audioTracks(tracks
);
522 ASSERT_LE(1ul, tracks
.size());
524 scoped_refptr
<MockRTCStatsRequest
> request(
525 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
526 request
->setSelector(tracks
[0]);
527 pc_handler_
->getStats(request
.get());
528 base::RunLoop().RunUntilIdle();
529 EXPECT_EQ(1, request
->result()->report_count());
532 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsWithRemoteSelector
) {
533 scoped_refptr
<webrtc::MediaStreamInterface
> stream(
534 AddRemoteMockMediaStream("remote_stream", "video", "audio"));
535 pc_handler_
->observer()->OnAddStream(stream
.get());
536 base::RunLoop().RunUntilIdle();
537 const blink::WebMediaStream
& remote_stream
= mock_client_
->remote_stream();
539 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
540 remote_stream
.audioTracks(tracks
);
541 ASSERT_LE(1ul, tracks
.size());
543 scoped_refptr
<MockRTCStatsRequest
> request(
544 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
545 request
->setSelector(tracks
[0]);
546 pc_handler_
->getStats(request
.get());
547 base::RunLoop().RunUntilIdle();
548 EXPECT_EQ(1, request
->result()->report_count());
551 TEST_F(RTCPeerConnectionHandlerTest
, GetStatsWithBadSelector
) {
552 // The setup is the same as GetStatsWithLocalSelector, but the stream is not
553 // added to the PeerConnection.
554 blink::WebMediaStream
local_stream(
555 CreateLocalMediaStream("local_stream_2"));
556 blink::WebMediaConstraints constraints
;
557 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
559 local_stream
.audioTracks(tracks
);
560 blink::WebMediaStreamTrack component
= tracks
[0];
561 mock_peer_connection_
->SetGetStatsResult(false);
563 scoped_refptr
<MockRTCStatsRequest
> request(
564 new rtc::RefCountedObject
<MockRTCStatsRequest
>());
565 request
->setSelector(component
);
566 pc_handler_
->getStats(request
.get());
567 base::RunLoop().RunUntilIdle();
568 EXPECT_EQ(0, request
->result()->report_count());
571 TEST_F(RTCPeerConnectionHandlerTest
, OnSignalingChange
) {
572 testing::InSequence sequence
;
574 webrtc::PeerConnectionInterface::SignalingState new_state
=
575 webrtc::PeerConnectionInterface::kHaveRemoteOffer
;
576 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
578 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer
));
579 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
580 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer
));
581 pc_handler_
->observer()->OnSignalingChange(new_state
);
583 new_state
= webrtc::PeerConnectionInterface::kHaveLocalPrAnswer
;
584 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
586 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer
));
587 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
588 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer
));
589 pc_handler_
->observer()->OnSignalingChange(new_state
);
591 new_state
= webrtc::PeerConnectionInterface::kHaveLocalOffer
;
592 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
594 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer
));
595 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
596 WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer
));
597 pc_handler_
->observer()->OnSignalingChange(new_state
);
599 new_state
= webrtc::PeerConnectionInterface::kHaveRemotePrAnswer
;
600 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
602 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer
));
603 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
604 WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer
));
605 pc_handler_
->observer()->OnSignalingChange(new_state
);
607 new_state
= webrtc::PeerConnectionInterface::kClosed
;
608 EXPECT_CALL(*mock_tracker_
.get(), TrackSignalingStateChange(
610 WebRTCPeerConnectionHandlerClient::SignalingStateClosed
));
611 EXPECT_CALL(*mock_client_
.get(), didChangeSignalingState(
612 WebRTCPeerConnectionHandlerClient::SignalingStateClosed
));
613 pc_handler_
->observer()->OnSignalingChange(new_state
);
616 TEST_F(RTCPeerConnectionHandlerTest
, OnIceConnectionChange
) {
617 testing::InSequence sequence
;
619 webrtc::PeerConnectionInterface::IceConnectionState new_state
=
620 webrtc::PeerConnectionInterface::kIceConnectionNew
;
621 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
623 WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting
));
624 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
625 WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting
));
626 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
628 new_state
= webrtc::PeerConnectionInterface::kIceConnectionChecking
;
629 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
631 WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking
));
632 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
633 WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking
));
634 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
636 new_state
= webrtc::PeerConnectionInterface::kIceConnectionConnected
;
637 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
639 WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected
));
640 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
641 WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected
));
642 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
644 new_state
= webrtc::PeerConnectionInterface::kIceConnectionCompleted
;
645 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
647 WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted
));
648 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
649 WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted
));
650 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
652 new_state
= webrtc::PeerConnectionInterface::kIceConnectionFailed
;
653 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
655 WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed
));
656 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
657 WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed
));
658 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
660 new_state
= webrtc::PeerConnectionInterface::kIceConnectionDisconnected
;
661 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
663 WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected
));
664 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
665 WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected
));
666 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
668 new_state
= webrtc::PeerConnectionInterface::kIceConnectionClosed
;
669 EXPECT_CALL(*mock_tracker_
.get(), TrackIceConnectionStateChange(
671 WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed
));
672 EXPECT_CALL(*mock_client_
.get(), didChangeICEConnectionState(
673 WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed
));
674 pc_handler_
->observer()->OnIceConnectionChange(new_state
);
677 TEST_F(RTCPeerConnectionHandlerTest
, OnIceGatheringChange
) {
678 testing::InSequence sequence
;
679 EXPECT_CALL(*mock_tracker_
.get(), TrackIceGatheringStateChange(
681 WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew
));
682 EXPECT_CALL(*mock_client_
.get(), didChangeICEGatheringState(
683 WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew
));
684 EXPECT_CALL(*mock_tracker_
.get(), TrackIceGatheringStateChange(
686 WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering
));
687 EXPECT_CALL(*mock_client_
.get(), didChangeICEGatheringState(
688 WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering
));
689 EXPECT_CALL(*mock_tracker_
.get(), TrackIceGatheringStateChange(
691 WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete
));
692 EXPECT_CALL(*mock_client_
.get(), didChangeICEGatheringState(
693 WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete
));
695 webrtc::PeerConnectionInterface::IceGatheringState new_state
=
696 webrtc::PeerConnectionInterface::kIceGatheringNew
;
697 pc_handler_
->observer()->OnIceGatheringChange(new_state
);
699 new_state
= webrtc::PeerConnectionInterface::kIceGatheringGathering
;
700 pc_handler_
->observer()->OnIceGatheringChange(new_state
);
702 new_state
= webrtc::PeerConnectionInterface::kIceGatheringComplete
;
703 pc_handler_
->observer()->OnIceGatheringChange(new_state
);
705 // Check NULL candidate after ice gathering is completed.
706 EXPECT_EQ("", mock_client_
->candidate_mid());
707 EXPECT_EQ(-1, mock_client_
->candidate_mlineindex());
708 EXPECT_EQ("", mock_client_
->candidate_sdp());
711 TEST_F(RTCPeerConnectionHandlerTest
, OnAddAndOnRemoveStream
) {
712 std::string
remote_stream_label("remote_stream");
713 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
714 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
716 testing::InSequence sequence
;
717 EXPECT_CALL(*mock_tracker_
.get(), TrackAddStream(
719 testing::Property(&blink::WebMediaStream::id
,
720 base::UTF8ToUTF16(remote_stream_label
)),
721 PeerConnectionTracker::SOURCE_REMOTE
));
722 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
723 testing::Property(&blink::WebMediaStream::id
,
724 base::UTF8ToUTF16(remote_stream_label
))));
726 EXPECT_CALL(*mock_tracker_
.get(), TrackRemoveStream(
728 testing::Property(&blink::WebMediaStream::id
,
729 base::UTF8ToUTF16(remote_stream_label
)),
730 PeerConnectionTracker::SOURCE_REMOTE
));
731 EXPECT_CALL(*mock_client_
.get(), didRemoveRemoteStream(
732 testing::Property(&blink::WebMediaStream::id
,
733 base::UTF8ToUTF16(remote_stream_label
))));
735 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
736 base::RunLoop().RunUntilIdle();
737 pc_handler_
->observer()->OnRemoveStream(remote_stream
.get());
738 base::RunLoop().RunUntilIdle();
741 // This test that WebKit is notified about remote track state changes.
742 TEST_F(RTCPeerConnectionHandlerTest
, RemoteTrackState
) {
743 std::string
remote_stream_label("remote_stream");
744 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
745 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
747 testing::InSequence sequence
;
748 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
749 testing::Property(&blink::WebMediaStream::id
,
750 base::UTF8ToUTF16(remote_stream_label
))));
751 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
752 base::RunLoop().RunUntilIdle();
753 const blink::WebMediaStream
& webkit_stream
= mock_client_
->remote_stream();
755 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
756 webkit_stream
.audioTracks(audio_tracks
);
757 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive
,
758 audio_tracks
[0].source().readyState());
760 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
761 webkit_stream
.videoTracks(video_tracks
);
762 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive
,
763 video_tracks
[0].source().readyState());
765 remote_stream
->GetAudioTracks()[0]->set_state(
766 webrtc::MediaStreamTrackInterface::kEnded
);
767 base::RunLoop().RunUntilIdle();
768 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded
,
769 audio_tracks
[0].source().readyState());
771 remote_stream
->GetVideoTracks()[0]->set_state(
772 webrtc::MediaStreamTrackInterface::kEnded
);
773 base::RunLoop().RunUntilIdle();
774 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded
,
775 video_tracks
[0].source().readyState());
778 TEST_F(RTCPeerConnectionHandlerTest
, RemoveAndAddAudioTrackFromRemoteStream
) {
779 std::string
remote_stream_label("remote_stream");
780 base::RunLoop run_loop
;
782 // Grab the added media stream when it's been successfully added to the PC.
783 blink::WebMediaStream webkit_stream
;
784 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
785 testing::Property(&blink::WebMediaStream::id
,
786 base::UTF8ToUTF16(remote_stream_label
))))
788 DoAll(SaveArg
<0>(&webkit_stream
),
789 ExitMessageLoop(&message_loop_
, run_loop
.QuitClosure())));
791 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
792 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
793 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
797 // Test in a small scope so that |audio_tracks| don't hold on to destroyed
799 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
800 webkit_stream
.audioTracks(audio_tracks
);
801 EXPECT_EQ(1u, audio_tracks
.size());
804 // Remove the Webrtc audio track from the Webrtc MediaStream.
805 scoped_refptr
<webrtc::AudioTrackInterface
> webrtc_track
=
806 remote_stream
->GetAudioTracks()[0].get();
807 remote_stream
->RemoveTrack(webrtc_track
.get());
808 base::RunLoop().RunUntilIdle();
811 blink::WebVector
<blink::WebMediaStreamTrack
> modified_audio_tracks1
;
812 webkit_stream
.audioTracks(modified_audio_tracks1
);
813 EXPECT_EQ(0u, modified_audio_tracks1
.size());
816 blink::WebHeap::collectGarbageForTesting();
818 // Add the WebRtc audio track again.
819 remote_stream
->AddTrack(webrtc_track
.get());
820 base::RunLoop().RunUntilIdle();
821 blink::WebVector
<blink::WebMediaStreamTrack
> modified_audio_tracks2
;
822 webkit_stream
.audioTracks(modified_audio_tracks2
);
823 EXPECT_EQ(1u, modified_audio_tracks2
.size());
826 TEST_F(RTCPeerConnectionHandlerTest
, RemoveAndAddVideoTrackFromRemoteStream
) {
827 std::string
remote_stream_label("remote_stream");
828 base::RunLoop run_loop
;
830 // Grab the added media stream when it's been successfully added to the PC.
831 blink::WebMediaStream webkit_stream
;
832 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
833 testing::Property(&blink::WebMediaStream::id
,
834 base::UTF8ToUTF16(remote_stream_label
))))
836 DoAll(SaveArg
<0>(&webkit_stream
),
837 ExitMessageLoop(&message_loop_
, run_loop
.QuitClosure())));
839 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
840 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
841 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
845 // Test in a small scope so that |video_tracks| don't hold on to destroyed
847 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
848 webkit_stream
.videoTracks(video_tracks
);
849 EXPECT_EQ(1u, video_tracks
.size());
852 // Remove the Webrtc video track from the Webrtc MediaStream.
853 scoped_refptr
<webrtc::VideoTrackInterface
> webrtc_track
=
854 remote_stream
->GetVideoTracks()[0].get();
855 remote_stream
->RemoveTrack(webrtc_track
.get());
856 base::RunLoop().RunUntilIdle();
858 blink::WebVector
<blink::WebMediaStreamTrack
> modified_video_tracks1
;
859 webkit_stream
.videoTracks(modified_video_tracks1
);
860 EXPECT_EQ(0u, modified_video_tracks1
.size());
863 blink::WebHeap::collectGarbageForTesting();
865 // Add the WebRtc video track again.
866 remote_stream
->AddTrack(webrtc_track
.get());
867 base::RunLoop().RunUntilIdle();
868 blink::WebVector
<blink::WebMediaStreamTrack
> modified_video_tracks2
;
869 webkit_stream
.videoTracks(modified_video_tracks2
);
870 EXPECT_EQ(1u, modified_video_tracks2
.size());
873 TEST_F(RTCPeerConnectionHandlerTest
, RemoveAndAddTracksFromRemoteStream
) {
874 std::string
remote_stream_label("remote_stream");
875 base::RunLoop run_loop
;
877 // Grab the added media stream when it's been successfully added to the PC.
878 blink::WebMediaStream webkit_stream
;
879 EXPECT_CALL(*mock_client_
.get(), didAddRemoteStream(
880 testing::Property(&blink::WebMediaStream::id
,
881 base::UTF8ToUTF16(remote_stream_label
))))
883 DoAll(SaveArg
<0>(&webkit_stream
),
884 ExitMessageLoop(&message_loop_
, run_loop
.QuitClosure())));
886 scoped_refptr
<webrtc::MediaStreamInterface
> remote_stream(
887 AddRemoteMockMediaStream(remote_stream_label
, "video", "audio"));
888 pc_handler_
->observer()->OnAddStream(remote_stream
.get());
892 // Test in a small scope so that |audio_tracks| don't hold on to destroyed
894 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
895 webkit_stream
.audioTracks(audio_tracks
);
896 EXPECT_EQ(1u, audio_tracks
.size());
897 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
898 webkit_stream
.videoTracks(video_tracks
);
899 EXPECT_EQ(1u, video_tracks
.size());
902 // Remove the Webrtc tracks from the MediaStream.
903 auto audio_track
= remote_stream
->GetAudioTracks()[0];
904 EXPECT_TRUE(remote_stream
->RemoveTrack(audio_track
.get()));
905 auto video_track
= remote_stream
->GetVideoTracks()[0];
906 EXPECT_TRUE(remote_stream
->RemoveTrack(video_track
.get()));
907 base::RunLoop().RunUntilIdle();
910 blink::WebVector
<blink::WebMediaStreamTrack
> modified_audio_tracks
;
911 webkit_stream
.audioTracks(modified_audio_tracks
);
912 EXPECT_EQ(0u, modified_audio_tracks
.size());
913 blink::WebVector
<blink::WebMediaStreamTrack
> modified_video_tracks
;
914 webkit_stream
.videoTracks(modified_video_tracks
);
915 EXPECT_EQ(0u, modified_video_tracks
.size());
918 blink::WebHeap::collectGarbageForTesting();
920 // Add the tracks again.
921 remote_stream
->AddTrack(audio_track
.get());
922 base::RunLoop().RunUntilIdle();
923 remote_stream
->AddTrack(video_track
.get());
924 base::RunLoop().RunUntilIdle();
926 blink::WebHeap::collectGarbageForTesting();
928 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
929 webkit_stream
.audioTracks(audio_tracks
);
930 EXPECT_EQ(1u, audio_tracks
.size());
931 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
932 webkit_stream
.videoTracks(video_tracks
);
933 EXPECT_EQ(1u, video_tracks
.size());
936 TEST_F(RTCPeerConnectionHandlerTest
, OnIceCandidate
) {
937 testing::InSequence sequence
;
938 EXPECT_CALL(*mock_tracker_
.get(),
939 TrackAddIceCandidate(pc_handler_
.get(), _
,
940 PeerConnectionTracker::SOURCE_LOCAL
, true));
941 EXPECT_CALL(*mock_client_
.get(), didGenerateICECandidate(_
));
943 scoped_ptr
<webrtc::IceCandidateInterface
> native_candidate(
944 mock_dependency_factory_
->CreateIceCandidate("sdpMid", 1, kDummySdp
));
945 pc_handler_
->observer()->OnIceCandidate(native_candidate
.get());
946 base::RunLoop().RunUntilIdle();
947 EXPECT_EQ("sdpMid", mock_client_
->candidate_mid());
948 EXPECT_EQ(1, mock_client_
->candidate_mlineindex());
949 EXPECT_EQ(kDummySdp
, mock_client_
->candidate_sdp());
952 TEST_F(RTCPeerConnectionHandlerTest
, OnRenegotiationNeeded
) {
953 testing::InSequence sequence
;
954 EXPECT_CALL(*mock_tracker_
.get(),
955 TrackOnRenegotiationNeeded(pc_handler_
.get()));
956 EXPECT_CALL(*mock_client_
.get(), negotiationNeeded());
957 pc_handler_
->observer()->OnRenegotiationNeeded();
960 TEST_F(RTCPeerConnectionHandlerTest
, CreateDataChannel
) {
961 blink::WebString label
= "d1";
962 EXPECT_CALL(*mock_tracker_
.get(),
963 TrackCreateDataChannel(pc_handler_
.get(),
965 PeerConnectionTracker::SOURCE_LOCAL
));
966 scoped_ptr
<blink::WebRTCDataChannelHandler
> channel(
967 pc_handler_
->createDataChannel("d1", blink::WebRTCDataChannelInit()));
968 EXPECT_TRUE(channel
.get() != NULL
);
969 EXPECT_EQ(label
, channel
->label());
970 channel
->setClient(nullptr);
973 TEST_F(RTCPeerConnectionHandlerTest
, CreateDtmfSender
) {
974 std::string stream_label
= "local_stream";
975 blink::WebMediaStream
local_stream(CreateLocalMediaStream(stream_label
));
976 blink::WebMediaConstraints constraints
;
977 pc_handler_
->addStream(local_stream
, constraints
);
979 blink::WebVector
<blink::WebMediaStreamTrack
> tracks
;
980 local_stream
.videoTracks(tracks
);
982 ASSERT_LE(1ul, tracks
.size());
983 EXPECT_FALSE(pc_handler_
->createDTMFSender(tracks
[0]));
985 local_stream
.audioTracks(tracks
);
986 ASSERT_LE(1ul, tracks
.size());
988 EXPECT_CALL(*mock_tracker_
.get(),
989 TrackCreateDTMFSender(pc_handler_
.get(),
990 testing::Ref(tracks
[0])));
992 scoped_ptr
<blink::WebRTCDTMFSenderHandler
> sender(
993 pc_handler_
->createDTMFSender(tracks
[0]));
994 EXPECT_TRUE(sender
.get());
997 } // namespace content