| // Copyright 2021 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/safe_browsing/content/browser/download/download_stats.h" |
| |
| #include "base/files/file_path.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/metrics/user_metrics_action.h" |
| #include "base/time/time.h" |
| #include "components/download/public/common/download_content.h" |
| #include "components/download/public/common/download_danger_type.h" |
| #include "components/safe_browsing/content/common/file_type_policies.h" |
| |
| namespace { |
| |
| using safe_browsing::FileTypePolicies; |
| |
| constexpr char kShownMetricSuffix[] = ".Shown"; |
| constexpr char kBypassedMetricSuffix[] = ".Bypassed"; |
| |
| std::string GetDangerTypeMetricSuffix( |
| download::DownloadDangerType danger_type) { |
| switch (danger_type) { |
| case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: |
| return ".DangerousFileType"; |
| case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: |
| case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: |
| case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: |
| case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE: |
| case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: |
| case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS: |
| return ".Malicious"; |
| case download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: |
| return ".Uncommon"; |
| case download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING: |
| case download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_LOCAL_PASSWORD_SCANNING: |
| case download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING: |
| case download::DOWNLOAD_DANGER_TYPE_ASYNC_LOCAL_PASSWORD_SCANNING: |
| case download::DOWNLOAD_DANGER_TYPE_BLOCKED_PASSWORD_PROTECTED: |
| case download::DOWNLOAD_DANGER_TYPE_BLOCKED_TOO_LARGE: |
| case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING: |
| case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK: |
| case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE: |
| case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_FAILED: |
| case download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: |
| case download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: |
| case download::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: |
| case download::DOWNLOAD_DANGER_TYPE_ALLOWLISTED_BY_POLICY: |
| case download::DOWNLOAD_DANGER_TYPE_BLOCKED_SCAN_FAILED: |
| case download::DOWNLOAD_DANGER_TYPE_MAX: |
| return ".Others"; |
| } |
| } |
| |
| void RecordDangerousWarningFileType(const base::FilePath& file_path, |
| const std::string& metrics_suffix) { |
| base::UmaHistogramSparse( |
| "SBClientDownload.Warning.FileType" + metrics_suffix, |
| FileTypePolicies::GetInstance()->UmaValueForFile(file_path)); |
| } |
| |
| void RecordDangerousWarningIsHttps(bool is_https, |
| const std::string& metrics_suffix) { |
| base::UmaHistogramBoolean( |
| "SBClientDownload.Warning.DownloadIsHttps" + metrics_suffix, is_https); |
| } |
| |
| void RecordDangerousWarningHasUserGesture(bool has_user_gesture, |
| const std::string& metrics_suffix) { |
| base::UmaHistogramBoolean( |
| "SBClientDownload.Warning.DownloadHasUserGesture" + metrics_suffix, |
| has_user_gesture); |
| } |
| |
| } // namespace |
| |
| namespace safe_browsing { |
| |
| void RecordDangerousDownloadWarningShown( |
| download::DownloadDangerType danger_type, |
| const base::FilePath& file_path, |
| bool is_https, |
| bool has_user_gesture) { |
| std::string metrics_suffix = |
| GetDangerTypeMetricSuffix(danger_type) + kShownMetricSuffix; |
| RecordDangerousWarningFileType(file_path, metrics_suffix); |
| RecordDangerousWarningIsHttps(is_https, metrics_suffix); |
| RecordDangerousWarningHasUserGesture(has_user_gesture, metrics_suffix); |
| base::RecordAction( |
| base::UserMetricsAction("SafeBrowsing.Download.WarningShown")); |
| } |
| |
| void RecordDangerousDownloadWarningBypassed( |
| download::DownloadDangerType danger_type, |
| const base::FilePath& file_path, |
| bool is_https, |
| bool has_user_gesture) { |
| std::string metrics_suffix = |
| GetDangerTypeMetricSuffix(danger_type) + kBypassedMetricSuffix; |
| RecordDangerousWarningFileType(file_path, metrics_suffix); |
| RecordDangerousWarningIsHttps(is_https, metrics_suffix); |
| RecordDangerousWarningHasUserGesture(has_user_gesture, metrics_suffix); |
| base::RecordAction( |
| base::UserMetricsAction("SafeBrowsing.Download.WarningBypassed")); |
| } |
| |
| void RecordDownloadFileTypeAttributes( |
| DownloadFileType::DangerLevel danger_level, |
| bool has_user_gesture, |
| bool visited_referrer_before, |
| std::optional<base::Time> last_bypass_time) { |
| if (danger_level != DownloadFileType::ALLOW_ON_USER_GESTURE) { |
| return; |
| } |
| base::UmaHistogramEnumeration( |
| "SBClientDownload.UserGestureFileType.Attributes", |
| UserGestureFileTypeAttributes::TOTAL_TYPE_CHECKED); |
| if (has_user_gesture) { |
| base::UmaHistogramEnumeration( |
| "SBClientDownload.UserGestureFileType.Attributes", |
| UserGestureFileTypeAttributes::HAS_USER_GESTURE); |
| } |
| if (visited_referrer_before) { |
| base::UmaHistogramEnumeration( |
| "SBClientDownload.UserGestureFileType.Attributes", |
| UserGestureFileTypeAttributes::HAS_REFERRER_VISIT); |
| } |
| if (has_user_gesture && visited_referrer_before) { |
| base::UmaHistogramEnumeration( |
| "SBClientDownload.UserGestureFileType.Attributes", |
| UserGestureFileTypeAttributes:: |
| HAS_BOTH_USER_GESTURE_AND_REFERRER_VISIT); |
| } |
| if (last_bypass_time) { |
| base::UmaHistogramEnumeration( |
| "SBClientDownload.UserGestureFileType.Attributes", |
| UserGestureFileTypeAttributes::HAS_BYPASSED_DOWNLOAD_WARNING); |
| } |
| } |
| |
| } // namespace safe_browsing |