permission_decision_auto_blocker.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Copyright 2016 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. #ifndef COMPONENTS_PERMISSIONS_PERMISSION_DECISION_AUTO_BLOCKER_H_
  5. #define COMPONENTS_PERMISSIONS_PERMISSION_DECISION_AUTO_BLOCKER_H_
  6. #include <set>
  7. #include "base/callback.h"
  8. #include "base/gtest_prod_util.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/time/default_clock.h"
  11. #include "components/content_settings/core/browser/host_content_settings_map.h"
  12. #include "components/content_settings/core/common/content_settings_types.h"
  13. #include "components/keyed_service/core/keyed_service.h"
  14. #include "components/permissions/permission_result.h"
  15. #include "third_party/abseil-cpp/absl/types/optional.h"
  16. #include "url/gurl.h"
  17. class GURL;
  18. namespace settings {
  19. FORWARD_DECLARE_TEST(SiteSettingsHandlerTest, GetAllSites);
  20. FORWARD_DECLARE_TEST(SiteSettingsHandlerTest, GetRecentSitePermissions);
  21. } // namespace settings
  22. namespace site_settings {
  23. FORWARD_DECLARE_TEST(RecentSiteSettingsHelperTest, CheckRecentSitePermissions);
  24. } // namespace site_settings
  25. namespace permissions {
  26. // The PermissionDecisionAutoBlocker decides whether or not a given origin
  27. // should be automatically blocked from requesting a permission. When an origin
  28. // is blocked, it is placed under an "embargo". Until the embargo expires, any
  29. // requests made by the origin are automatically blocked. Once the embargo is
  30. // lifted, the origin will be permitted to request a permission again, which may
  31. // result in it being placed under embargo again. Currently, an origin can be
  32. // placed under embargo if it has a number of prior dismissals greater than a
  33. // threshold.
  34. class PermissionDecisionAutoBlocker : public KeyedService {
  35. public:
  36. PermissionDecisionAutoBlocker() = delete;
  37. explicit PermissionDecisionAutoBlocker(HostContentSettingsMap* settings_map);
  38. PermissionDecisionAutoBlocker(const PermissionDecisionAutoBlocker&) = delete;
  39. PermissionDecisionAutoBlocker& operator=(
  40. const PermissionDecisionAutoBlocker&) = delete;
  41. ~PermissionDecisionAutoBlocker() override;
  42. // Returns whether the permission auto blocker is enabled for the passed-in
  43. // content setting.
  44. static bool IsEnabledForContentSetting(ContentSettingsType content_setting);
  45. // Checks the status of the content setting to determine if |request_origin|
  46. // is under embargo for |permission|. This checks all types of embargo.
  47. // Prefer to use PermissionManager::GetPermissionStatus when possible. This
  48. // method is only exposed to facilitate permission checks from threads other
  49. // than the UI thread. See https://crbug.com/658020.
  50. static absl::optional<PermissionResult> GetEmbargoResult(
  51. HostContentSettingsMap* settings_map,
  52. const GURL& request_origin,
  53. ContentSettingsType permission,
  54. base::Time current_time);
  55. // Updates the threshold to start blocking prompts from the field trial.
  56. static void UpdateFromVariations();
  57. // Returns whether |request_origin| is under embargo for |permission|.
  58. bool IsEmbargoed(const GURL& request_origin, ContentSettingsType permission);
  59. // Checks the status of the content setting to determine if |request_origin|
  60. // is under embargo for |permission|. This checks all types of embargo.
  61. absl::optional<PermissionResult> GetEmbargoResult(
  62. const GURL& request_origin,
  63. ContentSettingsType permission);
  64. // Returns the most recent recorded time either an ignore or dismiss embargo
  65. // was started. Records of embargo start times persist beyond the duration of
  66. // the embargo, but are removed along with embargoes when
  67. // RemoveEmbargoAndResetCounts is used. Returns base::Time() if no record is
  68. // found.
  69. base::Time GetEmbargoStartTime(const GURL& request_origin,
  70. ContentSettingsType permission);
  71. // Returns the current number of dismisses recorded for |permission| type at
  72. // |url|.
  73. int GetDismissCount(const GURL& url, ContentSettingsType permission);
  74. // Returns the current number of ignores recorded for |permission|
  75. // type at |url|.
  76. int GetIgnoreCount(const GURL& url, ContentSettingsType permission);
  77. // Returns a set of urls currently under embargo for |content_type|.
  78. std::set<GURL> GetEmbargoedOrigins(ContentSettingsType content_type);
  79. // Returns a set of urls currently under embargo for the provided
  80. // |content_type| types.
  81. std::set<GURL> GetEmbargoedOrigins(
  82. std::vector<ContentSettingsType> content_types);
  83. // Records that a dismissal of a prompt for |permission| was made. If the
  84. // total number of dismissals exceeds a threshhold and
  85. // features::kBlockPromptsIfDismissedOften is enabled, it will place |url|
  86. // under embargo for |permission|. |dismissed_prompt_was_quiet| will inform
  87. // the decision of which threshold to pick, depending on whether the prompt
  88. // that was presented to the user was quiet or not.
  89. bool RecordDismissAndEmbargo(const GURL& url,
  90. ContentSettingsType permission,
  91. bool dismissed_prompt_was_quiet);
  92. // Records that an ignore of a prompt for |permission| was made. If the total
  93. // number of ignores exceeds a threshold and
  94. // features::kBlockPromptsIfIgnoredOften is enabled, it will place |url| under
  95. // embargo for |permission|. |ignored_prompt_was_quiet| will inform the
  96. // decision of which threshold to pick, depending on whether the prompt that
  97. // was presented to the user was quiet or not.
  98. bool RecordIgnoreAndEmbargo(const GURL& url,
  99. ContentSettingsType permission,
  100. bool ignored_prompt_was_quiet);
  101. // Clears any existing embargo status for |url|, |permission|. For permissions
  102. // embargoed under repeated dismissals, this means a prompt will be shown to
  103. // the user on next permission request. Clears dismiss and ignore counts.
  104. void RemoveEmbargoAndResetCounts(const GURL& url,
  105. ContentSettingsType permission);
  106. // Same as above, but cleans the slate for all permissions and for all URLs
  107. // matching |filter|.
  108. void RemoveEmbargoAndResetCounts(
  109. base::RepeatingCallback<bool(const GURL& url)> filter);
  110. static const char* GetPromptDismissCountKeyForTesting();
  111. private:
  112. friend class PermissionDecisionAutoBlockerUnitTest;
  113. FRIEND_TEST_ALL_PREFIXES(site_settings::RecentSiteSettingsHelperTest,
  114. CheckRecentSitePermissions);
  115. FRIEND_TEST_ALL_PREFIXES(settings::SiteSettingsHandlerTest, GetAllSites);
  116. FRIEND_TEST_ALL_PREFIXES(settings::SiteSettingsHandlerTest,
  117. GetRecentSitePermissions);
  118. void PlaceUnderEmbargo(const GURL& request_origin,
  119. ContentSettingsType permission,
  120. const char* key);
  121. void SetClockForTesting(base::Clock* clock);
  122. // Keys used for storing count data in a website setting.
  123. static const char kPromptDismissCountKey[];
  124. static const char kPromptIgnoreCountKey[];
  125. static const char kPromptDismissCountWithQuietUiKey[];
  126. static const char kPromptIgnoreCountWithQuietUiKey[];
  127. static const char kPermissionDismissalEmbargoKey[];
  128. static const char kPermissionIgnoreEmbargoKey[];
  129. raw_ptr<HostContentSettingsMap> settings_map_;
  130. raw_ptr<base::Clock> clock_;
  131. };
  132. } // namespace permissions
  133. #endif // COMPONENTS_PERMISSIONS_PERMISSION_DECISION_AUTO_BLOCKER_H_