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/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
| 10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 #include "content/public/browser/desktop_media_id.h" | 35 #include "content/public/browser/desktop_media_id.h" |
| 36 #include "content/public/browser/media_capture_devices.h" | 36 #include "content/public/browser/media_capture_devices.h" |
| 37 #include "content/public/browser/notification_service.h" | 37 #include "content/public/browser/notification_service.h" |
| 38 #include "content/public/browser/notification_source.h" | 38 #include "content/public/browser/notification_source.h" |
| 39 #include "content/public/browser/notification_types.h" | 39 #include "content/public/browser/notification_types.h" |
| 40 #include "content/public/browser/render_frame_host.h" | 40 #include "content/public/browser/render_frame_host.h" |
| 41 #include "content/public/browser/render_process_host.h" | 41 #include "content/public/browser/render_process_host.h" |
| 42 #include "content/public/browser/web_contents.h" | 42 #include "content/public/browser/web_contents.h" |
| 43 #include "content/public/common/media_stream_request.h" | 43 #include "content/public/common/media_stream_request.h" |
| 44 #include "extensions/common/constants.h" | 44 #include "extensions/common/constants.h" |
| 45 #include "extensions/common/extension.h" | |
| 46 #include "extensions/common/permissions/permissions_data.h" | |
| 47 #include "media/audio/audio_manager_base.h" | 45 #include "media/audio/audio_manager_base.h" |
| 48 #include "media/base/media_switches.h" | 46 #include "media/base/media_switches.h" |
| 49 #include "net/base/net_util.h" | 47 #include "net/base/net_util.h" |
| 50 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h" | 48 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h" |
| 51 #include "ui/base/l10n/l10n_util.h" | 49 #include "ui/base/l10n/l10n_util.h" |
| 52 | 50 |
| 53 #if defined(OS_CHROMEOS) | 51 #if defined(OS_CHROMEOS) |
| 54 #include "ash/shell.h" | 52 #include "ash/shell.h" |
| 55 #endif // defined(OS_CHROMEOS) | 53 #endif // defined(OS_CHROMEOS) |
| 56 | 54 |
| 57 | |
| 58 #if defined(ENABLE_EXTENSIONS) | 55 #if defined(ENABLE_EXTENSIONS) |
| 59 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" | 56 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" |
| 60 #include "chrome/browser/extensions/extension_service.h" | 57 #include "chrome/browser/extensions/extension_service.h" |
| 61 #include "extensions/browser/app_window/app_window.h" | 58 #include "extensions/browser/app_window/app_window.h" |
| 62 #include "extensions/browser/app_window/app_window_registry.h" | 59 #include "extensions/browser/app_window/app_window_registry.h" |
| 63 #include "extensions/browser/extension_system.h" | 60 #include "extensions/browser/extension_system.h" |
| 61 #include "extensions/common/extension.h" | |
| 62 #include "extensions/common/permissions/permissions_data.h" | |
| 64 #endif | 63 #endif |
| 65 | 64 |
| 66 using content::BrowserThread; | 65 using content::BrowserThread; |
| 67 using content::MediaCaptureDevices; | 66 using content::MediaCaptureDevices; |
| 68 using content::MediaStreamDevices; | 67 using content::MediaStreamDevices; |
| 69 | 68 |
| 70 namespace { | 69 namespace { |
| 71 | 70 |
| 72 // A finch experiment to enable the permission bubble for media requests only. | 71 // A finch experiment to enable the permission bubble for media requests only. |
| 73 bool MediaStreamPermissionBubbleExperimentEnabled() { | 72 bool MediaStreamPermissionBubbleExperimentEnabled() { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 85 const std::string& device_id) { | 84 const std::string& device_id) { |
| 86 content::MediaStreamDevices::const_iterator iter = devices.begin(); | 85 content::MediaStreamDevices::const_iterator iter = devices.begin(); |
| 87 for (; iter != devices.end(); ++iter) { | 86 for (; iter != devices.end(); ++iter) { |
| 88 if (iter->id == device_id) { | 87 if (iter->id == device_id) { |
| 89 return &(*iter); | 88 return &(*iter); |
| 90 } | 89 } |
| 91 } | 90 } |
| 92 return NULL; | 91 return NULL; |
| 93 } | 92 } |
| 94 | 93 |
| 94 #if defined(ENABLE_EXTENSIONS) | |
| 95 // This is a short-term solution to grant camera and/or microphone access to | 95 // This is a short-term solution to grant camera and/or microphone access to |
| 96 // extensions: | 96 // extensions: |
| 97 // 1. Virtual keyboard extension. | 97 // 1. Virtual keyboard extension. |
| 98 // 2. Google Voice Search Hotword extension. | 98 // 2. Google Voice Search Hotword extension. |
| 99 // 3. Flutter gesture recognition extension. | 99 // 3. Flutter gesture recognition extension. |
| 100 // 4. TODO(smus): Airbender experiment 1. | 100 // 4. TODO(smus): Airbender experiment 1. |
| 101 // 5. TODO(smus): Airbender experiment 2. | 101 // 5. TODO(smus): Airbender experiment 2. |
| 102 // 6. Hotwording component extension. | 102 // 6. Hotwording component extension. |
| 103 // Once http://crbug.com/292856 is fixed, remove this whitelist. | 103 // Once http://crbug.com/292856 is fixed, remove this whitelist. |
| 104 bool IsMediaRequestWhitelistedForExtension( | 104 bool IsMediaRequestWhitelistedForExtension( |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 125 origin.spec() == "chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/" || | 125 origin.spec() == "chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/" || |
| 126 // Canary | 126 // Canary |
| 127 origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" || | 127 origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" || |
| 128 // Beta (internal) | 128 // Beta (internal) |
| 129 origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" || | 129 origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" || |
| 130 // Google Cast Beta | 130 // Google Cast Beta |
| 131 origin.spec() == "chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/" || | 131 origin.spec() == "chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm/" || |
| 132 // Google Cast Stable | 132 // Google Cast Stable |
| 133 origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/"; | 133 origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/"; |
| 134 } | 134 } |
| 135 #endif // defined(ENABLE_EXTENSIONS) | |
| 135 | 136 |
| 136 // Helper to get title of the calling application shown in the screen capture | 137 // Helper to get title of the calling application shown in the screen capture |
| 137 // notification. | 138 // notification. |
| 138 base::string16 GetApplicationTitle(content::WebContents* web_contents, | 139 base::string16 GetApplicationTitle(content::WebContents* web_contents, |
| 139 const extensions::Extension* extension) { | 140 const extensions::Extension* extension) { |
| 140 // Use extension name as title for extensions and host/origin for drive-by | 141 // Use extension name as title for extensions and host/origin for drive-by |
| 141 // web. | 142 // web. |
| 142 std::string title; | 143 std::string title; |
| 144 #if defined(ENABLE_EXTENSIONS) | |
| 143 if (extension) { | 145 if (extension) { |
| 144 title = extension->name(); | 146 title = extension->name(); |
| 145 } else { | 147 return base::UTF8ToUTF16(title); |
| 146 GURL url = web_contents->GetURL(); | |
| 147 title = url.SchemeIsSecure() ? net::GetHostAndOptionalPort(url) | |
| 148 : url.GetOrigin().spec(); | |
| 149 } | 148 } |
| 149 #endif | |
| 150 GURL url = web_contents->GetURL(); | |
| 151 title = url.SchemeIsSecure() ? net::GetHostAndOptionalPort(url) | |
| 152 : url.GetOrigin().spec(); | |
| 150 return base::UTF8ToUTF16(title); | 153 return base::UTF8ToUTF16(title); |
| 151 } | 154 } |
| 152 | 155 |
| 153 // Helper to get list of media stream devices for desktop capture in |devices|. | 156 // Helper to get list of media stream devices for desktop capture in |devices|. |
| 154 // Registers to display notification if |display_notification| is true. | 157 // Registers to display notification if |display_notification| is true. |
| 155 // Returns an instance of MediaStreamUI to be passed to content layer. | 158 // Returns an instance of MediaStreamUI to be passed to content layer. |
| 156 scoped_ptr<content::MediaStreamUI> GetDevicesForDesktopCapture( | 159 scoped_ptr<content::MediaStreamUI> GetDevicesForDesktopCapture( |
| 157 content::MediaStreamDevices& devices, | 160 content::MediaStreamDevices* devices, |
| 158 content::DesktopMediaID media_id, | 161 content::DesktopMediaID media_id, |
| 159 bool capture_audio, | 162 bool capture_audio, |
| 160 bool display_notification, | 163 bool display_notification, |
| 161 const base::string16& application_title, | 164 const base::string16& application_title, |
| 162 const base::string16& registered_extension_name) { | 165 const base::string16& registered_extension_name) { |
| 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 164 scoped_ptr<content::MediaStreamUI> ui; | 167 scoped_ptr<content::MediaStreamUI> ui; |
| 165 | 168 |
| 166 // Add selected desktop source to the list. | 169 // Add selected desktop source to the list. |
| 167 devices.push_back(content::MediaStreamDevice( | 170 devices->push_back(content::MediaStreamDevice( |
| 168 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), "Screen")); | 171 content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), "Screen")); |
| 169 if (capture_audio) { | 172 if (capture_audio) { |
| 170 // Use the special loopback device ID for system audio capture. | 173 // Use the special loopback device ID for system audio capture. |
| 171 devices.push_back(content::MediaStreamDevice( | 174 devices->push_back(content::MediaStreamDevice( |
| 172 content::MEDIA_LOOPBACK_AUDIO_CAPTURE, | 175 content::MEDIA_LOOPBACK_AUDIO_CAPTURE, |
| 173 media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); | 176 media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); |
| 174 } | 177 } |
| 175 | 178 |
| 176 // If required, register to display the notification for stream capture. | 179 // If required, register to display the notification for stream capture. |
| 177 if (display_notification) { | 180 if (display_notification) { |
| 178 if (application_title == registered_extension_name) { | 181 if (application_title == registered_extension_name) { |
| 179 ui = ScreenCaptureNotificationUI::Create(l10n_util::GetStringFUTF16( | 182 ui = ScreenCaptureNotificationUI::Create(l10n_util::GetStringFUTF16( |
| 180 IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_TEXT, | 183 IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_TEXT, |
| 181 application_title)); | 184 application_title)); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 205 window_list.begin(); | 208 window_list.begin(); |
| 206 iter != window_list.end(); ++iter) { | 209 iter != window_list.end(); ++iter) { |
| 207 if ((*iter)->web_contents() == web_contents) | 210 if ((*iter)->web_contents() == web_contents) |
| 208 return (*iter)->GetNativeWindow(); | 211 return (*iter)->GetNativeWindow(); |
| 209 } | 212 } |
| 210 | 213 |
| 211 return NULL; | 214 return NULL; |
| 212 } | 215 } |
| 213 #endif | 216 #endif |
| 214 | 217 |
| 218 #if defined(ENABLE_EXTENSIONS) | |
| 215 const extensions::Extension* GetExtensionForOrigin( | 219 const extensions::Extension* GetExtensionForOrigin( |
| 216 Profile* profile, | 220 Profile* profile, |
| 217 const GURL& security_origin) { | 221 const GURL& security_origin) { |
| 218 #if defined(ENABLE_EXTENSIONS) | |
| 219 if (!security_origin.SchemeIs(extensions::kExtensionScheme)) | 222 if (!security_origin.SchemeIs(extensions::kExtensionScheme)) |
| 220 return NULL; | 223 return NULL; |
| 221 | 224 |
| 222 ExtensionService* extensions_service = | 225 ExtensionService* extensions_service = |
| 223 extensions::ExtensionSystem::Get(profile)->extension_service(); | 226 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 224 const extensions::Extension* extension = | 227 const extensions::Extension* extension = |
| 225 extensions_service->extensions()->GetByID(security_origin.host()); | 228 extensions_service->extensions()->GetByID(security_origin.host()); |
| 226 DCHECK(extension); | 229 DCHECK(extension); |
| 227 return extension; | 230 return extension; |
| 228 #else | 231 } |
| 229 return NULL; | |
| 230 #endif | 232 #endif |
| 231 } | |
| 232 | 233 |
| 233 } // namespace | 234 } // namespace |
| 234 | 235 |
| 235 MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest( | 236 MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest( |
| 236 const content::MediaStreamRequest& request, | 237 const content::MediaStreamRequest& request, |
| 237 const content::MediaResponseCallback& callback) | 238 const content::MediaResponseCallback& callback) |
| 238 : request(request), | 239 : request(request), |
| 239 callback(callback) { | 240 callback(callback) { |
| 240 } | 241 } |
| 241 | 242 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 330 | 331 |
| 331 if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || | 332 if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || |
| 332 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE) { | 333 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE) { |
| 333 ProcessDesktopCaptureAccessRequest( | 334 ProcessDesktopCaptureAccessRequest( |
| 334 web_contents, request, callback, extension); | 335 web_contents, request, callback, extension); |
| 335 } else if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || | 336 } else if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || |
| 336 request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) { | 337 request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) { |
| 337 ProcessTabCaptureAccessRequest( | 338 ProcessTabCaptureAccessRequest( |
| 338 web_contents, request, callback, extension); | 339 web_contents, request, callback, extension); |
| 339 } else if (extension && (extension->is_platform_app() || | |
| 340 IsMediaRequestWhitelistedForExtension(extension))) { | |
| 341 // For extensions access is approved based on extension permissions. | |
| 342 ProcessMediaAccessRequestFromPlatformAppOrExtension( | |
| 343 web_contents, request, callback, extension); | |
| 344 } else { | 340 } else { |
| 341 #if defined(ENABLE_EXTENSIONS) | |
| 342 bool is_whitelisted = | |
| 343 extension && (extension->is_platform_app() || | |
| 344 IsMediaRequestWhitelistedForExtension(extension)); | |
| 345 if (is_whitelisted) { | |
| 346 // For extensions access is approved based on extension permissions. | |
| 347 ProcessMediaAccessRequestFromPlatformAppOrExtension( | |
| 348 web_contents, request, callback, extension); | |
| 349 return; | |
| 350 } | |
| 351 #endif | |
| 345 ProcessRegularMediaAccessRequest(web_contents, request, callback); | 352 ProcessRegularMediaAccessRequest(web_contents, request, callback); |
| 346 } | 353 } |
| 347 } | 354 } |
| 348 | 355 |
| 349 bool MediaCaptureDevicesDispatcher::CheckMediaAccessPermission( | 356 bool MediaCaptureDevicesDispatcher::CheckMediaAccessPermission( |
| 350 content::BrowserContext* browser_context, | 357 content::BrowserContext* browser_context, |
| 351 const GURL& security_origin, | 358 const GURL& security_origin, |
| 352 content::MediaStreamType type) { | 359 content::MediaStreamType type) { |
| 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 354 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE || | 361 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE || |
| 355 type == content::MEDIA_DEVICE_VIDEO_CAPTURE); | 362 type == content::MEDIA_DEVICE_VIDEO_CAPTURE); |
| 356 | 363 |
| 357 Profile* profile = Profile::FromBrowserContext(browser_context); | 364 Profile* profile = Profile::FromBrowserContext(browser_context); |
| 365 #if defined(ENABLE_EXTENSIONS) | |
| 358 const extensions::Extension* extension = | 366 const extensions::Extension* extension = |
| 359 GetExtensionForOrigin(profile, security_origin); | 367 GetExtensionForOrigin(profile, security_origin); |
| 360 | 368 |
| 361 if (extension && (extension->is_platform_app() || | 369 if (extension && (extension->is_platform_app() || |
| 362 IsMediaRequestWhitelistedForExtension(extension))) { | 370 IsMediaRequestWhitelistedForExtension(extension))) { |
| 363 return extension->permissions_data()->HasAPIPermission( | 371 return extension->permissions_data()->HasAPIPermission( |
| 364 type == content::MEDIA_DEVICE_AUDIO_CAPTURE | 372 type == content::MEDIA_DEVICE_AUDIO_CAPTURE |
| 365 ? extensions::APIPermission::kAudioCapture | 373 ? extensions::APIPermission::kAudioCapture |
| 366 : extensions::APIPermission::kVideoCapture); | 374 : extensions::APIPermission::kVideoCapture); |
| 367 } | 375 } |
| 376 #endif | |
| 368 | 377 |
| 369 if (CheckAllowAllMediaStreamContentForOrigin(profile, security_origin)) | 378 if (CheckAllowAllMediaStreamContentForOrigin(profile, security_origin)) |
| 370 return true; | 379 return true; |
| 371 | 380 |
| 372 const char* policy_name = type == content::MEDIA_DEVICE_AUDIO_CAPTURE | 381 const char* policy_name = type == content::MEDIA_DEVICE_AUDIO_CAPTURE |
| 373 ? prefs::kAudioCaptureAllowed | 382 ? prefs::kAudioCaptureAllowed |
| 374 : prefs::kVideoCaptureAllowed; | 383 : prefs::kVideoCaptureAllowed; |
| 375 const char* list_policy_name = type == content::MEDIA_DEVICE_AUDIO_CAPTURE | 384 const char* list_policy_name = type == content::MEDIA_DEVICE_AUDIO_CAPTURE |
| 376 ? prefs::kAudioCaptureAllowedUrls | 385 ? prefs::kAudioCaptureAllowedUrls |
| 377 : prefs::kVideoCaptureAllowedUrls; | 386 : prefs::kVideoCaptureAllowedUrls; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 loopback_audio_supported = true; | 523 loopback_audio_supported = true; |
| 515 #endif | 524 #endif |
| 516 | 525 |
| 517 // Audio is only supported for screen capture streams. | 526 // Audio is only supported for screen capture streams. |
| 518 bool capture_audio = | 527 bool capture_audio = |
| 519 (media_id.type == content::DesktopMediaID::TYPE_SCREEN && | 528 (media_id.type == content::DesktopMediaID::TYPE_SCREEN && |
| 520 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && | 529 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && |
| 521 loopback_audio_supported); | 530 loopback_audio_supported); |
| 522 | 531 |
| 523 ui = GetDevicesForDesktopCapture( | 532 ui = GetDevicesForDesktopCapture( |
| 524 devices, media_id, capture_audio, true, | 533 &devices, media_id, capture_audio, true, |
| 525 GetApplicationTitle(web_contents, extension), | 534 GetApplicationTitle(web_contents, extension), |
| 526 base::UTF8ToUTF16(original_extension_name)); | 535 base::UTF8ToUTF16(original_extension_name)); |
| 527 | 536 |
| 528 callback.Run(devices, content::MEDIA_DEVICE_OK, ui.Pass()); | 537 callback.Run(devices, content::MEDIA_DEVICE_OK, ui.Pass()); |
| 529 } | 538 } |
| 530 | 539 |
| 531 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( | 540 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( |
| 532 content::WebContents* web_contents, | 541 content::WebContents* web_contents, |
| 533 const content::MediaStreamRequest& request, | 542 const content::MediaStreamRequest& request, |
| 534 const content::MediaResponseCallback& callback, | 543 const content::MediaResponseCallback& callback, |
| 535 const extensions::Extension* extension) { | 544 const extensions::Extension* extension) { |
| 536 content::MediaStreamDevices devices; | 545 content::MediaStreamDevices devices; |
| 537 scoped_ptr<content::MediaStreamUI> ui; | 546 scoped_ptr<content::MediaStreamUI> ui; |
| 538 | 547 |
| 539 DCHECK_EQ(request.video_type, content::MEDIA_DESKTOP_VIDEO_CAPTURE); | 548 DCHECK_EQ(request.video_type, content::MEDIA_DESKTOP_VIDEO_CAPTURE); |
| 540 | 549 |
| 541 bool loopback_audio_supported = false; | 550 bool loopback_audio_supported = false; |
| 542 #if defined(USE_CRAS) || defined(OS_WIN) | 551 #if defined(USE_CRAS) || defined(OS_WIN) |
| 543 // Currently loopback audio capture is supported only on Windows and ChromeOS. | 552 // Currently loopback audio capture is supported only on Windows and ChromeOS. |
| 544 loopback_audio_supported = true; | 553 loopback_audio_supported = true; |
| 545 #endif | 554 #endif |
| 546 | 555 |
| 547 const bool component_extension = | 556 bool component_extension = false; |
| 557 #if defined(ENABLE_EXTENSIONS) | |
| 558 component_extension = | |
| 548 extension && extension->location() == extensions::Manifest::COMPONENT; | 559 extension && extension->location() == extensions::Manifest::COMPONENT; |
| 560 #endif | |
| 549 | 561 |
| 550 const bool screen_capture_enabled = | 562 bool screen_capture_enabled = |
| 551 CommandLine::ForCurrentProcess()->HasSwitch( | 563 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 552 switches::kEnableUserMediaScreenCapturing) || | 564 switches::kEnableUserMediaScreenCapturing); |
| 565 #if defined(ENABLE_EXTENSIONS) | |
| 566 screen_capture_enabled |= | |
| 553 IsOriginForCasting(request.security_origin) || | 567 IsOriginForCasting(request.security_origin) || |
| 554 IsBuiltInExtension(request.security_origin); | 568 IsBuiltInExtension(request.security_origin); |
| 569 #endif | |
| 555 | 570 |
| 556 const bool origin_is_secure = | 571 const bool origin_is_secure = |
| 557 request.security_origin.SchemeIsSecure() || | 572 request.security_origin.SchemeIsSecure() || |
| 558 request.security_origin.SchemeIs(extensions::kExtensionScheme) || | 573 request.security_origin.SchemeIs(extensions::kExtensionScheme) || |
| 559 CommandLine::ForCurrentProcess()->HasSwitch( | 574 CommandLine::ForCurrentProcess()->HasSwitch( |
| 560 switches::kAllowHttpScreenCapture); | 575 switches::kAllowHttpScreenCapture); |
| 561 | 576 |
| 562 // If basic conditions (screen capturing is enabled and origin is secure) | 577 // If basic conditions (screen capturing is enabled and origin is secure) |
| 563 // aren't fulfilled, we'll use "invalid state" as result. Otherwise, we set | 578 // aren't fulfilled, we'll use "invalid state" as result. Otherwise, we set |
| 564 // it after checking permission. | 579 // it after checking permission. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 582 gfx::NativeWindow parent_window = | 597 gfx::NativeWindow parent_window = |
| 583 FindParentWindowForWebContents(web_contents); | 598 FindParentWindowForWebContents(web_contents); |
| 584 #else | 599 #else |
| 585 gfx::NativeWindow parent_window = NULL; | 600 gfx::NativeWindow parent_window = NULL; |
| 586 #endif | 601 #endif |
| 587 web_contents = NULL; | 602 web_contents = NULL; |
| 588 | 603 |
| 589 // For component extensions, bypass message box. | 604 // For component extensions, bypass message box. |
| 590 bool user_approved = false; | 605 bool user_approved = false; |
| 591 if (!component_extension) { | 606 if (!component_extension) { |
| 592 base::string16 application_name = base::UTF8ToUTF16( | 607 base::string16 application_name = |
| 593 extension ? extension->name() : request.security_origin.spec()); | 608 base::UTF8ToUTF16(request.security_origin.spec()); |
| 609 #if defined(ENABLE_EXTENSIONS) | |
| 610 if (extension) | |
| 611 application_name = base::UTF8ToUTF16(extension->name()); | |
| 612 #endif | |
| 594 base::string16 confirmation_text = l10n_util::GetStringFUTF16( | 613 base::string16 confirmation_text = l10n_util::GetStringFUTF16( |
| 595 request.audio_type == content::MEDIA_NO_SERVICE ? | 614 request.audio_type == content::MEDIA_NO_SERVICE ? |
| 596 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT : | 615 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT : |
| 597 IDS_MEDIA_SCREEN_AND_AUDIO_CAPTURE_CONFIRMATION_TEXT, | 616 IDS_MEDIA_SCREEN_AND_AUDIO_CAPTURE_CONFIRMATION_TEXT, |
| 598 application_name); | 617 application_name); |
| 599 chrome::MessageBoxResult result = chrome::ShowMessageBox( | 618 chrome::MessageBoxResult result = chrome::ShowMessageBox( |
| 600 parent_window, | 619 parent_window, |
| 601 l10n_util::GetStringFUTF16( | 620 l10n_util::GetStringFUTF16( |
| 602 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name), | 621 IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name), |
| 603 confirmation_text, | 622 confirmation_text, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 617 #endif // !defined(OS_CHROMEOS) | 636 #endif // !defined(OS_CHROMEOS) |
| 618 | 637 |
| 619 bool capture_audio = | 638 bool capture_audio = |
| 620 (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && | 639 (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && |
| 621 loopback_audio_supported); | 640 loopback_audio_supported); |
| 622 | 641 |
| 623 // Unless we're being invoked from a component extension, register to | 642 // Unless we're being invoked from a component extension, register to |
| 624 // display the notification for stream capture. | 643 // display the notification for stream capture. |
| 625 bool display_notification = !component_extension; | 644 bool display_notification = !component_extension; |
| 626 | 645 |
| 627 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, | 646 ui = GetDevicesForDesktopCapture(&devices, screen_id, capture_audio, |
| 628 display_notification, application_title, | 647 display_notification, application_title, |
| 629 application_title); | 648 application_title); |
| 630 DCHECK(!devices.empty()); | 649 DCHECK(!devices.empty()); |
| 631 } | 650 } |
| 632 | 651 |
| 633 // The only case when devices can be empty is if the user has denied | 652 // The only case when devices can be empty is if the user has denied |
| 634 // permission. | 653 // permission. |
| 635 result = devices.empty() ? content::MEDIA_DEVICE_PERMISSION_DENIED | 654 result = devices.empty() ? content::MEDIA_DEVICE_PERMISSION_DENIED |
| 636 : content::MEDIA_DEVICE_OK; | 655 : content::MEDIA_DEVICE_OK; |
| 637 } | 656 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 callback.Run( | 702 callback.Run( |
| 684 devices, | 703 devices, |
| 685 devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : | 704 devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : |
| 686 content::MEDIA_DEVICE_OK, | 705 content::MEDIA_DEVICE_OK, |
| 687 ui.Pass()); | 706 ui.Pass()); |
| 688 #else // defined(ENABLE_EXTENSIONS) | 707 #else // defined(ENABLE_EXTENSIONS) |
| 689 callback.Run(devices, content::MEDIA_DEVICE_TAB_CAPTURE_FAILURE, ui.Pass()); | 708 callback.Run(devices, content::MEDIA_DEVICE_TAB_CAPTURE_FAILURE, ui.Pass()); |
| 690 #endif // defined(ENABLE_EXTENSIONS) | 709 #endif // defined(ENABLE_EXTENSIONS) |
| 691 } | 710 } |
| 692 | 711 |
| 712 #if defined(ENABLE_EXTENSIONS) | |
| 693 void MediaCaptureDevicesDispatcher:: | 713 void MediaCaptureDevicesDispatcher:: |
| 694 ProcessMediaAccessRequestFromPlatformAppOrExtension( | 714 ProcessMediaAccessRequestFromPlatformAppOrExtension( |
| 695 content::WebContents* web_contents, | 715 content::WebContents* web_contents, |
| 696 const content::MediaStreamRequest& request, | 716 const content::MediaStreamRequest& request, |
| 697 const content::MediaResponseCallback& callback, | 717 const content::MediaResponseCallback& callback, |
| 698 const extensions::Extension* extension) { | 718 const extensions::Extension* extension) { |
| 699 // TODO(vrk): This code is largely duplicated in | 719 // TODO(vrk): This code is largely duplicated in |
| 700 // MediaStreamDevicesController::Accept(). Move this code into a shared method | 720 // MediaStreamDevicesController::Accept(). Move this code into a shared method |
| 701 // between the two classes. | 721 // between the two classes. |
| 702 | 722 |
| 703 Profile* profile = | 723 Profile* profile = |
| 704 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 724 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 705 | 725 |
| 706 bool audio_allowed = | 726 bool audio_allowed = false; |
|
vrk (LEFT CHROMIUM)
2014/10/17 19:56:44
nit: looks like these two "audio_allowed"/ "video_
Lei Zhang
2014/10/17 21:44:51
indeed, I had the ifdef inside the function before
| |
| 727 bool video_allowed = false; | |
| 728 audio_allowed = | |
| 707 request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE && | 729 request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE && |
| 708 extension->permissions_data()->HasAPIPermission( | 730 extension->permissions_data()->HasAPIPermission( |
| 709 extensions::APIPermission::kAudioCapture) && | 731 extensions::APIPermission::kAudioCapture) && |
| 710 GetDevicePolicy(profile, extension->url(), | 732 GetDevicePolicy(profile, extension->url(), |
| 711 prefs::kAudioCaptureAllowed, | 733 prefs::kAudioCaptureAllowed, |
| 712 prefs::kAudioCaptureAllowedUrls) != ALWAYS_DENY; | 734 prefs::kAudioCaptureAllowedUrls) != ALWAYS_DENY; |
| 713 bool video_allowed = | 735 video_allowed = |
| 714 request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE && | 736 request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE && |
| 715 extension->permissions_data()->HasAPIPermission( | 737 extension->permissions_data()->HasAPIPermission( |
| 716 extensions::APIPermission::kVideoCapture) && | 738 extensions::APIPermission::kVideoCapture) && |
| 717 GetDevicePolicy(profile, extension->url(), | 739 GetDevicePolicy(profile, extension->url(), |
| 718 prefs::kVideoCaptureAllowed, | 740 prefs::kVideoCaptureAllowed, |
| 719 prefs::kVideoCaptureAllowedUrls) != ALWAYS_DENY; | 741 prefs::kVideoCaptureAllowedUrls) != ALWAYS_DENY; |
| 720 | 742 |
| 721 bool get_default_audio_device = audio_allowed; | 743 bool get_default_audio_device = audio_allowed; |
| 722 bool get_default_video_device = video_allowed; | 744 bool get_default_video_device = video_allowed; |
| 723 | 745 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 | 788 |
| 767 scoped_ptr<content::MediaStreamUI> ui; | 789 scoped_ptr<content::MediaStreamUI> ui; |
| 768 if (!devices.empty()) { | 790 if (!devices.empty()) { |
| 769 result = content::MEDIA_DEVICE_OK; | 791 result = content::MEDIA_DEVICE_OK; |
| 770 ui = media_stream_capture_indicator_->RegisterMediaStream( | 792 ui = media_stream_capture_indicator_->RegisterMediaStream( |
| 771 web_contents, devices); | 793 web_contents, devices); |
| 772 } | 794 } |
| 773 | 795 |
| 774 callback.Run(devices, result, ui.Pass()); | 796 callback.Run(devices, result, ui.Pass()); |
| 775 } | 797 } |
| 798 #endif | |
| 776 | 799 |
| 777 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( | 800 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( |
| 778 content::WebContents* web_contents, | 801 content::WebContents* web_contents, |
| 779 const content::MediaStreamRequest& request, | 802 const content::MediaStreamRequest& request, |
| 780 const content::MediaResponseCallback& callback) { | 803 const content::MediaResponseCallback& callback) { |
| 781 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 804 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 782 | 805 |
| 783 RequestsQueue& queue = pending_requests_[web_contents]; | 806 RequestsQueue& queue = pending_requests_[web_contents]; |
| 784 queue.push_back(PendingAccessRequest(request, callback)); | 807 queue.push_back(PendingAccessRequest(request, callback)); |
| 785 | 808 |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1086 | 1109 |
| 1087 void MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices( | 1110 void MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices( |
| 1088 const MediaStreamDevices& devices) { | 1111 const MediaStreamDevices& devices) { |
| 1089 test_audio_devices_ = devices; | 1112 test_audio_devices_ = devices; |
| 1090 } | 1113 } |
| 1091 | 1114 |
| 1092 void MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices( | 1115 void MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices( |
| 1093 const MediaStreamDevices& devices) { | 1116 const MediaStreamDevices& devices) { |
| 1094 test_video_devices_ = devices; | 1117 test_video_devices_ = devices; |
| 1095 } | 1118 } |
| OLD | NEW |