Commit c9cd43c8 authored by simonhatch's avatar simonhatch Committed by Commit bot

Skeleton for BackgroundTracingManager.

This version mostly just directs the TracingController using the specified BackgroundTracingConfig and pushes the compressed trace out to the BackgroundTracingUploadSink.

Specifically, we implement the PREEMPTIVE_TRACING_MODE for the rule MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED, which should allow us to get an experiment going on desktop with a simple trigger and upload.

We can then follow up with additional CL's implementing the rest of the functionality from the clientside doc below.

Needs to land first: https://codereview.chromium.org/1088673003/

Slow Reports Clientside: https://docs.google.com/document/d/1qZmXmodxOKmsTRO27z2WlH2h9Kpf-kjV-k-1pJIogIE/edit?pli=1

go/slow-reports

Review URL: https://codereview.chromium.org/1089253003

Cr-Commit-Position: refs/heads/master@{#330942}
parent 774a30f2
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind.h"
#include "content/public/browser/background_tracing_manager.h"
#include "content/public/browser/background_tracing_preemptive_config.h"
#include "content/public/browser/background_tracing_reactive_config.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
namespace content {
class BackgroundTracingManagerBrowserTest : public ContentBrowserTest {
public:
BackgroundTracingManagerBrowserTest() {}
private:
DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerBrowserTest);
};
class BackgroundTracingManagerUploadConfigWrapper {
public:
BackgroundTracingManagerUploadConfigWrapper(const base::Closure& callback)
: callback_(callback), receive_count_(0) {
receive_callback_ =
base::Bind(&BackgroundTracingManagerUploadConfigWrapper::Upload,
base::Unretained(this));
}
void Upload(const base::RefCountedString* file_contents,
base::Callback<void()> done_callback) {
receive_count_ += 1;
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(done_callback));
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(callback_));
}
int get_receive_count() const { return receive_count_; }
const BackgroundTracingManager::ReceiveCallback& get_receive_callback()
const {
return receive_callback_;
}
private:
BackgroundTracingManager::ReceiveCallback receive_callback_;
base::Closure callback_;
int receive_count_;
};
void StartedFinalizingCallback(base::Closure callback,
bool expected,
bool value) {
EXPECT_EQ(expected, value);
if (!callback.is_null())
callback.Run();
}
scoped_ptr<BackgroundTracingPreemptiveConfig> CreatePreemptiveConfig() {
scoped_ptr<BackgroundTracingPreemptiveConfig> config(
new BackgroundTracingPreemptiveConfig());
BackgroundTracingPreemptiveConfig::MonitoringRule rule;
rule.type =
BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
rule.named_trigger_info.trigger_name = "test";
config->configs.push_back(rule);
return config.Pass();
}
void SetupBackgroundTracingManager() {
content::BackgroundTracingManager::GetInstance()
->InvalidateTriggerHandlesForTesting();
}
void DisableScenarioWhenIdle() {
BackgroundTracingManager::GetInstance()->SetActiveScenario(
NULL, BackgroundTracingManager::ReceiveCallback(), false);
}
// This tests that the endpoint receives the final trace data.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
ReceiveTraceFinalContentsOnTrigger) {
{
SetupBackgroundTracingManager();
base::RunLoop run_loop;
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
run_loop.QuitClosure());
scoped_ptr<BackgroundTracingPreemptiveConfig> config =
CreatePreemptiveConfig();
BackgroundTracingManager::TriggerHandle handle =
BackgroundTracingManager::GetInstance()->RegisterTriggerType("test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
config.Pass(), upload_config_wrapper.get_receive_callback(), true);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
run_loop.Run();
EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
}
}
// This tests triggering more than once still only gathers once.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
CallTriggersMoreThanOnceOnlyGatherOnce) {
{
SetupBackgroundTracingManager();
base::RunLoop run_loop;
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
run_loop.QuitClosure());
scoped_ptr<BackgroundTracingPreemptiveConfig> config =
CreatePreemptiveConfig();
content::BackgroundTracingManager::TriggerHandle handle =
content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
"test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
config.Pass(), upload_config_wrapper.get_receive_callback(), true);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle, base::Bind(&StartedFinalizingCallback, base::Closure(), false));
run_loop.Run();
EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
}
}
// This tests multiple triggers still only gathers once.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
CallMultipleTriggersOnlyGatherOnce) {
{
SetupBackgroundTracingManager();
base::RunLoop run_loop;
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
run_loop.QuitClosure());
scoped_ptr<BackgroundTracingPreemptiveConfig> config =
CreatePreemptiveConfig();
BackgroundTracingPreemptiveConfig::MonitoringRule rule;
rule.type =
BackgroundTracingPreemptiveConfig::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
rule.named_trigger_info.trigger_name = "test1";
config->configs.push_back(rule);
rule.named_trigger_info.trigger_name = "test2";
config->configs.push_back(rule);
BackgroundTracingManager::TriggerHandle handle1 =
BackgroundTracingManager::GetInstance()->RegisterTriggerType("test1");
BackgroundTracingManager::TriggerHandle handle2 =
BackgroundTracingManager::GetInstance()->RegisterTriggerType("test2");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
config.Pass(), upload_config_wrapper.get_receive_callback(), true);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle1, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle2,
base::Bind(&StartedFinalizingCallback, base::Closure(), false));
run_loop.Run();
EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
}
}
// This tests that you can't trigger without a scenario set.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
CannotTriggerWithoutScenarioSet) {
{
SetupBackgroundTracingManager();
base::RunLoop run_loop;
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
(base::Closure()));
scoped_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();
content::BackgroundTracingManager::TriggerHandle handle =
content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
"test");
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle,
base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
run_loop.Run();
EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
}
}
// This tests that no trace is triggered with a handle that isn't specified
// in the config.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
DoesNotTriggerWithWrongHandle) {
{
SetupBackgroundTracingManager();
base::RunLoop run_loop;
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
(base::Closure()));
scoped_ptr<BackgroundTracingPreemptiveConfig> config =
CreatePreemptiveConfig();
content::BackgroundTracingManager::TriggerHandle handle =
content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
"does_not_exist");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
config.Pass(), upload_config_wrapper.get_receive_callback(), true);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle,
base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
run_loop.Run();
EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
}
}
// This tests that no trace is triggered with an invalid handle.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
DoesNotTriggerWithInvalidHandle) {
{
SetupBackgroundTracingManager();
base::RunLoop run_loop;
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
(base::Closure()));
scoped_ptr<BackgroundTracingPreemptiveConfig> config =
CreatePreemptiveConfig();
content::BackgroundTracingManager::TriggerHandle handle =
content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
"test");
content::BackgroundTracingManager::GetInstance()
->InvalidateTriggerHandlesForTesting();
BackgroundTracingManager::GetInstance()->SetActiveScenario(
config.Pass(), upload_config_wrapper.get_receive_callback(), true);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
handle,
base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
run_loop.Run();
EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
}
}
// This tests that reactive mode configs will fail.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
DoesNotAllowPreemptiveConfigThatsNotManual) {
{
SetupBackgroundTracingManager();
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
(base::Closure()));
scoped_ptr<BackgroundTracingPreemptiveConfig> config(
new content::BackgroundTracingPreemptiveConfig());
BackgroundTracingPreemptiveConfig::MonitoringRule rule;
rule.type = BackgroundTracingPreemptiveConfig::
MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE;
rule.histogram_trigger_info.histogram_name_to_trigger_on = "fake";
rule.histogram_trigger_info.histogram_bin_to_trigger_on = 0;
config->configs.push_back(rule);
bool result = BackgroundTracingManager::GetInstance()->SetActiveScenario(
config.Pass(), upload_config_wrapper.get_receive_callback(), true);
EXPECT_FALSE(result);
}
}
// This tests that reactive mode configs will fail.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
DoesNotAllowReactiveConfig) {
{
SetupBackgroundTracingManager();
BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
(base::Closure()));
scoped_ptr<BackgroundTracingConfig> config(
new BackgroundTracingReactiveConfig());
bool result = BackgroundTracingManager::GetInstance()->SetActiveScenario(
config.Pass(), upload_config_wrapper.get_receive_callback(), true);
EXPECT_FALSE(result);
}
}
} // namespace content
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "base/macros.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"
namespace content {
namespace {
base::LazyInstance<BackgroundTracingManagerImpl>::Leaky g_controller =
LAZY_INSTANCE_INITIALIZER;
} // namespace
BackgroundTracingManagerImpl::TraceDataEndpointWrapper::
TraceDataEndpointWrapper(base::Callback<
void(scoped_refptr<base::RefCountedString>)> done_callback)
: done_callback_(done_callback) {
}
BackgroundTracingManagerImpl::TraceDataEndpointWrapper::
~TraceDataEndpointWrapper() {
}
void BackgroundTracingManagerImpl::TraceDataEndpointWrapper::
ReceiveTraceFinalContents(const std::string& file_contents) {
std::string tmp = file_contents;
scoped_refptr<base::RefCountedString> contents_ptr =
base::RefCountedString::TakeString(&tmp);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(done_callback_, contents_ptr));
}
BackgroundTracingManager* BackgroundTracingManager::GetInstance() {
return BackgroundTracingManagerImpl::GetInstance();
}
BackgroundTracingManagerImpl* BackgroundTracingManagerImpl::GetInstance() {
return g_controller.Pointer();
}
BackgroundTracingManagerImpl::BackgroundTracingManagerImpl()
: is_gathering_(false),
is_tracing_(false),
requires_anonymized_data_(true),
trigger_handle_ids_(0) {
data_endpoint_wrapper_ = new TraceDataEndpointWrapper(
base::Bind(&BackgroundTracingManagerImpl::OnFinalizeStarted,
base::Unretained(this)));
}
BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() {
NOTREACHED();
}
void BackgroundTracingManagerImpl::WhenIdle(
base::Callback<void()> idle_callback) {
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
idle_callback_ = idle_callback;
}
bool BackgroundTracingManagerImpl::IsSupportedConfig(
BackgroundTracingConfig* config) {
// No config is just fine, we just don't do anything.
if (!config)
return true;
// TODO(simonhatch): Implement reactive tracing path.
if (config->mode != BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE)
return false;
// TODO(fmeawad): Implement uma triggers.
BackgroundTracingPreemptiveConfig* preemptive_config =
static_cast<BackgroundTracingPreemptiveConfig*>(config);
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_TRIGGER_NAMED)
return false;
}
return true;
}
bool BackgroundTracingManagerImpl::SetActiveScenario(
scoped_ptr<BackgroundTracingConfig> config,
const BackgroundTracingManager::ReceiveCallback& receive_callback,
bool requires_anonymized_data) {
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (is_tracing_)
return false;
if (!IsSupportedConfig(config.get()))
return false;
// No point in tracing if there's nowhere to send it.
if (config && receive_callback.is_null())
return false;
config_ = config.Pass();
receive_callback_ = receive_callback;
requires_anonymized_data_ = requires_anonymized_data;
EnableRecordingIfConfigNeedsIt();
return true;
}
void BackgroundTracingManagerImpl::EnableRecordingIfConfigNeedsIt() {
if (!config_)
return;
if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) {
EnableRecording(GetCategoryFilterForCategoryPreset(
static_cast<BackgroundTracingPreemptiveConfig*>(config_.get())
->category_preset));
} else {
// TODO(simonhatch): Implement reactive tracing path.
NOTREACHED();
}
}
bool BackgroundTracingManagerImpl::IsAbleToTriggerTracing(
TriggerHandle handle) const {
if (!config_)
return false;
// If the last trace is still uploading, we don't allow a new one to trigger.
if (is_gathering_)
return false;
if (!IsTriggerHandleValid(handle)) {
return false;
}
std::string trigger_name = GetTriggerNameFromHandle(handle);
if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) {
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_TRIGGER_NAMED)
continue;
if (trigger_name == configs[i].named_trigger_info.trigger_name) {
return true;
}
}
} else {
// TODO(simonhatch): Implement reactive path.
NOTREACHED();
}
return false;
}
void BackgroundTracingManagerImpl::TriggerNamedEvent(
BackgroundTracingManagerImpl::TriggerHandle handle,
StartedFinalizingCallback callback) {
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&BackgroundTracingManagerImpl::TriggerNamedEvent,
base::Unretained(this), handle, callback));
return;
}
if (!IsAbleToTriggerTracing(handle)) {
if (!callback.is_null())
callback.Run(false);
return;
}
if (config_->mode == BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE) {
BeginFinalizing(callback);
} else {
// TODO(simonhatch): Implement reactive tracing path.
NOTREACHED();
}
}
BackgroundTracingManagerImpl::TriggerHandle
BackgroundTracingManagerImpl::RegisterTriggerType(const char* trigger_name) {
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
trigger_handle_ids_ += 1;
trigger_handles_.insert(
std::pair<TriggerHandle, std::string>(trigger_handle_ids_, trigger_name));
return static_cast<TriggerHandle>(trigger_handle_ids_);
}
bool BackgroundTracingManagerImpl::IsTriggerHandleValid(
BackgroundTracingManager::TriggerHandle handle) const {
return trigger_handles_.find(handle) != trigger_handles_.end();
}
std::string BackgroundTracingManagerImpl::GetTriggerNameFromHandle(
BackgroundTracingManager::TriggerHandle handle) const {
CHECK(IsTriggerHandleValid(handle));
return trigger_handles_.find(handle)->second;
}
void BackgroundTracingManagerImpl::GetTriggerNameList(
std::vector<std::string>* trigger_names) {
for (std::map<TriggerHandle, std::string>::iterator it =
trigger_handles_.begin();
it != trigger_handles_.end(); ++it)
trigger_names->push_back(it->second);
}
void BackgroundTracingManagerImpl::InvalidateTriggerHandlesForTesting() {
trigger_handles_.clear();
}
void BackgroundTracingManagerImpl::EnableRecording(
base::trace_event::CategoryFilter category_filter) {
is_tracing_ = TracingController::GetInstance()->EnableRecording(
category_filter,
base::trace_event::TraceOptions(base::trace_event::RECORD_CONTINUOUSLY),
TracingController::EnableRecordingDoneCallback());
}
void BackgroundTracingManagerImpl::OnFinalizeStarted(
scoped_refptr<base::RefCountedString> file_contents) {
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (!receive_callback_.is_null())
receive_callback_.Run(
file_contents.get(),
base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete,
base::Unretained(this)));
}
void BackgroundTracingManagerImpl::OnFinalizeComplete() {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete,
base::Unretained(this)));
return;
}
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
is_gathering_ = false;
if (!idle_callback_.is_null())
idle_callback_.Run();
// Now that a trace has completed, we may need to enable recording again.
EnableRecordingIfConfigNeedsIt();
}
void BackgroundTracingManagerImpl::BeginFinalizing(
StartedFinalizingCallback callback) {
is_gathering_ = true;
is_tracing_ = false;
content::TracingController::GetInstance()->DisableRecording(
content::TracingController::CreateCompressedStringSink(
data_endpoint_wrapper_));
if (!callback.is_null())
callback.Run(true);
}
base::trace_event::CategoryFilter
BackgroundTracingManagerImpl::GetCategoryFilterForCategoryPreset(
BackgroundTracingConfig::CategoryPreset preset) const {
switch (preset) {
case BackgroundTracingConfig::CategoryPreset::BENCHMARK:
return base::trace_event::CategoryFilter(
"benchmark,"
"disabled-by-default-toplevel.flow,"
"disabled-by-default-ipc.flow");
case BackgroundTracingConfig::CategoryPreset::BENCHMARK_DEEP:
return base::trace_event::CategoryFilter(
"*,disabled-by-default-blink.debug.layout");
}
NOTREACHED();
return base::trace_event::CategoryFilter();
}
BackgroundTracingConfig* BackgroundTracingConfig::FromDict(
const base::DictionaryValue* dict) {
// TODO(simonhatch): Implement this.
CHECK(false);
return NULL;
}
void BackgroundTracingConfig::IntoDict(const BackgroundTracingConfig* config,
base::DictionaryValue* dict) {
// TODO(simonhatch): Implement this.
CHECK(false);
}
} // namspace content
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
#define CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
#include "base/lazy_instance.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/tracing/tracing_controller_impl.h"
#include "content/public/browser/background_tracing_config.h"
#include "content/public/browser/background_tracing_manager.h"
namespace content {
class BackgroundTracingManagerImpl : public content::BackgroundTracingManager {
public:
static BackgroundTracingManagerImpl* GetInstance();
bool SetActiveScenario(scoped_ptr<BackgroundTracingConfig>,
const ReceiveCallback&,
bool) override;
void WhenIdle(IdleCallback idle_callback) override;
void TriggerNamedEvent(TriggerHandle, StartedFinalizingCallback) override;
TriggerHandle RegisterTriggerType(const char* trigger_name) override;
void GetTriggerNameList(std::vector<std::string>* trigger_names) override;
void InvalidateTriggerHandlesForTesting() override;
private:
BackgroundTracingManagerImpl();
~BackgroundTracingManagerImpl() override;
void EnableRecording(base::trace_event::CategoryFilter);
void EnableRecordingIfConfigNeedsIt();
void OnFinalizeStarted(scoped_refptr<base::RefCountedString>);
void OnFinalizeComplete();
void BeginFinalizing(StartedFinalizingCallback);
std::string GetTriggerNameFromHandle(TriggerHandle handle) const;
bool IsTriggerHandleValid(TriggerHandle handle) const;
bool IsAbleToTriggerTracing(TriggerHandle handle) const;
bool IsSupportedConfig(BackgroundTracingConfig* config);
base::trace_event::CategoryFilter GetCategoryFilterForCategoryPreset(
BackgroundTracingConfig::CategoryPreset) const;
class TraceDataEndpointWrapper
: public content::TracingController::TraceDataEndpoint {
public:
TraceDataEndpointWrapper(base::Callback<
void(scoped_refptr<base::RefCountedString>)> done_callback);
void ReceiveTraceFinalContents(const std::string& file_contents) override;
private:
~TraceDataEndpointWrapper() override;
base::Callback<void(scoped_refptr<base::RefCountedString>)> done_callback_;
};
scoped_ptr<content::BackgroundTracingConfig> config_;
scoped_refptr<TraceDataEndpointWrapper> data_endpoint_wrapper_;
std::map<TriggerHandle, std::string> trigger_handles_;
ReceiveCallback receive_callback_;
bool is_gathering_;
bool is_tracing_;
bool requires_anonymized_data_;
int trigger_handle_ids_;
IdleCallback idle_callback_;
friend struct base::DefaultLazyInstanceTraits<BackgroundTracingManagerImpl>;
DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerImpl);
};
} // namespace content
#endif // CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
...@@ -70,6 +70,13 @@ ...@@ -70,6 +70,13 @@
'public/browser/appcache_service.h', 'public/browser/appcache_service.h',
'public/browser/ax_event_notification_details.cc', 'public/browser/ax_event_notification_details.cc',
'public/browser/ax_event_notification_details.h', 'public/browser/ax_event_notification_details.h',
'public/browser/background_tracing_config.cc',
'public/browser/background_tracing_config.h',
'public/browser/background_tracing_manager.h',
'public/browser/background_tracing_preemptive_config.cc',
'public/browser/background_tracing_preemptive_config.h',
'public/browser/background_tracing_reactive_config.cc',
'public/browser/background_tracing_reactive_config.h',
'public/browser/blob_handle.h', 'public/browser/blob_handle.h',
'public/browser/browser_accessibility_state.h', 'public/browser/browser_accessibility_state.h',
'public/browser/browser_child_process_host.h', 'public/browser/browser_child_process_host.h',
...@@ -1448,6 +1455,8 @@ ...@@ -1448,6 +1455,8 @@
'browser/time_zone_monitor_linux.cc', 'browser/time_zone_monitor_linux.cc',
'browser/time_zone_monitor_mac.mm', 'browser/time_zone_monitor_mac.mm',
'browser/time_zone_monitor_win.cc', 'browser/time_zone_monitor_win.cc',
'browser/tracing/background_tracing_manager_impl.cc',
'browser/tracing/background_tracing_manager_impl.h',
'browser/tracing/etw_system_event_consumer_win.cc', 'browser/tracing/etw_system_event_consumer_win.cc',
'browser/tracing/etw_system_event_consumer_win.h', 'browser/tracing/etw_system_event_consumer_win.h',
'browser/tracing/file_tracing_provider_impl.cc', 'browser/tracing/file_tracing_provider_impl.cc',
......
...@@ -239,6 +239,7 @@ ...@@ -239,6 +239,7 @@
'browser/shared_worker/worker_browsertest.cc', 'browser/shared_worker/worker_browsertest.cc',
'browser/site_per_process_browsertest.cc', 'browser/site_per_process_browsertest.cc',
'browser/site_per_process_browsertest.h', 'browser/site_per_process_browsertest.h',
'browser/tracing/background_tracing_manager_browsertest.cc',
'browser/tracing/tracing_controller_browsertest.cc', 'browser/tracing/tracing_controller_browsertest.cc',
'browser/web_contents/opened_by_dom_browsertest.cc', 'browser/web_contents/opened_by_dom_browsertest.cc',
'browser/web_contents/touch_editable_impl_aura_browsertest.cc', 'browser/web_contents/touch_editable_impl_aura_browsertest.cc',
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/browser/background_tracing_config.h"
namespace content {
BackgroundTracingConfig::BackgroundTracingConfig(Mode mode) : mode(mode) {
}
BackgroundTracingConfig::~BackgroundTracingConfig() {
}
} // namespace content
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_CONFIG_H_
#define CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_CONFIG_H_
#include "base/trace_event/trace_event_impl.h"
#include "content/common/content_export.h"
namespace base {
class DictionaryValue;
}
namespace content {
// BackgroundTracingConfig is passed to the BackgroundTracingManager to
// setup the trigger rules used to enable/disable background tracing.
struct CONTENT_EXPORT BackgroundTracingConfig {
virtual ~BackgroundTracingConfig();
enum Mode {
PREEMPTIVE_TRACING_MODE,
REACTIVE_TRACING_MODE,
};
enum CategoryPreset {
BENCHMARK,
BENCHMARK_DEEP,
};
Mode mode;
static BackgroundTracingConfig* FromDict(const base::DictionaryValue* dict);
static void IntoDict(const BackgroundTracingConfig* config,
base::DictionaryValue* dict);
protected:
BackgroundTracingConfig(Mode mode);
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_CONFIG_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_MANAGER_H_
#define CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_MANAGER_H_
#include "base/trace_event/trace_event_impl.h"
#include "base/values.h"
#include "content/common/content_export.h"
namespace content {
struct BackgroundTracingConfig;
struct BackgroundTracingUploadConfig;
// BackgroundTracingManager is used on the browser process to trigger the
// collection of trace data and upload the results. Only the browser UI thread
// is allowed to interact with the BackgroundTracingManager. All callbacks are
// called on the UI thread.
class BackgroundTracingManager {
public:
CONTENT_EXPORT static BackgroundTracingManager* GetInstance();
// ReceiveCallback will will be called on the UI thread every time the
// BackgroundTracingManager finalizes a trace. The first parameter of
// this callback is the trace data. The second is a callback to
// notify the BackgroundTracingManager that you've finished processing
// the trace data.
//
// Example:
//
// void Upload(const base::RefCountedString* data,
// base::Closure done_callback) {
// BrowserThread::PostTaskAndReply(
// BrowserThread::FILE,
// FROM_HERE,
// base::Bind(&DoUploadOnFileThread, data),
// done_callback
// );
// }
//
typedef base::Callback<void(const base::RefCountedString*, base::Closure)>
ReceiveCallback;
// Set the triggering rules for when to start recording.
//
// In preemptive mode, recording begins immediately and any calls to
// TriggerNamedEvent() will potentially trigger the trace to finalize and get
// uploaded to the specified upload_sink. Once the trace has been uploaded,
// tracing will be enabled again.
//
// In reactive mode, recording begins when TriggerNamedEvent() is called, and
// continues until either the next call to TriggerNamedEvent, or a timeout
// occurs. Tracing will not be re-enabled after the trace is finalized and
// uploaded to the upload_sink.
//
// Calls to SetActiveScenario() with a config will fail if tracing is
// currently on. Use WhenIdle to register a callback to get notified when
// the manager is idle and a config can be set again.
virtual bool SetActiveScenario(scoped_ptr<BackgroundTracingConfig> config,
const ReceiveCallback& receive_callback,
bool requires_anonymized_data) = 0;
// Notifies the caller when the manager is idle (not recording or uploading),
// so that a call to SetActiveScenario() is likely to succeed.
typedef base::Callback<void()> IdleCallback;
virtual void WhenIdle(IdleCallback idle_callback) = 0;
typedef base::Callback<void(bool)> StartedFinalizingCallback;
typedef int TriggerHandle;
// Notifies that a manual trigger event has occurred, and we may need to
// either begin recording or finalize the trace, depending on the config.
// If the trigger specified isn't active in the config, this will do nothing.
virtual void TriggerNamedEvent(
TriggerHandle trigger_handle,
StartedFinalizingCallback started_callback) = 0;
// Registers a manual trigger handle, and returns a TriggerHandle which can
// be passed to DidTriggerHappen().
virtual TriggerHandle RegisterTriggerType(const char* trigger_name) = 0;
// Returns a list of all registered triggers.
virtual void GetTriggerNameList(std::vector<std::string>* trigger_names) = 0;
virtual void InvalidateTriggerHandlesForTesting() = 0;
protected:
virtual ~BackgroundTracingManager() {}
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_MANAGER_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/browser/background_tracing_preemptive_config.h"
namespace content {
BackgroundTracingPreemptiveConfig::BackgroundTracingPreemptiveConfig()
: BackgroundTracingConfig(BackgroundTracingConfig::PREEMPTIVE_TRACING_MODE),
category_preset(BackgroundTracingConfig::BENCHMARK) {
}
BackgroundTracingPreemptiveConfig::~BackgroundTracingPreemptiveConfig() {
}
} // namespace content
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_PREEMPTIVE_CONFIG_H_
#define CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_PREEMPTIVE_CONFIG_H_
#include "content/public/browser/background_tracing_config.h"
namespace content {
// BackgroundTracingPreemptiveConfig holds trigger rules for use during
// preemptive tracing. Tracing will be enabled immediately, and whenever
// a trigger occurs, the trace will be finalized.
struct CONTENT_EXPORT BackgroundTracingPreemptiveConfig
: public BackgroundTracingConfig {
public:
BackgroundTracingPreemptiveConfig();
~BackgroundTracingPreemptiveConfig() override;
enum RuleType {
MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED,
MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE,
MONITOR_AND_DUMP_WHEN_BROWSER_STARTUP_COMPLETE,
};
struct HistogramTriggerInfo {
std::string histogram_name_to_trigger_on;
int histogram_bin_to_trigger_on;
};
struct NamedTriggerInfo {
std::string trigger_name;
};
struct MonitoringRule {
RuleType type;
HistogramTriggerInfo histogram_trigger_info;
NamedTriggerInfo named_trigger_info;
};
std::vector<MonitoringRule> configs;
CategoryPreset category_preset;
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_PREEMPTIVE_CONFIG_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/browser/background_tracing_reactive_config.h"
namespace content {
BackgroundTracingReactiveConfig::BackgroundTracingReactiveConfig()
: BackgroundTracingConfig(BackgroundTracingConfig::REACTIVE_TRACING_MODE) {
}
BackgroundTracingReactiveConfig::~BackgroundTracingReactiveConfig() {
}
} // namespace content
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_REACTIVE_CONFIG_H_
#define CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_REACTIVE_CONFIG_H_
#include "content/public/browser/background_tracing_config.h"
namespace content {
// BackgroundTracingReactiveConfig holds trigger rules for use during
// reactive tracing. Tracing will be not be enabled immediately, rather
// the BackgroundTracingManager will wait for a trigger to occur, and
// enable tracing at that point. Tracing will be finalized later, either
// after some time has elapsed or the trigger occurs again.
struct CONTENT_EXPORT BackgroundTracingReactiveConfig
: public BackgroundTracingConfig {
public:
BackgroundTracingReactiveConfig();
~BackgroundTracingReactiveConfig() override;
enum RuleType { TRACE_ON_MANUAL_TRIGGER_UNTIL_10S_OR_NEXT_TRIGGER_OR_FULL };
struct TracingRule {
RuleType type;
std::string trigger_name;
CategoryPreset category_preset;
};
std::vector<TracingRule> configs;
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_BACKGROUND_TRACING_REACTIVE_CONFIG_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment