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

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

Issue 483523006: Check all settings when checking mic and camera access (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Build fix for Android. Created 6 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 | Annotate | Revision Log
OLDNEW
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_stream_devices_controller.h" 5 #include "chrome/browser/media/media_stream_devices_controller.h"
6 6
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h" 8 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h" 10 #include "base/values.h"
13 #include "chrome/browser/content_settings/content_settings_provider.h" 11 #include "chrome/browser/content_settings/content_settings_provider.h"
14 #include "chrome/browser/content_settings/host_content_settings_map.h" 12 #include "chrome/browser/content_settings/host_content_settings_map.h"
15 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 13 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
16 #include "chrome/browser/media/media_capture_devices_dispatcher.h" 14 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
17 #include "chrome/browser/media/media_stream_capture_indicator.h" 15 #include "chrome/browser/media/media_stream_capture_indicator.h"
16 #include "chrome/browser/media/media_stream_device_permissions.h"
18 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h" 18 #include "chrome/browser/ui/browser.h"
20 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/content_settings.h" 20 #include "chrome/common/content_settings.h"
22 #include "chrome/common/content_settings_pattern.h" 21 #include "chrome/common/content_settings_pattern.h"
23 #include "chrome/common/pref_names.h" 22 #include "chrome/common/pref_names.h"
24 #include "chrome/grit/generated_resources.h" 23 #include "chrome/grit/generated_resources.h"
25 #include "components/pref_registry/pref_registry_syncable.h" 24 #include "components/pref_registry/pref_registry_syncable.h"
26 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/render_widget_host_view.h" 26 #include "content/public/browser/render_widget_host_view.h"
28 #include "content/public/common/media_stream_request.h" 27 #include "content/public/common/media_stream_request.h"
29 #include "extensions/common/constants.h" 28 #include "extensions/common/constants.h"
30 #include "grit/theme_resources.h" 29 #include "grit/theme_resources.h"
31 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/l10n/l10n_util.h"
32 31
33 #if defined(OS_CHROMEOS)
34 #include "components/user_manager/user_manager.h"
35 #endif
36
37 using content::BrowserThread; 32 using content::BrowserThread;
38 33
39 namespace { 34 namespace {
40 35
41 bool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) { 36 bool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) {
42 const content::MediaStreamDevices* audio_devices = 37 const content::MediaStreamDevices* audio_devices =
43 request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ? 38 request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
44 &MediaCaptureDevicesDispatcher::GetInstance() 39 &MediaCaptureDevicesDispatcher::GetInstance()
45 ->GetAudioCaptureDevices() : 40 ->GetAudioCaptureDevices() :
46 NULL; 41 NULL;
(...skipping 27 matching lines...) Expand all
74 } 69 }
75 70
76 if (!request.requested_video_device_id.empty() && 71 if (!request.requested_video_device_id.empty() &&
77 !video_devices->FindById(request.requested_video_device_id)) { 72 !video_devices->FindById(request.requested_video_device_id)) {
78 return false; 73 return false;
79 } 74 }
80 75
81 return true; 76 return true;
82 } 77 }
83 78
84 bool IsInKioskMode() {
85 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
86 return true;
87
88 #if defined(OS_CHROMEOS)
89 const user_manager::UserManager* user_manager =
90 user_manager::UserManager::Get();
91 return user_manager && user_manager->IsLoggedInAsKioskApp();
92 #else
93 return false;
94 #endif
95 }
96
97 enum DevicePermissionActions { 79 enum DevicePermissionActions {
98 kAllowHttps = 0, 80 kAllowHttps = 0,
99 kAllowHttp, 81 kAllowHttp,
100 kDeny, 82 kDeny,
101 kCancel, 83 kCancel,
102 kPermissionActionsMax // Must always be last! 84 kPermissionActionsMax // Must always be last!
103 }; 85 };
104 86
105 } // namespace 87 } // namespace
106 88
(...skipping 20 matching lines...) Expand all
127 // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam 109 // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam
128 // and microphone to avoid popping two infobars. 110 // and microphone to avoid popping two infobars.
129 // We start with setting the requested media type to allowed or blocked 111 // We start with setting the requested media type to allowed or blocked
130 // depending on the policy. If not blocked by policy it may be blocked later 112 // depending on the policy. If not blocked by policy it may be blocked later
131 // in the two remaining filtering steps (by user setting or by user when 113 // in the two remaining filtering steps (by user setting or by user when
132 // clicking the infobar). 114 // clicking the infobar).
133 // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE 115 // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE
134 // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed. 116 // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed.
135 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE || 117 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
136 request.request_type == content::MEDIA_OPEN_DEVICE) { 118 request.request_type == content::MEDIA_OPEN_DEVICE) {
137 if (GetDevicePolicy(prefs::kAudioCaptureAllowed, 119 if (GetDevicePolicy(profile_,
120 request_.security_origin,
121 prefs::kAudioCaptureAllowed,
138 prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) { 122 prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) {
139 request_permissions_.insert(std::make_pair( 123 request_permissions_.insert(std::make_pair(
140 content::MEDIA_DEVICE_AUDIO_CAPTURE, 124 content::MEDIA_DEVICE_AUDIO_CAPTURE,
141 MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY, 125 MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
142 request.requested_audio_device_id))); 126 request.requested_audio_device_id)));
143 } else { 127 } else {
144 request_permissions_.insert(std::make_pair( 128 request_permissions_.insert(std::make_pair(
145 content::MEDIA_DEVICE_AUDIO_CAPTURE, 129 content::MEDIA_DEVICE_AUDIO_CAPTURE,
146 MediaStreamTypeSettings(MEDIA_ALLOWED, 130 MediaStreamTypeSettings(MEDIA_ALLOWED,
147 request.requested_audio_device_id))); 131 request.requested_audio_device_id)));
148 } 132 }
149 } 133 }
150 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE || 134 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ||
151 request.request_type == content::MEDIA_OPEN_DEVICE) { 135 request.request_type == content::MEDIA_OPEN_DEVICE) {
152 if (GetDevicePolicy(prefs::kVideoCaptureAllowed, 136 if (GetDevicePolicy(profile_,
137 request_.security_origin,
138 prefs::kVideoCaptureAllowed,
153 prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) { 139 prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) {
154 request_permissions_.insert(std::make_pair( 140 request_permissions_.insert(std::make_pair(
155 content::MEDIA_DEVICE_VIDEO_CAPTURE, 141 content::MEDIA_DEVICE_VIDEO_CAPTURE,
156 MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY, 142 MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
157 request.requested_video_device_id))); 143 request.requested_video_device_id)));
158 } else { 144 } else {
159 request_permissions_.insert(std::make_pair( 145 request_permissions_.insert(std::make_pair(
160 content::MEDIA_DEVICE_VIDEO_CAPTURE, 146 content::MEDIA_DEVICE_VIDEO_CAPTURE,
161 MediaStreamTypeSettings(MEDIA_ALLOWED, 147 MediaStreamTypeSettings(MEDIA_ALLOWED,
162 request.requested_video_device_id))); 148 request.requested_video_device_id)));
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 void MediaStreamDevicesController::Cancelled() { 435 void MediaStreamDevicesController::Cancelled() {
450 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 436 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
451 kCancel, kPermissionActionsMax); 437 kCancel, kPermissionActionsMax);
452 Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED); 438 Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED);
453 } 439 }
454 440
455 void MediaStreamDevicesController::RequestFinished() { 441 void MediaStreamDevicesController::RequestFinished() {
456 delete this; 442 delete this;
457 } 443 }
458 444
459 MediaStreamDevicesController::DevicePolicy
460 MediaStreamDevicesController::GetDevicePolicy(
461 const char* policy_name,
462 const char* whitelist_policy_name) const {
463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
464
465 // If the security origin policy matches a value in the whitelist, allow it.
466 // Otherwise, check the |policy_name| master switch for the default behavior.
467
468 PrefService* prefs = profile_->GetPrefs();
469
470 // TODO(tommi): Remove the kiosk mode check when the whitelist below
471 // is visible in the media exceptions UI.
472 // See discussion here: https://codereview.chromium.org/15738004/
473 if (IsInKioskMode()) {
474 const base::ListValue* list = prefs->GetList(whitelist_policy_name);
475 std::string value;
476 for (size_t i = 0; i < list->GetSize(); ++i) {
477 if (list->GetString(i, &value)) {
478 ContentSettingsPattern pattern =
479 ContentSettingsPattern::FromString(value);
480 if (pattern == ContentSettingsPattern::Wildcard()) {
481 DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value;
482 continue;
483 }
484 DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value;
485 if (pattern.IsValid() && pattern.Matches(request_.security_origin))
486 return ALWAYS_ALLOW;
487 }
488 }
489 }
490
491 // If a match was not found, check if audio capture is otherwise disallowed
492 // or if the user should be prompted. Setting the policy value to "true"
493 // is equal to not setting it at all, so from hereon out, we will return
494 // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access).
495 if (!prefs->GetBoolean(policy_name))
496 return ALWAYS_DENY;
497
498 return POLICY_NOT_SET;
499 }
500
501 bool MediaStreamDevicesController::IsRequestAllowedByDefault() const { 445 bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
502 // The request from internal objects like chrome://URLs is always allowed. 446 // The request from internal objects like chrome://URLs is always allowed.
503 if (ShouldAlwaysAllowOrigin()) 447 if (CheckAllowAllMediaStreamContentForOrigin(profile_,
448 request_.security_origin)) {
504 return true; 449 return true;
450 }
505 451
506 struct { 452 struct {
507 bool has_capability; 453 bool has_capability;
508 const char* policy_name; 454 const char* policy_name;
509 const char* list_policy_name; 455 const char* list_policy_name;
510 ContentSettingsType settings_type; 456 ContentSettingsType settings_type;
511 } device_checks[] = { 457 } device_checks[] = {
512 { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed, 458 { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed,
513 prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC }, 459 prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC },
514 { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed, 460 { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed,
515 prefs::kVideoCaptureAllowedUrls, 461 prefs::kVideoCaptureAllowedUrls,
516 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA }, 462 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA },
517 }; 463 };
518 464
519 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) { 465 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) {
520 if (!device_checks[i].has_capability) 466 if (!device_checks[i].has_capability)
521 continue; 467 continue;
522 468
523 DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name, 469 MediaStreamDevicePolicy policy =
524 device_checks[i].list_policy_name); 470 GetDevicePolicy(profile_,
471 request_.security_origin,
472 device_checks[i].policy_name,
473 device_checks[i].list_policy_name);
525 474
526 if (policy == ALWAYS_DENY) 475 if (policy == ALWAYS_DENY)
527 return false; 476 return false;
528 477
529 if (policy == POLICY_NOT_SET) { 478 if (policy == POLICY_NOT_SET) {
530 // Only load content settings from secure origins unless it is a 479 // Only load content settings from secure origins unless it is a
531 // content::MEDIA_OPEN_DEVICE (Pepper) request. 480 // content::MEDIA_OPEN_DEVICE (Pepper) request.
532 if (!IsSchemeSecure() && 481 if (!IsSchemeSecure() &&
533 request_.request_type != content::MEDIA_OPEN_DEVICE) { 482 request_.request_type != content::MEDIA_OPEN_DEVICE) {
534 return false; 483 return false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 profile_->GetHostContentSettingsMap()->GetDefaultContentSetting( 537 profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
589 CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL); 538 CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
590 return (current_setting == CONTENT_SETTING_BLOCK); 539 return (current_setting == CONTENT_SETTING_BLOCK);
591 } 540 }
592 541
593 bool MediaStreamDevicesController::IsSchemeSecure() const { 542 bool MediaStreamDevicesController::IsSchemeSecure() const {
594 return request_.security_origin.SchemeIsSecure() || 543 return request_.security_origin.SchemeIsSecure() ||
595 request_.security_origin.SchemeIs(extensions::kExtensionScheme); 544 request_.security_origin.SchemeIs(extensions::kExtensionScheme);
596 } 545 }
597 546
598 bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const {
599 // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
600 // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
601 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
602 return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
603 request_.security_origin, request_.security_origin,
604 CONTENT_SETTINGS_TYPE_MEDIASTREAM);
605 }
606
607 void MediaStreamDevicesController::SetPermission(bool allowed) const { 547 void MediaStreamDevicesController::SetPermission(bool allowed) const {
608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 548 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
609 ContentSettingsPattern primary_pattern = 549 ContentSettingsPattern primary_pattern =
610 ContentSettingsPattern::FromURLNoWildcard(request_.security_origin); 550 ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
611 // Check the pattern is valid or not. When the request is from a file access, 551 // Check the pattern is valid or not. When the request is from a file access,
612 // no exception will be made. 552 // no exception will be made.
613 if (!primary_pattern.IsValid()) 553 if (!primary_pattern.IsValid())
614 return; 554 return;
615 555
616 ContentSetting content_setting = allowed ? 556 ContentSetting content_setting = allowed ?
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 } 617 }
678 618
679 bool MediaStreamDevicesController::IsCaptureDeviceRequestAllowed() const { 619 bool MediaStreamDevicesController::IsCaptureDeviceRequestAllowed() const {
680 #if defined(OS_ANDROID) 620 #if defined(OS_ANDROID)
681 // Don't approve device requests if the tab was hidden. 621 // Don't approve device requests if the tab was hidden.
682 // TODO(qinmin): Add a test for this. http://crbug.com/396869. 622 // TODO(qinmin): Add a test for this. http://crbug.com/396869.
683 return web_contents_->GetRenderWidgetHostView()->IsShowing(); 623 return web_contents_->GetRenderWidgetHostView()->IsShowing();
684 #endif 624 #endif
685 return true; 625 return true;
686 } 626 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698