| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/feedback/feedback_data.h" | 5 #include "chrome/browser/feedback/feedback_data.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 const size_t kFeedbackMaxLength = 4 * 1024; | 32 const size_t kFeedbackMaxLength = 4 * 1024; |
| 33 const size_t kFeedbackMaxLineCount = 40; | 33 const size_t kFeedbackMaxLineCount = 40; |
| 34 | 34 |
| 35 const char kTraceFilename[] = "tracing.zip\n"; | 35 const char kTraceFilename[] = "tracing.zip\n"; |
| 36 const char kPerformanceCategoryTag[] = "Performance"; | 36 const char kPerformanceCategoryTag[] = "Performance"; |
| 37 | 37 |
| 38 const char kZipExt[] = ".zip"; | 38 const char kZipExt[] = ".zip"; |
| 39 | 39 |
| 40 const base::FilePath::CharType kLogsFilename[] = | 40 const base::FilePath::CharType kLogsFilename[] = |
| 41 FILE_PATH_LITERAL("system_logs.txt"); | 41 FILE_PATH_LITERAL("system_logs.txt"); |
| 42 const base::FilePath::CharType kHistogramsFilename[] = |
| 43 FILE_PATH_LITERAL("histograms.txt"); |
| 42 | 44 |
| 43 // Converts the system logs into a string that we can compress and send | 45 // Converts the system logs into a string that we can compress and send |
| 44 // with the report. This method only converts those logs that we want in | 46 // with the report. This method only converts those logs that we want in |
| 45 // the compressed zip file sent with the report, hence it ignores any logs | 47 // the compressed zip file sent with the report, hence it ignores any logs |
| 46 // below the size threshold of what we want compressed. | 48 // below the size threshold of what we want compressed. |
| 47 std::string LogsToString(FeedbackData::SystemLogsMap* sys_info) { | 49 std::string LogsToString(const FeedbackData::SystemLogsMap& sys_info) { |
| 48 std::string syslogs_string; | 50 std::string syslogs_string; |
| 49 for (FeedbackData::SystemLogsMap::const_iterator it = sys_info->begin(); | 51 for (FeedbackData::SystemLogsMap::const_iterator it = sys_info.begin(); |
| 50 it != sys_info->end(); ++it) { | 52 it != sys_info.end(); ++it) { |
| 51 std::string key = it->first; | 53 std::string key = it->first; |
| 52 std::string value = it->second; | 54 std::string value = it->second; |
| 53 | 55 |
| 54 if (FeedbackData::BelowCompressionThreshold(value)) | 56 if (FeedbackData::BelowCompressionThreshold(value)) |
| 55 continue; | 57 continue; |
| 56 | 58 |
| 57 TrimString(key, "\n ", &key); | 59 TrimString(key, "\n ", &key); |
| 58 TrimString(value, "\n ", &value); | 60 TrimString(value, "\n ", &value); |
| 59 | 61 |
| 60 if (value.find("\n") != std::string::npos) { | 62 if (value.find("\n") != std::string::npos) { |
| 61 syslogs_string.append( | 63 syslogs_string.append( |
| 62 key + "=" + kMultilineIndicatorString + | 64 key + "=" + kMultilineIndicatorString + |
| 63 kMultilineStartString + | 65 kMultilineStartString + |
| 64 value + "\n" + | 66 value + "\n" + |
| 65 kMultilineEndString); | 67 kMultilineEndString); |
| 66 } else { | 68 } else { |
| 67 syslogs_string.append(key + "=" + value + "\n"); | 69 syslogs_string.append(key + "=" + value + "\n"); |
| 68 } | 70 } |
| 69 } | 71 } |
| 70 return syslogs_string; | 72 return syslogs_string; |
| 71 } | 73 } |
| 72 | 74 |
| 73 void ZipFile(const base::FilePath& filename, | 75 void ZipFile(const base::FilePath& filename, |
| 74 const std::string& data, std::string* compressed_data) { | 76 const std::string& data, std::string* compressed_data) { |
| 75 if (!feedback_util::ZipString(filename, data, compressed_data)) | 77 if (!feedback_util::ZipString(filename, data, compressed_data)) |
| 76 compressed_data->clear(); | 78 compressed_data->clear(); |
| 77 } | 79 } |
| 78 | 80 |
| 79 void ZipLogs(FeedbackData::SystemLogsMap* sys_info, | 81 void ZipLogs(const FeedbackData::SystemLogsMap& sys_info, |
| 80 std::string* compressed_logs) { | 82 std::string* compressed_logs) { |
| 81 DCHECK(compressed_logs); | 83 DCHECK(compressed_logs); |
| 82 std::string logs_string = LogsToString(sys_info); | 84 std::string logs_string = LogsToString(sys_info); |
| 83 if (logs_string.empty() || | 85 if (logs_string.empty() || |
| 84 !feedback_util::ZipString( | 86 !feedback_util::ZipString( |
| 85 base::FilePath(kLogsFilename), logs_string, compressed_logs)) { | 87 base::FilePath(kLogsFilename), logs_string, compressed_logs)) { |
| 86 compressed_logs->clear(); | 88 compressed_logs->clear(); |
| 87 } | 89 } |
| 88 } | 90 } |
| 89 | 91 |
| 92 void ZipHistograms(const std::string& histograms, |
| 93 std::string* compressed_histograms) { |
| 94 DCHECK(compressed_histograms); |
| 95 if (histograms.empty() || |
| 96 !feedback_util::ZipString( |
| 97 base::FilePath(kHistogramsFilename), |
| 98 histograms, |
| 99 compressed_histograms)) { |
| 100 compressed_histograms->clear(); |
| 101 } |
| 102 } |
| 103 |
| 90 } // namespace | 104 } // namespace |
| 91 | 105 |
| 92 // static | 106 // static |
| 93 bool FeedbackData::BelowCompressionThreshold(const std::string& content) { | 107 bool FeedbackData::BelowCompressionThreshold(const std::string& content) { |
| 94 if (content.length() > kFeedbackMaxLength) | 108 if (content.length() > kFeedbackMaxLength) |
| 95 return false; | 109 return false; |
| 96 const size_t line_count = std::count(content.begin(), content.end(), '\n'); | 110 const size_t line_count = std::count(content.begin(), content.end(), '\n'); |
| 97 if (line_count > kFeedbackMaxLineCount) | 111 if (line_count > kFeedbackMaxLineCount) |
| 98 return false; | 112 return false; |
| 99 return true; | 113 return true; |
| 100 } | 114 } |
| 101 | 115 |
| 102 FeedbackData::FeedbackData() : profile_(NULL), | 116 FeedbackData::FeedbackData() : profile_(NULL), |
| 103 trace_id_(0), | 117 trace_id_(0), |
| 104 feedback_page_data_complete_(false), | 118 feedback_page_data_complete_(false), |
| 105 syslogs_compression_complete_(false), | 119 syslogs_compression_complete_(false), |
| 120 histograms_compression_complete_(false), |
| 106 attached_file_compression_complete_(false), | 121 attached_file_compression_complete_(false), |
| 107 report_sent_(false) { | 122 report_sent_(false) { |
| 108 } | 123 } |
| 109 | 124 |
| 110 FeedbackData::~FeedbackData() { | 125 FeedbackData::~FeedbackData() { |
| 111 } | 126 } |
| 112 | 127 |
| 113 void FeedbackData::OnFeedbackPageDataComplete() { | 128 void FeedbackData::OnFeedbackPageDataComplete() { |
| 114 feedback_page_data_complete_ = true; | 129 feedback_page_data_complete_ = true; |
| 115 SendReport(); | 130 SendReport(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 129 } | 144 } |
| 130 } | 145 } |
| 131 | 146 |
| 132 sys_info_ = sys_info.Pass(); | 147 sys_info_ = sys_info.Pass(); |
| 133 if (sys_info_.get()) { | 148 if (sys_info_.get()) { |
| 134 std::string* compressed_logs_ptr = new std::string; | 149 std::string* compressed_logs_ptr = new std::string; |
| 135 scoped_ptr<std::string> compressed_logs(compressed_logs_ptr); | 150 scoped_ptr<std::string> compressed_logs(compressed_logs_ptr); |
| 136 BrowserThread::PostBlockingPoolTaskAndReply( | 151 BrowserThread::PostBlockingPoolTaskAndReply( |
| 137 FROM_HERE, | 152 FROM_HERE, |
| 138 base::Bind(&ZipLogs, | 153 base::Bind(&ZipLogs, |
| 139 sys_info_.get(), | 154 *sys_info_, |
| 140 compressed_logs_ptr), | 155 compressed_logs_ptr), |
| 141 base::Bind(&FeedbackData::OnCompressLogsComplete, | 156 base::Bind(&FeedbackData::OnCompressLogsComplete, |
| 142 this, | 157 this, |
| 143 base::Passed(&compressed_logs))); | 158 base::Passed(&compressed_logs))); |
| 144 } | 159 } |
| 145 } | 160 } |
| 146 | 161 |
| 162 void FeedbackData::SetAndCompressHistograms( |
| 163 scoped_ptr<std::string> histograms) { |
| 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 165 |
| 166 histograms_ = histograms.Pass(); |
| 167 if (histograms_.get()) { |
| 168 std::string* compressed_histograms_ptr = new std::string; |
| 169 scoped_ptr<std::string> compressed_histograms(compressed_histograms_ptr); |
| 170 BrowserThread::PostBlockingPoolTaskAndReply( |
| 171 FROM_HERE, |
| 172 base::Bind(&ZipHistograms, |
| 173 *histograms_, |
| 174 compressed_histograms_ptr), |
| 175 base::Bind(&FeedbackData::OnCompressHistogramsComplete, |
| 176 this, |
| 177 base::Passed(&compressed_histograms))); |
| 178 } |
| 179 } |
| 180 |
| 147 void FeedbackData::AttachAndCompressFileData( | 181 void FeedbackData::AttachAndCompressFileData( |
| 148 scoped_ptr<std::string> attached_filedata) { | 182 scoped_ptr<std::string> attached_filedata) { |
| 149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 150 | 184 |
| 151 attached_filedata_ = attached_filedata.Pass(); | 185 attached_filedata_ = attached_filedata.Pass(); |
| 152 | 186 |
| 153 if (!attached_filename_.empty() && attached_filedata_.get()) { | 187 if (!attached_filename_.empty() && attached_filedata_.get()) { |
| 154 std::string* compressed_file_ptr = new std::string; | 188 std::string* compressed_file_ptr = new std::string; |
| 155 scoped_ptr<std::string> compressed_file(compressed_file_ptr); | 189 scoped_ptr<std::string> compressed_file(compressed_file_ptr); |
| 156 #if defined(OS_WIN) | 190 #if defined(OS_WIN) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 void FeedbackData::OnCompressLogsComplete( | 228 void FeedbackData::OnCompressLogsComplete( |
| 195 scoped_ptr<std::string> compressed_logs) { | 229 scoped_ptr<std::string> compressed_logs) { |
| 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 197 | 231 |
| 198 compressed_logs_ = compressed_logs.Pass(); | 232 compressed_logs_ = compressed_logs.Pass(); |
| 199 syslogs_compression_complete_ = true; | 233 syslogs_compression_complete_ = true; |
| 200 | 234 |
| 201 SendReport(); | 235 SendReport(); |
| 202 } | 236 } |
| 203 | 237 |
| 238 void FeedbackData::OnCompressHistogramsComplete( |
| 239 scoped_ptr<std::string> compressed_histograms) { |
| 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 241 |
| 242 compressed_histograms_ = compressed_histograms.Pass(); |
| 243 histograms_compression_complete_ = true; |
| 244 |
| 245 SendReport(); |
| 246 } |
| 247 |
| 204 void FeedbackData::OnCompressFileComplete( | 248 void FeedbackData::OnCompressFileComplete( |
| 205 scoped_ptr<std::string> compressed_file) { | 249 scoped_ptr<std::string> compressed_file) { |
| 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 207 | 251 |
| 208 if (compressed_file.get()) { | 252 if (compressed_file.get()) { |
| 209 attached_filedata_ = compressed_file.Pass(); | 253 attached_filedata_ = compressed_file.Pass(); |
| 210 attached_filename_.append(kZipExt); | 254 attached_filename_.append(kZipExt); |
| 211 attached_file_compression_complete_ = true; | 255 attached_file_compression_complete_ = true; |
| 212 } else { | 256 } else { |
| 213 attached_filename_.clear(); | 257 attached_filename_.clear(); |
| 214 attached_filedata_.reset(NULL); | 258 attached_filedata_.reset(NULL); |
| 215 } | 259 } |
| 216 | 260 |
| 217 SendReport(); | 261 SendReport(); |
| 218 } | 262 } |
| 219 | 263 |
| 220 bool FeedbackData::IsDataComplete() { | 264 bool FeedbackData::IsDataComplete() { |
| 221 return (!sys_info_.get() || syslogs_compression_complete_) && | 265 return (!sys_info_.get() || syslogs_compression_complete_) && |
| 266 (!histograms_.get() || histograms_compression_complete_) && |
| 222 (!attached_filedata_.get() || attached_file_compression_complete_) && | 267 (!attached_filedata_.get() || attached_file_compression_complete_) && |
| 223 !trace_id_ && | 268 !trace_id_ && |
| 224 feedback_page_data_complete_; | 269 feedback_page_data_complete_; |
| 225 } | 270 } |
| 226 | 271 |
| 227 void FeedbackData::SendReport() { | 272 void FeedbackData::SendReport() { |
| 228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 229 if (IsDataComplete() && !report_sent_) { | 274 if (IsDataComplete() && !report_sent_) { |
| 230 report_sent_ = true; | 275 report_sent_ = true; |
| 231 feedback_util::SendReport(this); | 276 feedback_util::SendReport(this); |
| 232 } | 277 } |
| 233 } | 278 } |
| OLD | NEW |