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