Chromium Code Reviews| Index: content/browser/tracing/background_tracing_manager_impl.cc |
| diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc |
| index 68392b2c1e9f798b933b288169b672efb173426c..8acad9ef5e805242294b7382698c4d68b375adf1 100644 |
| --- a/content/browser/tracing/background_tracing_manager_impl.cc |
| +++ b/content/browser/tracing/background_tracing_manager_impl.cc |
| @@ -9,6 +9,8 @@ |
| #include "base/metrics/histogram_macros.h" |
| #include "base/metrics/statistics_recorder.h" |
| #include "base/time/time.h" |
| +#include "components/tracing/tracing_messages.h" |
| +#include "content/browser/tracing/trace_message_filter.h" |
| #include "content/public/browser/background_tracing_preemptive_config.h" |
| #include "content/public/browser/background_tracing_reactive_config.h" |
| #include "content/public/browser/browser_thread.h" |
| @@ -82,17 +84,31 @@ BackgroundTracingManagerImpl* BackgroundTracingManagerImpl::GetInstance() { |
| } |
| BackgroundTracingManagerImpl::BackgroundTracingManagerImpl() |
| - : delegate_(GetContentClient()->browser()->GetTracingDelegate()), |
| - is_gathering_(false), |
| + : is_gathering_(false), |
| is_tracing_(false), |
| requires_anonymized_data_(true), |
| trigger_handle_ids_(0) { |
| + CreateDelegate(); |
| } |
| BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() { |
| NOTREACHED(); |
| } |
| +void BackgroundTracingManagerImpl::CreateDelegate() { |
| + // The delegate must be instantiated on the UI thread, so if the |
| + // first access to the BackgroundTracingManagerImpl is from another thread |
|
oystein (OOO til 10th of July)
2015/07/21 20:52:45
When does this happen? Can we be sure there's no r
shatch
2015/07/22 17:44:13
This happened in a few tests where the message fil
|
| + // we'll need to defer initializing it. |
| + if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| + base::Bind(&BackgroundTracingManagerImpl::CreateDelegate, |
| + base::Unretained(this))); |
| + return; |
| + } |
| + delegate_.reset(GetContentClient()->browser()->GetTracingDelegate()); |
| +} |
| + |
| void BackgroundTracingManagerImpl::WhenIdle( |
| base::Callback<void()> idle_callback) { |
| CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| @@ -160,38 +176,58 @@ void BackgroundTracingManagerImpl::SetupUMACallbacks( |
| } else { |
| base::StatisticsRecorder::SetCallback( |
| configs[i].histogram_trigger_info.histogram_name, |
| - base::Bind(&BackgroundTracingManagerImpl::OnHistogramChanged, |
| + base::Bind(&BackgroundTracingManagerImpl::OnHistogramChangedCallback, |
| base::Unretained(this), |
| configs[i].histogram_trigger_info.histogram_name, |
| configs[i].histogram_trigger_info.histogram_value)); |
| } |
| } |
| + |
| + SetupFiltersFromConfig(mode); |
| } |
| -void BackgroundTracingManagerImpl::OnHistogramChanged( |
| - const std::string& histogram_name, |
| - base::Histogram::Sample reference_value, |
| - base::Histogram::Sample actual_value) { |
| +void BackgroundTracingManagerImpl::OnHistogramTrigger( |
| + const std::string& histogram_name) { |
| if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
| content::BrowserThread::PostTask( |
| content::BrowserThread::UI, FROM_HERE, |
| - base::Bind(&BackgroundTracingManagerImpl::OnHistogramChanged, |
| - base::Unretained(this), histogram_name, reference_value, |
| - actual_value)); |
| + base::Bind(&BackgroundTracingManagerImpl::OnHistogramTrigger, |
| + base::Unretained(this), histogram_name)); |
| return; |
| } |
| CHECK(config_ && |
| config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE); |
| - if (reference_value > actual_value) |
| + if (!is_tracing_ || is_gathering_) |
| return; |
| - if (!is_tracing_ || is_gathering_) |
| + BackgroundTracingPreemptiveConfig* preemptive_config = |
| + static_cast<BackgroundTracingPreemptiveConfig*>(config_.get()); |
| + const std::vector<BackgroundTracingPreemptiveConfig::MonitoringRule>& |
| + configs = preemptive_config->configs; |
| + for (size_t i = 0; i < configs.size(); ++i) { |
| + if (configs[i].type != |
| + BackgroundTracingPreemptiveConfig:: |
| + MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE) { |
| + continue; |
| + } |
| + |
| + if (configs[i].histogram_trigger_info.histogram_name == histogram_name) { |
| + RecordBackgroundTracingMetric(PREEMPTIVE_TRIGGERED); |
| + BeginFinalizing(StartedFinalizingCallback()); |
| + } |
| + } |
| +} |
| + |
| +void BackgroundTracingManagerImpl::OnHistogramChangedCallback( |
| + const std::string& histogram_name, |
| + base::Histogram::Sample reference_value, |
| + base::Histogram::Sample actual_value) { |
| + if (reference_value > actual_value) |
| return; |
| - RecordBackgroundTracingMetric(PREEMPTIVE_TRIGGERED); |
| - BeginFinalizing(StartedFinalizingCallback()); |
| + OnHistogramTrigger(histogram_name); |
| } |
| bool BackgroundTracingManagerImpl::SetActiveScenario( |
| @@ -248,6 +284,70 @@ bool BackgroundTracingManagerImpl::HasActiveScenarioForTesting() { |
| return config_; |
| } |
| +void BackgroundTracingManagerImpl::AddFilter( |
| + scoped_refptr<TraceMessageFilter> filter) { |
| + if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
|
oystein (OOO til 10th of July)
2015/07/21 20:52:45
Which threads can this be called on? Wouldn't this
shatch
2015/07/22 17:44:13
Called via OnChildSupportsTracing from the TraceMe
|
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| + base::Bind(&BackgroundTracingManagerImpl::AddFilter, |
| + base::Unretained(this), filter)); |
| + return; |
| + } |
| + |
| + filters_.insert(filter); |
| + SetupFilterFromConfig(filter, BIND_CALLBACKS); |
| +} |
| + |
| +void BackgroundTracingManagerImpl::RemoveFilter( |
| + scoped_refptr<TraceMessageFilter> filter) { |
| + if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
|
oystein (OOO til 10th of July)
2015/07/21 20:52:45
Same thread question as AddFilter
|
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| + base::Bind(&BackgroundTracingManagerImpl::RemoveFilter, |
| + base::Unretained(this), filter)); |
| + return; |
| + } |
| + |
| + filters_.erase(filter); |
| +} |
| + |
| +void BackgroundTracingManagerImpl::SetupFiltersFromConfig( |
| + BackgroundTracingManagerImpl::SetupUMACallMode mode) { |
| + for (auto it = filters_.begin(); it != filters_.end(); ++it) |
| + SetupFilterFromConfig(*it, mode); |
| +} |
| + |
| +void BackgroundTracingManagerImpl::SetupFilterFromConfig( |
| + scoped_refptr<TraceMessageFilter> filter, |
| + BackgroundTracingManagerImpl::SetupUMACallMode mode) { |
| + if (!config_ || |
| + config_->mode != BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) |
| + return; |
| + |
| + BackgroundTracingPreemptiveConfig* preemptive_config = |
| + static_cast<BackgroundTracingPreemptiveConfig*>(config_.get()); |
| + |
| + const std::vector<BackgroundTracingPreemptiveConfig::MonitoringRule>& |
| + configs = preemptive_config->configs; |
| + |
| + for (size_t i = 0; i < configs.size(); ++i) { |
| + if (configs[i].type != |
| + BackgroundTracingPreemptiveConfig:: |
| + MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE) { |
| + continue; |
| + } |
| + |
| + if (mode == CLEAR_CALLBACKS) { |
| + filter->Send(new TracingMsg_ClearUMACallback( |
| + configs[i].histogram_trigger_info.histogram_name)); |
| + } else { |
| + filter->Send(new TracingMsg_SetUMACallback( |
| + configs[i].histogram_trigger_info.histogram_name, |
| + configs[i].histogram_trigger_info.histogram_value)); |
| + } |
| + } |
| +} |
| + |
| void BackgroundTracingManagerImpl::ValidateStartupScenario() { |
| if (!config_ || !delegate_) |
| return; |
| @@ -518,6 +618,8 @@ void BackgroundTracingManagerImpl::BeginFinalizing( |
| } |
| void BackgroundTracingManagerImpl::AbortScenario() { |
| + SetupUMACallbacks(CLEAR_CALLBACKS); |
| + |
| is_tracing_ = false; |
| config_.reset(); |