| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" |
| |
| #include "content/browser/browser_main_loop.h" |
| #include "content/browser/renderer_host/media/web_contents_capture_util.h" |
| #include "content/common/media/media_stream_messages.h" |
| #include "content/common/media/media_stream_options.h" |
| #include "url/gurl.h" |
| |
| namespace content { |
| |
| struct MediaStreamDispatcherHost::StreamRequest { |
| StreamRequest() : render_view_id(0), page_request_id(0) {} |
| StreamRequest(int render_view_id, int page_request_id) |
| : render_view_id(render_view_id), |
| page_request_id(page_request_id ) { |
| } |
| int render_view_id; |
| // Id of the request generated by MediaStreamDispatcher. |
| int page_request_id; |
| }; |
| |
| MediaStreamDispatcherHost::MediaStreamDispatcherHost( |
| int render_process_id, |
| MediaStreamManager* media_stream_manager) |
| : render_process_id_(render_process_id), |
| media_stream_manager_(media_stream_manager) { |
| } |
| |
| void MediaStreamDispatcherHost::StreamGenerated( |
| const std::string& label, |
| const StreamDeviceInfoArray& audio_devices, |
| const StreamDeviceInfoArray& video_devices) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| DVLOG(1) << "MediaStreamDispatcherHost::StreamGenerated(" |
| << ", {label = " << label << "})"; |
| |
| StreamMap::iterator it = streams_.find(label); |
| DCHECK(it != streams_.end()); |
| StreamRequest request = it->second; |
| |
| Send(new MediaStreamMsg_StreamGenerated( |
| request.render_view_id, request.page_request_id, label, audio_devices, |
| video_devices)); |
| } |
| |
| void MediaStreamDispatcherHost::StreamGenerationFailed( |
| const std::string& label) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| DVLOG(1) << "MediaStreamDispatcherHost::StreamGenerationFailed(" |
| << ", {label = " << label << "})"; |
| |
| StreamMap::iterator it = streams_.find(label); |
| DCHECK(it != streams_.end()); |
| StreamRequest request = it->second; |
| streams_.erase(it); |
| |
| Send(new MediaStreamMsg_StreamGenerationFailed(request.render_view_id, |
| request.page_request_id)); |
| } |
| |
| void MediaStreamDispatcherHost::StopGeneratedStream( |
| const std::string& label) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| DVLOG(1) << "MediaStreamDispatcherHost::StopGeneratedStream(" |
| << ", {label = " << label << "})"; |
| |
| StreamMap::iterator it = streams_.find(label); |
| DCHECK(it != streams_.end()); |
| StreamRequest request = it->second; |
| streams_.erase(it); |
| |
| Send(new MediaStreamMsg_StopGeneratedStream(request.render_view_id, label)); |
| } |
| |
| void MediaStreamDispatcherHost::DevicesEnumerated( |
| const std::string& label, |
| const StreamDeviceInfoArray& devices) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| DVLOG(1) << "MediaStreamDispatcherHost::DevicesEnumerated(" |
| << ", {label = " << label << "})"; |
| |
| StreamMap::iterator it = streams_.find(label); |
| DCHECK(it != streams_.end()); |
| StreamRequest request = it->second; |
| |
| Send(new MediaStreamMsg_DevicesEnumerated( |
| request.render_view_id, request.page_request_id, label, devices)); |
| } |
| |
| void MediaStreamDispatcherHost::DeviceOpened( |
| const std::string& label, |
| const StreamDeviceInfo& video_device) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| DVLOG(1) << "MediaStreamDispatcherHost::DeviceOpened(" |
| << ", {label = " << label << "})"; |
| |
| StreamMap::iterator it = streams_.find(label); |
| DCHECK(it != streams_.end()); |
| StreamRequest request = it->second; |
| |
| Send(new MediaStreamMsg_DeviceOpened( |
| request.render_view_id, request.page_request_id, label, video_device)); |
| } |
| |
| bool MediaStreamDispatcherHost::OnMessageReceived( |
| const IPC::Message& message, bool* message_was_ok) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP_EX(MediaStreamDispatcherHost, message, *message_was_ok) |
| IPC_MESSAGE_HANDLER(MediaStreamHostMsg_GenerateStream, OnGenerateStream) |
| IPC_MESSAGE_HANDLER(MediaStreamHostMsg_CancelGenerateStream, |
| OnCancelGenerateStream) |
| IPC_MESSAGE_HANDLER(MediaStreamHostMsg_StopGeneratedStream, |
| OnStopGeneratedStream) |
| IPC_MESSAGE_HANDLER(MediaStreamHostMsg_EnumerateDevices, |
| OnEnumerateDevices) |
| IPC_MESSAGE_HANDLER(MediaStreamHostMsg_OpenDevice, |
| OnOpenDevice) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP_EX() |
| return handled; |
| } |
| |
| void MediaStreamDispatcherHost::OnChannelClosing() { |
| BrowserMessageFilter::OnChannelClosing(); |
| DVLOG(1) << "MediaStreamDispatcherHost::OnChannelClosing"; |
| |
| // Since the IPC channel is gone, close all requesting/requested streams. |
| for (StreamMap::iterator it = streams_.begin(); |
| it != streams_.end(); |
| ++it) { |
| std::string label = it->first; |
| media_stream_manager_->StopGeneratedStream(label); |
| } |
| // Clear the map after we have stopped all the streams. |
| streams_.clear(); |
| } |
| |
| MediaStreamDispatcherHost::~MediaStreamDispatcherHost() { |
| DCHECK(streams_.empty()); |
| } |
| |
| void MediaStreamDispatcherHost::OnGenerateStream( |
| int render_view_id, |
| int page_request_id, |
| const StreamOptions& components, |
| const GURL& security_origin) { |
| DVLOG(1) << "MediaStreamDispatcherHost::OnGenerateStream(" |
| << render_view_id << ", " |
| << page_request_id << ", [" |
| << " audio:" << components.audio_type |
| << " video:" << components.video_type |
| << " ], " |
| << security_origin.spec() << ")"; |
| |
| const std::string& label = media_stream_manager_->GenerateStream( |
| this, render_process_id_, render_view_id, page_request_id, |
| components, security_origin); |
| if (label.empty()) { |
| Send(new MediaStreamMsg_StreamGenerationFailed(render_view_id, |
| page_request_id)); |
| } else { |
| streams_[label] = StreamRequest(render_view_id, page_request_id); |
| } |
| } |
| |
| void MediaStreamDispatcherHost::OnCancelGenerateStream(int render_view_id, |
| int page_request_id) { |
| DVLOG(1) << "MediaStreamDispatcherHost::OnCancelGenerateStream(" |
| << render_view_id << ", " |
| << page_request_id << ")"; |
| |
| for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); ++it) { |
| if (it->second.render_view_id == render_view_id && |
| it->second.page_request_id == page_request_id) { |
| media_stream_manager_->CancelRequest(it->first); |
| } |
| } |
| } |
| |
| void MediaStreamDispatcherHost::OnStopGeneratedStream( |
| int render_view_id, const std::string& label) { |
| DVLOG(1) << "MediaStreamDispatcherHost::OnStopGeneratedStream(" |
| << ", {label = " << label << "})"; |
| |
| StreamMap::iterator it = streams_.find(label); |
| if (it == streams_.end()) |
| return; |
| |
| media_stream_manager_->StopGeneratedStream(label); |
| streams_.erase(it); |
| } |
| |
| void MediaStreamDispatcherHost::OnEnumerateDevices( |
| int render_view_id, |
| int page_request_id, |
| MediaStreamType type, |
| const GURL& security_origin) { |
| DVLOG(1) << "MediaStreamDispatcherHost::OnEnumerateDevices(" |
| << render_view_id << ", " |
| << page_request_id << ", " |
| << type << ", " |
| << security_origin.spec() << ")"; |
| |
| const std::string& label = media_stream_manager_->EnumerateDevices( |
| this, render_process_id_, render_view_id, page_request_id, |
| type, security_origin); |
| DCHECK(!label.empty()); |
| streams_[label] = StreamRequest(render_view_id, page_request_id); |
| } |
| |
| void MediaStreamDispatcherHost::OnOpenDevice( |
| int render_view_id, |
| int page_request_id, |
| const std::string& device_id, |
| MediaStreamType type, |
| const GURL& security_origin) { |
| DVLOG(1) << "MediaStreamDispatcherHost::OnOpenDevice(" |
| << render_view_id << ", " |
| << page_request_id << ", device_id: " |
| << device_id.c_str() << ", type: " |
| << type << ", " |
| << security_origin.spec() << ")"; |
| |
| const std::string& label = media_stream_manager_->OpenDevice( |
| this, render_process_id_, render_view_id, page_request_id, |
| device_id, type, security_origin); |
| DCHECK(!label.empty()); |
| streams_[label] = StreamRequest(render_view_id, page_request_id); |
| } |
| |
| } // namespace content |