Index: content/browser/renderer_host/media/media_stream_manager.cc |
=================================================================== |
--- content/browser/renderer_host/media/media_stream_manager.cc (revision 150592) |
+++ content/browser/renderer_host/media/media_stream_manager.cc (working copy) |
@@ -47,10 +47,14 @@ |
// Helper to verify if a media stream type is part of options or not. |
static bool Requested(const StreamOptions& options, |
MediaStreamType stream_type) { |
- return (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && |
- options.video) || |
- (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && |
- options.audio); |
+ if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && |
+ options.video) { |
+ return true; |
+ } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && |
+ options.audio) { |
+ return true; |
+ } |
+ return false; |
} |
DeviceThread::DeviceThread(const char* name) |
@@ -74,24 +78,24 @@ |
// TODO(xians): Merge DeviceRequest with MediaStreamRequest. |
struct MediaStreamManager::DeviceRequest { |
enum RequestState { |
- STATE_NOT_REQUESTED = 0, |
- STATE_REQUESTED, |
- STATE_PENDING_APPROVAL, |
- STATE_OPENING, |
- STATE_DONE, |
- STATE_ERROR |
+ kNotRequested = 0, |
+ kRequested, |
+ kPendingApproval, |
+ kOpening, |
+ kDone, |
+ kError |
}; |
enum RequestType { |
- GENERATE_STREAM = 0, |
- ENUMERATE_DEVICES, |
- OPEN_DEVICE |
+ kGenerateStream = 0, |
+ kEnumerateDevices, |
+ kOpenDevice |
}; |
DeviceRequest() |
: requester(NULL), |
- state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), |
- type(GENERATE_STREAM), |
+ state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested), |
+ type(kGenerateStream), |
render_process_id(-1), |
render_view_id(-1) { |
options.audio = false; |
@@ -105,8 +109,8 @@ |
const GURL& request_security_origin) |
: requester(requester), |
options(request_options), |
- state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), |
- type(GENERATE_STREAM), |
+ state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested), |
+ type(kGenerateStream), |
render_process_id(render_process_id), |
render_view_id(render_view_id), |
security_origin(request_security_origin) { |
@@ -127,13 +131,6 @@ |
StreamDeviceInfoArray video_devices; |
}; |
-MediaStreamManager::EnumerationCache::EnumerationCache() |
- : valid(false) { |
-} |
- |
-MediaStreamManager::EnumerationCache::~EnumerationCache() { |
-} |
- |
MediaStreamManager::MediaStreamManager( |
AudioInputDeviceManager* audio_input_device_manager, |
VideoCaptureManager* video_capture_manager) |
@@ -141,10 +138,8 @@ |
device_settings_(new MediaStreamDeviceSettings(this))), |
audio_input_device_manager_(audio_input_device_manager), |
video_capture_manager_(video_capture_manager), |
- monitoring_started_(false), |
+ enumeration_in_progress_(content::NUM_MEDIA_STREAM_DEVICE_TYPES, false), |
io_loop_(NULL) { |
- memset(active_enumeration_ref_count_, 0, |
- sizeof(active_enumeration_ref_count_)); |
} |
MediaStreamManager::~MediaStreamManager() { |
@@ -181,17 +176,6 @@ |
render_view_id, |
security_origin); |
StartEnumeration(&new_request, label); |
- |
- // Get user confirmation to use capture devices. |
- // Need to make an asynchronous call to make sure the |requester| gets the |
- // |label| before it would receive any event. |
- BrowserThread::PostTask(BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, |
- base::Unretained(device_settings_.get()), |
- *label, render_process_id, |
- render_view_id, options, |
- security_origin)); |
} |
void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { |
@@ -203,7 +187,7 @@ |
// opened -> close them. |
DeviceRequest* request = &(it->second); |
if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == |
- DeviceRequest::STATE_OPENING) { |
+ DeviceRequest::kOpening) { |
for (StreamDeviceInfoArray::iterator it = |
request->audio_devices.begin(); it != request->audio_devices.end(); |
++it) { |
@@ -211,7 +195,7 @@ |
} |
} |
if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == |
- DeviceRequest::STATE_OPENING) { |
+ DeviceRequest::kOpening) { |
for (StreamDeviceInfoArray::iterator it = |
request->video_devices.begin(); it != request->video_devices.end(); |
++it) { |
@@ -234,7 +218,7 @@ |
if (!RequestDone(it->second)) { |
DeviceRequest* request = &(it->second); |
if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == |
- DeviceRequest::STATE_OPENING) { |
+ DeviceRequest::kOpening) { |
for (StreamDeviceInfoArray::iterator it = |
request->audio_devices.begin(); it != request->audio_devices.end(); |
++it) { |
@@ -242,7 +226,7 @@ |
} |
} |
if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == |
- DeviceRequest::STATE_OPENING) { |
+ DeviceRequest::kOpening) { |
for (StreamDeviceInfoArray::iterator it = |
request->video_devices.begin(); it != request->video_devices.end(); |
++it) { |
@@ -262,10 +246,6 @@ |
// Find the request and close all open devices for the request. |
DeviceRequests::iterator it = requests_.find(label); |
if (it != requests_.end()) { |
- if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { |
- StopEnumerateDevices(label); |
- return; |
- } |
for (StreamDeviceInfoArray::iterator audio_it = |
it->second.audio_devices.begin(); |
audio_it != it->second.audio_devices.end(); ++audio_it) { |
@@ -276,10 +256,11 @@ |
video_it != it->second.video_devices.end(); ++video_it) { |
video_capture_manager()->Close(video_it->session_id); |
} |
- if (it->second.type == DeviceRequest::GENERATE_STREAM) { |
+ if (it->second.type == DeviceRequest::kGenerateStream) { |
NotifyObserverDevicesClosed(&(it->second)); |
} |
requests_.erase(it); |
+ return; |
} |
} |
@@ -291,55 +272,23 @@ |
const GURL& security_origin, |
std::string* label) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || |
- type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); |
// Create a new request. |
StreamOptions options; |
- EnumerationCache* cache = NULL; |
- if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
+ if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
options.audio = true; |
- cache = &audio_enumeration_cache_; |
- } else { |
+ else |
options.video = true; |
- cache = &video_enumeration_cache_; |
- } |
DeviceRequest new_request(requester, options, |
render_process_id, |
render_view_id, |
security_origin); |
- new_request.type = DeviceRequest::ENUMERATE_DEVICES; |
+ new_request.type = DeviceRequest::kEnumerateDevices; |
- if (cache->valid) { |
- // Cached device list of this type exists. Just send it out. |
- new_request.state[type] = DeviceRequest::STATE_REQUESTED; |
- AddRequest(&new_request, label); |
- // Need to post a task since the requester won't have label till |
- // this function returns. |
- BrowserThread::PostTask(BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(&MediaStreamManager::SendCachedDeviceList, |
- base::Unretained(this), cache, *label)); |
- } else { |
- StartEnumeration(&new_request, label); |
- StartMonitoring(); |
- } |
+ StartEnumeration(&new_request, label); |
} |
-void MediaStreamManager::StopEnumerateDevices(const std::string& label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- DeviceRequests::iterator it = requests_.find(label); |
- if (it != requests_.end()) { |
- DCHECK_EQ(it->second.type, DeviceRequest::ENUMERATE_DEVICES); |
- requests_.erase(it); |
- if (!HasEnumerationRequest()) { |
- StopMonitoring(); |
- } |
- } |
-} |
- |
void MediaStreamManager::OpenDevice( |
MediaStreamRequester* requester, |
int render_process_id, |
@@ -361,47 +310,12 @@ |
render_process_id, |
render_view_id, |
security_origin); |
- new_request.type = DeviceRequest::OPEN_DEVICE; |
+ new_request.type = DeviceRequest::kOpenDevice; |
new_request.requested_device_id = device_id; |
StartEnumeration(&new_request, label); |
} |
-void MediaStreamManager::SendCachedDeviceList( |
- EnumerationCache* cache, |
- const std::string& label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (cache->valid) { |
- DeviceRequests::iterator it = requests_.find(label); |
- if (it != requests_.end()) { |
- it->second.requester->DevicesEnumerated(label, cache->devices); |
- } |
- } |
-} |
- |
-void MediaStreamManager::StartMonitoring() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (!monitoring_started_) { |
- monitoring_started_ = true; |
- base::SystemMonitor::Get()->AddDevicesChangedObserver(this); |
- } |
-} |
- |
-void MediaStreamManager::StopMonitoring() { |
- DCHECK_EQ(MessageLoop::current(), io_loop_); |
- if (monitoring_started_ && !HasEnumerationRequest()) { |
- base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); |
- monitoring_started_ = false; |
- ClearEnumerationCache(&audio_enumeration_cache_); |
- ClearEnumerationCache(&video_enumeration_cache_); |
- } |
-} |
- |
-void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
- DCHECK_EQ(MessageLoop::current(), io_loop_); |
- cache->valid = false; |
-} |
- |
void MediaStreamManager::StartEnumeration( |
DeviceRequest* new_request, |
std::string* label) { |
@@ -409,31 +323,21 @@ |
MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
if (Requested(new_request->options, stream_type)) { |
- new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; |
- DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
- if (!active_enumeration_ref_count_[stream_type]) { |
- ++active_enumeration_ref_count_[stream_type]; |
+ new_request->state[stream_type] = DeviceRequest::kRequested; |
+ if (!enumeration_in_progress_[stream_type]) { |
+ enumeration_in_progress_[stream_type] = true; |
GetDeviceManager(stream_type)->EnumerateDevices(); |
} |
} |
stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
if (Requested(new_request->options, stream_type)) { |
- new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; |
- DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
- if (!active_enumeration_ref_count_[stream_type]) { |
- ++active_enumeration_ref_count_[stream_type]; |
+ new_request->state[stream_type] = DeviceRequest::kRequested; |
+ if (!enumeration_in_progress_[stream_type]) { |
+ enumeration_in_progress_[stream_type] = true; |
GetDeviceManager(stream_type)->EnumerateDevices(); |
} |
} |
- AddRequest(new_request, label); |
-} |
- |
-void MediaStreamManager::AddRequest( |
- DeviceRequest* new_request, |
- std::string* label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
// Create a label for this request and verify it is unique. |
std::string request_label; |
do { |
@@ -442,6 +346,19 @@ |
requests_.insert(std::make_pair(request_label, *new_request)); |
+ // Get user confirmation to use capture devices. |
+ // Need to make an asynchronous call to make sure the |requester| gets the |
+ // |label| before it would receive any event. |
+ if (new_request->type == DeviceRequest::kGenerateStream) { |
+ BrowserThread::PostTask(BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, |
+ base::Unretained(device_settings_.get()), |
+ request_label, new_request->render_process_id, |
+ new_request->render_view_id, new_request->options, |
+ new_request->security_origin)); |
+ } |
+ |
(*label) = request_label; |
} |
@@ -497,7 +414,7 @@ |
return; |
} |
- DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); |
+ DCHECK_NE(request->state[stream_type], DeviceRequest::kRequested); |
// Check if all devices for this stream type are opened. Update the state if |
// they are. |
@@ -508,7 +425,7 @@ |
return; |
} |
} |
- request->state[stream_type] = DeviceRequest::STATE_DONE; |
+ request->state[stream_type] = DeviceRequest::kDone; |
if (!RequestDone(*request)) { |
// This stream_type is done, but not the other type. |
@@ -516,10 +433,10 @@ |
} |
switch (request->type) { |
- case DeviceRequest::OPEN_DEVICE: |
+ case DeviceRequest::kOpenDevice: |
request->requester->DeviceOpened(label, (*devices)[0]); |
break; |
- case DeviceRequest::GENERATE_STREAM: |
+ case DeviceRequest::kGenerateStream: |
request->requester->StreamGenerated(label, request->audio_devices, |
request->video_devices); |
NotifyObserverDevicesOpened(request); |
@@ -538,21 +455,6 @@ |
MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- // Only cache device list when there is EnumerateDevices request, since |
- // other requests don't turn on device monitoring. |
- bool need_update_clients = false; |
- EnumerationCache* cache = |
- (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? |
- &audio_enumeration_cache_ : &video_enumeration_cache_); |
- if (HasEnumerationRequest(stream_type) && |
- (!cache->valid || |
- !std::equal(devices.begin(), devices.end(), cache->devices.begin(), |
- media_stream::StreamDeviceInfo::IsEqual))) { |
- cache->valid = true; |
- cache->devices = devices; |
- need_update_clients = true; |
- } |
- |
// Publish the result for all requests waiting for device list(s). |
// Find the requests waiting for this device list, store their labels and |
// release the iterator before calling device settings. We might get a call |
@@ -560,10 +462,9 @@ |
std::list<std::string> label_list; |
for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
++it) { |
- if (it->second.state[stream_type] == DeviceRequest::STATE_REQUESTED && |
+ if (it->second.state[stream_type] == DeviceRequest::kRequested && |
Requested(it->second.options, stream_type)) { |
- if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) |
- it->second.state[stream_type] = DeviceRequest::STATE_PENDING_APPROVAL; |
+ it->second.state[stream_type] = DeviceRequest::kPendingApproval; |
label_list.push_back(it->first); |
} |
} |
@@ -571,11 +472,11 @@ |
it != label_list.end(); ++it) { |
DeviceRequest& request = requests_[*it]; |
switch (request.type) { |
- case DeviceRequest::ENUMERATE_DEVICES: |
- if (need_update_clients) |
- request.requester->DevicesEnumerated(*it, devices); |
+ case DeviceRequest::kEnumerateDevices: |
+ request.requester->DevicesEnumerated(*it, devices); |
+ requests_.erase(*it); |
break; |
- case DeviceRequest::OPEN_DEVICE: |
+ case DeviceRequest::kOpenDevice: |
for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
device_it != devices.end(); device_it++) { |
if (request.requested_device_id == device_it->device_id) { |
@@ -583,8 +484,7 @@ |
device.in_use = false; |
device.session_id = |
GetDeviceManager(device_it->stream_type)->Open(device); |
- request.state[device_it->stream_type] = |
- DeviceRequest::STATE_OPENING; |
+ request.state[device_it->stream_type] = DeviceRequest::kOpening; |
if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
request.audio_devices.push_back(device); |
else |
@@ -602,8 +502,7 @@ |
} |
} |
label_list.clear(); |
- --active_enumeration_ref_count_[stream_type]; |
- DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
+ enumeration_in_progress_[stream_type] = false; |
} |
void MediaStreamManager::Error(MediaStreamType stream_type, |
@@ -627,7 +526,7 @@ |
device_it != devices->end(); ++device_it, ++device_idx) { |
if (device_it->session_id == capture_session_id) { |
// We've found the failing device. Find the error case: |
- if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { |
+ if (it->second.state[stream_type] == DeviceRequest::kDone) { |
// 1. Already opened -> signal device failure and close device. |
// Use device_idx to signal which of the devices encountered an |
// error. |
@@ -677,12 +576,12 @@ |
// opened. in_use might be true if the device type can be used in more |
// than one session. |
DCHECK_EQ(request_it->second.state[device_it->stream_type], |
- DeviceRequest::STATE_PENDING_APPROVAL); |
+ DeviceRequest::kPendingApproval); |
device_info.in_use = false; |
device_info.session_id = |
GetDeviceManager(device_info.stream_type)->Open(device_info); |
request_it->second.state[device_it->stream_type] = |
- DeviceRequest::STATE_OPENING; |
+ DeviceRequest::kOpening; |
if (device_info.stream_type == |
content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
request_it->second.audio_devices.push_back(device_info); |
@@ -698,12 +597,12 @@ |
content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
if (Requested(request_it->second.options, stream_type) && |
request_it->second.audio_devices.size() == 0) { |
- request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR; |
+ request_it->second.state[stream_type] = DeviceRequest::kError; |
} |
stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
if (Requested(request_it->second.options, stream_type) && |
request_it->second.video_devices.size() == 0) { |
- request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR; |
+ request_it->second.state[stream_type] = DeviceRequest::kError; |
} |
return; |
} |
@@ -714,7 +613,7 @@ |
// Erase this request and report an error. |
DeviceRequests::iterator it = requests_.find(label); |
if (it != requests_.end()) { |
- DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); |
+ DCHECK_EQ(it->second.type, DeviceRequest::kGenerateStream); |
it->second.requester->StreamGenerationFailed(label); |
requests_.erase(it); |
return; |
@@ -729,10 +628,7 @@ |
void MediaStreamManager::WillDestroyCurrentMessageLoop() { |
DCHECK_EQ(MessageLoop::current(), io_loop_); |
- DCHECK(requests_.empty()); |
if (device_thread_.get()) { |
- StopMonitoring(); |
- |
video_capture_manager_->Unregister(); |
audio_input_device_manager_->Unregister(); |
device_thread_.reset(); |
@@ -825,57 +721,4 @@ |
return NULL; |
} |
-void MediaStreamManager::OnDevicesChanged( |
- base::SystemMonitor::DeviceType device_type) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- MediaStreamType stream_type; |
- EnumerationCache* cache; |
- if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { |
- stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
- cache = &audio_enumeration_cache_; |
- } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { |
- stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
- cache = &video_enumeration_cache_; |
- } else { |
- return; // Uninteresting device change. |
- } |
- |
- if (!HasEnumerationRequest(stream_type)) { |
- // There is no request for that type, No need to enumerate devices. |
- // Therefore, invalidate the cache of that type. |
- ClearEnumerationCache(cache); |
- return; |
- } |
- |
- // Always do enumeration even though some enumeration is in progress, |
- // because those enumeration commands could be sent before these devices |
- // change. |
- ++active_enumeration_ref_count_[stream_type]; |
- GetDeviceManager(stream_type)->EnumerateDevices(); |
-} |
- |
-bool MediaStreamManager::HasEnumerationRequest() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- for (DeviceRequests::iterator it = requests_.begin(); |
- it != requests_.end(); ++it) { |
- if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-bool MediaStreamManager::HasEnumerationRequest( |
- MediaStreamType stream_type) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- for (DeviceRequests::iterator it = requests_.begin(); |
- it != requests_.end(); ++it) { |
- if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && |
- Requested(it->second.options, stream_type)) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
} // namespace media_stream |