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