Chromium Code Reviews| Index: content/renderer/media/media_stream_dispatcher.cc |
| =================================================================== |
| --- content/renderer/media/media_stream_dispatcher.cc (revision 148913) |
| +++ content/renderer/media/media_stream_dispatcher.cc (working copy) |
| @@ -31,8 +31,36 @@ |
| media_stream::StreamDeviceInfoArray video_array; |
| }; |
| +MediaStreamDispatcher::EnumerationRequest::EnumerationRequest( |
| + const base::WeakPtr<MediaStreamDispatcherEventHandler>& handler, |
| + int request_id) |
| + : handler(handler), |
| + request_id(request_id) { |
| +} |
| + |
| +MediaStreamDispatcher::EnumerationRequest::~EnumerationRequest() {} |
| + |
| +MediaStreamDispatcher::EnumerationState::EnumerationState() |
| + : ipc_id(-1) { |
| +} |
| + |
| +MediaStreamDispatcher::EnumerationState::~EnumerationState() {} |
| + |
| +struct MediaStreamDispatcher::EnumerationState::CachedDevices { |
| + CachedDevices(const std::string& label, |
| + const media_stream::StreamDeviceInfoArray& device_array) |
| + : label(label), |
| + device_array(device_array) { |
| + } |
| + ~CachedDevices() {} |
| + |
| + std::string label; |
| + media_stream::StreamDeviceInfoArray device_array; |
|
scherkus (not reviewing)
2012/08/02 22:45:18
nit: this can be |devices| -- no need to annotate
wjia(left Chromium)
2012/08/03 21:53:45
Done.
|
| +}; |
| + |
| MediaStreamDispatcher::MediaStreamDispatcher(RenderViewImpl* render_view) |
| : content::RenderViewObserver(render_view), |
| + main_loop_(base::MessageLoopProxy::current()), |
| next_ipc_id_(0) { |
| } |
| @@ -43,6 +71,7 @@ |
| const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler, |
| media_stream::StreamOptions components, |
| const GURL& security_origin) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| DVLOG(1) << "MediaStreamDispatcher::GenerateStream(" << request_id << ")"; |
| requests_.push_back(Request(event_handler, request_id, next_ipc_id_)); |
| @@ -53,6 +82,7 @@ |
| } |
| void MediaStreamDispatcher::CancelGenerateStream(int request_id) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| DVLOG(1) << "MediaStreamDispatcher::CancelGenerateStream" |
| << ", {request_id = " << request_id << "}"; |
| @@ -69,6 +99,7 @@ |
| } |
| void MediaStreamDispatcher::StopStream(const std::string& label) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| DVLOG(1) << "MediaStreamDispatcher::StopStream" |
| << ", {label = " << label << "}"; |
| @@ -85,22 +116,74 @@ |
| const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler, |
| media_stream::MediaStreamType type, |
| const GURL& security_origin) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| + DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || |
| + type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); |
| DVLOG(1) << "MediaStreamDispatcher::EnumerateDevices(" |
| << request_id << ")"; |
| - requests_.push_back(Request(event_handler, request_id, next_ipc_id_)); |
| - Send(new MediaStreamHostMsg_EnumerateDevices(routing_id(), |
| - next_ipc_id_++, |
| - type, |
| - security_origin)); |
| + EnumerationState* state = |
| + (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? |
| + &audio_enumeration_state_ : &video_enumeration_state_); |
| + state->requests.push_back( |
| + EnumerationRequest(event_handler, request_id)); |
| + |
| + if (state->cached_devices.get()) { |
| + event_handler->OnDevicesEnumerated( |
| + request_id, state->cached_devices->device_array); |
| + } else if (state->ipc_id < 0) { |
| + Send(new MediaStreamHostMsg_EnumerateDevices(routing_id(), |
| + next_ipc_id_, |
| + type, |
| + security_origin)); |
| + state->ipc_id = next_ipc_id_++; |
| + } |
| } |
| +void MediaStreamDispatcher::StopEnumerateDevices( |
| + int request_id, |
| + const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| + DVLOG(1) << "MediaStreamDispatcher::StopEnumerateDevices(" |
| + << request_id << ")"; |
| + |
| + // Remove the request. |
| + RemoveEnumerationRequest( |
| + request_id, event_handler, &audio_enumeration_state_); |
| + RemoveEnumerationRequest( |
| + request_id, event_handler, &video_enumeration_state_); |
| +} |
| + |
| +bool MediaStreamDispatcher::RemoveEnumerationRequest( |
|
scherkus (not reviewing)
2012/08/02 22:45:18
RER() no longer needs to return a bool
wjia(left Chromium)
2012/08/03 21:53:45
Done.
|
| + int request_id, |
| + const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler, |
| + EnumerationState* state) { |
| + EnumerationRequestList* requests = &state->requests; |
| + for (EnumerationRequestList::iterator it = requests->begin(); |
| + it != requests->end(); ++it) { |
| + if (it->request_id == request_id && it->handler == event_handler) { |
| + requests->erase(it); |
| + if (requests->empty() && !state->cached_devices.get()) { |
| + // No more request and has a label, try to stop the label |
| + // and invalidate the state. |
| + Send(new MediaStreamHostMsg_StopGeneratedStream( |
| + routing_id(), state->cached_devices->label)); |
| + state->ipc_id = -1; |
| + state->cached_devices.reset(); |
| + } |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| void MediaStreamDispatcher::OpenDevice( |
| int request_id, |
| const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler, |
| const std::string& device_id, |
| media_stream::MediaStreamType type, |
| const GURL& security_origin) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| DVLOG(1) << "MediaStreamDispatcher::OpenDevice(" << request_id << ")"; |
| requests_.push_back(Request(event_handler, request_id, next_ipc_id_)); |
| @@ -112,6 +195,7 @@ |
| } |
| void MediaStreamDispatcher::CloseDevice(const std::string& label) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| DVLOG(1) << "MediaStreamDispatcher::CloseDevice" |
| << ", {label = " << label << "}"; |
| @@ -147,6 +231,7 @@ |
| const std::string& label, |
| const media_stream::StreamDeviceInfoArray& audio_array, |
| const media_stream::StreamDeviceInfoArray& video_array) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| for (RequestList::iterator it = requests_.begin(); |
| it != requests_.end(); ++it) { |
| @@ -170,6 +255,7 @@ |
| } |
| void MediaStreamDispatcher::OnStreamGenerationFailed(int request_id) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| for (RequestList::iterator it = requests_.begin(); |
| it != requests_.end(); ++it) { |
| Request& request = *it; |
| @@ -187,6 +273,7 @@ |
| void MediaStreamDispatcher::OnVideoDeviceFailed(const std::string& label, |
| int index) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| LabelStreamMap::iterator it = label_stream_map_.find(label); |
| if (it == label_stream_map_.end()) |
| return; |
| @@ -202,6 +289,7 @@ |
| void MediaStreamDispatcher::OnAudioDeviceFailed(const std::string& label, |
| int index) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| LabelStreamMap::iterator it = label_stream_map_.find(label); |
| if (it == label_stream_map_.end()) |
| return; |
| @@ -217,24 +305,41 @@ |
| void MediaStreamDispatcher::OnDevicesEnumerated( |
| int request_id, |
| + const std::string& label, |
| const media_stream::StreamDeviceInfoArray& device_array) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| + DCHECK_GE(request_id, 0); |
| - for (RequestList::iterator it = requests_.begin(); |
| - it != requests_.end(); ++it) { |
| - Request& request = *it; |
| - if (request.ipc_request == request_id) { |
| - if (request.handler) { |
| - request.handler->OnDevicesEnumerated(request.request_id, device_array); |
| - DVLOG(1) << "MediaStreamDispatcher::OnDevicesEnumerated(" |
| - << request.request_id << ")"; |
| - } |
| - requests_.erase(it); |
| - break; |
| + EnumerationState* state; |
| + if (request_id == audio_enumeration_state_.ipc_id) { |
| + state = &audio_enumeration_state_; |
| + } else if (request_id == video_enumeration_state_.ipc_id) { |
| + state = &video_enumeration_state_; |
| + } else { |
| + // This could happen when requester has stopped enumeration while some |
| + // enumerated response is on the way. Have to stop the |label| because |
| + // this might be the first enumerated device list is received. This also |
| + // lead to same label being stopped multiple times. |
| + Send(new MediaStreamHostMsg_StopGeneratedStream(routing_id(), label)); |
| + return; |
| + } |
| + |
| + DCHECK(!label.empty()); |
| + state->cached_devices.reset(new EnumerationState::CachedDevices( |
| + label, device_array)); |
| + |
| + for (EnumerationRequestList::iterator it = state->requests.begin(); |
| + it != state->requests.end(); ++it) { |
| + if (it->handler) { |
| + it->handler->OnDevicesEnumerated(it->request_id, device_array); |
| + DVLOG(1) << "MediaStreamDispatcher::OnDevicesEnumerated(" |
| + << it->request_id << ")"; |
| } |
| } |
| } |
| void MediaStreamDispatcher::OnDevicesEnumerationFailed(int request_id) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| for (RequestList::iterator it = requests_.begin(); |
| it != requests_.end(); ++it) { |
| Request& request = *it; |
| @@ -254,6 +359,7 @@ |
| int request_id, |
| const std::string& label, |
| const media_stream::StreamDeviceInfo& device_info) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| for (RequestList::iterator it = requests_.begin(); |
| it != requests_.end(); ++it) { |
| Request& request = *it; |
| @@ -280,6 +386,7 @@ |
| } |
| void MediaStreamDispatcher::OnDeviceOpenFailed(int request_id) { |
| + DCHECK(main_loop_->BelongsToCurrentThread()); |
| for (RequestList::iterator it = requests_.begin(); |
| it != requests_.end(); ++it) { |
| Request& request = *it; |