| 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" |
| 11 #include "base/sha1.h" | 11 #include "base/sha1.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" | 15 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" |
| 16 #include "chrome/browser/media/audio_stream_indicator.h" | 16 #include "chrome/browser/media/audio_stream_indicator.h" |
| 17 #include "chrome/browser/media/desktop_streams_registry.h" | 17 #include "chrome/browser/media/desktop_streams_registry.h" |
| 18 #include "chrome/browser/media/media_stream_capture_indicator.h" | 18 #include "chrome/browser/media/media_stream_capture_indicator.h" |
| 19 #include "chrome/browser/media/media_stream_infobar_delegate.h" | 19 #include "chrome/browser/media/media_stream_infobar_delegate.h" |
| 20 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
| 21 #include "chrome/browser/ui/screen_capture_notification_ui.h" | 21 #include "chrome/browser/ui/screen_capture_notification_ui.h" |
| 22 #include "chrome/browser/ui/simple_message_box.h" | 22 #include "chrome/browser/ui/simple_message_box.h" |
| 23 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
| 24 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| 25 #include "components/user_prefs/pref_registry_syncable.h" | 25 #include "components/user_prefs/pref_registry_syncable.h" |
| 26 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/desktop_media_id.h" |
| 27 #include "content/public/browser/media_devices_monitor.h" | 28 #include "content/public/browser/media_devices_monitor.h" |
| 28 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
| 29 #include "content/public/browser/notification_source.h" | 30 #include "content/public/browser/notification_source.h" |
| 30 #include "content/public/browser/notification_types.h" | 31 #include "content/public/browser/notification_types.h" |
| 31 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 32 #include "content/public/common/desktop_media_id.h" | |
| 33 #include "content/public/common/media_stream_request.h" | 33 #include "content/public/common/media_stream_request.h" |
| 34 #include "extensions/common/constants.h" | 34 #include "extensions/common/constants.h" |
| 35 #include "extensions/common/extension.h" | 35 #include "extensions/common/extension.h" |
| 36 #include "grit/generated_resources.h" | 36 #include "grit/generated_resources.h" |
| 37 #include "media/audio/audio_manager_base.h" | 37 #include "media/audio/audio_manager_base.h" |
| 38 #include "ui/base/l10n/l10n_util.h" | 38 #include "ui/base/l10n/l10n_util.h" |
| 39 | 39 |
| 40 #if defined(OS_CHROMEOS) |
| 41 #include "ash/shell.h" |
| 42 #endif // defined(OS_CHROMEOS) |
| 43 |
| 40 using content::BrowserThread; | 44 using content::BrowserThread; |
| 41 using content::MediaStreamDevices; | 45 using content::MediaStreamDevices; |
| 42 | 46 |
| 43 namespace { | 47 namespace { |
| 44 | 48 |
| 45 // Finds a device in |devices| that has |device_id|, or NULL if not found. | 49 // Finds a device in |devices| that has |device_id|, or NULL if not found. |
| 46 const content::MediaStreamDevice* FindDeviceWithId( | 50 const content::MediaStreamDevice* FindDeviceWithId( |
| 47 const content::MediaStreamDevices& devices, | 51 const content::MediaStreamDevices& devices, |
| 48 const std::string& device_id) { | 52 const std::string& device_id) { |
| 49 content::MediaStreamDevices::const_iterator iter = devices.begin(); | 53 content::MediaStreamDevices::const_iterator iter = devices.begin(); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 const content::MediaResponseCallback& callback, | 232 const content::MediaResponseCallback& callback, |
| 229 const extensions::Extension* extension) { | 233 const extensions::Extension* extension) { |
| 230 content::MediaStreamDevices devices; | 234 content::MediaStreamDevices devices; |
| 231 scoped_ptr<content::MediaStreamUI> ui; | 235 scoped_ptr<content::MediaStreamUI> ui; |
| 232 | 236 |
| 233 if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) { | 237 if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| 234 callback.Run(devices, ui.Pass()); | 238 callback.Run(devices, ui.Pass()); |
| 235 return; | 239 return; |
| 236 } | 240 } |
| 237 | 241 |
| 238 // First check if Desktop Capture API (i.e. | 242 // If the device id wasn't specified then this is a screen capture request |
| 239 // chrome.desktopCapture.chooseDesktopMedia()) was used to generate device Id. | 243 // (i.e. chooseDesktopMedia() API wasn't used to generate device id). |
| 244 if (request.requested_video_device_id.empty()) { |
| 245 ProcessScreenCaptureAccessRequest( |
| 246 web_contents, request, callback, extension); |
| 247 return; |
| 248 } |
| 249 |
| 250 // Resolve DesktopMediaID for the specified device id. |
| 240 content::DesktopMediaID media_id = | 251 content::DesktopMediaID media_id = |
| 241 GetDesktopStreamsRegistry()->RequestMediaForStreamId( | 252 GetDesktopStreamsRegistry()->RequestMediaForStreamId( |
| 242 request.requested_video_device_id, request.render_process_id, | 253 request.requested_video_device_id, request.render_process_id, |
| 243 request.render_view_id, request.security_origin); | 254 request.render_view_id, request.security_origin); |
| 244 | 255 |
| 245 // If the id wasn't generated using Desktop Capture API then process it as a | 256 // Received invalid device id. |
| 246 // screen capture request. | |
| 247 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { | 257 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { |
| 248 ProcessScreenCaptureAccessRequest( | 258 callback.Run(devices, ui.Pass()); |
| 249 web_contents, request, callback, extension); | |
| 250 return; | 259 return; |
| 251 } | 260 } |
| 252 | 261 |
| 253 // Add selected desktop source to the list. | 262 // Add selected desktop source to the list. |
| 254 devices.push_back(content::MediaStreamDevice( | 263 devices.push_back(content::MediaStreamDevice( |
| 255 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), | 264 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), |
| 256 std::string())); | 265 std::string())); |
| 257 | 266 |
| 258 bool loopback_audio_supported = false; | 267 bool loopback_audio_supported = false; |
| 259 #if defined(USE_CRAS) || defined(OS_WIN) | 268 #if defined(USE_CRAS) || defined(OS_WIN) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 280 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( | 289 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( |
| 281 content::WebContents* web_contents, | 290 content::WebContents* web_contents, |
| 282 const content::MediaStreamRequest& request, | 291 const content::MediaStreamRequest& request, |
| 283 const content::MediaResponseCallback& callback, | 292 const content::MediaResponseCallback& callback, |
| 284 const extensions::Extension* extension) { | 293 const extensions::Extension* extension) { |
| 285 content::MediaStreamDevices devices; | 294 content::MediaStreamDevices devices; |
| 286 scoped_ptr<content::MediaStreamUI> ui; | 295 scoped_ptr<content::MediaStreamUI> ui; |
| 287 | 296 |
| 288 DCHECK_EQ(request.video_type, content::MEDIA_DESKTOP_VIDEO_CAPTURE); | 297 DCHECK_EQ(request.video_type, content::MEDIA_DESKTOP_VIDEO_CAPTURE); |
| 289 | 298 |
| 290 content::DesktopMediaID media_id = | |
| 291 content::DesktopMediaID::Parse(request.requested_video_device_id); | |
| 292 if (media_id.is_null()) { | |
| 293 LOG(ERROR) << "Invalid desktop media ID: " | |
| 294 << request.requested_video_device_id; | |
| 295 callback.Run(devices, ui.Pass()); | |
| 296 return; | |
| 297 } | |
| 298 | |
| 299 // Only screen capture can be requested without using desktop media picker. | |
| 300 if (media_id.type != content::DesktopMediaID::TYPE_SCREEN) { | |
| 301 LOG(ERROR) << "Unsupported desktop media ID: " | |
| 302 << request.requested_video_device_id; | |
| 303 callback.Run(devices, ui.Pass()); | |
| 304 return; | |
| 305 } | |
| 306 | |
| 307 bool loopback_audio_supported = false; | 299 bool loopback_audio_supported = false; |
| 308 #if defined(USE_CRAS) || defined(OS_WIN) | 300 #if defined(USE_CRAS) || defined(OS_WIN) |
| 309 // Currently loopback audio capture is supported only on Windows and ChromeOS. | 301 // Currently loopback audio capture is supported only on Windows and ChromeOS. |
| 310 loopback_audio_supported = true; | 302 loopback_audio_supported = true; |
| 311 #endif | 303 #endif |
| 312 | 304 |
| 313 const bool component_extension = | 305 const bool component_extension = |
| 314 extension && extension->location() == extensions::Manifest::COMPONENT; | 306 extension && extension->location() == extensions::Manifest::COMPONENT; |
| 315 | 307 |
| 316 const bool screen_capture_enabled = | 308 const bool screen_capture_enabled = |
| (...skipping 25 matching lines...) Expand all Loading... |
| 342 chrome::MessageBoxResult result = chrome::ShowMessageBox( | 334 chrome::MessageBoxResult result = chrome::ShowMessageBox( |
| 343 NULL, | 335 NULL, |
| 344 l10n_util::GetStringFUTF16( | 336 l10n_util::GetStringFUTF16( |
| 345 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name), | 337 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name), |
| 346 confirmation_text, | 338 confirmation_text, |
| 347 chrome::MESSAGE_BOX_TYPE_QUESTION); | 339 chrome::MESSAGE_BOX_TYPE_QUESTION); |
| 348 user_approved = (result == chrome::MESSAGE_BOX_RESULT_YES); | 340 user_approved = (result == chrome::MESSAGE_BOX_RESULT_YES); |
| 349 } | 341 } |
| 350 | 342 |
| 351 if (user_approved || component_extension) { | 343 if (user_approved || component_extension) { |
| 352 devices.push_back(content::MediaStreamDevice( | 344 content::DesktopMediaID screen_id; |
| 353 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), "Screen")); | 345 #if defined(OS_CHROMEOS) |
| 346 screen_id = content::DesktopMediaID::RegisterAuraWindow( |
| 347 ash::Shell::GetInstance()->GetPrimaryRootWindow()); |
| 348 #else // defined(OS_CHROMEOS) |
| 349 screen_id = |
| 350 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0); |
| 351 #endif // !defined(OS_CHROMEOS) |
| 352 devices.push_back( |
| 353 content::MediaStreamDevice(content::MEDIA_DESKTOP_VIDEO_CAPTURE, |
| 354 screen_id.ToString(), "Screen")); |
| 354 if (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && | 355 if (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && |
| 355 loopback_audio_supported) { | 356 loopback_audio_supported) { |
| 356 // Use the special loopback device ID for system audio capture. | 357 // Use the special loopback device ID for system audio capture. |
| 357 devices.push_back(content::MediaStreamDevice( | 358 devices.push_back(content::MediaStreamDevice( |
| 358 content::MEDIA_LOOPBACK_AUDIO_CAPTURE, | 359 content::MEDIA_LOOPBACK_AUDIO_CAPTURE, |
| 359 media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); | 360 media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); |
| 360 } | 361 } |
| 361 } | 362 } |
| 362 } | 363 } |
| 363 | 364 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 state)); | 709 state)); |
| 709 } | 710 } |
| 710 | 711 |
| 711 void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread( | 712 void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread( |
| 712 int render_process_id, | 713 int render_process_id, |
| 713 int render_view_id) { | 714 int render_view_id) { |
| 714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 715 FOR_EACH_OBSERVER(Observer, observers_, | 716 FOR_EACH_OBSERVER(Observer, observers_, |
| 716 OnCreatingAudioStream(render_process_id, render_view_id)); | 717 OnCreatingAudioStream(render_process_id, render_view_id)); |
| 717 } | 718 } |
| OLD | NEW |