diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-13 15:43:08 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-13 15:43:08 +0000 |
commit | 900e91294c742ce19d633dd5f2a0ce2e198febbc (patch) | |
tree | ad3b3f8a784407ffd3fe480b9ea616954ddc6681 | |
parent | 4fe481a76941852a69eb75c30c70316ca2805660 (diff) | |
download | chromium_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/DEPS | 1 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 2 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 4 | ||||
-rw-r--r-- | chrome/browser/ui/webui/profiler_ui.cc | 1 | ||||
-rw-r--r-- | chrome/browser/ui/webui/tracing_ui.cc | 7 | ||||
-rw-r--r-- | chrome/test/base/tracing.cc | 11 | ||||
-rw-r--r-- | content/browser/browser_main_loop.cc | 10 | ||||
-rw-r--r-- | content/browser/trace_controller.h | 180 | ||||
-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.h | 111 | ||||
-rw-r--r-- | content/browser/trace_message_filter.cc | 15 | ||||
-rw-r--r-- | content/browser/trace_subscriber_stdio.cc | 2 | ||||
-rw-r--r-- | content/browser/trace_subscriber_stdio.h | 6 | ||||
-rw-r--r-- | content/content_browser.gypi | 6 | ||||
-rw-r--r-- | content/public/browser/trace_controller.h | 86 | ||||
-rw-r--r-- | content/public/browser/trace_subscriber.h | 40 |
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_ |