Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(638)

Side by Side Diff: content/browser/tracing/background_tracing_manager_impl.cc

Issue 1089253003: Re-land first pass BackgroundTracingManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Scoped_ptr Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/tracing/background_tracing_manager_impl.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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/tracing/background_tracing_manager_impl.h"
6
7 #include "base/macros.h"
8 #include "content/public/browser/background_tracing_preemptive_config.h"
9 #include "content/public/browser/background_tracing_reactive_config.h"
10 #include "content/public/browser/browser_thread.h"
11
12 namespace content {
13
14 namespace {
15
16 base::LazyInstance<BackgroundTracingManagerImpl>::Leaky g_controller =
17 LAZY_INSTANCE_INITIALIZER;
18
19 } // namespace
20
21 BackgroundTracingManagerImpl::TraceDataEndpointWrapper::
22 TraceDataEndpointWrapper(base::Callback<
23 void(scoped_refptr<base::RefCountedString>)> done_callback)
24 : done_callback_(done_callback) {
25 }
26
27 BackgroundTracingManagerImpl::TraceDataEndpointWrapper::
28 ~TraceDataEndpointWrapper() {
29 }
30
31 void BackgroundTracingManagerImpl::TraceDataEndpointWrapper::
32 ReceiveTraceFinalContents(const std::string& file_contents) {
33 std::string tmp = file_contents;
34 scoped_refptr<base::RefCountedString> contents_ptr =
35 base::RefCountedString::TakeString(&tmp);
36
37 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
38 base::Bind(done_callback_, contents_ptr));
39 }
40
41 BackgroundTracingManager* BackgroundTracingManager::GetInstance() {
42 return BackgroundTracingManagerImpl::GetInstance();
43 }
44
45 BackgroundTracingManagerImpl* BackgroundTracingManagerImpl::GetInstance() {
46 return g_controller.Pointer();
47 }
48
49 BackgroundTracingManagerImpl::BackgroundTracingManagerImpl()
50 : is_gathering_(false),
51 is_tracing_(false),
52 requires_anonymized_data_(true),
53 trigger_handle_ids_(0) {
54 data_endpoint_wrapper_ = new TraceDataEndpointWrapper(
55 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeStarted,
56 base::Unretained(this)));
57 }
58
59 BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() {
60 NOTREACHED();
61 }
62
63 void BackgroundTracingManagerImpl::WhenIdle(
64 base::Callback<void()> idle_callback) {
65 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
66 idle_callback_ = idle_callback;
67 }
68
69 bool BackgroundTracingManagerImpl::IsSupportedConfig(
70 BackgroundTracingConfig* config) {
71 // No config is just fine, we just don't do anything.
72 if (!config)
73 return true;
74
75 // TODO(simonhatch): Implement reactive tracing path.
76 if (config->mode != BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE)
77 return false;
78
79 // TODO(fmeawad): Implement uma triggers.
80 BackgroundTracingPreemptiveConfig* preemptive_config =
81 static_cast<BackgroundTracingPreemptiveConfig*>(config);
82 const std::vector<BackgroundTracingPreemptiveConfig::MonitoringRule>&
83 configs = preemptive_config->configs;
84 for (size_t i = 0; i < configs.size(); ++i) {
85 if (configs[i].type !=
86 BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED)
87 return false;
88 }
89
90 return true;
91 }
92
93 bool BackgroundTracingManagerImpl::SetActiveScenario(
94 scoped_ptr<BackgroundTracingConfig> config,
95 const BackgroundTracingManager::ReceiveCallback& receive_callback,
96 bool requires_anonymized_data) {
97 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
98 if (is_tracing_)
99 return false;
100
101 if (!IsSupportedConfig(config.get()))
102 return false;
103
104 // No point in tracing if there's nowhere to send it.
105 if (config && receive_callback.is_null())
106 return false;
107
108 config_ = config.Pass();
109 receive_callback_ = receive_callback;
110 requires_anonymized_data_ = requires_anonymized_data;
111
112 EnableRecordingIfConfigNeedsIt();
113
114 return true;
115 }
116
117 void BackgroundTracingManagerImpl::EnableRecordingIfConfigNeedsIt() {
118 if (!config_)
119 return;
120
121 if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) {
122 EnableRecording(GetCategoryFilterForCategoryPreset(
123 static_cast<BackgroundTracingPreemptiveConfig*>(config_.get())
124 ->category_preset));
125 } else {
126 // TODO(simonhatch): Implement reactive tracing path.
127 NOTREACHED();
128 }
129 }
130
131 bool BackgroundTracingManagerImpl::IsAbleToTriggerTracing(
132 TriggerHandle handle) const {
133 if (!config_)
134 return false;
135
136 // If the last trace is still uploading, we don't allow a new one to trigger.
137 if (is_gathering_)
138 return false;
139
140 if (!IsTriggerHandleValid(handle)) {
141 return false;
142 }
143
144 std::string trigger_name = GetTriggerNameFromHandle(handle);
145
146 if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) {
147 BackgroundTracingPreemptiveConfig* preemptive_config =
148 static_cast<BackgroundTracingPreemptiveConfig*>(config_.get());
149
150 const std::vector<BackgroundTracingPreemptiveConfig::MonitoringRule>&
151 configs = preemptive_config->configs;
152
153 for (size_t i = 0; i < configs.size(); ++i) {
154 if (configs[i].type != BackgroundTracingPreemptiveConfig::
155 MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED)
156 continue;
157
158 if (trigger_name == configs[i].named_trigger_info.trigger_name) {
159 return true;
160 }
161 }
162 } else {
163 // TODO(simonhatch): Implement reactive path.
164 NOTREACHED();
165 }
166
167 return false;
168 }
169
170 void BackgroundTracingManagerImpl::TriggerNamedEvent(
171 BackgroundTracingManagerImpl::TriggerHandle handle,
172 StartedFinalizingCallback callback) {
173 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
174 content::BrowserThread::PostTask(
175 content::BrowserThread::UI, FROM_HERE,
176 base::Bind(&BackgroundTracingManagerImpl::TriggerNamedEvent,
177 base::Unretained(this), handle, callback));
178 return;
179 }
180
181 if (!IsAbleToTriggerTracing(handle)) {
182 if (!callback.is_null())
183 callback.Run(false);
184 return;
185 }
186
187 if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) {
188 BeginFinalizing(callback);
189 } else {
190 // TODO(simonhatch): Implement reactive tracing path.
191 NOTREACHED();
192 }
193 }
194
195 BackgroundTracingManagerImpl::TriggerHandle
196 BackgroundTracingManagerImpl::RegisterTriggerType(const char* trigger_name) {
197 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
198
199 trigger_handle_ids_ += 1;
200
201 trigger_handles_.insert(
202 std::pair<TriggerHandle, std::string>(trigger_handle_ids_, trigger_name));
203
204 return static_cast<TriggerHandle>(trigger_handle_ids_);
205 }
206
207 bool BackgroundTracingManagerImpl::IsTriggerHandleValid(
208 BackgroundTracingManager::TriggerHandle handle) const {
209 return trigger_handles_.find(handle) != trigger_handles_.end();
210 }
211
212 std::string BackgroundTracingManagerImpl::GetTriggerNameFromHandle(
213 BackgroundTracingManager::TriggerHandle handle) const {
214 CHECK(IsTriggerHandleValid(handle));
215 return trigger_handles_.find(handle)->second;
216 }
217
218 void BackgroundTracingManagerImpl::GetTriggerNameList(
219 std::vector<std::string>* trigger_names) {
220 for (std::map<TriggerHandle, std::string>::iterator it =
221 trigger_handles_.begin();
222 it != trigger_handles_.end(); ++it)
223 trigger_names->push_back(it->second);
224 }
225
226 void BackgroundTracingManagerImpl::InvalidateTriggerHandlesForTesting() {
227 trigger_handles_.clear();
228 }
229
230 void BackgroundTracingManagerImpl::EnableRecording(
231 base::trace_event::CategoryFilter category_filter) {
232 is_tracing_ = TracingController::GetInstance()->EnableRecording(
233 category_filter,
234 base::trace_event::TraceOptions(base::trace_event::RECORD_CONTINUOUSLY),
235 TracingController::EnableRecordingDoneCallback());
236 }
237
238 void BackgroundTracingManagerImpl::OnFinalizeStarted(
239 scoped_refptr<base::RefCountedString> file_contents) {
240 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
241
242 if (!receive_callback_.is_null())
243 receive_callback_.Run(
244 file_contents.get(),
245 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete,
246 base::Unretained(this)));
247 }
248
249 void BackgroundTracingManagerImpl::OnFinalizeComplete() {
250 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
251 BrowserThread::PostTask(
252 BrowserThread::UI, FROM_HERE,
253 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete,
254 base::Unretained(this)));
255 return;
256 }
257
258 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
259
260 is_gathering_ = false;
261
262 if (!idle_callback_.is_null())
263 idle_callback_.Run();
264
265 // Now that a trace has completed, we may need to enable recording again.
266 EnableRecordingIfConfigNeedsIt();
267 }
268
269 void BackgroundTracingManagerImpl::BeginFinalizing(
270 StartedFinalizingCallback callback) {
271 is_gathering_ = true;
272 is_tracing_ = false;
273
274 content::TracingController::GetInstance()->DisableRecording(
275 content::TracingController::CreateCompressedStringSink(
276 data_endpoint_wrapper_));
277
278 if (!callback.is_null())
279 callback.Run(true);
280 }
281
282 base::trace_event::CategoryFilter
283 BackgroundTracingManagerImpl::GetCategoryFilterForCategoryPreset(
284 BackgroundTracingConfig::CategoryPreset preset) const {
285 switch (preset) {
286 case BackgroundTracingConfig::CategoryPreset::BENCHMARK:
287 return base::trace_event::CategoryFilter(
288 "benchmark,"
289 "disabled-by-default-toplevel.flow,"
290 "disabled-by-default-ipc.flow");
291 case BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP:
292 return base::trace_event::CategoryFilter(
293 "*,disabled-by-default-blink.debug.layout");
294 }
295 NOTREACHED();
296 return base::trace_event::CategoryFilter();
297 }
298
299 scoped_ptr<BackgroundTracingConfig> BackgroundTracingConfig::FromDict(
300 const base::DictionaryValue* dict) {
301 // TODO(simonhatch): Implement this.
302 CHECK(false);
303 return NULL;
304 }
305
306 void BackgroundTracingConfig::IntoDict(const BackgroundTracingConfig* config,
307 base::DictionaryValue* dict) {
308 // TODO(simonhatch): Implement this.
309 CHECK(false);
310 }
311
312 } // namspace content
OLDNEW
« no previous file with comments | « content/browser/tracing/background_tracing_manager_impl.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698