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