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))); | |
piman
2013/11/15 23:42:52
What makes Unretained here safe?
Xianzhu
2013/11/16 01:16:14
TracingControllerImpl instance is a leaky singleto
| |
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 |