• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "components/feedback/feedback_data.h"
6 
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/json/json_string_value_serializer.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "components/feedback/feedback_util.h"
15 #include "components/feedback/tracing_manager.h"
16 #include "content/public/browser/browser_thread.h"
17 
18 using content::BrowserThread;
19 
20 namespace feedback {
21 namespace {
22 
23 const char kTraceFilename[] = "tracing.zip\n";
24 const char kPerformanceCategoryTag[] = "Performance";
25 
26 const base::FilePath::CharType kHistogramsFilename[] =
27     FILE_PATH_LITERAL("histograms.txt");
28 
29 const char kHistogramsAttachmentName[] = "histograms.zip";
30 
31 }  // namespace
32 
FeedbackData()33 FeedbackData::FeedbackData()
34     : send_report_(base::Bind(&feedback_util::SendReport)), context_(NULL),
35       trace_id_(0), pending_op_count_(1), report_sent_(false) {}
36 
~FeedbackData()37 FeedbackData::~FeedbackData() {
38 }
39 
OnFeedbackPageDataComplete()40 void FeedbackData::OnFeedbackPageDataComplete() {
41   pending_op_count_--;
42   SendReport();
43 }
44 
SetAndCompressSystemInfo(scoped_ptr<FeedbackData::SystemLogsMap> sys_info)45 void FeedbackData::SetAndCompressSystemInfo(
46     scoped_ptr<FeedbackData::SystemLogsMap> sys_info) {
47   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
48 
49   if (trace_id_ != 0) {
50     TracingManager* manager = TracingManager::Get();
51     ++pending_op_count_;
52     if (!manager ||
53         !manager->GetTraceData(
54             trace_id_,
55             base::Bind(&FeedbackData::OnGetTraceData, this, trace_id_))) {
56       pending_op_count_--;
57       trace_id_ = 0;
58     }
59   }
60 
61   if (sys_info.get()) {
62     ++pending_op_count_;
63     AddLogs(sys_info.Pass());
64     BrowserThread::PostBlockingPoolTaskAndReply(
65         FROM_HERE,
66         base::Bind(&FeedbackCommon::CompressLogs, this),
67         base::Bind(&FeedbackData::OnCompressComplete, this));
68   }
69 }
70 
SetAndCompressHistograms(scoped_ptr<std::string> histograms)71 void FeedbackData::SetAndCompressHistograms(
72     scoped_ptr<std::string> histograms) {
73   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
74 
75   if (!histograms.get())
76     return;
77   ++pending_op_count_;
78   BrowserThread::PostBlockingPoolTaskAndReply(
79       FROM_HERE,
80       base::Bind(&FeedbackCommon::CompressFile,
81                  this,
82                  base::FilePath(kHistogramsFilename),
83                  kHistogramsAttachmentName,
84                  base::Passed(&histograms)),
85       base::Bind(&FeedbackData::OnCompressComplete, this));
86 }
87 
AttachAndCompressFileData(scoped_ptr<std::string> attached_filedata)88 void FeedbackData::AttachAndCompressFileData(
89     scoped_ptr<std::string> attached_filedata) {
90   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
91 
92   if (!attached_filedata.get() || attached_filedata->empty())
93     return;
94   ++pending_op_count_;
95 #if defined(OS_WIN)
96   base::FilePath attached_file(base::UTF8ToWide(attached_filename_));
97 #else
98   base::FilePath attached_file(attached_filename_);
99 #endif
100   BrowserThread::PostBlockingPoolTaskAndReply(
101       FROM_HERE,
102       base::Bind(&FeedbackCommon::CompressFile,
103                  this,
104                  attached_file,
105                  std::string(),
106                  base::Passed(&attached_filedata)),
107       base::Bind(&FeedbackData::OnCompressComplete, this));
108 }
109 
OnGetTraceData(int trace_id,scoped_refptr<base::RefCountedString> trace_data)110 void FeedbackData::OnGetTraceData(
111     int trace_id,
112     scoped_refptr<base::RefCountedString> trace_data) {
113   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
114   TracingManager* manager = TracingManager::Get();
115   if (manager)
116     manager->DiscardTraceData(trace_id);
117 
118   scoped_ptr<std::string> data(new std::string);
119   data->swap(trace_data->data());
120 
121   AddFile(kTraceFilename, data.Pass());
122 
123   set_category_tag(kPerformanceCategoryTag);
124   --pending_op_count_;
125   trace_id_ = 0;
126   SendReport();
127 }
128 
OnCompressComplete()129 void FeedbackData::OnCompressComplete() {
130   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
131   --pending_op_count_;
132   SendReport();
133 }
134 
IsDataComplete()135 bool FeedbackData::IsDataComplete() {
136   return pending_op_count_ == 0;
137 }
138 
SendReport()139 void FeedbackData::SendReport() {
140   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
141   if (IsDataComplete() && !report_sent_) {
142     report_sent_ = true;
143     send_report_.Run(this);
144   }
145 }
146 
147 }  // namespace feedback
148