tree: 84a6fccde2e127f84c3815867441c21c3a0275ab [path history] [tgz]
  1. android/
  2. contexts/
  3. prediction_service/
  4. test/
  5. vector_icons/
  6. add_new_permission.md
  7. bluetooth_chooser_controller.cc
  8. bluetooth_chooser_controller.h
  9. bluetooth_chooser_controller_unittest.cc
  10. bluetooth_chooser_desktop.cc
  11. bluetooth_chooser_desktop.h
  12. bluetooth_delegate_impl.cc
  13. bluetooth_delegate_impl.h
  14. bluetooth_scanning_prompt_controller.cc
  15. bluetooth_scanning_prompt_controller.h
  16. bluetooth_scanning_prompt_controller_unittest.cc
  17. bluetooth_scanning_prompt_desktop.cc
  18. bluetooth_scanning_prompt_desktop.h
  19. BUILD.gn
  20. chooser_controller.cc
  21. chooser_controller.h
  22. constants.cc
  23. constants.h
  24. DEPS
  25. DIR_METADATA
  26. fake_bluetooth_chooser_controller.cc
  27. fake_bluetooth_chooser_controller.h
  28. fake_usb_chooser_controller.cc
  29. fake_usb_chooser_controller.h
  30. features.cc
  31. features.h
  32. mock_chooser_controller_view.cc
  33. mock_chooser_controller_view.h
  34. notifications_engagement_service.cc
  35. notifications_engagement_service.h
  36. object_permission_context_base.cc
  37. object_permission_context_base.h
  38. object_permission_context_base_unittest.cc
  39. origin_keyed_permission_action_service.cc
  40. origin_keyed_permission_action_service.h
  41. OWNERS
  42. pepc_initiated_permission_request_unittest.cc
  43. permission_actions_history.cc
  44. permission_actions_history.h
  45. permission_actions_history_unittest.cc
  46. permission_auditing_database.cc
  47. permission_auditing_database.h
  48. permission_auditing_database_unittest.cc
  49. permission_auditing_service.cc
  50. permission_auditing_service.h
  51. permission_auditing_service_unittest.cc
  52. permission_context_base.cc
  53. permission_context_base.h
  54. permission_context_base_unittest.cc
  55. permission_decision_auto_blocker.cc
  56. permission_decision_auto_blocker.h
  57. permission_decision_auto_blocker_unittest.cc
  58. permission_hats_trigger_helper.cc
  59. permission_hats_trigger_helper.h
  60. permission_manager.cc
  61. permission_manager.h
  62. permission_manager_unittest.cc
  63. permission_prompt.h
  64. permission_prompt_impl.cc
  65. permission_recovery_success_rate_tracker.cc
  66. permission_recovery_success_rate_tracker.h
  67. permission_request.cc
  68. permission_request.h
  69. permission_request_data.cc
  70. permission_request_data.h
  71. permission_request_enums.h
  72. permission_request_id.cc
  73. permission_request_id.h
  74. permission_request_manager.cc
  75. permission_request_manager.h
  76. permission_request_manager_unittest.cc
  77. permission_request_queue.cc
  78. permission_request_queue.h
  79. permission_request_queue_unittest.cc
  80. permission_ui_selector.cc
  81. permission_ui_selector.h
  82. permission_uma_util.cc
  83. permission_uma_util.h
  84. permission_uma_util_unittest.cc
  85. permission_usage_session.cc
  86. permission_usage_session.h
  87. permission_util.cc
  88. permission_util.h
  89. permissions_client.cc
  90. permissions_client.h
  91. PERMISSIONS_OWNERS
  92. pref_names.cc
  93. pref_names.h
  94. README.md
  95. request_type.cc
  96. request_type.h
  97. switches.cc
  98. switches.h
components/permissions/README.md

Permission Checks and Requests

PermissionController

The PermissionController is the entry point for clients of the permissions infrastructure from both the //content and the embedder (e.g. //chrome) layers. PermissionController provides access to the permissions API and can be reached as content::BrowserContext::GetPermissionController() or Profile::GetPermissionController().

PermissionController has the following API:

  • blink::mojom::PermissionStatus PermissionController::GetPermissionStatusForWorker
  • blink::mojom::PermissionStatus PermissionController::GetPermissionStatusForCurrentDocument
  • blink::mojom::PermissionStatus PermissionController::GetPermissionStatusForOriginWithoutContext Use this API only in special cases when there is no active document or worker. E.g., PermissionType::PAYMENT_HANDLER permission verification of payment providers in a PWA's manifest.
  • PermissionController::RequestPermissionFromCurrentDocument
  • PermissionController::RequestPermissionsFromCurrentDocument

PermissionControllerImpl

The PermissionControllerImpl is the implementation of the PermissionController. PermissionControllerImpl is meant to be used only internally in //content and is not available for external clients.

PermissionControllerImpl provides various functionality such as:

  • Reset a permission's state to the default
  • Observe permissions changes
  • Override permission status for DevTools.

PermissionManager and PermissionContextBase

The PermissionManager is an implementation of PermissionControllerDelegate. PermissionManager is a KeyedService which means it is attached to a BrowserContext. It allows to get permission status for ContentSettingsType. That API should be used only to display permission status in UI like PageInfo and SiteSettings.

Internally, PermissionManager holds a list of PermissionsContexts, one per ContentSettingType. PermissionContextBase is the base class for these contexts, and for every ContentSettingsType there is a specific ...PermissionsContext subclass.

EXAMPLE: NotificationPermissionContext handles the “NOTIFICATIONS” content setting.

In order to query, set, and reset the state of a permission, the HostContentSettingsMap KeyedService is used, which internally handles the more complicated things related to Content Settings.

In order to present the user with a permission prompt when a permission is requested, PermissionRequestManager is used.

HostContentSettingsMap

Patterns

In order to determine whether a permission is granted, blocked, needs a user decision, etc, the appropriate content setting is checked. Content settings are saved and retrieved using a key consisting of a 3-tuple of values:

  • Primary pattern: this is a ContentSettingsPattern that represents the primary resource's URL. For permissions this refers to the URL of the document requesting/using the permission.
  • Secondary pattern: this is a ContentSettingsPattern that is used for some types to provide some context around the primary resource. For permissions this refers to the URL of the top-level document of the page (except for “NOTIFICATIONS” in which case it's unused).
  • Content type: this is a ContentSettingsType that specifies which setting this operation refers to.

A ContentSettingsPattern is basically a URL where every part (scheme, host port, path) is allowed to be either Wildcard or a specified value. Any other form or regex is not supported.

A key that has Wildcard for both the primary and secondary patterns represents the “Default” value for a specific ContentSettingsType. This is the least specific content setting that will match anything and serves as a backup for when no more-specific setting has been set.

Providers

When setting or retrieving a content setting, the HostContentSettingsMap uses a list of registered providers. This enum is sorted from highest priority to lowest. If a provider is able to handle a specific operation it will do so and the following providers are ignored, otherwise the next provider is queried and so on.

The underlying storage mechanism is provider-dependent.

PermissionRequestManager

The PermissionRequestManager facilitates making permission requests via AddRequest(). Only one request prompt is allowed to be in progress at a time, the manager holds a deque of pending requests for all requests that are kept waiting until the current prompt is resolved.

The PermissionRequestManager is attached and scoped to the lifetime of a WebContents. When the WebContents object is destroyed all current and queued requests are finalized as “IGNORED”.

It is possible to have more than one request be tied in to the same prompt. This only happens when the requests are allowed to be grouped together and they all requested one after another. Currently this is only the case for the Camera and Microphone permissions which can be grouped into one Camera+Microphone prompt.

Automatic actions

  • The --deny-permission-prompts command line switch will cause all permissions to be automatically denied.
  • Notification permission requests that arrive too soon after a previous notifications prompt has been resolved are automatically “DENIED”. When a user denies a notifications permission prompt, the manager enters a “notifications cooldown mode” and a user-initiated navigation needs to happen before allowing another notifications permission prompt. This prevents an abusive pattern observed in the wild where a site is cycling through multiple subdomains and asking to show permissions until the user gives up or gives in.
  • On ChromeOS in WebKiosk mode, permission requests for the origin of the installed app are automatically “GRANTED”. This needs to be done because there is no “user” to grant a permissions when the browser is simply used to continuously display some presentation app (for example: a TV in a store that displays on screen the camera feed).
  • Requests that duplicate a currently pending requests are put into a separate list instead of the regular queue. When a request is resolved, its duplicates are also resolved.
  • Based on various indicators (user's behavior, settings, site score etc) a request can be downgraded to use a quiet UI or be dropped entirely. For more info see the Quiet permissions prompts section.
  • If the current permission prompt is quiet, it will be resolved as “IGNORED” when a new request is added. This prevents the permission requests being stuck around a prompt that is easily ignored by the user.

If the request has not been automatically resolved, it is added to deque of queued_requests_ from which it will be picked up as appropriate.

Showing prompts

When a trigger causes the DequeueRequestIfNeeded function to be called it will check if the necessary conditions are met to show a new permission prompt and it will trigger showing the prompt. The conditions are:

  • The document needs to be loaded and visible
  • There is no permission prompt currently being shown to the user
  • There is a queued request waiting to be shown to the user

DequeueRequestIfNeeded is triggered when:

  • The document loads
  • The document becomes visible
  • A new request is added
  • A permission prompt is resolved
  • An async decision about a permission request is made

When the prompt needs to be shown to the user, a platform specific subclass of PermissionPrompt is created which handles the creation and lifetime of the UI element and will report user actions back to the PermissionRequestManager.

The PermissionPrompt is responsible for deciding the exact UI surface and text to present to the user based on information about the request.

Quiet permissions prompts

For specific permission prompt requests a decision could be made to enforce a quiet UI version of the permission prompt. Currently this only applies to NOTIFICATIONS permission requests.

A quiet UI prompt can be triggered if any of these conditions are met:

  • The user has enabled quiet prompts in settings.
  • The site requesting the permissions is marked by Safe Browsing as having a bad reputation.

The AdaptiveQuietNotificationPermissionUiEnabler is responsible for recording the permission prompts outcomes and, if needed, enabling the quiet UI in settings. The ContextualNotificationPermissionUiSelector checks if the quiet UI is enabled in settings (among other things) when choosing the appropriate UI flavor.

A quiet UI prompt will use a right-side omnibox indicator on desktop or a mini-infobar on Android.

PermissionsSecurityModelInteractiveUITest

Testing

Requesting and verification of permissions does not feature unified behavior in different environments. In other words, based on the preconditions, a permission request could be shown or automatically declined. To make sure that all cases work as intended, we introduced PermissionsSecurityModelInteractiveUITest.

Add your own test

If you're adding a new environment that requires non-default behavior for permissions, then you need to add a test in PermissionsSecurityModelInteractiveUITest.

Steps to follow:

  • Create a new test fixture and activate your environment and get a WebContents or a RenderFrameHost.
  • Create a method VerifyPermissionForXYZ, where XYZ is the name of your environment. You can use the already defined VerifyPermission method if you expect to have default behavior for permissions. In VerifyPermissionForXYZ define a new behavior you expect to have.
  • Call VerifyPermissionForXYZ from your newly created test fixture.

EXAMPLE: PermissionRequestWithPortalTest enables the Portals. The [PortalActivation] test verifies that permissions are disabled in Portals. VerifyPermissionsDeniedForPortal incapsulates all logic needed for a particular permission verification.

Add new permission

See add_new_permission.md