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