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