summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorharaken@chromium.org <haraken@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-11 14:28:02 +0000
committerharaken@chromium.org <haraken@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-11 14:28:02 +0000
commita8ba174a916c832509e473cd4aee2c675bd9f577 (patch)
tree9451f38c83ec87d267e6758cd7a5d888721a898c
parentbfbab88d09783757953440e017a29413d07e247e (diff)
downloadchromium_src-a8ba174a916c832509e473cd4aee2c675bd9f577.zip
chromium_src-a8ba174a916c832509e473cd4aee2c675bd9f577.tar.gz
chromium_src-a8ba174a916c832509e473cd4aee2c675bd9f577.tar.bz2
We're refactoring the architecture of the tracing controller, as documented here:
https://docs.google.com/a/chromium.org/document/d/1qzprwk_jw6kiZTiOKMjuaoX4eIrivfqMZLYBxQglqkc/edit?disco=AAAAAGg-QgI# tracing_controller.h will list up the C++ APIs for tracing,and This CL declares the APIs. The API contents are implemented in tracing_controller_impl.{h,cpp} BUG=285471 Review URL: https://chromiumcodereview.appspot.com/23752004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222545 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/tracing/trace_message_filter.h2
-rw-r--r--content/browser/tracing/tracing_controller_browsertest.cc115
-rw-r--r--content/browser/tracing/tracing_controller_impl.cc270
-rw-r--r--content/browser/tracing/tracing_controller_impl.h100
-rw-r--r--content/content_browser.gypi3
-rw-r--r--content/content_tests.gypi1
-rw-r--r--content/public/browser/trace_controller.h3
-rw-r--r--content/public/browser/tracing_controller.h131
8 files changed, 624 insertions, 1 deletions
diff --git a/content/browser/tracing/trace_message_filter.h b/content/browser/tracing/trace_message_filter.h
index 8da3453..41fd017 100644
--- a/content/browser/tracing/trace_message_filter.h
+++ b/content/browser/tracing/trace_message_filter.h
@@ -14,7 +14,7 @@
namespace content {
// This class sends and receives trace messages on the browser process.
-// See also: trace_controller.h
+// See also: tracing_controller.h
// See also: child_trace_message_filter.h
class TraceMessageFilter : public BrowserMessageFilter {
public:
diff --git a/content/browser/tracing/tracing_controller_browsertest.cc b/content/browser/tracing/tracing_controller_browsertest.cc
new file mode 100644
index 0000000..c88932e
--- /dev/null
+++ b/content/browser/tracing/tracing_controller_browsertest.cc
@@ -0,0 +1,115 @@
+// Copyright 2013 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/file_util.h"
+#include "base/run_loop.h"
+#include "content/browser/tracing/tracing_controller_impl.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+
+namespace content {
+
+class TracingControllerTest : public ContentBrowserTest {
+ public:
+ TracingControllerTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ get_categories_done_callback_count_ = 0;
+ enable_recording_done_callback_count_ = 0;
+ disable_recording_done_callback_count_ = 0;
+ ContentBrowserTest::SetUp();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ ContentBrowserTest::TearDown();
+ }
+
+ void Navigate(Shell* shell) {
+ NavigateToURL(shell, GetTestUrl("", "title.html"));
+ }
+
+ void GetCategoriesDoneCallbackTest(base::Closure quit_callback,
+ const std::set<std::string>& categories) {
+ get_categories_done_callback_count_++;
+ EXPECT_TRUE(categories.size() > 0);
+ quit_callback.Run();
+ }
+
+ void EnableRecordingDoneCallbackTest(base::Closure quit_callback) {
+ enable_recording_done_callback_count_++;
+ quit_callback.Run();
+ }
+
+ void DisableRecordingDoneCallbackTest(base::Closure quit_callback,
+ scoped_ptr<base::FilePath> file_path) {
+ disable_recording_done_callback_count_++;
+ EXPECT_TRUE(PathExists(*file_path));
+ quit_callback.Run();
+ }
+
+ int get_categories_done_callback_count() const {
+ return get_categories_done_callback_count_;
+ }
+
+ int enable_recording_done_callback_count() const {
+ return enable_recording_done_callback_count_;
+ }
+
+ int disable_recording_done_callback_count() const {
+ return disable_recording_done_callback_count_;
+ }
+
+ private:
+ int get_categories_done_callback_count_;
+ int enable_recording_done_callback_count_;
+ int disable_recording_done_callback_count_;
+};
+
+IN_PROC_BROWSER_TEST_F(TracingControllerTest, GetCategories) {
+ Navigate(shell());
+
+ TracingController* controller = TracingController::GetInstance();
+
+ base::RunLoop run_loop;
+ TracingController::GetCategoriesDoneCallback callback =
+ base::Bind(&TracingControllerTest::GetCategoriesDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ controller->GetCategories(callback);
+ run_loop.Run();
+ EXPECT_EQ(get_categories_done_callback_count(), 1);
+}
+
+IN_PROC_BROWSER_TEST_F(TracingControllerTest, EnableAndDisableRecording) {
+ Navigate(shell());
+
+ TracingController* controller = TracingController::GetInstance();
+
+ {
+ base::RunLoop run_loop;
+ TracingController::EnableRecordingDoneCallback callback =
+ base::Bind(&TracingControllerTest::EnableRecordingDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ controller->EnableRecording(base::debug::CategoryFilter("*"),
+ TracingController::Options(), callback);
+ run_loop.Run();
+ EXPECT_EQ(enable_recording_done_callback_count(), 1);
+ }
+
+ {
+ base::RunLoop run_loop;
+ TracingController::TracingFileResultCallback callback =
+ base::Bind(&TracingControllerTest::DisableRecordingDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+ controller->DisableRecording(callback);
+ run_loop.Run();
+ EXPECT_EQ(disable_recording_done_callback_count(), 1);
+ }
+}
+
+} // namespace content
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
new file mode 100644
index 0000000..1c1c43a
--- /dev/null
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -0,0 +1,270 @@
+// Copyright 2013 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/tracing_controller_impl.h"
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/json/string_escape.h"
+#include "base/strings/string_number_conversions.h"
+#include "content/browser/tracing/trace_message_filter.h"
+#include "content/common/child_process_messages.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/common/content_switches.h"
+
+using base::debug::TraceLog;
+
+namespace content {
+
+namespace {
+
+base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+TracingController* TracingController::GetInstance() {
+ return TracingControllerImpl::GetInstance();
+}
+
+TracingControllerImpl::TracingControllerImpl() :
+ pending_end_ack_count_(0),
+ is_recording_(false),
+ category_filter_(
+ base::debug::CategoryFilter::kDefaultCategoryFilterString) {
+}
+
+TracingControllerImpl::~TracingControllerImpl() {
+ // This is a Leaky instance.
+ NOTREACHED();
+}
+
+TracingControllerImpl* TracingControllerImpl::GetInstance() {
+ return g_controller.Pointer();
+}
+
+void TracingControllerImpl::GetCategories(
+ const GetCategoriesDoneCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Known categories come back from child processes with the EndTracingAck
+ // message. So to get known categories, just begin and end tracing immediately
+ // afterwards. This will ping all the child processes for categories.
+ pending_get_categories_done_callback_ = callback;
+ EnableRecording(base::debug::CategoryFilter("*"),
+ TracingController::Options(),
+ EnableRecordingDoneCallback());
+ DisableRecording(TracingFileResultCallback());
+}
+
+void TracingControllerImpl::EnableRecording(
+ const base::debug::CategoryFilter& filter,
+ TracingController::Options options,
+ const EnableRecordingDoneCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!can_enable_recording())
+ return;
+
+ trace_options_ = TraceLog::GetInstance()->trace_options();
+ TraceLog::GetInstance()->SetEnabled(filter, trace_options_);
+
+ is_recording_ = true;
+ category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter();
+
+ // Notify all child processes.
+ for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
+ it->get()->SendBeginTracing(category_filter_.ToString(), trace_options_);
+ }
+
+ if (!callback.is_null())
+ callback.Run();
+}
+
+void TracingControllerImpl::DisableRecording(
+ const TracingFileResultCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!can_end_recording())
+ return;
+
+ pending_disable_recording_done_callback_ = callback;
+
+ // Disable local trace early to avoid traces during end-tracing process from
+ // interfering with the process.
+ TraceLog::GetInstance()->SetDisabled();
+
+ // We don't need to create a temporary file when getting categories.
+ if (pending_get_categories_done_callback_.is_null()) {
+ base::FilePath temporary_file;
+ file_util::CreateTemporaryFile(&temporary_file);
+ recording_result_file_.reset(new base::FilePath(temporary_file));
+ }
+
+ // There could be a case where there are no child processes and filters_
+ // is empty. In that case we can immediately tell the subscriber that tracing
+ // has ended. To avoid recursive calls back to the subscriber, we will just
+ // use the existing asynchronous OnDisableRecordingAcked code.
+ // Count myself (local trace) in pending_end_ack_count_, acked below.
+ pending_end_ack_count_ = filters_.size() + 1;
+
+ // Handle special case of zero child processes.
+ if (pending_end_ack_count_ == 1) {
+ // Ack asynchronously now, because we don't have any children to wait for.
+ std::vector<std::string> category_groups;
+ TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TracingControllerImpl::OnDisableRecordingAcked,
+ base::Unretained(this), category_groups));
+ }
+
+ // Notify all child processes.
+ for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
+ it->get()->SendEndTracing();
+ }
+}
+
+void TracingControllerImpl::EnableMonitoring(
+ const base::debug::CategoryFilter& filter,
+ TracingController::Options options,
+ const EnableMonitoringDoneCallback& callback) {
+ NOTIMPLEMENTED();
+}
+
+void TracingControllerImpl::DisableMonitoring(
+ const DisableMonitoringDoneCallback& callback) {
+ NOTIMPLEMENTED();
+}
+
+void TracingControllerImpl::GetMonitoringStatus(
+ bool* out_enabled,
+ base::debug::CategoryFilter* out_filter,
+ TracingController::Options* out_options) {
+ NOTIMPLEMENTED();
+}
+
+void TracingControllerImpl::CaptureCurrentMonitoringSnapshot(
+ const TracingFileResultCallback& callback) {
+ NOTIMPLEMENTED();
+}
+
+void TracingControllerImpl::AddFilter(TraceMessageFilter* filter) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TracingControllerImpl::AddFilter, base::Unretained(this),
+ make_scoped_refptr(filter)));
+ return;
+ }
+
+ filters_.insert(filter);
+ if (is_recording_enabled()) {
+ std::string cf_str = category_filter_.ToString();
+ filter->SendBeginTracing(cf_str, trace_options_);
+ }
+}
+
+void TracingControllerImpl::RemoveFilter(TraceMessageFilter* filter) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TracingControllerImpl::RemoveFilter, base::Unretained(this),
+ make_scoped_refptr(filter)));
+ return;
+ }
+
+ filters_.erase(filter);
+}
+
+void TracingControllerImpl::OnDisableRecordingAcked(
+ const std::vector<std::string>& known_category_groups) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TracingControllerImpl::OnDisableRecordingAcked,
+ base::Unretained(this), known_category_groups));
+ return;
+ }
+
+ // Merge known_category_groups with known_category_groups_
+ known_category_groups_.insert(known_category_groups.begin(),
+ known_category_groups.end());
+
+ if (pending_end_ack_count_ == 0)
+ return;
+
+ if (--pending_end_ack_count_ == 1) {
+ // All acks from subprocesses have been received. Now flush the local trace.
+ // During or after this call, our OnLocalTraceDataCollected will be
+ // called with the last of the local trace data.
+ TraceLog::GetInstance()->Flush(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)));
+ }
+
+ if (pending_end_ack_count_ != 0)
+ return;
+
+ // All acks (including from the subprocesses and the local trace) have been
+ // received.
+ is_recording_ = false;
+
+ // Trigger callback if one is set.
+ if (!pending_get_categories_done_callback_.is_null()) {
+ pending_get_categories_done_callback_.Run(known_category_groups_);
+ pending_get_categories_done_callback_.Reset();
+ } else {
+ OnEndTracingComplete();
+ }
+}
+
+void TracingControllerImpl::OnEndTracingComplete() {
+ if (pending_disable_recording_done_callback_.is_null())
+ return;
+
+ pending_disable_recording_done_callback_.Run(recording_result_file_.Pass());
+ pending_disable_recording_done_callback_.Reset();
+}
+
+void TracingControllerImpl::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(&TracingControllerImpl::OnTraceDataCollected,
+ base::Unretained(this), events_str_ptr));
+ return;
+ }
+
+ // Drop trace events if we are just getting categories.
+ if (!pending_get_categories_done_callback_.is_null())
+ return;
+
+ std::string javascript;
+ javascript.reserve(events_str_ptr->size() * 2);
+ base::JsonDoubleQuote(events_str_ptr->data(), false, &javascript);
+
+ // Intentionally append a , to the traceData. This technically causes all
+ // traceData that we pass back to JS to end with a comma, but that is
+ // actually something the JS side strips away anyway
+ javascript.append(",");
+
+ file_util::WriteFile(*recording_result_file_,
+ javascript.c_str(), javascript.length());
+}
+
+void TracingControllerImpl::OnLocalTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr,
+ bool has_more_events) {
+ if (events_str_ptr->data().size())
+ OnTraceDataCollected(events_str_ptr);
+
+ if (has_more_events)
+ return;
+
+ // Simulate an DisableRecordingAcked for the local trace.
+ std::vector<std::string> category_groups;
+ TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
+ OnDisableRecordingAcked(category_groups);
+}
+
+} // namespace content
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h
new file mode 100644
index 0000000..2219225
--- /dev/null
+++ b/content/browser/tracing/tracing_controller_impl.h
@@ -0,0 +1,100 @@
+// Copyright 2013 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_TRACING_CONTROLLER_IMPL_H_
+#define CONTENT_BROWSER_TRACING_TRACING_CONTROLLER_IMPL_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/lazy_instance.h"
+#include "content/public/browser/trace_subscriber.h"
+#include "content/public/browser/tracing_controller.h"
+
+namespace content {
+
+class TraceMessageFilter;
+
+class TracingControllerImpl :
+ public TracingController, public TraceSubscriber {
+ public:
+ static TracingControllerImpl* GetInstance();
+
+ // TracingController implementation.
+ virtual void GetCategories(
+ const GetCategoriesDoneCallback& callback) OVERRIDE;
+ virtual void EnableRecording(
+ const base::debug::CategoryFilter& filter,
+ TracingController::Options options,
+ const EnableRecordingDoneCallback& callback) OVERRIDE;
+ virtual void DisableRecording(
+ const TracingFileResultCallback& callback) OVERRIDE;
+ virtual void EnableMonitoring(const base::debug::CategoryFilter& filter,
+ TracingController::Options options,
+ const EnableMonitoringDoneCallback& callback) OVERRIDE;
+ virtual void DisableMonitoring(
+ const DisableMonitoringDoneCallback& callback) OVERRIDE;
+ virtual void GetMonitoringStatus(
+ bool* out_enabled,
+ base::debug::CategoryFilter* out_filter,
+ TracingController::Options* out_options) OVERRIDE;
+ virtual void CaptureCurrentMonitoringSnapshot(
+ const TracingFileResultCallback& callback) OVERRIDE;
+
+ private:
+ typedef std::set<scoped_refptr<TraceMessageFilter> > FilterMap;
+
+ friend struct base::DefaultLazyInstanceTraits<TracingControllerImpl>;
+ friend class TraceMessageFilter;
+
+ TracingControllerImpl();
+ virtual ~TracingControllerImpl();
+
+ // TraceSubscriber implementation.
+ virtual void OnEndTracingComplete() OVERRIDE;
+ virtual void OnTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr) OVERRIDE;
+
+ bool can_enable_recording() const {
+ return !is_recording_;
+ }
+
+ bool can_end_recording() const {
+ return is_recording_ && pending_end_ack_count_ == 0;
+ }
+
+ bool is_recording_enabled() const {
+ return can_end_recording();
+ }
+
+ // Methods for use by TraceMessageFilter.
+ void AddFilter(TraceMessageFilter* filter);
+ void RemoveFilter(TraceMessageFilter* filter);
+
+ // Callback of TraceLog::Flush() for the local trace.
+ void OnLocalTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr,
+ bool has_more_events);
+
+ void OnDisableRecordingAcked(
+ const std::vector<std::string>& known_category_groups);
+
+ FilterMap filters_;
+ // Pending acks for DisableRecording.
+ int pending_end_ack_count_;
+ bool is_recording_;
+ GetCategoriesDoneCallback pending_get_categories_done_callback_;
+ TracingFileResultCallback pending_disable_recording_done_callback_;
+ std::set<std::string> known_category_groups_;
+ base::debug::TraceLog::Options trace_options_;
+ base::debug::CategoryFilter category_filter_;
+ scoped_ptr<base::FilePath> recording_result_file_;
+
+ DISALLOW_COPY_AND_ASSIGN(TracingControllerImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_TRACING_TRACING_CONTROLLER_IMPL_H_
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 8b17172..23e5c0e 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -174,6 +174,7 @@
'public/browser/stream_handle.h',
'public/browser/trace_controller.h',
'public/browser/trace_subscriber.h',
+ 'public/browser/tracing_controller.h',
'public/browser/user_metrics.h',
'public/browser/utility_process_host.h',
'public/browser/web_contents.cc',
@@ -1104,6 +1105,8 @@
'browser/tracing/trace_message_filter.h',
'browser/tracing/trace_subscriber_stdio.cc',
'browser/tracing/trace_subscriber_stdio.h',
+ 'browser/tracing/tracing_controller_impl.cc',
+ 'browser/tracing/tracing_controller_impl.h',
'browser/tracing/tracing_ui.cc',
'browser/tracing/tracing_ui.h',
'browser/udev_linux.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index 3bb59bb..5a5b66a 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -842,6 +842,7 @@
'browser/session_history_browsertest.cc',
'browser/site_per_process_browsertest.cc',
'browser/speech/speech_recognition_browsertest.cc',
+ 'browser/tracing/tracing_controller_browsertest.cc',
'browser/web_contents/touch_editable_impl_aura_browsertest.cc',
'browser/web_contents/web_contents_impl_browsertest.cc',
'browser/web_contents/web_contents_view_aura_browsertest.cc',
diff --git a/content/public/browser/trace_controller.h b/content/public/browser/trace_controller.h
index 0049555..ebcff7f 100644
--- a/content/public/browser/trace_controller.h
+++ b/content/public/browser/trace_controller.h
@@ -12,6 +12,9 @@ namespace content {
class TraceSubscriber;
+// Note: TraceController is going to be deprecated and replaced with
+// TracingController.
+//
// 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
diff --git a/content/public/browser/tracing_controller.h b/content/public/browser/tracing_controller.h
new file mode 100644
index 0000000..18d4355
--- /dev/null
+++ b/content/public/browser/tracing_controller.h
@@ -0,0 +1,131 @@
+// Copyright 2013 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_TRACING_CONTROLLER_H_
+#define CONTENT_PUBLIC_BROWSER_TRACING_CONTROLLER_H_
+
+#include "base/debug/trace_event.h"
+#include "content/common/content_export.h"
+
+namespace base {
+class FilePath;
+};
+
+namespace content {
+
+class TracingController;
+
+// TracingController 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 TracingController object. All callbacks are called on
+// the UI thread.
+class TracingController {
+ public:
+ enum Options {
+ ENABLE_SYSTRACE = 1 << 0,
+ ENABLE_SAMPLING = 1 << 1,
+ };
+
+ CONTENT_EXPORT static TracingController* GetInstance();
+
+ // Get a set of category groups. The category groups can change as
+ // new code paths are reached.
+ //
+ // Once all child processes have acked to the GetCategories request,
+ // GetCategoriesDoneCallback is called back with a set of category
+ // groups.
+ typedef base::Callback<void(const std::set<std::string>&)>
+ GetCategoriesDoneCallback;
+ virtual void GetCategories(
+ const GetCategoriesDoneCallback& callback) = 0;
+
+ // Start recording on all processes.
+ //
+ // Recording begins immediately locally, and asynchronously on child processes
+ // as soon as they receive the EnableRecording request.
+ //
+ // Once all child processes have acked to the EnableRecording request,
+ // EnableRecordingDoneCallback will be called back.
+ //
+ // |filter| is a filter to control what category groups should be traced.
+ // A filter can have an optional '-' prefix to exclude category groups
+ // that contain a matching category. Having both included and excluded
+ // category patterns in the same list would not be supported.
+ //
+ // Examples: "test_MyTest*",
+ // "test_MyTest*,test_OtherStuff",
+ // "-excluded_category1,-excluded_category2"
+ //
+ // |options| controls what kind of tracing is enabled.
+ typedef base::Callback<void()> EnableRecordingDoneCallback;
+ virtual void EnableRecording(
+ const base::debug::CategoryFilter& filter,
+ TracingController::Options options,
+ const EnableRecordingDoneCallback& callback) = 0;
+
+ // Stop recording 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 to the DisableRecording request,
+ // TracingFileResultCallback will be called back with a file that contains
+ // the traced data.
+ typedef base::Callback<void(scoped_ptr<base::FilePath>)>
+ TracingFileResultCallback;
+ virtual void DisableRecording(const TracingFileResultCallback& callback) = 0;
+
+ // Start monitoring on all processes.
+ //
+ // Monitoring begins immediately locally, and asynchronously on child
+ // processes as soon as they receive the EnableMonitoring request.
+ //
+ // Once all child processes have acked to the EnableMonitoring request,
+ // EnableMonitoringDoneCallback will be called back.
+ //
+ // |filter| is a filter to control what category groups should be traced.
+ //
+ // |options| controls what kind of tracing is enabled.
+ typedef base::Callback<void()> EnableMonitoringDoneCallback;
+ virtual void EnableMonitoring(const base::debug::CategoryFilter& filter,
+ TracingController::Options options,
+ const EnableMonitoringDoneCallback& callback) = 0;
+
+ // Stop monitoring on all processes.
+ //
+ // Once all child processes have acked to the DisableMonitoring request,
+ // DisableMonitoringDoneCallback is called back.
+ typedef base::Callback<void()> DisableMonitoringDoneCallback;
+ virtual void DisableMonitoring(
+ const DisableMonitoringDoneCallback& callback) = 0;
+
+ // Get the current monitoring configuration.
+ virtual void GetMonitoringStatus(bool* out_enabled,
+ base::debug::CategoryFilter* out_filter,
+ TracingController::Options* out_options) = 0;
+
+ // Get the current monitoring traced data.
+ //
+ // 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 to the CaptureCurrentMonitoringSnapshot
+ // request, TracingFileResultCallback will be called back with a file that
+ // contains the traced data.
+ virtual void CaptureCurrentMonitoringSnapshot(
+ const TracingFileResultCallback& callback) = 0;
+
+ protected:
+ virtual ~TracingController() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_TRACING_CONTROLLER_H_