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
MediaStreamDispatcherHost(int render_process_id,const ResourceContext::SaltCallback & salt_callback,MediaStreamManager * media_stream_manager)16 MediaStreamDispatcherHost::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
StreamGenerated(int render_frame_id,int page_request_id,const std::string & label,const StreamDeviceInfoArray & audio_devices,const StreamDeviceInfoArray & video_devices)26 void 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
StreamGenerationFailed(int render_frame_id,int page_request_id,content::MediaStreamRequestResult result)40 void 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
DeviceStopped(int render_frame_id,const std::string & label,const StreamDeviceInfo & device)55 void 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
DevicesEnumerated(int render_frame_id,int page_request_id,const std::string & label,const StreamDeviceInfoArray & devices)67 void 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
DeviceOpened(int render_frame_id,int page_request_id,const std::string & label,const StreamDeviceInfo & video_device)80 void 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
OnMessageReceived(const IPC::Message & message)93 bool 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
OnChannelClosing()114 void 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
~MediaStreamDispatcherHost()121 MediaStreamDispatcherHost::~MediaStreamDispatcherHost() {
122 }
123
OnGenerateStream(int render_frame_id,int page_request_id,const StreamOptions & components,const GURL & security_origin,bool user_gesture)124 void 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
OnCancelGenerateStream(int render_frame_id,int page_request_id)147 void 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
OnStopStreamDevice(int render_frame_id,const std::string & device_id)156 void 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
OnEnumerateDevices(int render_frame_id,int page_request_id,MediaStreamType type,const GURL & security_origin)166 void 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
OnCancelEnumerateDevices(int render_frame_id,int page_request_id)185 void 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
OnOpenDevice(int render_frame_id,int page_request_id,const std::string & device_id,MediaStreamType type,const GURL & security_origin)195 void 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
OnCloseDevice(int render_frame_id,const std::string & label)216 void 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
IsURLAllowed(const GURL & url)226 bool 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