Avi Drissman | 8ba1bad | 2022-09-13 19:22:36 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Clark DuVall | 484c256 | 2020-01-23 22:05:09 | [diff] [blame] | 5 | #ifndef COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_H_ |
| 6 | #define COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_H_ |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 7 | |
Jan Wilken Dörrie | ad587c3 | 2021-03-11 14:09:27 | [diff] [blame] | 8 | #include <string> |
| 9 | |
Avi Drissman | 12be031 | 2023-01-11 09:16:09 | [diff] [blame] | 10 | #include "base/functional/callback.h" |
Thomas Nguyen | 9f1ff730 | 2023-03-30 12:23:35 | [diff] [blame] | 11 | #include "base/memory/weak_ptr.h" |
Clark DuVall | 484c256 | 2020-01-23 22:05:09 | [diff] [blame] | 12 | #include "build/build_config.h" |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 13 | #include "components/content_settings/core/common/content_settings.h" |
lshang | ada00c1 | 2016-10-17 04:51:10 | [diff] [blame] | 14 | #include "components/content_settings/core/common/content_settings_types.h" |
Andy Paicu | 0a6d4b50 | 2023-08-29 15:13:09 | [diff] [blame] | 15 | #include "components/permissions/permission_request_data.h" |
Andy Paicu | 4a88f42 | 2020-11-12 18:21:39 | [diff] [blame] | 16 | #include "components/permissions/permission_request_enums.h" |
Illia Klimov | fabd8b5 | 2021-10-21 07:15:40 | [diff] [blame] | 17 | #include "components/permissions/request_type.h" |
Illia Klimov | e406ecc1 | 2022-11-22 15:53:29 | [diff] [blame] | 18 | #include "content/public/browser/global_routing_id.h" |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame] | 19 | #include "third_party/abseil-cpp/absl/types/optional.h" |
[email protected] | d23cdeee | 2014-03-10 06:39:53 | [diff] [blame] | 20 | #include "url/gurl.h" |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 21 | |
Clark DuVall | 484c256 | 2020-01-23 22:05:09 | [diff] [blame] | 22 | namespace permissions { |
Bret Sepulveda | 362cce4 | 2021-01-13 18:47:54 | [diff] [blame] | 23 | enum class RequestType; |
Clark DuVall | 484c256 | 2020-01-23 22:05:09 | [diff] [blame] | 24 | |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 25 | // Describes the interface a feature making permission requests should |
| 26 | // implement. A class of this type is registered with the permission request |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 27 | // manager to receive updates about the result of the permissions request |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 28 | // from the bubble or infobar. It should live until it is unregistered or until |
[email protected] | 634e598 | 2014-04-18 19:20:48 | [diff] [blame] | 29 | // RequestFinished is called. |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 30 | // Note that no particular guarantees are made about what exact UI surface |
| 31 | // is presented to the user. The delegate may be coalesced with other bubble |
| 32 | // requests, or depending on the situation, not shown at all. |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 33 | class PermissionRequest { |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 34 | public: |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 35 | // If `result` is CONTENT_SETTING_ALLOW, the permission was granted by the |
| 36 | // user. If it's CONTENT_SETTING_BLOCK, the permission was blocked by the |
| 37 | // user. If it's CONTENT_SETTING_DEFAULT, the permission was ignored or |
| 38 | // dismissed without an explicit decision. No other ContentSetting value will |
| 39 | // be passed into this callback. |
| 40 | // If `is_one_time` is true, the decision will last until all tabs of |
| 41 | // `requesting_origin_` are closed or navigated away from. |
| 42 | using PermissionDecidedCallback = |
Illia Klimov | e406ecc1 | 2022-11-22 15:53:29 | [diff] [blame] | 43 | base::RepeatingCallback<void(ContentSetting /*result*/, |
| 44 | bool /*is_one_time*/, |
| 45 | bool /*is_final_decision*/)>; |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 46 | |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 47 | // `permission_decided_callback` is called when the permission request is |
| 48 | // resolved by the user (see comment on PermissionDecidedCallback above). |
| 49 | // `delete_callback` is called when the permission request is no longer needed |
| 50 | // by the permission system. Therefore, it is safe to delete `this` inside |
| 51 | // `delete_callback`. It will always be called eventually by the permission |
| 52 | // system. |
| 53 | // `delete_callback` may be called before `permission_decided_callback`, for |
| 54 | // example if the tab is closed without user interaction. In this case, the |
| 55 | // javascript promise from the requesting origin will not be resolved. |
| 56 | PermissionRequest(const GURL& requesting_origin, |
| 57 | RequestType request_type, |
| 58 | bool has_gesture, |
| 59 | PermissionDecidedCallback permission_decided_callback, |
| 60 | base::OnceClosure delete_callback); |
| 61 | |
Andy Paicu | 0a6d4b50 | 2023-08-29 15:13:09 | [diff] [blame] | 62 | PermissionRequest(PermissionRequestData request_data, |
| 63 | PermissionDecidedCallback permission_decided_callback, |
| 64 | base::OnceClosure delete_callback); |
| 65 | |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 66 | PermissionRequest(const PermissionRequest&) = delete; |
| 67 | PermissionRequest& operator=(const PermissionRequest&) = delete; |
| 68 | |
Florian Jacky | eeb6206 | 2022-10-05 18:04:07 | [diff] [blame] | 69 | enum ChipTextType { |
| 70 | LOUD_REQUEST, |
| 71 | QUIET_REQUEST, |
| 72 | ALLOW_CONFIRMATION, |
Florian Jacky | 2b3f54f | 2023-05-03 08:31:52 | [diff] [blame] | 73 | ALLOW_ONCE_CONFIRMATION, |
Florian Jacky | eeb6206 | 2022-10-05 18:04:07 | [diff] [blame] | 74 | BLOCKED_CONFIRMATION, |
| 75 | ACCESSIBILITY_ALLOWED_CONFIRMATION, |
Florian Jacky | 2b3f54f | 2023-05-03 08:31:52 | [diff] [blame] | 76 | ACCESSIBILITY_ALLOWED_ONCE_CONFIRMATION, |
Florian Jacky | eeb6206 | 2022-10-05 18:04:07 | [diff] [blame] | 77 | ACCESSIBILITY_BLOCKED_CONFIRMATION |
| 78 | }; |
| 79 | |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 80 | virtual ~PermissionRequest(); |
| 81 | |
Andy Paicu | 0a6d4b50 | 2023-08-29 15:13:09 | [diff] [blame] | 82 | GURL requesting_origin() const { return data_.requesting_origin; } |
| 83 | RequestType request_type() const; |
[email protected] | d23cdeee | 2014-03-10 06:39:53 | [diff] [blame] | 84 | |
Bret Sepulveda | d7e4d44 | 2021-04-20 13:46:41 | [diff] [blame] | 85 | // Whether |this| and |other_request| are duplicates and therefore don't both |
| 86 | // need to be shown in the UI. |
| 87 | virtual bool IsDuplicateOf(PermissionRequest* other_request) const; |
| 88 | |
Xiaohan Wang | e81358230 | 2022-01-14 14:50:46 | [diff] [blame] | 89 | #if BUILDFLAG(IS_ANDROID) |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 90 | // Returns prompt text appropriate for displaying in an Android dialog. |
| 91 | virtual std::u16string GetDialogMessageText() const; |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 92 | #endif |
| 93 | |
Thomas Nguyen | 9f1ff730 | 2023-03-30 12:23:35 | [diff] [blame] | 94 | // Returns a weak pointer to this instance. |
| 95 | base::WeakPtr<PermissionRequest> GetWeakPtr(); |
| 96 | |
Xiaohan Wang | e81358230 | 2022-01-14 14:50:46 | [diff] [blame] | 97 | #if !BUILDFLAG(IS_ANDROID) |
Florian Jacky | 4748cf3 | 2022-10-06 09:04:18 | [diff] [blame] | 98 | // Returns whether displaying a confirmation chip for the request is |
| 99 | // supported. |
| 100 | bool IsConfirmationChipSupported(); |
| 101 | |
Illia Klimov | fabd8b5 | 2021-10-21 07:15:40 | [diff] [blame] | 102 | // Returns prompt icon appropriate for displaying on the chip button in the |
| 103 | // location bar. |
| 104 | IconId GetIconForChip(); |
| 105 | |
| 106 | // Returns prompt icon appropriate for displaying on the quiet chip button in |
| 107 | // the location bar. |
| 108 | IconId GetBlockedIconForChip(); |
| 109 | |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 110 | // Returns prompt text appropriate for displaying on the chip button in the |
| 111 | // location bar. |
Florian Jacky | eeb6206 | 2022-10-05 18:04:07 | [diff] [blame] | 112 | absl::optional<std::u16string> GetRequestChipText(ChipTextType type) const; |
Olesia Marukhno | f8a4bed8 | 2020-06-17 13:35:31 | [diff] [blame] | 113 | |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 114 | // Returns prompt text appropriate for displaying under the dialog title |
| 115 | // "[domain] wants to:". |
| 116 | virtual std::u16string GetMessageTextFragment() const; |
Bret Sepulveda | d7e4d44 | 2021-04-20 13:46:41 | [diff] [blame] | 117 | #endif |
[email protected] | dd1ba69 | 2014-01-24 23:17:37 | [diff] [blame] | 118 | |
Kamila | 04c0b18 | 2023-09-01 09:47:55 | [diff] [blame] | 119 | // Whether the request was initiated by the user clicking on the permission |
| 120 | // element. |
| 121 | bool IsEmbeddedPermissionElementInitiated() const; |
| 122 | |
Filipa Senra | 1f968d45 | 2023-04-24 17:15:40 | [diff] [blame] | 123 | // Returns true if the request has two origins and should use the two origin |
| 124 | // prompt. Returns false otherwise. |
| 125 | bool ShouldUseTwoOriginPrompt() const; |
| 126 | |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 127 | // Called when the user has granted the requested permission. |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 128 | // If |is_one_time| is true the permission will last until all tabs of |
| 129 | // |origin| are closed or navigated away from, and then the permission will |
Ravjit Singh Uppal | c73b5a6 | 2020-11-13 01:38:52 | [diff] [blame] | 130 | // automatically expire after 1 day. |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 131 | void PermissionGranted(bool is_one_time); |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 132 | |
| 133 | // Called when the user has denied the requested permission. |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 134 | void PermissionDenied(); |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 135 | |
| 136 | // Called when the user has cancelled the permission request. This |
| 137 | // corresponds to a denial, but is segregated in case the context needs to |
| 138 | // be able to distinguish between an active refusal or an implicit refusal. |
Illia Klimov | e406ecc1 | 2022-11-22 15:53:29 | [diff] [blame] | 139 | void Cancelled(bool is_final_decision = true); |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 140 | |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 141 | // The UI this request was associated with was answered by the user. |
[email protected] | e2ff17e | 2014-02-06 02:32:33 | [diff] [blame] | 142 | // It is safe for the request to be deleted at this point -- it will receive |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 143 | // no further message from the permission request system. This method will |
[email protected] | e2ff17e | 2014-02-06 02:32:33 | [diff] [blame] | 144 | // eventually be called on every request which is not unregistered. |
Anatoliy Potapchuk | 1c46f7e | 2020-01-23 13:31:03 | [diff] [blame] | 145 | // It is ok to call this method without actually resolving the request via |
| 146 | // PermissionGranted(), PermissionDenied() or Canceled(). However, it will not |
| 147 | // resolve the javascript promise from the requesting origin. |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 148 | void RequestFinished(); |
benwells | 46b02fa | 2016-04-20 02:37:02 | [diff] [blame] | 149 | |
benwells | 471d1f1 | 2016-07-25 23:58:04 | [diff] [blame] | 150 | // Used to record UMA for whether requests are associated with a user gesture. |
| 151 | // To keep things simple this metric is only recorded for the most popular |
| 152 | // request types. |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 153 | PermissionRequestGestureType GetGestureType() const; |
dominickn | d4e446a | 2016-09-13 07:44:13 | [diff] [blame] | 154 | |
lshang | ada00c1 | 2016-10-17 04:51:10 | [diff] [blame] | 155 | // Used on Android to determine what Android OS permissions are needed for |
| 156 | // this permission request. |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 157 | ContentSettingsType GetContentSettingsType() const; |
lshang | ada00c1 | 2016-10-17 04:51:10 | [diff] [blame] | 158 | |
Illia Klimov | e406ecc1 | 2022-11-22 15:53:29 | [diff] [blame] | 159 | void set_requesting_frame_id(content::GlobalRenderFrameHostId id) { |
Andy Paicu | 0a6d4b50 | 2023-08-29 15:13:09 | [diff] [blame] | 160 | data_.id.set_global_render_frame_host_id(id); |
Illia Klimov | e406ecc1 | 2022-11-22 15:53:29 | [diff] [blame] | 161 | } |
| 162 | |
Andy Paicu | 0a6d4b50 | 2023-08-29 15:13:09 | [diff] [blame] | 163 | const content::GlobalRenderFrameHostId& get_requesting_frame_id() { |
| 164 | return data_.id.global_render_frame_host_id(); |
Illia Klimov | e406ecc1 | 2022-11-22 15:53:29 | [diff] [blame] | 165 | } |
| 166 | |
Andy Paicu | 1173436 | 2023-09-11 09:39:29 | [diff] [blame] | 167 | // Permission name text fragment which can be used in permission prompts to |
| 168 | // identify the permission being requested. |
| 169 | virtual std::u16string GetPermissionNameTextFragment() const; |
| 170 | |
Andy Paicu | 489b8d5 | 2023-10-16 20:49:55 | [diff] [blame^] | 171 | protected: |
| 172 | // Sets whether this request is permission element initiated, for testing |
| 173 | // subclasses only. |
| 174 | void SetEmbeddedPermissionElementInitiatedForTesting( |
| 175 | bool embedded_permission_element_initiated); |
| 176 | |
dominickn | d4e446a | 2016-09-13 07:44:13 | [diff] [blame] | 177 | private: |
Andy Paicu | 0a6d4b50 | 2023-08-29 15:13:09 | [diff] [blame] | 178 | PermissionRequestData data_; |
Bret Sepulveda | 5327d8b5 | 2021-07-21 17:44:23 | [diff] [blame] | 179 | |
| 180 | // Called once a decision is made about the permission. |
| 181 | PermissionDecidedCallback permission_decided_callback_; |
| 182 | |
| 183 | // Called when the request is no longer in use so it can be deleted by the |
| 184 | // caller. |
| 185 | base::OnceClosure delete_callback_; |
Thomas Nguyen | 9f1ff730 | 2023-03-30 12:23:35 | [diff] [blame] | 186 | |
| 187 | base::WeakPtrFactory<PermissionRequest> weak_factory_{this}; |
[email protected] | efad90f | 2014-01-17 00:45:54 | [diff] [blame] | 188 | }; |
| 189 | |
Clark DuVall | 484c256 | 2020-01-23 22:05:09 | [diff] [blame] | 190 | } // namespace permissions |
| 191 | |
| 192 | #endif // COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_H_ |