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
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/media/webrtc/media_stream_device_permission_context.h"
6 #include "chrome/browser/media/webrtc/media_stream_device_permissions.h"
7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/common/pref_names.h"
9 #include "components/content_settings/core/browser/host_content_settings_map.h"
10 #include "components/content_settings/core/common/content_settings.h"
11 #include "content/public/common/content_features.h"
12 #include "content/public/common/url_constants.h"
13 #include "extensions/common/constants.h"
14 #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h"
15 
16 namespace {
17 
GetFeaturePolicyFeature(ContentSettingsType type)18 blink::mojom::FeaturePolicyFeature GetFeaturePolicyFeature(
19     ContentSettingsType type) {
20   if (type == ContentSettingsType::MEDIASTREAM_MIC)
21     return blink::mojom::FeaturePolicyFeature::kMicrophone;
22 
23   DCHECK_EQ(ContentSettingsType::MEDIASTREAM_CAMERA, type);
24   return blink::mojom::FeaturePolicyFeature::kCamera;
25 }
26 
27 }  // namespace
28 
MediaStreamDevicePermissionContext(content::BrowserContext * browser_context,const ContentSettingsType content_settings_type)29 MediaStreamDevicePermissionContext::MediaStreamDevicePermissionContext(
30     content::BrowserContext* browser_context,
31     const ContentSettingsType content_settings_type)
32     : PermissionContextBase(browser_context,
33                             content_settings_type,
34                             GetFeaturePolicyFeature(content_settings_type)),
35       content_settings_type_(content_settings_type) {
36   DCHECK(content_settings_type_ == ContentSettingsType::MEDIASTREAM_MIC ||
37          content_settings_type_ == ContentSettingsType::MEDIASTREAM_CAMERA);
38 }
39 
~MediaStreamDevicePermissionContext()40 MediaStreamDevicePermissionContext::~MediaStreamDevicePermissionContext() {}
41 
DecidePermission(content::WebContents * web_contents,const permissions::PermissionRequestID & id,const GURL & requesting_origin,const GURL & embedding_origin,bool user_gesture,permissions::BrowserPermissionCallback callback)42 void MediaStreamDevicePermissionContext::DecidePermission(
43     content::WebContents* web_contents,
44     const permissions::PermissionRequestID& id,
45     const GURL& requesting_origin,
46     const GURL& embedding_origin,
47     bool user_gesture,
48     permissions::BrowserPermissionCallback callback) {
49   permissions::PermissionContextBase::DecidePermission(
50       web_contents, id, requesting_origin, embedding_origin, user_gesture,
51       std::move(callback));
52 }
53 
GetPermissionStatusInternal(content::RenderFrameHost * render_frame_host,const GURL & requesting_origin,const GURL & embedding_origin) const54 ContentSetting MediaStreamDevicePermissionContext::GetPermissionStatusInternal(
55     content::RenderFrameHost* render_frame_host,
56     const GURL& requesting_origin,
57     const GURL& embedding_origin) const {
58   // TODO(raymes): Merge this policy check into content settings
59   // crbug.com/244389.
60   const char* policy_name = nullptr;
61   const char* urls_policy_name = nullptr;
62   if (content_settings_type_ == ContentSettingsType::MEDIASTREAM_MIC) {
63     policy_name = prefs::kAudioCaptureAllowed;
64     urls_policy_name = prefs::kAudioCaptureAllowedUrls;
65   } else {
66     DCHECK(content_settings_type_ == ContentSettingsType::MEDIASTREAM_CAMERA);
67     policy_name = prefs::kVideoCaptureAllowed;
68     urls_policy_name = prefs::kVideoCaptureAllowedUrls;
69   }
70 
71   MediaStreamDevicePolicy policy =
72       GetDevicePolicy(Profile::FromBrowserContext(browser_context()),
73                       requesting_origin, policy_name, urls_policy_name);
74 
75   switch (policy) {
76     case ALWAYS_DENY:
77       return CONTENT_SETTING_BLOCK;
78     case ALWAYS_ALLOW:
79       return CONTENT_SETTING_ALLOW;
80     default:
81       DCHECK_EQ(POLICY_NOT_SET, policy);
82   }
83 
84   // Check the content setting. TODO(raymes): currently mic/camera permission
85   // doesn't consider the embedder.
86   ContentSetting setting =
87       permissions::PermissionContextBase::GetPermissionStatusInternal(
88           render_frame_host, requesting_origin, requesting_origin);
89 
90   if (setting == CONTENT_SETTING_DEFAULT)
91     setting = CONTENT_SETTING_ASK;
92 
93   return setting;
94 }
95 
ResetPermission(const GURL & requesting_origin,const GURL & embedding_origin)96 void MediaStreamDevicePermissionContext::ResetPermission(
97     const GURL& requesting_origin,
98     const GURL& embedding_origin) {
99   NOTREACHED() << "ResetPermission is not implemented";
100 }
101 
IsRestrictedToSecureOrigins() const102 bool MediaStreamDevicePermissionContext::IsRestrictedToSecureOrigins() const {
103   return true;
104 }
105