[email protected] | 731809e | 2012-02-15 21:56:48 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/browser/download/download_stats.h" |
| 6 | |
| 7 | #include "base/metrics/histogram.h" |
[email protected] | 81c26ef | 2013-10-31 18:31:45 | [diff] [blame] | 8 | #include "base/metrics/sparse_histogram.h" |
[email protected] | 10994d13 | 2013-06-11 07:16:18 | [diff] [blame] | 9 | #include "base/strings/string_util.h" |
[email protected] | 8c4ef8d | 2011-11-02 17:09:32 | [diff] [blame] | 10 | #include "content/browser/download/download_resource_handler.h" |
[email protected] | bf3b08a | 2012-03-08 01:52:34 | [diff] [blame] | 11 | #include "content/public/browser/download_interrupt_reasons.h" |
[email protected] | a7206e7 | 2012-12-17 00:16:54 | [diff] [blame] | 12 | #include "net/http/http_content_disposition.h" |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 13 | |
[email protected] | 3586962 | 2012-10-26 23:23:55 | [diff] [blame] | 14 | namespace content { |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 15 | |
[email protected] | a7206e7 | 2012-12-17 00:16:54 | [diff] [blame] | 16 | namespace { |
| 17 | |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 18 | // All possible error codes from the network module. Note that the error codes |
| 19 | // are all positive (since histograms expect positive sample values). |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 20 | const int kAllInterruptReasonCodes[] = { |
| 21 | #define INTERRUPT_REASON(label, value) (value), |
[email protected] | bf3b08a | 2012-03-08 01:52:34 | [diff] [blame] | 22 | #include "content/public/browser/download_interrupt_reason_values.h" |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 23 | #undef INTERRUPT_REASON |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 24 | }; |
| 25 | |
[email protected] | a7206e7 | 2012-12-17 00:16:54 | [diff] [blame] | 26 | // These values are based on net::HttpContentDisposition::ParseResult values. |
| 27 | // Values other than HEADER_PRESENT and IS_VALID are only measured if |IS_VALID| |
| 28 | // is true. |
| 29 | enum ContentDispositionCountTypes { |
| 30 | // Count of downloads which had a Content-Disposition headers. The total |
| 31 | // number of downloads is measured by UNTHROTTLED_COUNT. |
| 32 | CONTENT_DISPOSITION_HEADER_PRESENT = 0, |
| 33 | |
| 34 | // At least one of 'name', 'filename' or 'filenae*' attributes were valid and |
| 35 | // yielded a non-empty filename. |
| 36 | CONTENT_DISPOSITION_IS_VALID, |
| 37 | |
| 38 | // The following enum values correspond to |
| 39 | // net::HttpContentDisposition::ParseResult. |
| 40 | CONTENT_DISPOSITION_HAS_DISPOSITION_TYPE, |
| 41 | CONTENT_DISPOSITION_HAS_UNKNOWN_TYPE, |
| 42 | CONTENT_DISPOSITION_HAS_NAME, |
| 43 | CONTENT_DISPOSITION_HAS_FILENAME, |
| 44 | CONTENT_DISPOSITION_HAS_EXT_FILENAME, |
| 45 | CONTENT_DISPOSITION_HAS_NON_ASCII_STRINGS, |
| 46 | CONTENT_DISPOSITION_HAS_PERCENT_ENCODED_STRINGS, |
| 47 | CONTENT_DISPOSITION_HAS_RFC2047_ENCODED_STRINGS, |
| 48 | |
| 49 | // Only have the 'name' attribute is present. |
| 50 | CONTENT_DISPOSITION_HAS_NAME_ONLY, |
| 51 | |
| 52 | CONTENT_DISPOSITION_LAST_ENTRY |
| 53 | }; |
| 54 | |
| 55 | void RecordContentDispositionCount(ContentDispositionCountTypes type, |
| 56 | bool record) { |
| 57 | if (!record) |
| 58 | return; |
| 59 | UMA_HISTOGRAM_ENUMERATION( |
| 60 | "Download.ContentDisposition", type, CONTENT_DISPOSITION_LAST_ENTRY); |
| 61 | } |
| 62 | |
| 63 | void RecordContentDispositionCountFlag( |
| 64 | ContentDispositionCountTypes type, |
| 65 | int flags_to_test, |
| 66 | net::HttpContentDisposition::ParseResultFlags flag) { |
| 67 | RecordContentDispositionCount(type, (flags_to_test & flag) == flag); |
| 68 | } |
| 69 | |
[email protected] | 81c26ef | 2013-10-31 18:31:45 | [diff] [blame] | 70 | // Do not insert, delete, or reorder; this is being histogrammed. Append only. |
| 71 | // All of the download_extensions.cc file types should be in this list. |
| 72 | const base::FilePath::CharType* kDangerousFileTypes[] = { |
| 73 | FILE_PATH_LITERAL(".ad"), |
| 74 | FILE_PATH_LITERAL(".ade"), |
| 75 | FILE_PATH_LITERAL(".adp"), |
| 76 | FILE_PATH_LITERAL(".ah"), |
| 77 | FILE_PATH_LITERAL(".apk"), |
| 78 | FILE_PATH_LITERAL(".app"), |
| 79 | FILE_PATH_LITERAL(".application"), |
| 80 | FILE_PATH_LITERAL(".asp"), |
| 81 | FILE_PATH_LITERAL(".asx"), |
| 82 | FILE_PATH_LITERAL(".bas"), |
| 83 | FILE_PATH_LITERAL(".bash"), |
| 84 | FILE_PATH_LITERAL(".bat"), |
| 85 | FILE_PATH_LITERAL(".cfg"), |
| 86 | FILE_PATH_LITERAL(".chi"), |
| 87 | FILE_PATH_LITERAL(".chm"), |
| 88 | FILE_PATH_LITERAL(".class"), |
| 89 | FILE_PATH_LITERAL(".cmd"), |
| 90 | FILE_PATH_LITERAL(".com"), |
| 91 | FILE_PATH_LITERAL(".command"), |
| 92 | FILE_PATH_LITERAL(".crt"), |
| 93 | FILE_PATH_LITERAL(".crx"), |
| 94 | FILE_PATH_LITERAL(".csh"), |
| 95 | FILE_PATH_LITERAL(".deb"), |
| 96 | FILE_PATH_LITERAL(".dex"), |
| 97 | FILE_PATH_LITERAL(".dll"), |
| 98 | FILE_PATH_LITERAL(".drv"), |
| 99 | FILE_PATH_LITERAL(".exe"), |
| 100 | FILE_PATH_LITERAL(".fxp"), |
| 101 | FILE_PATH_LITERAL(".grp"), |
| 102 | FILE_PATH_LITERAL(".hlp"), |
| 103 | FILE_PATH_LITERAL(".hta"), |
| 104 | FILE_PATH_LITERAL(".htm"), |
| 105 | FILE_PATH_LITERAL(".html"), |
| 106 | FILE_PATH_LITERAL(".htt"), |
| 107 | FILE_PATH_LITERAL(".inf"), |
| 108 | FILE_PATH_LITERAL(".ini"), |
| 109 | FILE_PATH_LITERAL(".ins"), |
| 110 | FILE_PATH_LITERAL(".isp"), |
| 111 | FILE_PATH_LITERAL(".jar"), |
| 112 | FILE_PATH_LITERAL(".jnlp"), |
| 113 | FILE_PATH_LITERAL(".user.js"), |
| 114 | FILE_PATH_LITERAL(".js"), |
| 115 | FILE_PATH_LITERAL(".jse"), |
| 116 | FILE_PATH_LITERAL(".ksh"), |
| 117 | FILE_PATH_LITERAL(".lnk"), |
| 118 | FILE_PATH_LITERAL(".local"), |
| 119 | FILE_PATH_LITERAL(".mad"), |
| 120 | FILE_PATH_LITERAL(".maf"), |
| 121 | FILE_PATH_LITERAL(".mag"), |
| 122 | FILE_PATH_LITERAL(".mam"), |
| 123 | FILE_PATH_LITERAL(".manifest"), |
| 124 | FILE_PATH_LITERAL(".maq"), |
| 125 | FILE_PATH_LITERAL(".mar"), |
| 126 | FILE_PATH_LITERAL(".mas"), |
| 127 | FILE_PATH_LITERAL(".mat"), |
| 128 | FILE_PATH_LITERAL(".mau"), |
| 129 | FILE_PATH_LITERAL(".mav"), |
| 130 | FILE_PATH_LITERAL(".maw"), |
| 131 | FILE_PATH_LITERAL(".mda"), |
| 132 | FILE_PATH_LITERAL(".mdb"), |
| 133 | FILE_PATH_LITERAL(".mde"), |
| 134 | FILE_PATH_LITERAL(".mdt"), |
| 135 | FILE_PATH_LITERAL(".mdw"), |
| 136 | FILE_PATH_LITERAL(".mdz"), |
| 137 | FILE_PATH_LITERAL(".mht"), |
| 138 | FILE_PATH_LITERAL(".mhtml"), |
| 139 | FILE_PATH_LITERAL(".mmc"), |
| 140 | FILE_PATH_LITERAL(".mof"), |
| 141 | FILE_PATH_LITERAL(".msc"), |
| 142 | FILE_PATH_LITERAL(".msh"), |
| 143 | FILE_PATH_LITERAL(".mshxml"), |
| 144 | FILE_PATH_LITERAL(".msi"), |
| 145 | FILE_PATH_LITERAL(".msp"), |
| 146 | FILE_PATH_LITERAL(".mst"), |
| 147 | FILE_PATH_LITERAL(".ocx"), |
| 148 | FILE_PATH_LITERAL(".ops"), |
| 149 | FILE_PATH_LITERAL(".pcd"), |
| 150 | FILE_PATH_LITERAL(".pif"), |
| 151 | FILE_PATH_LITERAL(".pkg"), |
| 152 | FILE_PATH_LITERAL(".pl"), |
| 153 | FILE_PATH_LITERAL(".plg"), |
| 154 | FILE_PATH_LITERAL(".prf"), |
| 155 | FILE_PATH_LITERAL(".prg"), |
| 156 | FILE_PATH_LITERAL(".pst"), |
| 157 | FILE_PATH_LITERAL(".py"), |
| 158 | FILE_PATH_LITERAL(".pyc"), |
| 159 | FILE_PATH_LITERAL(".pyw"), |
| 160 | FILE_PATH_LITERAL(".rb"), |
| 161 | FILE_PATH_LITERAL(".reg"), |
| 162 | FILE_PATH_LITERAL(".rpm"), |
| 163 | FILE_PATH_LITERAL(".scf"), |
| 164 | FILE_PATH_LITERAL(".scr"), |
| 165 | FILE_PATH_LITERAL(".sct"), |
| 166 | FILE_PATH_LITERAL(".sh"), |
| 167 | FILE_PATH_LITERAL(".shar"), |
| 168 | FILE_PATH_LITERAL(".shb"), |
| 169 | FILE_PATH_LITERAL(".shs"), |
| 170 | FILE_PATH_LITERAL(".shtm"), |
| 171 | FILE_PATH_LITERAL(".shtml"), |
| 172 | FILE_PATH_LITERAL(".spl"), |
| 173 | FILE_PATH_LITERAL(".svg"), |
| 174 | FILE_PATH_LITERAL(".swf"), |
| 175 | FILE_PATH_LITERAL(".sys"), |
| 176 | FILE_PATH_LITERAL(".tcsh"), |
| 177 | FILE_PATH_LITERAL(".url"), |
| 178 | FILE_PATH_LITERAL(".vb"), |
| 179 | FILE_PATH_LITERAL(".vbe"), |
| 180 | FILE_PATH_LITERAL(".vbs"), |
| 181 | FILE_PATH_LITERAL(".vsd"), |
| 182 | FILE_PATH_LITERAL(".vsmacros"), |
| 183 | FILE_PATH_LITERAL(".vss"), |
| 184 | FILE_PATH_LITERAL(".vst"), |
| 185 | FILE_PATH_LITERAL(".vsw"), |
| 186 | FILE_PATH_LITERAL(".ws"), |
| 187 | FILE_PATH_LITERAL(".wsc"), |
| 188 | FILE_PATH_LITERAL(".wsf"), |
| 189 | FILE_PATH_LITERAL(".wsh"), |
| 190 | FILE_PATH_LITERAL(".xbap"), |
| 191 | FILE_PATH_LITERAL(".xht"), |
| 192 | FILE_PATH_LITERAL(".xhtm"), |
| 193 | FILE_PATH_LITERAL(".xhtml"), |
| 194 | FILE_PATH_LITERAL(".xml"), |
| 195 | FILE_PATH_LITERAL(".xsl"), |
| 196 | FILE_PATH_LITERAL(".xslt") |
| 197 | }; |
| 198 | |
| 199 | // Maps extensions to their matching UMA histogram int value. |
| 200 | int GetDangerousFileType(const base::FilePath& file_path) { |
| 201 | for (size_t i = 0; i < arraysize(kDangerousFileTypes); ++i) { |
| 202 | if (file_path.MatchesExtension(kDangerousFileTypes[i])) |
| 203 | return i + 1; |
| 204 | } |
| 205 | return 0; // Unknown extension. |
| 206 | } |
| 207 | |
[email protected] | a7206e7 | 2012-12-17 00:16:54 | [diff] [blame] | 208 | } // namespace |
| 209 | |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 210 | void RecordDownloadCount(DownloadCountTypes type) { |
| 211 | UMA_HISTOGRAM_ENUMERATION( |
| 212 | "Download.Counts", type, DOWNLOAD_COUNT_TYPES_LAST_ENTRY); |
| 213 | } |
| 214 | |
[email protected] | 731809e | 2012-02-15 21:56:48 | [diff] [blame] | 215 | void RecordDownloadSource(DownloadSource source) { |
| 216 | UMA_HISTOGRAM_ENUMERATION( |
| 217 | "Download.Sources", source, DOWNLOAD_SOURCE_LAST_ENTRY); |
| 218 | } |
| 219 | |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 220 | void RecordDownloadCompleted(const base::TimeTicks& start, int64 download_len) { |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 221 | RecordDownloadCount(COMPLETED_COUNT); |
| 222 | UMA_HISTOGRAM_LONG_TIMES("Download.Time", (base::TimeTicks::Now() - start)); |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 223 | int64 max = 1024 * 1024 * 1024; // One Terabyte. |
| 224 | download_len /= 1024; // In Kilobytes |
| 225 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.DownloadSize", |
| 226 | download_len, |
| 227 | 1, |
| 228 | max, |
| 229 | 256); |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 230 | } |
| 231 | |
[email protected] | 3586962 | 2012-10-26 23:23:55 | [diff] [blame] | 232 | void RecordDownloadInterrupted(DownloadInterruptReason reason, |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 233 | int64 received, |
| 234 | int64 total) { |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 235 | RecordDownloadCount(INTERRUPTED_COUNT); |
| 236 | UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 237 | "Download.InterruptedReason", |
| 238 | reason, |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 239 | base::CustomHistogram::ArrayToCustomRanges( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 240 | kAllInterruptReasonCodes, arraysize(kAllInterruptReasonCodes))); |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 241 | |
| 242 | // The maximum should be 2^kBuckets, to have the logarithmic bucket |
| 243 | // boundaries fall on powers of 2. |
| 244 | static const int kBuckets = 30; |
| 245 | static const int64 kMaxKb = 1 << kBuckets; // One Terabyte, in Kilobytes. |
| 246 | int64 delta_bytes = total - received; |
| 247 | bool unknown_size = total <= 0; |
| 248 | int64 received_kb = received / 1024; |
| 249 | int64 total_kb = total / 1024; |
| 250 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedReceivedSizeK", |
| 251 | received_kb, |
| 252 | 1, |
| 253 | kMaxKb, |
| 254 | kBuckets); |
| 255 | if (!unknown_size) { |
| 256 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedTotalSizeK", |
| 257 | total_kb, |
| 258 | 1, |
| 259 | kMaxKb, |
| 260 | kBuckets); |
[email protected] | f39c99a | 2011-09-21 23:14:50 | [diff] [blame] | 261 | if (delta_bytes == 0) { |
| 262 | RecordDownloadCount(INTERRUPTED_AT_END_COUNT); |
| 263 | UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 264 | "Download.InterruptedAtEndReason", |
| 265 | reason, |
[email protected] | f39c99a | 2011-09-21 23:14:50 | [diff] [blame] | 266 | base::CustomHistogram::ArrayToCustomRanges( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 267 | kAllInterruptReasonCodes, |
| 268 | arraysize(kAllInterruptReasonCodes))); |
[email protected] | f39c99a | 2011-09-21 23:14:50 | [diff] [blame] | 269 | } else if (delta_bytes > 0) { |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 270 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedOverrunBytes", |
| 271 | delta_bytes, |
| 272 | 1, |
| 273 | kMaxKb, |
| 274 | kBuckets); |
| 275 | } else { |
| 276 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedUnderrunBytes", |
| 277 | -delta_bytes, |
| 278 | 1, |
| 279 | kMaxKb, |
| 280 | kBuckets); |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | UMA_HISTOGRAM_BOOLEAN("Download.InterruptedUnknownSize", unknown_size); |
| 285 | } |
| 286 | |
[email protected] | 7aea00e | 2014-01-14 18:20:11 | [diff] [blame] | 287 | void RecordMaliciousDownloadClassified(DownloadDangerType danger_type) { |
| 288 | UMA_HISTOGRAM_ENUMERATION("Download.MaliciousDownloadClassified", |
| 289 | danger_type, |
| 290 | DOWNLOAD_DANGER_TYPE_MAX); |
| 291 | } |
| 292 | |
[email protected] | 81c26ef | 2013-10-31 18:31:45 | [diff] [blame] | 293 | void RecordDangerousDownloadAccept(DownloadDangerType danger_type, |
| 294 | const base::FilePath& file_path) { |
[email protected] | fe75227 | 2013-05-29 18:57:45 | [diff] [blame] | 295 | UMA_HISTOGRAM_ENUMERATION("Download.DangerousDownloadValidated", |
| 296 | danger_type, |
| 297 | DOWNLOAD_DANGER_TYPE_MAX); |
[email protected] | 81c26ef | 2013-10-31 18:31:45 | [diff] [blame] | 298 | if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) { |
| 299 | UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 300 | "Download.DangerousFile.DangerousDownloadValidated", |
| 301 | GetDangerousFileType(file_path)); |
| 302 | } |
[email protected] | fe75227 | 2013-05-29 18:57:45 | [diff] [blame] | 303 | } |
| 304 | |
| 305 | void RecordDangerousDownloadDiscard(DownloadDiscardReason reason, |
[email protected] | 81c26ef | 2013-10-31 18:31:45 | [diff] [blame] | 306 | DownloadDangerType danger_type, |
| 307 | const base::FilePath& file_path) { |
[email protected] | fe75227 | 2013-05-29 18:57:45 | [diff] [blame] | 308 | switch (reason) { |
| 309 | case DOWNLOAD_DISCARD_DUE_TO_USER_ACTION: |
| 310 | UMA_HISTOGRAM_ENUMERATION( |
| 311 | "Download.UserDiscard", danger_type, DOWNLOAD_DANGER_TYPE_MAX); |
[email protected] | 81c26ef | 2013-10-31 18:31:45 | [diff] [blame] | 312 | if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) { |
| 313 | UMA_HISTOGRAM_SPARSE_SLOWLY("Download.DangerousFile.UserDiscard", |
| 314 | GetDangerousFileType(file_path)); |
| 315 | } |
[email protected] | fe75227 | 2013-05-29 18:57:45 | [diff] [blame] | 316 | break; |
| 317 | case DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN: |
| 318 | UMA_HISTOGRAM_ENUMERATION( |
| 319 | "Download.Discard", danger_type, DOWNLOAD_DANGER_TYPE_MAX); |
[email protected] | 81c26ef | 2013-10-31 18:31:45 | [diff] [blame] | 320 | if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) { |
| 321 | UMA_HISTOGRAM_SPARSE_SLOWLY("Download.DangerousFile.Discard", |
| 322 | GetDangerousFileType(file_path)); |
| 323 | } |
[email protected] | d6d19f3e | 2014-01-16 06:40:38 | [diff] [blame] | 324 | break; |
[email protected] | fe75227 | 2013-05-29 18:57:45 | [diff] [blame] | 325 | default: |
| 326 | NOTREACHED(); |
| 327 | } |
| 328 | } |
| 329 | |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 330 | void RecordDownloadWriteSize(size_t data_len) { |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 331 | int max = 1024 * 1024; // One Megabyte. |
| 332 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.WriteSize", data_len, 1, max, 256); |
| 333 | } |
| 334 | |
| 335 | void RecordDownloadWriteLoopCount(int count) { |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 336 | UMA_HISTOGRAM_ENUMERATION("Download.WriteLoopCount", count, 20); |
| 337 | } |
| 338 | |
[email protected] | c2db5bf | 2011-11-29 00:29:16 | [diff] [blame] | 339 | void RecordAcceptsRanges(const std::string& accepts_ranges, |
[email protected] | 11325a2 | 2013-07-30 23:02:26 | [diff] [blame] | 340 | int64 download_len, |
[email protected] | 9e997d1 | 2013-11-22 21:11:28 | [diff] [blame] | 341 | bool has_strong_validator) { |
[email protected] | c2db5bf | 2011-11-29 00:29:16 | [diff] [blame] | 342 | int64 max = 1024 * 1024 * 1024; // One Terabyte. |
| 343 | download_len /= 1024; // In Kilobytes |
| 344 | static const int kBuckets = 50; |
| 345 | |
[email protected] | df80704 | 2014-08-13 16:48:41 | [diff] [blame] | 346 | if (LowerCaseEqualsASCII(accepts_ranges, "none")) { |
[email protected] | c7deb56 | 2011-11-30 21:59:07 | [diff] [blame] | 347 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.AcceptRangesNone.KBytes", |
[email protected] | c2db5bf | 2011-11-29 00:29:16 | [diff] [blame] | 348 | download_len, |
| 349 | 1, |
| 350 | max, |
| 351 | kBuckets); |
[email protected] | df80704 | 2014-08-13 16:48:41 | [diff] [blame] | 352 | } else if (LowerCaseEqualsASCII(accepts_ranges, "bytes")) { |
[email protected] | c7deb56 | 2011-11-30 21:59:07 | [diff] [blame] | 353 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.AcceptRangesBytes.KBytes", |
[email protected] | c2db5bf | 2011-11-29 00:29:16 | [diff] [blame] | 354 | download_len, |
| 355 | 1, |
| 356 | max, |
| 357 | kBuckets); |
[email protected] | 9e997d1 | 2013-11-22 21:11:28 | [diff] [blame] | 358 | if (has_strong_validator) |
| 359 | RecordDownloadCount(STRONG_VALIDATOR_AND_ACCEPTS_RANGES); |
[email protected] | c2db5bf | 2011-11-29 00:29:16 | [diff] [blame] | 360 | } else { |
[email protected] | c7deb56 | 2011-11-30 21:59:07 | [diff] [blame] | 361 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.AcceptRangesMissingOrInvalid.KBytes", |
[email protected] | c2db5bf | 2011-11-29 00:29:16 | [diff] [blame] | 362 | download_len, |
| 363 | 1, |
| 364 | max, |
| 365 | kBuckets); |
| 366 | } |
| 367 | } |
| 368 | |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 369 | namespace { |
| 370 | |
| 371 | enum DownloadContent { |
| 372 | DOWNLOAD_CONTENT_UNRECOGNIZED = 0, |
| 373 | DOWNLOAD_CONTENT_TEXT = 1, |
| 374 | DOWNLOAD_CONTENT_IMAGE = 2, |
| 375 | DOWNLOAD_CONTENT_AUDIO = 3, |
| 376 | DOWNLOAD_CONTENT_VIDEO = 4, |
| 377 | DOWNLOAD_CONTENT_OCTET_STREAM = 5, |
| 378 | DOWNLOAD_CONTENT_PDF = 6, |
| 379 | DOWNLOAD_CONTENT_DOC = 7, |
| 380 | DOWNLOAD_CONTENT_XLS = 8, |
| 381 | DOWNLOAD_CONTENT_PPT = 9, |
| 382 | DOWNLOAD_CONTENT_ARCHIVE = 10, |
| 383 | DOWNLOAD_CONTENT_EXE = 11, |
| 384 | DOWNLOAD_CONTENT_DMG = 12, |
| 385 | DOWNLOAD_CONTENT_CRX = 13, |
| 386 | DOWNLOAD_CONTENT_MAX = 14, |
| 387 | }; |
| 388 | |
| 389 | struct MimeTypeToDownloadContent { |
| 390 | const char* mime_type; |
| 391 | DownloadContent download_content; |
| 392 | }; |
| 393 | |
| 394 | static MimeTypeToDownloadContent kMapMimeTypeToDownloadContent[] = { |
| 395 | {"application/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM}, |
| 396 | {"binary/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM}, |
| 397 | {"application/pdf", DOWNLOAD_CONTENT_PDF}, |
| 398 | {"application/msword", DOWNLOAD_CONTENT_DOC}, |
| 399 | {"application/vnd.ms-excel", DOWNLOAD_CONTENT_XLS}, |
| 400 | {"application/vns.ms-powerpoint", DOWNLOAD_CONTENT_PPT}, |
| 401 | {"application/zip", DOWNLOAD_CONTENT_ARCHIVE}, |
| 402 | {"application/x-gzip", DOWNLOAD_CONTENT_ARCHIVE}, |
| 403 | {"application/x-rar-compressed", DOWNLOAD_CONTENT_ARCHIVE}, |
| 404 | {"application/x-tar", DOWNLOAD_CONTENT_ARCHIVE}, |
| 405 | {"application/x-bzip", DOWNLOAD_CONTENT_ARCHIVE}, |
| 406 | {"application/x-exe", DOWNLOAD_CONTENT_EXE}, |
| 407 | {"application/x-apple-diskimage", DOWNLOAD_CONTENT_DMG}, |
| 408 | {"application/x-chrome-extension", DOWNLOAD_CONTENT_CRX}, |
| 409 | }; |
| 410 | |
[email protected] | 88cb7aae | 2011-12-02 16:10:32 | [diff] [blame] | 411 | enum DownloadImage { |
| 412 | DOWNLOAD_IMAGE_UNRECOGNIZED = 0, |
| 413 | DOWNLOAD_IMAGE_GIF = 1, |
| 414 | DOWNLOAD_IMAGE_JPEG = 2, |
| 415 | DOWNLOAD_IMAGE_PNG = 3, |
| 416 | DOWNLOAD_IMAGE_TIFF = 4, |
| 417 | DOWNLOAD_IMAGE_ICON = 5, |
| 418 | DOWNLOAD_IMAGE_WEBP = 6, |
| 419 | DOWNLOAD_IMAGE_MAX = 7, |
| 420 | }; |
| 421 | |
| 422 | struct MimeTypeToDownloadImage { |
| 423 | const char* mime_type; |
| 424 | DownloadImage download_image; |
| 425 | }; |
| 426 | |
| 427 | static MimeTypeToDownloadImage kMapMimeTypeToDownloadImage[] = { |
| 428 | {"image/gif", DOWNLOAD_IMAGE_GIF}, |
| 429 | {"image/jpeg", DOWNLOAD_IMAGE_JPEG}, |
| 430 | {"image/png", DOWNLOAD_IMAGE_PNG}, |
| 431 | {"image/tiff", DOWNLOAD_IMAGE_TIFF}, |
| 432 | {"image/vnd.microsoft.icon", DOWNLOAD_IMAGE_ICON}, |
| 433 | {"image/webp", DOWNLOAD_IMAGE_WEBP}, |
| 434 | }; |
| 435 | |
| 436 | void RecordDownloadImageType(const std::string& mime_type_string) { |
| 437 | DownloadImage download_image = DOWNLOAD_IMAGE_UNRECOGNIZED; |
| 438 | |
| 439 | // Look up exact matches. |
| 440 | for (size_t i = 0; i < arraysize(kMapMimeTypeToDownloadImage); ++i) { |
| 441 | const MimeTypeToDownloadImage& entry = kMapMimeTypeToDownloadImage[i]; |
| 442 | if (mime_type_string == entry.mime_type) { |
| 443 | download_image = entry.download_image; |
| 444 | break; |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | UMA_HISTOGRAM_ENUMERATION("Download.ContentImageType", |
| 449 | download_image, |
| 450 | DOWNLOAD_IMAGE_MAX); |
| 451 | } |
| 452 | |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 453 | } // namespace |
| 454 | |
| 455 | void RecordDownloadMimeType(const std::string& mime_type_string) { |
| 456 | DownloadContent download_content = DOWNLOAD_CONTENT_UNRECOGNIZED; |
| 457 | |
| 458 | // Look up exact matches. |
| 459 | for (size_t i = 0; i < arraysize(kMapMimeTypeToDownloadContent); ++i) { |
[email protected] | 88cb7aae | 2011-12-02 16:10:32 | [diff] [blame] | 460 | const MimeTypeToDownloadContent& entry = kMapMimeTypeToDownloadContent[i]; |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 461 | if (mime_type_string == entry.mime_type) { |
| 462 | download_content = entry.download_content; |
| 463 | break; |
| 464 | } |
| 465 | } |
| 466 | |
| 467 | // Do partial matches. |
| 468 | if (download_content == DOWNLOAD_CONTENT_UNRECOGNIZED) { |
| 469 | if (StartsWithASCII(mime_type_string, "text/", true)) { |
| 470 | download_content = DOWNLOAD_CONTENT_TEXT; |
| 471 | } else if (StartsWithASCII(mime_type_string, "image/", true)) { |
| 472 | download_content = DOWNLOAD_CONTENT_IMAGE; |
[email protected] | 88cb7aae | 2011-12-02 16:10:32 | [diff] [blame] | 473 | RecordDownloadImageType(mime_type_string); |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 474 | } else if (StartsWithASCII(mime_type_string, "audio/", true)) { |
| 475 | download_content = DOWNLOAD_CONTENT_AUDIO; |
| 476 | } else if (StartsWithASCII(mime_type_string, "video/", true)) { |
| 477 | download_content = DOWNLOAD_CONTENT_VIDEO; |
| 478 | } |
| 479 | } |
| 480 | |
| 481 | // Record the value. |
| 482 | UMA_HISTOGRAM_ENUMERATION("Download.ContentType", |
| 483 | download_content, |
| 484 | DOWNLOAD_CONTENT_MAX); |
| 485 | } |
| 486 | |
[email protected] | a7206e7 | 2012-12-17 00:16:54 | [diff] [blame] | 487 | void RecordDownloadContentDisposition( |
| 488 | const std::string& content_disposition_string) { |
| 489 | if (content_disposition_string.empty()) |
| 490 | return; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 491 | net::HttpContentDisposition content_disposition(content_disposition_string, |
| 492 | std::string()); |
[email protected] | a7206e7 | 2012-12-17 00:16:54 | [diff] [blame] | 493 | int result = content_disposition.parse_result_flags(); |
| 494 | |
| 495 | bool is_valid = !content_disposition.filename().empty(); |
| 496 | RecordContentDispositionCount(CONTENT_DISPOSITION_HEADER_PRESENT, true); |
| 497 | RecordContentDispositionCount(CONTENT_DISPOSITION_IS_VALID, is_valid); |
| 498 | if (!is_valid) |
| 499 | return; |
| 500 | |
| 501 | RecordContentDispositionCountFlag( |
| 502 | CONTENT_DISPOSITION_HAS_DISPOSITION_TYPE, result, |
| 503 | net::HttpContentDisposition::HAS_DISPOSITION_TYPE); |
| 504 | RecordContentDispositionCountFlag( |
| 505 | CONTENT_DISPOSITION_HAS_UNKNOWN_TYPE, result, |
| 506 | net::HttpContentDisposition::HAS_UNKNOWN_DISPOSITION_TYPE); |
| 507 | RecordContentDispositionCountFlag( |
| 508 | CONTENT_DISPOSITION_HAS_NAME, result, |
| 509 | net::HttpContentDisposition::HAS_NAME); |
| 510 | RecordContentDispositionCountFlag( |
| 511 | CONTENT_DISPOSITION_HAS_FILENAME, result, |
| 512 | net::HttpContentDisposition::HAS_FILENAME); |
| 513 | RecordContentDispositionCountFlag( |
| 514 | CONTENT_DISPOSITION_HAS_EXT_FILENAME, result, |
| 515 | net::HttpContentDisposition::HAS_EXT_FILENAME); |
| 516 | RecordContentDispositionCountFlag( |
| 517 | CONTENT_DISPOSITION_HAS_NON_ASCII_STRINGS, result, |
| 518 | net::HttpContentDisposition::HAS_NON_ASCII_STRINGS); |
| 519 | RecordContentDispositionCountFlag( |
| 520 | CONTENT_DISPOSITION_HAS_PERCENT_ENCODED_STRINGS, result, |
| 521 | net::HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS); |
| 522 | RecordContentDispositionCountFlag( |
| 523 | CONTENT_DISPOSITION_HAS_RFC2047_ENCODED_STRINGS, result, |
| 524 | net::HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS); |
| 525 | |
| 526 | RecordContentDispositionCount( |
| 527 | CONTENT_DISPOSITION_HAS_NAME_ONLY, |
| 528 | (result & (net::HttpContentDisposition::HAS_NAME | |
| 529 | net::HttpContentDisposition::HAS_FILENAME | |
| 530 | net::HttpContentDisposition::HAS_EXT_FILENAME)) == |
| 531 | net::HttpContentDisposition::HAS_NAME); |
| 532 | } |
| 533 | |
[email protected] | 8c4ef8d | 2011-11-02 17:09:32 | [diff] [blame] | 534 | void RecordFileThreadReceiveBuffers(size_t num_buffers) { |
| 535 | UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 536 | "Download.FileThreadReceiveBuffers", num_buffers, 1, |
[email protected] | d7db4f62 | 2012-06-04 18:20:56 | [diff] [blame] | 537 | 100, 100); |
[email protected] | 8c4ef8d | 2011-11-02 17:09:32 | [diff] [blame] | 538 | } |
| 539 | |
| 540 | void RecordBandwidth(double actual_bandwidth, double potential_bandwidth) { |
| 541 | UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 542 | "Download.ActualBandwidth", actual_bandwidth, 1, 1000000000, 50); |
| 543 | UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 544 | "Download.PotentialBandwidth", potential_bandwidth, 1, 1000000000, 50); |
| 545 | UMA_HISTOGRAM_PERCENTAGE( |
| 546 | "Download.BandwidthUsed", |
| 547 | (int) ((actual_bandwidth * 100)/ potential_bandwidth)); |
| 548 | } |
| 549 | |
[email protected] | da4a558 | 2011-10-17 19:08:06 | [diff] [blame] | 550 | void RecordOpen(const base::Time& end, bool first) { |
| 551 | if (!end.is_null()) { |
| 552 | UMA_HISTOGRAM_LONG_TIMES("Download.OpenTime", (base::Time::Now() - end)); |
| 553 | if (first) { |
| 554 | UMA_HISTOGRAM_LONG_TIMES("Download.FirstOpenTime", |
| 555 | (base::Time::Now() - end)); |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | |
[email protected] | da4a558 | 2011-10-17 19:08:06 | [diff] [blame] | 560 | void RecordClearAllSize(int size) { |
| 561 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.ClearAllSize", |
| 562 | size, |
| 563 | 0/*min*/, |
| 564 | (1 << 10)/*max*/, |
| 565 | 32/*num_buckets*/); |
| 566 | } |
| 567 | |
| 568 | void RecordOpensOutstanding(int size) { |
| 569 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.OpensOutstanding", |
| 570 | size, |
| 571 | 0/*min*/, |
| 572 | (1 << 10)/*max*/, |
| 573 | 64/*num_buckets*/); |
| 574 | } |
| 575 | |
[email protected] | d7db4f62 | 2012-06-04 18:20:56 | [diff] [blame] | 576 | void RecordContiguousWriteTime(base::TimeDelta time_blocked) { |
| 577 | UMA_HISTOGRAM_TIMES("Download.FileThreadBlockedTime", time_blocked); |
| 578 | } |
| 579 | |
[email protected] | c95d82d | 2012-07-03 16:53:28 | [diff] [blame] | 580 | // Record what percentage of the time we have the network flow controlled. |
| 581 | void RecordNetworkBlockage(base::TimeDelta resource_handler_lifetime, |
| 582 | base::TimeDelta resource_handler_blocked_time) { |
| 583 | int percentage = 0; |
| 584 | // Avoid division by zero errors. |
| 585 | if (resource_handler_blocked_time != base::TimeDelta()) { |
| 586 | percentage = |
| 587 | resource_handler_blocked_time * 100 / resource_handler_lifetime; |
| 588 | } |
[email protected] | d7db4f62 | 2012-06-04 18:20:56 | [diff] [blame] | 589 | |
[email protected] | c95d82d | 2012-07-03 16:53:28 | [diff] [blame] | 590 | UMA_HISTOGRAM_COUNTS_100("Download.ResourceHandlerBlockedPercentage", |
| 591 | percentage); |
[email protected] | d7db4f62 | 2012-06-04 18:20:56 | [diff] [blame] | 592 | } |
| 593 | |
| 594 | void RecordFileBandwidth(size_t length, |
| 595 | base::TimeDelta disk_write_time, |
| 596 | base::TimeDelta elapsed_time) { |
| 597 | size_t elapsed_time_ms = elapsed_time.InMilliseconds(); |
| 598 | if (0u == elapsed_time_ms) |
| 599 | elapsed_time_ms = 1; |
| 600 | size_t disk_write_time_ms = disk_write_time.InMilliseconds(); |
| 601 | if (0u == disk_write_time_ms) |
| 602 | disk_write_time_ms = 1; |
| 603 | |
| 604 | UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 605 | "Download.BandwidthOverallBytesPerSecond", |
| 606 | (1000 * length / elapsed_time_ms), 1, 50000000, 50); |
| 607 | UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 608 | "Download.BandwidthDiskBytesPerSecond", |
| 609 | (1000 * length / disk_write_time_ms), 1, 50000000, 50); |
[email protected] | c95d82d | 2012-07-03 16:53:28 | [diff] [blame] | 610 | UMA_HISTOGRAM_COUNTS_100("Download.DiskBandwidthUsedPercentage", |
| 611 | disk_write_time_ms * 100 / elapsed_time_ms); |
[email protected] | d7db4f62 | 2012-06-04 18:20:56 | [diff] [blame] | 612 | } |
| 613 | |
asanka | f4b6a28 | 2014-09-26 15:43:32 | [diff] [blame] | 614 | void RecordDownloadFileRenameResultAfterRetry( |
| 615 | base::TimeDelta time_since_first_failure, |
| 616 | DownloadInterruptReason interrupt_reason) { |
| 617 | if (interrupt_reason == DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 618 | UMA_HISTOGRAM_TIMES("Download.TimeToRenameSuccessAfterInitialFailure", |
| 619 | time_since_first_failure); |
| 620 | } else { |
| 621 | UMA_HISTOGRAM_TIMES("Download.TimeToRenameFailureAfterInitialFailure", |
| 622 | time_since_first_failure); |
| 623 | } |
| 624 | } |
| 625 | |
[email protected] | 48624098 | 2012-02-17 06:05:09 | [diff] [blame] | 626 | void RecordSavePackageEvent(SavePackageEvent event) { |
| 627 | UMA_HISTOGRAM_ENUMERATION("Download.SavePackage", |
| 628 | event, |
| 629 | SAVE_PACKAGE_LAST_ENTRY); |
| 630 | } |
| 631 | |
[email protected] | e87e583 | 2013-12-13 22:20:27 | [diff] [blame] | 632 | void RecordOriginStateOnResumption(bool is_partial, |
| 633 | int state) { |
| 634 | if (is_partial) |
| 635 | UMA_HISTOGRAM_ENUMERATION("Download.OriginStateOnPartialResumption", state, |
| 636 | ORIGIN_STATE_ON_RESUMPTION_MAX); |
| 637 | else |
| 638 | UMA_HISTOGRAM_ENUMERATION("Download.OriginStateOnFullResumption", state, |
| 639 | ORIGIN_STATE_ON_RESUMPTION_MAX); |
| 640 | } |
| 641 | |
[email protected] | 3586962 | 2012-10-26 23:23:55 | [diff] [blame] | 642 | } // namespace content |