blob: bace9811475a10fcf96c6caabe1b6d4b2c397354 [file] [log] [blame]
mlamouri4e372022015-03-29 14:51:061// 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
Clark DuVall6b73c742020-03-11 19:00:155#ifndef COMPONENTS_PERMISSIONS_PERMISSION_MANAGER_H_
6#define COMPONENTS_PERMISSIONS_PERMISSION_MANAGER_H_
mlamouri4e372022015-03-29 14:51:067
Lei Zhang998100f2021-06-25 17:58:198#include <map>
raymese3afee6b2016-04-18 02:00:509#include <unordered_map>
10
mlamouri4e372022015-03-29 14:51:0611#include "base/callback_forward.h"
James Hollyerd281a7312021-04-29 21:07:5912#include "base/containers/flat_map.h"
Brett Wilsonf976d3f2017-08-18 17:23:3913#include "base/containers/id_map.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
mlamouri23957a22015-04-01 10:37:5615#include "components/content_settings/core/browser/content_settings_observer.h"
lalitm27583e92015-10-02 11:34:1716#include "components/content_settings/core/common/content_settings.h"
mlamouri4e372022015-03-29 14:51:0617#include "components/keyed_service/core/keyed_service.h"
James Hollyerd281a7312021-04-29 21:07:5918#include "components/permissions/permission_context_base.h"
Balazs Engedye15473b2021-04-14 09:09:2119#include "components/permissions/permission_request_id.h"
Clark DuVall732778e2020-01-27 18:13:5820#include "components/permissions/permission_util.h"
Andrey Lushnikovf3500102018-07-16 19:55:2221#include "content/public/browser/permission_controller_delegate.h"
Rohan Pavonefaf64572019-07-30 17:50:2022#include "url/origin.h"
mlamouri4e372022015-03-29 14:51:0623
Andy Paicua6d6d852022-04-28 18:08:3624namespace blink {
25enum class PermissionType;
26}
27
Clark DuVall6b73c742020-03-11 19:00:1528namespace content {
29class BrowserContext;
Robbie McElrath8d5602a2022-04-01 17:39:1830class RenderFrameHost;
31class RenderProcessHost;
Clark DuVall6b73c742020-03-11 19:00:1532}
33
Illia Klimov770b145f2022-04-20 17:19:0934class GeolocationPermissionContextDelegateTests;
35class SubscriptionInterceptingPermissionManager;
36
Clark DuVall484c2562020-01-23 22:05:0937namespace permissions {
Clark DuValla11361ad32020-02-20 22:14:2738class PermissionContextBase;
timlohc6911802017-03-01 05:37:0339struct PermissionResult;
Illia Klimov770b145f2022-04-20 17:19:0940class PermissionManagerTest;
mlamouri4e372022015-03-29 14:51:0641
mlamouri4e372022015-03-29 14:51:0642class PermissionManager : public KeyedService,
Andrey Lushnikovf3500102018-07-16 19:55:2243 public content::PermissionControllerDelegate,
James Hollyerd281a7312021-04-29 21:07:5944 public permissions::Observer {
mlamouri4e372022015-03-29 14:51:0645 public:
Clark DuVall6b73c742020-03-11 19:00:1546 using PermissionContextMap =
47 std::unordered_map<ContentSettingsType,
48 std::unique_ptr<PermissionContextBase>,
49 ContentSettingsTypeHash>;
50 PermissionManager(content::BrowserContext* browser_context,
51 PermissionContextMap permission_contexts);
Peter Boström09c01822021-09-20 22:43:2752
53 PermissionManager(const PermissionManager&) = delete;
54 PermissionManager& operator=(const PermissionManager&) = delete;
55
mlamouri4e372022015-03-29 14:51:0656 ~PermissionManager() override;
57
Marc Treib9e4bd922017-09-25 08:32:1358 // Converts from |url|'s actual origin to the "canonical origin" that should
59 // be used for the purpose of requesting/storing permissions. For example, the
Raymes Khouryb474c642018-02-28 06:16:2860 // origin of the local NTP gets mapped to the Google base URL instead. With
61 // Permission Delegation it will transform the requesting origin into
62 // the embedding origin because all permission checks happen on the top level
63 // origin.
64 //
65 // All the public methods below, such as RequestPermission or
66 // GetPermissionStatus, take the actual origin and do the canonicalization
67 // internally. You only need to call this directly if you do something else
68 // with the origin, such as display it in the UI.
Balazs Engedyf39e22b2019-07-30 11:16:2469 GURL GetCanonicalOrigin(ContentSettingsType permission,
70 const GURL& requesting_origin,
Raymes Khouryb474c642018-02-28 06:16:2871 const GURL& embedding_origin) const;
Marc Treib9e4bd922017-09-25 08:32:1372
Illia Klimov770b145f2022-04-20 17:19:0973 // This method is deprecated. Use `GetPermissionStatusForCurrentDocument`
74 // instead or `GetPermissionStatusForDisplayOnSettingsUI`.
75 PermissionResult GetPermissionStatusDeprecated(ContentSettingsType permission,
76 const GURL& requesting_origin,
77 const GURL& embedding_origin);
78
79 // Returns the permission status for a given `permission` and displayed,
80 // top-level `origin`. This should be used only for displaying on the
81 // browser's native UI (PageInfo, Settings, etc.). This method does not take
82 // context specific restrictions (e.g. permission policy) into consideration.
83 PermissionResult GetPermissionStatusForDisplayOnSettingsUI(
84 ContentSettingsType permission,
85 const GURL& origin);
86
87 // Returns the status for the given `permission` on behalf of the last
88 // committed document in `render_frame_host`, also performing additional
89 // checks such as Permission Policy.
90 PermissionResult GetPermissionStatusForCurrentDocument(
91 ContentSettingsType permission,
92 content::RenderFrameHost* render_frame_host);
93
94 // KeyedService implementation.
95 void Shutdown() override;
96
Illia Klimov770b145f2022-04-20 17:19:0997 PermissionContextBase* GetPermissionContextForTesting(
98 ContentSettingsType type);
99
100 PermissionContextMap& PermissionContextsForTesting() {
101 return permission_contexts_;
102 }
103
104 private:
105 friend class PermissionManagerTest;
106 friend class ::GeolocationPermissionContextDelegateTests;
107 friend class ::SubscriptionInterceptingPermissionManager;
108
109 // The `PendingRequestLocalId` will be unique within the `PermissionManager`
110 // instance, thus within a `BrowserContext`, which overachieves the
111 // requirement from `PermissionRequestID` that the `RequestLocalId` be unique
112 // within each frame.
113 class PendingRequest;
114 using PendingRequestLocalId = PermissionRequestID::RequestLocalId;
115 using PendingRequestsMap =
116 base::IDMap<std::unique_ptr<PendingRequest>, PendingRequestLocalId>;
117
118 class PermissionResponseCallback;
119
120 struct Subscription;
121 using SubscriptionsMap =
122 base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
123 using SubscriptionTypeCounts = base::flat_map<ContentSettingsType, size_t>;
124
125 PermissionContextBase* GetPermissionContext(ContentSettingsType type);
126
Andrey Lushnikovf3500102018-07-16 19:55:22127 // content::PermissionControllerDelegate implementation.
Balazs Engedye30e9612021-04-02 10:37:29128 void RequestPermission(
Andy Paicua6d6d852022-04-28 18:08:36129 blink::PermissionType permission,
Balazs Engedye30e9612021-04-02 10:37:29130 content::RenderFrameHost* render_frame_host,
131 const GURL& requesting_origin,
132 bool user_gesture,
133 base::OnceCallback<void(blink::mojom::PermissionStatus)> callback)
134 override;
135 void RequestPermissions(
Andy Paicua6d6d852022-04-28 18:08:36136 const std::vector<blink::PermissionType>& permissions,
mlamouri8b5ec902015-10-24 00:52:03137 content::RenderFrameHost* render_frame_host,
138 const GURL& requesting_origin,
benwellsfd2b1552016-07-05 04:26:53139 bool user_gesture,
danakj47c8fb52019-05-02 16:34:36140 base::OnceCallback<
141 void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
leon.han06e55662016-03-26 17:19:42142 override;
Andy Paicua6d6d852022-04-28 18:08:36143 void ResetPermission(blink::PermissionType permission,
mlamouri4e372022015-03-29 14:51:06144 const GURL& requesting_origin,
145 const GURL& embedding_origin) override;
Illia Klimov27239edc2022-05-11 17:14:59146 void RequestPermissionsFromCurrentDocument(
147 const std::vector<blink::PermissionType>& permissions,
148 content::RenderFrameHost* render_frame_host,
149 bool user_gesture,
150 base::OnceCallback<
151 void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
152 override;
mathpcc29ae52016-05-04 15:22:17153 blink::mojom::PermissionStatus GetPermissionStatus(
Andy Paicua6d6d852022-04-28 18:08:36154 blink::PermissionType permission,
mlamouri4e372022015-03-29 14:51:06155 const GURL& requesting_origin,
156 const GURL& embedding_origin) override;
Illia Klimovf2842842022-03-22 11:33:39157 blink::mojom::PermissionStatus GetPermissionStatusForCurrentDocument(
Andy Paicua6d6d852022-04-28 18:08:36158 blink::PermissionType permission,
Illia Klimovf2842842022-03-22 11:33:39159 content::RenderFrameHost* render_frame_host) override;
Robbie McElrath8d5602a2022-04-01 17:39:18160 blink::mojom::PermissionStatus GetPermissionStatusForWorker(
Andy Paicua6d6d852022-04-28 18:08:36161 blink::PermissionType permission,
Robbie McElrath8d5602a2022-04-01 17:39:18162 content::RenderProcessHost* render_process_host,
163 const GURL& worker_origin) override;
Pavel Feldman446a91b2020-03-13 17:39:55164 bool IsPermissionOverridableByDevTools(
Andy Paicua6d6d852022-04-28 18:08:36165 blink::PermissionType permission,
Anton Bikineev1156b5f2021-05-15 22:35:36166 const absl::optional<url::Origin>& origin) override;
Balazs Engedyad1489b2021-03-31 07:47:19167 SubscriptionId SubscribePermissionStatusChange(
Andy Paicua6d6d852022-04-28 18:08:36168 blink::PermissionType permission,
Robbie McElrath8d5602a2022-04-01 17:39:18169 content::RenderProcessHost* render_process_host,
Raymes Khoury3ef4f6e2018-08-09 09:34:48170 content::RenderFrameHost* render_frame_host,
mlamouri23957a22015-04-01 10:37:56171 const GURL& requesting_origin,
danakj47c8fb52019-05-02 16:34:36172 base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
mathpcc29ae52016-05-04 15:22:17173 override;
Balazs Engedyad1489b2021-03-31 07:47:19174 void UnsubscribePermissionStatusChange(
175 SubscriptionId subscription_id) override;
mlamouri4e372022015-03-29 14:51:06176
mlamouri8b5ec902015-10-24 00:52:03177 // Called when a permission was decided for a given PendingRequest. The
Balazs Engedye15473b2021-04-14 09:09:21178 // PendingRequest is identified by its |request_local_id| and the permission
179 // is identified by its |permission_id|. If the PendingRequest contains more
180 // than one permission, it will wait for the remaining permissions to be
181 // resolved. When all the permissions have been resolved, the PendingRequest's
182 // callback is run.
183 void OnPermissionsRequestResponseStatus(
184 PendingRequestLocalId request_local_id,
185 int permission_id,
186 ContentSetting status);
lalitm27583e92015-10-02 11:34:17187
James Hollyerd281a7312021-04-29 21:07:59188 // permissions::Observer:
189 void OnPermissionChanged(const ContentSettingsPattern& primary_pattern,
190 const ContentSettingsPattern& secondary_pattern,
Christian Dullweber2c4c71d2021-10-14 15:07:43191 ContentSettingsTypeSet content_type_set) override;
mlamouri23957a22015-04-01 10:37:56192
Robbie McElrath8d5602a2022-04-01 17:39:18193 // Only one of |render_process_host| and |render_frame_host| should be set,
194 // or neither. RenderProcessHost will be inferred from |render_frame_host|.
Clark DuVall6b73c742020-03-11 19:00:15195 PermissionResult GetPermissionStatusHelper(
raymesf6104d492017-03-09 01:20:18196 ContentSettingsType permission,
Robbie McElrath8d5602a2022-04-01 17:39:18197 content::RenderProcessHost* render_process_host,
raymesf6104d492017-03-09 01:20:18198 content::RenderFrameHost* render_frame_host,
199 const GURL& requesting_origin,
200 const GURL& embedding_origin);
201
Pavel Feldman73b22022018-11-02 02:55:30202 ContentSetting GetPermissionOverrideForDevTools(
Rohan Pavone8180cba62019-08-26 20:55:09203 const url::Origin& origin,
Pavel Feldman73b22022018-11-02 02:55:30204 ContentSettingsType permission);
205
Illia Klimov770b145f2022-04-20 17:19:09206 // content::PermissionControllerDelegate implementation.
207 // For the given |origin|, overrides permissions that belong to |overrides|.
208 // These permissions are in-sync with the PermissionController.
209 void SetPermissionOverridesForDevTools(
210 const absl::optional<url::Origin>& origin,
211 const PermissionOverrides& overrides) override;
212 void ResetPermissionOverridesForDevTools() override;
213
Keishi Hattori0e45c022021-11-27 09:25:52214 raw_ptr<content::BrowserContext> browser_context_;
Balazs Engedye15473b2021-04-14 09:09:21215
lalitm27583e92015-10-02 11:34:17216 PendingRequestsMap pending_requests_;
Balazs Engedye15473b2021-04-14 09:09:21217 PendingRequestLocalId::Generator request_local_id_generator_;
218
mlamouri23957a22015-04-01 10:37:56219 SubscriptionsMap subscriptions_;
Balazs Engedyad1489b2021-03-31 07:47:19220 SubscriptionId::Generator subscription_id_generator_;
mlamouri4e372022015-03-29 14:51:06221
James Hollyerd281a7312021-04-29 21:07:59222 // Tracks the number of Subscriptions in |subscriptions_| which have a
223 // certain ContentSettingsType. An entry for a given ContentSettingsType key
224 // is added on first use and never removed. This is done to utilize the
225 // flat_map's efficiency in accessing/editing items and minimize the use of
226 // the unefficient addition/removal of items.
227 SubscriptionTypeCounts subscription_type_counts_;
228
Clark DuVall6b73c742020-03-11 19:00:15229 PermissionContextMap permission_contexts_;
Rohan Pavonefaf64572019-07-30 17:50:20230 using ContentSettingsTypeOverrides =
231 base::flat_map<ContentSettingsType, ContentSetting>;
232 std::map<url::Origin, ContentSettingsTypeOverrides>
233 devtools_permission_overrides_;
Pavel Feldman446a91b2020-03-13 17:39:55234 url::Origin devtools_global_overrides_origin_;
raymese3afee6b2016-04-18 02:00:50235
Alexey Baskakov386f1742019-09-03 04:08:47236 bool is_shutting_down_ = false;
mlamouri4e372022015-03-29 14:51:06237};
238
Clark DuVall6b73c742020-03-11 19:00:15239} // namespace permissions
240
241#endif // COMPONENTS_PERMISSIONS_PERMISSION_MANAGER_H_