Chromium Code Reviews| 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 |