Fix emulator build error
[platform/framework/web/chromium-efl.git] / components / permissions / permission_util.cc
1 // Copyright 2015 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.
4
5 #include "components/permissions/permission_util.h"
6
7 #include "base/check.h"
8 #include "base/feature_list.h"
9 #include "base/notreached.h"
10 #include "build/build_config.h"
11 #include "build/chromeos_buildflags.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 "content/public/browser/browser_context.h"
17 #include "content/public/browser/permission_result.h"
18 #include "content/public/browser/render_frame_host.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "content/public/browser/web_contents.h"
21 #include "third_party/blink/public/common/permissions/permission_utils.h"
22 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
23 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
24 #include "url/gurl.h"
25 #include "url/origin.h"
26
27 using blink::PermissionType;
28
29 namespace permissions {
30
31 namespace {
32 // Represents the possible methods of delegating permissions from main frames
33 // to child frames.
34 enum class PermissionDelegationMode {
35   // Permissions from the main frame are delegated to child frames.
36   // This is the default delegation mode for permissions. If a main frame was
37   // granted a permission that is delegated, its child frames will inherit that
38   // permission if allowed by the permissions policy.
39   kDelegated,
40   // Permissions from the main frame are not delegated to child frames.
41   // An undelegated permission will only be granted to a child frame if the
42   // child frame's origin was previously granted access to the permission when
43   // in a main frame.
44   kUndelegated,
45   // Permission access is a function of both the requesting and embedding
46   // origins.
47   kDoubleKeyed,
48 };
49
50 PermissionDelegationMode GetPermissionDelegationMode(
51     ContentSettingsType permission) {
52   // TODO(crbug.com/987654): Generalize this to other "background permissions",
53   // that is, permissions that can be used by a service worker. This includes
54   // durable storage, background sync, etc.
55   if (permission == ContentSettingsType::NOTIFICATIONS)
56     return PermissionDelegationMode::kUndelegated;
57   if (permission == ContentSettingsType::STORAGE_ACCESS ||
58       permission == ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS) {
59     return PermissionDelegationMode::kDoubleKeyed;
60   }
61   return PermissionDelegationMode::kDelegated;
62 }
63 }  // namespace
64
65 // The returned strings must match any Field Trial configs for the Permissions
66 // kill switch e.g. Permissions.Action.Geolocation etc..
67 std::string PermissionUtil::GetPermissionString(
68     ContentSettingsType content_type) {
69   PermissionType permission;
70   bool success = PermissionUtil::GetPermissionType(content_type, &permission);
71   DCHECK(success);
72
73   return blink::GetPermissionString(permission);
74 }
75
76 PermissionRequestGestureType PermissionUtil::GetGestureType(bool user_gesture) {
77   return user_gesture ? PermissionRequestGestureType::GESTURE
78                       : PermissionRequestGestureType::NO_GESTURE;
79 }
80
81 absl::optional<blink::mojom::PermissionsPolicyFeature>
82 PermissionUtil::GetPermissionsPolicyFeature(ContentSettingsType permission) {
83   PermissionType permission_type;
84   bool success =
85       PermissionUtil::GetPermissionType(permission, &permission_type);
86   DCHECK(success);
87   return success
88              ? blink::PermissionTypeToPermissionsPolicyFeature(permission_type)
89              : absl::nullopt;
90 }
91
92 bool PermissionUtil::GetPermissionType(ContentSettingsType type,
93                                        PermissionType* out) {
94   switch (type) {
95     case ContentSettingsType::GEOLOCATION:
96       *out = PermissionType::GEOLOCATION;
97       break;
98     case ContentSettingsType::NOTIFICATIONS:
99       *out = PermissionType::NOTIFICATIONS;
100       break;
101     case ContentSettingsType::MIDI:
102       *out = PermissionType::MIDI;
103       break;
104     case ContentSettingsType::MIDI_SYSEX:
105       *out = PermissionType::MIDI_SYSEX;
106       break;
107     case ContentSettingsType::DURABLE_STORAGE:
108       *out = PermissionType::DURABLE_STORAGE;
109       break;
110     case ContentSettingsType::MEDIASTREAM_CAMERA:
111       *out = PermissionType::VIDEO_CAPTURE;
112       break;
113     case ContentSettingsType::MEDIASTREAM_MIC:
114       *out = PermissionType::AUDIO_CAPTURE;
115       break;
116     case ContentSettingsType::BACKGROUND_SYNC:
117       *out = PermissionType::BACKGROUND_SYNC;
118       break;
119 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || \
120     BUILDFLAG(IS_FUCHSIA)
121     case ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER:
122       *out = PermissionType::PROTECTED_MEDIA_IDENTIFIER;
123       break;
124 #endif
125     case ContentSettingsType::SENSORS:
126       *out = PermissionType::SENSORS;
127       break;
128     case ContentSettingsType::ACCESSIBILITY_EVENTS:
129       *out = PermissionType::ACCESSIBILITY_EVENTS;
130       break;
131     case ContentSettingsType::CLIPBOARD_READ_WRITE:
132       *out = PermissionType::CLIPBOARD_READ_WRITE;
133       break;
134     case ContentSettingsType::CLIPBOARD_SANITIZED_WRITE:
135       *out = PermissionType::CLIPBOARD_SANITIZED_WRITE;
136       break;
137     case ContentSettingsType::PAYMENT_HANDLER:
138       *out = PermissionType::PAYMENT_HANDLER;
139       break;
140     case ContentSettingsType::BACKGROUND_FETCH:
141       *out = PermissionType::BACKGROUND_FETCH;
142       break;
143     case ContentSettingsType::PERIODIC_BACKGROUND_SYNC:
144       *out = PermissionType::PERIODIC_BACKGROUND_SYNC;
145       break;
146     case ContentSettingsType::WAKE_LOCK_SCREEN:
147       *out = PermissionType::WAKE_LOCK_SCREEN;
148       break;
149     case ContentSettingsType::WAKE_LOCK_SYSTEM:
150       *out = PermissionType::WAKE_LOCK_SYSTEM;
151       break;
152     case ContentSettingsType::NFC:
153       *out = PermissionType::NFC;
154       break;
155     case ContentSettingsType::VR:
156       *out = PermissionType::VR;
157       break;
158     case ContentSettingsType::AR:
159       *out = PermissionType::AR;
160       break;
161     case ContentSettingsType::STORAGE_ACCESS:
162       *out = PermissionType::STORAGE_ACCESS_GRANT;
163       break;
164     case ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS:
165       *out = PermissionType::TOP_LEVEL_STORAGE_ACCESS;
166       break;
167     case ContentSettingsType::CAMERA_PAN_TILT_ZOOM:
168       *out = PermissionType::CAMERA_PAN_TILT_ZOOM;
169       break;
170     case ContentSettingsType::WINDOW_MANAGEMENT:
171       *out = PermissionType::WINDOW_MANAGEMENT;
172       break;
173     case ContentSettingsType::LOCAL_FONTS:
174       *out = PermissionType::LOCAL_FONTS;
175       break;
176     case ContentSettingsType::IDLE_DETECTION:
177       *out = PermissionType::IDLE_DETECTION;
178       break;
179     case ContentSettingsType::DISPLAY_CAPTURE:
180       *out = PermissionType::DISPLAY_CAPTURE;
181       break;
182     default:
183       return false;
184   }
185   return true;
186 }
187
188 bool PermissionUtil::IsPermission(ContentSettingsType type) {
189   PermissionType permission;
190   return PermissionUtil::GetPermissionType(type, &permission);
191 }
192
193 bool PermissionUtil::IsLowPriorityPermissionRequest(
194     const PermissionRequest* request) {
195   return request->request_type() == RequestType::kNotifications ||
196          request->request_type() == RequestType::kGeolocation;
197 }
198
199 bool PermissionUtil::IsGuardContentSetting(ContentSettingsType type) {
200   switch (type) {
201     case ContentSettingsType::USB_GUARD:
202     case ContentSettingsType::SERIAL_GUARD:
203     case ContentSettingsType::BLUETOOTH_GUARD:
204     case ContentSettingsType::BLUETOOTH_SCANNING:
205     case ContentSettingsType::FILE_SYSTEM_WRITE_GUARD:
206     case ContentSettingsType::HID_GUARD:
207       return true;
208     default:
209       return false;
210   }
211 }
212
213 bool PermissionUtil::CanPermissionBeAllowedOnce(ContentSettingsType type) {
214   switch (type) {
215     case ContentSettingsType::GEOLOCATION:
216     case ContentSettingsType::MEDIASTREAM_MIC:
217     case ContentSettingsType::MEDIASTREAM_CAMERA:
218       return base::FeatureList::IsEnabled(
219           permissions::features::kOneTimePermission);
220     default:
221       return false;
222   }
223 }
224
225 // Due to dependency issues, this method is duplicated in
226 // content/browser/permissions/permission_util.cc.
227 GURL PermissionUtil::GetLastCommittedOriginAsURL(
228     content::RenderFrameHost* render_frame_host) {
229   DCHECK(render_frame_host);
230
231 #if BUILDFLAG(IS_ANDROID)
232   content::WebContents* web_contents =
233       content::WebContents::FromRenderFrameHost(render_frame_host);
234   // If `allow_universal_access_from_file_urls` flag is enabled, a file:/// can
235   // change its url via history.pushState/replaceState to any other url,
236   // including about:blank. To avoid user confusion we should always use a
237   // visible url, in other words `GetLastCommittedURL`.
238   if (web_contents->GetOrCreateWebPreferences()
239           .allow_universal_access_from_file_urls &&
240       render_frame_host->GetLastCommittedOrigin().GetURL().SchemeIsFile()) {
241     return render_frame_host->GetLastCommittedURL().DeprecatedGetOriginAsURL();
242   }
243 #endif
244
245   return render_frame_host->GetLastCommittedOrigin().GetURL();
246 }
247
248 ContentSettingsType PermissionUtil::PermissionTypeToContentSettingTypeSafe(
249     PermissionType permission) {
250   switch (permission) {
251     case PermissionType::MIDI:
252       return ContentSettingsType::MIDI;
253     case PermissionType::MIDI_SYSEX:
254       return ContentSettingsType::MIDI_SYSEX;
255     case PermissionType::NOTIFICATIONS:
256       return ContentSettingsType::NOTIFICATIONS;
257     case PermissionType::GEOLOCATION:
258       return ContentSettingsType::GEOLOCATION;
259     case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
260 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || \
261     BUILDFLAG(IS_FUCHSIA)
262       return ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER;
263 #else
264       break;
265 #endif
266     case PermissionType::DURABLE_STORAGE:
267       return ContentSettingsType::DURABLE_STORAGE;
268     case PermissionType::AUDIO_CAPTURE:
269       return ContentSettingsType::MEDIASTREAM_MIC;
270     case PermissionType::VIDEO_CAPTURE:
271       return ContentSettingsType::MEDIASTREAM_CAMERA;
272     case PermissionType::BACKGROUND_SYNC:
273       return ContentSettingsType::BACKGROUND_SYNC;
274     case PermissionType::SENSORS:
275       return ContentSettingsType::SENSORS;
276     case PermissionType::ACCESSIBILITY_EVENTS:
277       return ContentSettingsType::ACCESSIBILITY_EVENTS;
278     case PermissionType::CLIPBOARD_READ_WRITE:
279       return ContentSettingsType::CLIPBOARD_READ_WRITE;
280     case PermissionType::CLIPBOARD_SANITIZED_WRITE:
281       return ContentSettingsType::CLIPBOARD_SANITIZED_WRITE;
282     case PermissionType::PAYMENT_HANDLER:
283       return ContentSettingsType::PAYMENT_HANDLER;
284     case PermissionType::BACKGROUND_FETCH:
285       return ContentSettingsType::BACKGROUND_FETCH;
286     case PermissionType::IDLE_DETECTION:
287       return ContentSettingsType::IDLE_DETECTION;
288     case PermissionType::PERIODIC_BACKGROUND_SYNC:
289       return ContentSettingsType::PERIODIC_BACKGROUND_SYNC;
290     case PermissionType::WAKE_LOCK_SCREEN:
291       return ContentSettingsType::WAKE_LOCK_SCREEN;
292     case PermissionType::WAKE_LOCK_SYSTEM:
293       return ContentSettingsType::WAKE_LOCK_SYSTEM;
294     case PermissionType::NFC:
295       return ContentSettingsType::NFC;
296     case PermissionType::VR:
297       return ContentSettingsType::VR;
298     case PermissionType::AR:
299       return ContentSettingsType::AR;
300     case PermissionType::STORAGE_ACCESS_GRANT:
301       return ContentSettingsType::STORAGE_ACCESS;
302     case PermissionType::TOP_LEVEL_STORAGE_ACCESS:
303       return ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS;
304     case PermissionType::CAMERA_PAN_TILT_ZOOM:
305       return ContentSettingsType::CAMERA_PAN_TILT_ZOOM;
306     case PermissionType::WINDOW_MANAGEMENT:
307       return ContentSettingsType::WINDOW_MANAGEMENT;
308     case PermissionType::LOCAL_FONTS:
309       return ContentSettingsType::LOCAL_FONTS;
310     case PermissionType::DISPLAY_CAPTURE:
311       return ContentSettingsType::DISPLAY_CAPTURE;
312     case PermissionType::NUM:
313       break;
314   }
315
316   return ContentSettingsType::DEFAULT;
317 }
318
319 ContentSettingsType PermissionUtil::PermissionTypeToContentSettingType(
320     PermissionType permission) {
321   ContentSettingsType content_setting =
322       PermissionTypeToContentSettingTypeSafe(permission);
323   DCHECK_NE(content_setting, ContentSettingsType::DEFAULT)
324       << "Unknown content setting for permission "
325       << static_cast<int>(permission);
326   return content_setting;
327 }
328
329 PermissionType PermissionUtil::ContentSettingTypeToPermissionType(
330     ContentSettingsType permission) {
331   PermissionType permission_type;
332   bool success =
333       PermissionUtil::GetPermissionType(permission, &permission_type);
334   DCHECK(success);
335
336   return permission_type;
337 }
338
339 ContentSetting PermissionUtil::PermissionStatusToContentSetting(
340     blink::mojom::PermissionStatus status) {
341   switch (status) {
342     case blink::mojom::PermissionStatus::GRANTED:
343       return CONTENT_SETTING_ALLOW;
344     case blink::mojom::PermissionStatus::ASK:
345       return CONTENT_SETTING_ASK;
346     case blink::mojom::PermissionStatus::DENIED:
347     default:
348       return CONTENT_SETTING_BLOCK;
349   }
350
351   NOTREACHED();
352   return CONTENT_SETTING_DEFAULT;
353 }
354
355 blink::mojom::PermissionStatus PermissionUtil::ContentSettingToPermissionStatus(
356     ContentSetting setting) {
357   switch (setting) {
358     case CONTENT_SETTING_ALLOW:
359       return blink::mojom::PermissionStatus::GRANTED;
360     case CONTENT_SETTING_BLOCK:
361       return blink::mojom::PermissionStatus::DENIED;
362     case CONTENT_SETTING_ASK:
363       return blink::mojom::PermissionStatus::ASK;
364     case CONTENT_SETTING_SESSION_ONLY:
365     case CONTENT_SETTING_DETECT_IMPORTANT_CONTENT:
366     case CONTENT_SETTING_DEFAULT:
367     case CONTENT_SETTING_NUM_SETTINGS:
368       break;
369   }
370
371   NOTREACHED();
372   return blink::mojom::PermissionStatus::DENIED;
373 }
374
375 bool PermissionUtil::IsPermissionBlockedInPartition(
376     ContentSettingsType permission,
377     const GURL& requesting_origin,
378     content::RenderProcessHost* render_process_host) {
379   DCHECK(render_process_host);
380   switch (GetPermissionDelegationMode(permission)) {
381     case PermissionDelegationMode::kDelegated:
382       return false;
383     case PermissionDelegationMode::kDoubleKeyed:
384       return false;
385     case PermissionDelegationMode::kUndelegated:
386       // TODO(crbug.com/1312218): This will create |requesting_origin|'s home
387       // StoragePartition if it doesn't already exist. Given how
388       // StoragePartitions are used today, this shouldn't actually be a
389       // problem, but ideally we'd compare StoragePartitionConfigs.
390       content::StoragePartition* requesting_home_partition =
391           render_process_host->GetBrowserContext()->GetStoragePartitionForUrl(
392               requesting_origin);
393       return requesting_home_partition !=
394              render_process_host->GetStoragePartition();
395   }
396 }
397
398 GURL PermissionUtil::GetCanonicalOrigin(ContentSettingsType permission,
399                                         const GURL& requesting_origin,
400                                         const GURL& embedding_origin) {
401   absl::optional<GURL> override_origin =
402       PermissionsClient::Get()->OverrideCanonicalOrigin(requesting_origin,
403                                                         embedding_origin);
404   if (override_origin)
405     return override_origin.value();
406
407   switch (GetPermissionDelegationMode(permission)) {
408     case PermissionDelegationMode::kDelegated:
409       return embedding_origin;
410     case PermissionDelegationMode::kDoubleKeyed:
411     case PermissionDelegationMode::kUndelegated:
412       return requesting_origin;
413   }
414 }
415
416 bool PermissionUtil::HasUserGesture(PermissionPrompt::Delegate* delegate) {
417   const std::vector<permissions::PermissionRequest*>& requests =
418       delegate->Requests();
419   return std::any_of(
420       requests.begin(), requests.end(),
421       [](permissions::PermissionRequest* request) {
422         return request->GetGestureType() ==
423                permissions::PermissionRequestGestureType::GESTURE;
424       });
425 }
426
427 bool PermissionUtil::CanPermissionRequestIgnoreStatus(
428     const PermissionRequestData& request,
429     content::PermissionStatusSource source) {
430   if (!request.embedded_permission_element_initiated) {
431     return false;
432   }
433
434   switch (source) {
435     case content::PermissionStatusSource::KILL_SWITCH:
436     case content::PermissionStatusSource::FEATURE_POLICY:
437     case content::PermissionStatusSource::FENCED_FRAME:
438     case content::PermissionStatusSource::INSECURE_ORIGIN:
439     case content::PermissionStatusSource::VIRTUAL_URL_DIFFERENT_ORIGIN:
440     case content::PermissionStatusSource::PORTAL:
441       return false;
442     case content::PermissionStatusSource::MULTIPLE_DISMISSALS:
443     case content::PermissionStatusSource::MULTIPLE_IGNORES:
444     case content::PermissionStatusSource::RECENT_DISPLAY:
445     case content::PermissionStatusSource::UNSPECIFIED:
446       return true;
447   }
448
449   NOTREACHED();
450 }
451
452 // static
453 bool PermissionUtil::DoesPlatformSupportChip() {
454 #if BUILDFLAG(IS_ANDROID)
455   return false;
456 #else
457   return true;
458 #endif
459 }
460
461 }  // namespace permissions