| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_PERMISSIONS_PERMISSION_UMA_UTIL_H_ |
| #define COMPONENTS_PERMISSIONS_PERMISSION_UMA_UTIL_H_ |
| |
| #include <optional> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/time/time.h" |
| #include "base/version.h" |
| #include "components/content_settings/core/browser/host_content_settings_map.h" |
| #include "components/content_settings/core/common/content_settings_types.h" |
| #include "components/permissions/permission_request_enums.h" |
| #include "components/permissions/prediction_service/prediction_service_messages.pb.h" |
| #include "components/permissions/request_type.h" |
| #include "content/public/browser/permission_result.h" |
| #include "url/gurl.h" |
| |
| namespace blink { |
| enum class PermissionType; |
| } |
| |
| namespace content { |
| class BrowserContext; |
| class RenderFrameHost; |
| class WebContents; |
| class RenderFrameHost; |
| } // namespace content |
| |
| namespace permissions { |
| enum class PermissionRequestGestureType; |
| enum class PermissionAction; |
| class PermissionRequest; |
| |
| enum class ActivityIndicatorState { |
| kInUse = 0, |
| kBlockedOnSiteLevel = 1, |
| kBlockedOnSystemLevel = 2, |
| |
| // Always keep at the end. |
| kMaxValue = kBlockedOnSystemLevel, |
| }; |
| |
| // Used for UMA histograms to record model execution stats for the different |
| // models we use for a permission prediction. |
| // LINT.IfChange(PredictionModelType) |
| enum class PredictionModelType { |
| kUnknown = 0, |
| kServerSideCpssV3Model = 1, |
| kOnDeviceCpssV1Model = 2, |
| kOnDeviceAiV3Model = 3, |
| }; |
| // LINT.ThenChange(//tools/metrics/histograms/metadata/permissions/histograms.xml:PredictionModels) |
| |
| // Used for UMA to record the types of permission prompts shown. |
| // When updating, you also need to update: |
| // 1) The PermissionRequestType enum in |
| // tools/metrics/histograms/metadata/permissions/enums.xml. |
| // 2) The PermissionRequestTypes suffix list in |
| // tools/metrics/histograms/metadata/histogram_suffixes_list.xml. |
| // 3) GetPermissionRequestString function in |
| // components/permissions/permission_uma_util.cc |
| // |
| // The usual rules of updating UMA values applies to this enum: |
| // - don't remove values |
| // - only ever add values at the end |
| enum class RequestTypeForUma { |
| UNKNOWN = 0, |
| MULTIPLE_AUDIO_AND_VIDEO_CAPTURE = 1, |
| // UNUSED_PERMISSION = 2, |
| QUOTA = 3, |
| DOWNLOAD = 4, |
| // MEDIA_STREAM = 5, |
| REGISTER_PROTOCOL_HANDLER = 6, |
| PERMISSION_GEOLOCATION = 7, |
| PERMISSION_MIDI_SYSEX = 8, |
| PERMISSION_NOTIFICATIONS = 9, |
| PERMISSION_PROTECTED_MEDIA_IDENTIFIER = 10, |
| // PERMISSION_PUSH_MESSAGING = 11, |
| PERMISSION_FLASH = 12, |
| PERMISSION_MEDIASTREAM_MIC = 13, |
| PERMISSION_MEDIASTREAM_CAMERA = 14, |
| // PERMISSION_ACCESSIBILITY_EVENTS = 15, // Removed in M131. |
| // PERMISSION_CLIPBOARD_READ = 16, // Replaced by |
| // PERMISSION_CLIPBOARD_READ_WRITE in M81. |
| // PERMISSION_SECURITY_KEY_ATTESTATION = 17, |
| PERMISSION_PAYMENT_HANDLER = 18, |
| PERMISSION_NFC = 19, |
| PERMISSION_CLIPBOARD_READ_WRITE = 20, |
| PERMISSION_VR = 21, |
| PERMISSION_AR = 22, |
| PERMISSION_STORAGE_ACCESS = 23, |
| PERMISSION_CAMERA_PAN_TILT_ZOOM = 24, |
| PERMISSION_WINDOW_MANAGEMENT = 25, |
| PERMISSION_LOCAL_FONTS = 26, |
| PERMISSION_IDLE_DETECTION = 27, |
| PERMISSION_FILE_HANDLING = 28, |
| // PERMISSION_U2F_API_REQUEST = 29, |
| PERMISSION_TOP_LEVEL_STORAGE_ACCESS = 30, |
| // PERMISSION_MIDI = 31, |
| PERMISSION_FILE_SYSTEM_ACCESS = 32, |
| CAPTURED_SURFACE_CONTROL = 33, |
| PERMISSION_SMART_CARD = 34, |
| PERMISSION_WEB_PRINTING = 35, |
| PERMISSION_IDENTITY_PROVIDER = 36, |
| PERMISSION_KEYBOARD_LOCK = 37, |
| PERMISSION_POINTER_LOCK = 38, |
| MULTIPLE_KEYBOARD_AND_POINTER_LOCK = 39, |
| PERMISSION_HAND_TRACKING = 40, |
| PERMISSION_WEB_APP_INSTALLATION = 41, |
| PERMISSION_LOCAL_NETWORK_ACCESS = 42, |
| // NUM must be the last value in the enum. |
| NUM, |
| }; |
| |
| // Any new values should be inserted immediately prior to kMaxValue. |
| enum class PermissionSourceUI { |
| // Permission prompt. |
| PROMPT = 0, |
| |
| // Origin info bubble. |
| // https://www.chromium.org/Home/chromium-security/enamel/goals-for-the-origin-info-bubble |
| OIB = 1, |
| |
| // chrome://settings/content/siteDetails?site=[SITE] |
| // chrome://settings/content/[PERMISSION TYPE] |
| SITE_SETTINGS = 2, |
| |
| // Page action bubble. |
| PAGE_ACTION = 3, |
| |
| // Permission settings from Android. |
| // Currently this value is only used when revoking notification permission in |
| // Android O+ system channel settings. |
| ANDROID_SETTINGS = 4, |
| |
| // Permission settings as part of the event's UI. |
| // Currently this value is only used when revoking notification permission |
| // through the notification UI. |
| INLINE_SETTINGS = 5, |
| |
| // Permission settings changes as part of the abusive origins revocation. |
| AUTO_REVOCATION = 6, |
| |
| // Permission changes due to automatic revocations of permissions from unused |
| // sites, as part of Safety Hub. |
| SAFETY_HUB_AUTO_REVOCATION = 7, |
| |
| // The permission status changed, but we're unsure from what source. |
| // This is likely ANDROID_SETTINGS above though. |
| UNIDENTIFIED = 8, |
| |
| // Always keep this at the end. |
| kMaxValue = UNIDENTIFIED, |
| }; |
| |
| // Any new values should be inserted immediately prior to NUM. |
| enum class PermissionEmbargoStatus { |
| NOT_EMBARGOED = 0, |
| // Removed: PERMISSIONS_BLACKLISTING = 1, |
| REPEATED_DISMISSALS = 2, |
| REPEATED_IGNORES = 3, |
| RECENT_DISPLAY = 4, |
| |
| // Keep this at the end. |
| NUM, |
| }; |
| |
| // Used for UMA to record the strict level of permission policy which is |
| // configured to allow sub-frame origin. Any new values should be inserted |
| // immediately prior to NUM. All values here should have corresponding entries |
| // PermissionsPolicyConfiguration area of enums.xml. |
| enum class PermissionHeaderPolicyForUMA { |
| // No (or an invalid) Permissions-Policy header was present, results in an |
| // empty features list. It indicates none security-awareness of permissions |
| // policy configuration. |
| HEADER_NOT_PRESENT_OR_INVALID = 0, |
| |
| // Permissions-Policy header was present, but it did not define an allowlist |
| // for the feature. It indicates less security-awareness of permissions policy |
| // configuration. |
| FEATURE_NOT_PRESENT = 1, |
| |
| // The sub-frame origin is included in allow-list of permission |
| // policy. This indicates a good policy configuration. |
| FEATURE_ALLOWLIST_EXPLICITLY_MATCHES_ORIGIN = 2, |
| |
| // Granted by setting value of permission policy to '*'. This also |
| // indicates a bad policy configuration. |
| FEATURE_ALLOWLIST_IS_WILDCARD = 3, |
| |
| // The Permissions-Policy header was present and defined an empty |
| // allowlist for the feature. The feature will be disabled everywhere. |
| FEATURE_ALLOWLIST_IS_NONE = 4, |
| |
| // The sub-frame origin is not explicitly declared in allow-list of top level |
| // permission policy. It generally indicates less security-awareness of |
| // policy configuration. |
| FEATURE_ALLOWLIST_DOES_NOT_MATCH_ORIGIN = 5, |
| |
| // Always keep this at the end. |
| NUM, |
| }; |
| |
| // The kind of permission prompt UX used to surface a permission request. |
| // Enum used in UKMs and UMAs, do not re-order or change values. Deprecated |
| // items should only be commented out. New items should be added at the end, |
| // and the "PermissionPromptDisposition" histogram suffix needs to be updated to |
| // match (tools/metrics/histograms/metadata/histogram_suffixes_list.xml). |
| enum class PermissionPromptDisposition { |
| // Not all permission actions will have an associated permission prompt (e.g. |
| // changing permission via the settings page). |
| NOT_APPLICABLE = 0, |
| |
| // Only used on desktop, a bubble under the site settings padlock. |
| ANCHORED_BUBBLE = 1, |
| |
| // Only used on desktop, a static indicator on the right-hand side of the |
| // location bar. |
| LOCATION_BAR_RIGHT_STATIC_ICON = 2, |
| |
| // Only used on desktop, an animated indicator on the right-hand side of the |
| // location bar. |
| LOCATION_BAR_RIGHT_ANIMATED_ICON = 3, |
| |
| // Only used on Android, a modal dialog. |
| MODAL_DIALOG = 4, |
| |
| // Only used on Android, an initially-collapsed infobar at the bottom of the |
| // page. |
| MINI_INFOBAR = 5, |
| |
| // Only used on desktop, a chip on the left-hand side of the location bar that |
| // shows a bubble when clicked. |
| LOCATION_BAR_LEFT_CHIP = 6, |
| |
| // There was no UI being shown. This is usually because the user closed an |
| // inactive tab that had a pending permission request. |
| NONE_VISIBLE = 7, |
| |
| // Other custom modal dialogs. |
| CUSTOM_MODAL_DIALOG = 8, |
| |
| // Only used on desktop, a less prominent version of chip on the left-hand |
| // side of the location bar that shows a bubble when clicked. |
| LOCATION_BAR_LEFT_QUIET_CHIP = 9, |
| |
| // Only used on Android, a message bubble near top of the screen and below the |
| // location bar. Message UI is an alternative UI to infobar UI. |
| MESSAGE_UI = 10, |
| |
| // Only used on desktop, a chip on the left-hand side of the location bar that |
| // automatically shows a bubble. |
| LOCATION_BAR_LEFT_QUIET_ABUSIVE_CHIP = 11, |
| |
| // Only used on desktop, a chip on the left-hand side of the location bar that |
| // automatically shows a bubble. |
| LOCATION_BAR_LEFT_CHIP_AUTO_BUBBLE = 12, |
| |
| // A prompt shown as a result of the user clicking the permission element. |
| ELEMENT_ANCHORED_BUBBLE = 13, |
| |
| // Only used on macOS, a native OS provided permission prompt. |
| MAC_OS_PROMPT = 14, |
| }; |
| |
| // The reason why the permission prompt disposition was used. Enum used in UKMs, |
| // do not re-order or change values. Deprecated items should only be commented |
| // out. |
| enum class PermissionPromptDispositionReason { |
| // Disposition was selected in prefs. |
| USER_PREFERENCE_IN_SETTINGS = 0, |
| |
| // Disposition was chosen because Safe Browsing classifies the origin |
| // as being spammy or abusive with permission requests. |
| SAFE_BROWSING_VERDICT = 1, |
| |
| // Disposition was chosen based on grant likelihood predicted by the |
| // Web Permission Prediction Service. |
| PREDICTION_SERVICE = 2, |
| |
| // Disposition was used as a fallback, if no selector made a decision. |
| DEFAULT_FALLBACK = 3, |
| |
| // Disposition was chosen based on grant likelihood predicted by the On-Device |
| // Permission Prediction Model. |
| ON_DEVICE_PREDICTION_MODEL = 4, |
| }; |
| |
| enum class AdaptiveTriggers { |
| // None of the adaptive triggers were met. Currently this means two or less |
| // consecutive denies in a row. |
| NONE = 0, |
| |
| // User denied permission prompt 3 or more times. |
| THREE_CONSECUTIVE_DENIES = 0x01, |
| }; |
| |
| // LINT.IfChange(DismissedReason) |
| enum class DismissedReason { |
| // The prompt was dismissed through the [x] button. |
| kDismissedXButton = 0, |
| |
| // The prompt was dismissed through the user clicking on the scrim (area |
| // around the prompt). |
| kDismissedScrim = 1, |
| |
| kMaxValue = kDismissedScrim, |
| }; |
| // LINT.ThenChange(//tools/metrics/histograms/metadata/permissions/enums.xml:DismissedReason) |
| |
| // LINT.IfChange(OsScreen) |
| enum class OsScreen { |
| // Informs the user that Chrome needs permission from the OS level. |
| kOsPrompt = 0, |
| |
| // Informs the user that they need to go to OS system settings. |
| kOsSystemSettings = 1, |
| |
| kMaxValue = kOsSystemSettings, |
| }; |
| // LINT.ThenChange(//tools/metrics/histograms/metadata/permissions/histograms.xml:OsScreen) |
| |
| // LINT.IfChange(OsScreenAction) |
| enum class OsScreenAction { |
| // User clicks on "Go to System settings" |
| kSystemSettings = 0, |
| |
| // The prompt was dismissed through the [x] button. |
| kDismissedXButton = 1, |
| |
| // The prompt was dismissed through the user clicking on the scrim (area |
| // around the prompt). |
| kDismissedScrim = 2, |
| |
| // Os prompt denied. |
| kOsPromptDenied = 3, |
| |
| // Os prompt allowed. |
| kOsPromptAllowed = 4, |
| |
| kMaxValue = kOsPromptAllowed, |
| }; |
| // LINT.ThenChange(//tools/metrics/histograms/metadata/permissions/histograms.xml:OsScreenAction) |
| |
| // These values are logged to UMA. Entries should not be renumbered and |
| // numeric values should never be reused. Please keep in sync with |
| // "OneTimePermissionEvent" in tools/metrics/histograms/enums.xml. |
| enum class OneTimePermissionEvent { |
| // Recorded for each one time grant |
| GRANTED_ONE_TIME = 0, |
| |
| // Recorded when the user manually revokes a one time grant |
| REVOKED_MANUALLY = 1, |
| |
| // Recorded when a one time grant expires because all tabs are either closed |
| // or discarded. |
| ALL_TABS_CLOSED_OR_DISCARDED = 2, |
| |
| // Recorded when a one time grant expires because the permission was unused in |
| // the background. |
| EXPIRED_IN_BACKGROUND = 3, |
| |
| // Revoked because of the maximum one time permission lifetime |
| // `kOneTimePermissionMaximumLifetime` |
| EXPIRED_AFTER_MAXIMUM_LIFETIME = 4, |
| |
| // Recorded when a one time grant expires because the device was suspended. |
| EXPIRED_ON_SUSPEND = 5, |
| |
| kMaxValue = EXPIRED_ON_SUSPEND, |
| }; |
| |
| // LINT.IfChange(ElementAnchoredBubbleVariant) |
| // Prompt views shown after the user clicks on the embedded permission prompt. |
| // The values represent the priority of each variant, higher number means |
| // higher priority. |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class ElementAnchoredBubbleVariant { |
| // Default when conditions are not met to show any of the permission views. |
| kUninitialized = 0, |
| // Informs the user that the permission was allowed by their administrator. |
| kAdministratorGranted = 1, |
| // Permission prompt that informs the user they already granted permission. |
| // Offers additional options to modify the permission decision. |
| kPreviouslyGranted = 2, |
| // Informs the user that they need to go to OS system settings to grant |
| // access to Chrome. |
| kOsSystemSettings = 3, |
| // Informs the user that Chrome needs permission from the OS level, in order |
| // for the site to be able to access a permission. |
| kOsPrompt = 4, |
| // Permission prompt that asks the user for site-level permission. |
| kAsk = 5, |
| // Permission prompt that additionally informs the user that they have |
| // previously denied permission to the site. May offer different options |
| // (buttons) to the site-level prompt |kAsk|. |
| kPreviouslyDenied = 6, |
| // Informs the user that the permission was denied by their administrator. |
| kAdministratorDenied = 7, |
| |
| kMaxValue = kAdministratorDenied, |
| }; |
| // LINT.ThenChange(//tools/metrics/histograms/enums.xml:ElementAnchoredBubbleVariant) |
| |
| enum class PermissionAutoRevocationHistory { |
| // Permission has not been automatically revoked. |
| NONE = 0, |
| |
| // Permission has been automatically revoked. |
| PREVIOUSLY_AUTO_REVOKED = 0x01, |
| }; |
| |
| // This enum backs up the `AutoDSEPermissionRevertTransition` histogram enum. |
| // Never reuse values and mirror any updates to it. |
| // Describes the transition that has occurred for the setting of a DSE origin |
| // when DSE autogrant becomes disabled. |
| enum class AutoDSEPermissionRevertTransition { |
| // The user has not previously made any decision so it results in an `ASK` end |
| // state. |
| NO_DECISION_ASK = 0, |
| // The user has decided to `ALLOW` the origin before it was the DSE origin and |
| // has not reverted this decision. |
| PRESERVE_ALLOW = 1, |
| // The user has previously `BLOCKED` the origin but has allowed it after it |
| // became the DSE origin. Resolve the conflict by setting it to `ASK` so the |
| // user will make a decision again. |
| CONFLICT_ASK = 2, |
| // The user has blocked the DSE origin and has not made a previous decision |
| // before the origin became the DSE origin. |
| PRESERVE_BLOCK_ASK = 3, |
| // The user has blocked the DSE origin and has `ALLOWED` it before it became |
| // the DSE origin, preserve the latest decision. |
| PRESERVE_BLOCK_ALLOW = 4, |
| // The user has blocked the DSE origin and has `BLOCKED` it before it became |
| // the DSE origin as well. |
| PRESERVE_BLOCK_BLOCK = 5, |
| // There has been an invalid transition. |
| INVALID_END_STATE = 6, |
| |
| // Always keep at the end. |
| kMaxValue = INVALID_END_STATE, |
| }; |
| |
| // LINT.IfChange(PermissionPredictionSource) |
| |
| // This enum backs up the 'PermissionPredictionSource` histogram enum. It |
| // indicates whether the permission prediction was done by the local on device |
| // model or by the server side model (or both). |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class PermissionPredictionSource { |
| ON_DEVICE_TFLITE = 0, |
| SERVER_SIDE = 1, |
| ONDEVICE_AI_AND_SERVER_SIDE = 2, |
| |
| // Always keep at the end. |
| kMaxValue = ONDEVICE_AI_AND_SERVER_SIDE, |
| }; |
| |
| // LINT.ThenChange(//tools/metrics/histograms/metadata/permissions/enums.xml:PermissionPredictionSource) |
| |
| // This enum backs up the 'PageInfoDialogAccessType' histogram enum. |
| // It is used for collecting page info access type metrics in the context of |
| // the confirmation chip. |
| enum class PageInfoDialogAccessType { |
| // The user opened page info by clicking on the lock in a situation that is |
| // considered independent of the display of a confirmation chip. |
| LOCK_CLICK = 0, |
| // The user opened page info by clicking on the lock while a confirmation chip |
| // was being displayed. |
| LOCK_CLICK_DURING_CONFIRMATION_CHIP = 1, |
| // The user opened page info by clicking on the confirmation chip while it was |
| // being displayed. |
| CONFIRMATION_CHIP_CLICK = 2, |
| |
| // The user opened page info by clicking on the lock within |
| // 'kConfirmationConsiderationDurationForUma' after confirmation chip has |
| // collapsed. This click may be considered influenced by the displaying of the |
| // confirmation chip. |
| LOCK_CLICK_SHORTLY_AFTER_CONFIRMATION_CHIP = 3, |
| |
| // Always keep at the end. |
| kMaxValue = LOCK_CLICK_SHORTLY_AFTER_CONFIRMATION_CHIP, |
| }; |
| |
| constexpr auto kConfirmationConsiderationDurationForUma = base::Seconds(20); |
| |
| // This enum backs up the |
| // 'Permissions.PageInfo.ChangedWithin1m.{PermissionType}' histograms enum. It |
| // is used for collecting page info permission change metrics following in the |
| // first minute after a PermissionAction has been taken. Note that |
| // PermissionActions DISMISSED and IGNORED are not taken into account, as they |
| // don't have an effect on the content settings. |
| enum class PermissionChangeAction { |
| // PermissionAction was one of {GRANTED, GRANTED_ONCE} and the content |
| // setting is changed to CONTENT_SETTING_BLOCK. |
| REVOKED = 0, |
| |
| // PermissionAction was DENIED and the content setting is changed to |
| // CONTENT_SETTING_ALLOW. |
| REALLOWED = 1, |
| |
| // PermissionAction was one of {GRANTED, GRANTED_ONCE} and the content setting |
| // is changed to CONTENT_SETTING_DEFAULT. |
| RESET_FROM_ALLOWED = 2, |
| |
| // PermissionAction was DENIED and the content setting is changed to |
| // CONTENT_SETTING_DEFAULT. |
| RESET_FROM_DENIED = 3, |
| |
| // For one time grantable permissions, the user can toggle a remember checkbox |
| // in the secondary page info page which toggles grants between permanent |
| // grant and one time grant. |
| REMEMBER_CHECKBOX_TOGGLED = 4, |
| |
| // Always keep at the end. |
| kMaxValue = REMEMBER_CHECKBOX_TOGGLED, |
| }; |
| |
| // LINT.IfChange(ElementAnchoredBubbleAction) |
| enum class ElementAnchoredBubbleAction { |
| // Site level permission was granted. |
| kGranted = 0, |
| |
| // Site level permission was granted once. |
| kGrantedOnce = 1, |
| |
| // Site level permission was denied. |
| kDenied = 2, |
| |
| // Acknowledging the prompt informing the user a permission is managed by |
| // admin. |
| kOk = 3, |
| |
| // The prompt was dismissed by the user clicking on the [X] button. |
| kDismissedXButton = 4, |
| |
| // The prompt was dismissed by the user clicking outside of the prompt area. |
| kDismissedScrim = 5, |
| |
| // User clicked "Open system settings" to manage OS level permission prompts. |
| kSystemSettings = 6, |
| |
| // Always keep at the end. |
| kMaxValue = kSystemSettings, |
| }; |
| // LINT.ThenChange(//tools/metrics/histograms/enums.xml:ElementAnchoredBubbleAction) |
| |
| // The reason the permission action `PermissionAction::IGNORED` was triggered. |
| enum class PermissionIgnoredReason { |
| // Ignore was triggered due to closure of the browser window |
| WINDOW_CLOSED = 0, |
| |
| // Ignore was triggered due to closure of the tab |
| TAB_CLOSED = 1, |
| |
| // Ignore was triggered due to navigation |
| NAVIGATION = 2, |
| |
| // Catches all other cases |
| UNKNOWN = 3, |
| |
| // Always keep at the end |
| NUM, |
| }; |
| |
| // This enum backs up the |
| // 'Permissions.PageInfo.Changed.{PermissionType}.Reallowed.Outcome' histograms |
| // enum. It is used for collecting permission usage rates after permission |
| // status was reallowed via PageInfo. It is applicable only if permission is |
| // allowed as all other states are no-op for an origin. |
| // |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class PermissionChangeInfo { |
| kInfobarShownPageReloadPermissionUsed = 0, |
| |
| kInfobarShownPageReloadPermissionNotUsed = 1, |
| |
| kInfobarShownNoPageReloadPermissionUsed = 2, |
| |
| kInfobarShownNoPageReloadPermissionNotUsed = 3, |
| |
| kInfobarNotShownPageReloadPermissionUsed = 4, |
| |
| kInfobarNotShownPageReloadPermissionNotUsed = 5, |
| |
| kInfobarNotShownNoPageReloadPermissionUsed = 6, |
| |
| kInfobarNotShownNoPageReloadPermissionNotUsed = 7, |
| |
| // Always keep at the end. |
| kMaxValue = kInfobarNotShownNoPageReloadPermissionNotUsed, |
| }; |
| |
| // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.permissions |
| // GENERATED_JAVA_CLASS_NAME_OVERRIDE: DismissalType |
| enum class DismissalType { |
| // Fallback if a more specific dismissal type is not available.. |
| kUnspecified = 0, |
| |
| // The user dismissed by touching the back button. |
| kNavigateBack = 1, // |
| |
| // The user dismissed by touching outside the scrim |
| kTouchOutside = 2, |
| |
| // It's possible for the context to be null if a prompt is |
| // dequeued after the user backgrounds the browser and cleanup has already |
| // happened. In that case, the prompt gets quietly dismissed. |
| kAutodismissNoContext = 3, |
| |
| // The user accepted the site-level prompt but denied the |
| // app-level prompt (= OS prompt), in which case the permission request gets |
| // quietly dismissed. |
| kAutodismissOsDenied = 4, |
| |
| // It's possible that the modal dialog manager is null when showing a dialog, |
| // for example if the tab has been navigated/closed or the layout might not be |
| // inflated in some embedders (e.g WebEngine). |
| kAutodismissNoDialogManager = 5, |
| |
| // Always keep this at the end. |
| kMaxValue = kAutodismissNoDialogManager, |
| }; |
| |
| // Provides a convenient way of logging UMA for permission related operations. |
| class PermissionUmaUtil { |
| public: |
| using PredictionGrantLikelihood = |
| PermissionPrediction_Likelihood_DiscretizedLikelihood; |
| |
| static const char kPermissionsPromptShown[]; |
| static const char kPermissionsPromptShownGesture[]; |
| static const char kPermissionsPromptShownNoGesture[]; |
| static const char kPermissionsPromptAccepted[]; |
| static const char kPermissionsPromptAcceptedGesture[]; |
| static const char kPermissionsPromptAcceptedNoGesture[]; |
| static const char kPermissionsPromptAcceptedOnce[]; |
| static const char kPermissionsPromptAcceptedOnceGesture[]; |
| static const char kPermissionsPromptAcceptedOnceNoGesture[]; |
| static const char kPermissionsPromptDenied[]; |
| static const char kPermissionsPromptDeniedGesture[]; |
| static const char kPermissionsPromptDeniedNoGesture[]; |
| static const char kPermissionsPromptDismissed[]; |
| |
| static const char kPermissionsExperimentalUsagePrefix[]; |
| static const char kPermissionsActionPrefix[]; |
| |
| PermissionUmaUtil() = delete; |
| PermissionUmaUtil(const PermissionUmaUtil&) = delete; |
| PermissionUmaUtil& operator=(const PermissionUmaUtil&) = delete; |
| |
| static void PermissionRequested(ContentSettingsType permission); |
| |
| static void RecordActivityIndicator(std::set<ContentSettingsType> permissions, |
| bool blocked, |
| bool blocked_system_level, |
| bool clicked); |
| |
| static void RecordDismissalType( |
| const std::vector<ContentSettingsType>& content_settings_types, |
| PermissionPromptDisposition ui_disposition, |
| DismissalType dismissalType); |
| |
| static void RecordPermissionRequestedFromFrame( |
| ContentSettingsType content_settings_type, |
| content::RenderFrameHost* rfh); |
| |
| static void PermissionRequestPreignored(blink::PermissionType permission); |
| |
| // Records the revocation UMA and UKM metrics for ContentSettingsTypes that |
| // have user facing permission prompts. The passed in `permission` must be |
| // such that PermissionUtil::IsPermission(permission) returns true. |
| static void PermissionRevoked(ContentSettingsType permission, |
| PermissionSourceUI source_ui, |
| const GURL& revoked_origin, |
| content::BrowserContext* browser_context); |
| |
| static void RecordEmbargoPromptSuppression( |
| PermissionEmbargoStatus embargo_status); |
| |
| static void RecordEmbargoPromptSuppressionFromSource( |
| content::PermissionStatusSource source); |
| |
| static void RecordEmbargoStatus(PermissionEmbargoStatus embargo_status); |
| |
| static void RecordPermissionRecoverySuccessRate( |
| ContentSettingsType permission, |
| bool is_used, |
| bool show_infobar, |
| bool page_reload); |
| |
| // This gets recorded during the creation process of a prompt, but only for |
| // prompts that aren't labeled as abusive or disruptive. |
| static void RecordPermissionPromptAttempt( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| bool can_display_prompt); |
| |
| // UMA specifically for when permission prompts are shown. This should be |
| // roughly equivalent to the metrics above, however it is |
| // useful to have separate UMA to a few reasons: |
| // - to account for, and get data on coalesced permission bubbles |
| // - there are other types of permissions prompts (e.g. download limiting) |
| // which don't go through PermissionContext |
| // - the above metrics don't always add up (e.g. sum of |
| // granted+denied+dismissed+ignored is not equal to requested), so it is |
| // unclear from those metrics alone how many prompts are seen by users. |
| static void PermissionPromptShown( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests); |
| |
| static void PermissionPromptResolved( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| content::WebContents* web_contents, |
| PermissionAction permission_action, |
| base::TimeDelta time_to_action, |
| PermissionPromptDisposition ui_disposition, |
| std::optional<PermissionPromptDispositionReason> ui_reason, |
| std::optional<std::vector<ElementAnchoredBubbleVariant>> variants, |
| std::optional<PredictionGrantLikelihood> predicted_grant_likelihood, |
| std::optional<PermissionRequestRelevance> permission_request_relevance, |
| std::optional<bool> prediction_decision_held_back, |
| std::optional<permissions::PermissionIgnoredReason> ignored_reason, |
| bool did_show_prompt, |
| bool did_click_manage, |
| bool did_click_learn_more); |
| |
| static void RecordCrowdDenyDelayedPushNotification(base::TimeDelta delay); |
| |
| static void RecordCrowdDenyVersionAtAbuseCheckTime( |
| const std::optional<base::Version>& version); |
| |
| static void RecordElementAnchoredBubbleDismiss( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| DismissedReason reason); |
| |
| static void RecordElementAnchoredBubbleOsMetrics( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| OsScreen screen, |
| OsScreenAction action, |
| base::TimeDelta time_to_action); |
| |
| static void RecordElementAnchoredBubbleVariantUMA( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| ElementAnchoredBubbleVariant variant); |
| |
| // Record UMAs related to the Android "Missing permissions" infobar. |
| static void RecordMissingPermissionInfobarShouldShow( |
| bool should_show, |
| const std::vector<ContentSettingsType>& content_settings_types); |
| static void RecordMissingPermissionInfobarAction( |
| PermissionAction action, |
| const std::vector<ContentSettingsType>& content_settings_types); |
| |
| static void RecordPermissionUsage(ContentSettingsType permission_type, |
| content::BrowserContext* browser_context, |
| content::WebContents* web_contents, |
| const GURL& requesting_origin); |
| |
| static void RecordPermissionUsageNotificationShown( |
| bool did_user_always_allow_notifications, |
| bool is_allowlisted, |
| int suspicious_score, |
| content::BrowserContext* browser_context, |
| const GURL& requesting_origin, |
| uint64_t site_engagement_level); |
| |
| static void RecordTimeElapsedBetweenGrantAndUse( |
| ContentSettingsType type, |
| base::TimeDelta delta, |
| content_settings::SettingSource source); |
| |
| static void RecordTimeElapsedBetweenGrantAndRevoke(ContentSettingsType type, |
| base::TimeDelta delta); |
| |
| static void RecordAutoDSEPermissionReverted( |
| ContentSettingsType permission_type, |
| ContentSetting backed_up_setting, |
| ContentSetting effective_setting, |
| ContentSetting end_state_setting); |
| |
| static void RecordDSEEffectiveSetting(ContentSettingsType permission_type, |
| ContentSetting setting); |
| |
| static void RecordPermissionPredictionSource( |
| PermissionPredictionSource prediction_type); |
| |
| static void RecordPermissionPredictionServiceHoldback( |
| RequestType request_type, |
| PredictionModelType model_type, |
| bool is_heldback); |
| |
| static void RecordPageInfoDialogAccessType( |
| PageInfoDialogAccessType access_type); |
| |
| static std::string GetOneTimePermissionEventHistogram( |
| ContentSettingsType type); |
| |
| static void RecordOneTimePermissionEvent(ContentSettingsType type, |
| OneTimePermissionEvent event); |
| |
| static void RecordPageInfoPermissionChangeWithin1m( |
| ContentSettingsType type, |
| PermissionAction previous_action, |
| ContentSetting setting_after); |
| |
| static void RecordPageInfoPermissionChange(ContentSettingsType type, |
| ContentSetting setting_before, |
| ContentSetting setting_after, |
| bool suppress_reload_page_bar); |
| |
| static std::string GetPermissionActionString( |
| PermissionAction permission_action); |
| |
| static std::string GetPredictionModelString(PredictionModelType model_type); |
| |
| static std::string GetPromptDispositionString( |
| PermissionPromptDisposition ui_disposition); |
| |
| static std::string GetPromptDispositionReasonString( |
| PermissionPromptDispositionReason ui_disposition_reason); |
| |
| static std::string GetRequestTypeString(RequestType request_type); |
| |
| static bool IsPromptDispositionQuiet( |
| PermissionPromptDisposition prompt_disposition); |
| |
| static bool IsPromptDispositionLoud( |
| PermissionPromptDisposition prompt_disposition); |
| |
| static void RecordIgnoreReason( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| PermissionPromptDisposition prompt_disposition, |
| PermissionIgnoredReason reason); |
| |
| // Record metrics related to usage of permissions delegation. |
| static void RecordPermissionsUsageSourceAndPolicyConfiguration( |
| ContentSettingsType content_settings_type, |
| content::RenderFrameHost* render_frame_host); |
| |
| static void RecordCrossOriginFrameActionAndPolicyConfiguration( |
| ContentSettingsType content_settings_type, |
| PermissionAction action, |
| content::RenderFrameHost* render_frame_host); |
| |
| static void RecordTopLevelPermissionsHeaderPolicyOnNavigation( |
| content::RenderFrameHost* render_frame_host); |
| |
| // Logs a metric that captures how long since revocation, due to a site being |
| // considered unused, the user regrants a revoked permission. |
| static void RecordPermissionRegrantForUnusedSites( |
| const GURL& origin, |
| ContentSettingsType request_type, |
| PermissionSourceUI source_ui, |
| content::BrowserContext* browser_context, |
| base::Time current_time); |
| |
| static std::optional<uint32_t> GetDaysSinceUnusedSitePermissionRevocation( |
| const GURL& origin, |
| ContentSettingsType content_settings_type, |
| base::Time current_time, |
| HostContentSettingsMap* hcsm); |
| |
| // Records UKM metrics for ContentSettingsTypes that have user facing |
| // permission prompts triggered by the user clicking on the Embedded |
| // Permission Element. The passed in `permission` must be such that |
| // PermissionUtil::IsPermission(permission) returns true. |
| static void RecordElementAnchoredPermissionPromptAction( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| const std::vector<base::WeakPtr<permissions::PermissionRequest>>& |
| screen_requests, |
| ElementAnchoredBubbleAction action, |
| ElementAnchoredBubbleVariant variant, |
| int screen_counter, |
| const GURL& requesting_origin, |
| content::WebContents* web_contents, |
| content::BrowserContext* browser_context); |
| |
| // Records `TimeDelta` between two consecutive indicators of the same |
| // `RequestTypeForUma`. |
| static void RecordPermissionIndicatorElapsedTimeSinceLastUsage( |
| RequestTypeForUma request_type, |
| base::TimeDelta time_delta); |
| |
| static void RecordPermissionRequestRelevance( |
| PermissionRequestRelevance permission_request_relevance); |
| |
| // Records if the browser was always active while the prompt was |
| // displaying. |
| static void RecordBrowserAlwaysActiveWhilePrompting( |
| RequestTypeForUma request_type, |
| bool embedded_permission_element_initiated, |
| bool always_active); |
| |
| // Records if the browser was always active before user's interaction. |
| static void RecordActionBrowserAlwaysActive(RequestTypeForUma request_type, |
| std::string permission_action, |
| bool always_active); |
| |
| // Records the execution time of prediction model inquiries. |
| static void RecordPredictionModelInquireTime( |
| base::TimeTicks model_inquire_start_time, |
| PredictionModelType model_type); |
| |
| // Records if the browser was active at the time the prompt started displaying |
| static void RecordPromptShownInActiveBrowser( |
| RequestTypeForUma request_type, |
| bool embedded_permission_element_initiated, |
| bool active); |
| |
| // A scoped class that will check the current resolved content setting on |
| // construction and report a revocation metric accordingly if the revocation |
| // condition is met (from ALLOW to something else). |
| class ScopedRevocationReporter { |
| public: |
| ScopedRevocationReporter(content::BrowserContext* browser_context, |
| const GURL& primary_url, |
| const GURL& secondary_url, |
| ContentSettingsType content_type, |
| PermissionSourceUI source_ui); |
| |
| ScopedRevocationReporter(content::BrowserContext* browser_context, |
| const ContentSettingsPattern& primary_pattern, |
| const ContentSettingsPattern& secondary_pattern, |
| ContentSettingsType content_type, |
| PermissionSourceUI source_ui); |
| |
| ~ScopedRevocationReporter(); |
| |
| // Returns true if a ScopedRevocationReporter instance is in scope. |
| static bool IsInstanceInScope(); |
| |
| private: |
| raw_ptr<content::BrowserContext> browser_context_; |
| const GURL primary_url_; |
| const GURL secondary_url_; |
| ContentSettingsType content_type_; |
| PermissionSourceUI source_ui_; |
| bool is_initially_allowed_; |
| base::Time last_modified_date_; |
| }; |
| |
| private: |
| friend class PermissionUmaUtilTest; |
| |
| // Records UMA and UKM metrics for ContentSettingsTypes that have user |
| // facing permission prompts. The passed in `permission` must be such that |
| // PermissionUtil::IsPermission(permission) returns true. |
| // web_contents may be null when for recording non-prompt actions. |
| static void RecordPermissionAction( |
| ContentSettingsType permission, |
| PermissionAction action, |
| PermissionSourceUI source_ui, |
| PermissionRequestGestureType gesture_type, |
| base::TimeDelta time_to_action, |
| PermissionPromptDisposition ui_disposition, |
| std::optional<PermissionPromptDispositionReason> ui_reason, |
| std::optional<std::vector<ElementAnchoredBubbleVariant>> variants, |
| const GURL& requesting_origin, |
| content::WebContents* web_contents, |
| content::BrowserContext* browser_context, |
| content::RenderFrameHost* render_frame_host, |
| std::optional<PredictionGrantLikelihood> predicted_grant_likelihood, |
| std::optional<PermissionRequestRelevance> permission_request_relevance, |
| std::optional<bool> prediction_decision_held_back); |
| |
| // Records |count| total prior actions for a prompt of type |permission| |
| // for a single origin using |prefix| for the metric. |
| static void RecordPermissionPromptPriorCount(ContentSettingsType permission, |
| const std::string& prefix, |
| int count); |
| |
| static void RecordPromptDecided( |
| const std::vector<std::unique_ptr<PermissionRequest>>& requests, |
| bool accepted, |
| bool is_one_time); |
| }; |
| |
| } // namespace permissions |
| |
| #endif // COMPONENTS_PERMISSIONS_PERMISSION_UMA_UTIL_H_ |