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