OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/media/media_capture_devices_dispatcher.h" | 5 #include "chrome/browser/media/media_capture_devices_dispatcher.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/prefs/scoped_user_pref_update.h" | 10 #include "base/prefs/scoped_user_pref_update.h" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 // Use extension name as title for extensions and origin for drive-by web. | 104 // Use extension name as title for extensions and origin for drive-by web. |
105 std::string title; | 105 std::string title; |
106 if (extension) { | 106 if (extension) { |
107 title = extension->name(); | 107 title = extension->name(); |
108 } else { | 108 } else { |
109 title = web_contents->GetURL().GetOrigin().spec(); | 109 title = web_contents->GetURL().GetOrigin().spec(); |
110 } | 110 } |
111 return UTF8ToUTF16(title); | 111 return UTF8ToUTF16(title); |
112 } | 112 } |
113 | 113 |
114 // Helper to get list of media stream devices for desktop capture in |devices|. | |
115 // Registers to display notification if |display_notification| is true. | |
116 // Returns an instance of MediaStreamUI to be passed to content layer. | |
117 scoped_ptr<content::MediaStreamUI> GetDevicesForDesktopCapture( | |
118 content::MediaStreamDevices& devices, | |
119 content::DesktopMediaID media_id, | |
120 bool capture_audio, | |
121 bool display_notification, | |
122 base::string16 application_title) { | |
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
124 scoped_ptr<content::MediaStreamUI> ui; | |
125 | |
126 // Add selected desktop source to the list. | |
127 devices.push_back(content::MediaStreamDevice( | |
128 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), "Screen")); | |
129 if (capture_audio) { | |
130 // Use the special loopback device ID for system audio capture. | |
131 devices.push_back(content::MediaStreamDevice( | |
132 content::MEDIA_LOOPBACK_AUDIO_CAPTURE, | |
133 media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); | |
134 } | |
135 | |
136 // If required, register to display the notification for stream capture. | |
137 if (display_notification) { | |
138 ui = ScreenCaptureNotificationUI::Create(l10n_util::GetStringFUTF16( | |
139 IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_TEXT, | |
140 application_title)); | |
141 } | |
142 | |
143 return ui.Pass(); | |
144 } | |
145 | |
114 } // namespace | 146 } // namespace |
115 | 147 |
116 MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest( | 148 MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest( |
117 const content::MediaStreamRequest& request, | 149 const content::MediaStreamRequest& request, |
118 const content::MediaResponseCallback& callback) | 150 const content::MediaResponseCallback& callback) |
119 : request(request), | 151 : request(request), |
120 callback(callback) { | 152 callback(callback) { |
121 } | 153 } |
122 | 154 |
123 MediaCaptureDevicesDispatcher::PendingAccessRequest::~PendingAccessRequest() {} | 155 MediaCaptureDevicesDispatcher::PendingAccessRequest::~PendingAccessRequest() {} |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 request.render_view_id, request.security_origin); | 276 request.render_view_id, request.security_origin); |
245 | 277 |
246 // If the id wasn't generated using Desktop Capture API then process it as a | 278 // If the id wasn't generated using Desktop Capture API then process it as a |
247 // screen capture request. | 279 // screen capture request. |
248 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { | 280 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { |
249 ProcessScreenCaptureAccessRequest( | 281 ProcessScreenCaptureAccessRequest( |
250 web_contents, request, callback, extension); | 282 web_contents, request, callback, extension); |
251 return; | 283 return; |
252 } | 284 } |
253 | 285 |
254 // Add selected desktop source to the list. | |
255 devices.push_back(content::MediaStreamDevice( | |
256 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), | |
257 std::string())); | |
258 | |
259 bool loopback_audio_supported = false; | 286 bool loopback_audio_supported = false; |
260 #if defined(USE_CRAS) || defined(OS_WIN) | 287 #if defined(USE_CRAS) || defined(OS_WIN) |
261 // Currently loopback audio capture is supported only on Windows and ChromeOS. | 288 // Currently loopback audio capture is supported only on Windows and ChromeOS. |
262 loopback_audio_supported = true; | 289 loopback_audio_supported = true; |
263 #endif | 290 #endif |
264 | 291 |
265 // Audio is only supported for screen capture streams. | 292 // Audio is only supported for screen capture streams. |
266 if (media_id.type == content::DesktopMediaID::TYPE_SCREEN && | 293 bool capture_audio = |
267 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && | 294 (media_id.type == content::DesktopMediaID::TYPE_SCREEN && |
268 loopback_audio_supported) { | 295 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && |
269 devices.push_back(content::MediaStreamDevice( | 296 loopback_audio_supported); |
270 content::MEDIA_LOOPBACK_AUDIO_CAPTURE, | |
271 media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); | |
272 } | |
273 | 297 |
274 ui = ScreenCaptureNotificationUI::Create(l10n_util::GetStringFUTF16( | 298 ui = GetDevicesForDesktopCapture( |
275 IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_TEXT, | 299 devices, media_id, capture_audio, true, |
276 GetApplicationTitle(web_contents, extension))); | 300 GetApplicationTitle(web_contents, extension)); |
277 | 301 |
278 callback.Run(devices, ui.Pass()); | 302 callback.Run(devices, ui.Pass()); |
279 } | 303 } |
280 | 304 |
281 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( | 305 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( |
282 content::WebContents* web_contents, | 306 content::WebContents* web_contents, |
283 const content::MediaStreamRequest& request, | 307 const content::MediaStreamRequest& request, |
284 const content::MediaResponseCallback& callback, | 308 const content::MediaResponseCallback& callback, |
285 const extensions::Extension* extension) { | 309 const extensions::Extension* extension) { |
286 content::MediaStreamDevices devices; | 310 content::MediaStreamDevices devices; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 request.security_origin.SchemeIsSecure() || | 347 request.security_origin.SchemeIsSecure() || |
324 request.security_origin.SchemeIs(extensions::kExtensionScheme) || | 348 request.security_origin.SchemeIs(extensions::kExtensionScheme) || |
325 CommandLine::ForCurrentProcess()->HasSwitch( | 349 CommandLine::ForCurrentProcess()->HasSwitch( |
326 switches::kAllowHttpScreenCapture); | 350 switches::kAllowHttpScreenCapture); |
327 | 351 |
328 // Approve request only when the following conditions are met: | 352 // Approve request only when the following conditions are met: |
329 // 1. Screen capturing is enabled via command line switch or white-listed for | 353 // 1. Screen capturing is enabled via command line switch or white-listed for |
330 // the given origin. | 354 // the given origin. |
331 // 2. Request comes from a page with a secure origin or from an extension. | 355 // 2. Request comes from a page with a secure origin or from an extension. |
332 if (screen_capture_enabled && origin_is_secure) { | 356 if (screen_capture_enabled && origin_is_secure) { |
357 // Get title of the calling application prior to showing the message box. | |
358 // chrome::ShowMessageBox() starts a nested message loop which may allow | |
359 // |web_contents| to be destroyed on the UI thread before the message box | |
360 // is closed. See http://crbug.com/326690. | |
361 base::string16 application_title = | |
362 GetApplicationTitle(web_contents, extension); | |
Ami GONE FROM CHROMIUM
2013/12/10 20:18:28
Please follow this with
web_contents = NULL;
to b
hshi1
2013/12/10 20:22:37
Done.
| |
363 | |
333 // For component extensions, bypass message box. | 364 // For component extensions, bypass message box. |
334 bool user_approved = false; | 365 bool user_approved = false; |
335 if (!component_extension) { | 366 if (!component_extension) { |
336 base::string16 application_name = UTF8ToUTF16( | 367 base::string16 application_name = UTF8ToUTF16( |
337 extension ? extension->name() : request.security_origin.spec()); | 368 extension ? extension->name() : request.security_origin.spec()); |
338 base::string16 confirmation_text = l10n_util::GetStringFUTF16( | 369 base::string16 confirmation_text = l10n_util::GetStringFUTF16( |
339 request.audio_type == content::MEDIA_NO_SERVICE ? | 370 request.audio_type == content::MEDIA_NO_SERVICE ? |
340 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT : | 371 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT : |
341 IDS_MEDIA_SCREEN_AND_AUDIO_CAPTURE_CONFIRMATION_TEXT, | 372 IDS_MEDIA_SCREEN_AND_AUDIO_CAPTURE_CONFIRMATION_TEXT, |
342 application_name); | 373 application_name); |
343 chrome::MessageBoxResult result = chrome::ShowMessageBox( | 374 chrome::MessageBoxResult result = chrome::ShowMessageBox( |
344 NULL, | 375 NULL, |
345 l10n_util::GetStringFUTF16( | 376 l10n_util::GetStringFUTF16( |
346 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name), | 377 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name), |
347 confirmation_text, | 378 confirmation_text, |
348 chrome::MESSAGE_BOX_TYPE_QUESTION); | 379 chrome::MESSAGE_BOX_TYPE_QUESTION); |
349 user_approved = (result == chrome::MESSAGE_BOX_RESULT_YES); | 380 user_approved = (result == chrome::MESSAGE_BOX_RESULT_YES); |
350 } | 381 } |
351 | 382 |
352 if (user_approved || component_extension) { | 383 if (user_approved || component_extension) { |
353 devices.push_back(content::MediaStreamDevice( | 384 bool capture_audio = |
354 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), "Screen")); | 385 (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && |
355 if (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && | 386 loopback_audio_supported); |
356 loopback_audio_supported) { | 387 |
357 // Use the special loopback device ID for system audio capture. | 388 // Unless we're being invoked from a component extension, register to |
358 devices.push_back(content::MediaStreamDevice( | 389 // display the notification for stream capture. |
359 content::MEDIA_LOOPBACK_AUDIO_CAPTURE, | 390 bool display_notification = !component_extension; |
360 media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); | 391 |
361 } | 392 ui = GetDevicesForDesktopCapture(devices, media_id, capture_audio, |
393 display_notification, application_title); | |
362 } | 394 } |
363 } | 395 } |
364 | 396 |
365 // Unless we're being invoked from a component extension, register to display | |
366 // the notification for stream capture. | |
367 if (!devices.empty() && !component_extension) { | |
368 ui = ScreenCaptureNotificationUI::Create(l10n_util::GetStringFUTF16( | |
369 IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_TEXT, | |
370 GetApplicationTitle(web_contents, extension))); | |
371 } | |
372 | |
373 callback.Run(devices, ui.Pass()); | 397 callback.Run(devices, ui.Pass()); |
374 } | 398 } |
375 | 399 |
376 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( | 400 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( |
377 content::WebContents* web_contents, | 401 content::WebContents* web_contents, |
378 const content::MediaStreamRequest& request, | 402 const content::MediaStreamRequest& request, |
379 const content::MediaResponseCallback& callback, | 403 const content::MediaResponseCallback& callback, |
380 const extensions::Extension* extension) { | 404 const extensions::Extension* extension) { |
381 content::MediaStreamDevices devices; | 405 content::MediaStreamDevices devices; |
382 scoped_ptr<content::MediaStreamUI> ui; | 406 scoped_ptr<content::MediaStreamUI> ui; |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
737 int render_view_id) { | 761 int render_view_id) { |
738 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
739 FOR_EACH_OBSERVER(Observer, observers_, | 763 FOR_EACH_OBSERVER(Observer, observers_, |
740 OnCreatingAudioStream(render_process_id, render_view_id)); | 764 OnCreatingAudioStream(render_process_id, render_view_id)); |
741 } | 765 } |
742 | 766 |
743 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() { | 767 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() { |
744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 768 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
745 return desktop_capture_sessions_.size() > 0; | 769 return desktop_capture_sessions_.size() > 0; |
746 } | 770 } |
OLD | NEW |