#include "components/permissions/permission_uma_util.h"
#include <cstdint>
#include <utility>
#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/content_settings/core/browser/content_settings_uma_util.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/features.h"
#include "components/permissions/constants.h"
#include "components/permissions/permission_actions_history.h"
#include "components/permissions/permission_decision_auto_blocker.h"
#include "components/permissions/permission_request.h"
#include "components/permissions/permission_util.h"
#include "components/permissions/permissions_client.h"
#include "components/permissions/prediction_service/prediction_common.h"
#include "components/permissions/prediction_service/prediction_request_features.h"
#include "components/permissions/request_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "printing/buildflags/buildflags.h"
#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/jni_string.h"
#endif
namespace {
bool scoped_revocation_reporter_in_scope = …;
}
namespace permissions {
#define PERMISSION_BUBBLE_TYPE_UMA(metric_name, request_type_for_uma) …
#define PERMISSION_BUBBLE_GESTURE_TYPE_UMA( \
gesture_metric_name, no_gesture_metric_name, gesture_type, \
permission_bubble_type) …
PermissionType;
namespace {
RequestTypeForUma GetUmaValueForRequestType(RequestType request_type) { … }
RequestTypeForUma GetUmaValueForRequests(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>&
requests) { … }
const int kPriorCountCap = …;
std::string GetPermissionRequestString(RequestTypeForUma type) { … }
bool IsCrossOriginSubframe(content::RenderFrameHost* render_frame_host) { … }
bool IsCrossOriginWithAnyParent(content::RenderFrameHost* render_frame_host) { … }
PermissionHeaderPolicyForUMA GetTopLevelPermissionHeaderPolicyForUMA(
content::RenderFrameHost* render_frame_host,
blink::mojom::PermissionsPolicyFeature feature) { … }
void RecordEngagementMetric(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
content::WebContents* web_contents,
const std::string& action) { … }
void RecordUmaForWhetherRevocationUkmWasRecorded(
ContentSettingsType permission_type,
bool has_source_id) { … }
void RecordUmaForWhetherUsageUkmWasRecorded(ContentSettingsType permission_type,
bool has_source_id) { … }
void RecordUmaForRevocationSourceUI(ContentSettingsType permission_type,
PermissionSourceUI source_ui) { … }
void RecordPermissionUsageUkm(ContentSettingsType permission_type,
std::optional<ukm::SourceId> source_id) { … }
void RecordPermissionActionUkm(
PermissionAction action,
PermissionRequestGestureType gesture_type,
ContentSettingsType permission,
int dismiss_count,
int ignore_count,
PermissionSourceUI source_ui,
base::TimeDelta time_to_action,
PermissionPromptDisposition ui_disposition,
std::optional<PermissionPromptDispositionReason> ui_reason,
std::optional<std::vector<ElementAnchoredBubbleVariant>> variants,
std::optional<bool> has_three_consecutive_denies,
std::optional<bool> has_previously_revoked_permission,
std::optional<PermissionUmaUtil::PredictionGrantLikelihood>
predicted_grant_likelihood,
PredictionRequestFeatures::ActionCounts
loud_ui_actions_counts_for_request_type,
PredictionRequestFeatures::ActionCounts loud_ui_actions_counts,
PredictionRequestFeatures::ActionCounts actions_counts_for_request_type,
PredictionRequestFeatures::ActionCounts actions_counts,
std::optional<bool> prediction_decision_held_back,
std::optional<ukm::SourceId> source_id) { … }
void RecordElementAnchoredPermissionPromptActionUkm(
RequestTypeForUma permission,
RequestTypeForUma screen_permission,
ElementAnchoredBubbleAction action,
ElementAnchoredBubbleVariant variant,
int screen_counter,
std::optional<ukm::SourceId> source_id) { … }
int ConvertCrowdDenyVersionToInt(const std::optional<base::Version>& version) { … }
AutoDSEPermissionRevertTransition GetAutoDSEPermissionRevertedTransition(
ContentSetting backed_up_setting,
ContentSetting effective_setting,
ContentSetting end_state_setting) { … }
void RecordTopLevelPermissionsHeaderPolicy(
ContentSettingsType content_settings_type,
const std::string& histogram,
content::RenderFrameHost* render_frame_host) { … }
PermissionChangeInfo GetChangeInfo(bool is_used,
bool show_infobar,
bool page_reload) { … }
}
const char PermissionUmaUtil::kPermissionsPromptShown[] = …;
const char PermissionUmaUtil::kPermissionsPromptShownGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptShownNoGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptAccepted[] = …;
const char PermissionUmaUtil::kPermissionsPromptAcceptedGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptAcceptedNoGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptAcceptedOnce[] = …;
const char PermissionUmaUtil::kPermissionsPromptAcceptedOnceGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptAcceptedOnceNoGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptDenied[] = …;
const char PermissionUmaUtil::kPermissionsPromptDeniedGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptDeniedNoGesture[] = …;
const char PermissionUmaUtil::kPermissionsPromptDismissed[] = …;
const char PermissionUmaUtil::kPermissionsExperimentalUsagePrefix[] = …;
const char PermissionUmaUtil::kPermissionsActionPrefix[] = …;
void PermissionUmaUtil::PermissionRequested(ContentSettingsType content_type) { … }
void PermissionUmaUtil::RecordActivityIndicator(
std::set<ContentSettingsType> permissions,
bool blocked,
bool blocked_system_level,
bool clicked) { … }
void PermissionUmaUtil::RecordDismissalType(
const std::vector<ContentSettingsType>& content_settings_types,
PermissionPromptDisposition ui_disposition,
DismissalType dismissalType) { … }
void PermissionUmaUtil::RecordPermissionRequestedFromFrame(
ContentSettingsType content_settings_type,
content::RenderFrameHost* rfh) { … }
void PermissionUmaUtil::PermissionRequestPreignored(PermissionType permission) { … }
void PermissionUmaUtil::PermissionRevoked(
ContentSettingsType permission,
PermissionSourceUI source_ui,
const GURL& revoked_origin,
content::BrowserContext* browser_context) { … }
void PermissionUmaUtil::RecordEmbargoPromptSuppression(
PermissionEmbargoStatus embargo_status) { … }
void PermissionUmaUtil::RecordEmbargoPromptSuppressionFromSource(
content::PermissionStatusSource source) { … }
void PermissionUmaUtil::RecordEmbargoStatus(
PermissionEmbargoStatus embargo_status) { … }
void PermissionUmaUtil::RecordPermissionRecoverySuccessRate(
ContentSettingsType permission,
bool is_used,
bool show_infobar,
bool page_reload) { … }
void PermissionUmaUtil::RecordPermissionPromptAttempt(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
bool IsLocationBarEditingOrEmpty) { … }
void PermissionUmaUtil::PermissionPromptShown(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>&
requests) { … }
void PermissionUmaUtil::PermissionPromptResolved(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& 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<bool> prediction_decision_held_back,
std::optional<permissions::PermissionIgnoredReason> ignored_reason,
bool did_show_prompt,
bool did_click_managed,
bool did_click_learn_more) { … }
void PermissionUmaUtil::RecordPermissionPromptPriorCount(
ContentSettingsType permission,
const std::string& prefix,
int count) { … }
void PermissionUmaUtil::RecordInfobarDetailsExpanded(bool expanded) { … }
void PermissionUmaUtil::RecordCrowdDenyDelayedPushNotification(
base::TimeDelta delay) { … }
void PermissionUmaUtil::RecordCrowdDenyVersionAtAbuseCheckTime(
const std::optional<base::Version>& version) { … }
void PermissionUmaUtil::RecordMissingPermissionInfobarShouldShow(
bool should_show,
const std::vector<ContentSettingsType>& content_settings_types) { … }
void PermissionUmaUtil::RecordMissingPermissionInfobarAction(
PermissionAction action,
const std::vector<ContentSettingsType>& content_settings_types) { … }
PermissionUmaUtil::ScopedRevocationReporter::ScopedRevocationReporter(
content::BrowserContext* browser_context,
const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type,
PermissionSourceUI source_ui)
: … { … }
PermissionUmaUtil::ScopedRevocationReporter::ScopedRevocationReporter(
content::BrowserContext* browser_context,
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
PermissionSourceUI source_ui)
: … { … }
PermissionUmaUtil::ScopedRevocationReporter::~ScopedRevocationReporter() { … }
bool PermissionUmaUtil::ScopedRevocationReporter::IsInstanceInScope() { … }
void PermissionUmaUtil::RecordPermissionUsage(
ContentSettingsType permission_type,
content::BrowserContext* browser_context,
content::WebContents* web_contents,
const GURL& requesting_origin) { … }
void PermissionUmaUtil::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<bool> prediction_decision_held_back) { … }
void PermissionUmaUtil::RecordPromptDecided(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
bool accepted,
bool is_one_time) { … }
void PermissionUmaUtil::RecordTimeElapsedBetweenGrantAndUse(
ContentSettingsType type,
base::TimeDelta delta,
content_settings::SettingSource source) { … }
void PermissionUmaUtil::RecordTimeElapsedBetweenGrantAndRevoke(
ContentSettingsType type,
base::TimeDelta delta) { … }
void PermissionUmaUtil::RecordAutoDSEPermissionReverted(
ContentSettingsType permission_type,
ContentSetting backed_up_setting,
ContentSetting effective_setting,
ContentSetting end_state_setting) { … }
void PermissionUmaUtil::RecordDSEEffectiveSetting(
ContentSettingsType permission_type,
ContentSetting setting) { … }
void PermissionUmaUtil::RecordPermissionPredictionSource(
PermissionPredictionSource prediction_source) { … }
void PermissionUmaUtil::RecordPermissionPredictionServiceHoldback(
RequestType request_type,
bool is_on_device,
bool is_heldback) { … }
void PermissionUmaUtil::RecordPageInfoDialogAccessType(
PageInfoDialogAccessType access_type) { … }
std::string PermissionUmaUtil::GetOneTimePermissionEventHistogram(
ContentSettingsType type) { … }
void PermissionUmaUtil::RecordOneTimePermissionEvent(
ContentSettingsType type,
OneTimePermissionEvent event) { … }
void PermissionUmaUtil::RecordPageInfoPermissionChangeWithin1m(
ContentSettingsType type,
PermissionAction previous_action,
ContentSetting setting_after) { … }
void PermissionUmaUtil::RecordPageInfoPermissionChange(
ContentSettingsType type,
ContentSetting setting_before,
ContentSetting setting_after,
bool suppress_reload_page_bar) { … }
std::string PermissionUmaUtil::GetPermissionActionString(
PermissionAction permission_action) { … }
std::string PermissionUmaUtil::GetPromptDispositionString(
PermissionPromptDisposition ui_disposition) { … }
std::string PermissionUmaUtil::GetPromptDispositionReasonString(
PermissionPromptDispositionReason ui_disposition_reason) { … }
std::string PermissionUmaUtil::GetRequestTypeString(RequestType request_type) { … }
bool PermissionUmaUtil::IsPromptDispositionQuiet(
PermissionPromptDisposition prompt_disposition) { … }
bool PermissionUmaUtil::IsPromptDispositionLoud(
PermissionPromptDisposition prompt_disposition) { … }
void PermissionUmaUtil::RecordIgnoreReason(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
PermissionPromptDisposition prompt_disposition,
PermissionIgnoredReason reason) { … }
void PermissionUmaUtil::RecordPermissionsUsageSourceAndPolicyConfiguration(
ContentSettingsType content_settings_type,
content::RenderFrameHost* render_frame_host) { … }
void PermissionUmaUtil::RecordElementAnchoredBubbleDismiss(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
DismissedReason reason) { … }
void PermissionUmaUtil::RecordElementAnchoredBubbleOsMetrics(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
OsScreen screen,
OsScreenAction action,
base::TimeDelta time_to_action) { … }
void PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
ElementAnchoredBubbleVariant variant) { … }
void PermissionUmaUtil::RecordCrossOriginFrameActionAndPolicyConfiguration(
ContentSettingsType content_settings_type,
PermissionAction action,
content::RenderFrameHost* render_frame_host) { … }
void PermissionUmaUtil::RecordTopLevelPermissionsHeaderPolicyOnNavigation(
content::RenderFrameHost* render_frame_host) { … }
void PermissionUmaUtil::RecordPermissionRegrantForUnusedSites(
const GURL& origin,
ContentSettingsType content_settings_type,
PermissionSourceUI source_ui,
content::BrowserContext* browser_context,
base::Time current_time) { … }
std::optional<uint32_t>
PermissionUmaUtil::GetDaysSinceUnusedSitePermissionRevocation(
const GURL& origin,
ContentSettingsType content_settings_type,
base::Time current_time,
HostContentSettingsMap* hcsm) { … }
void PermissionUmaUtil::RecordElementAnchoredPermissionPromptAction(
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>&
screen_requests,
ElementAnchoredBubbleAction action,
ElementAnchoredBubbleVariant variant,
int screen_counter,
const GURL& requesting_origin,
content::WebContents* web_contents,
content::BrowserContext* browser_context) { … }
}