// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/utf_string_conversions.h" #include "content/renderer/media/media_stream_impl.h" #include "content/renderer/media/mock_media_stream_dependency_factory.h" #include "content/renderer/media/mock_media_stream_dispatcher.h" #include "content/renderer/media/mock_web_peer_connection_00_handler_client.h" #include "content/renderer/media/mock_web_peer_connection_handler_client.h" #include "content/renderer/media/peer_connection_handler_jsep.h" #include "content/renderer/media/video_capture_impl_manager.h" #include "content/renderer/p2p/socket_dispatcher.h" #include "media/base/message_loop_factory.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamSource.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnection00Handler.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnectionHandler.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" class MediaStreamImplUnderTest : public MediaStreamImpl { public: MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher, content::P2PSocketDispatcher* p2p_socket_dispatcher, VideoCaptureImplManager* vc_manager, MediaStreamDependencyFactory* dependency_factory) : MediaStreamImpl(NULL, media_stream_dispatcher, p2p_socket_dispatcher, vc_manager, dependency_factory) { } virtual void CompleteGetUserMediaRequest( const WebKit::WebMediaStreamDescriptor& stream, WebKit::WebUserMediaRequest* request) { last_generated_stream_ = stream; } virtual WebKit::WebMediaStreamDescriptor GetMediaStream(const GURL& url) { return last_generated_stream_; } const WebKit::WebMediaStreamDescriptor& last_generated_stream() { return last_generated_stream_; } private: WebKit::WebMediaStreamDescriptor last_generated_stream_; }; class MediaStreamImplTest : public ::testing::Test { public: void SetUp() { // Create our test object. ms_dispatcher_.reset(new MockMediaStreamDispatcher()); p2p_socket_dispatcher_.reset(new content::P2PSocketDispatcher(NULL)); scoped_refptr vc_manager( new VideoCaptureImplManager()); MockMediaStreamDependencyFactory* dependency_factory = new MockMediaStreamDependencyFactory(vc_manager); ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(), p2p_socket_dispatcher_.get(), vc_manager.get(), dependency_factory)); } void TearDown() { // Make sure the message created by // P2PSocketDispatcher::AsyncMessageSender::Send is handled before // tear down to avoid a memory leak. loop_.RunAllPending(); } WebKit::WebMediaStreamDescriptor RequestLocalMediaStream(bool audio, bool video) { WebKit::WebUserMediaRequest user_media_request; WebKit::WebVector audio_sources( audio ? static_cast(1) : 0); WebKit::WebVector video_sources( video ? static_cast(1) : 0); ms_impl_->requestUserMedia(user_media_request, audio_sources, video_sources); ms_impl_->OnStreamGenerated(ms_dispatcher_->request_id(), ms_dispatcher_->stream_label(), ms_dispatcher_->audio_array(), ms_dispatcher_->video_array()); WebKit::WebMediaStreamDescriptor desc = ms_impl_->last_generated_stream(); MediaStreamExtraData* extra_data = static_cast( desc.extraData()); if (!extra_data || !extra_data->local_stream()) { ADD_FAILURE(); return desc; } if (audio) EXPECT_EQ(1u, extra_data->local_stream()->audio_tracks()->count()); if (video) EXPECT_EQ(1u, extra_data->local_stream()->video_tracks()->count()); if (audio && video) { EXPECT_NE(extra_data->local_stream()->audio_tracks()->at(0)->label(), extra_data->local_stream()->video_tracks()->at(0)->label()); } return desc; } protected: MessageLoop loop_; scoped_ptr ms_dispatcher_; scoped_ptr p2p_socket_dispatcher_; scoped_ptr ms_impl_; }; TEST_F(MediaStreamImplTest, CreatePeerConnection) { // Create JSEP PeerConnection. WebKit::MockWebPeerConnection00HandlerClient client_jsep; scoped_ptr pc_handler_jsep( ms_impl_->CreatePeerConnectionHandlerJsep(&client_jsep)); pc_handler_jsep.reset(); } TEST_F(MediaStreamImplTest, LocalMediaStream) { // Test a stream with both audio and video. WebKit::WebMediaStreamDescriptor mixed_desc = RequestLocalMediaStream(true, true); // Create a renderer for the stream. scoped_ptr message_loop_factory( new media::MessageLoopFactory()); scoped_refptr mixed_decoder( ms_impl_->GetVideoDecoder(GURL(), message_loop_factory.get())); EXPECT_TRUE(mixed_decoder.get() != NULL); // Test a stream with audio only. WebKit::WebMediaStreamDescriptor audio_desc = RequestLocalMediaStream(true, false); scoped_refptr audio_decoder( ms_impl_->GetVideoDecoder(GURL(), message_loop_factory.get())); EXPECT_TRUE(audio_decoder.get() == NULL); // Test a stream with video only. WebKit::WebMediaStreamDescriptor video_desc = RequestLocalMediaStream(false, true); scoped_refptr video_decoder( ms_impl_->GetVideoDecoder(GURL(), message_loop_factory.get())); EXPECT_TRUE(video_decoder.get() != NULL); // Stop generated local streams. ms_impl_->StopLocalMediaStream(mixed_desc); EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter()); ms_impl_->StopLocalMediaStream(audio_desc); EXPECT_EQ(2, ms_dispatcher_->stop_stream_counter()); // Test that the MediaStreams are deleted if the owning WebFrame is deleted. // In the unit test the owning frame is NULL. ms_impl_->FrameWillClose(NULL); EXPECT_EQ(3, ms_dispatcher_->stop_stream_counter()); }