This source file includes following definitions.
- RecordContentDispositionCount
- RecordContentDispositionCountFlag
- GetDangerousFileType
- RecordDownloadCount
- RecordDownloadSource
- RecordDownloadCompleted
- RecordDownloadInterrupted
- RecordMaliciousDownloadClassified
- RecordDangerousDownloadAccept
- RecordDangerousDownloadDiscard
- RecordDownloadWriteSize
- RecordDownloadWriteLoopCount
- RecordAcceptsRanges
- RecordDownloadImageType
- RecordDownloadMimeType
- RecordDownloadContentDisposition
- RecordFileThreadReceiveBuffers
- RecordBandwidth
- RecordOpen
- RecordClearAllSize
- RecordOpensOutstanding
- RecordContiguousWriteTime
- RecordNetworkBlockage
- RecordFileBandwidth
- RecordSavePackageEvent
- RecordOriginStateOnResumption
#include "content/browser/download/download_stats.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_util.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "net/http/http_content_disposition.h"
namespace content {
namespace {
const int kAllInterruptReasonCodes[] = {
#define INTERRUPT_REASON(label, value) (value),
#include "content/public/browser/download_interrupt_reason_values.h"
#undef INTERRUPT_REASON
};
enum ContentDispositionCountTypes {
CONTENT_DISPOSITION_HEADER_PRESENT = 0,
CONTENT_DISPOSITION_IS_VALID,
CONTENT_DISPOSITION_HAS_DISPOSITION_TYPE,
CONTENT_DISPOSITION_HAS_UNKNOWN_TYPE,
CONTENT_DISPOSITION_HAS_NAME,
CONTENT_DISPOSITION_HAS_FILENAME,
CONTENT_DISPOSITION_HAS_EXT_FILENAME,
CONTENT_DISPOSITION_HAS_NON_ASCII_STRINGS,
CONTENT_DISPOSITION_HAS_PERCENT_ENCODED_STRINGS,
CONTENT_DISPOSITION_HAS_RFC2047_ENCODED_STRINGS,
CONTENT_DISPOSITION_HAS_NAME_ONLY,
CONTENT_DISPOSITION_LAST_ENTRY
};
void RecordContentDispositionCount(ContentDispositionCountTypes type,
bool record) {
if (!record)
return;
UMA_HISTOGRAM_ENUMERATION(
"Download.ContentDisposition", type, CONTENT_DISPOSITION_LAST_ENTRY);
}
void RecordContentDispositionCountFlag(
ContentDispositionCountTypes type,
int flags_to_test,
net::HttpContentDisposition::ParseResultFlags flag) {
RecordContentDispositionCount(type, (flags_to_test & flag) == flag);
}
const base::FilePath::CharType* kDangerousFileTypes[] = {
FILE_PATH_LITERAL(".ad"),
FILE_PATH_LITERAL(".ade"),
FILE_PATH_LITERAL(".adp"),
FILE_PATH_LITERAL(".ah"),
FILE_PATH_LITERAL(".apk"),
FILE_PATH_LITERAL(".app"),
FILE_PATH_LITERAL(".application"),
FILE_PATH_LITERAL(".asp"),
FILE_PATH_LITERAL(".asx"),
FILE_PATH_LITERAL(".bas"),
FILE_PATH_LITERAL(".bash"),
FILE_PATH_LITERAL(".bat"),
FILE_PATH_LITERAL(".cfg"),
FILE_PATH_LITERAL(".chi"),
FILE_PATH_LITERAL(".chm"),
FILE_PATH_LITERAL(".class"),
FILE_PATH_LITERAL(".cmd"),
FILE_PATH_LITERAL(".com"),
FILE_PATH_LITERAL(".command"),
FILE_PATH_LITERAL(".crt"),
FILE_PATH_LITERAL(".crx"),
FILE_PATH_LITERAL(".csh"),
FILE_PATH_LITERAL(".deb"),
FILE_PATH_LITERAL(".dex"),
FILE_PATH_LITERAL(".dll"),
FILE_PATH_LITERAL(".drv"),
FILE_PATH_LITERAL(".exe"),
FILE_PATH_LITERAL(".fxp"),
FILE_PATH_LITERAL(".grp"),
FILE_PATH_LITERAL(".hlp"),
FILE_PATH_LITERAL(".hta"),
FILE_PATH_LITERAL(".htm"),
FILE_PATH_LITERAL(".html"),
FILE_PATH_LITERAL(".htt"),
FILE_PATH_LITERAL(".inf"),
FILE_PATH_LITERAL(".ini"),
FILE_PATH_LITERAL(".ins"),
FILE_PATH_LITERAL(".isp"),
FILE_PATH_LITERAL(".jar"),
FILE_PATH_LITERAL(".jnlp"),
FILE_PATH_LITERAL(".user.js"),
FILE_PATH_LITERAL(".js"),
FILE_PATH_LITERAL(".jse"),
FILE_PATH_LITERAL(".ksh"),
FILE_PATH_LITERAL(".lnk"),
FILE_PATH_LITERAL(".local"),
FILE_PATH_LITERAL(".mad"),
FILE_PATH_LITERAL(".maf"),
FILE_PATH_LITERAL(".mag"),
FILE_PATH_LITERAL(".mam"),
FILE_PATH_LITERAL(".manifest"),
FILE_PATH_LITERAL(".maq"),
FILE_PATH_LITERAL(".mar"),
FILE_PATH_LITERAL(".mas"),
FILE_PATH_LITERAL(".mat"),
FILE_PATH_LITERAL(".mau"),
FILE_PATH_LITERAL(".mav"),
FILE_PATH_LITERAL(".maw"),
FILE_PATH_LITERAL(".mda"),
FILE_PATH_LITERAL(".mdb"),
FILE_PATH_LITERAL(".mde"),
FILE_PATH_LITERAL(".mdt"),
FILE_PATH_LITERAL(".mdw"),
FILE_PATH_LITERAL(".mdz"),
FILE_PATH_LITERAL(".mht"),
FILE_PATH_LITERAL(".mhtml"),
FILE_PATH_LITERAL(".mmc"),
FILE_PATH_LITERAL(".mof"),
FILE_PATH_LITERAL(".msc"),
FILE_PATH_LITERAL(".msh"),
FILE_PATH_LITERAL(".mshxml"),
FILE_PATH_LITERAL(".msi"),
FILE_PATH_LITERAL(".msp"),
FILE_PATH_LITERAL(".mst"),
FILE_PATH_LITERAL(".ocx"),
FILE_PATH_LITERAL(".ops"),
FILE_PATH_LITERAL(".pcd"),
FILE_PATH_LITERAL(".pif"),
FILE_PATH_LITERAL(".pkg"),
FILE_PATH_LITERAL(".pl"),
FILE_PATH_LITERAL(".plg"),
FILE_PATH_LITERAL(".prf"),
FILE_PATH_LITERAL(".prg"),
FILE_PATH_LITERAL(".pst"),
FILE_PATH_LITERAL(".py"),
FILE_PATH_LITERAL(".pyc"),
FILE_PATH_LITERAL(".pyw"),
FILE_PATH_LITERAL(".rb"),
FILE_PATH_LITERAL(".reg"),
FILE_PATH_LITERAL(".rpm"),
FILE_PATH_LITERAL(".scf"),
FILE_PATH_LITERAL(".scr"),
FILE_PATH_LITERAL(".sct"),
FILE_PATH_LITERAL(".sh"),
FILE_PATH_LITERAL(".shar"),
FILE_PATH_LITERAL(".shb"),
FILE_PATH_LITERAL(".shs"),
FILE_PATH_LITERAL(".shtm"),
FILE_PATH_LITERAL(".shtml"),
FILE_PATH_LITERAL(".spl"),
FILE_PATH_LITERAL(".svg"),
FILE_PATH_LITERAL(".swf"),
FILE_PATH_LITERAL(".sys"),
FILE_PATH_LITERAL(".tcsh"),
FILE_PATH_LITERAL(".url"),
FILE_PATH_LITERAL(".vb"),
FILE_PATH_LITERAL(".vbe"),
FILE_PATH_LITERAL(".vbs"),
FILE_PATH_LITERAL(".vsd"),
FILE_PATH_LITERAL(".vsmacros"),
FILE_PATH_LITERAL(".vss"),
FILE_PATH_LITERAL(".vst"),
FILE_PATH_LITERAL(".vsw"),
FILE_PATH_LITERAL(".ws"),
FILE_PATH_LITERAL(".wsc"),
FILE_PATH_LITERAL(".wsf"),
FILE_PATH_LITERAL(".wsh"),
FILE_PATH_LITERAL(".xbap"),
FILE_PATH_LITERAL(".xht"),
FILE_PATH_LITERAL(".xhtm"),
FILE_PATH_LITERAL(".xhtml"),
FILE_PATH_LITERAL(".xml"),
FILE_PATH_LITERAL(".xsl"),
FILE_PATH_LITERAL(".xslt")
};
int GetDangerousFileType(const base::FilePath& file_path) {
for (size_t i = 0; i < arraysize(kDangerousFileTypes); ++i) {
if (file_path.MatchesExtension(kDangerousFileTypes[i]))
return i + 1;
}
return 0;
}
}
void RecordDownloadCount(DownloadCountTypes type) {
UMA_HISTOGRAM_ENUMERATION(
"Download.Counts", type, DOWNLOAD_COUNT_TYPES_LAST_ENTRY);
}
void RecordDownloadSource(DownloadSource source) {
UMA_HISTOGRAM_ENUMERATION(
"Download.Sources", source, DOWNLOAD_SOURCE_LAST_ENTRY);
}
void RecordDownloadCompleted(const base::TimeTicks& start, int64 download_len) {
RecordDownloadCount(COMPLETED_COUNT);
UMA_HISTOGRAM_LONG_TIMES("Download.Time", (base::TimeTicks::Now() - start));
int64 max = 1024 * 1024 * 1024;
download_len /= 1024;
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.DownloadSize",
download_len,
1,
max,
256);
}
void RecordDownloadInterrupted(DownloadInterruptReason reason,
int64 received,
int64 total) {
RecordDownloadCount(INTERRUPTED_COUNT);
UMA_HISTOGRAM_CUSTOM_ENUMERATION(
"Download.InterruptedReason",
reason,
base::CustomHistogram::ArrayToCustomRanges(
kAllInterruptReasonCodes, arraysize(kAllInterruptReasonCodes)));
static const int kBuckets = 30;
static const int64 kMaxKb = 1 << kBuckets;
int64 delta_bytes = total - received;
bool unknown_size = total <= 0;
int64 received_kb = received / 1024;
int64 total_kb = total / 1024;
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedReceivedSizeK",
received_kb,
1,
kMaxKb,
kBuckets);
if (!unknown_size) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedTotalSizeK",
total_kb,
1,
kMaxKb,
kBuckets);
if (delta_bytes == 0) {
RecordDownloadCount(INTERRUPTED_AT_END_COUNT);
UMA_HISTOGRAM_CUSTOM_ENUMERATION(
"Download.InterruptedAtEndReason",
reason,
base::CustomHistogram::ArrayToCustomRanges(
kAllInterruptReasonCodes,
arraysize(kAllInterruptReasonCodes)));
} else if (delta_bytes > 0) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedOverrunBytes",
delta_bytes,
1,
kMaxKb,
kBuckets);
} else {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedUnderrunBytes",
-delta_bytes,
1,
kMaxKb,
kBuckets);
}
}
UMA_HISTOGRAM_BOOLEAN("Download.InterruptedUnknownSize", unknown_size);
}
void RecordMaliciousDownloadClassified(DownloadDangerType danger_type) {
UMA_HISTOGRAM_ENUMERATION("Download.MaliciousDownloadClassified",
danger_type,
DOWNLOAD_DANGER_TYPE_MAX);
}
void RecordDangerousDownloadAccept(DownloadDangerType danger_type,
const base::FilePath& file_path) {
UMA_HISTOGRAM_ENUMERATION("Download.DangerousDownloadValidated",
danger_type,
DOWNLOAD_DANGER_TYPE_MAX);
if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) {
UMA_HISTOGRAM_SPARSE_SLOWLY(
"Download.DangerousFile.DangerousDownloadValidated",
GetDangerousFileType(file_path));
}
}
void RecordDangerousDownloadDiscard(DownloadDiscardReason reason,
DownloadDangerType danger_type,
const base::FilePath& file_path) {
switch (reason) {
case DOWNLOAD_DISCARD_DUE_TO_USER_ACTION:
UMA_HISTOGRAM_ENUMERATION(
"Download.UserDiscard", danger_type, DOWNLOAD_DANGER_TYPE_MAX);
if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) {
UMA_HISTOGRAM_SPARSE_SLOWLY("Download.DangerousFile.UserDiscard",
GetDangerousFileType(file_path));
}
break;
case DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN:
UMA_HISTOGRAM_ENUMERATION(
"Download.Discard", danger_type, DOWNLOAD_DANGER_TYPE_MAX);
if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) {
UMA_HISTOGRAM_SPARSE_SLOWLY("Download.DangerousFile.Discard",
GetDangerousFileType(file_path));
}
break;
default:
NOTREACHED();
}
}
void RecordDownloadWriteSize(size_t data_len) {
int max = 1024 * 1024;
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.WriteSize", data_len, 1, max, 256);
}
void RecordDownloadWriteLoopCount(int count) {
UMA_HISTOGRAM_ENUMERATION("Download.WriteLoopCount", count, 20);
}
void RecordAcceptsRanges(const std::string& accepts_ranges,
int64 download_len,
bool has_strong_validator) {
int64 max = 1024 * 1024 * 1024;
download_len /= 1024;
static const int kBuckets = 50;
if (LowerCaseEqualsASCII(accepts_ranges, "none")) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.AcceptRangesNone.KBytes",
download_len,
1,
max,
kBuckets);
} else if (LowerCaseEqualsASCII(accepts_ranges, "bytes")) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.AcceptRangesBytes.KBytes",
download_len,
1,
max,
kBuckets);
if (has_strong_validator)
RecordDownloadCount(STRONG_VALIDATOR_AND_ACCEPTS_RANGES);
} else {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.AcceptRangesMissingOrInvalid.KBytes",
download_len,
1,
max,
kBuckets);
}
}
namespace {
enum DownloadContent {
DOWNLOAD_CONTENT_UNRECOGNIZED = 0,
DOWNLOAD_CONTENT_TEXT = 1,
DOWNLOAD_CONTENT_IMAGE = 2,
DOWNLOAD_CONTENT_AUDIO = 3,
DOWNLOAD_CONTENT_VIDEO = 4,
DOWNLOAD_CONTENT_OCTET_STREAM = 5,
DOWNLOAD_CONTENT_PDF = 6,
DOWNLOAD_CONTENT_DOC = 7,
DOWNLOAD_CONTENT_XLS = 8,
DOWNLOAD_CONTENT_PPT = 9,
DOWNLOAD_CONTENT_ARCHIVE = 10,
DOWNLOAD_CONTENT_EXE = 11,
DOWNLOAD_CONTENT_DMG = 12,
DOWNLOAD_CONTENT_CRX = 13,
DOWNLOAD_CONTENT_MAX = 14,
};
struct MimeTypeToDownloadContent {
const char* mime_type;
DownloadContent download_content;
};
static MimeTypeToDownloadContent kMapMimeTypeToDownloadContent[] = {
{"application/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM},
{"binary/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM},
{"application/pdf", DOWNLOAD_CONTENT_PDF},
{"application/msword", DOWNLOAD_CONTENT_DOC},
{"application/vnd.ms-excel", DOWNLOAD_CONTENT_XLS},
{"application/vns.ms-powerpoint", DOWNLOAD_CONTENT_PPT},
{"application/zip", DOWNLOAD_CONTENT_ARCHIVE},
{"application/x-gzip", DOWNLOAD_CONTENT_ARCHIVE},
{"application/x-rar-compressed", DOWNLOAD_CONTENT_ARCHIVE},
{"application/x-tar", DOWNLOAD_CONTENT_ARCHIVE},
{"application/x-bzip", DOWNLOAD_CONTENT_ARCHIVE},
{"application/x-exe", DOWNLOAD_CONTENT_EXE},
{"application/x-apple-diskimage", DOWNLOAD_CONTENT_DMG},
{"application/x-chrome-extension", DOWNLOAD_CONTENT_CRX},
};
enum DownloadImage {
DOWNLOAD_IMAGE_UNRECOGNIZED = 0,
DOWNLOAD_IMAGE_GIF = 1,
DOWNLOAD_IMAGE_JPEG = 2,
DOWNLOAD_IMAGE_PNG = 3,
DOWNLOAD_IMAGE_TIFF = 4,
DOWNLOAD_IMAGE_ICON = 5,
DOWNLOAD_IMAGE_WEBP = 6,
DOWNLOAD_IMAGE_MAX = 7,
};
struct MimeTypeToDownloadImage {
const char* mime_type;
DownloadImage download_image;
};
static MimeTypeToDownloadImage kMapMimeTypeToDownloadImage[] = {
{"image/gif", DOWNLOAD_IMAGE_GIF},
{"image/jpeg", DOWNLOAD_IMAGE_JPEG},
{"image/png", DOWNLOAD_IMAGE_PNG},
{"image/tiff", DOWNLOAD_IMAGE_TIFF},
{"image/vnd.microsoft.icon", DOWNLOAD_IMAGE_ICON},
{"image/webp", DOWNLOAD_IMAGE_WEBP},
};
void RecordDownloadImageType(const std::string& mime_type_string) {
DownloadImage download_image = DOWNLOAD_IMAGE_UNRECOGNIZED;
for (size_t i = 0; i < arraysize(kMapMimeTypeToDownloadImage); ++i) {
const MimeTypeToDownloadImage& entry = kMapMimeTypeToDownloadImage[i];
if (mime_type_string == entry.mime_type) {
download_image = entry.download_image;
break;
}
}
UMA_HISTOGRAM_ENUMERATION("Download.ContentImageType",
download_image,
DOWNLOAD_IMAGE_MAX);
}
}
void RecordDownloadMimeType(const std::string& mime_type_string) {
DownloadContent download_content = DOWNLOAD_CONTENT_UNRECOGNIZED;
for (size_t i = 0; i < arraysize(kMapMimeTypeToDownloadContent); ++i) {
const MimeTypeToDownloadContent& entry = kMapMimeTypeToDownloadContent[i];
if (mime_type_string == entry.mime_type) {
download_content = entry.download_content;
break;
}
}
if (download_content == DOWNLOAD_CONTENT_UNRECOGNIZED) {
if (StartsWithASCII(mime_type_string, "text/", true)) {
download_content = DOWNLOAD_CONTENT_TEXT;
} else if (StartsWithASCII(mime_type_string, "image/", true)) {
download_content = DOWNLOAD_CONTENT_IMAGE;
RecordDownloadImageType(mime_type_string);
} else if (StartsWithASCII(mime_type_string, "audio/", true)) {
download_content = DOWNLOAD_CONTENT_AUDIO;
} else if (StartsWithASCII(mime_type_string, "video/", true)) {
download_content = DOWNLOAD_CONTENT_VIDEO;
}
}
UMA_HISTOGRAM_ENUMERATION("Download.ContentType",
download_content,
DOWNLOAD_CONTENT_MAX);
}
void RecordDownloadContentDisposition(
const std::string& content_disposition_string) {
if (content_disposition_string.empty())
return;
net::HttpContentDisposition content_disposition(content_disposition_string,
std::string());
int result = content_disposition.parse_result_flags();
bool is_valid = !content_disposition.filename().empty();
RecordContentDispositionCount(CONTENT_DISPOSITION_HEADER_PRESENT, true);
RecordContentDispositionCount(CONTENT_DISPOSITION_IS_VALID, is_valid);
if (!is_valid)
return;
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_DISPOSITION_TYPE, result,
net::HttpContentDisposition::HAS_DISPOSITION_TYPE);
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_UNKNOWN_TYPE, result,
net::HttpContentDisposition::HAS_UNKNOWN_DISPOSITION_TYPE);
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_NAME, result,
net::HttpContentDisposition::HAS_NAME);
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_FILENAME, result,
net::HttpContentDisposition::HAS_FILENAME);
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_EXT_FILENAME, result,
net::HttpContentDisposition::HAS_EXT_FILENAME);
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_NON_ASCII_STRINGS, result,
net::HttpContentDisposition::HAS_NON_ASCII_STRINGS);
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_PERCENT_ENCODED_STRINGS, result,
net::HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS);
RecordContentDispositionCountFlag(
CONTENT_DISPOSITION_HAS_RFC2047_ENCODED_STRINGS, result,
net::HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS);
RecordContentDispositionCount(
CONTENT_DISPOSITION_HAS_NAME_ONLY,
(result & (net::HttpContentDisposition::HAS_NAME |
net::HttpContentDisposition::HAS_FILENAME |
net::HttpContentDisposition::HAS_EXT_FILENAME)) ==
net::HttpContentDisposition::HAS_NAME);
}
void RecordFileThreadReceiveBuffers(size_t num_buffers) {
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Download.FileThreadReceiveBuffers", num_buffers, 1,
100, 100);
}
void RecordBandwidth(double actual_bandwidth, double potential_bandwidth) {
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Download.ActualBandwidth", actual_bandwidth, 1, 1000000000, 50);
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Download.PotentialBandwidth", potential_bandwidth, 1, 1000000000, 50);
UMA_HISTOGRAM_PERCENTAGE(
"Download.BandwidthUsed",
(int) ((actual_bandwidth * 100)/ potential_bandwidth));
}
void RecordOpen(const base::Time& end, bool first) {
if (!end.is_null()) {
UMA_HISTOGRAM_LONG_TIMES("Download.OpenTime", (base::Time::Now() - end));
if (first) {
UMA_HISTOGRAM_LONG_TIMES("Download.FirstOpenTime",
(base::Time::Now() - end));
}
}
}
void RecordClearAllSize(int size) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.ClearAllSize",
size,
0,
(1 << 10),
32);
}
void RecordOpensOutstanding(int size) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.OpensOutstanding",
size,
0,
(1 << 10),
64);
}
void RecordContiguousWriteTime(base::TimeDelta time_blocked) {
UMA_HISTOGRAM_TIMES("Download.FileThreadBlockedTime", time_blocked);
}
void RecordNetworkBlockage(base::TimeDelta resource_handler_lifetime,
base::TimeDelta resource_handler_blocked_time) {
int percentage = 0;
if (resource_handler_blocked_time != base::TimeDelta()) {
percentage =
resource_handler_blocked_time * 100 / resource_handler_lifetime;
}
UMA_HISTOGRAM_COUNTS_100("Download.ResourceHandlerBlockedPercentage",
percentage);
}
void RecordFileBandwidth(size_t length,
base::TimeDelta disk_write_time,
base::TimeDelta elapsed_time) {
size_t elapsed_time_ms = elapsed_time.InMilliseconds();
if (0u == elapsed_time_ms)
elapsed_time_ms = 1;
size_t disk_write_time_ms = disk_write_time.InMilliseconds();
if (0u == disk_write_time_ms)
disk_write_time_ms = 1;
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Download.BandwidthOverallBytesPerSecond",
(1000 * length / elapsed_time_ms), 1, 50000000, 50);
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Download.BandwidthDiskBytesPerSecond",
(1000 * length / disk_write_time_ms), 1, 50000000, 50);
UMA_HISTOGRAM_COUNTS_100("Download.DiskBandwidthUsedPercentage",
disk_write_time_ms * 100 / elapsed_time_ms);
}
void RecordSavePackageEvent(SavePackageEvent event) {
UMA_HISTOGRAM_ENUMERATION("Download.SavePackage",
event,
SAVE_PACKAGE_LAST_ENTRY);
}
void RecordOriginStateOnResumption(bool is_partial,
int state) {
if (is_partial)
UMA_HISTOGRAM_ENUMERATION("Download.OriginStateOnPartialResumption", state,
ORIGIN_STATE_ON_RESUMPTION_MAX);
else
UMA_HISTOGRAM_ENUMERATION("Download.OriginStateOnFullResumption", state,
ORIGIN_STATE_ON_RESUMPTION_MAX);
}
}