OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/tracing/tracing_controller_impl.h" | 5 #include "content/browser/tracing/tracing_controller_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" |
8 #include "base/file_util.h" | 9 #include "base/file_util.h" |
9 #include "base/json/string_escape.h" | 10 #include "base/json/string_escape.h" |
10 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/values.h" |
11 #include "content/browser/tracing/trace_message_filter.h" | 13 #include "content/browser/tracing/trace_message_filter.h" |
12 #include "content/common/child_process_messages.h" | 14 #include "content/common/child_process_messages.h" |
13 #include "content/public/browser/browser_message_filter.h" | 15 #include "content/public/browser/browser_message_filter.h" |
14 #include "content/public/common/content_switches.h" | 16 #include "content/public/common/content_switches.h" |
15 | 17 |
16 using base::debug::TraceLog; | 18 using base::debug::TraceLog; |
17 | 19 |
18 namespace content { | 20 namespace content { |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = | 24 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = |
23 LAZY_INSTANCE_INITIALIZER; | 25 LAZY_INSTANCE_INITIALIZER; |
24 | 26 |
| 27 // The keys of tracing parameters in JSON. Must keep consistent with |
| 28 // third_party/trace-viewer/src/about_tracing/begin_recording.js. |
| 29 const char kCategoryFilter[] = "categoryFilter"; |
| 30 const char kUseSystemTracing[] = "useSystemTracing"; |
| 31 const char kUseContinuousTracing[] = "useContinuousTracing"; |
| 32 const char kUseSampling[] = "useSampling"; |
| 33 |
25 } // namespace | 34 } // namespace |
26 | 35 |
27 TracingController* TracingController::GetInstance() { | 36 TracingController* TracingController::GetInstance() { |
28 return TracingControllerImpl::GetInstance(); | 37 return TracingControllerImpl::GetInstance(); |
29 } | 38 } |
30 | 39 |
31 class TracingControllerImpl::ResultFile { | 40 class TracingControllerImpl::ResultFile { |
32 public: | 41 public: |
33 explicit ResultFile(const base::FilePath& path); | 42 explicit ResultFile(const base::FilePath& path); |
34 void Write(const scoped_refptr<base::RefCountedString>& events_str_ptr) { | 43 void Write(const scoped_refptr<base::RefCountedString>& events_str_ptr) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 | 118 |
110 | 119 |
111 TracingControllerImpl::TracingControllerImpl() : | 120 TracingControllerImpl::TracingControllerImpl() : |
112 pending_disable_recording_ack_count_(0), | 121 pending_disable_recording_ack_count_(0), |
113 pending_capture_monitoring_snapshot_ack_count_(0), | 122 pending_capture_monitoring_snapshot_ack_count_(0), |
114 pending_trace_buffer_percent_full_ack_count_(0), | 123 pending_trace_buffer_percent_full_ack_count_(0), |
115 maximum_trace_buffer_percent_full_(0), | 124 maximum_trace_buffer_percent_full_(0), |
116 // Tracing may have been enabled by ContentMainRunner if kTraceStartup | 125 // Tracing may have been enabled by ContentMainRunner if kTraceStartup |
117 // is specified in command line. | 126 // is specified in command line. |
118 is_recording_(TraceLog::GetInstance()->IsEnabled()), | 127 is_recording_(TraceLog::GetInstance()->IsEnabled()), |
119 is_monitoring_(false), | 128 is_monitoring_(false) { |
120 category_filter_( | |
121 base::debug::CategoryFilter::kDefaultCategoryFilterString) { | |
122 } | 129 } |
123 | 130 |
124 TracingControllerImpl::~TracingControllerImpl() { | 131 TracingControllerImpl::~TracingControllerImpl() { |
125 // This is a Leaky instance. | 132 // This is a Leaky instance. |
126 NOTREACHED(); | 133 NOTREACHED(); |
127 } | 134 } |
128 | 135 |
129 TracingControllerImpl* TracingControllerImpl::GetInstance() { | 136 TracingControllerImpl* TracingControllerImpl::GetInstance() { |
130 return g_controller.Pointer(); | 137 return g_controller.Pointer(); |
131 } | 138 } |
132 | 139 |
133 void TracingControllerImpl::GetCategories( | 140 void TracingControllerImpl::GetCategories( |
134 const GetCategoriesDoneCallback& callback) { | 141 const GetCategoriesDoneCallback& callback) { |
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
136 | 143 |
137 // Known categories come back from child processes with the EndTracingAck | 144 // Known categories come back from child processes with the EndTracingAck |
138 // message. So to get known categories, just begin and end tracing immediately | 145 // message. So to get known categories, just begin and end tracing immediately |
139 // afterwards. This will ping all the child processes for categories. | 146 // afterwards. This will ping all the child processes for categories. |
140 pending_get_categories_done_callback_ = callback; | 147 pending_get_categories_done_callback_ = callback; |
141 EnableRecording(base::debug::CategoryFilter("*"), | 148 EnableRecording("*", TracingController::Options(), |
142 TracingController::Options(), | |
143 EnableRecordingDoneCallback()); | 149 EnableRecordingDoneCallback()); |
144 DisableRecording(base::FilePath(), TracingFileResultCallback()); | 150 DisableRecording(base::FilePath(), TracingFileResultCallback()); |
145 } | 151 } |
146 | 152 |
147 bool TracingControllerImpl::EnableRecording( | 153 bool TracingControllerImpl::EnableRecording( |
148 const base::debug::CategoryFilter& filter, | 154 const std::string& category_filter, |
149 TracingController::Options options, | 155 TracingController::Options options, |
150 const EnableRecordingDoneCallback& callback) { | 156 const EnableRecordingDoneCallback& callback) { |
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
152 | 158 |
153 if (!can_enable_recording()) | 159 if (!can_enable_recording()) |
154 return false; | 160 return false; |
155 | 161 |
156 #if defined(OS_ANDROID) | 162 #if defined(OS_ANDROID) |
157 if (pending_get_categories_done_callback_.is_null()) | 163 if (pending_get_categories_done_callback_.is_null()) |
158 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 164 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
159 #endif | 165 #endif |
160 | 166 |
161 TraceLog::Options trace_options = (options & RECORD_CONTINUOUSLY) ? | 167 TraceLog::Options trace_options = (options & RECORD_CONTINUOUSLY) ? |
162 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; | 168 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; |
163 if (options & ENABLE_SAMPLING) { | 169 if (options & ENABLE_SAMPLING) { |
164 trace_options = static_cast<TraceLog::Options>( | 170 trace_options = static_cast<TraceLog::Options>( |
165 trace_options | TraceLog::ENABLE_SAMPLING); | 171 trace_options | TraceLog::ENABLE_SAMPLING); |
166 } | 172 } |
167 // TODO(haraken): How to handle ENABLE_SYSTRACE? | 173 // TODO(haraken): How to handle ENABLE_SYSTRACE? |
168 | 174 |
169 TraceLog::GetInstance()->SetEnabled(filter, trace_options); | 175 TraceLog::GetInstance()->SetEnabled( |
| 176 base::debug::CategoryFilter(category_filter), trace_options); |
170 is_recording_ = true; | 177 is_recording_ = true; |
171 category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter(); | |
172 | 178 |
173 // Notify all child processes. | 179 // Notify all child processes. |
174 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { | 180 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
175 it->get()->SendBeginTracing(category_filter_.ToString(), trace_options); | 181 it != trace_message_filters_.end(); ++it) { |
| 182 it->get()->SendBeginTracing(category_filter, trace_options); |
176 } | 183 } |
177 | 184 |
178 if (!callback.is_null()) | 185 if (!callback.is_null()) |
179 callback.Run(); | 186 callback.Run(); |
180 return true; | 187 return true; |
181 } | 188 } |
182 | 189 |
183 bool TracingControllerImpl::DisableRecording( | 190 bool TracingControllerImpl::DisableRecording( |
184 const base::FilePath& result_file_path, | 191 const base::FilePath& result_file_path, |
185 const TracingFileResultCallback& callback) { | 192 const TracingFileResultCallback& callback) { |
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
187 | 194 |
188 if (!can_disable_recording()) | 195 if (!can_disable_recording()) |
189 return false; | 196 return false; |
190 | 197 |
191 pending_disable_recording_done_callback_ = callback; | 198 pending_disable_recording_done_callback_ = callback; |
192 | 199 |
193 // Disable local trace early to avoid traces during end-tracing process from | 200 // Disable local trace early to avoid traces during end-tracing process from |
194 // interfering with the process. | 201 // interfering with the process. |
195 TraceLog::GetInstance()->SetDisabled(); | 202 TraceLog::GetInstance()->SetDisabled(); |
196 | 203 |
197 #if defined(OS_ANDROID) | 204 #if defined(OS_ANDROID) |
198 if (pending_get_categories_done_callback_.is_null()) | 205 if (pending_get_categories_done_callback_.is_null()) |
199 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 206 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
200 #endif | 207 #endif |
201 | 208 |
202 if (!callback.is_null() || !result_file_path.empty()) | 209 if (!callback.is_null() || !result_file_path.empty()) |
203 result_file_.reset(new ResultFile(result_file_path)); | 210 result_file_.reset(new ResultFile(result_file_path)); |
204 | 211 |
205 // There could be a case where there are no child processes and filters_ | |
206 // is empty. In that case we can immediately tell the subscriber that tracing | |
207 // has ended. To avoid recursive calls back to the subscriber, we will just | |
208 // use the existing asynchronous OnDisableRecordingAcked code. | |
209 // Count myself (local trace) in pending_disable_recording_ack_count_, | 212 // Count myself (local trace) in pending_disable_recording_ack_count_, |
210 // acked below. | 213 // acked below. |
211 pending_disable_recording_ack_count_ = filters_.size() + 1; | 214 pending_disable_recording_ack_count_ = trace_message_filters_.size() + 1; |
212 | 215 |
213 // Handle special case of zero child processes. | 216 // Handle special case of zero child processes by immediately telling the |
| 217 // caller that tracing has ended. Use asynchronous OnDisableRecordingAcked |
| 218 // to avoid recursive call back to the caller. |
214 if (pending_disable_recording_ack_count_ == 1) { | 219 if (pending_disable_recording_ack_count_ == 1) { |
215 // Ack asynchronously now, because we don't have any children to wait for. | 220 // Ack asynchronously now, because we don't have any children to wait for. |
216 std::vector<std::string> category_groups; | 221 std::vector<std::string> category_groups; |
217 TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups); | 222 TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups); |
218 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 223 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
219 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, | 224 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, |
220 base::Unretained(this), category_groups)); | 225 base::Unretained(this), category_groups)); |
221 } | 226 } |
222 | 227 |
223 // Notify all child processes. | 228 // Notify all child processes. |
224 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { | 229 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
| 230 it != trace_message_filters_.end(); ++it) { |
225 it->get()->SendEndTracing(); | 231 it->get()->SendEndTracing(); |
226 } | 232 } |
227 return true; | 233 return true; |
228 } | 234 } |
229 | 235 |
230 bool TracingControllerImpl::EnableMonitoring( | 236 bool TracingControllerImpl::EnableMonitoring( |
231 const base::debug::CategoryFilter& filter, | 237 const std::string& category_filter, |
232 TracingController::Options options, | 238 TracingController::Options options, |
233 const EnableMonitoringDoneCallback& callback) { | 239 const EnableMonitoringDoneCallback& callback) { |
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
235 | 241 |
236 if (!can_enable_monitoring()) | 242 if (!can_enable_monitoring()) |
237 return false; | 243 return false; |
238 is_monitoring_ = true; | 244 is_monitoring_ = true; |
239 | 245 |
240 #if defined(OS_ANDROID) | 246 #if defined(OS_ANDROID) |
241 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 247 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
242 #endif | 248 #endif |
243 | 249 |
244 int monitoring_tracing_options = 0; | 250 int monitoring_tracing_options = 0; |
245 if (options & ENABLE_SAMPLING) | 251 if (options & ENABLE_SAMPLING) |
246 monitoring_tracing_options |= base::debug::TraceLog::MONITOR_SAMPLING; | 252 monitoring_tracing_options |= base::debug::TraceLog::MONITOR_SAMPLING; |
247 | 253 |
248 // Notify all child processes. | 254 // Notify all child processes. |
249 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { | 255 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
250 it->get()->SendEnableMonitoring(filter.ToString(), | 256 it != trace_message_filters_.end(); ++it) { |
| 257 it->get()->SendEnableMonitoring(category_filter, |
251 base::debug::TraceLog::Options(monitoring_tracing_options)); | 258 base::debug::TraceLog::Options(monitoring_tracing_options)); |
252 } | 259 } |
253 | 260 |
254 if (!callback.is_null()) | 261 if (!callback.is_null()) |
255 callback.Run(); | 262 callback.Run(); |
256 return true; | 263 return true; |
257 } | 264 } |
258 | 265 |
259 bool TracingControllerImpl::DisableMonitoring( | 266 bool TracingControllerImpl::DisableMonitoring( |
260 const DisableMonitoringDoneCallback& callback) { | 267 const DisableMonitoringDoneCallback& callback) { |
261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
262 | 269 |
263 if (!can_disable_monitoring()) | 270 if (!can_disable_monitoring()) |
264 return false; | 271 return false; |
265 is_monitoring_ = false; | 272 is_monitoring_ = false; |
266 | 273 |
267 // Notify all child processes. | 274 // Notify all child processes. |
268 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { | 275 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
| 276 it != trace_message_filters_.end(); ++it) { |
269 it->get()->SendDisableMonitoring(); | 277 it->get()->SendDisableMonitoring(); |
270 } | 278 } |
271 | 279 |
272 if (!callback.is_null()) | 280 if (!callback.is_null()) |
273 callback.Run(); | 281 callback.Run(); |
274 return true; | 282 return true; |
275 } | 283 } |
276 | 284 |
277 void TracingControllerImpl::GetMonitoringStatus( | 285 void TracingControllerImpl::GetMonitoringStatus( |
278 bool* out_enabled, | 286 bool* out_enabled, |
279 base::debug::CategoryFilter* out_filter, | 287 std::string* out_category_filter, |
280 TracingController::Options* out_options) { | 288 TracingController::Options* out_options) { |
281 NOTIMPLEMENTED(); | 289 NOTIMPLEMENTED(); |
282 } | 290 } |
283 | 291 |
284 void TracingControllerImpl::CaptureMonitoringSnapshot( | 292 void TracingControllerImpl::CaptureMonitoringSnapshot( |
285 const base::FilePath& result_file_path, | 293 const base::FilePath& result_file_path, |
286 const TracingFileResultCallback& callback) { | 294 const TracingFileResultCallback& callback) { |
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
288 | 296 |
289 if (!can_disable_monitoring()) | 297 if (!can_disable_monitoring()) |
290 return; | 298 return; |
291 | 299 |
292 pending_capture_monitoring_snapshot_done_callback_ = callback; | 300 pending_capture_monitoring_snapshot_done_callback_ = callback; |
293 | 301 |
294 if (!callback.is_null() || !result_file_path.empty()) | 302 if (!callback.is_null() || !result_file_path.empty()) |
295 monitoring_snapshot_file_.reset(new ResultFile(result_file_path)); | 303 monitoring_snapshot_file_.reset(new ResultFile(result_file_path)); |
296 | 304 |
297 // There could be a case where there are no child processes and filters_ | |
298 // is empty. In that case we can immediately tell the subscriber that tracing | |
299 // has ended. To avoid recursive calls back to the subscriber, we will just | |
300 // use the existing asynchronous OnCaptureMonitoringSnapshotAcked code. | |
301 // Count myself in pending_capture_monitoring_snapshot_ack_count_, | 305 // Count myself in pending_capture_monitoring_snapshot_ack_count_, |
302 // acked below. | 306 // acked below. |
303 pending_capture_monitoring_snapshot_ack_count_ = filters_.size() + 1; | 307 pending_capture_monitoring_snapshot_ack_count_ = |
| 308 trace_message_filters_.size() + 1; |
304 | 309 |
305 // Handle special case of zero child processes. | 310 // Handle special case of zero child processes by immediately telling the |
| 311 // caller that capturing snapshot has ended. Use asynchronous |
| 312 // OnCaptureMonitoringSnapshotAcked to avoid recursive call back to the |
| 313 // caller. |
306 if (pending_capture_monitoring_snapshot_ack_count_ == 1) { | 314 if (pending_capture_monitoring_snapshot_ack_count_ == 1) { |
307 // Ack asynchronously now, because we don't have any children to wait for. | 315 // Ack asynchronously now, because we don't have any children to wait for. |
308 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 316 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
309 base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked, | 317 base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked, |
310 base::Unretained(this))); | 318 base::Unretained(this))); |
311 } | 319 } |
312 | 320 |
313 // Notify all child processes. | 321 // Notify all child processes. |
314 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { | 322 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
| 323 it != trace_message_filters_.end(); ++it) { |
315 it->get()->SendCaptureMonitoringSnapshot(); | 324 it->get()->SendCaptureMonitoringSnapshot(); |
316 } | 325 } |
317 | 326 |
318 #if defined(OS_ANDROID) | 327 #if defined(OS_ANDROID) |
319 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 328 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
320 #endif | 329 #endif |
321 } | 330 } |
322 | 331 |
323 bool TracingControllerImpl::GetTraceBufferPercentFull( | 332 bool TracingControllerImpl::GetTraceBufferPercentFull( |
324 const GetTraceBufferPercentFullCallback& callback) { | 333 const GetTraceBufferPercentFullCallback& callback) { |
325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
326 | 335 |
327 if (!can_get_trace_buffer_percent_full() || callback.is_null()) | 336 if (!can_get_trace_buffer_percent_full() || callback.is_null()) |
328 return false; | 337 return false; |
329 | 338 |
330 pending_trace_buffer_percent_full_callback_ = callback; | 339 pending_trace_buffer_percent_full_callback_ = callback; |
331 | 340 |
332 // Count myself in pending_trace_buffer_percent_full_ack_count_, acked below. | 341 // Count myself in pending_trace_buffer_percent_full_ack_count_, acked below. |
333 pending_trace_buffer_percent_full_ack_count_ = filters_.size() + 1; | 342 pending_trace_buffer_percent_full_ack_count_ = |
| 343 trace_message_filters_.size() + 1; |
334 maximum_trace_buffer_percent_full_ = 0; | 344 maximum_trace_buffer_percent_full_ = 0; |
335 | 345 |
336 // Handle special case of zero child processes. | 346 // Handle special case of zero child processes. |
337 if (pending_trace_buffer_percent_full_ack_count_ == 1) { | 347 if (pending_trace_buffer_percent_full_ack_count_ == 1) { |
338 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 348 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
339 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, | 349 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, |
340 base::Unretained(this), | 350 base::Unretained(this), |
341 TraceLog::GetInstance()->GetBufferPercentFull())); | 351 TraceLog::GetInstance()->GetBufferPercentFull())); |
342 } | 352 } |
343 | 353 |
344 // Notify all child processes. | 354 // Notify all child processes. |
345 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { | 355 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
| 356 it != trace_message_filters_.end(); ++it) { |
346 it->get()->SendGetTraceBufferPercentFull(); | 357 it->get()->SendGetTraceBufferPercentFull(); |
347 } | 358 } |
348 return true; | 359 return true; |
349 } | 360 } |
350 | 361 |
351 void TracingControllerImpl::AddFilter(TraceMessageFilter* filter) { | 362 bool TracingControllerImpl::SetWatchEvent( |
| 363 const std::string& category_name, |
| 364 const std::string& event_name, |
| 365 const WatchEventCallback& callback) { |
| 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 367 |
| 368 if (!can_set_watch_event() || callback.is_null()) |
| 369 return false; |
| 370 |
| 371 watch_event_callback_ = callback; |
| 372 |
| 373 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
| 374 it != trace_message_filters_.end(); ++it) { |
| 375 it->get()->SendSetWatchEvent(category_name, event_name); |
| 376 } |
| 377 return true; |
| 378 } |
| 379 |
| 380 bool TracingControllerImpl::CancelWatchEvent() { |
| 381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 382 |
| 383 if (!can_cancel_watch_event()) |
| 384 return false; |
| 385 |
| 386 for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin(); |
| 387 it != trace_message_filters_.end(); ++it) { |
| 388 it->get()->SendCancelWatchEvent(); |
| 389 } |
| 390 |
| 391 watch_event_callback_.Reset(); |
| 392 return true; |
| 393 } |
| 394 |
| 395 void TracingControllerImpl::AddTraceMessageFilter( |
| 396 TraceMessageFilter* trace_message_filter) { |
352 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 397 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
353 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 398 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
354 base::Bind(&TracingControllerImpl::AddFilter, base::Unretained(this), | 399 base::Bind(&TracingControllerImpl::AddTraceMessageFilter, |
355 make_scoped_refptr(filter))); | 400 base::Unretained(this), |
| 401 make_scoped_refptr(trace_message_filter))); |
356 return; | 402 return; |
357 } | 403 } |
358 | 404 |
359 filters_.insert(filter); | 405 trace_message_filters_.insert(trace_message_filter); |
360 if (can_disable_recording()) { | 406 if (can_disable_recording()) { |
361 std::string cf_str = category_filter_.ToString(); | 407 trace_message_filter->SendBeginTracing( |
362 filter->SendBeginTracing(cf_str, TraceLog::GetInstance()->trace_options()); | 408 TraceLog::GetInstance()->GetCurrentCategoryFilter().ToString(), |
| 409 TraceLog::GetInstance()->trace_options()); |
363 } | 410 } |
364 } | 411 } |
365 | 412 |
366 void TracingControllerImpl::RemoveFilter(TraceMessageFilter* filter) { | 413 void TracingControllerImpl::RemoveTraceMessageFilter( |
| 414 TraceMessageFilter* trace_message_filter) { |
367 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 415 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
368 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 416 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
369 base::Bind(&TracingControllerImpl::RemoveFilter, base::Unretained(this), | 417 base::Bind(&TracingControllerImpl::RemoveTraceMessageFilter, |
370 make_scoped_refptr(filter))); | 418 base::Unretained(this), |
| 419 make_scoped_refptr(trace_message_filter))); |
371 return; | 420 return; |
372 } | 421 } |
373 | 422 |
374 filters_.erase(filter); | 423 trace_message_filters_.erase(trace_message_filter); |
375 } | 424 } |
376 | 425 |
377 void TracingControllerImpl::OnDisableRecordingAcked( | 426 void TracingControllerImpl::OnDisableRecordingAcked( |
378 const std::vector<std::string>& known_category_groups) { | 427 const std::vector<std::string>& known_category_groups) { |
379 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 428 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
380 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 429 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
381 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, | 430 base::Bind(&TracingControllerImpl::OnDisableRecordingAcked, |
382 base::Unretained(this), known_category_groups)); | 431 base::Unretained(this), known_category_groups)); |
383 return; | 432 return; |
384 } | 433 } |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 if (pending_trace_buffer_percent_full_ack_count_ == 1) { | 603 if (pending_trace_buffer_percent_full_ack_count_ == 1) { |
555 // The last ack represents local trace, so we need to ack it now. Note that | 604 // The last ack represents local trace, so we need to ack it now. Note that |
556 // this code only executes if there were child processes. | 605 // this code only executes if there were child processes. |
557 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 606 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
558 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, | 607 base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply, |
559 base::Unretained(this), | 608 base::Unretained(this), |
560 TraceLog::GetInstance()->GetBufferPercentFull())); | 609 TraceLog::GetInstance()->GetBufferPercentFull())); |
561 } | 610 } |
562 } | 611 } |
563 | 612 |
| 613 void TracingControllerImpl::OnWatchEventMatched() { |
| 614 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 615 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 616 base::Bind(&TracingControllerImpl::OnWatchEventMatched, |
| 617 base::Unretained(this))); |
| 618 } |
| 619 |
| 620 if (!watch_event_callback_.is_null()) |
| 621 watch_event_callback_.Run(); |
| 622 } |
| 623 |
| 624 // static |
| 625 bool TracingControllerImpl::ParseTracingParams( |
| 626 const base::DictionaryValue* params, |
| 627 std::string* category_filter, |
| 628 Options* options) { |
| 629 bool use_system_tracing; |
| 630 bool use_continuous_tracing; |
| 631 bool use_sampling; |
| 632 |
| 633 if (!params->GetString(kCategoryFilter, category_filter) || |
| 634 !params->GetBoolean(kUseSystemTracing, &use_system_tracing) || |
| 635 !params->GetBoolean(kUseContinuousTracing, &use_continuous_tracing) || |
| 636 !params->GetBoolean(kUseSampling, &use_sampling)) { |
| 637 LOG(ERROR) << "Malformed params"; |
| 638 return false; |
| 639 } |
| 640 |
| 641 int tracing_options = 0; |
| 642 if (use_system_tracing) |
| 643 tracing_options |= ENABLE_SYSTRACE; |
| 644 if (use_continuous_tracing) |
| 645 tracing_options |= RECORD_CONTINUOUSLY; |
| 646 if (use_sampling) |
| 647 tracing_options |= ENABLE_SAMPLING; |
| 648 |
| 649 *options = static_cast<Options>(tracing_options); |
| 650 return true; |
| 651 } |
| 652 |
| 653 // static |
| 654 void TracingControllerImpl::EncodeTracingParams( |
| 655 const std::string& category_filter, |
| 656 Options options, |
| 657 base::DictionaryValue* result) { |
| 658 result->SetString(kCategoryFilter, category_filter); |
| 659 result->SetBoolean(kUseSystemTracing, options & ENABLE_SYSTRACE); |
| 660 result->SetBoolean(kUseContinuousTracing, options & RECORD_CONTINUOUSLY); |
| 661 result->SetBoolean(kUseSampling, options & ENABLE_SAMPLING); |
| 662 } |
| 663 |
564 } // namespace content | 664 } // namespace content |
OLD | NEW |