[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 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" |
| 8 | #include "base/string_util.h" |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 9 | #include "content/browser/download/interrupt_reasons.h" |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 10 | |
| 11 | namespace download_stats { |
| 12 | |
| 13 | // All possible error codes from the network module. Note that the error codes |
| 14 | // are all positive (since histograms expect positive sample values). |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 15 | const int kAllInterruptReasonCodes[] = { |
| 16 | #define INTERRUPT_REASON(label, value) (value), |
| 17 | #include "content/browser/download/interrupt_reason_values.h" |
| 18 | #undef INTERRUPT_REASON |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 19 | }; |
| 20 | |
| 21 | void RecordDownloadCount(DownloadCountTypes type) { |
| 22 | UMA_HISTOGRAM_ENUMERATION( |
| 23 | "Download.Counts", type, DOWNLOAD_COUNT_TYPES_LAST_ENTRY); |
| 24 | } |
| 25 | |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 26 | void RecordDownloadCompleted(const base::TimeTicks& start, int64 download_len) { |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 27 | RecordDownloadCount(COMPLETED_COUNT); |
| 28 | UMA_HISTOGRAM_LONG_TIMES("Download.Time", (base::TimeTicks::Now() - start)); |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 29 | int64 max = 1024 * 1024 * 1024; // One Terabyte. |
| 30 | download_len /= 1024; // In Kilobytes |
| 31 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.DownloadSize", |
| 32 | download_len, |
| 33 | 1, |
| 34 | max, |
| 35 | 256); |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 36 | } |
| 37 | |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 38 | void RecordDownloadInterrupted(InterruptReason reason, |
| 39 | int64 received, |
| 40 | int64 total) { |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 41 | RecordDownloadCount(INTERRUPTED_COUNT); |
| 42 | UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 43 | "Download.InterruptedReason", |
| 44 | reason, |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 45 | base::CustomHistogram::ArrayToCustomRanges( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 46 | kAllInterruptReasonCodes, arraysize(kAllInterruptReasonCodes))); |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 47 | |
| 48 | // The maximum should be 2^kBuckets, to have the logarithmic bucket |
| 49 | // boundaries fall on powers of 2. |
| 50 | static const int kBuckets = 30; |
| 51 | static const int64 kMaxKb = 1 << kBuckets; // One Terabyte, in Kilobytes. |
| 52 | int64 delta_bytes = total - received; |
| 53 | bool unknown_size = total <= 0; |
| 54 | int64 received_kb = received / 1024; |
| 55 | int64 total_kb = total / 1024; |
| 56 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedReceivedSizeK", |
| 57 | received_kb, |
| 58 | 1, |
| 59 | kMaxKb, |
| 60 | kBuckets); |
| 61 | if (!unknown_size) { |
| 62 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedTotalSizeK", |
| 63 | total_kb, |
| 64 | 1, |
| 65 | kMaxKb, |
| 66 | kBuckets); |
[email protected] | f39c99a | 2011-09-21 23:14:50 | [diff] [blame] | 67 | if (delta_bytes == 0) { |
| 68 | RecordDownloadCount(INTERRUPTED_AT_END_COUNT); |
| 69 | UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 70 | "Download.InterruptedAtEndReason", |
| 71 | reason, |
[email protected] | f39c99a | 2011-09-21 23:14:50 | [diff] [blame] | 72 | base::CustomHistogram::ArrayToCustomRanges( |
[email protected] | be76b7e | 2011-10-13 12:57:57 | [diff] [blame] | 73 | kAllInterruptReasonCodes, |
| 74 | arraysize(kAllInterruptReasonCodes))); |
[email protected] | f39c99a | 2011-09-21 23:14:50 | [diff] [blame] | 75 | } else if (delta_bytes > 0) { |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 76 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedOverrunBytes", |
| 77 | delta_bytes, |
| 78 | 1, |
| 79 | kMaxKb, |
| 80 | kBuckets); |
| 81 | } else { |
| 82 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedUnderrunBytes", |
| 83 | -delta_bytes, |
| 84 | 1, |
| 85 | kMaxKb, |
| 86 | kBuckets); |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | UMA_HISTOGRAM_BOOLEAN("Download.InterruptedUnknownSize", unknown_size); |
| 91 | } |
| 92 | |
[email protected] | 4615795e | 2011-09-07 19:45:21 | [diff] [blame] | 93 | void RecordDownloadWriteSize(size_t data_len) { |
| 94 | RecordDownloadCount(WRITE_SIZE_COUNT); |
| 95 | int max = 1024 * 1024; // One Megabyte. |
| 96 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.WriteSize", data_len, 1, max, 256); |
| 97 | } |
| 98 | |
| 99 | void RecordDownloadWriteLoopCount(int count) { |
| 100 | RecordDownloadCount(WRITE_LOOP_COUNT); |
| 101 | UMA_HISTOGRAM_ENUMERATION("Download.WriteLoopCount", count, 20); |
| 102 | } |
| 103 | |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 104 | namespace { |
| 105 | |
| 106 | enum DownloadContent { |
| 107 | DOWNLOAD_CONTENT_UNRECOGNIZED = 0, |
| 108 | DOWNLOAD_CONTENT_TEXT = 1, |
| 109 | DOWNLOAD_CONTENT_IMAGE = 2, |
| 110 | DOWNLOAD_CONTENT_AUDIO = 3, |
| 111 | DOWNLOAD_CONTENT_VIDEO = 4, |
| 112 | DOWNLOAD_CONTENT_OCTET_STREAM = 5, |
| 113 | DOWNLOAD_CONTENT_PDF = 6, |
| 114 | DOWNLOAD_CONTENT_DOC = 7, |
| 115 | DOWNLOAD_CONTENT_XLS = 8, |
| 116 | DOWNLOAD_CONTENT_PPT = 9, |
| 117 | DOWNLOAD_CONTENT_ARCHIVE = 10, |
| 118 | DOWNLOAD_CONTENT_EXE = 11, |
| 119 | DOWNLOAD_CONTENT_DMG = 12, |
| 120 | DOWNLOAD_CONTENT_CRX = 13, |
| 121 | DOWNLOAD_CONTENT_MAX = 14, |
| 122 | }; |
| 123 | |
| 124 | struct MimeTypeToDownloadContent { |
| 125 | const char* mime_type; |
| 126 | DownloadContent download_content; |
| 127 | }; |
| 128 | |
| 129 | static MimeTypeToDownloadContent kMapMimeTypeToDownloadContent[] = { |
| 130 | {"application/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM}, |
| 131 | {"binary/octet-stream", DOWNLOAD_CONTENT_OCTET_STREAM}, |
| 132 | {"application/pdf", DOWNLOAD_CONTENT_PDF}, |
| 133 | {"application/msword", DOWNLOAD_CONTENT_DOC}, |
| 134 | {"application/vnd.ms-excel", DOWNLOAD_CONTENT_XLS}, |
| 135 | {"application/vns.ms-powerpoint", DOWNLOAD_CONTENT_PPT}, |
| 136 | {"application/zip", DOWNLOAD_CONTENT_ARCHIVE}, |
| 137 | {"application/x-gzip", DOWNLOAD_CONTENT_ARCHIVE}, |
| 138 | {"application/x-rar-compressed", DOWNLOAD_CONTENT_ARCHIVE}, |
| 139 | {"application/x-tar", DOWNLOAD_CONTENT_ARCHIVE}, |
| 140 | {"application/x-bzip", DOWNLOAD_CONTENT_ARCHIVE}, |
| 141 | {"application/x-exe", DOWNLOAD_CONTENT_EXE}, |
| 142 | {"application/x-apple-diskimage", DOWNLOAD_CONTENT_DMG}, |
| 143 | {"application/x-chrome-extension", DOWNLOAD_CONTENT_CRX}, |
| 144 | }; |
| 145 | |
| 146 | } // namespace |
| 147 | |
| 148 | void RecordDownloadMimeType(const std::string& mime_type_string) { |
| 149 | DownloadContent download_content = DOWNLOAD_CONTENT_UNRECOGNIZED; |
| 150 | |
| 151 | // Look up exact matches. |
| 152 | for (size_t i = 0; i < arraysize(kMapMimeTypeToDownloadContent); ++i) { |
| 153 | const MimeTypeToDownloadContent& entry = |
| 154 | kMapMimeTypeToDownloadContent[i]; |
| 155 | if (mime_type_string == entry.mime_type) { |
| 156 | download_content = entry.download_content; |
| 157 | break; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | // Do partial matches. |
| 162 | if (download_content == DOWNLOAD_CONTENT_UNRECOGNIZED) { |
| 163 | if (StartsWithASCII(mime_type_string, "text/", true)) { |
| 164 | download_content = DOWNLOAD_CONTENT_TEXT; |
| 165 | } else if (StartsWithASCII(mime_type_string, "image/", true)) { |
| 166 | download_content = DOWNLOAD_CONTENT_IMAGE; |
| 167 | } else if (StartsWithASCII(mime_type_string, "audio/", true)) { |
| 168 | download_content = DOWNLOAD_CONTENT_AUDIO; |
| 169 | } else if (StartsWithASCII(mime_type_string, "video/", true)) { |
| 170 | download_content = DOWNLOAD_CONTENT_VIDEO; |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | // Record the value. |
| 175 | UMA_HISTOGRAM_ENUMERATION("Download.ContentType", |
| 176 | download_content, |
| 177 | DOWNLOAD_CONTENT_MAX); |
| 178 | } |
| 179 | |
[email protected] | da4a558 | 2011-10-17 19:08:06 | [diff] [blame] | 180 | void RecordOpen(const base::Time& end, bool first) { |
| 181 | if (!end.is_null()) { |
| 182 | UMA_HISTOGRAM_LONG_TIMES("Download.OpenTime", (base::Time::Now() - end)); |
| 183 | if (first) { |
| 184 | UMA_HISTOGRAM_LONG_TIMES("Download.FirstOpenTime", |
| 185 | (base::Time::Now() - end)); |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | void RecordHistorySize(int size) { |
| 191 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.HistorySize", |
| 192 | size, |
| 193 | 0/*min*/, |
| 194 | (1 << 10)/*max*/, |
| 195 | 32/*num_buckets*/); |
| 196 | } |
| 197 | |
| 198 | void RecordShelfClose(int size, int in_progress, bool autoclose) { |
| 199 | static const int kMaxShelfSize = 16; |
| 200 | if (autoclose) { |
| 201 | UMA_HISTOGRAM_ENUMERATION("Download.ShelfSizeOnAutoClose", |
| 202 | size, |
| 203 | kMaxShelfSize); |
| 204 | UMA_HISTOGRAM_ENUMERATION("Download.ShelfInProgressSizeOnAutoClose", |
| 205 | in_progress, |
| 206 | kMaxShelfSize); |
| 207 | } else { |
| 208 | UMA_HISTOGRAM_ENUMERATION("Download.ShelfSizeOnUserClose", |
| 209 | size, |
| 210 | kMaxShelfSize); |
| 211 | UMA_HISTOGRAM_ENUMERATION("Download.ShelfInProgressSizeOnUserClose", |
| 212 | in_progress, |
| 213 | kMaxShelfSize); |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | void RecordClearAllSize(int size) { |
| 218 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.ClearAllSize", |
| 219 | size, |
| 220 | 0/*min*/, |
| 221 | (1 << 10)/*max*/, |
| 222 | 32/*num_buckets*/); |
| 223 | } |
| 224 | |
| 225 | void RecordOpensOutstanding(int size) { |
| 226 | UMA_HISTOGRAM_CUSTOM_COUNTS("Download.OpensOutstanding", |
| 227 | size, |
| 228 | 0/*min*/, |
| 229 | (1 << 10)/*max*/, |
| 230 | 64/*num_buckets*/); |
| 231 | } |
| 232 | |
[email protected] | 8bd9e56 | 2011-08-16 23:55:46 | [diff] [blame] | 233 | } // namespace download_stats |