blob: ebc4d894b4a6cc50c67be62744d0fbabf36e688c [file] [log] [blame]
// 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