summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-13 15:43:08 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-13 15:43:08 +0000
commit900e91294c742ce19d633dd5f2a0ce2e198febbc (patch)
treead3b3f8a784407ffd3fe480b9ea616954ddc6681
parent4fe481a76941852a69eb75c30c70316ca2805660 (diff)
downloadchromium_src-900e91294c742ce19d633dd5f2a0ce2e198febbc.zip
chromium_src-900e91294c742ce19d633dd5f2a0ce2e198febbc.tar.gz
chromium_src-900e91294c742ce19d633dd5f2a0ce2e198febbc.tar.bz2
Add a Content API around TracingController.
BUG=98716 Review URL: https://chromiumcodereview.appspot.com/9694028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126396 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/DEPS1
-rw-r--r--chrome/browser/automation/automation_provider.cc2
-rw-r--r--chrome/browser/automation/automation_provider.h4
-rw-r--r--chrome/browser/ui/webui/profiler_ui.cc1
-rw-r--r--chrome/browser/ui/webui/tracing_ui.cc7
-rw-r--r--chrome/test/base/tracing.cc11
-rw-r--r--content/browser/browser_main_loop.cc10
-rw-r--r--content/browser/trace_controller.h180
-rw-r--r--content/browser/trace_controller_impl.cc (renamed from content/browser/trace_controller.cc)86
-rw-r--r--content/browser/trace_controller_impl.h111
-rw-r--r--content/browser/trace_message_filter.cc15
-rw-r--r--content/browser/trace_subscriber_stdio.cc2
-rw-r--r--content/browser/trace_subscriber_stdio.h6
-rw-r--r--content/content_browser.gypi6
-rw-r--r--content/public/browser/trace_controller.h86
-rw-r--r--content/public/browser/trace_subscriber.h40
16 files changed, 319 insertions, 249 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 38506f5..cf33fbf 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -51,7 +51,6 @@ include_rules = [
"+content/browser/tab_contents/web_drag_dest_gtk.h",
"+content/browser/tab_contents/web_drag_dest_win.h",
"+content/browser/tab_contents/web_drag_source_gtk.h",
- "+content/browser/trace_controller.h",
# DO NOT ADD ANY MORE ITEMS TO THE ABOVE LIST!
"-content/common",
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 5a42b09..52dd9bd 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -80,6 +80,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/trace_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "net/proxy/proxy_config_service_fixed.h"
@@ -102,6 +103,7 @@ using content::BrowserThread;
using content::DownloadItem;
using content::NavigationController;
using content::RenderViewHost;
+using content::TraceController;
using content::WebContents;
namespace {
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index d589e15..21b4557 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -28,9 +28,9 @@
#include "chrome/browser/cancelable_request.h"
#include "chrome/common/automation_constants.h"
#include "chrome/common/content_settings.h"
-#include "content/browser/trace_controller.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/trace_subscriber.h"
#include "ipc/ipc_channel.h"
#if defined(OS_WIN) && !defined(USE_AURA)
@@ -86,7 +86,7 @@ class AutomationProvider
public base::SupportsWeakPtr<AutomationProvider>,
public base::RefCountedThreadSafe<
AutomationProvider, content::BrowserThread::DeleteOnUIThread>,
- public TraceSubscriber {
+ public content::TraceSubscriber {
public:
explicit AutomationProvider(Profile* profile);
diff --git a/chrome/browser/ui/webui/profiler_ui.cc b/chrome/browser/ui/webui/profiler_ui.cc
index 218cea8..a995160 100644
--- a/chrome/browser/ui/webui/profiler_ui.cc
+++ b/chrome/browser/ui/webui/profiler_ui.cc
@@ -19,7 +19,6 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h"
#include "chrome/common/url_constants.h"
-#include "content/browser/trace_controller.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/tracing_ui.cc b/chrome/browser/ui/webui/tracing_ui.cc
index ae5b234..4b2cf03 100644
--- a/chrome/browser/ui/webui/tracing_ui.cc
+++ b/chrome/browser/ui/webui/tracing_ui.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/debug/trace_event.h"
#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
@@ -20,11 +21,12 @@
#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/url_constants.h"
-#include "content/browser/trace_controller.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/trace_controller.h"
+#include "content/public/browser/trace_subscriber.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/browser/web_ui.h"
@@ -35,6 +37,7 @@
using content::BrowserThread;
using content::GpuDataManager;
+using content::TraceController;
using content::WebContents;
using content::WebUIMessageHandler;
@@ -58,7 +61,7 @@ class TracingMessageHandler
: public WebUIMessageHandler,
public SelectFileDialog::Listener,
public base::SupportsWeakPtr<TracingMessageHandler>,
- public TraceSubscriber,
+ public content::TraceSubscriber,
public content::GpuDataManagerObserver {
public:
TracingMessageHandler();
diff --git a/chrome/test/base/tracing.cc b/chrome/test/base/tracing.cc
index 365e714..790ab3c 100644
--- a/chrome/test/base/tracing.cc
+++ b/chrome/test/base/tracing.cc
@@ -4,14 +4,16 @@
#include "chrome/test/base/tracing.h"
+#include "base/debug/trace_event.h"
#include "base/memory/singleton.h"
#include "base/message_loop.h"
#include "chrome/test/base/ui_test_utils.h"
-#include "content/browser/trace_controller.h"
+#include "content/public/browser/trace_controller.h"
+#include "content/public/browser/trace_subscriber.h"
namespace {
-class InProcessTraceController : public TraceSubscriber {
+class InProcessTraceController : public content::TraceSubscriber {
public:
static InProcessTraceController* GetInstance() {
return Singleton<InProcessTraceController>::get();
@@ -21,7 +23,8 @@ class InProcessTraceController : public TraceSubscriber {
virtual ~InProcessTraceController() {}
bool BeginTracing(const std::string& categories) {
- return TraceController::GetInstance()->BeginTracing(this, categories);
+ return content::TraceController::GetInstance()->BeginTracing(
+ this, categories);
}
bool EndTracing(std::string* json_trace_output) {
@@ -31,7 +34,7 @@ class InProcessTraceController : public TraceSubscriber {
trace_buffer_.SetOutputCallback(output.GetCallback());
trace_buffer_.Start();
- if (!TraceController::GetInstance()->EndTracingAsync(this))
+ if (!content::TraceController::GetInstance()->EndTracingAsync(this))
return false;
// Wait for OnEndTracingComplete() to quit the message loop.
// OnTraceDataCollected may be called multiple times while blocking here.
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 15006c4..9b65ac54 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -23,7 +23,7 @@
#include "content/browser/net/browser_online_state_observer.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
-#include "content/browser/trace_controller.h"
+#include "content/browser/trace_controller_impl.h"
#include "content/common/hi_res_timer_manager.h"
#include "content/common/sandbox_policy.h"
#include "content/public/browser/browser_main_parts.h"
@@ -86,6 +86,8 @@
#undef DestroyAll
#endif
+using content::TraceControllerImpl;
+
namespace {
#if defined(OS_POSIX) && !defined(OS_MACOSX)
@@ -323,8 +325,10 @@ void BrowserMainLoop::MainMessageLoopStart() {
InitializeMainThread();
// Start tracing to a file if needed.
- if (base::debug::TraceLog::GetInstance()->IsEnabled())
- TraceController::GetInstance()->InitStartupTracing(parsed_command_line_);
+ if (base::debug::TraceLog::GetInstance()->IsEnabled()) {
+ TraceControllerImpl::GetInstance()->InitStartupTracing(
+ parsed_command_line_);
+ }
system_monitor_.reset(new base::SystemMonitor);
hi_res_timer_manager_.reset(new HighResolutionTimerManager);
diff --git a/content/browser/trace_controller.h b/content/browser/trace_controller.h
deleted file mode 100644
index b0b05cc..0000000
--- a/content/browser/trace_controller.h
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2012 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_TRACE_CONTROLLER_H_
-#define CONTENT_BROWSER_TRACE_CONTROLLER_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/debug/trace_event.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/memory/singleton.h"
-#include "content/common/content_export.h"
-
-class CommandLine;
-class TraceMessageFilter;
-
-// Objects interested in receiving trace data derive from TraceSubscriber.
-// See also: trace_message_filter.h
-// See also: child_trace_message_filter.h
-class CONTENT_EXPORT TraceSubscriber {
- public:
- // Called once after TraceController::EndTracingAsync.
- virtual void OnEndTracingComplete() = 0;
- // Called 0 or more times between TraceController::BeginTracing and
- // OnEndTracingComplete. Use base::debug::TraceResultBuffer to convert one or
- // more trace fragments to JSON.
- virtual void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& trace_fragment) = 0;
- // Called once after TraceController::GetKnownCategoriesAsync.
- virtual void OnKnownCategoriesCollected(
- const std::set<std::string>& known_categories);
- virtual void OnTraceBufferPercentFullReply(float percent_full);
-
- protected:
- virtual ~TraceSubscriber();
-};
-
-// TraceController is used on the browser processes to enable/disable
-// trace status and collect trace data. Only the browser UI thread is allowed
-// to interact with the TraceController object. All calls on the TraceSubscriber
-// happen on the UI thread.
-class CONTENT_EXPORT TraceController {
- public:
- static TraceController* GetInstance();
-
- // Called on the main thread of the browser process to initialize
- // startup tracing.
- void InitStartupTracing(const CommandLine& command_line);
-
- // Get set of known categories. This can change as new code paths are reached.
- // If true is returned, subscriber->OnKnownCategoriesCollected will be called
- // when once the categories are retrieved from child processes.
- bool GetKnownCategoriesAsync(TraceSubscriber* subscriber);
-
- // Called by browser process to start tracing events on all processes.
- //
- // Currently only one subscriber is allowed at a time.
- // Tracing begins immediately locally, and asynchronously on child processes
- // as soon as they receive the BeginTracing request.
- // By default, all categories are traced except those matching "test_*".
- //
- // If BeginTracing was already called previously,
- // or if an EndTracingAsync is pending,
- // or if another subscriber is tracing,
- // BeginTracing will return false meaning it failed.
- bool BeginTracing(TraceSubscriber* subscriber);
-
- // Same as above, but specifies which categories to trace.
- // If both included_categories and excluded_categories are empty,
- // all categories are traced.
- // Else if included_categories is non-empty, only those are traced.
- // Else if excluded_categories is non-empty, everything but those are traced.
- bool BeginTracing(TraceSubscriber* subscriber,
- const std::vector<std::string>& included_categories,
- const std::vector<std::string>& excluded_categories);
-
- // |categories| is a comma-delimited list of category wildcards.
- // A category can have an optional '-' prefix to make it an excluded category.
- // All the same rules apply above, so for example, having both included and
- // excluded categories in the same list would not be supported.
- //
- // Example: BeginTracing("test_MyTest*");
- // Example: BeginTracing("test_MyTest*,test_OtherStuff");
- // Example: BeginTracing("-excluded_category1,-excluded_category2");
- bool BeginTracing(TraceSubscriber* subscriber, const std::string& categories);
-
- // Called by browser process to stop tracing events on all processes.
- //
- // Child processes typically are caching trace data and only rarely flush
- // and send trace data back to the browser process. That is because it may be
- // an expensive operation to send the trace data over IPC, and we would like
- // to avoid much runtime overhead of tracing. So, to end tracing, we must
- // asynchronously ask all child processes to flush any pending trace data.
- //
- // Once all child processes have acked the EndTracing request,
- // TraceSubscriber will be called with OnEndTracingComplete.
- //
- // If a previous call to EndTracingAsync is already pending,
- // or if another subscriber is tracing,
- // EndTracingAsync will return false meaning it failed.
- bool EndTracingAsync(TraceSubscriber* subscriber);
-
- // Get the maximum across processes of trace buffer percent full state.
- // When the TraceBufferPercentFull value is determined,
- // subscriber->OnTraceBufferPercentFullReply is called.
- // When any child process reaches 100% full, the TraceController will end
- // tracing, and call TraceSubscriber::OnEndTracingComplete.
- // GetTraceBufferPercentFullAsync fails in the following conditions:
- // trace is ending or disabled;
- // a previous call to GetTraceBufferPercentFullAsync is pending; or
- // the caller is not the current subscriber.
- bool GetTraceBufferPercentFullAsync(TraceSubscriber* subscriber);
-
- // Cancel the subscriber so that it will not be called when EndTracingAsync is
- // acked by all child processes. This will also call EndTracingAsync
- // internally if necessary.
- // Safe to call even if caller is not the current subscriber.
- void CancelSubscriber(TraceSubscriber* subscriber);
-
- private:
- typedef std::set<scoped_refptr<TraceMessageFilter> > FilterMap;
-
- friend struct DefaultSingletonTraits<TraceController>;
- friend class TraceMessageFilter;
-
- TraceController();
- ~TraceController();
-
- bool is_tracing_enabled() const {
- return can_end_tracing();
- }
-
- bool can_end_tracing() const {
- return is_tracing_ && pending_end_ack_count_ == 0;
- }
-
- // Can get Buffer Percent Full
- bool can_get_buffer_percent_full() const {
- return is_tracing_ &&
- pending_end_ack_count_ == 0 &&
- pending_bpf_ack_count_ == 0;
- }
-
- bool can_begin_tracing(TraceSubscriber* subscriber) const {
- return !is_tracing_ &&
- (subscriber_ == NULL || subscriber == subscriber_);
- }
-
- // Methods for use by TraceMessageFilter.
-
- void AddFilter(TraceMessageFilter* filter);
- void RemoveFilter(TraceMessageFilter* filter);
- void OnTracingBegan(TraceSubscriber* subscriber);
- void OnEndTracingAck(const std::vector<std::string>& known_categories);
- void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr);
- void OnTraceBufferFull();
- void OnTraceBufferPercentFullReply(float percent_full);
-
- FilterMap filters_;
- TraceSubscriber* subscriber_;
- // Pending acks for EndTracingAsync:
- int pending_end_ack_count_;
- // Pending acks for GetTraceBufferPercentFullAsync:
- int pending_bpf_ack_count_;
- float maximum_bpf_;
- bool is_tracing_;
- bool is_get_categories_;
- std::set<std::string> known_categories_;
- std::vector<std::string> included_categories_;
- std::vector<std::string> excluded_categories_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceController);
-};
-
-#endif // CONTENT_BROWSER_TRACE_CONTROLLER_H_
-
diff --git a/content/browser/trace_controller.cc b/content/browser/trace_controller_impl.cc
index 3c669b4..0c5d5cd 100644
--- a/content/browser/trace_controller.cc
+++ b/content/browser/trace_controller_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/trace_controller.h"
+#include "content/browser/trace_controller_impl.h"
#include "base/bind.h"
#include "base/command_line.h"
@@ -15,8 +15,8 @@
#include "content/public/common/content_switches.h"
using base::debug::TraceLog;
-using content::BrowserMessageFilter;
-using content::BrowserThread;
+
+namespace content {
namespace {
@@ -26,7 +26,7 @@ class AutoStopTraceSubscriberStdio : public content::TraceSubscriberStdio {
: TraceSubscriberStdio(file_path) {}
static void EndStartupTrace(TraceSubscriberStdio* subscriber) {
- if (!TraceController::GetInstance()->EndTracingAsync(subscriber))
+ if (!TraceControllerImpl::GetInstance()->EndTracingAsync(subscriber))
delete subscriber;
// else, the tracing will end asynchronously in OnEndTracingComplete().
}
@@ -41,14 +41,11 @@ class AutoStopTraceSubscriberStdio : public content::TraceSubscriberStdio {
} // namespace
-void TraceSubscriber::OnKnownCategoriesCollected(
- const std::set<std::string>& known_categories) {}
-
-void TraceSubscriber::OnTraceBufferPercentFullReply(float percent_full) {}
-
-TraceSubscriber::~TraceSubscriber() {}
+TraceController* TraceController::GetInstance() {
+ return TraceControllerImpl::GetInstance();
+}
-TraceController::TraceController() :
+TraceControllerImpl::TraceControllerImpl() :
subscriber_(NULL),
pending_end_ack_count_(0),
pending_bpf_ack_count_(0),
@@ -56,20 +53,20 @@ TraceController::TraceController() :
is_tracing_(false),
is_get_categories_(false) {
TraceLog::GetInstance()->SetOutputCallback(
- base::Bind(&TraceController::OnTraceDataCollected,
+ base::Bind(&TraceControllerImpl::OnTraceDataCollected,
base::Unretained(this)));
}
-TraceController::~TraceController() {
+TraceControllerImpl::~TraceControllerImpl() {
if (TraceLog* trace_log = TraceLog::GetInstance())
trace_log->SetOutputCallback(TraceLog::OutputCallback());
}
-TraceController* TraceController::GetInstance() {
- return Singleton<TraceController>::get();
+TraceControllerImpl* TraceControllerImpl::GetInstance() {
+ return Singleton<TraceControllerImpl>::get();
}
-void TraceController::InitStartupTracing(const CommandLine& command_line) {
+void TraceControllerImpl::InitStartupTracing(const CommandLine& command_line) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
FilePath trace_file = command_line.GetSwitchValuePath(
switches::kTraceStartupFile);
@@ -105,7 +102,7 @@ void TraceController::InitStartupTracing(const CommandLine& command_line) {
base::TimeDelta::FromSeconds(delay_secs));
}
-bool TraceController::GetKnownCategoriesAsync(TraceSubscriber* subscriber) {
+bool TraceControllerImpl::GetKnownCategoriesAsync(TraceSubscriber* subscriber) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Known categories come back from child processes with the EndTracingAck
@@ -117,14 +114,14 @@ bool TraceController::GetKnownCategoriesAsync(TraceSubscriber* subscriber) {
return success;
}
-bool TraceController::BeginTracing(TraceSubscriber* subscriber) {
+bool TraceControllerImpl::BeginTracing(TraceSubscriber* subscriber) {
std::vector<std::string> include, exclude;
// By default, exclude all categories that begin with test_
exclude.push_back("test_*");
return BeginTracing(subscriber, include, exclude);
}
-bool TraceController::BeginTracing(
+bool TraceControllerImpl::BeginTracing(
TraceSubscriber* subscriber,
const std::vector<std::string>& included_categories,
const std::vector<std::string>& excluded_categories) {
@@ -140,8 +137,8 @@ bool TraceController::BeginTracing(
return true;
}
-bool TraceController::BeginTracing(TraceSubscriber* subscriber,
- const std::string& categories) {
+bool TraceControllerImpl::BeginTracing(TraceSubscriber* subscriber,
+ const std::string& categories) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!can_begin_tracing(subscriber))
@@ -155,7 +152,7 @@ bool TraceController::BeginTracing(TraceSubscriber* subscriber,
return true;
}
-bool TraceController::EndTracingAsync(TraceSubscriber* subscriber) {
+bool TraceControllerImpl::EndTracingAsync(TraceSubscriber* subscriber) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!can_end_tracing() || subscriber != subscriber_)
@@ -174,8 +171,8 @@ bool TraceController::EndTracingAsync(TraceSubscriber* subscriber) {
std::vector<std::string> categories;
TraceLog::GetInstance()->GetKnownCategories(&categories);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnEndTracingAck, base::Unretained(this),
- categories));
+ base::Bind(&TraceControllerImpl::OnEndTracingAck,
+ base::Unretained(this), categories));
}
// Notify all child processes.
@@ -186,7 +183,7 @@ bool TraceController::EndTracingAsync(TraceSubscriber* subscriber) {
return true;
}
-bool TraceController::GetTraceBufferPercentFullAsync(
+bool TraceControllerImpl::GetTraceBufferPercentFullAsync(
TraceSubscriber* subscriber) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -201,7 +198,7 @@ bool TraceController::GetTraceBufferPercentFullAsync(
// Ack asynchronously now, because we don't have any children to wait for.
float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnTraceBufferPercentFullReply,
+ base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
base::Unretained(this), bpf));
}
@@ -213,7 +210,7 @@ bool TraceController::GetTraceBufferPercentFullAsync(
return true;
}
-void TraceController::CancelSubscriber(TraceSubscriber* subscriber) {
+void TraceControllerImpl::CancelSubscriber(TraceSubscriber* subscriber) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (subscriber == subscriber_) {
@@ -224,10 +221,10 @@ void TraceController::CancelSubscriber(TraceSubscriber* subscriber) {
}
}
-void TraceController::AddFilter(TraceMessageFilter* filter) {
+void TraceControllerImpl::AddFilter(TraceMessageFilter* filter) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::AddFilter, base::Unretained(this),
+ base::Bind(&TraceControllerImpl::AddFilter, base::Unretained(this),
make_scoped_refptr(filter)));
return;
}
@@ -238,10 +235,10 @@ void TraceController::AddFilter(TraceMessageFilter* filter) {
}
}
-void TraceController::RemoveFilter(TraceMessageFilter* filter) {
+void TraceControllerImpl::RemoveFilter(TraceMessageFilter* filter) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::RemoveFilter, base::Unretained(this),
+ base::Bind(&TraceControllerImpl::RemoveFilter, base::Unretained(this),
make_scoped_refptr(filter)));
return;
}
@@ -249,7 +246,7 @@ void TraceController::RemoveFilter(TraceMessageFilter* filter) {
filters_.erase(filter);
}
-void TraceController::OnTracingBegan(TraceSubscriber* subscriber) {
+void TraceControllerImpl::OnTracingBegan(TraceSubscriber* subscriber) {
is_tracing_ = true;
subscriber_ = subscriber;
@@ -262,12 +259,12 @@ void TraceController::OnTracingBegan(TraceSubscriber* subscriber) {
}
}
-void TraceController::OnEndTracingAck(
+void TraceControllerImpl::OnEndTracingAck(
const std::vector<std::string>& known_categories) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnEndTracingAck, base::Unretained(this),
- known_categories));
+ base::Bind(&TraceControllerImpl::OnEndTracingAck,
+ base::Unretained(this), known_categories));
return;
}
@@ -306,18 +303,18 @@ void TraceController::OnEndTracingAck(
std::vector<std::string> categories;
TraceLog::GetInstance()->GetKnownCategories(&categories);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnEndTracingAck, base::Unretained(this),
- categories));
+ base::Bind(&TraceControllerImpl::OnEndTracingAck,
+ base::Unretained(this), categories));
}
}
-void TraceController::OnTraceDataCollected(
+void TraceControllerImpl::OnTraceDataCollected(
const scoped_refptr<base::RefCountedString>& events_str_ptr) {
// OnTraceDataCollected may be called from any browser thread, either by the
// local event trace system or from child processes via TraceMessageFilter.
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnTraceDataCollected,
+ base::Bind(&TraceControllerImpl::OnTraceDataCollected,
base::Unretained(this), events_str_ptr));
return;
}
@@ -327,12 +324,12 @@ void TraceController::OnTraceDataCollected(
subscriber_->OnTraceDataCollected(events_str_ptr);
}
-void TraceController::OnTraceBufferFull() {
+void TraceControllerImpl::OnTraceBufferFull() {
// OnTraceBufferFull may be called from any browser thread, either by the
// local event trace system or from child processes via TraceMessageFilter.
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnTraceBufferFull,
+ base::Bind(&TraceControllerImpl::OnTraceBufferFull,
base::Unretained(this)));
return;
}
@@ -342,10 +339,10 @@ void TraceController::OnTraceBufferFull() {
EndTracingAsync(subscriber_);
}
-void TraceController::OnTraceBufferPercentFullReply(float percent_full) {
+void TraceControllerImpl::OnTraceBufferPercentFullReply(float percent_full) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnTraceBufferPercentFullReply,
+ base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
base::Unretained(this), percent_full));
return;
}
@@ -366,8 +363,9 @@ void TraceController::OnTraceBufferPercentFullReply(float percent_full) {
// this code only executes if there were child processes.
float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceController::OnTraceBufferPercentFullReply,
+ base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
base::Unretained(this), bpf));
}
}
+} // namespace content
diff --git a/content/browser/trace_controller_impl.h b/content/browser/trace_controller_impl.h
new file mode 100644
index 0000000..3564bb3
--- /dev/null
+++ b/content/browser/trace_controller_impl.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2012 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_TRACE_CONTROLLER_IMPL_H_
+#define CONTENT_BROWSER_TRACE_CONTROLLER_IMPL_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/debug/trace_event.h"
+#include "base/memory/singleton.h"
+#include "content/public/browser/trace_controller.h"
+
+class CommandLine;
+class TraceMessageFilter;
+
+namespace content {
+
+class TraceControllerImpl : public TraceController {
+ public:
+ static TraceControllerImpl* GetInstance();
+
+ // Called on the main thread of the browser process to initialize
+ // startup tracing.
+ void InitStartupTracing(const CommandLine& command_line);
+
+ // Get set of known categories. This can change as new code paths are reached.
+ // If true is returned, subscriber->OnKnownCategoriesCollected will be called
+ // when once the categories are retrieved from child processes.
+ bool GetKnownCategoriesAsync(TraceSubscriber* subscriber);
+
+ // Same as above, but specifies which categories to trace.
+ // If both included_categories and excluded_categories are empty,
+ // all categories are traced.
+ // Else if included_categories is non-empty, only those are traced.
+ // Else if excluded_categories is non-empty, everything but those are traced.
+ bool BeginTracing(TraceSubscriber* subscriber,
+ const std::vector<std::string>& included_categories,
+ const std::vector<std::string>& excluded_categories);
+
+ // TraceController implementation:
+ virtual bool BeginTracing(TraceSubscriber* subscriber) OVERRIDE;
+ virtual bool BeginTracing(TraceSubscriber* subscriber,
+ const std::string& categories) OVERRIDE;
+ virtual bool EndTracingAsync(TraceSubscriber* subscriber) OVERRIDE;
+ virtual bool GetTraceBufferPercentFullAsync(
+ TraceSubscriber* subscriber) OVERRIDE;
+ virtual void CancelSubscriber(TraceSubscriber* subscriber) OVERRIDE;
+
+ private:
+ typedef std::set<scoped_refptr<TraceMessageFilter> > FilterMap;
+
+ friend struct DefaultSingletonTraits<TraceControllerImpl>;
+ friend class ::TraceMessageFilter;
+
+ TraceControllerImpl();
+ virtual ~TraceControllerImpl();
+
+ bool is_tracing_enabled() const {
+ return can_end_tracing();
+ }
+
+ bool can_end_tracing() const {
+ return is_tracing_ && pending_end_ack_count_ == 0;
+ }
+
+ // Can get Buffer Percent Full
+ bool can_get_buffer_percent_full() const {
+ return is_tracing_ &&
+ pending_end_ack_count_ == 0 &&
+ pending_bpf_ack_count_ == 0;
+ }
+
+ bool can_begin_tracing(TraceSubscriber* subscriber) const {
+ return !is_tracing_ &&
+ (subscriber_ == NULL || subscriber == subscriber_);
+ }
+
+ // Methods for use by TraceMessageFilter.
+
+ void AddFilter(TraceMessageFilter* filter);
+ void RemoveFilter(TraceMessageFilter* filter);
+ void OnTracingBegan(TraceSubscriber* subscriber);
+ void OnEndTracingAck(const std::vector<std::string>& known_categories);
+ void OnTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr);
+ void OnTraceBufferFull();
+ void OnTraceBufferPercentFullReply(float percent_full);
+
+ FilterMap filters_;
+ TraceSubscriber* subscriber_;
+ // Pending acks for EndTracingAsync:
+ int pending_end_ack_count_;
+ // Pending acks for GetTraceBufferPercentFullAsync:
+ int pending_bpf_ack_count_;
+ float maximum_bpf_;
+ bool is_tracing_;
+ bool is_get_categories_;
+ std::set<std::string> known_categories_;
+ std::vector<std::string> included_categories_;
+ std::vector<std::string> excluded_categories_;
+
+ DISALLOW_COPY_AND_ASSIGN(TraceControllerImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_TRACE_CONTROLLER_IMPL_H_
+
diff --git a/content/browser/trace_message_filter.cc b/content/browser/trace_message_filter.cc
index 292f02d..739d413 100644
--- a/content/browser/trace_message_filter.cc
+++ b/content/browser/trace_message_filter.cc
@@ -4,11 +4,12 @@
#include "content/browser/trace_message_filter.h"
-#include "content/browser/trace_controller.h"
+#include "content/browser/trace_controller_impl.h"
#include "content/common/child_process_messages.h"
using content::BrowserMessageFilter;
using content::BrowserThread;
+using content::TraceControllerImpl;
TraceMessageFilter::TraceMessageFilter() :
has_child_(false),
@@ -35,7 +36,7 @@ void TraceMessageFilter::OnChannelClosing() {
if (is_awaiting_end_ack_)
OnTraceBufferPercentFullReply(0.0f);
- TraceController::GetInstance()->RemoveFilter(this);
+ TraceControllerImpl::GetInstance()->RemoveFilter(this);
}
}
@@ -82,7 +83,7 @@ void TraceMessageFilter::SendGetTraceBufferPercentFull() {
void TraceMessageFilter::OnChildSupportsTracing() {
has_child_ = true;
- TraceController::GetInstance()->AddFilter(this);
+ TraceControllerImpl::GetInstance()->AddFilter(this);
}
void TraceMessageFilter::OnEndTracingAck(
@@ -91,24 +92,24 @@ void TraceMessageFilter::OnEndTracingAck(
// child process is compromised.
if (is_awaiting_end_ack_) {
is_awaiting_end_ack_ = false;
- TraceController::GetInstance()->OnEndTracingAck(known_categories);
+ TraceControllerImpl::GetInstance()->OnEndTracingAck(known_categories);
}
}
void TraceMessageFilter::OnTraceDataCollected(const std::string& data) {
scoped_refptr<base::RefCountedString> data_ptr(new base::RefCountedString());
data_ptr->data() = data;
- TraceController::GetInstance()->OnTraceDataCollected(data_ptr);
+ TraceControllerImpl::GetInstance()->OnTraceDataCollected(data_ptr);
}
void TraceMessageFilter::OnTraceBufferFull() {
- TraceController::GetInstance()->OnTraceBufferFull();
+ TraceControllerImpl::GetInstance()->OnTraceBufferFull();
}
void TraceMessageFilter::OnTraceBufferPercentFullReply(float percent_full) {
if (is_awaiting_bpf_ack_) {
is_awaiting_bpf_ack_ = false;
- TraceController::GetInstance()->OnTraceBufferPercentFullReply(
+ TraceControllerImpl::GetInstance()->OnTraceBufferPercentFullReply(
percent_full);
}
}
diff --git a/content/browser/trace_subscriber_stdio.cc b/content/browser/trace_subscriber_stdio.cc
index 028404c..a55c611 100644
--- a/content/browser/trace_subscriber_stdio.cc
+++ b/content/browser/trace_subscriber_stdio.cc
@@ -5,6 +5,7 @@
#include "content/browser/trace_subscriber_stdio.h"
#include "base/bind.h"
+#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/public/browser/browser_thread.h"
@@ -96,4 +97,3 @@ void TraceSubscriberStdio::OnTraceDataCollected(
}
} // namespace content
-
diff --git a/content/browser/trace_subscriber_stdio.h b/content/browser/trace_subscriber_stdio.h
index c7014f7..1989729 100644
--- a/content/browser/trace_subscriber_stdio.h
+++ b/content/browser/trace_subscriber_stdio.h
@@ -8,8 +8,9 @@
#include <string>
+#include "base/compiler_specific.h"
#include "base/file_util.h"
-#include "content/browser/trace_controller.h"
+#include "content/public/browser/trace_subscriber.h"
#include "content/common/content_export.h"
namespace content {
@@ -17,7 +18,8 @@ namespace content {
class TraceSubscriberStdioImpl;
// Stdio implementation of TraceSubscriber. Use this to write traces to a file.
-class CONTENT_EXPORT TraceSubscriberStdio : public TraceSubscriber {
+class CONTENT_EXPORT TraceSubscriberStdio
+ : NON_EXPORTED_BASE(public content::TraceSubscriber) {
public:
// Creates or overwrites the specified file. Check IsValid() for success.
explicit TraceSubscriberStdio(const FilePath& path);
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index fe1e423..3f853c2 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -129,6 +129,8 @@
'public/browser/speech_recognition_preferences.h',
'public/browser/speech_recognizer.h',
'public/browser/speech_recognizer_delegate.h',
+ 'public/browser/trace_controller.h',
+ 'public/browser/trace_subscriber.h',
'public/browser/user_metrics.h',
'public/browser/utility_process_host.h',
'public/browser/web_contents.h',
@@ -668,8 +670,8 @@
'browser/tab_contents/web_drag_source_win.h',
'browser/tab_contents/web_drag_utils_win.cc',
'browser/tab_contents/web_drag_utils_win.h',
- 'browser/trace_controller.cc',
- 'browser/trace_controller.h',
+ 'browser/trace_controller_impl.cc',
+ 'browser/trace_controller_impl.h',
'browser/trace_message_filter.cc',
'browser/trace_message_filter.h',
'browser/trace_subscriber_stdio.cc',
diff --git a/content/public/browser/trace_controller.h b/content/public/browser/trace_controller.h
new file mode 100644
index 0000000..49670f2
--- /dev/null
+++ b/content/public/browser/trace_controller.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2012 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_TRACE_CONTROLLER_H_
+#define CONTENT_PUBLIC_BROWSER_TRACE_CONTROLLER_H_
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+class TraceSubscriber;
+
+// TraceController is used on the browser processes to enable/disable
+// trace status and collect trace data. Only the browser UI thread is allowed
+// to interact with the TraceController object. All calls on the TraceSubscriber
+// happen on the UI thread.
+class TraceController {
+ public:
+ CONTENT_EXPORT static TraceController* GetInstance();
+
+ // Called by browser process to start tracing events on all processes.
+ //
+ // Currently only one subscriber is allowed at a time.
+ // Tracing begins immediately locally, and asynchronously on child processes
+ // as soon as they receive the BeginTracing request.
+ // By default, all categories are traced except those matching "test_*".
+ //
+ // If BeginTracing was already called previously,
+ // or if an EndTracingAsync is pending,
+ // or if another subscriber is tracing,
+ // BeginTracing will return false meaning it failed.
+ virtual bool BeginTracing(TraceSubscriber* subscriber) = 0;
+
+ // |categories| is a comma-delimited list of category wildcards.
+ // A category can have an optional '-' prefix to make it an excluded category.
+ // All the same rules apply above, so for example, having both included and
+ // excluded categories in the same list would not be supported.
+ //
+ // Example: BeginTracing("test_MyTest*");
+ // Example: BeginTracing("test_MyTest*,test_OtherStuff");
+ // Example: BeginTracing("-excluded_category1,-excluded_category2");
+ virtual bool BeginTracing(TraceSubscriber* subscriber,
+ const std::string& categories) = 0;
+
+ // Called by browser process to stop tracing events on all processes.
+ //
+ // Child processes typically are caching trace data and only rarely flush
+ // and send trace data back to the browser process. That is because it may be
+ // an expensive operation to send the trace data over IPC, and we would like
+ // to avoid much runtime overhead of tracing. So, to end tracing, we must
+ // asynchronously ask all child processes to flush any pending trace data.
+ //
+ // Once all child processes have acked the EndTracing request,
+ // TraceSubscriber will be called with OnEndTracingComplete.
+ //
+ // If a previous call to EndTracingAsync is already pending,
+ // or if another subscriber is tracing,
+ // EndTracingAsync will return false meaning it failed.
+ virtual bool EndTracingAsync(TraceSubscriber* subscriber) = 0;
+
+ // Get the maximum across processes of trace buffer percent full state.
+ // When the TraceBufferPercentFull value is determined,
+ // subscriber->OnTraceBufferPercentFullReply is called.
+ // When any child process reaches 100% full, the TraceController will end
+ // tracing, and call TraceSubscriber::OnEndTracingComplete.
+ // GetTraceBufferPercentFullAsync fails in the following conditions:
+ // trace is ending or disabled;
+ // a previous call to GetTraceBufferPercentFullAsync is pending; or
+ // the caller is not the current subscriber.
+ virtual bool GetTraceBufferPercentFullAsync(TraceSubscriber* subscriber) = 0;
+
+ // Cancel the subscriber so that it will not be called when EndTracingAsync is
+ // acked by all child processes. This will also call EndTracingAsync
+ // internally if necessary.
+ // Safe to call even if caller is not the current subscriber.
+ virtual void CancelSubscriber(TraceSubscriber* subscriber) = 0;
+
+ protected:
+ virtual ~TraceController() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_TRACE_CONTROLLER_H_
+
diff --git a/content/public/browser/trace_subscriber.h b/content/public/browser/trace_subscriber.h
new file mode 100644
index 0000000..08e408c1
--- /dev/null
+++ b/content/public/browser/trace_subscriber.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 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_TRACE_SUBSCRIBER_H_
+#define CONTENT_PUBLIC_BROWSER_TRACE_SUBSCRIBER_H_
+
+#include <set>
+
+#include "base/memory/ref_counted_memory.h"
+
+namespace content {
+
+// Objects interested in receiving trace data derive from TraceSubscriber.
+// See also: trace_message_filter.h
+// See also: child_trace_message_filter.h
+class TraceSubscriber {
+ public:
+ // Called once after TraceController::EndTracingAsync.
+ virtual void OnEndTracingComplete() = 0;
+
+ // Called 0 or more times between TraceController::BeginTracing and
+ // OnEndTracingComplete. Use base::debug::TraceResultBuffer to convert one or
+ // more trace fragments to JSON.
+ virtual void OnTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& trace_fragment) = 0;
+
+ // Called once after TraceController::GetKnownCategoriesAsync.
+ virtual void OnKnownCategoriesCollected(
+ const std::set<std::string>& known_categories) {}
+
+ virtual void OnTraceBufferPercentFullReply(float percent_full) {}
+
+ protected:
+ virtual ~TraceSubscriber() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_TRACE_SUBSCRIBER_H_