diff options
author | mflodman@chromium.org <mflodman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-14 12:12:26 +0000 |
---|---|---|
committer | mflodman@chromium.org <mflodman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-14 12:12:26 +0000 |
commit | 961695e13deeb7e8a9cde6dec08e145cda98f2d0 (patch) | |
tree | afbf7f4618d2e356cd4a5480aafa18b3f83a61b9 | |
parent | 78774d7afbc951c4cc3fd67a08b33bebbb861375 (diff) | |
download | chromium_src-961695e13deeb7e8a9cde6dec08e145cda98f2d0.zip chromium_src-961695e13deeb7e8a9cde6dec08e145cda98f2d0.tar.gz chromium_src-961695e13deeb7e8a9cde6dec08e145cda98f2d0.tar.bz2 |
Removing singleton property of MediaStreamManager and creating thread first when needed.
BUG=92125
TEST=
Review URL: http://codereview.chromium.org/7649016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101063 0039d316-1c4b-4281-b951-d872f2087c98
15 files changed, 204 insertions, 91 deletions
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 59dd64b..88127fd 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -42,6 +42,7 @@ #include "content/browser/browser_thread.h" #include "content/browser/chrome_blob_storage_context.h" #include "content/browser/host_zoom_map.h" +#include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" #include "content/browser/resource_context.h" @@ -473,6 +474,8 @@ void ProfileIOData::LazyInitialize() const { job_factory_->AddInterceptor(new chromeos::GViewRequestInterceptor); #endif // defined(OS_CHROMEOS) + media_stream_manager_.reset(new media_stream::MediaStreamManager); + // Take ownership over these parameters. database_tracker_ = profile_params_->database_tracker; appcache_service_ = profile_params_->appcache_service; @@ -497,6 +500,7 @@ void ProfileIOData::LazyInitialize() const { resource_context_.SetUserData(NULL, const_cast<ProfileIOData*>(this)); resource_context_.set_media_observer( io_thread_globals->media.media_internals.get()); + resource_context_.set_media_stream_manager(media_stream_manager_.get()); LazyInitializeInternal(profile_params_.get()); diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index 760a06d..3a6f2fc 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h @@ -34,6 +34,10 @@ namespace fileapi { class FileSystemContext; } // namespace fileapi +namespace media_stream { +class MediaStreamManager; +} // namespace media_stream + namespace net { class CookieStore; class DnsCertProvenanceChecker; @@ -281,6 +285,7 @@ class ProfileIOData { mutable scoped_refptr<fileapi::FileSystemContext> file_system_context_; mutable scoped_refptr<quota::QuotaManager> quota_manager_; mutable scoped_refptr<HostZoomMap> host_zoom_map_; + mutable scoped_ptr<media_stream::MediaStreamManager> media_stream_manager_; // TODO(willchan): Remove from ResourceContext. mutable scoped_refptr<ExtensionInfoMap> extension_info_map_; diff --git a/content/browser/renderer_host/browser_render_process_host.cc b/content/browser/renderer_host/browser_render_process_host.cc index e863591..b9bb664 100644 --- a/content/browser/renderer_host/browser_render_process_host.cc +++ b/content/browser/renderer_host/browser_render_process_host.cc @@ -361,7 +361,8 @@ void BrowserRenderProcessHost::CreateMessageFilters() { channel_->AddFilter(new AudioInputRendererHost()); channel_->AddFilter( new AudioRendererHost(&browser_context()->GetResourceContext())); - channel_->AddFilter(new VideoCaptureHost()); + channel_->AddFilter( + new VideoCaptureHost(&browser_context()->GetResourceContext())); channel_->AddFilter( new AppCacheDispatcherHost(browser_context()->GetAppCacheService(), id())); @@ -374,7 +375,8 @@ void BrowserRenderProcessHost::CreateMessageFilters() { GeolocationDispatcherHost::New( id(), browser_context()->GetGeolocationPermissionContext())); channel_->AddFilter(new GpuMessageFilter(id(), widget_helper_.get())); - channel_->AddFilter(new media_stream::MediaStreamDispatcherHost(id())); + channel_->AddFilter(new media_stream::MediaStreamDispatcherHost( + &browser_context()->GetResourceContext(), id())); channel_->AddFilter(new PepperFileMessageFilter(id(), browser_context())); channel_->AddFilter( new PepperMessageFilter(&browser_context()->GetResourceContext())); diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc index 9f7ddb7..9272a7d 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc @@ -4,20 +4,23 @@ #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" +#include "content/browser/resource_context.h" #include "content/common/media/media_stream_messages.h" #include "content/common/media/media_stream_options.h" namespace media_stream { -MediaStreamDispatcherHost::MediaStreamDispatcherHost(int render_process_id) - : render_process_id_(render_process_id) { +MediaStreamDispatcherHost::MediaStreamDispatcherHost( + const content::ResourceContext* resource_context, int render_process_id) + : resource_context_(resource_context), + render_process_id_(render_process_id) { } MediaStreamDispatcherHost::~MediaStreamDispatcherHost() { } MediaStreamManager* MediaStreamDispatcherHost::manager() { - return MediaStreamManager::Get(); + return resource_context_->media_stream_manager(); } bool MediaStreamDispatcherHost::OnMessageReceived( diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/content/browser/renderer_host/media/media_stream_dispatcher_host.h index 3951339..c02d675 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.h +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.h @@ -14,6 +14,10 @@ #include "content/browser/renderer_host/media/media_stream_requester.h" #include "content/common/media/media_stream_options.h" +namespace content { +class ResourceContext; +} // namespace content + namespace media_stream { // MediaStreamDispatcherHost is a delegate for Media Stream API messages used by @@ -23,7 +27,8 @@ class MediaStreamDispatcherHost : public BrowserMessageFilter, public MediaStreamRequester { public: - explicit MediaStreamDispatcherHost(int render_process_id); + MediaStreamDispatcherHost(const content::ResourceContext* resource_context, + int render_process_id); virtual ~MediaStreamDispatcherHost(); // MediaStreamRequester implementation. @@ -54,7 +59,9 @@ class MediaStreamDispatcherHost // creating one if needed. MediaStreamManager* manager(); + const content::ResourceContext* resource_context_; int render_process_id_; + struct StreamRequest { StreamRequest() {} StreamRequest(int render_view_id, int page_request_id) diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index 76eef56..cb311f3 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc @@ -5,9 +5,11 @@ #include <string> #include "base/message_loop.h" +#include "content/browser/mock_resource_context.h" #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/video_capture_manager.h" +#include "content/browser/resource_context.h" #include "content/common/media/media_stream_messages.h" #include "content/common/media/media_stream_options.h" #include "ipc/ipc_message_macros.h" @@ -27,8 +29,9 @@ namespace media_stream { class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost { public: - explicit MockMediaStreamDispatcherHost(MessageLoop* message_loop) - : MediaStreamDispatcherHost(kProcessId), + MockMediaStreamDispatcherHost(content::ResourceContext* resource_context, + MessageLoop* message_loop) + : MediaStreamDispatcherHost(resource_context, kProcessId), message_loop_(message_loop) {} virtual ~MockMediaStreamDispatcherHost() {} @@ -41,9 +44,7 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost { MOCK_METHOD2(OnVideoDeviceFailed, void(int routing_id, int index)); // Accessor to private functions. - void OnGenerateStream( - int page_request_id, - const StreamOptions& components) { + void OnGenerateStream(int page_request_id, const StreamOptions& components) { MediaStreamDispatcherHost::OnGenerateStream(kRenderId, page_request_id, components, @@ -104,8 +105,7 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost { video_devices_ = video_device_list; } - void OnStreamGenerationFailed(const IPC::Message& msg, - int request_id) { + void OnStreamGenerationFailed(const IPC::Message& msg, int request_id) { OnStreamGenerationFailed(msg.routing_id(), request_id); message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); label_= ""; @@ -138,23 +138,64 @@ class MediaStreamDispatcherHostTest : public testing::Test { protected: virtual void SetUp() { - // Create message loop so that - // DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) passes. message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); + // ResourceContext must be created on UI thread. + ui_thread_.reset(new BrowserThread(BrowserThread::UI, message_loop_.get())); + // MediaStreamManager must be created and called on IO thread. io_thread_.reset(new BrowserThread(BrowserThread::IO, message_loop_.get())); - // Make sure the MediaStreamManager exist and use - // fake audio / video devices. - MediaStreamManager* manager = MediaStreamManager::Get(); - manager->UseFakeDevice(); + // Create a MediaStreamManager instance and hand over pointer to + // ResourceContext. + media_stream_manager_.reset(new MediaStreamManager()); + // Make sure we use fake devices to avoid long delays. + media_stream_manager_->UseFakeDevice(); + content::MockResourceContext::GetInstance()->set_media_stream_manager( + media_stream_manager_.get()); - host_ = - new MockMediaStreamDispatcherHost(message_loop_.get()); + host_ = new MockMediaStreamDispatcherHost( + content::MockResourceContext::GetInstance(), message_loop_.get()); + } + + virtual void TearDown() { + content::MockResourceContext::GetInstance()->set_media_stream_manager(NULL); + + // Needed to make sure the manager finishes all tasks on its own thread. + SyncWithVideoCaptureManagerThread(); + } + + // Called on the VideoCaptureManager thread. + static void PostQuitMessageLoop(MessageLoop* message_loop) { + message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); + } + + // Called on the main thread. + static void PostQuitOnVideoCaptureManagerThread( + MessageLoop* message_loop, + media_stream::MediaStreamManager* media_stream_manager) { + media_stream_manager->video_capture_manager()->GetMessageLoop()-> + PostTask(FROM_HERE, + NewRunnableFunction(&PostQuitMessageLoop, message_loop)); + } + + // SyncWithVideoCaptureManagerThread() waits until all pending tasks on the + // video_capture_manager thread are executed while also processing pending + // task in message_loop_ on the current thread. It is used to synchronize + // with the video capture manager thread when we are stopping a video + // capture device. + void SyncWithVideoCaptureManagerThread() { + message_loop_->PostTask( + FROM_HERE, + NewRunnableFunction(&PostQuitOnVideoCaptureManagerThread, + message_loop_.get(), + media_stream_manager_.get())); + message_loop_->Run(); } scoped_refptr<MockMediaStreamDispatcherHost> host_; scoped_ptr<MessageLoop> message_loop_; + scoped_ptr<BrowserThread> ui_thread_; scoped_ptr<BrowserThread> io_thread_; + scoped_ptr<MediaStreamManager> media_stream_manager_; }; TEST_F(MediaStreamDispatcherHostTest, GenerateStream) { @@ -223,7 +264,8 @@ TEST_F(MediaStreamDispatcherHostTest, FailDevice) { EXPECT_CALL(*host_, OnVideoDeviceFailed(kRenderId, 0)); int session_id = host_->video_devices_[0].session_id; - MediaStreamManager::Get()->video_capture_manager()->Error(session_id); + content::MockResourceContext::GetInstance()->media_stream_manager()-> + video_capture_manager()->Error(session_id); WaitForResult(); EXPECT_EQ(host_->video_devices_.size(), 0u); EXPECT_EQ(host_->NumberOfStreams(), 1u); diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index 786cb26..8f17b54 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc @@ -6,7 +6,7 @@ #include <list> -#include "base/lazy_instance.h" +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/rand_util.h" #include "content/browser/browser_thread.h" @@ -17,13 +17,9 @@ namespace media_stream { -// TODO(mflodman) Find out who should own MediaStreamManager. -base::LazyInstance<MediaStreamManager> g_media_stream_manager( - base::LINKER_INITIALIZED); - // Creates a random label used to identify requests. static std::string RandomLabel() { - // Alphbet according to WhatWG standard, i.e. containing 36 characters from + // Alphabet according to WhatWG standard, i.e. containing 36 characters from // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. static const char alphabet[] = "!#$%&\'*+-.0123456789" @@ -49,18 +45,24 @@ static bool Requested(const StreamOptions& options, return false; } -MediaStreamManager* MediaStreamManager::Get() { - return g_media_stream_manager.Pointer(); +MediaStreamManager::MediaStreamManager() + : ALLOW_THIS_IN_INITIALIZER_LIST( + device_settings_(new MediaStreamDeviceSettings(this))), + enumeration_in_progress_(kNumMediaStreamTypes, false) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); } MediaStreamManager::~MediaStreamManager() { - delete device_settings_; - delete video_capture_manager_; + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); } VideoCaptureManager* MediaStreamManager::video_capture_manager() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - return video_capture_manager_; + if (!video_capture_manager_.get()) { + video_capture_manager_.reset(new VideoCaptureManager()); + video_capture_manager_->Register(this); + } + return video_capture_manager_.get(); } void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, @@ -120,7 +122,7 @@ void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { request->video_devices.begin(); it != request->video_devices.end(); ++it) { if (it->in_use == true) { - video_capture_manager_->Close(it->session_id); + video_capture_manager()->Close(it->session_id); } } } @@ -145,7 +147,7 @@ void MediaStreamManager::StopGeneratedStream(const std::string& label) { for (StreamDeviceInfoArray::iterator video_it = it->second.video_devices.begin(); video_it != it->second.video_devices.end(); ++video_it) { - video_capture_manager_->Close(video_it->session_id); + video_capture_manager()->Close(video_it->session_id); } requests_.erase(it); return; @@ -354,7 +356,7 @@ void MediaStreamManager::SettingsError(const std::string& label) { void MediaStreamManager::UseFakeDevice() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - video_capture_manager_->UseFakeDevice(); + video_capture_manager()->UseFakeDevice(); device_settings_->UseFakeUI(); // TODO(mflodman) Add audio manager when available. } @@ -385,9 +387,9 @@ bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { // Called to get media capture device manager of specified type. MediaStreamProvider* MediaStreamManager::GetDeviceManager( - MediaStreamType stream_type) const { + MediaStreamType stream_type) { if (stream_type == kVideoCapture) { - return video_capture_manager_; + return video_capture_manager(); } else if (stream_type == kAudioCapture) { // TODO(mflodman) Add support when audio input manager is available. NOTREACHED(); @@ -397,16 +399,6 @@ MediaStreamProvider* MediaStreamManager::GetDeviceManager( return NULL; } -MediaStreamManager::MediaStreamManager() - : video_capture_manager_(new VideoCaptureManager()), - enumeration_in_progress_(kNumMediaStreamTypes, false), - requests_(), - device_settings_(NULL) { - device_settings_ = new MediaStreamDeviceSettings(this); - video_capture_manager_->Register(this); - // TODO(mflodman) Add when audio input manager is available. -} - MediaStreamManager::DeviceRequest::DeviceRequest() : requester(NULL), state(kNumMediaStreamTypes, kNotRequested) { diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h index f5792ce..50a28d5 100644 --- a/content/browser/renderer_host/media/media_stream_manager.h +++ b/content/browser/renderer_host/media/media_stream_manager.h @@ -23,7 +23,8 @@ #include <string> #include <vector> -#include "base/lazy_instance.h" +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" #include "content/browser/renderer_host/media/media_stream_provider.h" #include "content/browser/renderer_host/media/media_stream_settings_requester.h" #include "content/common/media/media_stream_options.h" @@ -42,11 +43,10 @@ class MediaStreamManager : public MediaStreamProviderListener, public SettingsRequester { public: - typedef MediaStreamManager* (AccessorMethod)(); - static MediaStreamManager* Get(); + MediaStreamManager(); virtual ~MediaStreamManager(); - // Used to access VideoCaptuerManager. + // Used to access VideoCaptureManager. VideoCaptureManager* video_capture_manager(); // GenerateStream opens new media devices according to |components|. The @@ -106,13 +106,10 @@ class MediaStreamManager // Helpers. bool RequestDone(const MediaStreamManager::DeviceRequest& request) const; - MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type) const; - - // Private constructor to enforce singleton. - friend struct base::DefaultLazyInstanceTraits<MediaStreamManager>; - MediaStreamManager(); + MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type); - VideoCaptureManager* video_capture_manager_; + scoped_ptr<MediaStreamDeviceSettings> device_settings_; + scoped_ptr<VideoCaptureManager> video_capture_manager_; // TODO(mflodman) Add AudioInputManager. // Keeps track of device types currently being enumerated to not enumerate @@ -123,8 +120,6 @@ class MediaStreamManager typedef std::map<std::string, DeviceRequest> DeviceRequests; DeviceRequests requests_; - MediaStreamDeviceSettings* device_settings_; - DISALLOW_COPY_AND_ASSIGN(MediaStreamManager); }; diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc index bdad7e0..82dbabb 100644 --- a/content/browser/renderer_host/media/video_capture_controller.cc +++ b/content/browser/renderer_host/media/video_capture_controller.cc @@ -16,11 +16,13 @@ static const size_t kNoOfDIBS = 3; VideoCaptureController::VideoCaptureController( const VideoCaptureControllerID& id, base::ProcessHandle render_process, - VideoCaptureControllerEventHandler* event_handler) + VideoCaptureControllerEventHandler* event_handler, + media_stream::VideoCaptureManager* video_capture_manager) : render_handle_(render_process), report_ready_to_delete_(false), event_handler_(event_handler), - id_(id) { + id_(id), + video_capture_manager_(video_capture_manager) { memset(¶ms_, 0, sizeof(params_)); } @@ -35,21 +37,18 @@ void VideoCaptureController::StartCapture( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); params_ = params; - media_stream::VideoCaptureManager* manager = - media_stream::MediaStreamManager::Get()->video_capture_manager(); // Order the manager to start the actual capture. - manager->Start(params, this); + video_capture_manager_->Start(params, this); } void VideoCaptureController::StopCapture(Task* stopped_task) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - media_stream::VideoCaptureManager* manager = - media_stream::MediaStreamManager::Get()->video_capture_manager(); - manager->Stop(params_.session_id, - NewRunnableMethod(this, - &VideoCaptureController::OnDeviceStopped, - stopped_task)); + video_capture_manager_->Stop( + params_.session_id, + NewRunnableMethod(this, + &VideoCaptureController::OnDeviceStopped, + stopped_task)); } void VideoCaptureController::ReturnBuffer(int buffer_id) { @@ -158,8 +157,7 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data, void VideoCaptureController::OnError() { event_handler_->OnError(id_); - media_stream::MediaStreamManager::Get()->video_capture_manager()-> - Error(params_.session_id); + video_capture_manager_->Error(params_.session_id); } void VideoCaptureController::OnFrameInfo( diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h index 432ac4a..0c760cb 100644 --- a/content/browser/renderer_host/media/video_capture_controller.h +++ b/content/browser/renderer_host/media/video_capture_controller.h @@ -27,13 +27,19 @@ #include "media/video/capture/video_capture_types.h" #include "ui/gfx/surface/transport_dib.h" +namespace media_stream { +class VideoCaptureManager; +} // namespace media_stream + class VideoCaptureController : public base::RefCountedThreadSafe<VideoCaptureController>, public media::VideoCaptureDevice::EventHandler { public: - VideoCaptureController(const VideoCaptureControllerID& id, - base::ProcessHandle render_process, - VideoCaptureControllerEventHandler* event_handler); + VideoCaptureController( + const VideoCaptureControllerID& id, + base::ProcessHandle render_process, + VideoCaptureControllerEventHandler* event_handler, + media_stream::VideoCaptureManager* video_capture_manager); virtual ~VideoCaptureController(); // Starts video capturing and tries to use the resolution specified in @@ -87,6 +93,8 @@ class VideoCaptureController VideoCaptureControllerID id_; media::VideoCaptureDevice::Capability frame_info_; + media_stream::VideoCaptureManager* video_capture_manager_; + DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureController); }; diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc index d3192d6..65be7a3 100644 --- a/content/browser/renderer_host/media/video_capture_host.cc +++ b/content/browser/renderer_host/media/video_capture_host.cc @@ -6,9 +6,14 @@ #include "base/memory/scoped_ptr.h" #include "base/stl_util.h" +#include "content/browser/renderer_host/media/media_stream_manager.h" +#include "content/browser/resource_context.h" #include "content/common/media/video_capture_messages.h" -VideoCaptureHost::VideoCaptureHost() {} +VideoCaptureHost::VideoCaptureHost( + const content::ResourceContext* resource_context) + : resource_context_(resource_context) { +} VideoCaptureHost::~VideoCaptureHost() {} @@ -147,7 +152,9 @@ void VideoCaptureHost::OnStartCapture(int device_id, DCHECK(entries_.find(controller_id) == entries_.end()); scoped_refptr<VideoCaptureController> controller = - new VideoCaptureController(controller_id, peer_handle(), this); + new VideoCaptureController( + controller_id, peer_handle(), this, + resource_context_->media_stream_manager()->video_capture_manager()); entries_.insert(std::make_pair(controller_id, controller)); controller->StartCapture(params); } diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h index 335ee4b..e0c0869 100644 --- a/content/browser/renderer_host/media/video_capture_host.h +++ b/content/browser/renderer_host/media/video_capture_host.h @@ -43,11 +43,15 @@ #include "content/browser/renderer_host/media/video_capture_controller.h" #include "ipc/ipc_message.h" +namespace content { +class ResourceContext; +} // namespace content + class VideoCaptureHost : public BrowserMessageFilter, public VideoCaptureControllerEventHandler { public: - VideoCaptureHost(); + VideoCaptureHost(const content::ResourceContext* resource_context); // BrowserMessageFilter implementation. virtual void OnChannelClosing(); @@ -127,6 +131,9 @@ class VideoCaptureHost // objects that is currently active. EntryMap entries_; + // Used to get a pointer to VideoCaptureManager to start/stop capture devices. + const content::ResourceContext* resource_context_; + DISALLOW_COPY_AND_ASSIGN(VideoCaptureHost); }; diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc index e80266a..8ab1098 100644 --- a/content/browser/renderer_host/media/video_capture_host_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc @@ -12,9 +12,11 @@ #include "base/stl_util.h" #include "base/stringprintf.h" #include "content/browser/browser_thread.h" +#include "content/browser/mock_resource_context.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/video_capture_host.h" #include "content/browser/renderer_host/media/video_capture_manager.h" +#include "content/browser/resource_context.h" #include "content/common/media/video_capture_messages.h" #include "media/video/capture/video_capture_types.h" @@ -66,7 +68,10 @@ class DumpVideo { class MockVideoCaptureHost : public VideoCaptureHost { public: - MockVideoCaptureHost() : return_buffers_(false), dump_video_(false) {} + explicit MockVideoCaptureHost(content::ResourceContext* resource_context) + : VideoCaptureHost(resource_context), + return_buffers_(false), + dump_video_(false) {} virtual ~MockVideoCaptureHost() { STLDeleteContainerPairSecondPointers(filled_dib_.begin(), filled_dib_.end()); @@ -187,14 +192,25 @@ class VideoCaptureHostTest : public testing::Test { virtual void SetUp() { // Create a message loop so VideoCaptureHostTest can use it. message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); + + // ResourceContext must be created on the UI thread. + ui_thread_.reset(new BrowserThread(BrowserThread::UI, message_loop_.get())); + + // MediaStreamManager must be created on the IO thread. io_thread_.reset(new BrowserThread(BrowserThread::IO, message_loop_.get())); - // Setup the VideoCaptureManager to use fake video capture device. + + // Create a MediaStreamManager instance and hand over pointer to + // ResourceContext. + media_stream_manager_.reset(new media_stream::MediaStreamManager()); + #ifndef TEST_REAL_CAPTURE_DEVICE - media_stream::VideoCaptureManager* manager = - media_stream::MediaStreamManager::Get()->video_capture_manager(); - manager->UseFakeDevice(); + media_stream_manager_->UseFakeDevice(); #endif - host_ = new MockVideoCaptureHost(); + + content::MockResourceContext::GetInstance()->set_media_stream_manager( + media_stream_manager_.get()); + host_ = new MockVideoCaptureHost( + content::MockResourceContext::GetInstance()); // Simulate IPC channel connected. host_->OnChannelConnected(base::GetCurrentProcId()); @@ -219,7 +235,7 @@ class VideoCaptureHostTest : public testing::Test { // We need to continue running message_loop_ to complete all destructions. SyncWithVideoCaptureManagerThread(); - io_thread_.reset(); + content::MockResourceContext::GetInstance()->set_media_stream_manager(NULL); } // Called on the VideoCaptureManager thread. @@ -228,8 +244,9 @@ class VideoCaptureHostTest : public testing::Test { } // Called on the main thread. - static void PostQuitOnVideoCaptureManagerThread(MessageLoop* message_loop) { - media_stream::MediaStreamManager::Get()->video_capture_manager()-> + static void PostQuitOnVideoCaptureManagerThread( + MessageLoop* message_loop, content::ResourceContext* resource_context) { + resource_context->media_stream_manager()->video_capture_manager()-> GetMessageLoop()->PostTask(FROM_HERE, NewRunnableFunction( &PostQuitMessageLoop, message_loop)); @@ -242,8 +259,10 @@ class VideoCaptureHostTest : public testing::Test { // capture device. void SyncWithVideoCaptureManagerThread() { message_loop_->PostTask( - FROM_HERE, NewRunnableFunction(&PostQuitOnVideoCaptureManagerThread, - message_loop_.get())); + FROM_HERE, + NewRunnableFunction(&PostQuitOnVideoCaptureManagerThread, + message_loop_.get(), + content::MockResourceContext::GetInstance())); message_loop_->Run(); } @@ -339,7 +358,9 @@ class VideoCaptureHostTest : public testing::Test { scoped_refptr<MockVideoCaptureHost> host_; private: scoped_ptr<MessageLoop> message_loop_; + scoped_ptr<BrowserThread> ui_thread_; scoped_ptr<BrowserThread> io_thread_; + scoped_ptr<media_stream::MediaStreamManager> media_stream_manager_; DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); }; diff --git a/content/browser/resource_context.cc b/content/browser/resource_context.cc index bc3c6d6..f366242 100644 --- a/content/browser/resource_context.cc +++ b/content/browser/resource_context.cc @@ -20,7 +20,8 @@ ResourceContext::ResourceContext() blob_storage_context_(NULL), quota_manager_(NULL), host_zoom_map_(NULL), - media_observer_(NULL) { + media_observer_(NULL), + media_stream_manager_(NULL) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } @@ -152,6 +153,19 @@ void ResourceContext::set_media_observer(MediaObserver* media_observer) { media_observer_ = media_observer; } +media_stream::MediaStreamManager* +ResourceContext::media_stream_manager() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + EnsureInitialized(); + return media_stream_manager_; +} + +void ResourceContext::set_media_stream_manager( + media_stream::MediaStreamManager* media_stream_manager) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + media_stream_manager_ = media_stream_manager; +} + const base::Callback<prerender::PrerenderManager*(void)>& ResourceContext::prerender_manager_getter() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); diff --git a/content/browser/resource_context.h b/content/browser/resource_context.h index f53de50..0c8ad77 100644 --- a/content/browser/resource_context.h +++ b/content/browser/resource_context.h @@ -20,6 +20,9 @@ class MediaObserver; namespace fileapi { class FileSystemContext; } // namespace fileapi +namespace media_stream { +class MediaStreamManager; +} // namespace media_stream namespace net { class HostResolver; class URLRequestContext; @@ -76,6 +79,10 @@ class CONTENT_EXPORT ResourceContext { MediaObserver* media_observer() const; void set_media_observer(MediaObserver* media_observer); + media_stream::MediaStreamManager* media_stream_manager() const; + void set_media_stream_manager( + media_stream::MediaStreamManager* media_stream_manager); + // ======================================================================= // TODO(willchan): These don't belong in content/. Remove them eventually. @@ -101,6 +108,7 @@ class CONTENT_EXPORT ResourceContext { quota::QuotaManager* quota_manager_; HostZoomMap* host_zoom_map_; MediaObserver* media_observer_; + media_stream::MediaStreamManager* media_stream_manager_; // Externally-defined data accessible by key. typedef std::map<const void*, void*> UserDataMap; |