blob: 6c8facff9f47eb439c09396744c5bc83e5592435 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_WARNING_DATA_H_
#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_WARNING_DATA_H_
#include <vector>
#include "base/supports_user_data.h"
#include "base/time/time.h"
#include "components/safe_browsing/core/common/proto/csd.pb.h"
namespace download {
class DownloadItem;
}
// Per DownloadItem data for storing warning events on download warnings. The
// data is only set if a warning is shown. These events are added to Safe
// Browsing reports.
class DownloadItemWarningData : public base::SupportsUserData::Data {
public:
// The surface that the warning is shown. See
// go/chrome-download-warning-surfaces for details.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class WarningSurface {
// Applicable actions: DISCARD, OPEN_SUBPAGE
BUBBLE_MAINPAGE = 1,
// Applicable actions: PROCEED, DISCARD, DISMISS, CLOSE, BACK,
// PROCEED_DEEP_SCAN, OPEN_LEARN_MORE_LINK
BUBBLE_SUBPAGE = 2,
// Applicable actions: DISCARD, KEEP
DOWNLOADS_PAGE = 3,
// Applicable actions: PROCEED, CANCEL, CLOSE
DOWNLOAD_PROMPT = 4,
kMaxValue = DOWNLOAD_PROMPT
};
// Users action on the warning surface.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class WarningAction {
// The warning is shown. This is a special action that may not be triggered
// by user. We will use this action as the anchor to track the latency of
// other actions.
SHOWN = 0,
// The user clicks proceed, which means the user decides to bypass the
// warning.
PROCEED = 1,
// The user clicks discard, which means the user decides to obey the
// warning and the dangerous download is deleted from disk.
DISCARD = 2,
// The user has clicked the keep button on the surface.
KEEP = 3,
// The user has clicked the close button on the surface.
CLOSE = 4,
// The user clicks cancel on the download prompt.
CANCEL = 5,
// The user has dismissed the bubble by clicking anywhere outside
// the bubble.
DISMISS = 6,
// The user has clicked the back button on the bubble subpage to go back
// to the bubble main page.
BACK = 7,
// The user has opened the subpage from the main page.
OPEN_SUBPAGE = 8,
// The user clicks proceed on a prompt for deep scanning.
PROCEED_DEEP_SCAN = 9,
// The user clicks the learn more link on the bubble subpage.
OPEN_LEARN_MORE_LINK = 10,
kMaxValue = OPEN_LEARN_MORE_LINK
};
struct WarningActionEvent {
WarningSurface surface;
WarningAction action;
// The latency between when the warning is shown for the first time and when
// this event has happened.
int64_t action_latency_msec;
// A terminal action means that the warning disappears after this event,
// the download is either deleted or saved.
bool is_terminal_action = false;
WarningActionEvent(WarningSurface surface,
WarningAction action,
int64_t action_latency_msec,
bool is_terminal_action);
};
~DownloadItemWarningData() override;
// Gets all warning actions associated with this `download`. Returns an
// empty vector if there's no warning data or there is no warning shown for
// this `download`.
static std::vector<WarningActionEvent> GetWarningActionEvents(
const download::DownloadItem* download);
// Adds an `action` triggered on `surface` for `download`. It may not be
// added if `download` is null or the length of events associated with this
// `download` exceeds the limit.
static void AddWarningActionEvent(download::DownloadItem* download,
WarningSurface surface,
WarningAction action);
// Returns whether the download was an encrypted archive.
static bool IsEncryptedArchive(const download::DownloadItem* download);
static void SetIsEncryptedArchive(download::DownloadItem* download,
bool is_encrypted_archive);
// Returns whether the user has entered an incorrect password for the
// archive.
static bool HasIncorrectPassword(const download::DownloadItem* download);
static void SetHasIncorrectPassword(download::DownloadItem* download,
bool has_incorrect_password);
// Converts an `event` to the Safe Browsing report proto format.
static safe_browsing::ClientSafeBrowsingReportRequest::DownloadWarningAction
ConstructCsbrrDownloadWarningAction(const WarningActionEvent& event);
// Returns whether we have shown a local password decryption prompt for this
// download.
static bool HasShownLocalDecryptionPrompt(
const download::DownloadItem* download);
static void SetHasShownLocalDecryptionPrompt(download::DownloadItem* download,
bool has_shown);
// Returns whether an encrypted archive was fully extracted.
static bool IsFullyExtractedArchive(const download::DownloadItem* download);
static void SetIsFullyExtractedArchive(download::DownloadItem* download,
bool extracted);
private:
DownloadItemWarningData();
template <typename F, typename V>
static V GetWithDefault(const download::DownloadItem* download,
F&& f,
V&& default_value);
static DownloadItemWarningData* GetOrCreate(download::DownloadItem* download);
std::vector<WarningActionEvent> ActionEvents() const;
static const char kKey[];
base::Time warning_first_shown_time_;
std::vector<WarningActionEvent> action_events_;
bool is_encrypted_archive_ = false;
bool has_incorrect_password_ = false;
bool has_shown_local_decryption_prompt_ = false;
bool fully_extracted_archive_ = false;
};
#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_WARNING_DATA_H_