OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #include "content/browser/tracing/tracing_controller_impl.h" | 4 #include "content/browser/tracing/tracing_controller_impl.h" |
5 | 5 |
6 #include <algorithm> | 6 #include <algorithm> |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 return TracingControllerImpl::GetInstance(); | 193 return TracingControllerImpl::GetInstance(); |
194 } | 194 } |
195 | 195 |
196 TracingControllerImpl::TracingControllerImpl() | 196 TracingControllerImpl::TracingControllerImpl() |
197 : pending_start_tracing_ack_count_(0), | 197 : pending_start_tracing_ack_count_(0), |
198 pending_stop_tracing_ack_count_(0), | 198 pending_stop_tracing_ack_count_(0), |
199 pending_trace_log_status_ack_count_(0), | 199 pending_trace_log_status_ack_count_(0), |
200 maximum_trace_buffer_usage_(0), | 200 maximum_trace_buffer_usage_(0), |
201 approximate_event_count_(0), | 201 approximate_event_count_(0), |
202 pending_clock_sync_ack_count_(0), | 202 pending_clock_sync_ack_count_(0), |
203 is_tracing_(false) { | 203 enabled_tracing_modes_(0) { |
204 // Deliberately leaked, like this class. | 204 // Deliberately leaked, like this class. |
205 base::FileTracing::SetProvider(new FileTracingProviderImpl); | 205 base::FileTracing::SetProvider(new FileTracingProviderImpl); |
206 } | 206 } |
207 | 207 |
208 TracingControllerImpl::~TracingControllerImpl() { | 208 TracingControllerImpl::~TracingControllerImpl() { |
209 // This is a Leaky instance. | 209 // This is a Leaky instance. |
210 NOTREACHED(); | 210 NOTREACHED(); |
211 } | 211 } |
212 | 212 |
213 TracingControllerImpl* TracingControllerImpl::GetInstance() { | 213 TracingControllerImpl* TracingControllerImpl::GetInstance() { |
(...skipping 13 matching lines...) Expand all Loading... |
227 return false; | 227 return false; |
228 } | 228 } |
229 | 229 |
230 bool ok = StopTracing(NULL); | 230 bool ok = StopTracing(NULL); |
231 DCHECK(ok); | 231 DCHECK(ok); |
232 return true; | 232 return true; |
233 } | 233 } |
234 | 234 |
235 void TracingControllerImpl::SetEnabledOnFileThread( | 235 void TracingControllerImpl::SetEnabledOnFileThread( |
236 const TraceConfig& trace_config, | 236 const TraceConfig& trace_config, |
237 int mode, | |
238 const base::Closure& callback) { | 237 const base::Closure& callback) { |
239 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 238 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
240 | 239 |
241 TraceLog::GetInstance()->SetEnabled( | 240 TraceLog::GetInstance()->SetEnabled(trace_config, enabled_tracing_modes_); |
242 trace_config, static_cast<TraceLog::Mode>(mode)); | |
243 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); | 241 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); |
244 } | 242 } |
245 | 243 |
246 void TracingControllerImpl::SetDisabledOnFileThread( | 244 void TracingControllerImpl::SetDisabledOnFileThread( |
247 const base::Closure& callback) { | 245 const base::Closure& callback) { |
248 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 246 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
249 | 247 |
250 TraceLog::GetInstance()->SetDisabled(); | 248 DCHECK(enabled_tracing_modes_); |
| 249 TraceLog::GetInstance()->SetDisabled(enabled_tracing_modes_); |
251 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); | 250 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); |
252 } | 251 } |
253 | 252 |
254 bool TracingControllerImpl::StartTracing( | 253 bool TracingControllerImpl::StartTracing( |
255 const TraceConfig& trace_config, | 254 const TraceConfig& trace_config, |
256 const StartTracingDoneCallback& callback) { | 255 const StartTracingDoneCallback& callback) { |
257 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 256 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
258 DCHECK(additional_tracing_agents_.empty()); | 257 DCHECK(additional_tracing_agents_.empty()); |
259 | 258 |
| 259 // TODO(ssid): Introduce a priority for tracing agents to handle multiple |
| 260 // start and stop requests, crbug.com/705087. |
260 if (!can_start_tracing()) | 261 if (!can_start_tracing()) |
261 return false; | 262 return false; |
262 is_tracing_ = true; | |
263 start_tracing_done_callback_ = callback; | 263 start_tracing_done_callback_ = callback; |
264 start_tracing_trace_config_.reset( | 264 start_tracing_trace_config_.reset( |
265 new base::trace_event::TraceConfig(trace_config)); | 265 new base::trace_event::TraceConfig(trace_config)); |
| 266 enabled_tracing_modes_ = TraceLog::RECORDING_MODE; |
| 267 if (!start_tracing_trace_config_->event_filters().empty()) |
| 268 enabled_tracing_modes_ |= TraceLog::FILTERING_MODE; |
266 metadata_.reset(new base::DictionaryValue()); | 269 metadata_.reset(new base::DictionaryValue()); |
267 pending_start_tracing_ack_count_ = 0; | 270 pending_start_tracing_ack_count_ = 0; |
268 | 271 |
269 #if defined(OS_ANDROID) | 272 #if defined(OS_ANDROID) |
270 if (pending_get_categories_done_callback_.is_null()) | 273 if (pending_get_categories_done_callback_.is_null()) |
271 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 274 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
272 #endif | 275 #endif |
273 | 276 |
274 if (trace_config.IsSystraceEnabled()) { | 277 if (trace_config.IsSystraceEnabled()) { |
275 #if defined(ENABLE_POWER_TRACING) | 278 #if defined(ENABLE_POWER_TRACING) |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 | 465 |
463 // Notify all child processes. | 466 // Notify all child processes. |
464 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | 467 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
465 it != trace_message_filters_.end(); ++it) { | 468 it != trace_message_filters_.end(); ++it) { |
466 it->get()->SendGetTraceLogStatus(); | 469 it->get()->SendGetTraceLogStatus(); |
467 } | 470 } |
468 return true; | 471 return true; |
469 } | 472 } |
470 | 473 |
471 bool TracingControllerImpl::IsTracing() const { | 474 bool TracingControllerImpl::IsTracing() const { |
472 return is_tracing_; | 475 return !!enabled_tracing_modes_; |
473 } | 476 } |
474 | 477 |
475 void TracingControllerImpl::AddTraceMessageFilter( | 478 void TracingControllerImpl::AddTraceMessageFilter( |
476 TraceMessageFilter* trace_message_filter) { | 479 TraceMessageFilter* trace_message_filter) { |
477 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 480 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
478 BrowserThread::PostTask( | 481 BrowserThread::PostTask( |
479 BrowserThread::UI, FROM_HERE, | 482 BrowserThread::UI, FROM_HERE, |
480 base::Bind(&TracingControllerImpl::AddTraceMessageFilter, | 483 base::Bind(&TracingControllerImpl::AddTraceMessageFilter, |
481 base::Unretained(this), | 484 base::Unretained(this), |
482 base::RetainedRef(trace_message_filter))); | 485 base::RetainedRef(trace_message_filter))); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 base::Unretained(this))); | 641 base::Unretained(this))); |
639 } | 642 } |
640 return; | 643 return; |
641 } | 644 } |
642 | 645 |
643 if (pending_stop_tracing_ack_count_ != 0) | 646 if (pending_stop_tracing_ack_count_ != 0) |
644 return; | 647 return; |
645 | 648 |
646 // All acks (including from the subprocesses and the local trace) have been | 649 // All acks (including from the subprocesses and the local trace) have been |
647 // received. | 650 // received. |
648 is_tracing_ = false; | 651 enabled_tracing_modes_ = 0; |
649 | 652 |
650 // Trigger callback if one is set. | 653 // Trigger callback if one is set. |
651 if (!pending_get_categories_done_callback_.is_null()) { | 654 if (!pending_get_categories_done_callback_.is_null()) { |
652 pending_get_categories_done_callback_.Run(known_category_groups_); | 655 pending_get_categories_done_callback_.Run(known_category_groups_); |
653 pending_get_categories_done_callback_.Reset(); | 656 pending_get_categories_done_callback_.Reset(); |
654 } else if (trace_data_sink_.get()) { | 657 } else if (trace_data_sink_.get()) { |
655 trace_data_sink_->Close(); | 658 trace_data_sink_->Close(); |
656 trace_data_sink_ = NULL; | 659 trace_data_sink_ = NULL; |
657 } | 660 } |
658 } | 661 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 const base::trace_event::TraceConfig& trace_config, | 772 const base::trace_event::TraceConfig& trace_config, |
770 const StartAgentTracingCallback& callback) { | 773 const StartAgentTracingCallback& callback) { |
771 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 774 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
772 | 775 |
773 base::Closure on_agent_started = | 776 base::Closure on_agent_started = |
774 base::Bind(callback, kChromeTracingAgentName, true); | 777 base::Bind(callback, kChromeTracingAgentName, true); |
775 if (!BrowserThread::PostTask( | 778 if (!BrowserThread::PostTask( |
776 BrowserThread::FILE, FROM_HERE, | 779 BrowserThread::FILE, FROM_HERE, |
777 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, | 780 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
778 base::Unretained(this), trace_config, | 781 base::Unretained(this), trace_config, |
779 base::trace_event::TraceLog::RECORDING_MODE, | |
780 on_agent_started))) { | 782 on_agent_started))) { |
781 // BrowserThread::PostTask fails if the threads haven't been created yet, | 783 // BrowserThread::PostTask fails if the threads haven't been created yet, |
782 // so it should be safe to just use TraceLog::SetEnabled directly. | 784 // so it should be safe to just use TraceLog::SetEnabled directly. |
783 base::trace_event::TraceLog::GetInstance()->SetEnabled( | 785 TraceLog::GetInstance()->SetEnabled(trace_config, enabled_tracing_modes_); |
784 trace_config, base::trace_event::TraceLog::RECORDING_MODE); | |
785 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_agent_started); | 786 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_agent_started); |
786 } | 787 } |
787 } | 788 } |
788 | 789 |
789 void TracingControllerImpl::StopAgentTracing( | 790 void TracingControllerImpl::StopAgentTracing( |
790 const StopAgentTracingCallback& callback) { | 791 const StopAgentTracingCallback& callback) { |
791 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 792 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
792 // Handle special case of zero child processes by immediately flushing the | 793 // Handle special case of zero child processes by immediately flushing the |
793 // trace log. Once the flush has completed the caller will be notified that | 794 // trace log. Once the flush has completed the caller will be notified that |
794 // tracing has ended. | 795 // tracing has ended. |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 void TracingControllerImpl::RemoveTraceMessageFilterObserver( | 909 void TracingControllerImpl::RemoveTraceMessageFilterObserver( |
909 TraceMessageFilterObserver* observer) { | 910 TraceMessageFilterObserver* observer) { |
910 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 911 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
911 trace_message_filter_observers_.RemoveObserver(observer); | 912 trace_message_filter_observers_.RemoveObserver(observer); |
912 | 913 |
913 for (auto& filter : trace_message_filters_) | 914 for (auto& filter : trace_message_filters_) |
914 observer->OnTraceMessageFilterRemoved(filter.get()); | 915 observer->OnTraceMessageFilterRemoved(filter.get()); |
915 } | 916 } |
916 | 917 |
917 } // namespace content | 918 } // namespace content |
OLD | NEW |