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/macros.h" | 8 #include "base/macros.h" |
| 8 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/strings/string_split.h" | |
| 9 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 10 #include "content/public/browser/background_tracing_preemptive_config.h" | 12 #include "content/public/browser/background_tracing_preemptive_config.h" |
| 11 #include "content/public/browser/background_tracing_reactive_config.h" | 13 #include "content/public/browser/background_tracing_reactive_config.h" |
| 12 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 13 #include "content/public/browser/content_browser_client.h" | 15 #include "content/public/browser/content_browser_client.h" |
| 14 #include "content/public/browser/tracing_delegate.h" | 16 #include "content/public/browser/tracing_delegate.h" |
| 15 #include "content/public/common/content_client.h" | 17 #include "content/public/common/content_client.h" |
| 16 | 18 |
| 17 namespace content { | 19 namespace content { |
| 18 | 20 |
| 19 namespace { | 21 namespace { |
| 20 | 22 |
| 21 base::LazyInstance<BackgroundTracingManagerImpl>::Leaky g_controller = | 23 base::LazyInstance<BackgroundTracingManagerImpl>::Leaky g_controller = |
| 22 LAZY_INSTANCE_INITIALIZER; | 24 LAZY_INSTANCE_INITIALIZER; |
| 23 | 25 |
| 26 const char kMetaDataConfigKey[] = "config"; | |
| 27 const char kMetaDataVersionKey[] = "version"; | |
| 28 | |
| 24 // These values are used for a histogram. Do not reorder. | 29 // These values are used for a histogram. Do not reorder. |
| 25 enum BackgroundTracingMetrics { | 30 enum BackgroundTracingMetrics { |
| 26 SCENARIO_ACTIVATION_REQUESTED = 0, | 31 SCENARIO_ACTIVATION_REQUESTED = 0, |
| 27 SCENARIO_ACTIVATED_SUCCESSFULLY = 1, | 32 SCENARIO_ACTIVATED_SUCCESSFULLY = 1, |
| 28 RECORDING_ENABLED = 2, | 33 RECORDING_ENABLED = 2, |
| 29 PREEMPTIVE_TRIGGERED = 3, | 34 PREEMPTIVE_TRIGGERED = 3, |
| 30 REACTIVE_TRIGGERED = 4, | 35 REACTIVE_TRIGGERED = 4, |
| 31 FINALIZATION_ALLOWED = 5, | 36 FINALIZATION_ALLOWED = 5, |
| 32 FINALIZATION_DISALLOWED = 6, | 37 FINALIZATION_DISALLOWED = 6, |
| 33 FINALIZATION_STARTED = 7, | 38 FINALIZATION_STARTED = 7, |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 } | 368 } |
| 364 | 369 |
| 365 void BackgroundTracingManagerImpl::OnFinalizeStarted( | 370 void BackgroundTracingManagerImpl::OnFinalizeStarted( |
| 366 scoped_refptr<base::RefCountedString> file_contents) { | 371 scoped_refptr<base::RefCountedString> file_contents) { |
| 367 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 372 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 368 | 373 |
| 369 RecordBackgroundTracingMetric(FINALIZATION_STARTED); | 374 RecordBackgroundTracingMetric(FINALIZATION_STARTED); |
| 370 UMA_HISTOGRAM_MEMORY_KB("Tracing.Background.FinalizingTraceSizeInKB", | 375 UMA_HISTOGRAM_MEMORY_KB("Tracing.Background.FinalizingTraceSizeInKB", |
| 371 file_contents->size() / 1024); | 376 file_contents->size() / 1024); |
| 372 | 377 |
| 373 if (!receive_callback_.is_null()) | 378 if (!receive_callback_.is_null()) { |
| 379 std::map<std::string, std::string> metadata; | |
| 380 | |
| 381 auto metadata_dict = GenerateMetadataDict(); | |
| 382 if (metadata_dict) { | |
| 383 for (base::DictionaryValue::Iterator it(*metadata_dict); !it.IsAtEnd(); | |
| 384 it.Advance()) { | |
| 385 std::string value; | |
| 386 if (!it.value().GetAsString(&value)) | |
| 387 continue; | |
| 388 metadata.insert(std::make_pair(it.key(), value)); | |
| 389 } | |
| 390 } | |
| 391 | |
| 374 receive_callback_.Run( | 392 receive_callback_.Run( |
| 375 file_contents, | 393 file_contents, metadata, |
| 376 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete, | 394 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete, |
| 377 base::Unretained(this))); | 395 base::Unretained(this))); |
| 396 } | |
| 378 } | 397 } |
| 379 | 398 |
| 380 void BackgroundTracingManagerImpl::OnFinalizeComplete() { | 399 void BackgroundTracingManagerImpl::OnFinalizeComplete() { |
| 381 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 400 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 382 BrowserThread::PostTask( | 401 BrowserThread::PostTask( |
| 383 BrowserThread::UI, FROM_HERE, | 402 BrowserThread::UI, FROM_HERE, |
| 384 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete, | 403 base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete, |
| 385 base::Unretained(this))); | 404 base::Unretained(this))); |
| 386 return; | 405 return; |
| 387 } | 406 } |
| 388 | 407 |
| 389 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 408 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 390 | 409 |
| 391 is_gathering_ = false; | 410 is_gathering_ = false; |
| 392 | 411 |
| 393 if (!idle_callback_.is_null()) | 412 if (!idle_callback_.is_null()) |
| 394 idle_callback_.Run(); | 413 idle_callback_.Run(); |
| 395 | 414 |
| 396 // Now that a trace has completed, we may need to enable recording again. | 415 // Now that a trace has completed, we may need to enable recording again. |
| 397 EnableRecordingIfConfigNeedsIt(); | 416 EnableRecordingIfConfigNeedsIt(); |
| 398 RecordBackgroundTracingMetric(FINALIZATION_COMPLETE); | 417 RecordBackgroundTracingMetric(FINALIZATION_COMPLETE); |
| 399 } | 418 } |
| 400 | 419 |
| 420 scoped_ptr<base::DictionaryValue> | |
| 421 BackgroundTracingManagerImpl::GenerateMetadataDict() const { | |
| 422 // Grab the product version. | |
| 423 std::string product_version = GetContentClient()->GetProduct(); | |
| 424 std::vector<std::string> product_components; | |
| 425 base::SplitString(product_version, '/', &product_components); | |
| 426 DCHECK_EQ(2U, product_components.size()); | |
| 427 if (product_components.size() != 2U) | |
| 428 return nullptr; | |
| 429 | |
| 430 product_version = product_components[1]; | |
|
oystein (OOO til 10th of July)
2015/06/12 19:29:16
Is it worth cutting out the "Chrome/" part? Could
shatch
2015/06/12 20:53:47
Done.
| |
| 431 | |
| 432 // Serialize the config into json. | |
| 433 scoped_ptr<base::DictionaryValue> config_dict(new base::DictionaryValue()); | |
| 434 | |
| 435 BackgroundTracingConfig::IntoDict(config_.get(), config_dict.get()); | |
| 436 | |
| 437 std::string config_string; | |
| 438 if (!base::JSONWriter::Write(*config_dict.get(), &config_string)) | |
| 439 return nullptr; | |
| 440 | |
| 441 scoped_ptr<base::DictionaryValue> metadata_dict(new base::DictionaryValue()); | |
| 442 metadata_dict->SetString(kMetaDataConfigKey, config_string); | |
| 443 metadata_dict->SetString(kMetaDataVersionKey, product_version); | |
| 444 | |
| 445 return metadata_dict.Pass(); | |
| 446 } | |
| 447 | |
| 401 void BackgroundTracingManagerImpl::BeginFinalizing( | 448 void BackgroundTracingManagerImpl::BeginFinalizing( |
| 402 StartedFinalizingCallback callback) { | 449 StartedFinalizingCallback callback) { |
| 403 is_gathering_ = true; | 450 is_gathering_ = true; |
| 404 is_tracing_ = false; | 451 is_tracing_ = false; |
| 405 | 452 |
| 406 bool is_allowed_finalization = | 453 bool is_allowed_finalization = |
| 407 !delegate_ || (config_ && | 454 !delegate_ || (config_ && |
| 408 delegate_->IsAllowedToEndBackgroundScenario( | 455 delegate_->IsAllowedToEndBackgroundScenario( |
| 409 *config_.get(), requires_anonymized_data_)); | 456 *config_.get(), requires_anonymized_data_)); |
| 410 | 457 |
| 411 scoped_refptr<TracingControllerImpl::TraceDataSink> trace_data_sink; | 458 scoped_refptr<TracingControllerImpl::TraceDataSink> trace_data_sink; |
| 412 if (is_allowed_finalization) { | 459 if (is_allowed_finalization) { |
| 413 trace_data_sink = content::TracingController::CreateCompressedStringSink( | 460 trace_data_sink = content::TracingController::CreateCompressedStringSink( |
| 414 data_endpoint_wrapper_); | 461 data_endpoint_wrapper_); |
| 415 RecordBackgroundTracingMetric(FINALIZATION_ALLOWED); | 462 RecordBackgroundTracingMetric(FINALIZATION_ALLOWED); |
| 463 | |
| 464 auto metadata_dict = GenerateMetadataDict(); | |
| 465 if (metadata_dict) { | |
| 466 std::string results; | |
| 467 if (base::JSONWriter::Write(*metadata_dict.get(), &results)) | |
|
dsinclair
2015/06/12 19:38:51
This is going to produce strange levels of encodin
shatch
2015/06/12 20:53:48
Ah didn't think about the double encoding, checked
| |
| 468 trace_data_sink->SetMetadata(results); | |
| 469 } | |
| 416 } else { | 470 } else { |
| 417 RecordBackgroundTracingMetric(FINALIZATION_DISALLOWED); | 471 RecordBackgroundTracingMetric(FINALIZATION_DISALLOWED); |
| 418 } | 472 } |
| 419 | 473 |
| 420 content::TracingController::GetInstance()->DisableRecording(trace_data_sink); | 474 content::TracingController::GetInstance()->DisableRecording(trace_data_sink); |
| 421 | 475 |
| 422 if (!callback.is_null()) | 476 if (!callback.is_null()) |
| 423 callback.Run(is_allowed_finalization); | 477 callback.Run(is_allowed_finalization); |
| 424 } | 478 } |
| 425 | 479 |
| 426 std::string | 480 std::string |
| 427 BackgroundTracingManagerImpl::GetCategoryFilterStringForCategoryPreset( | 481 BackgroundTracingManagerImpl::GetCategoryFilterStringForCategoryPreset( |
| 428 BackgroundTracingConfig::CategoryPreset preset) const { | 482 BackgroundTracingConfig::CategoryPreset preset) const { |
| 429 switch (preset) { | 483 switch (preset) { |
| 430 case BackgroundTracingConfig::CategoryPreset::BENCHMARK: | 484 case BackgroundTracingConfig::CategoryPreset::BENCHMARK: |
| 431 return "benchmark," | 485 return "benchmark," |
| 432 "disabled-by-default-toplevel.flow," | 486 "disabled-by-default-toplevel.flow," |
| 433 "disabled-by-default-ipc.flow"; | 487 "disabled-by-default-ipc.flow"; |
| 434 case BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP: | 488 case BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP: |
| 435 return "*,disabled-by-default-blink.debug.layout"; | 489 return "*,disabled-by-default-blink.debug.layout"; |
| 436 } | 490 } |
| 437 NOTREACHED(); | 491 NOTREACHED(); |
| 438 return ""; | 492 return ""; |
| 439 } | 493 } |
| 440 | 494 |
| 441 } // namspace content | 495 } // namspace content |
| OLD | NEW |