Commit ab45ceff authored by mflodman@chromium.org's avatar mflodman@chromium.org

Removing singelton property of MediaStreamManager.

This is almost the same patch [1] as was reverted last week due to flakiness in one of the Win tests, but for one change: MediaStreamManager is not called from MediaStreamDispatcherHost::OnChannelClosing, to avoid shut-down crash. This will be changed as soon as the shut-down issue is solved.

[1] http://codereview.chromium.org/7649016/

Review URL: http://codereview.chromium.org/7948004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102255 0039d316-1c4b-4281-b951-d872f2087c98
parent b54b7c6c
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "content/browser/browser_thread.h" #include "content/browser/browser_thread.h"
#include "content/browser/chrome_blob_storage_context.h" #include "content/browser/chrome_blob_storage_context.h"
#include "content/browser/host_zoom_map.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.h"
#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "content/browser/resource_context.h" #include "content/browser/resource_context.h"
...@@ -483,6 +484,8 @@ void ProfileIOData::LazyInitialize() const { ...@@ -483,6 +484,8 @@ void ProfileIOData::LazyInitialize() const {
job_factory_->AddInterceptor(new chromeos::GViewRequestInterceptor); job_factory_->AddInterceptor(new chromeos::GViewRequestInterceptor);
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
media_stream_manager_.reset(new media_stream::MediaStreamManager);
// Take ownership over these parameters. // Take ownership over these parameters.
database_tracker_ = profile_params_->database_tracker; database_tracker_ = profile_params_->database_tracker;
appcache_service_ = profile_params_->appcache_service; appcache_service_ = profile_params_->appcache_service;
...@@ -508,6 +511,7 @@ void ProfileIOData::LazyInitialize() const { ...@@ -508,6 +511,7 @@ void ProfileIOData::LazyInitialize() const {
resource_context_.set_media_observer( resource_context_.set_media_observer(
io_thread_globals->media.media_internals.get()); io_thread_globals->media.media_internals.get());
resource_context_.set_next_download_id_thunk(next_download_id_thunk_); resource_context_.set_next_download_id_thunk(next_download_id_thunk_);
resource_context_.set_media_stream_manager(media_stream_manager_.get());
LazyInitializeInternal(profile_params_.get()); LazyInitializeInternal(profile_params_.get());
......
...@@ -36,6 +36,10 @@ namespace fileapi { ...@@ -36,6 +36,10 @@ namespace fileapi {
class FileSystemContext; class FileSystemContext;
} // namespace fileapi } // namespace fileapi
namespace media_stream {
class MediaStreamManager;
} // namespace media_stream
namespace net { namespace net {
class CookieStore; class CookieStore;
class DnsCertProvenanceChecker; class DnsCertProvenanceChecker;
...@@ -289,6 +293,7 @@ class ProfileIOData { ...@@ -289,6 +293,7 @@ class ProfileIOData {
mutable scoped_refptr<quota::QuotaManager> quota_manager_; mutable scoped_refptr<quota::QuotaManager> quota_manager_;
mutable scoped_refptr<HostZoomMap> host_zoom_map_; mutable scoped_refptr<HostZoomMap> host_zoom_map_;
mutable DownloadManager::GetNextIdThunkType next_download_id_thunk_; mutable DownloadManager::GetNextIdThunkType next_download_id_thunk_;
mutable scoped_ptr<media_stream::MediaStreamManager> media_stream_manager_;
// TODO(willchan): Remove from ResourceContext. // TODO(willchan): Remove from ResourceContext.
mutable scoped_refptr<ExtensionInfoMap> extension_info_map_; mutable scoped_refptr<ExtensionInfoMap> extension_info_map_;
......
...@@ -362,7 +362,8 @@ void BrowserRenderProcessHost::CreateMessageFilters() { ...@@ -362,7 +362,8 @@ void BrowserRenderProcessHost::CreateMessageFilters() {
channel_->AddFilter(new AudioInputRendererHost()); channel_->AddFilter(new AudioInputRendererHost());
channel_->AddFilter( channel_->AddFilter(
new AudioRendererHost(&browser_context()->GetResourceContext())); new AudioRendererHost(&browser_context()->GetResourceContext()));
channel_->AddFilter(new VideoCaptureHost()); channel_->AddFilter(
new VideoCaptureHost(&browser_context()->GetResourceContext()));
channel_->AddFilter( channel_->AddFilter(
new AppCacheDispatcherHost(browser_context()->GetAppCacheService(), new AppCacheDispatcherHost(browser_context()->GetAppCacheService(),
id())); id()));
...@@ -375,7 +376,8 @@ void BrowserRenderProcessHost::CreateMessageFilters() { ...@@ -375,7 +376,8 @@ void BrowserRenderProcessHost::CreateMessageFilters() {
GeolocationDispatcherHost::New( GeolocationDispatcherHost::New(
id(), browser_context()->GetGeolocationPermissionContext())); id(), browser_context()->GetGeolocationPermissionContext()));
channel_->AddFilter(new GpuMessageFilter(id(), widget_helper_.get())); 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 PepperFileMessageFilter(id(), browser_context()));
channel_->AddFilter( channel_->AddFilter(
new PepperMessageFilter(&browser_context()->GetResourceContext())); new PepperMessageFilter(&browser_context()->GetResourceContext()));
......
...@@ -4,20 +4,23 @@ ...@@ -4,20 +4,23 @@
#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" #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_messages.h"
#include "content/common/media/media_stream_options.h" #include "content/common/media/media_stream_options.h"
namespace media_stream { namespace media_stream {
MediaStreamDispatcherHost::MediaStreamDispatcherHost(int render_process_id) MediaStreamDispatcherHost::MediaStreamDispatcherHost(
: render_process_id_(render_process_id) { const content::ResourceContext* resource_context, int render_process_id)
: resource_context_(resource_context),
render_process_id_(render_process_id) {
} }
MediaStreamDispatcherHost::~MediaStreamDispatcherHost() { MediaStreamDispatcherHost::~MediaStreamDispatcherHost() {
} }
MediaStreamManager* MediaStreamDispatcherHost::manager() { MediaStreamManager* MediaStreamDispatcherHost::manager() {
return MediaStreamManager::Get(); return resource_context_->media_stream_manager();
} }
bool MediaStreamDispatcherHost::OnMessageReceived( bool MediaStreamDispatcherHost::OnMessageReceived(
...@@ -36,13 +39,17 @@ void MediaStreamDispatcherHost::OnChannelClosing() { ...@@ -36,13 +39,17 @@ void MediaStreamDispatcherHost::OnChannelClosing() {
BrowserMessageFilter::OnChannelClosing(); BrowserMessageFilter::OnChannelClosing();
VLOG(1) << "MediaStreamDispatcherHost::OnChannelClosing"; VLOG(1) << "MediaStreamDispatcherHost::OnChannelClosing";
// TODO(mflodman) Remove this temporary solution when shut-down issue is
// resolved, i.e. uncomment the code below.
// Since the IPC channel is gone, close all requested VideCaptureDevices and // Since the IPC channel is gone, close all requested VideCaptureDevices and
// cancel pending requests. // cancel pending requests.
manager()->CancelRequests(this); // manager()->CancelRequests(this);
for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); it++) { // for (StreamMap::iterator it = streams_.begin();
std::string label = it->first; // it != streams_.end();
manager()->StopGeneratedStream(label); // it++) {
} // std::string label = it->first;
// manager()->StopGeneratedStream(label);
// }
} }
void MediaStreamDispatcherHost::OnGenerateStream( void MediaStreamDispatcherHost::OnGenerateStream(
......
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
#include "content/browser/renderer_host/media/media_stream_requester.h" #include "content/browser/renderer_host/media/media_stream_requester.h"
#include "content/common/media/media_stream_options.h" #include "content/common/media/media_stream_options.h"
namespace content {
class ResourceContext;
} // namespace content
namespace media_stream { namespace media_stream {
// MediaStreamDispatcherHost is a delegate for Media Stream API messages used by // MediaStreamDispatcherHost is a delegate for Media Stream API messages used by
...@@ -23,7 +27,8 @@ class MediaStreamDispatcherHost ...@@ -23,7 +27,8 @@ class MediaStreamDispatcherHost
: public BrowserMessageFilter, : public BrowserMessageFilter,
public MediaStreamRequester { public MediaStreamRequester {
public: public:
explicit MediaStreamDispatcherHost(int render_process_id); MediaStreamDispatcherHost(const content::ResourceContext* resource_context,
int render_process_id);
virtual ~MediaStreamDispatcherHost(); virtual ~MediaStreamDispatcherHost();
// MediaStreamRequester implementation. // MediaStreamRequester implementation.
...@@ -54,7 +59,9 @@ class MediaStreamDispatcherHost ...@@ -54,7 +59,9 @@ class MediaStreamDispatcherHost
// creating one if needed. // creating one if needed.
MediaStreamManager* manager(); MediaStreamManager* manager();
const content::ResourceContext* resource_context_;
int render_process_id_; int render_process_id_;
struct StreamRequest { struct StreamRequest {
StreamRequest() {} StreamRequest() {}
StreamRequest(int render_view_id, int page_request_id) StreamRequest(int render_view_id, int page_request_id)
......
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
#include <string> #include <string>
#include "base/message_loop.h" #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_dispatcher_host.h"
#include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_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_messages.h"
#include "content/common/media/media_stream_options.h" #include "content/common/media/media_stream_options.h"
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
...@@ -27,8 +29,9 @@ namespace media_stream { ...@@ -27,8 +29,9 @@ namespace media_stream {
class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost { class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost {
public: public:
explicit MockMediaStreamDispatcherHost(MessageLoop* message_loop) MockMediaStreamDispatcherHost(content::ResourceContext* resource_context,
: MediaStreamDispatcherHost(kProcessId), MessageLoop* message_loop)
: MediaStreamDispatcherHost(resource_context, kProcessId),
message_loop_(message_loop) {} message_loop_(message_loop) {}
virtual ~MockMediaStreamDispatcherHost() {} virtual ~MockMediaStreamDispatcherHost() {}
...@@ -41,9 +44,7 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost { ...@@ -41,9 +44,7 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost {
MOCK_METHOD2(OnVideoDeviceFailed, void(int routing_id, int index)); MOCK_METHOD2(OnVideoDeviceFailed, void(int routing_id, int index));
// Accessor to private functions. // Accessor to private functions.
void OnGenerateStream( void OnGenerateStream(int page_request_id, const StreamOptions& components) {
int page_request_id,
const StreamOptions& components) {
MediaStreamDispatcherHost::OnGenerateStream(kRenderId, MediaStreamDispatcherHost::OnGenerateStream(kRenderId,
page_request_id, page_request_id,
components, components,
...@@ -104,8 +105,7 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost { ...@@ -104,8 +105,7 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost {
video_devices_ = video_device_list; video_devices_ = video_device_list;
} }
void OnStreamGenerationFailed(const IPC::Message& msg, void OnStreamGenerationFailed(const IPC::Message& msg, int request_id) {
int request_id) {
OnStreamGenerationFailed(msg.routing_id(), request_id); OnStreamGenerationFailed(msg.routing_id(), request_id);
message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
label_= ""; label_= "";
...@@ -138,23 +138,64 @@ class MediaStreamDispatcherHostTest : public testing::Test { ...@@ -138,23 +138,64 @@ class MediaStreamDispatcherHostTest : public testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
// Create message loop so that
// DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) passes.
message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); 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())); io_thread_.reset(new BrowserThread(BrowserThread::IO, message_loop_.get()));
// Make sure the MediaStreamManager exist and use // Create a MediaStreamManager instance and hand over pointer to
// fake audio / video devices. // ResourceContext.
MediaStreamManager* manager = MediaStreamManager::Get(); media_stream_manager_.reset(new MediaStreamManager());
manager->UseFakeDevice(); // 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_ = host_ = new MockMediaStreamDispatcherHost(
new MockMediaStreamDispatcherHost(message_loop_.get()); 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_refptr<MockMediaStreamDispatcherHost> host_;
scoped_ptr<MessageLoop> message_loop_; scoped_ptr<MessageLoop> message_loop_;
scoped_ptr<BrowserThread> ui_thread_;
scoped_ptr<BrowserThread> io_thread_; scoped_ptr<BrowserThread> io_thread_;
scoped_ptr<MediaStreamManager> media_stream_manager_;
}; };
TEST_F(MediaStreamDispatcherHostTest, GenerateStream) { TEST_F(MediaStreamDispatcherHostTest, GenerateStream) {
...@@ -223,7 +264,8 @@ TEST_F(MediaStreamDispatcherHostTest, FailDevice) { ...@@ -223,7 +264,8 @@ TEST_F(MediaStreamDispatcherHostTest, FailDevice) {
EXPECT_CALL(*host_, OnVideoDeviceFailed(kRenderId, 0)); EXPECT_CALL(*host_, OnVideoDeviceFailed(kRenderId, 0));
int session_id = host_->video_devices_[0].session_id; 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(); WaitForResult();
EXPECT_EQ(host_->video_devices_.size(), 0u); EXPECT_EQ(host_->video_devices_.size(), 0u);
EXPECT_EQ(host_->NumberOfStreams(), 1u); EXPECT_EQ(host_->NumberOfStreams(), 1u);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <list> #include <list>
#include "base/lazy_instance.h" #include "base/compiler_specific.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "content/browser/browser_thread.h" #include "content/browser/browser_thread.h"
...@@ -17,13 +17,9 @@ ...@@ -17,13 +17,9 @@
namespace media_stream { 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. // Creates a random label used to identify requests.
static std::string RandomLabel() { 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, // 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. // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E.
static const char alphabet[] = "!#$%&\'*+-.0123456789" static const char alphabet[] = "!#$%&\'*+-.0123456789"
...@@ -49,18 +45,24 @@ static bool Requested(const StreamOptions& options, ...@@ -49,18 +45,24 @@ static bool Requested(const StreamOptions& options,
return false; return false;
} }
MediaStreamManager* MediaStreamManager::Get() { MediaStreamManager::MediaStreamManager()
return g_media_stream_manager.Pointer(); : ALLOW_THIS_IN_INITIALIZER_LIST(
device_settings_(new MediaStreamDeviceSettings(this))),
enumeration_in_progress_(kNumMediaStreamTypes, false) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
} }
MediaStreamManager::~MediaStreamManager() { MediaStreamManager::~MediaStreamManager() {
delete device_settings_; DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
delete video_capture_manager_;
} }
VideoCaptureManager* MediaStreamManager::video_capture_manager() { VideoCaptureManager* MediaStreamManager::video_capture_manager() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 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();
} }
AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
...@@ -126,7 +128,7 @@ void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { ...@@ -126,7 +128,7 @@ void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) {
request->video_devices.begin(); it != request->video_devices.end(); request->video_devices.begin(); it != request->video_devices.end();
++it) { ++it) {
if (it->in_use == true) { if (it->in_use == true) {
video_capture_manager_->Close(it->session_id); video_capture_manager()->Close(it->session_id);
} }
} }
} }
...@@ -151,7 +153,7 @@ void MediaStreamManager::StopGeneratedStream(const std::string& label) { ...@@ -151,7 +153,7 @@ void MediaStreamManager::StopGeneratedStream(const std::string& label) {
for (StreamDeviceInfoArray::iterator video_it = for (StreamDeviceInfoArray::iterator video_it =
it->second.video_devices.begin(); it->second.video_devices.begin();
video_it != it->second.video_devices.end(); ++video_it) { 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); requests_.erase(it);
return; return;
...@@ -360,7 +362,7 @@ void MediaStreamManager::SettingsError(const std::string& label) { ...@@ -360,7 +362,7 @@ void MediaStreamManager::SettingsError(const std::string& label) {
void MediaStreamManager::UseFakeDevice() { void MediaStreamManager::UseFakeDevice() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
video_capture_manager_->UseFakeDevice(); video_capture_manager()->UseFakeDevice();
device_settings_->UseFakeUI(); device_settings_->UseFakeUI();
// TODO(mflodman): Add audio manager when available. // TODO(mflodman): Add audio manager when available.
} }
...@@ -391,9 +393,9 @@ bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { ...@@ -391,9 +393,9 @@ bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
// Called to get media capture device manager of specified type. // Called to get media capture device manager of specified type.
MediaStreamProvider* MediaStreamManager::GetDeviceManager( MediaStreamProvider* MediaStreamManager::GetDeviceManager(
MediaStreamType stream_type) const { MediaStreamType stream_type) {
if (stream_type == kVideoCapture) { if (stream_type == kVideoCapture) {
return video_capture_manager_; return video_capture_manager();
} else if (stream_type == kAudioCapture) { } else if (stream_type == kAudioCapture) {
// TODO(mflodman): Add support when audio input manager is available. // TODO(mflodman): Add support when audio input manager is available.
NOTREACHED(); NOTREACHED();
...@@ -403,16 +405,6 @@ MediaStreamProvider* MediaStreamManager::GetDeviceManager( ...@@ -403,16 +405,6 @@ MediaStreamProvider* MediaStreamManager::GetDeviceManager(
return NULL; 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() MediaStreamManager::DeviceRequest::DeviceRequest()
: requester(NULL), : requester(NULL),
state(kNumMediaStreamTypes, kNotRequested) { state(kNumMediaStreamTypes, kNotRequested) {
......
...@@ -23,7 +23,8 @@ ...@@ -23,7 +23,8 @@
#include <string> #include <string>
#include <vector> #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_provider.h"
#include "content/browser/renderer_host/media/media_stream_settings_requester.h" #include "content/browser/renderer_host/media/media_stream_settings_requester.h"
#include "content/common/media/media_stream_options.h" #include "content/common/media/media_stream_options.h"
...@@ -43,11 +44,10 @@ class MediaStreamManager ...@@ -43,11 +44,10 @@ class MediaStreamManager
: public MediaStreamProviderListener, : public MediaStreamProviderListener,
public SettingsRequester { public SettingsRequester {
public: public:
typedef MediaStreamManager* (AccessorMethod)(); MediaStreamManager();
static MediaStreamManager* Get();
virtual ~MediaStreamManager(); virtual ~MediaStreamManager();
// Used to access VideoCaptuerManager. // Used to access VideoCaptureManager.
VideoCaptureManager* video_capture_manager(); VideoCaptureManager* video_capture_manager();
// Used to access AudioInputDeviceManager. // Used to access AudioInputDeviceManager.
...@@ -110,13 +110,11 @@ class MediaStreamManager ...@@ -110,13 +110,11 @@ class MediaStreamManager
// Helpers. // Helpers.
bool RequestDone(const MediaStreamManager::DeviceRequest& request) const; bool RequestDone(const MediaStreamManager::DeviceRequest& request) const;
MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type) const; MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type);
// Private constructor to enforce singleton.
friend struct base::DefaultLazyInstanceTraits<MediaStreamManager>;
MediaStreamManager();
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 // Keeps track of device types currently being enumerated to not enumerate
// when not necessary. // when not necessary.
...@@ -126,8 +124,6 @@ class MediaStreamManager ...@@ -126,8 +124,6 @@ class MediaStreamManager
typedef std::map<std::string, DeviceRequest> DeviceRequests; typedef std::map<std::string, DeviceRequest> DeviceRequests;
DeviceRequests requests_; DeviceRequests requests_;
MediaStreamDeviceSettings* device_settings_;
DISALLOW_COPY_AND_ASSIGN(MediaStreamManager); DISALLOW_COPY_AND_ASSIGN(MediaStreamManager);
}; };
......
...@@ -16,11 +16,13 @@ static const size_t kNoOfDIBS = 3; ...@@ -16,11 +16,13 @@ static const size_t kNoOfDIBS = 3;
VideoCaptureController::VideoCaptureController( VideoCaptureController::VideoCaptureController(
const VideoCaptureControllerID& id, const VideoCaptureControllerID& id,
base::ProcessHandle render_process, base::ProcessHandle render_process,
VideoCaptureControllerEventHandler* event_handler) VideoCaptureControllerEventHandler* event_handler,
media_stream::VideoCaptureManager* video_capture_manager)
: render_handle_(render_process), : render_handle_(render_process),
report_ready_to_delete_(false), report_ready_to_delete_(false),
event_handler_(event_handler), event_handler_(event_handler),
id_(id) { id_(id),
video_capture_manager_(video_capture_manager) {
memset(&params_, 0, sizeof(params_)); memset(&params_, 0, sizeof(params_));
} }
...@@ -35,21 +37,18 @@ void VideoCaptureController::StartCapture( ...@@ -35,21 +37,18 @@ void VideoCaptureController::StartCapture(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
params_ = params; params_ = params;
media_stream::VideoCaptureManager* manager =
media_stream::MediaStreamManager::Get()->video_capture_manager();
// Order the manager to start the actual capture. // Order the manager to start the actual capture.
manager->Start(params, this); video_capture_manager_->Start(params, this);
} }
void VideoCaptureController::StopCapture(Task* stopped_task) { void VideoCaptureController::StopCapture(Task* stopped_task) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
media_stream::VideoCaptureManager* manager = video_capture_manager_->Stop(
media_stream::MediaStreamManager::Get()->video_capture_manager(); params_.session_id,
manager->Stop(params_.session_id, NewRunnableMethod(this,
NewRunnableMethod(this, &VideoCaptureController::OnDeviceStopped,
&VideoCaptureController::OnDeviceStopped, stopped_task));
stopped_task));
} }
void VideoCaptureController::ReturnBuffer(int buffer_id) { void VideoCaptureController::ReturnBuffer(int buffer_id) {
...@@ -158,8 +157,7 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data, ...@@ -158,8 +157,7 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
void VideoCaptureController::OnError() { void VideoCaptureController::OnError() {
event_handler_->OnError(id_); event_handler_->OnError(id_);
media_stream::MediaStreamManager::Get()->video_capture_manager()-> video_capture_manager_->Error(params_.session_id);
Error(params_.session_id);
} }
void VideoCaptureController::OnFrameInfo( void VideoCaptureController::OnFrameInfo(
......
...@@ -27,13 +27,19 @@ ...@@ -27,13 +27,19 @@
#include "media/video/capture/video_capture_types.h" #include "media/video/capture/video_capture_types.h"
#include "ui/gfx/surface/transport_dib.h" #include "ui/gfx/surface/transport_dib.h"
namespace media_stream {
class VideoCaptureManager;
} // namespace media_stream
class VideoCaptureController class VideoCaptureController
: public base::RefCountedThreadSafe<VideoCaptureController>, : public base::RefCountedThreadSafe<VideoCaptureController>,
public media::VideoCaptureDevice::EventHandler { public media::VideoCaptureDevice::EventHandler {
public: public:
VideoCaptureController(const VideoCaptureControllerID& id, VideoCaptureController(
base::ProcessHandle render_process, const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler); base::ProcessHandle render_process,
VideoCaptureControllerEventHandler* event_handler,
media_stream::VideoCaptureManager* video_capture_manager);
virtual ~VideoCaptureController(); virtual ~VideoCaptureController();
// Starts video capturing and tries to use the resolution specified in // Starts video capturing and tries to use the resolution specified in
...@@ -87,6 +93,8 @@ class VideoCaptureController ...@@ -87,6 +93,8 @@ class VideoCaptureController
VideoCaptureControllerID id_; VideoCaptureControllerID id_;
media::VideoCaptureDevice::Capability frame_info_; media::VideoCaptureDevice::Capability frame_info_;
media_stream::VideoCaptureManager* video_capture_manager_;
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureController); DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureController);
}; };
......
...@@ -6,9 +6,14 @@ ...@@ -6,9 +6,14 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/stl_util.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" #include "content/common/media/video_capture_messages.h"
VideoCaptureHost::VideoCaptureHost() {} VideoCaptureHost::VideoCaptureHost(
const content::ResourceContext* resource_context)
: resource_context_(resource_context) {
}
VideoCaptureHost::~VideoCaptureHost() {} VideoCaptureHost::~VideoCaptureHost() {}
...@@ -147,7 +152,9 @@ void VideoCaptureHost::OnStartCapture(int device_id, ...@@ -147,7 +152,9 @@ void VideoCaptureHost::OnStartCapture(int device_id,
DCHECK(entries_.find(controller_id) == entries_.end()); DCHECK(entries_.find(controller_id) == entries_.end());
scoped_refptr<VideoCaptureController> controller = 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)); entries_.insert(std::make_pair(controller_id, controller));
controller->StartCapture(params); controller->StartCapture(params);
} }
......
...@@ -43,11 +43,15 @@ ...@@ -43,11 +43,15 @@
#include "content/browser/renderer_host/media/video_capture_controller.h" #include "content/browser/renderer_host/media/video_capture_controller.h"
#include "ipc/ipc_message.h" #include "ipc/ipc_message.h"
namespace content {
class ResourceContext;
} // namespace content
class VideoCaptureHost class VideoCaptureHost
: public BrowserMessageFilter, : public BrowserMessageFilter,
public VideoCaptureControllerEventHandler { public VideoCaptureControllerEventHandler {
public: public:
VideoCaptureHost(); explicit VideoCaptureHost(const content::ResourceContext* resource_context);
// BrowserMessageFilter implementation. // BrowserMessageFilter implementation.
virtual void OnChannelClosing(); virtual void OnChannelClosing();
...@@ -127,6 +131,9 @@ class VideoCaptureHost ...@@ -127,6 +131,9 @@ class VideoCaptureHost
// objects that is currently active. // objects that is currently active.
EntryMap entries_; EntryMap entries_;
// Used to get a pointer to VideoCaptureManager to start/stop capture devices.
const content::ResourceContext* resource_context_;
DISALLOW_COPY_AND_ASSIGN(VideoCaptureHost); DISALLOW_COPY_AND_ASSIGN(VideoCaptureHost);
}; };
......
...@@ -12,9 +12,11 @@ ...@@ -12,9 +12,11 @@
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/stringprintf.h" #include "base/stringprintf.h"
#include "content/browser/browser_thread.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/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_host.h" #include "content/browser/renderer_host/media/video_capture_host.h"
#include "content/browser/renderer_host/media/video_capture_manager.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 "content/common/media/video_capture_messages.h"
#include "media/video/capture/video_capture_types.h" #include "media/video/capture/video_capture_types.h"
...@@ -66,7 +68,10 @@ class DumpVideo { ...@@ -66,7 +68,10 @@ class DumpVideo {
class MockVideoCaptureHost : public VideoCaptureHost { class MockVideoCaptureHost : public VideoCaptureHost {
public: 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() { virtual ~MockVideoCaptureHost() {
STLDeleteContainerPairSecondPointers(filled_dib_.begin(), STLDeleteContainerPairSecondPointers(filled_dib_.begin(),
filled_dib_.end()); filled_dib_.end());
...@@ -187,14 +192,25 @@ class VideoCaptureHostTest : public testing::Test { ...@@ -187,14 +192,25 @@ class VideoCaptureHostTest : public testing::Test {
virtual void SetUp() { virtual void SetUp() {
// Create a message loop so VideoCaptureHostTest can use it. // Create a message loop so VideoCaptureHostTest can use it.
message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); 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())); 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 #ifndef TEST_REAL_CAPTURE_DEVICE
media_stream::VideoCaptureManager* manager = media_stream_manager_->UseFakeDevice();
media_stream::MediaStreamManager::Get()->video_capture_manager();
manager->UseFakeDevice();
#endif #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. // Simulate IPC channel connected.
host_->OnChannelConnected(base::GetCurrentProcId()); host_->OnChannelConnected(base::GetCurrentProcId());
...@@ -219,7 +235,7 @@ class VideoCaptureHostTest : public testing::Test { ...@@ -219,7 +235,7 @@ class VideoCaptureHostTest : public testing::Test {
// We need to continue running message_loop_ to complete all destructions. // We need to continue running message_loop_ to complete all destructions.
SyncWithVideoCaptureManagerThread(); SyncWithVideoCaptureManagerThread();
io_thread_.reset(); content::MockResourceContext::GetInstance()->set_media_stream_manager(NULL);
} }
// Called on the VideoCaptureManager thread. // Called on the VideoCaptureManager thread.
...@@ -228,8 +244,9 @@ class VideoCaptureHostTest : public testing::Test { ...@@ -228,8 +244,9 @@ class VideoCaptureHostTest : public testing::Test {
} }
// Called on the main thread. // Called on the main thread.
static void PostQuitOnVideoCaptureManagerThread(MessageLoop* message_loop) { static void PostQuitOnVideoCaptureManagerThread(
media_stream::MediaStreamManager::Get()->video_capture_manager()-> MessageLoop* message_loop, content::ResourceContext* resource_context) {
resource_context->media_stream_manager()->video_capture_manager()->
GetMessageLoop()->PostTask(FROM_HERE, GetMessageLoop()->PostTask(FROM_HERE,
NewRunnableFunction( NewRunnableFunction(
&PostQuitMessageLoop, message_loop)); &PostQuitMessageLoop, message_loop));
...@@ -242,8 +259,10 @@ class VideoCaptureHostTest : public testing::Test { ...@@ -242,8 +259,10 @@ class VideoCaptureHostTest : public testing::Test {
// capture device. // capture device.
void SyncWithVideoCaptureManagerThread() { void SyncWithVideoCaptureManagerThread() {
message_loop_->PostTask( message_loop_->PostTask(
FROM_HERE, NewRunnableFunction(&PostQuitOnVideoCaptureManagerThread, FROM_HERE,
message_loop_.get())); NewRunnableFunction(&PostQuitOnVideoCaptureManagerThread,
message_loop_.get(),
content::MockResourceContext::GetInstance()));
message_loop_->Run(); message_loop_->Run();
} }
...@@ -337,9 +356,12 @@ class VideoCaptureHostTest : public testing::Test { ...@@ -337,9 +356,12 @@ class VideoCaptureHostTest : public testing::Test {
} }
scoped_refptr<MockVideoCaptureHost> host_; scoped_refptr<MockVideoCaptureHost> host_;
private: private:
scoped_ptr<MessageLoop> message_loop_; scoped_ptr<MessageLoop> message_loop_;
scoped_ptr<BrowserThread> ui_thread_;
scoped_ptr<BrowserThread> io_thread_; scoped_ptr<BrowserThread> io_thread_;
scoped_ptr<media_stream::MediaStreamManager> media_stream_manager_;
DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest);
}; };
......
...@@ -25,8 +25,18 @@ VideoCaptureManager::VideoCaptureManager() ...@@ -25,8 +25,18 @@ VideoCaptureManager::VideoCaptureManager()
} }
VideoCaptureManager::~VideoCaptureManager() { VideoCaptureManager::~VideoCaptureManager() {
DCHECK(devices_.empty());
vc_device_thread_.Stop(); vc_device_thread_.Stop();
// TODO(mflodman) Remove this temporary solution when shut-down issue is
// resolved, i.e. all code below this comment.
// Temporary solution: close all open devices and delete them, after the
// thread is stopped.
DLOG_IF(ERROR, !devices_.empty()) << "VideoCaptureManager: Open devices!";
for (VideoCaptureDevices::iterator it = devices_.begin();
it != devices_.end();
++it) {
it->second->DeAllocate();
delete it->second;
}
} }
void VideoCaptureManager::Register(MediaStreamProviderListener* listener) { void VideoCaptureManager::Register(MediaStreamProviderListener* listener) {
......
...@@ -209,8 +209,6 @@ TEST_F(VideoCaptureManagerTest, OpenTwo) { ...@@ -209,8 +209,6 @@ TEST_F(VideoCaptureManagerTest, OpenTwo) {
listener_->devices_.begin(); listener_->devices_.begin();
int video_session_id_first = vcm_->Open(*it); int video_session_id_first = vcm_->Open(*it);
// This should trigger an error callback with error code 'kDeviceAlreadyInUse'
++it; ++it;
int video_session_id_second = vcm_->Open(*it); int video_session_id_second = vcm_->Open(*it);
...@@ -275,4 +273,33 @@ TEST_F(VideoCaptureManagerTest, StartUsingId) { ...@@ -275,4 +273,33 @@ TEST_F(VideoCaptureManagerTest, StartUsingId) {
vcm_->Unregister(); vcm_->Unregister();
} }
// TODO(mflodman) Remove test case below when shut-down bug is resolved, this is
// only to verify this temporary solution is ok in regards to the
// VideoCaptureManager.
// Open the devices and delete manager.
TEST_F(VideoCaptureManagerTest, DeleteManager) {
InSequence s;
EXPECT_CALL(*listener_, DevicesEnumerated(_))
.Times(1);
EXPECT_CALL(*listener_, Opened(media_stream::kVideoCapture, _))
.Times(2);
vcm_->EnumerateDevices();
// Wait to get device callback...
SyncWithVideoCaptureManagerThread();
media_stream::StreamDeviceInfoArray::iterator it =
listener_->devices_.begin();
vcm_->Open(*it);
++it;
vcm_->Open(*it);
// Wait to check callbacks before removing the listener
SyncWithVideoCaptureManagerThread();
// Delete the manager.
vcm_.reset();
}
} // namespace } // namespace
...@@ -20,7 +20,8 @@ ResourceContext::ResourceContext() ...@@ -20,7 +20,8 @@ ResourceContext::ResourceContext()
blob_storage_context_(NULL), blob_storage_context_(NULL),
quota_manager_(NULL), quota_manager_(NULL),
host_zoom_map_(NULL), host_zoom_map_(NULL),
media_observer_(NULL) { media_observer_(NULL),
media_stream_manager_(NULL) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
} }
...@@ -164,6 +165,19 @@ void ResourceContext::set_next_download_id_thunk( ...@@ -164,6 +165,19 @@ void ResourceContext::set_next_download_id_thunk(
next_download_id_thunk_ = thunk; next_download_id_thunk_ = thunk;
} }
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)>& const base::Callback<prerender::PrerenderManager*(void)>&
ResourceContext::prerender_manager_getter() const { ResourceContext::prerender_manager_getter() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
......
...@@ -21,6 +21,9 @@ class MediaObserver; ...@@ -21,6 +21,9 @@ class MediaObserver;
namespace fileapi { namespace fileapi {
class FileSystemContext; class FileSystemContext;
} // namespace fileapi } // namespace fileapi
namespace media_stream {
class MediaStreamManager;
} // namespace media_stream
namespace net { namespace net {
class HostResolver; class HostResolver;
class URLRequestContext; class URLRequestContext;
...@@ -82,6 +85,10 @@ class CONTENT_EXPORT ResourceContext { ...@@ -82,6 +85,10 @@ class CONTENT_EXPORT ResourceContext {
void set_next_download_id_thunk( void set_next_download_id_thunk(
const DownloadManager::GetNextIdThunkType& thunk); const DownloadManager::GetNextIdThunkType& thunk);
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. // TODO(willchan): These don't belong in content/. Remove them eventually.
...@@ -108,6 +115,7 @@ class CONTENT_EXPORT ResourceContext { ...@@ -108,6 +115,7 @@ class CONTENT_EXPORT ResourceContext {
HostZoomMap* host_zoom_map_; HostZoomMap* host_zoom_map_;
MediaObserver* media_observer_; MediaObserver* media_observer_;
DownloadManager::GetNextIdThunkType next_download_id_thunk_; DownloadManager::GetNextIdThunkType next_download_id_thunk_;
media_stream::MediaStreamManager* media_stream_manager_;
// Externally-defined data accessible by key. // Externally-defined data accessible by key.
typedef std::map<const void*, void*> UserDataMap; typedef std::map<const void*, void*> UserDataMap;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment