permission_context_base.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. // Copyright 2014 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. #include "components/permissions/permission_context_base.h"
  5. #include <stddef.h>
  6. #include <string>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/callback.h"
  10. #include "base/logging.h"
  11. #include "base/metrics/field_trial_params.h"
  12. #include "base/observer_list.h"
  13. #include "base/strings/stringprintf.h"
  14. #include "base/time/time.h"
  15. #include "build/build_config.h"
  16. #include "components/content_settings/core/browser/content_settings_registry.h"
  17. #include "components/content_settings/core/browser/host_content_settings_map.h"
  18. #include "components/permissions/features.h"
  19. #include "components/permissions/permission_decision_auto_blocker.h"
  20. #include "components/permissions/permission_request.h"
  21. #include "components/permissions/permission_request_id.h"
  22. #include "components/permissions/permission_request_manager.h"
  23. #include "components/permissions/permission_uma_util.h"
  24. #include "components/permissions/permission_util.h"
  25. #include "components/permissions/permissions_client.h"
  26. #include "components/permissions/request_type.h"
  27. #include "content/public/browser/back_forward_cache.h"
  28. #include "content/public/browser/browser_thread.h"
  29. #include "content/public/browser/disallow_activation_reason.h"
  30. #include "content/public/browser/global_routing_id.h"
  31. #include "content/public/browser/navigation_entry.h"
  32. #include "content/public/browser/render_frame_host.h"
  33. #include "content/public/browser/web_contents.h"
  34. #include "content/public/common/content_features.h"
  35. #include "services/network/public/cpp/is_potentially_trustworthy.h"
  36. #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
  37. #include "url/gurl.h"
  38. namespace permissions {
  39. namespace {
  40. const char kPermissionBlockedKillSwitchMessage[] =
  41. "%s permission has been blocked.";
  42. #if BUILDFLAG(IS_ANDROID)
  43. const char kPermissionBlockedRepeatedDismissalsMessage[] =
  44. "%s permission has been blocked as the user has dismissed the permission "
  45. "prompt several times. This can be reset in Site Settings. See "
  46. "https://www.chromestatus.com/feature/6443143280984064 for more "
  47. "information.";
  48. const char kPermissionBlockedRepeatedIgnoresMessage[] =
  49. "%s permission has been blocked as the user has ignored the permission "
  50. "prompt several times. This can be reset in Site Settings. See "
  51. "https://www.chromestatus.com/feature/6443143280984064 for more "
  52. "information.";
  53. #else
  54. const char kPermissionBlockedRepeatedDismissalsMessage[] =
  55. "%s permission has been blocked as the user has dismissed the permission "
  56. "prompt several times. This can be reset in Page Info which can be "
  57. "accessed by clicking the lock icon next to the URL. See "
  58. "https://www.chromestatus.com/feature/6443143280984064 for more "
  59. "information.";
  60. const char kPermissionBlockedRepeatedIgnoresMessage[] =
  61. "%s permission has been blocked as the user has ignored the permission "
  62. "prompt several times. This can be reset in Page Info which can be "
  63. "accessed by clicking the lock icon next to the URL. See "
  64. "https://www.chromestatus.com/feature/6443143280984064 for more "
  65. "information.";
  66. #endif
  67. const char kPermissionBlockedPermissionsPolicyMessage[] =
  68. "%s permission has been blocked because of a permissions policy applied to"
  69. " the current document. See https://goo.gl/EuHzyv for more details.";
  70. const char kPermissionBlockedPortalsMessage[] =
  71. "%s permission has been blocked because it was requested inside a portal. "
  72. "Portals don't currently support permission requests.";
  73. const char kPermissionBlockedFencedFrameMessage[] =
  74. "%s permission has been blocked because it was requested inside a fenced "
  75. "frame. Fenced frames don't currently support permission requests.";
  76. void LogPermissionBlockedMessage(content::RenderFrameHost* rfh,
  77. const char* message,
  78. ContentSettingsType type) {
  79. rfh->GetOutermostMainFrame()->AddMessageToConsole(
  80. blink::mojom::ConsoleMessageLevel::kWarning,
  81. base::StringPrintf(message,
  82. PermissionUtil::GetPermissionString(type).c_str()));
  83. }
  84. } // namespace
  85. // static
  86. const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] =
  87. "PermissionsKillSwitch";
  88. // static
  89. const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] =
  90. "blocked";
  91. PermissionContextBase::PermissionContextBase(
  92. content::BrowserContext* browser_context,
  93. ContentSettingsType content_settings_type,
  94. blink::mojom::PermissionsPolicyFeature permissions_policy_feature)
  95. : browser_context_(browser_context),
  96. content_settings_type_(content_settings_type),
  97. permissions_policy_feature_(permissions_policy_feature) {
  98. PermissionDecisionAutoBlocker::UpdateFromVariations();
  99. }
  100. PermissionContextBase::~PermissionContextBase() {
  101. DCHECK(permission_observers_.empty());
  102. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  103. }
  104. void PermissionContextBase::RequestPermission(
  105. const PermissionRequestID& id,
  106. const GURL& requesting_frame,
  107. bool user_gesture,
  108. BrowserPermissionCallback callback) {
  109. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  110. content::RenderFrameHost* const rfh = content::RenderFrameHost::FromID(
  111. id.render_process_id(), id.render_frame_id());
  112. if (!rfh) {
  113. // Permission request is not allowed without a valid RenderFrameHost.
  114. std::move(callback).Run(CONTENT_SETTING_ASK);
  115. return;
  116. }
  117. const GURL requesting_origin = requesting_frame.DeprecatedGetOriginAsURL();
  118. const GURL embedding_origin =
  119. PermissionUtil::GetLastCommittedOriginAsURL(rfh->GetMainFrame());
  120. if (!requesting_origin.is_valid() || !embedding_origin.is_valid()) {
  121. std::string type_name =
  122. PermissionUtil::GetPermissionString(content_settings_type_);
  123. DVLOG(1) << "Attempt to use " << type_name
  124. << " from an invalid URL: " << requesting_origin << ","
  125. << embedding_origin << " (" << type_name
  126. << " is not supported in popups)";
  127. NotifyPermissionSet(id, requesting_origin, embedding_origin,
  128. std::move(callback), /*persist=*/false,
  129. CONTENT_SETTING_BLOCK, /*is_one_time=*/false);
  130. return;
  131. }
  132. // Check the content setting to see if the user has already made a decision,
  133. // or if the origin is under embargo. If so, respect that decision.
  134. DCHECK(rfh);
  135. PermissionResult result =
  136. GetPermissionStatus(rfh, requesting_origin, embedding_origin);
  137. if (result.content_setting == CONTENT_SETTING_ALLOW ||
  138. result.content_setting == CONTENT_SETTING_BLOCK) {
  139. switch (result.source) {
  140. case PermissionStatusSource::KILL_SWITCH:
  141. // Block the request and log to the developer console.
  142. LogPermissionBlockedMessage(rfh, kPermissionBlockedKillSwitchMessage,
  143. content_settings_type_);
  144. std::move(callback).Run(CONTENT_SETTING_BLOCK);
  145. return;
  146. case PermissionStatusSource::MULTIPLE_DISMISSALS:
  147. LogPermissionBlockedMessage(rfh,
  148. kPermissionBlockedRepeatedDismissalsMessage,
  149. content_settings_type_);
  150. break;
  151. case PermissionStatusSource::MULTIPLE_IGNORES:
  152. LogPermissionBlockedMessage(rfh,
  153. kPermissionBlockedRepeatedIgnoresMessage,
  154. content_settings_type_);
  155. break;
  156. case PermissionStatusSource::FEATURE_POLICY:
  157. LogPermissionBlockedMessage(rfh,
  158. kPermissionBlockedPermissionsPolicyMessage,
  159. content_settings_type_);
  160. break;
  161. case PermissionStatusSource::PORTAL:
  162. LogPermissionBlockedMessage(rfh, kPermissionBlockedPortalsMessage,
  163. content_settings_type_);
  164. break;
  165. case PermissionStatusSource::FENCED_FRAME:
  166. LogPermissionBlockedMessage(rfh, kPermissionBlockedFencedFrameMessage,
  167. content_settings_type_);
  168. break;
  169. case PermissionStatusSource::INSECURE_ORIGIN:
  170. case PermissionStatusSource::UNSPECIFIED:
  171. case PermissionStatusSource::VIRTUAL_URL_DIFFERENT_ORIGIN:
  172. break;
  173. }
  174. // If we are under embargo, record the embargo reason for which we have
  175. // suppressed the prompt.
  176. PermissionUmaUtil::RecordEmbargoPromptSuppressionFromSource(result.source);
  177. NotifyPermissionSet(id, requesting_origin, embedding_origin,
  178. std::move(callback), /*persist=*/false,
  179. result.content_setting, /*is_one_time=*/false);
  180. return;
  181. }
  182. // Don't show request permission UI for an inactive RenderFrameHost as the
  183. // page might not distinguish properly between user denying the permission and
  184. // automatic rejection, leading to an inconsistent UX once the page becomes
  185. // active again.
  186. // - If this is called when RenderFrameHost is in BackForwardCache, evict the
  187. // document from the cache.
  188. // - If this is called when RenderFrameHost is in prerendering, cancel
  189. // prerendering.
  190. if (rfh->IsInactiveAndDisallowActivation(
  191. content::DisallowActivationReasonId::kRequestPermission)) {
  192. std::move(callback).Run(result.content_setting);
  193. return;
  194. }
  195. // We are going to show a prompt now.
  196. PermissionUmaUtil::PermissionRequested(content_settings_type_,
  197. requesting_origin);
  198. PermissionUmaUtil::RecordEmbargoPromptSuppression(
  199. PermissionEmbargoStatus::NOT_EMBARGOED);
  200. DecidePermission(id, requesting_origin, embedding_origin, user_gesture,
  201. std::move(callback));
  202. }
  203. void PermissionContextBase::UserMadePermissionDecision(
  204. const PermissionRequestID& id,
  205. const GURL& requesting_origin,
  206. const GURL& embedding_origin,
  207. ContentSetting content_setting) {}
  208. std::unique_ptr<PermissionRequest>
  209. PermissionContextBase::CreatePermissionRequest(
  210. const GURL& request_origin,
  211. ContentSettingsType content_settings_type,
  212. bool has_gesture,
  213. content::WebContents* web_contents,
  214. PermissionRequest::PermissionDecidedCallback permission_decided_callback,
  215. base::OnceClosure delete_callback) const {
  216. return std::make_unique<PermissionRequest>(
  217. request_origin, ContentSettingsTypeToRequestType(content_settings_type),
  218. has_gesture, std::move(permission_decided_callback),
  219. std::move(delete_callback));
  220. }
  221. PermissionResult PermissionContextBase::GetPermissionStatus(
  222. content::RenderFrameHost* render_frame_host,
  223. const GURL& requesting_origin,
  224. const GURL& embedding_origin) const {
  225. // If the permission has been disabled through Finch, block all requests.
  226. if (IsPermissionKillSwitchOn()) {
  227. return PermissionResult(CONTENT_SETTING_BLOCK,
  228. PermissionStatusSource::KILL_SWITCH);
  229. }
  230. if (!IsPermissionAvailableToOrigins(requesting_origin, embedding_origin)) {
  231. return PermissionResult(CONTENT_SETTING_BLOCK,
  232. PermissionStatusSource::INSECURE_ORIGIN);
  233. }
  234. // Check whether the feature is enabled for the frame by permissions policy.
  235. // We can only do this when a RenderFrameHost has been provided.
  236. if (render_frame_host &&
  237. !PermissionAllowedByPermissionsPolicy(render_frame_host)) {
  238. return PermissionResult(CONTENT_SETTING_BLOCK,
  239. PermissionStatusSource::FEATURE_POLICY);
  240. }
  241. if (render_frame_host) {
  242. content::WebContents* web_contents =
  243. content::WebContents::FromRenderFrameHost(render_frame_host);
  244. // Permissions are denied for portals.
  245. if (web_contents && web_contents->IsPortal()) {
  246. return PermissionResult(CONTENT_SETTING_BLOCK,
  247. PermissionStatusSource::PORTAL);
  248. }
  249. // Permissions are denied for fenced frames.
  250. if (render_frame_host->IsNestedWithinFencedFrame()) {
  251. return PermissionResult(CONTENT_SETTING_BLOCK,
  252. PermissionStatusSource::FENCED_FRAME);
  253. }
  254. // Automatically deny all HTTP or HTTPS requests where the virtual URL and
  255. // the loaded URL are for different origins. The loaded URL is the one
  256. // actually in the renderer, but the virtual URL is the one
  257. // seen by the user. This may be very confusing for a user to see in a
  258. // permissions request.
  259. content::NavigationEntry* entry =
  260. web_contents->GetController().GetLastCommittedEntry();
  261. if (entry) {
  262. const GURL virtual_url = entry->GetVirtualURL();
  263. const GURL loaded_url = entry->GetURL();
  264. if (virtual_url.SchemeIsHTTPOrHTTPS() &&
  265. loaded_url.SchemeIsHTTPOrHTTPS() &&
  266. !url::IsSameOriginWith(virtual_url, loaded_url)) {
  267. return PermissionResult(
  268. CONTENT_SETTING_BLOCK,
  269. PermissionStatusSource::VIRTUAL_URL_DIFFERENT_ORIGIN);
  270. }
  271. }
  272. }
  273. ContentSetting content_setting = GetPermissionStatusInternal(
  274. render_frame_host, requesting_origin, embedding_origin);
  275. if (content_setting != CONTENT_SETTING_ASK) {
  276. return PermissionResult(content_setting,
  277. PermissionStatusSource::UNSPECIFIED);
  278. }
  279. absl::optional<PermissionResult> result =
  280. PermissionsClient::Get()
  281. ->GetPermissionDecisionAutoBlocker(browser_context_)
  282. ->GetEmbargoResult(requesting_origin, content_settings_type_);
  283. if (result) {
  284. DCHECK(result->content_setting == CONTENT_SETTING_BLOCK);
  285. return *result;
  286. }
  287. return PermissionResult(CONTENT_SETTING_ASK,
  288. PermissionStatusSource::UNSPECIFIED);
  289. }
  290. bool PermissionContextBase::IsPermissionAvailableToOrigins(
  291. const GURL& requesting_origin,
  292. const GURL& embedding_origin) const {
  293. if (IsRestrictedToSecureOrigins()) {
  294. if (!network::IsUrlPotentiallyTrustworthy(requesting_origin))
  295. return false;
  296. // TODO(raymes): We should check the entire chain of embedders here whenever
  297. // possible as this corresponds to the requirements of the secure contexts
  298. // spec and matches what is implemented in blink. Right now we just check
  299. // the top level and requesting origins.
  300. if (!PermissionsClient::Get()->CanBypassEmbeddingOriginCheck(
  301. requesting_origin, embedding_origin) &&
  302. !network::IsUrlPotentiallyTrustworthy(embedding_origin)) {
  303. return false;
  304. }
  305. }
  306. return true;
  307. }
  308. PermissionResult PermissionContextBase::UpdatePermissionStatusWithDeviceStatus(
  309. PermissionResult result,
  310. const GURL& requesting_origin,
  311. const GURL& embedding_origin) const {
  312. return result;
  313. }
  314. void PermissionContextBase::ResetPermission(const GURL& requesting_origin,
  315. const GURL& embedding_origin) {
  316. if (!content_settings::ContentSettingsRegistry::GetInstance()->Get(
  317. content_settings_type_)) {
  318. return;
  319. }
  320. PermissionsClient::Get()
  321. ->GetSettingsMap(browser_context_)
  322. ->SetContentSettingDefaultScope(requesting_origin, embedding_origin,
  323. content_settings_type_,
  324. CONTENT_SETTING_DEFAULT);
  325. }
  326. bool PermissionContextBase::IsPermissionKillSwitchOn() const {
  327. const std::string param = base::GetFieldTrialParamValue(
  328. kPermissionsKillSwitchFieldStudy,
  329. PermissionUtil::GetPermissionString(content_settings_type_));
  330. return param == kPermissionsKillSwitchBlockedValue;
  331. }
  332. ContentSetting PermissionContextBase::GetPermissionStatusInternal(
  333. content::RenderFrameHost* render_frame_host,
  334. const GURL& requesting_origin,
  335. const GURL& embedding_origin) const {
  336. return PermissionsClient::Get()
  337. ->GetSettingsMap(browser_context_)
  338. ->GetContentSetting(requesting_origin, embedding_origin,
  339. content_settings_type_);
  340. }
  341. void PermissionContextBase::DecidePermission(
  342. const PermissionRequestID& id,
  343. const GURL& requesting_origin,
  344. const GURL& embedding_origin,
  345. bool user_gesture,
  346. BrowserPermissionCallback callback) {
  347. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  348. // Under permission delegation, when we display a permission prompt, the
  349. // origin displayed in the prompt should never differ from the top-level
  350. // origin. Storage access API requests are excluded as they are expected to
  351. // request permissions from the frame origin needing access.
  352. DCHECK(PermissionsClient::Get()->CanBypassEmbeddingOriginCheck(
  353. requesting_origin, embedding_origin) ||
  354. requesting_origin == embedding_origin ||
  355. content_settings_type_ == ContentSettingsType::STORAGE_ACCESS);
  356. content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
  357. id.render_process_id(), id.render_frame_id());
  358. DCHECK(rfh);
  359. content::WebContents* web_contents =
  360. content::WebContents::FromRenderFrameHost(rfh);
  361. PermissionRequestManager* permission_request_manager =
  362. PermissionRequestManager::FromWebContents(web_contents);
  363. // TODO(felt): sometimes |permission_request_manager| is null. This check is
  364. // meant to prevent crashes. See crbug.com/457091.
  365. if (!permission_request_manager)
  366. return;
  367. std::unique_ptr<PermissionRequest> request_ptr = CreatePermissionRequest(
  368. requesting_origin, content_settings_type_, user_gesture, web_contents,
  369. base::BindOnce(&PermissionContextBase::PermissionDecided,
  370. weak_factory_.GetWeakPtr(), id, requesting_origin,
  371. embedding_origin, std::move(callback)),
  372. base::BindOnce(&PermissionContextBase::CleanUpRequest,
  373. weak_factory_.GetWeakPtr(), id));
  374. PermissionRequest* request = request_ptr.get();
  375. bool inserted =
  376. pending_requests_
  377. .insert(std::make_pair(id.ToString(), std::move(request_ptr)))
  378. .second;
  379. DCHECK(inserted) << "Duplicate id " << id.ToString();
  380. permission_request_manager->AddRequest(rfh, request);
  381. }
  382. void PermissionContextBase::PermissionDecided(
  383. const PermissionRequestID& id,
  384. const GURL& requesting_origin,
  385. const GURL& embedding_origin,
  386. BrowserPermissionCallback callback,
  387. ContentSetting content_setting,
  388. bool is_one_time) {
  389. DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
  390. content_setting == CONTENT_SETTING_BLOCK ||
  391. content_setting == CONTENT_SETTING_DEFAULT);
  392. UserMadePermissionDecision(id, requesting_origin, embedding_origin,
  393. content_setting);
  394. bool persist = content_setting != CONTENT_SETTING_DEFAULT;
  395. NotifyPermissionSet(id, requesting_origin, embedding_origin,
  396. std::move(callback), persist, content_setting,
  397. is_one_time);
  398. }
  399. content::BrowserContext* PermissionContextBase::browser_context() const {
  400. return browser_context_;
  401. }
  402. void PermissionContextBase::OnContentSettingChanged(
  403. const ContentSettingsPattern& primary_pattern,
  404. const ContentSettingsPattern& secondary_pattern,
  405. ContentSettingsTypeSet content_type_set) {
  406. if (!content_type_set.Contains(content_settings_type_))
  407. return;
  408. for (permissions::Observer& obs : permission_observers_) {
  409. obs.OnPermissionChanged(primary_pattern, secondary_pattern,
  410. content_type_set);
  411. }
  412. }
  413. void PermissionContextBase::AddObserver(
  414. permissions::Observer* permission_observer) {
  415. if (permission_observers_.empty() &&
  416. !content_setting_observer_registered_by_subclass_) {
  417. PermissionsClient::Get()
  418. ->GetSettingsMap(browser_context_)
  419. ->AddObserver(this);
  420. }
  421. permission_observers_.AddObserver(permission_observer);
  422. }
  423. void PermissionContextBase::RemoveObserver(
  424. permissions::Observer* permission_observer) {
  425. permission_observers_.RemoveObserver(permission_observer);
  426. if (permission_observers_.empty() &&
  427. !content_setting_observer_registered_by_subclass_) {
  428. PermissionsClient::Get()
  429. ->GetSettingsMap(browser_context_)
  430. ->RemoveObserver(this);
  431. }
  432. }
  433. void PermissionContextBase::NotifyPermissionSet(
  434. const PermissionRequestID& id,
  435. const GURL& requesting_origin,
  436. const GURL& embedding_origin,
  437. BrowserPermissionCallback callback,
  438. bool persist,
  439. ContentSetting content_setting,
  440. bool is_one_time) {
  441. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  442. if (persist) {
  443. UpdateContentSetting(requesting_origin, embedding_origin, content_setting,
  444. is_one_time);
  445. }
  446. UpdateTabContext(id, requesting_origin,
  447. content_setting == CONTENT_SETTING_ALLOW);
  448. if (content_setting == CONTENT_SETTING_DEFAULT)
  449. content_setting = CONTENT_SETTING_ASK;
  450. std::move(callback).Run(content_setting);
  451. }
  452. void PermissionContextBase::CleanUpRequest(const PermissionRequestID& id) {
  453. size_t success = pending_requests_.erase(id.ToString());
  454. DCHECK(success == 1) << "Missing request " << id.ToString();
  455. }
  456. void PermissionContextBase::UpdateContentSetting(const GURL& requesting_origin,
  457. const GURL& embedding_origin,
  458. ContentSetting content_setting,
  459. bool is_one_time) {
  460. DCHECK_EQ(requesting_origin, requesting_origin.DeprecatedGetOriginAsURL());
  461. DCHECK_EQ(embedding_origin, embedding_origin.DeprecatedGetOriginAsURL());
  462. DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
  463. content_setting == CONTENT_SETTING_BLOCK);
  464. content_settings::ContentSettingConstraints constraints = {
  465. base::Time(), is_one_time ? content_settings::SessionModel::OneTime
  466. : content_settings::SessionModel::Durable};
  467. #if !BUILDFLAG(IS_ANDROID)
  468. if (base::FeatureList::IsEnabled(
  469. features::kRecordPermissionExpirationTimestamps)) {
  470. // The Permissions module in Safety check will revoke permissions after
  471. // a finite amount of time.
  472. // We're only interested in expiring permissions that:
  473. // 1. Are ALLOWed.
  474. // 2. Fall back to ASK.
  475. // 3. Are not already a one-time grant.
  476. if (content_setting == CONTENT_SETTING_ALLOW && !is_one_time) {
  477. // For #2, by definition, that should be all of them. If that changes in
  478. // the future, consider whether revocation for such permission makes
  479. // sense, and/or change this to an early return so that we don't
  480. // unnecessarily record timestamps where we don't need them.
  481. DCHECK(content_settings::ContentSettingsRegistry::GetInstance()
  482. ->Get(content_settings_type_)
  483. ->GetInitialDefaultSetting() == CONTENT_SETTING_ASK);
  484. // To avoid inadvertently recording a history entry that a permission was
  485. // granted at a certain exact time, the timer is fuzzed.
  486. constraints.expiration = base::Time::Now() + base::Days(60 + rand() % 7);
  487. }
  488. }
  489. #endif // !BUILDFLAG(IS_ANDROID)
  490. PermissionsClient::Get()
  491. ->GetSettingsMap(browser_context_)
  492. ->SetContentSettingDefaultScope(requesting_origin, embedding_origin,
  493. content_settings_type_, content_setting,
  494. constraints);
  495. }
  496. bool PermissionContextBase::PermissionAllowedByPermissionsPolicy(
  497. content::RenderFrameHost* rfh) const {
  498. // Some features don't have an associated permissions policy yet. Allow those.
  499. if (permissions_policy_feature_ ==
  500. blink::mojom::PermissionsPolicyFeature::kNotFound)
  501. return true;
  502. return rfh->IsFeatureEnabled(permissions_policy_feature_);
  503. }
  504. } // namespace permissions