chromium/components/permissions/permission_uma_util.cc

// 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.

#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

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) {}

// Helper to check if the current render frame host is cross-origin with top
// level frame. Note: in case of nested frames like A(B(A)), the bottom frame A
// will get |IsCrossOriginSubframe| returns false.
bool IsCrossOriginSubframe(content::RenderFrameHost* render_frame_host) {}

// Helper to check if the current render frame host is cross-origin with any of
// its parents.
bool IsCrossOriginWithAnyParent(content::RenderFrameHost* render_frame_host) {}

// Helper to get permission policy header policy for the top-level frame.
// render_frame_host could be the top-level frame or a descendant of top-level
// frame.
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) {}

// Records in a UMA histogram whether we should expect to see an event in UKM,
// to allow for evaluating if the current constraints on UKM recording work well
// in practice.
void RecordUmaForWhetherRevocationUkmWasRecorded(
    ContentSettingsType permission_type,
    bool has_source_id) {}

// Records in a UMA histogram whether we should expect to see an event in UKM,
// to allow for evaluating if the current constraints on UKM recording work well
// in practice.
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) {}

// |full_version| represented in the format `YYYY.M.D.m`, where m is the
// minute-of-day. Return int represented in the format `YYYYMMDD`.
// CrowdDeny versions published before 2020 will be reported as 1.
// Returns 0 if no version available.
// Returns 1 if a version has invalid format.
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) {}

}  // anonymous namespace

// PermissionUmaUtil ----------------------------------------------------------

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[] =;

// Make sure you update histograms.xml permission histogram_suffix if you
// add new permission
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) {}  // namespace permissions

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) {}

// static
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) {}

// static
void PermissionUmaUtil::RecordAutoDSEPermissionReverted(
    ContentSettingsType permission_type,
    ContentSetting backed_up_setting,
    ContentSetting effective_setting,
    ContentSetting end_state_setting) {}

// static
void PermissionUmaUtil::RecordDSEEffectiveSetting(
    ContentSettingsType permission_type,
    ContentSetting setting) {}

// static
void PermissionUmaUtil::RecordPermissionPredictionSource(
    PermissionPredictionSource prediction_source) {}

// static
void PermissionUmaUtil::RecordPermissionPredictionServiceHoldback(
    RequestType request_type,
    bool is_on_device,
    bool is_heldback) {}

// static
void PermissionUmaUtil::RecordPageInfoDialogAccessType(
    PageInfoDialogAccessType access_type) {}

// static
std::string PermissionUmaUtil::GetOneTimePermissionEventHistogram(
    ContentSettingsType type) {}

// static
void PermissionUmaUtil::RecordOneTimePermissionEvent(
    ContentSettingsType type,
    OneTimePermissionEvent event) {}

// static
void PermissionUmaUtil::RecordPageInfoPermissionChangeWithin1m(
    ContentSettingsType type,
    PermissionAction previous_action,
    ContentSetting setting_after) {}

// static
void PermissionUmaUtil::RecordPageInfoPermissionChange(
    ContentSettingsType type,
    ContentSetting setting_before,
    ContentSetting setting_after,
    bool suppress_reload_page_bar) {}

// static
std::string PermissionUmaUtil::GetPermissionActionString(
    PermissionAction permission_action) {}

// static
std::string PermissionUmaUtil::GetPromptDispositionString(
    PermissionPromptDisposition ui_disposition) {}

// static
std::string PermissionUmaUtil::GetPromptDispositionReasonString(
    PermissionPromptDispositionReason ui_disposition_reason) {}

// static
std::string PermissionUmaUtil::GetRequestTypeString(RequestType request_type) {}

// static
bool PermissionUmaUtil::IsPromptDispositionQuiet(
    PermissionPromptDisposition prompt_disposition) {}

// static
bool PermissionUmaUtil::IsPromptDispositionLoud(
    PermissionPromptDisposition prompt_disposition) {}

// static
void PermissionUmaUtil::RecordIgnoreReason(
    const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
    PermissionPromptDisposition prompt_disposition,
    PermissionIgnoredReason reason) {}

// static
void PermissionUmaUtil::RecordPermissionsUsageSourceAndPolicyConfiguration(
    ContentSettingsType content_settings_type,
    content::RenderFrameHost* render_frame_host) {}

// static
void PermissionUmaUtil::RecordElementAnchoredBubbleDismiss(
    const std::vector<raw_ptr<PermissionRequest, VectorExperimental>>& requests,
    DismissedReason reason) {}

// static
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) {}

// static
void PermissionUmaUtil::RecordCrossOriginFrameActionAndPolicyConfiguration(
    ContentSettingsType content_settings_type,
    PermissionAction action,
    content::RenderFrameHost* render_frame_host) {}

// static
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) {}

// static
std::optional<uint32_t>
PermissionUmaUtil::GetDaysSinceUnusedSitePermissionRevocation(
    const GURL& origin,
    ContentSettingsType content_settings_type,
    base::Time current_time,
    HostContentSettingsMap* hcsm) {}

// static
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) {}

}  // namespace permissions