1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/permissions/request_type.h"
7 #include "base/check.h"
8 #include "base/feature_list.h"
9 #include "base/notreached.h"
10 #include "base/ranges/algorithm.h"
11 #include "build/build_config.h"
12 #include "components/content_settings/core/common/content_settings_types.h"
13 #include "components/permissions/features.h"
14 #include "components/permissions/permission_request.h"
15 #include "components/permissions/permissions_client.h"
16 #include "ui/base/ui_base_features.h"
18 #if BUILDFLAG(IS_ANDROID)
19 #include "components/resources/android/theme_resources.h"
21 #include "components/permissions/vector_icons/vector_icons.h"
22 #include "components/vector_icons/vector_icons.h"
23 #include "ui/gfx/paint_vector_icon.h"
24 #include "ui/gfx/vector_icon_types.h"
25 #endif // BUILDFLAG(IS_ANDROID)
27 namespace permissions {
31 #if BUILDFLAG(IS_ANDROID)
32 int GetIconIdAndroid(RequestType type) {
34 case RequestType::kAccessibilityEvents:
35 return IDR_ANDROID_INFOBAR_ACCESSIBILITY_EVENTS;
36 case RequestType::kArSession:
37 case RequestType::kVrSession:
38 return IDR_ANDROID_INFOBAR_VR_HEADSET;
39 case RequestType::kCameraStream:
40 return IDR_ANDROID_INFOBAR_MEDIA_STREAM_CAMERA;
41 case RequestType::kClipboard:
42 return IDR_ANDROID_INFOBAR_CLIPBOARD;
43 case RequestType::kDiskQuota:
44 return IDR_ANDROID_INFOBAR_FOLDER;
45 case RequestType::kGeolocation:
46 return IDR_ANDROID_INFOBAR_GEOLOCATION;
47 case RequestType::kIdleDetection:
48 return IDR_ANDROID_INFOBAR_IDLE_DETECTION;
49 case RequestType::kMicStream:
50 return IDR_ANDROID_INFOBAR_MEDIA_STREAM_MIC;
51 case RequestType::kMidi:
52 // kMidi and kMidiSysex share the same Android icon ID.
53 case RequestType::kMidiSysex:
54 return IDR_ANDROID_INFOBAR_MIDI;
55 case RequestType::kMultipleDownloads:
56 return IDR_ANDROID_INFOBAR_MULTIPLE_DOWNLOADS;
57 case RequestType::kNfcDevice:
58 return IDR_ANDROID_INFOBAR_NFC;
59 case RequestType::kNotifications:
60 return IDR_ANDROID_INFOBAR_NOTIFICATIONS;
61 case RequestType::kProtectedMediaIdentifier:
62 return IDR_ANDROID_INFOBAR_PROTECTED_MEDIA_IDENTIFIER;
63 case RequestType::kStorageAccess:
64 case RequestType::kTopLevelStorageAccess:
65 return base::FeatureList::IsEnabled(
66 permissions::features::kPermissionStorageAccessAPI)
67 ? IDR_ANDROID_STORAGE_ACCESS
68 : IDR_ANDROID_INFOBAR_PERMISSION_COOKIE;
73 #endif // BUILDFLAG(IS_ANDROID)
75 #if !BUILDFLAG(IS_ANDROID)
76 const gfx::VectorIcon& GetIconIdDesktop(RequestType type) {
77 const bool cr23 = ::features::IsChromeRefresh2023();
79 case RequestType::kAccessibilityEvents:
80 return kAccessibilityIcon;
81 case RequestType::kArSession:
82 case RequestType::kVrSession:
83 return cr23 ? vector_icons::kVrHeadsetChromeRefreshIcon
84 : vector_icons::kVrHeadsetIcon;
85 case RequestType::kCameraPanTiltZoom:
86 case RequestType::kCameraStream:
87 return cr23 ? vector_icons::kVideocamChromeRefreshIcon
88 : vector_icons::kVideocamIcon;
89 case RequestType::kClipboard:
90 return cr23 ? vector_icons::kContentPasteChromeRefreshIcon
91 : vector_icons::kContentPasteIcon;
92 case RequestType::kDiskQuota:
93 return cr23 ? vector_icons::kFolderChromeRefreshIcon
94 : vector_icons::kFolderIcon;
95 case RequestType::kGeolocation:
96 return cr23 ? vector_icons::kLocationOnChromeRefreshIcon
97 : vector_icons::kLocationOnIcon;
98 case RequestType::kIdleDetection:
99 return cr23 ? vector_icons::kDevicesChromeRefreshIcon
100 : vector_icons::kDevicesIcon;
101 case RequestType::kLocalFonts:
102 return cr23 ? vector_icons::kFontDownloadChromeRefreshIcon
103 : vector_icons::kFontDownloadIcon;
104 case RequestType::kMicStream:
105 return cr23 ? vector_icons::kMicChromeRefreshIcon
106 : vector_icons::kMicIcon;
107 case RequestType::kMidi:
108 // kMidi and kMidiSysex share the same desktop icon ID.
109 case RequestType::kMidiSysex:
110 return cr23 ? vector_icons::kMidiChromeRefreshIcon
111 : vector_icons::kMidiIcon;
112 case RequestType::kMultipleDownloads:
113 return cr23 ? vector_icons::kFileDownloadChromeRefreshIcon
114 : vector_icons::kFileDownloadIcon;
115 case RequestType::kNotifications:
116 return cr23 ? vector_icons::kNotificationsChromeRefreshIcon
117 : vector_icons::kNotificationsIcon;
118 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
119 case RequestType::kProtectedMediaIdentifier:
120 // This icon is provided by ChromePermissionsClient::GetOverrideIconId.
122 return gfx::kNoneIcon;
124 case RequestType::kRegisterProtocolHandler:
125 return vector_icons::kProtocolHandlerIcon;
126 case RequestType::kStorageAccess:
127 case RequestType::kTopLevelStorageAccess:
128 if (base::FeatureList::IsEnabled(
129 permissions::features::kPermissionStorageAccessAPI)) {
130 return vector_icons::kStorageAccessIcon;
132 return cr23 ? vector_icons::kCookieChromeRefreshIcon
133 : vector_icons::kCookieIcon;
134 case RequestType::kWindowManagement:
135 return cr23 ? vector_icons::kSelectWindowChromeRefreshIcon
136 : vector_icons::kSelectWindowIcon;
137 case RequestType::kFileSystemAccess:
138 return vector_icons::kFolderIcon;
141 return gfx::kNoneIcon;
144 const gfx::VectorIcon& GetBlockedIconIdDesktop(RequestType type) {
145 const bool cr23 = ::features::IsChromeRefresh2023();
147 case RequestType::kGeolocation:
148 return cr23 ? vector_icons::kLocationOffChromeRefreshIcon
149 : vector_icons::kLocationOffIcon;
150 case RequestType::kNotifications:
151 return cr23 ? vector_icons::kNotificationsOffChromeRefreshIcon
152 : vector_icons::kNotificationsOffIcon;
153 case RequestType::kArSession:
154 case RequestType::kVrSession:
155 return cr23 ? vector_icons::kVrHeadsetOffChromeRefreshIcon
156 : vector_icons::kVrHeadsetOffIcon;
157 case RequestType::kCameraStream:
158 return cr23 ? vector_icons::kVideocamOffChromeRefreshIcon
159 : vector_icons::kVideocamOffIcon;
160 case RequestType::kClipboard:
161 return cr23 ? vector_icons::kContentPasteOffChromeRefreshIcon
162 : vector_icons::kContentPasteOffIcon;
163 case RequestType::kIdleDetection:
164 return cr23 ? vector_icons::kDevicesOffChromeRefreshIcon
165 : vector_icons::kDevicesOffIcon;
166 case RequestType::kMicStream:
167 return cr23 ? vector_icons::kMicOffChromeRefreshIcon
168 : vector_icons::kMicOffIcon;
169 case RequestType::kMidi:
170 // kMidi and kMidiSysex share the same desktop block icon ID.
171 case RequestType::kMidiSysex:
172 return cr23 ? vector_icons::kMidiOffChromeRefreshIcon
173 : vector_icons::kMidiOffIcon;
174 case RequestType::kStorageAccess:
175 return vector_icons::kStorageAccessOffIcon;
180 return gfx::kNoneIcon;
182 #endif // !BUILDFLAG(IS_ANDROID)
186 bool IsRequestablePermissionType(ContentSettingsType content_settings_type) {
187 return !!ContentSettingsTypeToRequestTypeIfExists(content_settings_type);
190 absl::optional<RequestType> ContentSettingsTypeToRequestTypeIfExists(
191 ContentSettingsType content_settings_type) {
192 switch (content_settings_type) {
193 case ContentSettingsType::ACCESSIBILITY_EVENTS:
194 return RequestType::kAccessibilityEvents;
195 case ContentSettingsType::AR:
196 return RequestType::kArSession;
197 #if !BUILDFLAG(IS_ANDROID)
198 case ContentSettingsType::CAMERA_PAN_TILT_ZOOM:
199 return RequestType::kCameraPanTiltZoom;
201 case ContentSettingsType::MEDIASTREAM_CAMERA:
202 return RequestType::kCameraStream;
203 case ContentSettingsType::CLIPBOARD_READ_WRITE:
204 return RequestType::kClipboard;
205 #if !BUILDFLAG(IS_ANDROID)
206 case ContentSettingsType::LOCAL_FONTS:
207 return RequestType::kLocalFonts;
209 case ContentSettingsType::GEOLOCATION:
210 return RequestType::kGeolocation;
211 case ContentSettingsType::IDLE_DETECTION:
212 return RequestType::kIdleDetection;
213 case ContentSettingsType::MEDIASTREAM_MIC:
214 return RequestType::kMicStream;
215 case ContentSettingsType::MIDI:
216 if (base::FeatureList::IsEnabled(features::kBlockMidiByDefault)) {
217 return RequestType::kMidi;
219 return absl::nullopt;
221 case ContentSettingsType::MIDI_SYSEX:
222 return RequestType::kMidiSysex;
223 case ContentSettingsType::NOTIFICATIONS:
224 return RequestType::kNotifications;
225 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
226 case ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER:
227 return RequestType::kProtectedMediaIdentifier;
229 #if BUILDFLAG(IS_ANDROID)
230 case ContentSettingsType::NFC:
231 return RequestType::kNfcDevice;
233 case ContentSettingsType::STORAGE_ACCESS:
234 return RequestType::kStorageAccess;
235 case ContentSettingsType::VR:
236 return RequestType::kVrSession;
237 #if !BUILDFLAG(IS_ANDROID)
238 case ContentSettingsType::WINDOW_MANAGEMENT:
239 return RequestType::kWindowManagement;
241 case ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS:
242 return RequestType::kTopLevelStorageAccess;
243 #if !BUILDFLAG(IS_ANDROID)
244 case ContentSettingsType::FILE_SYSTEM_WRITE_GUARD:
245 return RequestType::kFileSystemAccess;
248 return absl::nullopt;
252 RequestType ContentSettingsTypeToRequestType(
253 ContentSettingsType content_settings_type) {
254 absl::optional<RequestType> request_type =
255 ContentSettingsTypeToRequestTypeIfExists(content_settings_type);
257 return *request_type;
260 absl::optional<ContentSettingsType> RequestTypeToContentSettingsType(
261 RequestType request_type) {
262 switch (request_type) {
263 case RequestType::kAccessibilityEvents:
264 return ContentSettingsType::ACCESSIBILITY_EVENTS;
265 case RequestType::kArSession:
266 return ContentSettingsType::AR;
267 #if !BUILDFLAG(IS_ANDROID)
268 case RequestType::kCameraPanTiltZoom:
269 return ContentSettingsType::CAMERA_PAN_TILT_ZOOM;
271 case RequestType::kCameraStream:
272 return ContentSettingsType::MEDIASTREAM_CAMERA;
273 case RequestType::kClipboard:
274 return ContentSettingsType::CLIPBOARD_READ_WRITE;
275 #if !BUILDFLAG(IS_ANDROID)
276 case RequestType::kLocalFonts:
277 return ContentSettingsType::LOCAL_FONTS;
279 case RequestType::kGeolocation:
280 return ContentSettingsType::GEOLOCATION;
281 case RequestType::kIdleDetection:
282 return ContentSettingsType::IDLE_DETECTION;
283 case RequestType::kMicStream:
284 return ContentSettingsType::MEDIASTREAM_MIC;
285 case RequestType::kMidi:
286 if (base::FeatureList::IsEnabled(features::kBlockMidiByDefault)) {
287 return ContentSettingsType::MIDI;
289 return absl::nullopt;
291 case RequestType::kMidiSysex:
292 return ContentSettingsType::MIDI_SYSEX;
293 #if BUILDFLAG(IS_ANDROID)
294 case RequestType::kNfcDevice:
295 return ContentSettingsType::NFC;
297 case RequestType::kNotifications:
298 return ContentSettingsType::NOTIFICATIONS;
299 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
300 case RequestType::kProtectedMediaIdentifier:
301 return ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER;
303 case RequestType::kStorageAccess:
304 return ContentSettingsType::STORAGE_ACCESS;
305 case RequestType::kVrSession:
306 return ContentSettingsType::VR;
307 #if !BUILDFLAG(IS_ANDROID)
308 case RequestType::kWindowManagement:
309 return ContentSettingsType::WINDOW_MANAGEMENT;
311 case RequestType::kTopLevelStorageAccess:
312 return ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS;
314 // Not associated with a ContentSettingsType.
315 return absl::nullopt;
319 // Returns whether confirmation chips can be displayed
320 bool IsConfirmationChipSupported(RequestType for_request_type) {
321 return base::ranges::any_of(
322 std::vector<RequestType>{
323 RequestType::kNotifications, RequestType::kGeolocation,
324 RequestType::kCameraStream, RequestType::kMicStream},
325 [for_request_type](permissions::RequestType request_type) {
326 return request_type == for_request_type;
330 IconId GetIconId(RequestType type) {
331 IconId override_id = PermissionsClient::Get()->GetOverrideIconId(type);
332 #if BUILDFLAG(IS_ANDROID)
335 return GetIconIdAndroid(type);
337 if (!override_id.is_empty())
339 return GetIconIdDesktop(type);
343 #if !BUILDFLAG(IS_ANDROID)
344 IconId GetBlockedIconId(RequestType type) {
345 return GetBlockedIconIdDesktop(type);
349 const char* PermissionKeyForRequestType(permissions::RequestType request_type) {
350 switch (request_type) {
351 case permissions::RequestType::kAccessibilityEvents:
352 return "accessibility_events";
353 case permissions::RequestType::kArSession:
355 #if !BUILDFLAG(IS_ANDROID)
356 case permissions::RequestType::kCameraPanTiltZoom:
357 return "camera_pan_tilt_zoom";
359 case permissions::RequestType::kCameraStream:
360 return "camera_stream";
361 case permissions::RequestType::kClipboard:
363 case permissions::RequestType::kDiskQuota:
365 #if !BUILDFLAG(IS_ANDROID)
366 case permissions::RequestType::kFileSystemAccess:
367 return "file_system";
369 case permissions::RequestType::kGeolocation:
370 return "geolocation";
371 case permissions::RequestType::kIdleDetection:
372 return "idle_detection";
373 #if !BUILDFLAG(IS_ANDROID)
374 case permissions::RequestType::kLocalFonts:
375 return "local_fonts";
377 case permissions::RequestType::kMicStream:
379 case permissions::RequestType::kMidi:
380 if (base::FeatureList::IsEnabled(features::kBlockMidiByDefault)) {
385 case permissions::RequestType::kMidiSysex:
387 case permissions::RequestType::kMultipleDownloads:
388 return "multiple_downloads";
389 #if BUILDFLAG(IS_ANDROID)
390 case permissions::RequestType::kNfcDevice:
393 case permissions::RequestType::kNotifications:
394 return "notifications";
395 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
396 case permissions::RequestType::kProtectedMediaIdentifier:
397 return "protected_media_identifier";
399 #if !BUILDFLAG(IS_ANDROID)
400 case permissions::RequestType::kRegisterProtocolHandler:
401 return "register_protocol_handler";
403 case permissions::RequestType::kStorageAccess:
404 return "storage_access";
405 case permissions::RequestType::kTopLevelStorageAccess:
406 return "top_level_storage_access";
407 case permissions::RequestType::kVrSession:
409 #if !BUILDFLAG(IS_ANDROID)
410 case permissions::RequestType::kWindowManagement:
411 if (base::FeatureList::IsEnabled(
412 features::kWindowPlacementPermissionAlias)) {
413 return "window_placement";
415 return "window_management";
423 } // namespace permissions