blob: 05321f0d14a3fdfb4327422a44ee469aacc42dfd [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2014 The Chromium Authors
[email protected]bb326052014-07-09 10:55:492// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Clark DuValla11361ad32020-02-20 22:14:275#include "components/permissions/permission_context_base.h"
[email protected]bb326052014-07-09 10:55:496
avib896c712015-12-26 02:10:437#include <stddef.h>
meredithl62b8c3d2017-01-10 05:47:538
Florian Jacky7f3e3ca1b2025-05-05 16:19:209#include <memory>
Zelin Liu2046c8422024-08-27 20:25:0510#include <optional>
meredithl62b8c3d2017-01-10 05:47:5311#include <string>
Peter Kastingc70def22025-01-06 22:49:4812#include <string_view>
dchenge73d8520c2015-12-27 01:19:0913#include <utility>
avib896c712015-12-26 02:10:4314
Avi Drissman12be0312023-01-11 09:16:0915#include "base/functional/bind.h"
16#include "base/functional/callback.h"
Florian Jacky11f98102025-05-20 15:57:1817#include "base/functional/callback_forward.h"
[email protected]bb326052014-07-09 10:55:4918#include "base/logging.h"
Florian Jacky11f98102025-05-20 15:57:1819#include "base/memory/weak_ptr.h"
Clark DuValla11361ad32020-02-20 22:14:2720#include "base/metrics/field_trial_params.h"
David Sanders88b24432022-02-28 01:10:0221#include "base/observer_list.h"
meredithl03b12852017-01-25 05:08:0122#include "base/time/time.h"
avib896c712015-12-26 02:10:4323#include "build/build_config.h"
Raymes Khoury47df4b22018-05-10 04:30:1724#include "components/content_settings/core/browser/content_settings_registry.h"
Christian Dullwebera68ee8d2022-09-09 12:47:3125#include "components/content_settings/core/browser/content_settings_utils.h"
mukai8eaec822014-10-25 17:53:1626#include "components/content_settings/core/browser/host_content_settings_map.h"
Andy Paicu24b02bb2023-09-06 14:49:0827#include "components/content_settings/core/common/content_settings.h"
Andy Paicu72b4edf2023-09-15 09:52:4328#include "components/content_settings/core/common/content_settings_pattern.h"
Matt Reichhoffdae0bfb2023-01-06 19:55:3129#include "components/content_settings/core/common/content_settings_types.h"
Florian Jacky989b41b2023-07-31 16:33:4230#include "components/content_settings/core/common/features.h"
Clark DuValla11361ad32020-02-20 22:14:2731#include "components/permissions/features.h"
Florian Jacky989b41b2023-07-31 16:33:4232#include "components/permissions/permission_context_base.h"
Clark DuVall03628dedc2020-01-30 22:25:5233#include "components/permissions/permission_decision_auto_blocker.h"
Clark DuVall484c2562020-01-23 22:05:0934#include "components/permissions/permission_request.h"
35#include "components/permissions/permission_request_id.h"
Clark DuVall5ca4ae12020-02-19 22:25:2736#include "components/permissions/permission_request_manager.h"
Clark DuVall38189ee2020-02-14 02:30:2837#include "components/permissions/permission_uma_util.h"
Clark DuVall732778e2020-01-27 18:13:5838#include "components/permissions/permission_util.h"
Clark DuValla11361ad32020-02-20 22:14:2739#include "components/permissions/permissions_client.h"
Bret Sepulveda5327d8b52021-07-21 17:44:2340#include "components/permissions/request_type.h"
Florian Jacky7f3e3ca1b2025-05-05 16:19:2041#include "components/permissions/resolvers/content_setting_permission_resolver.h"
[email protected]bb326052014-07-09 10:55:4942#include "content/public/browser/browser_thread.h"
Carlos Caballerob6b466482019-11-29 13:33:1843#include "content/public/browser/global_routing_id.h"
Robert Ogden24375242018-10-05 21:16:2644#include "content/public/browser/navigation_entry.h"
kcarattini5d97c632015-11-05 00:38:2945#include "content/public/browser/render_frame_host.h"
[email protected]bb326052014-07-09 10:55:4946#include "content/public/browser/web_contents.h"
raymes21b9affc2017-05-31 06:15:2647#include "content/public/common/content_features.h"
Frédéric Wang073e74a2020-12-16 17:43:3248#include "services/network/public/cpp/is_potentially_trustworthy.h"
Sandor «Alex» Majore9545a72025-01-31 20:40:4649#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
dominickn6947d752016-08-10 02:00:0650#include "url/gurl.h"
[email protected]bb326052014-07-09 10:55:4951
Dave Tapuska28e05eda2023-08-28 19:52:2152#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
Kevin McNee03403842023-08-28 14:48:3653#include "components/guest_view/browser/guest_view_base.h"
54#endif
55
Thomas Nguyen781e1352025-01-27 18:07:1956#if BUILDFLAG(IS_ANDROID)
57#include "components/permissions/android/android_permission_util.h"
58#include "ui/android/window_android.h"
59#endif
60
Clark DuValla11361ad32020-02-20 22:14:2761namespace permissions {
dominicknd9fb73c12017-03-01 03:34:1862namespace {
63
Illia Klimov2c6138b2023-08-14 09:39:2564using PermissionStatus = blink::mojom::PermissionStatus;
65
Julie Jeongeun Kima50467b2021-12-24 02:40:3466void LogPermissionBlockedMessage(content::RenderFrameHost* rfh,
Peter Kastingc70def22025-01-06 22:49:4867 std::string_view reason,
dominicknd9fb73c12017-03-01 03:34:1868 ContentSettingsType type) {
Julie Jeongeun Kima50467b2021-12-24 02:40:3469 rfh->GetOutermostMainFrame()->AddMessageToConsole(
Abhijeet Kandalkara5928a0a2019-03-13 05:04:4270 blink::mojom::ConsoleMessageLevel::kWarning,
Peter Kastingc70def22025-01-06 22:49:4871 base::StrCat({PermissionUtil::GetPermissionString(type),
72 " permission has been blocked", reason}));
dominicknd9fb73c12017-03-01 03:34:1873}
74
75} // namespace
76
kcarattini2ee48ad52015-10-26 23:45:3177// static
78const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] =
79 "PermissionsKillSwitch";
80// static
81const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] =
82 "blocked";
meredithl62b8c3d2017-01-10 05:47:5383
[email protected]bb326052014-07-09 10:55:4984PermissionContextBase::PermissionContextBase(
Clark DuValla11361ad32020-02-20 22:14:2785 content::BrowserContext* browser_context,
raymes21b9affc2017-05-31 06:15:2686 ContentSettingsType content_settings_type,
Sandor «Alex» Majore9545a72025-01-31 20:40:4687 network::mojom::PermissionsPolicyFeature permissions_policy_feature)
Clark DuValla11361ad32020-02-20 22:14:2788 : browser_context_(browser_context),
lshang88ec36a2015-12-09 04:50:1789 content_settings_type_(content_settings_type),
Charlie Hue20fe2f2021-03-07 03:39:5990 permissions_policy_feature_(permissions_policy_feature) {
Kevin McNee03403842023-08-28 14:48:3691 CHECK(permissions::PermissionUtil::IsPermission(content_settings_type_));
[email protected]bb326052014-07-09 10:55:4992}
93
94PermissionContextBase::~PermissionContextBase() {
James Hollyerd281a7312021-04-29 21:07:5995 DCHECK(permission_observers_.empty());
miguelgfa052072014-09-29 15:31:3896 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
[email protected]bb326052014-07-09 10:55:4997}
98
99void PermissionContextBase::RequestPermission(
Florian Jacky7f3e3ca1b2025-05-05 16:19:20100 std::unique_ptr<PermissionRequestData> request_data,
danakj47c8fb52019-05-02 16:34:36101 BrowserPermissionCallback callback) {
miguelgfa052072014-09-29 15:31:38102 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
[email protected]bb326052014-07-09 10:55:49103
Andy Paicu0a6d4b502023-08-29 15:13:09104 content::RenderFrameHost* const rfh = content::RenderFrameHost::FromID(
Florian Jacky7f3e3ca1b2025-05-05 16:19:20105 request_data->id.global_render_frame_host_id());
Illia Klimovba5d9762022-05-27 14:10:40106
107 if (!rfh) {
108 // Permission request is not allowed without a valid RenderFrameHost.
109 std::move(callback).Run(CONTENT_SETTING_ASK);
110 return;
111 }
112
Andy Paicu0a6d4b502023-08-29 15:13:09113 request_data
Florian Jacky7f3e3ca1b2025-05-05 16:19:20114 ->WithRequestingOrigin(
115 request_data->requesting_origin.DeprecatedGetOriginAsURL())
Ari Chivukulaf6f09ba2025-03-04 20:01:34116 .WithEmbeddingOrigin(GetEffectiveEmbedderOrigin(rfh));
johnmec36a56c2015-12-02 15:56:42117
Florian Jacky7f3e3ca1b2025-05-05 16:19:20118 if (!request_data->requesting_origin.is_valid() ||
119 !request_data->embedding_origin.is_valid()) {
Clark DuValla11361ad32020-02-20 22:14:27120 std::string type_name =
121 PermissionUtil::GetPermissionString(content_settings_type_);
johnmec36a56c2015-12-02 15:56:42122
123 DVLOG(1) << "Attempt to use " << type_name
Florian Jacky7f3e3ca1b2025-05-05 16:19:20124 << " from an invalid URL: " << request_data->requesting_origin
125 << "," << request_data->embedding_origin << " (" << type_name
johnmec36a56c2015-12-02 15:56:42126 << " is not supported in popups)";
Chris Fredrickson173060c862025-05-14 14:23:01127 NotifyPermissionSet(*request_data, std::move(callback),
Andy Paicu0a6d4b502023-08-29 15:13:09128 /*persist=*/false, CONTENT_SETTING_BLOCK,
129 /*is_one_time=*/false,
Illia Klimove406ecc12022-11-22 15:53:29130 /*is_final_decision=*/true);
johnmec36a56c2015-12-02 15:56:42131 return;
132 }
133
Timothy Loh8fbdac52018-03-15 03:34:30134 // Check the content setting to see if the user has already made a decision,
135 // or if the origin is under embargo. If so, respect that decision.
Henrique Ferreirof89870f2022-03-30 17:08:13136 DCHECK(rfh);
Andy Paicu0a6d4b502023-08-29 15:13:09137 content::PermissionResult result = GetPermissionStatus(
Chris Fredrickson173060c862025-05-14 14:23:01138 *request_data->resolver, rfh, request_data->requesting_origin,
Florian Jacky7f3e3ca1b2025-05-05 16:19:20139 request_data->embedding_origin);
meredithlcda94daf2017-01-19 03:03:35140
Andy Paicu0e16f8582023-09-28 08:34:34141 bool status_ignorable = PermissionUtil::CanPermissionRequestIgnoreStatus(
142 request_data, result.source);
143
144 if (!status_ignorable && (result.status == PermissionStatus::GRANTED ||
145 result.status == PermissionStatus::DENIED)) {
Peter Kastingc70def22025-01-06 22:49:48146 static constexpr char kResetInstructions[] =
147 " This can be reset in "
148#if BUILDFLAG(IS_ANDROID)
149 "Site Settings"
150#else
151 "Page Info which can be accessed by clicking the tune icon next to "
152 "the URL"
153#endif
154 ". See https://www.chromestatus.com/feature/6443143280984064 for "
155 "more information.";
dominickn728c5022017-04-04 09:14:15156 switch (result.source) {
Illia Klimov2c6138b2023-08-14 09:39:25157 case content::PermissionStatusSource::KILL_SWITCH:
dominickn728c5022017-04-04 09:14:15158 // Block the request and log to the developer console.
Peter Kastingc70def22025-01-06 22:49:48159 static constexpr char kPermissionBlockedKillSwitchReason[] = ".";
160 LogPermissionBlockedMessage(rfh, kPermissionBlockedKillSwitchReason,
dominickn728c5022017-04-04 09:14:15161 content_settings_type_);
Illia Klimovb5f70f12023-03-06 13:13:00162 PermissionUmaUtil::RecordPermissionRequestedFromFrame(
163 content_settings_type_, rfh);
danakj47c8fb52019-05-02 16:34:36164 std::move(callback).Run(CONTENT_SETTING_BLOCK);
dominickn728c5022017-04-04 09:14:15165 return;
Illia Klimov2c6138b2023-08-14 09:39:25166 case content::PermissionStatusSource::MULTIPLE_DISMISSALS:
Peter Kastingc70def22025-01-06 22:49:48167 static constexpr char kPermissionBlockedRepeatedDismissalsReason[] =
168 " as the user has dismissed the permission prompt several times.";
169 LogPermissionBlockedMessage(
170 rfh,
171 base::StrCat({kPermissionBlockedRepeatedDismissalsReason,
172 kResetInstructions}),
173 content_settings_type_);
Illia Klimovb5f70f12023-03-06 13:13:00174 PermissionUmaUtil::RecordPermissionRequestedFromFrame(
175 content_settings_type_, rfh);
dominickn728c5022017-04-04 09:14:15176 break;
Illia Klimov2c6138b2023-08-14 09:39:25177 case content::PermissionStatusSource::MULTIPLE_IGNORES:
Peter Kastingc70def22025-01-06 22:49:48178 static constexpr char kPermissionBlockedRepeatedIgnoresReason[] =
179 " as the user has ignored the permission prompt several times.";
180 LogPermissionBlockedMessage(
181 rfh,
182 base::StrCat(
183 {kPermissionBlockedRepeatedIgnoresReason, kResetInstructions}),
184 content_settings_type_);
Illia Klimovb5f70f12023-03-06 13:13:00185 PermissionUmaUtil::RecordPermissionRequestedFromFrame(
186 content_settings_type_, rfh);
dominickn728c5022017-04-04 09:14:15187 break;
Illia Klimov2c6138b2023-08-14 09:39:25188 case content::PermissionStatusSource::FEATURE_POLICY:
Peter Kastingc70def22025-01-06 22:49:48189 static constexpr char kPermissionBlockedPermissionsPolicyReason[] =
190 " because of a permissions policy applied to the current document. "
Elias Klim8897d612025-04-29 11:06:10191 "See https://crbug.com/414348233 for more details.";
Julie Jeongeun Kima50467b2021-12-24 02:40:34192 LogPermissionBlockedMessage(rfh,
Peter Kastingc70def22025-01-06 22:49:48193 kPermissionBlockedPermissionsPolicyReason,
Raymes Khoury42aff112017-10-18 06:47:06194 content_settings_type_);
195 break;
Illia Klimov2c6138b2023-08-14 09:39:25196 case content::PermissionStatusSource::RECENT_DISPLAY:
Peter Kastingc70def22025-01-06 22:49:48197 static constexpr char kPermissionBlockedRecentDisplayReason[] =
198 " as the prompt has already been displayed to the user recently.";
199 LogPermissionBlockedMessage(rfh, kPermissionBlockedRecentDisplayReason,
Zachary Tan11b28b12023-02-09 13:53:36200 content_settings_type_);
201 break;
Illia Klimov2c6138b2023-08-14 09:39:25202 case content::PermissionStatusSource::UNSPECIFIED:
Illia Klimovb5f70f12023-03-06 13:13:00203 PermissionUmaUtil::RecordPermissionRequestedFromFrame(
204 content_settings_type_, rfh);
205 break;
Illia Klimov2c6138b2023-08-14 09:39:25206 case content::PermissionStatusSource::FENCED_FRAME:
207 case content::PermissionStatusSource::INSECURE_ORIGIN:
208 case content::PermissionStatusSource::VIRTUAL_URL_DIFFERENT_ORIGIN:
dominickn728c5022017-04-04 09:14:15209 break;
dominickn23913152017-02-23 12:04:02210 }
211
212 // If we are under embargo, record the embargo reason for which we have
213 // suppressed the prompt.
Clark DuValla11361ad32020-02-20 22:14:27214 PermissionUmaUtil::RecordEmbargoPromptSuppressionFromSource(result.source);
Illia Klimov2c6138b2023-08-14 09:39:25215 NotifyPermissionSet(
Chris Fredrickson173060c862025-05-14 14:23:01216 *request_data, std::move(callback),
Illia Klimov2c6138b2023-08-14 09:39:25217 /*persist=*/false,
218 PermissionUtil::PermissionStatusToContentSetting(result.status),
219 /*is_one_time=*/false,
220 /*is_final_decision=*/true);
meredithlcda94daf2017-01-19 03:03:35221 return;
222 }
223
Illia Klimovb5f70f12023-03-06 13:13:00224 PermissionUmaUtil::RecordPermissionRequestedFromFrame(content_settings_type_,
225 rfh);
226
dominickn23913152017-02-23 12:04:02227 // We are going to show a prompt now.
Illia Klimove406ecc12022-11-22 15:53:29228 PermissionUmaUtil::PermissionRequested(content_settings_type_);
Clark DuValla11361ad32020-02-20 22:14:27229 PermissionUmaUtil::RecordEmbargoPromptSuppression(
230 PermissionEmbargoStatus::NOT_EMBARGOED);
johnmec36a56c2015-12-02 15:56:42231
Andy Paicu0a6d4b502023-08-29 15:13:09232 DecidePermission(std::move(request_data), std::move(callback));
[email protected]bb326052014-07-09 10:55:49233}
234
Illia Klimov0e1f7e002022-10-13 15:13:52235bool PermissionContextBase::IsRestrictedToSecureOrigins() const {
236 return true;
237}
238
benwells0b3748a2017-03-21 06:28:40239void PermissionContextBase::UserMadePermissionDecision(
Clark DuValla11361ad32020-02-20 22:14:27240 const PermissionRequestID& id,
benwells0b3748a2017-03-21 06:28:40241 const GURL& requesting_origin,
242 const GURL& embedding_origin,
243 ContentSetting content_setting) {}
244
Darwin Huang2aedfd562021-04-30 01:39:17245std::unique_ptr<PermissionRequest>
246PermissionContextBase::CreatePermissionRequest(
Darwin Huang2aedfd562021-04-30 01:39:17247 content::WebContents* web_contents,
Florian Jacky7f3e3ca1b2025-05-05 16:19:20248 std::unique_ptr<PermissionRequestData> request_data,
Bret Sepulveda5327d8b52021-07-21 17:44:23249 PermissionRequest::PermissionDecidedCallback permission_decided_callback,
Florian Jacky11f98102025-05-20 15:57:18250 base::OnceClosure request_finished_callback) const {
Bret Sepulveda5327d8b52021-07-21 17:44:23251 return std::make_unique<PermissionRequest>(
Andy Paicu0a6d4b502023-08-29 15:13:09252 std::move(request_data), std::move(permission_decided_callback),
Florian Jacky11f98102025-05-20 15:57:18253 std::move(request_finished_callback), UsesAutomaticEmbargo());
Elad Alonb3331802024-01-24 22:29:36254}
255
256bool PermissionContextBase::UsesAutomaticEmbargo() const {
257 return true;
Darwin Huang2aedfd562021-04-30 01:39:17258}
259
Andy Paicua0693aac2025-02-12 18:42:32260const PermissionRequest* PermissionContextBase::FindPermissionRequest(
261 const PermissionRequestID& id) const {
262 const auto request = pending_requests_.find(id.ToString());
263
264 if (request == pending_requests_.end()) {
265 return nullptr;
266 }
267
268 return request->second.first.get();
269}
270
Ari Chivukulaf6f09ba2025-03-04 20:01:34271GURL PermissionContextBase::GetEffectiveEmbedderOrigin(
272 content::RenderFrameHost* rfh) const {
273 return PermissionUtil::GetLastCommittedOriginAsURL(rfh->GetMainFrame());
274}
275
Illia Klimov2c6138b2023-08-14 09:39:25276content::PermissionResult PermissionContextBase::GetPermissionStatus(
Chris Fredrickson173060c862025-05-14 14:23:01277 const PermissionResolver& resolver,
raymesf6104d492017-03-09 01:20:18278 content::RenderFrameHost* render_frame_host,
miguelg7e9a98d2014-10-31 14:21:37279 const GURL& requesting_origin,
280 const GURL& embedding_origin) const {
kcarattini2ee48ad52015-10-26 23:45:31281 // If the permission has been disabled through Finch, block all requests.
raymesab359712017-02-15 06:23:25282 if (IsPermissionKillSwitchOn()) {
Illia Klimov2c6138b2023-08-14 09:39:25283 return content::PermissionResult(
284 PermissionStatus::DENIED, content::PermissionStatusSource::KILL_SWITCH);
raymesab359712017-02-15 06:23:25285 }
kcarattini2ee48ad52015-10-26 23:45:31286
Rohan Pavone013c4002019-08-21 20:13:52287 if (!IsPermissionAvailableToOrigins(requesting_origin, embedding_origin)) {
Illia Klimov2c6138b2023-08-14 09:39:25288 return content::PermissionResult(
289 PermissionStatus::DENIED,
290 content::PermissionStatusSource::INSECURE_ORIGIN);
mlamouria31c6ff12015-06-01 15:40:52291 }
292
Charlie Hu5130d25e2021-03-05 21:53:39293 // Check whether the feature is enabled for the frame by permissions policy.
294 // We can only do this when a RenderFrameHost has been provided.
raymes21b9affc2017-05-31 06:15:26295 if (render_frame_host &&
Charlie Hubb5943d2021-03-09 19:46:12296 !PermissionAllowedByPermissionsPolicy(render_frame_host)) {
Illia Klimov2c6138b2023-08-14 09:39:25297 return content::PermissionResult(
298 PermissionStatus::DENIED,
299 content::PermissionStatusSource::FEATURE_POLICY);
raymes21b9affc2017-05-31 06:15:26300 }
301
Robert Ogden24375242018-10-05 21:16:26302 if (render_frame_host) {
303 content::WebContents* web_contents =
304 content::WebContents::FromRenderFrameHost(render_frame_host);
305
306 // Automatically deny all HTTP or HTTPS requests where the virtual URL and
307 // the loaded URL are for different origins. The loaded URL is the one
308 // actually in the renderer, but the virtual URL is the one
309 // seen by the user. This may be very confusing for a user to see in a
310 // permissions request.
Lucas Furukawa Gadani5553a152019-01-08 18:55:57311 content::NavigationEntry* entry =
Robert Ogden24375242018-10-05 21:16:26312 web_contents->GetController().GetLastCommittedEntry();
313 if (entry) {
314 const GURL virtual_url = entry->GetVirtualURL();
315 const GURL loaded_url = entry->GetURL();
316 if (virtual_url.SchemeIsHTTPOrHTTPS() &&
317 loaded_url.SchemeIsHTTPOrHTTPS() &&
Lukasz Anforowiczd00c1ed2022-01-13 05:25:10318 !url::IsSameOriginWith(virtual_url, loaded_url)) {
Illia Klimov2c6138b2023-08-14 09:39:25319 return content::PermissionResult(
320 PermissionStatus::DENIED,
321 content::PermissionStatusSource::VIRTUAL_URL_DIFFERENT_ORIGIN);
Robert Ogden24375242018-10-05 21:16:26322 }
323 }
324 }
325
Dave Tapuska28e05eda2023-08-28 19:52:21326#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
Zelin Liu2046c8422024-08-27 20:25:05327 guest_view::GuestViewBase* guest =
328 guest_view::GuestViewBase::FromRenderFrameHost(render_frame_host);
329 if (guest) {
330 // Content inside GuestView instances may have different permission
331 // behavior.
332 std::optional<content::PermissionResult> maybe_result =
333 guest->OverridePermissionResult(content_settings_type_);
334 if (maybe_result.has_value()) {
335 return maybe_result.value();
336 }
337 // Some GuestViews are loaded in a separate StoragePartition. Given that
338 // permissions are scoped to a BrowserContext, not a StoragePartition, we
339 // may have a situation where a user has granted a permission to an origin
340 // in a tab and then visits the same origin in a guest. This would lead to
341 // inappropriate sharing of the permission with the guest. To mitigate this,
342 // we drop permission requests from guests for cases where it's not possible
343 // for the guest to have been granted the permission. Note that sharing of
344 // permissions that the guest could legitimately be granted is still
345 // possible.
346 // TODO(crbug.com/40068594): Scope granted permissions to a
347 // StoragePartition.
348 if (base::FeatureList::IsEnabled(
349 features::kMitigateUnpartitionedWebviewPermissions) &&
350 !guest->IsPermissionRequestable(content_settings_type_)) {
Kevin McNee03403842023-08-28 14:48:36351 return content::PermissionResult(
352 PermissionStatus::DENIED,
353 content::PermissionStatusSource::UNSPECIFIED);
354 }
355 }
356#endif
357
raymesf6104d492017-03-09 01:20:18358 ContentSetting content_setting = GetPermissionStatusInternal(
359 render_frame_host, requesting_origin, embedding_origin);
raymesab359712017-02-15 06:23:25360
Anatoliy Potapchuk57f83092019-11-15 13:42:22361 if (content_setting != CONTENT_SETTING_ASK) {
Illia Klimov2c6138b2023-08-14 09:39:25362 return content::PermissionResult(
363 PermissionUtil::ContentSettingToPermissionStatus(content_setting),
364 content::PermissionStatusSource::UNSPECIFIED);
Anatoliy Potapchuk57f83092019-11-15 13:42:22365 }
Anatoliy Potapchuk57f83092019-11-15 13:42:22366
Elad Alonb3331802024-01-24 22:29:36367 if (UsesAutomaticEmbargo()) {
Arthur Sonzognic571efb2024-01-26 20:26:18368 std::optional<content::PermissionResult> result =
Elad Alonb3331802024-01-24 22:29:36369 PermissionsClient::Get()
370 ->GetPermissionDecisionAutoBlocker(browser_context_)
371 ->GetEmbargoResult(requesting_origin, content_settings_type_);
372 if (result) {
373 DCHECK(result->status == PermissionStatus::DENIED);
374 return result.value();
375 }
Peter Kotwicz63559a82022-06-07 03:46:35376 }
Illia Klimov2c6138b2023-08-14 09:39:25377 return content::PermissionResult(
378 PermissionStatus::ASK, content::PermissionStatusSource::UNSPECIFIED);
miguelg7e9a98d2014-10-31 14:21:37379}
380
Florian Jacky7f3e3ca1b2025-05-05 16:19:20381content::PermissionResult PermissionContextBase::GetPermissionStatus(
382 const blink::mojom::PermissionDescriptorPtr& permission_descriptor,
383 content::RenderFrameHost* render_frame_host,
384 const GURL& requesting_origin,
385 const GURL& embedding_origin) const {
Chris Fredrickson173060c862025-05-14 14:23:01386 return GetPermissionStatus(*CreatePermissionResolver(permission_descriptor),
Florian Jacky7f3e3ca1b2025-05-05 16:19:20387 render_frame_host, requesting_origin,
388 embedding_origin);
389}
390
Rohan Pavone013c4002019-08-21 20:13:52391bool PermissionContextBase::IsPermissionAvailableToOrigins(
392 const GURL& requesting_origin,
393 const GURL& embedding_origin) const {
394 if (IsRestrictedToSecureOrigins()) {
Frédéric Wang073e74a2020-12-16 17:43:32395 if (!network::IsUrlPotentiallyTrustworthy(requesting_origin))
Rohan Pavone013c4002019-08-21 20:13:52396 return false;
397
398 // TODO(raymes): We should check the entire chain of embedders here whenever
399 // possible as this corresponds to the requirements of the secure contexts
400 // spec and matches what is implemented in blink. Right now we just check
Clark DuValla11361ad32020-02-20 22:14:27401 // the top level and requesting origins.
402 if (!PermissionsClient::Get()->CanBypassEmbeddingOriginCheck(
403 requesting_origin, embedding_origin) &&
Frédéric Wang073e74a2020-12-16 17:43:32404 !network::IsUrlPotentiallyTrustworthy(embedding_origin)) {
Rohan Pavone013c4002019-08-21 20:13:52405 return false;
Clark DuValla11361ad32020-02-20 22:14:27406 }
Rohan Pavone013c4002019-08-21 20:13:52407 }
408 return true;
409}
410
Illia Klimov2c6138b2023-08-14 09:39:25411content::PermissionResult
412PermissionContextBase::UpdatePermissionStatusWithDeviceStatus(
Thomas Nguyen781e1352025-01-27 18:07:19413 content::WebContents* web_contents,
Illia Klimov2c6138b2023-08-14 09:39:25414 content::PermissionResult result,
benwells59547522017-03-10 05:30:00415 const GURL& requesting_origin,
Andy Paicu9d70da42024-05-10 22:24:39416 const GURL& embedding_origin) {
Thomas Nguyen781e1352025-01-27 18:07:19417 MaybeUpdateCachedHasDevicePermission(web_contents);
Andy Paicu72b4edf2023-09-15 09:52:43418
419 // If the site content setting is ASK/BLOCKED the device-level permission
420 // won't affect it.
421 if (result.status != blink::mojom::PermissionStatus::GRANTED) {
Andy Paicu24b02bb2023-09-06 14:49:08422 return result;
423 }
424
425 // If the device-level permission is granted, it has no effect on the result.
Thomas Nguyen781e1352025-01-27 18:07:19426 if (last_has_device_permission_result_.has_value() &&
427 last_has_device_permission_result_.value()) {
Andy Paicu24b02bb2023-09-06 14:49:08428 return result;
429 }
430
Thomas Nguyen781e1352025-01-27 18:07:19431#if BUILDFLAG(IS_ANDROID)
432 if (!web_contents || !web_contents->GetNativeView() ||
433 !web_contents->GetNativeView()->GetWindowAndroid()) {
434 return result;
435 }
436 result.status =
437 CanRequestSystemPermission(content_settings_type(), web_contents)
438 ? blink::mojom::PermissionStatus::ASK
439 : blink::mojom::PermissionStatus::DENIED;
440#else
Andy Paicu24b02bb2023-09-06 14:49:08441 // Otherwise the result will be "ASK" if the browser can ask for the
Andy Paicu72b4edf2023-09-15 09:52:43442 // device-level permission, and "BLOCKED" otherwise.
Andy Paicu24b02bb2023-09-06 14:49:08443 result.status = PermissionsClient::Get()->CanRequestDevicePermission(
444 content_settings_type())
Andy Paicu72b4edf2023-09-15 09:52:43445 ? blink::mojom::PermissionStatus::ASK
446 : blink::mojom::PermissionStatus::DENIED;
Thomas Nguyen781e1352025-01-27 18:07:19447#endif
benwells59547522017-03-10 05:30:00448 return result;
449}
450
dominickn23913152017-02-23 12:04:02451void PermissionContextBase::ResetPermission(const GURL& requesting_origin,
452 const GURL& embedding_origin) {
Raymes Khoury47df4b22018-05-10 04:30:17453 if (!content_settings::ContentSettingsRegistry::GetInstance()->Get(
454 content_settings_type_)) {
455 return;
456 }
Clark DuValla11361ad32020-02-20 22:14:27457 PermissionsClient::Get()
458 ->GetSettingsMap(browser_context_)
lshang38126112016-03-22 03:19:58459 ->SetContentSettingDefaultScope(requesting_origin, embedding_origin,
Illia Klimov48f643c2020-11-05 20:06:14460 content_settings_type_,
cm.sanchi761e67a2017-11-16 08:23:28461 CONTENT_SETTING_DEFAULT);
timvolodine16be5202015-02-02 17:44:54462}
463
Andy Paicu9d70da42024-05-10 22:24:39464bool PermissionContextBase::AlwaysIncludeDeviceStatus() const {
465 return false;
466}
467
raymes0f93a582016-12-20 04:08:42468bool PermissionContextBase::IsPermissionKillSwitchOn() const {
Clark DuValla11361ad32020-02-20 22:14:27469 const std::string param = base::GetFieldTrialParamValue(
raymes0f93a582016-12-20 04:08:42470 kPermissionsKillSwitchFieldStudy,
Clark DuValla11361ad32020-02-20 22:14:27471 PermissionUtil::GetPermissionString(content_settings_type_));
raymes0f93a582016-12-20 04:08:42472
473 return param == kPermissionsKillSwitchBlockedValue;
474}
475
476ContentSetting PermissionContextBase::GetPermissionStatusInternal(
raymesf6104d492017-03-09 01:20:18477 content::RenderFrameHost* render_frame_host,
raymes0f93a582016-12-20 04:08:42478 const GURL& requesting_origin,
479 const GURL& embedding_origin) const {
Clark DuValla11361ad32020-02-20 22:14:27480 return PermissionsClient::Get()
481 ->GetSettingsMap(browser_context_)
raymes0f93a582016-12-20 04:08:42482 ->GetContentSetting(requesting_origin, embedding_origin,
Illia Klimov48f643c2020-11-05 20:06:14483 content_settings_type_);
raymes0f93a582016-12-20 04:08:42484}
485
[email protected]bb326052014-07-09 10:55:49486void PermissionContextBase::DecidePermission(
Florian Jacky7f3e3ca1b2025-05-05 16:19:20487 std::unique_ptr<PermissionRequestData> request_data,
danakj47c8fb52019-05-02 16:34:36488 BrowserPermissionCallback callback) {
thestig00844cea2015-09-08 21:44:52489 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
[email protected]bb326052014-07-09 10:55:49490
Raymes Khouryb474c642018-02-28 06:16:28491 // Under permission delegation, when we display a permission prompt, the
492 // origin displayed in the prompt should never differ from the top-level
Clark DuValla11361ad32020-02-20 22:14:27493 // origin. Storage access API requests are excluded as they are expected to
Matt Reichhoff4c85cb32023-01-20 16:49:16494 // request permissions from the frame origin needing access.
Andy Paicu93e63ac82020-08-18 14:52:17495 DCHECK(PermissionsClient::Get()->CanBypassEmbeddingOriginCheck(
Florian Jacky7f3e3ca1b2025-05-05 16:19:20496 request_data->requesting_origin, request_data->embedding_origin) ||
497 request_data->requesting_origin == request_data->embedding_origin ||
Matt Reichhoff4c85cb32023-01-20 16:49:16498 content_settings_type_ == ContentSettingsType::STORAGE_ACCESS);
Raymes Khouryb474c642018-02-28 06:16:28499
Andy Paicu0a6d4b502023-08-29 15:13:09500 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
Florian Jacky7f3e3ca1b2025-05-05 16:19:20501 request_data->id.global_render_frame_host_id());
Illia Klimovba5d9762022-05-27 14:10:40502 DCHECK(rfh);
503
504 content::WebContents* web_contents =
505 content::WebContents::FromRenderFrameHost(rfh);
Clark DuValla11361ad32020-02-20 22:14:27506 PermissionRequestManager* permission_request_manager =
507 PermissionRequestManager::FromWebContents(web_contents);
Timothy Loh8786fb32017-09-06 03:04:05508 // TODO(felt): sometimes |permission_request_manager| is null. This check is
509 // meant to prevent crashes. See crbug.com/457091.
Kevin McNee03403842023-08-28 14:48:36510 if (!permission_request_manager) {
511 std::move(callback).Run(CONTENT_SETTING_ASK);
Timothy Loh8786fb32017-09-06 03:04:05512 return;
Kevin McNee03403842023-08-28 14:48:36513 }
[email protected]bb326052014-07-09 10:55:49514
Andy Paicu0a6d4b502023-08-29 15:13:09515 auto decided_cb = base::BindRepeating(
Florian Jacky7f3e3ca1b2025-05-05 16:19:20516 &PermissionContextBase::PermissionDecided, weak_factory_.GetWeakPtr());
Thomas Nguyen781e1352025-01-27 18:07:19517 auto cleanup_cb =
518 base::BindOnce(&PermissionContextBase::CleanUpRequest,
Florian Jacky7f3e3ca1b2025-05-05 16:19:20519 weak_factory_.GetWeakPtr(), web_contents, request_data->id,
520 request_data->embedded_permission_element_initiated);
521 PermissionRequestID permission_request_id = request_data->id;
Andy Paicu0a6d4b502023-08-29 15:13:09522
Florian Jacky11f98102025-05-20 15:57:18523 std::unique_ptr<PermissionRequest> request =
Andy Paicu0a6d4b502023-08-29 15:13:09524 CreatePermissionRequest(web_contents, std::move(request_data),
525 std::move(decided_cb), std::move(cleanup_cb));
lshangc4089c72016-10-26 06:54:30526
Andy Paicu0a6d4b502023-08-29 15:13:09527 bool inserted =
528 pending_requests_
529 .insert(std::make_pair(
530 permission_request_id.ToString(),
Florian Jacky11f98102025-05-20 15:57:18531 std::make_pair(request->GetWeakPtr(), std::move(callback))))
Andy Paicu0a6d4b502023-08-29 15:13:09532 .second;
Florian Jacky7f3e3ca1b2025-05-05 16:19:20533
Andy Paicu0a6d4b502023-08-29 15:13:09534 DCHECK(inserted) << "Duplicate id " << permission_request_id.ToString();
Carlos Caballero8a6c6b72020-07-20 16:56:22535
Florian Jacky7f3e3ca1b2025-05-05 16:19:20536 permission_request_manager->AddRequest(rfh, std::move(request));
[email protected]bb326052014-07-09 10:55:49537}
538
Florian Jacky7f3e3ca1b2025-05-05 16:19:20539void PermissionContextBase::PermissionDecided(
540 ContentSetting content_setting,
541 bool is_one_time,
542 bool is_final_decision,
Chris Fredrickson173060c862025-05-14 14:23:01543 const PermissionRequestData& request_data) {
Timothy Loh8786fb32017-09-06 03:04:05544 DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
545 content_setting == CONTENT_SETTING_BLOCK ||
546 content_setting == CONTENT_SETTING_DEFAULT);
Chris Fredrickson173060c862025-05-14 14:23:01547 UserMadePermissionDecision(request_data.id, request_data.requesting_origin,
548 request_data.embedding_origin, content_setting);
Timothy Loh92a6b8c2018-01-12 06:49:54549
550 bool persist = content_setting != CONTENT_SETTING_DEFAULT;
Illia Klimove406ecc12022-11-22 15:53:29551
Chris Fredrickson173060c862025-05-14 14:23:01552 auto request = pending_requests_.find(request_data.id.ToString());
Florian Jacky11f98102025-05-20 15:57:18553 CHECK(request->second.first);
Daniel Cheng4d54f0a2025-05-26 22:59:12554 CHECK(request != pending_requests_.end());
Illia Klimove406ecc12022-11-22 15:53:29555 // Check if `request` has `BrowserPermissionCallback`. The call back might be
556 // missing if a permission prompt was preignored and we already notified an
557 // origin about it.
558 if (request->second.second) {
Florian Jacky7f3e3ca1b2025-05-05 16:19:20559 NotifyPermissionSet(request_data, std::move(request->second.second),
560 persist, content_setting, is_one_time,
561 is_final_decision);
Illia Klimove406ecc12022-11-22 15:53:29562 } else {
Florian Jacky7f3e3ca1b2025-05-05 16:19:20563 NotifyPermissionSet(request_data, base::DoNothing(), persist,
564 content_setting, is_one_time, is_final_decision);
Illia Klimove406ecc12022-11-22 15:53:29565 }
[email protected]bb326052014-07-09 10:55:49566}
567
Clark DuValla11361ad32020-02-20 22:14:27568content::BrowserContext* PermissionContextBase::browser_context() const {
569 return browser_context_;
timvolodine1baa38862014-12-12 16:33:12570}
571
James Hollyerd281a7312021-04-29 21:07:59572void PermissionContextBase::OnContentSettingChanged(
573 const ContentSettingsPattern& primary_pattern,
574 const ContentSettingsPattern& secondary_pattern,
Christian Dullweber2c4c71d2021-10-14 15:07:43575 ContentSettingsTypeSet content_type_set) {
Andy Paicu72b4edf2023-09-15 09:52:43576 NotifyObservers(primary_pattern, secondary_pattern, content_type_set);
James Hollyerd281a7312021-04-29 21:07:59577}
578
579void PermissionContextBase::AddObserver(
580 permissions::Observer* permission_observer) {
581 if (permission_observers_.empty() &&
582 !content_setting_observer_registered_by_subclass_) {
583 PermissionsClient::Get()
584 ->GetSettingsMap(browser_context_)
585 ->AddObserver(this);
586 }
587 permission_observers_.AddObserver(permission_observer);
588}
589
590void PermissionContextBase::RemoveObserver(
591 permissions::Observer* permission_observer) {
592 permission_observers_.RemoveObserver(permission_observer);
593 if (permission_observers_.empty() &&
594 !content_setting_observer_registered_by_subclass_) {
595 PermissionsClient::Get()
596 ->GetSettingsMap(browser_context_)
597 ->RemoveObserver(this);
598 }
599}
600
Florian Jacky7f3e3ca1b2025-05-05 16:19:20601std::unique_ptr<PermissionResolver>
602PermissionContextBase::CreatePermissionResolver(
603 const blink::mojom::PermissionDescriptorPtr& permission_descriptor) const {
604 return CreateRequestIndependentPermissionResolver();
605}
606
607std::unique_ptr<PermissionResolver>
608PermissionContextBase::CreateRequestIndependentPermissionResolver() const {
609 return std::make_unique<ContentSettingPermissionResolver>(
610 content_settings_type_);
611}
612
Thomas Nguyen781e1352025-01-27 18:07:19613void PermissionContextBase::MaybeUpdateCachedHasDevicePermission(
614 content::WebContents* web_contents) {
615#if BUILDFLAG(IS_ANDROID)
616 if (!web_contents || !web_contents->GetNativeView() ||
617 !web_contents->GetNativeView()->GetWindowAndroid()) {
618 return;
619 }
620 const bool has_device_permission =
621 has_device_permission_for_test_.has_value()
622 ? has_device_permission_for_test_.value()
623 : HasSystemPermission(content_settings_type(), web_contents);
624#else
Andy Paicu9d70da42024-05-10 22:24:39625 const bool has_device_permission =
Thomas Nguyend9d33072024-06-06 15:15:27626 has_device_permission_for_test_.has_value()
627 ? has_device_permission_for_test_.value()
628 : PermissionsClient::Get()->HasDevicePermission(
629 content_settings_type());
Thomas Nguyen781e1352025-01-27 18:07:19630#endif
631
Andy Paicu9d70da42024-05-10 22:24:39632 const bool should_notify_observers =
633 last_has_device_permission_result_.has_value() &&
634 has_device_permission != last_has_device_permission_result_;
635
636 // We need to update |last_has_device_permission_result_| before calling
637 // |OnContentSettingChanged| to avoid causing a re-entrancy issue since the
638 // |OnContentSettingChanged| will likely end up calling |GetPermissionStatus|.
639 last_has_device_permission_result_ = has_device_permission;
640
641 if (should_notify_observers) {
642 NotifyObservers(ContentSettingsPattern::Wildcard(),
643 ContentSettingsPattern::Wildcard(),
644 ContentSettingsTypeSet(content_settings_type()));
645 }
646}
647
[email protected]bb326052014-07-09 10:55:49648void PermissionContextBase::NotifyPermissionSet(
Chris Fredrickson173060c862025-05-14 14:23:01649 const PermissionRequestData& request_data,
danakj47c8fb52019-05-02 16:34:36650 BrowserPermissionCallback callback,
[email protected]bb326052014-07-09 10:55:49651 bool persist,
Ravjit Singh Uppalc73b5a62020-11-13 01:38:52652 ContentSetting content_setting,
Illia Klimove406ecc12022-11-22 15:53:29653 bool is_one_time,
654 bool is_final_decision) {
thestig00844cea2015-09-08 21:44:52655 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
[email protected]bb326052014-07-09 10:55:49656
Ravjit Singh Uppalc73b5a62020-11-13 01:38:52657 if (persist) {
Florian Jacky7f3e3ca1b2025-05-05 16:19:20658 UpdateContentSetting(request_data, content_setting, is_one_time);
Ravjit Singh Uppalc73b5a62020-11-13 01:38:52659 }
mlamouridf357a312015-03-03 17:34:05660
Illia Klimove406ecc12022-11-22 15:53:29661 if (is_final_decision) {
Chris Fredrickson173060c862025-05-14 14:23:01662 UpdateTabContext(request_data.id, request_data.requesting_origin,
Illia Klimove406ecc12022-11-22 15:53:29663 content_setting == CONTENT_SETTING_ALLOW);
Thomas Nguyen88df73a2023-02-28 20:50:46664 if (content_setting == CONTENT_SETTING_ALLOW) {
665 if (auto* rfh = content::RenderFrameHost::FromID(
Chris Fredrickson173060c862025-05-14 14:23:01666 request_data.id.global_render_frame_host_id())) {
Thomas Nguyen88df73a2023-02-28 20:50:46667 PermissionUmaUtil::RecordPermissionsUsageSourceAndPolicyConfiguration(
668 content_settings_type_, rfh);
669 }
670 }
Illia Klimove406ecc12022-11-22 15:53:29671 }
mlamouridf357a312015-03-03 17:34:05672
raymes423d965f2016-09-29 00:46:25673 if (content_setting == CONTENT_SETTING_DEFAULT)
674 content_setting = CONTENT_SETTING_ASK;
mlamouridf357a312015-03-03 17:34:05675
danakj47c8fb52019-05-02 16:34:36676 std::move(callback).Run(content_setting);
[email protected]bb326052014-07-09 10:55:49677}
678
Thomas Nguyend9d33072024-06-06 15:15:27679void PermissionContextBase::CleanUpRequest(
Thomas Nguyen781e1352025-01-27 18:07:19680 content::WebContents* web_contents,
Thomas Nguyend9d33072024-06-06 15:15:27681 const PermissionRequestID& id,
682 bool embedded_permission_element_initiated) {
tsergeant58defcfb2016-07-19 23:47:28683 size_t success = pending_requests_.erase(id.ToString());
Thomas Nguyend9d33072024-06-06 15:15:27684 // A request from an embedded permission element requires a notification
685 // `OnPermissionChanged` when changing the device status, which is currently
686 // unavailable. We compare the device status with the cached status and notify
687 // `OnPermissionChanged` here. We should remove this line once the device
688 // status change observer is implemented.
689 if (embedded_permission_element_initiated) {
Thomas Nguyen781e1352025-01-27 18:07:19690 MaybeUpdateCachedHasDevicePermission(web_contents);
Thomas Nguyend9d33072024-06-06 15:15:27691 }
[email protected]bb326052014-07-09 10:55:49692 DCHECK(success == 1) << "Missing request " << id.ToString();
693}
694
Florian Jacky7f3e3ca1b2025-05-05 16:19:20695void PermissionContextBase::UpdateContentSetting(
Chris Fredrickson173060c862025-05-14 14:23:01696 const PermissionRequestData& request_data,
Florian Jacky7f3e3ca1b2025-05-05 16:19:20697 ContentSetting content_setting,
698 bool is_one_time) {
Chris Fredrickson173060c862025-05-14 14:23:01699 DCHECK_EQ(request_data.requesting_origin,
700 request_data.requesting_origin.DeprecatedGetOriginAsURL());
701 DCHECK_EQ(request_data.embedding_origin,
702 request_data.embedding_origin.DeprecatedGetOriginAsURL());
mlamouridf357a312015-03-03 17:34:05703 DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
704 content_setting == CONTENT_SETTING_BLOCK);
705
Chris Fredrickson4486fdd2023-06-12 18:18:27706 content_settings::ContentSettingConstraints constraints;
Jonathan Njeunjedc5bc0102024-02-23 16:54:06707 constraints.set_session_model(
708 is_one_time ? content_settings::mojom::SessionModel::ONE_TIME
709 : content_settings::mojom::SessionModel::DURABLE);
Martin Šrámek83594ca2022-08-03 19:25:58710
Zaina Al-Mashni19011012025-01-09 12:28:22711 // The Permissions module in Safety check will revoke permissions after
712 // a finite amount of time if the permission can be revoked.
713 if (content_settings::CanBeAutoRevoked(content_settings_type_,
714 content_setting, is_one_time)) {
715 // For #2, by definition, that should be all of them. If that changes in
716 // the future, consider whether revocation for such permission makes
717 // sense, and/or change this to an early return so that we don't
718 // unnecessarily record timestamps where we don't need them.
719 constraints.set_track_last_visit_for_autoexpiration(true);
Martin Šrámek83594ca2022-08-03 19:25:58720 }
Martin Šrámek83594ca2022-08-03 19:25:58721
Florian Jacky8425f922024-05-08 20:57:47722 if (is_one_time) {
Florian Jacky41742ec62024-12-05 09:48:29723 if (content_settings::ShouldTypeExpireActively(content_settings_type_)) {
Florian Jacky989b41b2023-07-31 16:33:42724 constraints.set_lifetime(kOneTimePermissionMaximumLifetime);
725 }
726 }
727
Clark DuValla11361ad32020-02-20 22:14:27728 PermissionsClient::Get()
729 ->GetSettingsMap(browser_context_)
Florian Jacky7f3e3ca1b2025-05-05 16:19:20730 ->SetContentSettingDefaultScope(
Chris Fredrickson173060c862025-05-14 14:23:01731 request_data.requesting_origin, request_data.embedding_origin,
Florian Jacky7f3e3ca1b2025-05-05 16:19:20732 content_settings_type_, content_setting, constraints);
[email protected]bb326052014-07-09 10:55:49733}
raymes21b9affc2017-05-31 06:15:26734
Charlie Hubb5943d2021-03-09 19:46:12735bool PermissionContextBase::PermissionAllowedByPermissionsPolicy(
raymes21b9affc2017-05-31 06:15:26736 content::RenderFrameHost* rfh) const {
Charlie Hu5130d25e2021-03-05 21:53:39737 // Some features don't have an associated permissions policy yet. Allow those.
Charlie Hue20fe2f2021-03-07 03:39:59738 if (permissions_policy_feature_ ==
Sandor «Alex» Majore9545a72025-01-31 20:40:46739 network::mojom::PermissionsPolicyFeature::kNotFound) {
raymes21b9affc2017-05-31 06:15:26740 return true;
Sandor «Alex» Majore9545a72025-01-31 20:40:46741 }
raymes21b9affc2017-05-31 06:15:26742
Charlie Hue20fe2f2021-03-07 03:39:59743 return rfh->IsFeatureEnabled(permissions_policy_feature_);
raymes21b9affc2017-05-31 06:15:26744}
Clark DuValla11361ad32020-02-20 22:14:27745
Andy Paicu72b4edf2023-09-15 09:52:43746void PermissionContextBase::NotifyObservers(
747 const ContentSettingsPattern& primary_pattern,
748 const ContentSettingsPattern& secondary_pattern,
749 ContentSettingsTypeSet content_type_set) const {
750 if (!content_type_set.Contains(content_settings_type_)) {
751 return;
752 }
753
754 for (permissions::Observer& obs : permission_observers_) {
755 obs.OnPermissionChanged(primary_pattern, secondary_pattern,
756 content_type_set);
757 }
758}
759
Clark DuValla11361ad32020-02-20 22:14:27760} // namespace permissions