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 @@
#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"
......@@ -483,6 +484,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;
......@@ -508,6 +511,7 @@ void ProfileIOData::LazyInitialize() const {
resource_context_.set_media_observer(
io_thread_globals->media.media_internals.get());
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());
......
......@@ -36,6 +36,10 @@ namespace fileapi {
class FileSystemContext;
} // namespace fileapi
namespace media_stream {
class MediaStreamManager;
} // namespace media_stream
namespace net {
class CookieStore;
class DnsCertProvenanceChecker;
......@@ -289,6 +293,7 @@ class ProfileIOData {
mutable scoped_refptr<quota::QuotaManager> quota_manager_;
mutable scoped_refptr<HostZoomMap> host_zoom_map_;
mutable DownloadManager::GetNextIdThunkType next_download_id_thunk_;
mutable scoped_ptr<media_stream::MediaStreamManager> media_stream_manager_;
// TODO(willchan): Remove from ResourceContext.
mutable scoped_refptr<ExtensionInfoMap> extension_info_map_;
......
......@@ -362,7 +362,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()));
......@@ -375,7 +376,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()));
......
......@@ -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(
......@@ -36,13 +39,17 @@ void MediaStreamDispatcherHost::OnChannelClosing() {
BrowserMessageFilter::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
// cancel pending requests.
manager()->CancelRequests(this);
for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); it++) {
std::string label = it->first;
manager()->StopGeneratedStream(label);
}
// manager()->CancelRequests(this);
// for (StreamMap::iterator it = streams_.begin();
// it != streams_.end();
// it++) {
// std::string label = it->first;
// manager()->StopGeneratedStream(label);
// }
}
void MediaStreamDispatcherHost::OnGenerateStream(
......
......@@ -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)
......
......@@ -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);
......
......@@ -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();
}
AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
......@@ -126,7 +128,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);
}
}
}
......@@ -151,7 +153,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;
......@@ -360,7 +362,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.
}
......@@ -391,9 +393,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();
......@@ -403,16 +405,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) {
......
......@@ -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"
......@@ -43,11 +44,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();
// Used to access AudioInputDeviceManager.
......@@ -110,13 +110,11 @@ 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
// when not necessary.
......@@ -126,8 +124,6 @@ class MediaStreamManager
typedef std::map<std::string, DeviceRequest> DeviceRequests;
DeviceRequests requests_;
MediaStreamDeviceSettings* device_settings_;
DISALLOW_COPY_AND_ASSIGN(MediaStreamManager);
};
......
......@@ -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(&params_, 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(
......
......@@ -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);
};
......
......@@ -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);
}
......
......@@ -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();
explicit 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);
};
......
......@@ -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();
}
......@@ -337,9 +356,12 @@ 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);
};
......
......@@ -25,8 +25,18 @@ VideoCaptureManager::VideoCaptureManager()
}
VideoCaptureManager::~VideoCaptureManager() {
DCHECK(devices_.empty());
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) {
......
......@@ -209,8 +209,6 @@ TEST_F(VideoCaptureManagerTest, OpenTwo) {
listener_->devices_.begin();
int video_session_id_first = vcm_->Open(*it);
// This should trigger an error callback with error code 'kDeviceAlreadyInUse'
++it;
int video_session_id_second = vcm_->Open(*it);
......@@ -275,4 +273,33 @@ TEST_F(VideoCaptureManagerTest, StartUsingId) {
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
......@@ -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));
}
......@@ -164,6 +165,19 @@ void ResourceContext::set_next_download_id_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)>&
ResourceContext::prerender_manager_getter() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
......
......@@ -21,6 +21,9 @@ class MediaObserver;
namespace fileapi {
class FileSystemContext;
} // namespace fileapi
namespace media_stream {
class MediaStreamManager;
} // namespace media_stream
namespace net {
class HostResolver;
class URLRequestContext;
......@@ -82,6 +85,10 @@ class CONTENT_EXPORT ResourceContext {
void set_next_download_id_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.
......@@ -108,6 +115,7 @@ class CONTENT_EXPORT ResourceContext {
HostZoomMap* host_zoom_map_;
MediaObserver* media_observer_;
DownloadManager::GetNextIdThunkType next_download_id_thunk_;
media_stream::MediaStreamManager* media_stream_manager_;
// Externally-defined data accessible by key.
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