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 46static const char kDummySdp[] = "dummy sdp"; 47static const char kDummySdpType[] = "dummy type"; 48 49using blink::WebRTCPeerConnectionHandlerClient; 50using testing::NiceMock; 51using testing::_; 52using testing::Ref; 53 54namespace content { 55 56class MockRTCStatsResponse : public LocalRTCStatsResponse { 57 public: 58 MockRTCStatsResponse() 59 : report_count_(0), 60 statistic_count_(0) { 61 } 62 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 70 virtual void addStatistic(size_t report, 71 blink::WebString name, blink::WebString value) 72 OVERRIDE { 73 ++statistic_count_; 74 } 75 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 83class MockRTCStatsRequest : public LocalRTCStatsRequest { 84 public: 85 MockRTCStatsRequest() 86 : has_selector_(false), 87 request_succeeded_called_(false) {} 88 89 virtual bool hasSelector() const OVERRIDE { 90 return has_selector_; 91 } 92 virtual blink::WebMediaStreamTrack component() const OVERRIDE { 93 return component_; 94 } 95 virtual scoped_refptr<LocalRTCStatsResponse> createResponse() OVERRIDE { 96 DCHECK(!response_.get()); 97 response_ = new rtc::RefCountedObject<MockRTCStatsResponse>(); 98 return response_; 99 } 100 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. 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. 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 129class 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 187class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler { 188 public: 189 RTCPeerConnectionHandlerUnderTest( 190 WebRTCPeerConnectionHandlerClient* client, 191 PeerConnectionDependencyFactory* dependency_factory) 192 : RTCPeerConnectionHandler(client, dependency_factory) { 193 } 194 195 MockPeerConnectionImpl* native_peer_connection() { 196 return static_cast<MockPeerConnectionImpl*>( 197 RTCPeerConnectionHandler::native_peer_connection()); 198 } 199}; 200 201class RTCPeerConnectionHandlerTest : public ::testing::Test { 202 public: 203 RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL) { 204 child_process_.reset(new ChildProcess()); 205 } 206 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 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. 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> 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 310TEST_F(RTCPeerConnectionHandlerTest, Destruct) { 311 EXPECT_CALL(*mock_tracker_.get(), UnregisterPeerConnection(pc_handler_.get())) 312 .Times(1); 313 pc_handler_.reset(NULL); 314} 315 316TEST_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 329TEST_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 341TEST_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 364TEST_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 388TEST_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 399TEST_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 414TEST_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 441TEST_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 471TEST_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 480TEST_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 490TEST_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 506TEST_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 523TEST_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 542TEST_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 587TEST_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 648TEST_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 682TEST_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. 711TEST_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 744TEST_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 783TEST_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 821TEST_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 836TEST_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 844TEST_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 856TEST_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