1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" 6 7#include "content/browser/browser_main_loop.h" 8#include "content/browser/child_process_security_policy_impl.h" 9#include "content/common/media/media_stream_messages.h" 10#include "content/common/media/media_stream_options.h" 11#include "content/public/browser/render_process_host.h" 12#include "url/gurl.h" 13 14namespace content { 15 16MediaStreamDispatcherHost::MediaStreamDispatcherHost( 17 int render_process_id, 18 const ResourceContext::SaltCallback& salt_callback, 19 MediaStreamManager* media_stream_manager) 20 : BrowserMessageFilter(MediaStreamMsgStart), 21 render_process_id_(render_process_id), 22 salt_callback_(salt_callback), 23 media_stream_manager_(media_stream_manager) { 24} 25 26void MediaStreamDispatcherHost::StreamGenerated( 27 int render_frame_id, 28 int page_request_id, 29 const std::string& label, 30 const StreamDeviceInfoArray& audio_devices, 31 const StreamDeviceInfoArray& video_devices) { 32 DCHECK_CURRENTLY_ON(BrowserThread::IO); 33 DVLOG(1) << "MediaStreamDispatcherHost::StreamGenerated(" 34 << ", {label = " << label << "})"; 35 36 Send(new MediaStreamMsg_StreamGenerated( 37 render_frame_id, page_request_id, label, audio_devices, video_devices)); 38} 39 40void MediaStreamDispatcherHost::StreamGenerationFailed( 41 int render_frame_id, 42 int page_request_id, 43 content::MediaStreamRequestResult result) { 44 DCHECK_CURRENTLY_ON(BrowserThread::IO); 45 DVLOG(1) << "MediaStreamDispatcherHost::StreamGenerationFailed(" 46 << ", {page_request_id = " << page_request_id << "}" 47 << ", { result= " << result << "})"; 48 49 50 Send(new MediaStreamMsg_StreamGenerationFailed(render_frame_id, 51 page_request_id, 52 result)); 53} 54 55void MediaStreamDispatcherHost::DeviceStopped(int render_frame_id, 56 const std::string& label, 57 const StreamDeviceInfo& device) { 58 DCHECK_CURRENTLY_ON(BrowserThread::IO); 59 DVLOG(1) << "MediaStreamDispatcherHost::DeviceStopped(" 60 << "{label = " << label << "}, " 61 << "{type = " << device.device.type << "}, " 62 << "{device_id = " << device.device.id << "})"; 63 64 Send(new MediaStreamMsg_DeviceStopped(render_frame_id, label, device)); 65} 66 67void MediaStreamDispatcherHost::DevicesEnumerated( 68 int render_frame_id, 69 int page_request_id, 70 const std::string& label, 71 const StreamDeviceInfoArray& devices) { 72 DCHECK_CURRENTLY_ON(BrowserThread::IO); 73 DVLOG(1) << "MediaStreamDispatcherHost::DevicesEnumerated(" 74 << ", {page_request_id = " << page_request_id << "})"; 75 76 Send(new MediaStreamMsg_DevicesEnumerated(render_frame_id, page_request_id, 77 devices)); 78} 79 80void MediaStreamDispatcherHost::DeviceOpened( 81 int render_frame_id, 82 int page_request_id, 83 const std::string& label, 84 const StreamDeviceInfo& video_device) { 85 DCHECK_CURRENTLY_ON(BrowserThread::IO); 86 DVLOG(1) << "MediaStreamDispatcherHost::DeviceOpened(" 87 << ", {page_request_id = " << page_request_id << "})"; 88 89 Send(new MediaStreamMsg_DeviceOpened( 90 render_frame_id, page_request_id, label, video_device)); 91} 92 93bool MediaStreamDispatcherHost::OnMessageReceived(const IPC::Message& message) { 94 bool handled = true; 95 IPC_BEGIN_MESSAGE_MAP(MediaStreamDispatcherHost, message) 96 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_GenerateStream, OnGenerateStream) 97 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_CancelGenerateStream, 98 OnCancelGenerateStream) 99 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_StopStreamDevice, 100 OnStopStreamDevice) 101 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_EnumerateDevices, 102 OnEnumerateDevices) 103 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_CancelEnumerateDevices, 104 OnCancelEnumerateDevices) 105 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_OpenDevice, 106 OnOpenDevice) 107 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_CloseDevice, 108 OnCloseDevice) 109 IPC_MESSAGE_UNHANDLED(handled = false) 110 IPC_END_MESSAGE_MAP() 111 return handled; 112} 113 114void MediaStreamDispatcherHost::OnChannelClosing() { 115 DVLOG(1) << "MediaStreamDispatcherHost::OnChannelClosing"; 116 117 // Since the IPC sender is gone, close all requesting/requested streams. 118 media_stream_manager_->CancelAllRequests(render_process_id_); 119} 120 121MediaStreamDispatcherHost::~MediaStreamDispatcherHost() { 122} 123 124void MediaStreamDispatcherHost::OnGenerateStream( 125 int render_frame_id, 126 int page_request_id, 127 const StreamOptions& components, 128 const GURL& security_origin, 129 bool user_gesture) { 130 DVLOG(1) << "MediaStreamDispatcherHost::OnGenerateStream(" 131 << render_frame_id << ", " 132 << page_request_id << ", [" 133 << " audio:" << components.audio_requested 134 << " video:" << components.video_requested 135 << " ], " 136 << security_origin.spec() 137 << ", " << user_gesture << ")"; 138 139 if (!IsURLAllowed(security_origin)) 140 return; 141 142 media_stream_manager_->GenerateStream( 143 this, render_process_id_, render_frame_id, salt_callback_, 144 page_request_id, components, security_origin, user_gesture); 145} 146 147void MediaStreamDispatcherHost::OnCancelGenerateStream(int render_frame_id, 148 int page_request_id) { 149 DVLOG(1) << "MediaStreamDispatcherHost::OnCancelGenerateStream(" 150 << render_frame_id << ", " 151 << page_request_id << ")"; 152 media_stream_manager_->CancelRequest(render_process_id_, render_frame_id, 153 page_request_id); 154} 155 156void MediaStreamDispatcherHost::OnStopStreamDevice( 157 int render_frame_id, 158 const std::string& device_id) { 159 DVLOG(1) << "MediaStreamDispatcherHost::OnStopStreamDevice(" 160 << render_frame_id << ", " 161 << device_id << ")"; 162 media_stream_manager_->StopStreamDevice(render_process_id_, render_frame_id, 163 device_id); 164} 165 166void MediaStreamDispatcherHost::OnEnumerateDevices( 167 int render_frame_id, 168 int page_request_id, 169 MediaStreamType type, 170 const GURL& security_origin) { 171 DVLOG(1) << "MediaStreamDispatcherHost::OnEnumerateDevices(" 172 << render_frame_id << ", " 173 << page_request_id << ", " 174 << type << ", " 175 << security_origin.spec() << ")"; 176 177 if (!IsURLAllowed(security_origin)) 178 return; 179 180 media_stream_manager_->EnumerateDevices( 181 this, render_process_id_, render_frame_id, salt_callback_, 182 page_request_id, type, security_origin); 183} 184 185void MediaStreamDispatcherHost::OnCancelEnumerateDevices( 186 int render_frame_id, 187 int page_request_id) { 188 DVLOG(1) << "MediaStreamDispatcherHost::OnCancelEnumerateDevices(" 189 << render_frame_id << ", " 190 << page_request_id << ")"; 191 media_stream_manager_->CancelRequest(render_process_id_, render_frame_id, 192 page_request_id); 193} 194 195void MediaStreamDispatcherHost::OnOpenDevice( 196 int render_frame_id, 197 int page_request_id, 198 const std::string& device_id, 199 MediaStreamType type, 200 const GURL& security_origin) { 201 DVLOG(1) << "MediaStreamDispatcherHost::OnOpenDevice(" 202 << render_frame_id << ", " 203 << page_request_id << ", device_id: " 204 << device_id.c_str() << ", type: " 205 << type << ", " 206 << security_origin.spec() << ")"; 207 208 if (!IsURLAllowed(security_origin)) 209 return; 210 211 media_stream_manager_->OpenDevice( 212 this, render_process_id_, render_frame_id, salt_callback_, 213 page_request_id, device_id, type, security_origin); 214} 215 216void MediaStreamDispatcherHost::OnCloseDevice( 217 int render_frame_id, 218 const std::string& label) { 219 DVLOG(1) << "MediaStreamDispatcherHost::OnCloseDevice(" 220 << render_frame_id << ", " 221 << label << ")"; 222 223 media_stream_manager_->CancelRequest(label); 224} 225 226bool MediaStreamDispatcherHost::IsURLAllowed(const GURL& url) { 227 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( 228 render_process_id_, url)) { 229 LOG(ERROR) << "MSDH: Renderer requested a URL it's not allowed to use."; 230 return false; 231 } 232 233 return true; 234} 235 236} // namespace content 237