OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_permission.h" | 5 #include "chrome/browser/media/media_permission.h" |
6 | 6 |
7 #include "chrome/browser/media/media_capture_devices_dispatcher.h" | 7 #include "chrome/browser/media/media_capture_devices_dispatcher.h" |
| 8 #include "chrome/browser/media/media_stream_device_permission_context.h" |
8 #include "chrome/browser/media/media_stream_device_permissions.h" | 9 #include "chrome/browser/media/media_stream_device_permissions.h" |
| 10 #include "chrome/browser/permissions/permission_context.h" |
| 11 #include "chrome/browser/permissions/permission_context_base.h" |
9 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
10 #include "chrome/common/pref_names.h" | 13 #include "chrome/common/pref_names.h" |
11 #include "components/content_settings/core/browser/host_content_settings_map.h" | 14 #include "content/public/browser/permission_manager.h" |
| 15 #include "content/public/browser/permission_type.h" |
12 #include "content/public/common/url_constants.h" | 16 #include "content/public/common/url_constants.h" |
13 #include "extensions/common/constants.h" | 17 #include "extensions/common/constants.h" |
14 | 18 |
| 19 namespace { |
| 20 |
| 21 content::PermissionType ContentSettingsTypeToPermission( |
| 22 ContentSettingsType content_setting) { |
| 23 if (content_setting == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) { |
| 24 return content::PermissionType::AUDIO_CAPTURE; |
| 25 } else { |
| 26 DCHECK_EQ(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, content_setting); |
| 27 return content::PermissionType::VIDEO_CAPTURE; |
| 28 } |
| 29 } |
| 30 |
| 31 } // namespace |
| 32 |
15 MediaPermission::MediaPermission(ContentSettingsType content_type, | 33 MediaPermission::MediaPermission(ContentSettingsType content_type, |
16 content::MediaStreamRequestType request_type, | 34 content::MediaStreamRequestType request_type, |
17 const GURL& origin, | 35 const GURL& requesting_origin, |
| 36 const GURL& embedding_origin, |
18 Profile* profile) | 37 Profile* profile) |
19 : content_type_(content_type), | 38 : content_type_(content_type), |
20 request_type_(request_type), | 39 request_type_(request_type), |
21 origin_(origin), | 40 requesting_origin_(requesting_origin), |
22 profile_(profile) { | 41 embedding_origin_(embedding_origin), |
23 } | 42 profile_(profile) {} |
24 | 43 |
25 ContentSetting MediaPermission::GetPermissionStatus( | 44 ContentSetting MediaPermission::GetPermissionStatus( |
26 content::MediaStreamRequestResult* denial_reason) const { | 45 content::MediaStreamRequestResult* denial_reason) const { |
27 // Deny the request if the security origin is empty, this happens with | 46 // Deny the request if the security origin is empty, this happens with |
28 // file access without |--allow-file-access-from-files| flag. | 47 // file access without |--allow-file-access-from-files| flag. |
29 if (origin_.is_empty()) { | 48 if (requesting_origin_.is_empty()) { |
30 *denial_reason = content::MEDIA_DEVICE_INVALID_SECURITY_ORIGIN; | 49 *denial_reason = content::MEDIA_DEVICE_INVALID_SECURITY_ORIGIN; |
31 return CONTENT_SETTING_BLOCK; | 50 return CONTENT_SETTING_BLOCK; |
32 } | 51 } |
33 | 52 |
34 // Check policy and content settings. | 53 // Check policy and content settings. |
35 ContentSetting result = GetStoredContentSetting(); | 54 ContentSetting result = GetStoredContentSetting(); |
36 if (result == CONTENT_SETTING_BLOCK) | 55 if (result == CONTENT_SETTING_BLOCK) |
37 *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; | 56 *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; |
38 | 57 |
39 return result; | 58 return result; |
40 } | 59 } |
41 | 60 |
42 ContentSetting MediaPermission::GetPermissionStatusWithDeviceRequired( | 61 ContentSetting MediaPermission::GetPermissionStatusWithDeviceRequired( |
43 const std::string& device_id, | 62 const std::string& device_id, |
44 content::MediaStreamRequestResult* denial_reason) const { | 63 content::MediaStreamRequestResult* denial_reason) const { |
45 // Deny the request if there is no device attached to the OS of the requested | 64 // Deny the request if there is no device attached to the OS of the requested |
46 // type. | 65 // type. |
47 if (!HasAvailableDevices(device_id)) { | 66 if (!HasAvailableDevices(device_id)) { |
48 *denial_reason = content::MEDIA_DEVICE_NO_HARDWARE; | 67 *denial_reason = content::MEDIA_DEVICE_NO_HARDWARE; |
49 return CONTENT_SETTING_BLOCK; | 68 return CONTENT_SETTING_BLOCK; |
50 } | 69 } |
51 | 70 |
52 return GetPermissionStatus(denial_reason); | 71 return GetPermissionStatus(denial_reason); |
53 } | 72 } |
54 | 73 |
55 ContentSetting MediaPermission::GetStoredContentSetting() const { | 74 ContentSetting MediaPermission::GetStoredContentSetting() const { |
56 // TODO(raymes): Merge this policy check into content settings | 75 content::PermissionType permission_type = |
57 // crbug.com/244389. | 76 ContentSettingsTypeToPermission(content_type_); |
58 const char* policy_name = nullptr; | 77 PermissionContextBase* permission_context = |
59 const char* urls_policy_name = nullptr; | 78 PermissionContext::Get(profile_, permission_type); |
60 if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) { | |
61 policy_name = prefs::kAudioCaptureAllowed; | |
62 urls_policy_name = prefs::kAudioCaptureAllowedUrls; | |
63 } else if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) { | |
64 policy_name = prefs::kVideoCaptureAllowed; | |
65 urls_policy_name = prefs::kVideoCaptureAllowedUrls; | |
66 } else { | |
67 NOTREACHED(); | |
68 } | |
69 | 79 |
70 MediaStreamDevicePolicy policy = | 80 if (!permission_context) |
71 GetDevicePolicy(profile_, origin_, policy_name, urls_policy_name); | |
72 | |
73 if (policy == ALWAYS_DENY) | |
74 return CONTENT_SETTING_BLOCK; | 81 return CONTENT_SETTING_BLOCK; |
75 | 82 |
76 if (policy == ALWAYS_ALLOW) | 83 MediaStreamDevicePermissionContext* media_device_permission_context = |
77 return CONTENT_SETTING_ALLOW; | 84 static_cast<MediaStreamDevicePermissionContext*>(permission_context); |
78 | 85 |
79 DCHECK(policy == POLICY_NOT_SET); | 86 if (request_type_ == content::MEDIA_OPEN_DEVICE) { |
80 // Check the content setting. | 87 return media_device_permission_context->GetPermissionStatusForPepper( |
81 ContentSetting setting = | 88 requesting_origin_, embedding_origin_); |
82 profile_->GetHostContentSettingsMap()->GetContentSetting( | 89 } else { |
83 origin_, origin_, content_type_, | 90 return media_device_permission_context->GetPermissionStatus( |
84 content_settings::ResourceIdentifier()); | 91 requesting_origin_, embedding_origin_); |
85 | |
86 if (setting == CONTENT_SETTING_DEFAULT) | |
87 return CONTENT_SETTING_ASK; | |
88 | |
89 // TODO(raymes): This is here for safety to ensure that we always ask the user | |
90 // even if a content setting is set to "allow" if the origin is insecure. In | |
91 // reality we shouldn't really need to check this here as we should respect | |
92 // the user's content setting. The problem is that pepper requests allow | |
93 // insecure origins to be persisted. We should stop allowing this, do some | |
94 // sort of migration and remove this check. See crbug.com/512301. | |
95 if (!ShouldPersistContentSetting(setting, origin_, request_type_) && | |
96 !origin_.SchemeIs(extensions::kExtensionScheme) && | |
97 !origin_.SchemeIs(content::kChromeUIScheme) && | |
98 !origin_.SchemeIs(content::kChromeDevToolsScheme)) { | |
99 return CONTENT_SETTING_ASK; | |
100 } | 92 } |
101 | |
102 return setting; | |
103 } | 93 } |
104 | 94 |
105 bool MediaPermission::HasAvailableDevices(const std::string& device_id) const { | 95 bool MediaPermission::HasAvailableDevices(const std::string& device_id) const { |
106 const content::MediaStreamDevices* devices = nullptr; | 96 const content::MediaStreamDevices* devices = nullptr; |
107 if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) { | 97 if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) { |
108 devices = | 98 devices = |
109 &MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices(); | 99 &MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices(); |
110 } else if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) { | 100 } else if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) { |
111 devices = | 101 devices = |
112 &MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices(); | 102 &MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices(); |
(...skipping 10 matching lines...) Expand all Loading... |
123 return false; | 113 return false; |
124 | 114 |
125 // Note: we check device_id before dereferencing devices. If the requested | 115 // Note: we check device_id before dereferencing devices. If the requested |
126 // device id is non-empty, then the corresponding device list must not be | 116 // device id is non-empty, then the corresponding device list must not be |
127 // NULL. | 117 // NULL. |
128 if (!device_id.empty() && !devices->FindById(device_id)) | 118 if (!device_id.empty() && !devices->FindById(device_id)) |
129 return false; | 119 return false; |
130 | 120 |
131 return true; | 121 return true; |
132 } | 122 } |
OLD | NEW |