| Index: content/renderer/media/media_stream_dispatcher.cc
|
| ===================================================================
|
| --- content/renderer/media/media_stream_dispatcher.cc (revision 150440)
|
| +++ 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),
|
| + devices(device_array) {
|
| + }
|
| + ~CachedDevices() {}
|
| +
|
| + std::string label;
|
| + media_stream::StreamDeviceInfoArray devices;
|
| +};
|
| +
|
| 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,73 @@
|
| 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->devices);
|
| + } 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_);
|
| +}
|
| +
|
| +void MediaStreamDispatcher::RemoveEnumerationRequest(
|
| + 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;
|
| + }
|
| + }
|
| +}
|
| +
|
| 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 +194,7 @@
|
| }
|
|
|
| void MediaStreamDispatcher::CloseDevice(const std::string& label) {
|
| + DCHECK(main_loop_->BelongsToCurrentThread());
|
| DVLOG(1) << "MediaStreamDispatcher::CloseDevice"
|
| << ", {label = " << label << "}";
|
|
|
| @@ -147,6 +230,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 +254,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 +272,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 +288,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 +304,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 +358,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 +385,7 @@
|
| }
|
|
|
| void MediaStreamDispatcher::OnDeviceOpenFailed(int request_id) {
|
| + DCHECK(main_loop_->BelongsToCurrentThread());
|
| for (RequestList::iterator it = requests_.begin();
|
| it != requests_.end(); ++it) {
|
| Request& request = *it;
|
|
|