| // 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<VideoCaptureImplManager> 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<WebKit::WebMediaStreamSource> audio_sources( |
| audio ? static_cast<size_t>(1) : 0); |
| WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources( |
| video ? static_cast<size_t>(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<MediaStreamExtraData*>( |
| 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<MockMediaStreamDispatcher> ms_dispatcher_; |
| scoped_ptr<content::P2PSocketDispatcher> p2p_socket_dispatcher_; |
| scoped_ptr<MediaStreamImplUnderTest> ms_impl_; |
| }; |
| |
| TEST_F(MediaStreamImplTest, CreatePeerConnection) { |
| // Create JSEP PeerConnection. |
| WebKit::MockWebPeerConnection00HandlerClient client_jsep; |
| scoped_ptr<WebKit::WebPeerConnection00Handler> 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<media::MessageLoopFactory> message_loop_factory( |
| new media::MessageLoopFactory()); |
| scoped_refptr<media::VideoDecoder> 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<media::VideoDecoder> 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<media::VideoDecoder> 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()); |
| } |