Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: chrome/browser/media/media_capture_devices_dispatcher.cc

Issue 2307083002: Cleanup: move WebRTC related files from chrome/browser/media to chrome/browser/media/webrtc/ (Closed)
Patch Set: Removed file wrongly resuscitated during rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "chrome/browser/media/media_capture_devices_dispatcher.h"
6
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "build/build_config.h"
14 #include "chrome/browser/media/desktop_streams_registry.h"
15 #include "chrome/browser/media/media_access_handler.h"
16 #include "chrome/browser/media/media_stream_capture_indicator.h"
17 #include "chrome/browser/media/permission_bubble_media_access_handler.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_window.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/pref_names.h"
23 #include "components/pref_registry/pref_registry_syncable.h"
24 #include "components/prefs/pref_service.h"
25 #include "components/prefs/scoped_user_pref_update.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/media_capture_devices.h"
28 #include "content/public/browser/notification_source.h"
29 #include "content/public/browser/render_frame_host.h"
30 #include "content/public/browser/render_process_host.h"
31 #include "content/public/browser/web_contents.h"
32 #include "content/public/common/media_stream_request.h"
33 #include "extensions/common/constants.h"
34 #include "media/base/media_switches.h"
35
36 #if defined(OS_CHROMEOS)
37 #include "ash/shell.h"
38 #endif // defined(OS_CHROMEOS)
39
40 #if defined(ENABLE_EXTENSIONS)
41 #include "chrome/browser/media/desktop_capture_access_handler.h"
42 #include "chrome/browser/media/extension_media_access_handler.h"
43 #include "chrome/browser/media/tab_capture_access_handler.h"
44 #include "extensions/browser/extension_registry.h"
45 #include "extensions/common/extension.h"
46 #include "extensions/common/permissions/permissions_data.h"
47 #endif
48
49 using content::BrowserThread;
50 using content::MediaCaptureDevices;
51 using content::MediaStreamDevices;
52
53 namespace {
54
55 // Finds a device in |devices| that has |device_id|, or NULL if not found.
56 const content::MediaStreamDevice* FindDeviceWithId(
57 const content::MediaStreamDevices& devices,
58 const std::string& device_id) {
59 content::MediaStreamDevices::const_iterator iter = devices.begin();
60 for (; iter != devices.end(); ++iter) {
61 if (iter->id == device_id) {
62 return &(*iter);
63 }
64 }
65 return NULL;
66 }
67
68 #if defined(ENABLE_EXTENSIONS)
69 inline CaptureAccessHandlerBase* ToCaptureAccessHandlerBase(
70 MediaAccessHandler* handler) {
71 return static_cast<CaptureAccessHandlerBase*>(handler);
72 }
73 #endif
74 } // namespace
75
76 MediaCaptureDevicesDispatcher* MediaCaptureDevicesDispatcher::GetInstance() {
77 return base::Singleton<MediaCaptureDevicesDispatcher>::get();
78 }
79
80 MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher()
81 : is_device_enumeration_disabled_(false),
82 media_stream_capture_indicator_(new MediaStreamCaptureIndicator()) {
83 DCHECK_CURRENTLY_ON(BrowserThread::UI);
84
85 #if defined(ENABLE_EXTENSIONS)
86 media_access_handlers_.push_back(new ExtensionMediaAccessHandler());
87 media_access_handlers_.push_back(new DesktopCaptureAccessHandler());
88 media_access_handlers_.push_back(new TabCaptureAccessHandler());
89 #endif
90 media_access_handlers_.push_back(new PermissionBubbleMediaAccessHandler());
91 }
92
93 MediaCaptureDevicesDispatcher::~MediaCaptureDevicesDispatcher() {}
94
95 void MediaCaptureDevicesDispatcher::RegisterProfilePrefs(
96 user_prefs::PrefRegistrySyncable* registry) {
97 registry->RegisterStringPref(prefs::kDefaultAudioCaptureDevice,
98 std::string());
99 registry->RegisterStringPref(prefs::kDefaultVideoCaptureDevice,
100 std::string());
101 }
102
103 bool MediaCaptureDevicesDispatcher::IsOriginForCasting(const GURL& origin) {
104 // Whitelisted tab casting extensions.
105 return
106 // Dev
107 origin.spec() == "chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/" ||
108 // Canary
109 origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" ||
110 // Beta (internal)
111 origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" ||
112 // Google Cast Beta
113 origin.spec() == "chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/" ||
114 // Google Cast Stable
115 origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/" ||
116 // http://crbug.com/457908
117 origin.spec() == "chrome-extension://ekpaaapppgpmolpcldedioblbkmijaca/" ||
118 // http://crbug.com/574889
119 origin.spec() == "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/";
120 }
121
122 void MediaCaptureDevicesDispatcher::AddObserver(Observer* observer) {
123 DCHECK_CURRENTLY_ON(BrowserThread::UI);
124 if (!observers_.HasObserver(observer))
125 observers_.AddObserver(observer);
126 }
127
128 void MediaCaptureDevicesDispatcher::RemoveObserver(Observer* observer) {
129 DCHECK_CURRENTLY_ON(BrowserThread::UI);
130 observers_.RemoveObserver(observer);
131 }
132
133 const MediaStreamDevices&
134 MediaCaptureDevicesDispatcher::GetAudioCaptureDevices() {
135 DCHECK_CURRENTLY_ON(BrowserThread::UI);
136 if (is_device_enumeration_disabled_ || !test_audio_devices_.empty())
137 return test_audio_devices_;
138
139 return MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices();
140 }
141
142 const MediaStreamDevices&
143 MediaCaptureDevicesDispatcher::GetVideoCaptureDevices() {
144 DCHECK_CURRENTLY_ON(BrowserThread::UI);
145 if (is_device_enumeration_disabled_ || !test_video_devices_.empty())
146 return test_video_devices_;
147
148 return MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices();
149 }
150
151 void MediaCaptureDevicesDispatcher::ProcessMediaAccessRequest(
152 content::WebContents* web_contents,
153 const content::MediaStreamRequest& request,
154 const content::MediaResponseCallback& callback,
155 const extensions::Extension* extension) {
156 DCHECK_CURRENTLY_ON(BrowserThread::UI);
157
158 for (MediaAccessHandler* handler : media_access_handlers_) {
159 if (handler->SupportsStreamType(request.video_type, extension) ||
160 handler->SupportsStreamType(request.audio_type, extension)) {
161 handler->HandleRequest(web_contents, request, callback, extension);
162 return;
163 }
164 }
165 callback.Run(content::MediaStreamDevices(),
166 content::MEDIA_DEVICE_NOT_SUPPORTED, nullptr);
167 }
168
169 bool MediaCaptureDevicesDispatcher::CheckMediaAccessPermission(
170 content::WebContents* web_contents,
171 const GURL& security_origin,
172 content::MediaStreamType type) {
173 DCHECK_CURRENTLY_ON(BrowserThread::UI);
174 return CheckMediaAccessPermission(web_contents, security_origin, type,
175 nullptr);
176 }
177
178 bool MediaCaptureDevicesDispatcher::CheckMediaAccessPermission(
179 content::WebContents* web_contents,
180 const GURL& security_origin,
181 content::MediaStreamType type,
182 const extensions::Extension* extension) {
183 DCHECK_CURRENTLY_ON(BrowserThread::UI);
184 for (MediaAccessHandler* handler : media_access_handlers_) {
185 if (handler->SupportsStreamType(type, extension)) {
186 return handler->CheckMediaAccessPermission(web_contents, security_origin,
187 type, extension);
188 }
189 }
190 return false;
191 }
192
193 void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile(
194 Profile* profile,
195 bool audio,
196 bool video,
197 content::MediaStreamDevices* devices) {
198 DCHECK_CURRENTLY_ON(BrowserThread::UI);
199 DCHECK(audio || video);
200
201 PrefService* prefs = profile->GetPrefs();
202 std::string default_device;
203 if (audio) {
204 default_device = prefs->GetString(prefs::kDefaultAudioCaptureDevice);
205 const content::MediaStreamDevice* device =
206 GetRequestedAudioDevice(default_device);
207 if (!device)
208 device = GetFirstAvailableAudioDevice();
209 if (device)
210 devices->push_back(*device);
211 }
212
213 if (video) {
214 default_device = prefs->GetString(prefs::kDefaultVideoCaptureDevice);
215 const content::MediaStreamDevice* device =
216 GetRequestedVideoDevice(default_device);
217 if (!device)
218 device = GetFirstAvailableVideoDevice();
219 if (device)
220 devices->push_back(*device);
221 }
222 }
223
224 const content::MediaStreamDevice*
225 MediaCaptureDevicesDispatcher::GetRequestedAudioDevice(
226 const std::string& requested_audio_device_id) {
227 DCHECK_CURRENTLY_ON(BrowserThread::UI);
228 const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
229 const content::MediaStreamDevice* const device =
230 FindDeviceWithId(audio_devices, requested_audio_device_id);
231 return device;
232 }
233
234 const content::MediaStreamDevice*
235 MediaCaptureDevicesDispatcher::GetFirstAvailableAudioDevice() {
236 DCHECK_CURRENTLY_ON(BrowserThread::UI);
237 const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
238 if (audio_devices.empty())
239 return NULL;
240 return &(*audio_devices.begin());
241 }
242
243 const content::MediaStreamDevice*
244 MediaCaptureDevicesDispatcher::GetRequestedVideoDevice(
245 const std::string& requested_video_device_id) {
246 DCHECK_CURRENTLY_ON(BrowserThread::UI);
247 const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
248 const content::MediaStreamDevice* const device =
249 FindDeviceWithId(video_devices, requested_video_device_id);
250 return device;
251 }
252
253 const content::MediaStreamDevice*
254 MediaCaptureDevicesDispatcher::GetFirstAvailableVideoDevice() {
255 DCHECK_CURRENTLY_ON(BrowserThread::UI);
256 const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
257 if (video_devices.empty())
258 return NULL;
259 return &(*video_devices.begin());
260 }
261
262 void MediaCaptureDevicesDispatcher::DisableDeviceEnumerationForTesting() {
263 is_device_enumeration_disabled_ = true;
264 }
265
266 scoped_refptr<MediaStreamCaptureIndicator>
267 MediaCaptureDevicesDispatcher::GetMediaStreamCaptureIndicator() {
268 return media_stream_capture_indicator_;
269 }
270
271 DesktopStreamsRegistry*
272 MediaCaptureDevicesDispatcher::GetDesktopStreamsRegistry() {
273 if (!desktop_streams_registry_)
274 desktop_streams_registry_.reset(new DesktopStreamsRegistry());
275 return desktop_streams_registry_.get();
276 }
277
278 void MediaCaptureDevicesDispatcher::OnAudioCaptureDevicesChanged() {
279 DCHECK_CURRENTLY_ON(BrowserThread::IO);
280 BrowserThread::PostTask(
281 BrowserThread::UI, FROM_HERE,
282 base::Bind(
283 &MediaCaptureDevicesDispatcher::NotifyAudioDevicesChangedOnUIThread,
284 base::Unretained(this)));
285 }
286
287 void MediaCaptureDevicesDispatcher::OnVideoCaptureDevicesChanged() {
288 DCHECK_CURRENTLY_ON(BrowserThread::IO);
289 BrowserThread::PostTask(
290 BrowserThread::UI, FROM_HERE,
291 base::Bind(
292 &MediaCaptureDevicesDispatcher::NotifyVideoDevicesChangedOnUIThread,
293 base::Unretained(this)));
294 }
295
296 void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(
297 int render_process_id,
298 int render_frame_id,
299 int page_request_id,
300 const GURL& security_origin,
301 content::MediaStreamType stream_type,
302 content::MediaRequestState state) {
303 DCHECK_CURRENTLY_ON(BrowserThread::IO);
304 BrowserThread::PostTask(
305 BrowserThread::UI, FROM_HERE,
306 base::Bind(
307 &MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread,
308 base::Unretained(this), render_process_id, render_frame_id,
309 page_request_id, security_origin, stream_type, state));
310 }
311
312 void MediaCaptureDevicesDispatcher::OnCreatingAudioStream(
313 int render_process_id,
314 int render_frame_id) {
315 DCHECK_CURRENTLY_ON(BrowserThread::IO);
316 BrowserThread::PostTask(
317 BrowserThread::UI, FROM_HERE,
318 base::Bind(
319 &MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread,
320 base::Unretained(this), render_process_id, render_frame_id));
321 }
322
323 void MediaCaptureDevicesDispatcher::NotifyAudioDevicesChangedOnUIThread() {
324 MediaStreamDevices devices = GetAudioCaptureDevices();
325 FOR_EACH_OBSERVER(Observer, observers_,
326 OnUpdateAudioDevices(devices));
327 }
328
329 void MediaCaptureDevicesDispatcher::NotifyVideoDevicesChangedOnUIThread() {
330 MediaStreamDevices devices = GetVideoCaptureDevices();
331 FOR_EACH_OBSERVER(Observer, observers_,
332 OnUpdateVideoDevices(devices));
333 }
334
335 void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread(
336 int render_process_id,
337 int render_frame_id,
338 int page_request_id,
339 const GURL& security_origin,
340 content::MediaStreamType stream_type,
341 content::MediaRequestState state) {
342 for (MediaAccessHandler* handler : media_access_handlers_) {
343 if (handler->SupportsStreamType(stream_type, nullptr)) {
344 handler->UpdateMediaRequestState(render_process_id, render_frame_id,
345 page_request_id, stream_type, state);
346 break;
347 }
348 }
349
350 #if defined(OS_CHROMEOS)
351 if (IsOriginForCasting(security_origin) && IsVideoMediaType(stream_type)) {
352 // Notify ash that casting state has changed.
353 if (state == content::MEDIA_REQUEST_STATE_DONE) {
354 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(true);
355 } else if (state == content::MEDIA_REQUEST_STATE_CLOSING) {
356 ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(false);
357 }
358 }
359 #endif
360
361 FOR_EACH_OBSERVER(Observer, observers_,
362 OnRequestUpdate(render_process_id,
363 render_frame_id,
364 stream_type,
365 state));
366 }
367
368 void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread(
369 int render_process_id,
370 int render_frame_id) {
371 DCHECK_CURRENTLY_ON(BrowserThread::UI);
372 FOR_EACH_OBSERVER(Observer, observers_,
373 OnCreatingAudioStream(render_process_id, render_frame_id));
374 }
375
376 bool MediaCaptureDevicesDispatcher::IsInsecureCapturingInProgress(
377 int render_process_id,
378 int render_frame_id) {
379 DCHECK_CURRENTLY_ON(BrowserThread::UI);
380 #if defined(ENABLE_EXTENSIONS)
381 for (MediaAccessHandler* handler : media_access_handlers_) {
382 if (handler->SupportsStreamType(content::MEDIA_DESKTOP_VIDEO_CAPTURE,
383 nullptr) ||
384 handler->SupportsStreamType(content::MEDIA_TAB_VIDEO_CAPTURE,
385 nullptr)) {
386 if (ToCaptureAccessHandlerBase(handler)->IsInsecureCapturingInProgress(
387 render_process_id, render_frame_id))
388 return true;
389 }
390 }
391 #endif
392 return false;
393 }
394
395 void MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices(
396 const MediaStreamDevices& devices) {
397 test_audio_devices_ = devices;
398 }
399
400 void MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices(
401 const MediaStreamDevices& devices) {
402 test_video_devices_ = devices;
403 }
404
405 void MediaCaptureDevicesDispatcher::OnSetCapturingLinkSecured(
406 int render_process_id,
407 int render_frame_id,
408 int page_request_id,
409 content::MediaStreamType stream_type,
410 bool is_secure) {
411 DCHECK_CURRENTLY_ON(BrowserThread::IO);
412 if (stream_type != content::MEDIA_TAB_VIDEO_CAPTURE &&
413 stream_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE)
414 return;
415
416 BrowserThread::PostTask(
417 BrowserThread::UI, FROM_HERE,
418 base::Bind(&MediaCaptureDevicesDispatcher::UpdateCapturingLinkSecured,
419 base::Unretained(this), render_process_id, render_frame_id,
420 page_request_id, stream_type, is_secure));
421 }
422
423 void MediaCaptureDevicesDispatcher::UpdateCapturingLinkSecured(
424 int render_process_id,
425 int render_frame_id,
426 int page_request_id,
427 content::MediaStreamType stream_type,
428 bool is_secure) {
429 DCHECK_CURRENTLY_ON(BrowserThread::UI);
430 if (stream_type != content::MEDIA_TAB_VIDEO_CAPTURE &&
431 stream_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE)
432 return;
433
434 #if defined(ENABLE_EXTENSIONS)
435 for (MediaAccessHandler* handler : media_access_handlers_) {
436 if (handler->SupportsStreamType(stream_type, nullptr)) {
437 ToCaptureAccessHandlerBase(handler)->UpdateCapturingLinkSecured(
438 render_process_id, render_frame_id, page_request_id, is_secure);
439 break;
440 }
441 }
442 #endif
443 }
OLDNEW
« no previous file with comments | « chrome/browser/media/media_capture_devices_dispatcher.h ('k') | chrome/browser/media/media_permission.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698