OLD | NEW |
---|---|
(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/browser_thread.h" | |
9 #include "content/public/browser/tracing_controller.h" | |
10 | |
11 | |
12 namespace content { | |
13 | |
14 namespace { | |
15 | |
16 base::LazyInstance<BackgroundTracingManagerImpl>::Leaky g_controller = | |
17 LAZY_INSTANCE_INITIALIZER; | |
18 | |
19 class TraceDataEndpointWrapper : | |
20 public content::TracingController::TraceDataEndpoint { | |
21 public: | |
22 TraceDataEndpointWrapper( | |
23 scoped_refptr<content::BackgroundTracingManager::UploadSink> upload_sink, | |
24 base::Callback<void()> done_callback) : | |
25 upload_sink_(upload_sink), | |
26 done_callback_(done_callback) { | |
27 } | |
28 | |
29 void ReceiveTraceFinalContents(const std::string& file_contents) override { | |
30 upload_sink_->Upload(file_contents, done_callback_); | |
31 } | |
32 | |
33 private: | |
34 ~TraceDataEndpointWrapper() override { | |
35 } | |
36 | |
37 scoped_refptr<content::BackgroundTracingManager::UploadSink> upload_sink_; | |
38 base::Callback<void()> done_callback_; | |
39 }; | |
40 | |
41 } // namespace | |
42 | |
43 BackgroundTracingManager* BackgroundTracingManager::GetInstance() { | |
44 return BackgroundTracingManagerImpl::GetInstance(); | |
45 } | |
46 | |
47 BackgroundTracingManagerImpl* BackgroundTracingManagerImpl::GetInstance() { | |
48 return g_controller.Pointer(); | |
49 } | |
50 | |
51 BackgroundTracingManagerImpl::BackgroundTracingManagerImpl() | |
52 : is_idle_(true), is_gathering_(false) { | |
53 } | |
54 | |
55 BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() { | |
56 NOTREACHED(); | |
57 } | |
58 | |
59 void BackgroundTracingManagerImpl::WhenIdle(base::Callback<void()> idle_callback ) { | |
oystein (OOO til 10th of July)
2015/05/05 19:28:30
Is this used anywhere? What's it for?
shatch
2015/05/05 20:20:22
Used to notify anybody who's interested that the B
| |
60 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
61 idle_callback_ = idle_callback; | |
62 } | |
63 | |
64 bool BackgroundTracingManagerImpl::SetActiveScenario( | |
65 scoped_refptr<BackgroundTracingConfig> config, | |
66 scoped_refptr<BackgroundTracingManager::UploadSink> upload_sink) { | |
67 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
68 if (!is_idle_) | |
69 return false; | |
70 | |
71 // TODO(simonhatch): Implement reactive tracing path. | |
72 if (config && config->mode == BackgroundTracingConfig::REACTIVE_TRACING_MODE) | |
73 return false; | |
74 | |
75 config_ = config; | |
76 upload_sink_ = upload_sink; | |
77 | |
78 MaybeEnableRecording(); | |
79 | |
80 return true; | |
81 } | |
82 | |
83 void BackgroundTracingManagerImpl::MaybeEnableRecording() { | |
84 if (!config_ || !upload_sink_) | |
85 return; | |
86 | |
87 if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) { | |
88 // HACK | |
89 EnableRecording( | |
90 GetCategoryFilterForCategoryPreset( | |
91 static_cast<BackgroundTracingPreemptiveConfig*>( | |
92 config_.get())->category_preset)); | |
93 } else { | |
94 // TODO(simonhatch): Implement reactive tracing path. | |
95 NOTREACHED(); | |
96 } | |
97 } | |
98 | |
99 bool BackgroundTracingManagerImpl::IsAbleToStartTracing(TriggerHandle handle) co nst { | |
100 if (!config_ || !upload_sink_ || is_gathering_) | |
101 return false; | |
102 | |
103 if (!IsTriggerHandleValid(handle)) { | |
104 return false; | |
105 } | |
106 | |
107 std::string trigger_name = GetTriggerNameFromHandle(handle); | |
108 | |
109 if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) { | |
110 BackgroundTracingPreemptiveConfig* preemptive_config = | |
111 static_cast<BackgroundTracingPreemptiveConfig*>(config_.get()); | |
112 | |
113 for (size_t i = 0; i < preemptive_config->configs.size(); ++i) { | |
114 if (preemptive_config->configs[i].type != | |
115 BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED ) | |
116 continue; | |
117 | |
118 if (trigger_name == | |
119 preemptive_config->configs[i].named_trigger_info.trigger_name) { | |
120 return true; | |
121 } | |
122 } | |
123 } else { | |
124 // TODO(simonhatch): Implement reactive path. | |
125 NOTREACHED(); | |
126 } | |
127 | |
128 return false; | |
129 } | |
130 | |
131 void BackgroundTracingManagerImpl::DidTriggerHappen( | |
132 BackgroundTracingManagerImpl::TriggerHandle handle, | |
133 StartedFinalizingCallback callback) { | |
134 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { | |
135 content::BrowserThread::PostTask( | |
136 content::BrowserThread::UI, FROM_HERE, | |
137 base::Bind( | |
138 &BackgroundTracingManagerImpl::DidTriggerHappen, | |
139 base::Unretained(this), handle, callback)); | |
140 return; | |
141 } | |
142 | |
143 if (!IsAbleToStartTracing(handle)) { | |
144 if (!callback.is_null()) | |
145 callback.Run(false); | |
146 return; | |
147 } | |
148 | |
149 if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) { | |
150 BeginFinalizing(callback); | |
151 } else { | |
152 // TODO(simonhatch): Implement reactive tracing path. | |
153 NOTREACHED(); | |
154 } | |
155 } | |
156 | |
157 BackgroundTracingManagerImpl::TriggerHandle | |
158 BackgroundTracingManagerImpl::RegisterTriggerType(const char* trigger_name) { | |
159 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
160 | |
161 trigger_handles_.push_back(trigger_name); | |
162 | |
163 return static_cast<TriggerHandle>(trigger_handles_.size() - 1); | |
164 } | |
165 | |
166 bool BackgroundTracingManagerImpl::IsTriggerHandleValid( | |
167 BackgroundTracingManager::TriggerHandle handle) const { | |
168 return handle < trigger_handles_.size(); | |
169 } | |
170 | |
171 std::string BackgroundTracingManagerImpl::GetTriggerNameFromHandle( | |
172 BackgroundTracingManager::TriggerHandle handle) const { | |
173 CHECK(IsTriggerHandleValid(handle)); | |
174 return trigger_handles_[handle]; | |
175 } | |
176 | |
177 void BackgroundTracingManagerImpl::GetTriggerNameList( | |
178 std::vector<std::string>& trigger_names) { | |
179 trigger_names = trigger_handles_; | |
180 } | |
181 | |
182 void BackgroundTracingManagerImpl::InvalidateTriggerHandlesForTesting() { | |
183 trigger_handles_.clear(); | |
184 } | |
185 | |
186 void BackgroundTracingManagerImpl::EnableRecording( | |
187 base::trace_event::CategoryFilter category_filter) { | |
188 is_idle_ = false; | |
189 TracingController::GetInstance()->EnableRecording( | |
190 category_filter, | |
191 base::trace_event::TraceOptions(base::trace_event::RECORD_CONTINUOUSLY), | |
192 TracingController::EnableRecordingDoneCallback()); | |
193 } | |
194 | |
195 void BackgroundTracingManagerImpl::OnFinalizeComplete() { | |
196 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
197 BrowserThread::PostTask( | |
198 BrowserThread::UI, FROM_HERE, | |
199 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete, | |
200 base::Unretained(this))); | |
201 return; | |
202 } | |
203 | |
204 printf("BackgroundTracingManagerImpl::OnFinalizeComplete\n"); | |
oystein (OOO til 10th of July)
2015/05/05 19:28:30
kill
shatch
2015/05/05 20:20:22
Done.
| |
205 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
206 | |
207 is_idle_ = true; | |
oystein (OOO til 10th of July)
2015/05/05 19:28:30
Do we need to track this? Can we check if the uplo
shatch
2015/05/05 20:20:22
Added a function on TracingControllerImpl instead.
| |
208 | |
209 if (!idle_callback_.is_null()) | |
210 idle_callback_.Run(); | |
211 | |
212 // Now that a trace has completed, we may need to enable recording again. | |
213 MaybeEnableRecording(); | |
214 } | |
215 | |
216 void BackgroundTracingManagerImpl::BeginFinalizing( | |
217 StartedFinalizingCallback callback) { | |
218 is_gathering_ = true; | |
oystein (OOO til 10th of July)
2015/05/05 19:28:30
Can we query the TracingController for this instea
shatch
2015/05/05 20:20:22
Nah there's no way to query that. Will have to add
| |
219 | |
220 content::TracingController::GetInstance()->DisableRecording( | |
221 content::TracingController::CreateCompressedStringSink( | |
222 new TraceDataEndpointWrapper( | |
oystein (OOO til 10th of July)
2015/05/05 19:28:30
Do we delete this anywhere? Can we store the wrapp
shatch
2015/05/05 20:20:22
CreateCompressedStringSink takes a refptr. Uploade
| |
223 upload_sink_, | |
224 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete, | |
225 base::Unretained(this))))); | |
226 | |
227 if (!callback.is_null()) | |
228 callback.Run(true); | |
229 } | |
230 | |
231 base::trace_event::CategoryFilter | |
232 BackgroundTracingManagerImpl::GetCategoryFilterForCategoryPreset( | |
233 BackgroundTracingConfig::CategoryPreset preset) const { | |
234 switch (preset) { | |
235 case BackgroundTracingConfig::CategoryPreset::BENCHMARK: | |
236 return base::trace_event::CategoryFilter( | |
237 "benchmark," | |
238 "disabled-by-default-toplevel.flow," | |
239 "disabled-by-default-ipc.flow"); | |
240 case BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP: | |
241 return base::trace_event::CategoryFilter( | |
242 "*,disabled-by-default-blink.debug.layout"); | |
243 default: | |
oystein (OOO til 10th of July)
2015/05/05 19:28:30
Maybe without the default label, so we know every
shatch
2015/05/05 20:20:22
Done.
| |
244 NOTREACHED(); | |
245 } | |
246 return base::trace_event::CategoryFilter(); | |
247 } | |
248 | |
249 } // namspace content | |
OLD | NEW |