Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/background_tracing_manager_impl.h" | 5 #include "content/browser/tracing/background_tracing_manager_impl.h" |
| 6 | 6 |
| 7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/metrics/statistics_recorder.h" | 10 #include "base/metrics/statistics_recorder.h" |
| 11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 12 #include "components/tracing/tracing_messages.h" | |
| 13 #include "content/browser/tracing/trace_message_filter.h" | |
| 12 #include "content/public/browser/background_tracing_preemptive_config.h" | 14 #include "content/public/browser/background_tracing_preemptive_config.h" |
| 13 #include "content/public/browser/background_tracing_reactive_config.h" | 15 #include "content/public/browser/background_tracing_reactive_config.h" |
| 14 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 15 #include "content/public/browser/content_browser_client.h" | 17 #include "content/public/browser/content_browser_client.h" |
| 16 #include "content/public/browser/tracing_delegate.h" | 18 #include "content/public/browser/tracing_delegate.h" |
| 17 #include "content/public/common/content_client.h" | 19 #include "content/public/common/content_client.h" |
| 18 | 20 |
| 19 namespace content { | 21 namespace content { |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 | 77 |
| 76 BackgroundTracingManager* BackgroundTracingManager::GetInstance() { | 78 BackgroundTracingManager* BackgroundTracingManager::GetInstance() { |
| 77 return BackgroundTracingManagerImpl::GetInstance(); | 79 return BackgroundTracingManagerImpl::GetInstance(); |
| 78 } | 80 } |
| 79 | 81 |
| 80 BackgroundTracingManagerImpl* BackgroundTracingManagerImpl::GetInstance() { | 82 BackgroundTracingManagerImpl* BackgroundTracingManagerImpl::GetInstance() { |
| 81 return g_controller.Pointer(); | 83 return g_controller.Pointer(); |
| 82 } | 84 } |
| 83 | 85 |
| 84 BackgroundTracingManagerImpl::BackgroundTracingManagerImpl() | 86 BackgroundTracingManagerImpl::BackgroundTracingManagerImpl() |
| 85 : delegate_(GetContentClient()->browser()->GetTracingDelegate()), | 87 : is_gathering_(false), |
| 86 is_gathering_(false), | |
| 87 is_tracing_(false), | 88 is_tracing_(false), |
| 88 requires_anonymized_data_(true), | 89 requires_anonymized_data_(true), |
| 89 trigger_handle_ids_(0) { | 90 trigger_handle_ids_(0) { |
| 91 CreateDelegate(); | |
| 90 } | 92 } |
| 91 | 93 |
| 92 BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() { | 94 BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() { |
| 93 NOTREACHED(); | 95 NOTREACHED(); |
| 94 } | 96 } |
| 95 | 97 |
| 98 void BackgroundTracingManagerImpl::CreateDelegate() { | |
| 99 // The delegate must be instantiated on the UI thread, so if the | |
| 100 // 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
| |
| 101 // we'll need to defer initializing it. | |
| 102 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { | |
| 103 content::BrowserThread::PostTask( | |
| 104 content::BrowserThread::UI, FROM_HERE, | |
| 105 base::Bind(&BackgroundTracingManagerImpl::CreateDelegate, | |
| 106 base::Unretained(this))); | |
| 107 return; | |
| 108 } | |
| 109 delegate_.reset(GetContentClient()->browser()->GetTracingDelegate()); | |
| 110 } | |
| 111 | |
| 96 void BackgroundTracingManagerImpl::WhenIdle( | 112 void BackgroundTracingManagerImpl::WhenIdle( |
| 97 base::Callback<void()> idle_callback) { | 113 base::Callback<void()> idle_callback) { |
| 98 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 114 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 99 idle_callback_ = idle_callback; | 115 idle_callback_ = idle_callback; |
| 100 } | 116 } |
| 101 | 117 |
| 102 bool BackgroundTracingManagerImpl::IsSupportedConfig( | 118 bool BackgroundTracingManagerImpl::IsSupportedConfig( |
| 103 BackgroundTracingConfig* config) { | 119 BackgroundTracingConfig* config) { |
| 104 // No config is just fine, we just don't do anything. | 120 // No config is just fine, we just don't do anything. |
| 105 if (!config) | 121 if (!config) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE) { | 169 MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE) { |
| 154 continue; | 170 continue; |
| 155 } | 171 } |
| 156 | 172 |
| 157 if (mode == CLEAR_CALLBACKS) { | 173 if (mode == CLEAR_CALLBACKS) { |
| 158 base::StatisticsRecorder::ClearCallback( | 174 base::StatisticsRecorder::ClearCallback( |
| 159 configs[i].histogram_trigger_info.histogram_name); | 175 configs[i].histogram_trigger_info.histogram_name); |
| 160 } else { | 176 } else { |
| 161 base::StatisticsRecorder::SetCallback( | 177 base::StatisticsRecorder::SetCallback( |
| 162 configs[i].histogram_trigger_info.histogram_name, | 178 configs[i].histogram_trigger_info.histogram_name, |
| 163 base::Bind(&BackgroundTracingManagerImpl::OnHistogramChanged, | 179 base::Bind(&BackgroundTracingManagerImpl::OnHistogramChangedCallback, |
| 164 base::Unretained(this), | 180 base::Unretained(this), |
| 165 configs[i].histogram_trigger_info.histogram_name, | 181 configs[i].histogram_trigger_info.histogram_name, |
| 166 configs[i].histogram_trigger_info.histogram_value)); | 182 configs[i].histogram_trigger_info.histogram_value)); |
| 167 } | 183 } |
| 168 } | 184 } |
| 185 | |
| 186 SetupFiltersFromConfig(mode); | |
| 169 } | 187 } |
| 170 | 188 |
| 171 void BackgroundTracingManagerImpl::OnHistogramChanged( | 189 void BackgroundTracingManagerImpl::OnHistogramTrigger( |
| 172 const std::string& histogram_name, | 190 const std::string& histogram_name) { |
| 173 base::Histogram::Sample reference_value, | |
| 174 base::Histogram::Sample actual_value) { | |
| 175 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { | 191 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
| 176 content::BrowserThread::PostTask( | 192 content::BrowserThread::PostTask( |
| 177 content::BrowserThread::UI, FROM_HERE, | 193 content::BrowserThread::UI, FROM_HERE, |
| 178 base::Bind(&BackgroundTracingManagerImpl::OnHistogramChanged, | 194 base::Bind(&BackgroundTracingManagerImpl::OnHistogramTrigger, |
| 179 base::Unretained(this), histogram_name, reference_value, | 195 base::Unretained(this), histogram_name)); |
| 180 actual_value)); | |
| 181 return; | 196 return; |
| 182 } | 197 } |
| 183 | 198 |
| 184 CHECK(config_ && | 199 CHECK(config_ && |
| 185 config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE); | 200 config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE); |
| 186 | 201 |
| 202 if (!is_tracing_ || is_gathering_) | |
| 203 return; | |
| 204 | |
| 205 BackgroundTracingPreemptiveConfig* preemptive_config = | |
| 206 static_cast<BackgroundTracingPreemptiveConfig*>(config_.get()); | |
| 207 const std::vector<BackgroundTracingPreemptiveConfig::MonitoringRule>& | |
| 208 configs = preemptive_config->configs; | |
| 209 for (size_t i = 0; i < configs.size(); ++i) { | |
| 210 if (configs[i].type != | |
| 211 BackgroundTracingPreemptiveConfig:: | |
| 212 MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE) { | |
| 213 continue; | |
| 214 } | |
| 215 | |
| 216 if (configs[i].histogram_trigger_info.histogram_name == histogram_name) { | |
| 217 RecordBackgroundTracingMetric(PREEMPTIVE_TRIGGERED); | |
| 218 BeginFinalizing(StartedFinalizingCallback()); | |
| 219 } | |
| 220 } | |
| 221 } | |
| 222 | |
| 223 void BackgroundTracingManagerImpl::OnHistogramChangedCallback( | |
| 224 const std::string& histogram_name, | |
| 225 base::Histogram::Sample reference_value, | |
| 226 base::Histogram::Sample actual_value) { | |
| 187 if (reference_value > actual_value) | 227 if (reference_value > actual_value) |
| 188 return; | 228 return; |
| 189 | 229 |
| 190 if (!is_tracing_ || is_gathering_) | 230 OnHistogramTrigger(histogram_name); |
| 191 return; | |
| 192 | |
| 193 RecordBackgroundTracingMetric(PREEMPTIVE_TRIGGERED); | |
| 194 BeginFinalizing(StartedFinalizingCallback()); | |
| 195 } | 231 } |
| 196 | 232 |
| 197 bool BackgroundTracingManagerImpl::SetActiveScenario( | 233 bool BackgroundTracingManagerImpl::SetActiveScenario( |
| 198 scoped_ptr<BackgroundTracingConfig> config, | 234 scoped_ptr<BackgroundTracingConfig> config, |
| 199 const BackgroundTracingManager::ReceiveCallback& receive_callback, | 235 const BackgroundTracingManager::ReceiveCallback& receive_callback, |
| 200 DataFiltering data_filtering) { | 236 DataFiltering data_filtering) { |
| 201 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 237 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 202 RecordBackgroundTracingMetric(SCENARIO_ACTIVATION_REQUESTED); | 238 RecordBackgroundTracingMetric(SCENARIO_ACTIVATION_REQUESTED); |
| 203 | 239 |
| 204 if (is_tracing_) | 240 if (is_tracing_) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 EnableRecordingIfConfigNeedsIt(); | 277 EnableRecordingIfConfigNeedsIt(); |
| 242 | 278 |
| 243 RecordBackgroundTracingMetric(SCENARIO_ACTIVATED_SUCCESSFULLY); | 279 RecordBackgroundTracingMetric(SCENARIO_ACTIVATED_SUCCESSFULLY); |
| 244 return true; | 280 return true; |
| 245 } | 281 } |
| 246 | 282 |
| 247 bool BackgroundTracingManagerImpl::HasActiveScenarioForTesting() { | 283 bool BackgroundTracingManagerImpl::HasActiveScenarioForTesting() { |
| 248 return config_; | 284 return config_; |
| 249 } | 285 } |
| 250 | 286 |
| 287 void BackgroundTracingManagerImpl::AddFilter( | |
| 288 scoped_refptr<TraceMessageFilter> filter) { | |
| 289 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
| |
| 290 content::BrowserThread::PostTask( | |
| 291 content::BrowserThread::UI, FROM_HERE, | |
| 292 base::Bind(&BackgroundTracingManagerImpl::AddFilter, | |
| 293 base::Unretained(this), filter)); | |
| 294 return; | |
| 295 } | |
| 296 | |
| 297 filters_.insert(filter); | |
| 298 SetupFilterFromConfig(filter, BIND_CALLBACKS); | |
| 299 } | |
| 300 | |
| 301 void BackgroundTracingManagerImpl::RemoveFilter( | |
| 302 scoped_refptr<TraceMessageFilter> filter) { | |
| 303 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { | |
|
oystein (OOO til 10th of July)
2015/07/21 20:52:45
Same thread question as AddFilter
| |
| 304 content::BrowserThread::PostTask( | |
| 305 content::BrowserThread::UI, FROM_HERE, | |
| 306 base::Bind(&BackgroundTracingManagerImpl::RemoveFilter, | |
| 307 base::Unretained(this), filter)); | |
| 308 return; | |
| 309 } | |
| 310 | |
| 311 filters_.erase(filter); | |
| 312 } | |
| 313 | |
| 314 void BackgroundTracingManagerImpl::SetupFiltersFromConfig( | |
| 315 BackgroundTracingManagerImpl::SetupUMACallMode mode) { | |
| 316 for (auto it = filters_.begin(); it != filters_.end(); ++it) | |
| 317 SetupFilterFromConfig(*it, mode); | |
| 318 } | |
| 319 | |
| 320 void BackgroundTracingManagerImpl::SetupFilterFromConfig( | |
| 321 scoped_refptr<TraceMessageFilter> filter, | |
| 322 BackgroundTracingManagerImpl::SetupUMACallMode mode) { | |
| 323 if (!config_ || | |
| 324 config_->mode != BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) | |
| 325 return; | |
| 326 | |
| 327 BackgroundTracingPreemptiveConfig* preemptive_config = | |
| 328 static_cast<BackgroundTracingPreemptiveConfig*>(config_.get()); | |
| 329 | |
| 330 const std::vector<BackgroundTracingPreemptiveConfig::MonitoringRule>& | |
| 331 configs = preemptive_config->configs; | |
| 332 | |
| 333 for (size_t i = 0; i < configs.size(); ++i) { | |
| 334 if (configs[i].type != | |
| 335 BackgroundTracingPreemptiveConfig:: | |
| 336 MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE) { | |
| 337 continue; | |
| 338 } | |
| 339 | |
| 340 if (mode == CLEAR_CALLBACKS) { | |
| 341 filter->Send(new TracingMsg_ClearUMACallback( | |
| 342 configs[i].histogram_trigger_info.histogram_name)); | |
| 343 } else { | |
| 344 filter->Send(new TracingMsg_SetUMACallback( | |
| 345 configs[i].histogram_trigger_info.histogram_name, | |
| 346 configs[i].histogram_trigger_info.histogram_value)); | |
| 347 } | |
| 348 } | |
| 349 } | |
| 350 | |
| 251 void BackgroundTracingManagerImpl::ValidateStartupScenario() { | 351 void BackgroundTracingManagerImpl::ValidateStartupScenario() { |
| 252 if (!config_ || !delegate_) | 352 if (!config_ || !delegate_) |
| 253 return; | 353 return; |
| 254 | 354 |
| 255 if (!delegate_->IsAllowedToBeginBackgroundScenario( | 355 if (!delegate_->IsAllowedToBeginBackgroundScenario( |
| 256 *config_.get(), requires_anonymized_data_)) { | 356 *config_.get(), requires_anonymized_data_)) { |
| 257 AbortScenario(); | 357 AbortScenario(); |
| 258 } | 358 } |
| 259 } | 359 } |
| 260 | 360 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 RecordBackgroundTracingMetric(FINALIZATION_DISALLOWED); | 611 RecordBackgroundTracingMetric(FINALIZATION_DISALLOWED); |
| 512 } | 612 } |
| 513 | 613 |
| 514 content::TracingController::GetInstance()->DisableRecording(trace_data_sink); | 614 content::TracingController::GetInstance()->DisableRecording(trace_data_sink); |
| 515 | 615 |
| 516 if (!callback.is_null()) | 616 if (!callback.is_null()) |
| 517 callback.Run(is_allowed_finalization); | 617 callback.Run(is_allowed_finalization); |
| 518 } | 618 } |
| 519 | 619 |
| 520 void BackgroundTracingManagerImpl::AbortScenario() { | 620 void BackgroundTracingManagerImpl::AbortScenario() { |
| 621 SetupUMACallbacks(CLEAR_CALLBACKS); | |
| 622 | |
| 521 is_tracing_ = false; | 623 is_tracing_ = false; |
| 522 config_.reset(); | 624 config_.reset(); |
| 523 | 625 |
| 524 content::TracingController::GetInstance()->DisableRecording(nullptr); | 626 content::TracingController::GetInstance()->DisableRecording(nullptr); |
| 525 } | 627 } |
| 526 | 628 |
| 527 std::string | 629 std::string |
| 528 BackgroundTracingManagerImpl::GetCategoryFilterStringForCategoryPreset( | 630 BackgroundTracingManagerImpl::GetCategoryFilterStringForCategoryPreset( |
| 529 BackgroundTracingConfig::CategoryPreset preset) const { | 631 BackgroundTracingConfig::CategoryPreset preset) const { |
| 530 switch (preset) { | 632 switch (preset) { |
| 531 case BackgroundTracingConfig::CategoryPreset::BENCHMARK: | 633 case BackgroundTracingConfig::CategoryPreset::BENCHMARK: |
| 532 return "benchmark,toplevel"; | 634 return "benchmark,toplevel"; |
| 533 case BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP: | 635 case BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP: |
| 534 return "*,disabled-by-default-benchmark.detailed"; | 636 return "*,disabled-by-default-benchmark.detailed"; |
| 535 } | 637 } |
| 536 NOTREACHED(); | 638 NOTREACHED(); |
| 537 return ""; | 639 return ""; |
| 538 } | 640 } |
| 539 | 641 |
| 540 } // namspace content | 642 } // namspace content |
| OLD | NEW |