Chromium Code Reviews| Index: chrome/test/base/tracing.cc |
| diff --git a/chrome/test/base/tracing.cc b/chrome/test/base/tracing.cc |
| index 7e609ec6d515255ed68ae2b7bb40ac5343b3393b..208cfbf85f1a54d1468d86b6e036bf259fe9266e 100644 |
| --- a/chrome/test/base/tracing.cc |
| +++ b/chrome/test/base/tracing.cc |
| @@ -7,27 +7,64 @@ |
| #include "base/debug/trace_event.h" |
| #include "base/memory/singleton.h" |
| #include "base/message_loop.h" |
| +#include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/trace_controller.h" |
| #include "content/public/browser/trace_subscriber.h" |
| #include "content/public/test/test_utils.h" |
| namespace { |
| +using content::BrowserThread; |
| + |
| class InProcessTraceController : public content::TraceSubscriber { |
| public: |
| static InProcessTraceController* GetInstance() { |
| return Singleton<InProcessTraceController>::get(); |
| } |
| - InProcessTraceController() {} |
| + InProcessTraceController() |
| + : is_waiting_on_watch_(false) |
| + , watch_notification_count_(0) {} |
|
sky
2012/08/29 16:05:09
, on previous line.
jbates
2012/08/29 21:14:12
Done.
|
| virtual ~InProcessTraceController() {} |
| bool BeginTracing(const std::string& categories) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| return content::TraceController::GetInstance()->BeginTracing( |
| this, categories); |
| } |
| + bool BeginTracingWithWatch(const std::string& categories, |
| + const char* category_name, |
| + const char* event_name, |
| + int num_occurrences) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(num_occurrences > 0); |
| + watch_notification_count_ = num_occurrences; |
| + return BeginTracing(categories) && |
| + content::TraceController::GetInstance()->SetWatchEvent( |
| + this, category_name, event_name); |
| + } |
| + |
| + bool WaitForWatchEvent(base::TimeDelta timeout) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (watch_notification_count_ == 0) |
| + return true; |
| + |
| + if (timeout != base::TimeDelta()) { |
| + timer_.Start(FROM_HERE, timeout, this, |
| + &InProcessTraceController::Timeout); |
| + } |
| + |
| + is_waiting_on_watch_ = true; |
| + message_loop_runner_ = new content::MessageLoopRunner; |
| + message_loop_runner_->Run(); |
| + is_waiting_on_watch_ = false; |
| + |
| + return watch_notification_count_ == 0; |
| + } |
| + |
| bool EndTracing(std::string* json_trace_output) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| using namespace base::debug; |
| TraceResultBuffer::SimpleOutput output; |
| @@ -44,28 +81,53 @@ class InProcessTraceController : public content::TraceSubscriber { |
| trace_buffer_.SetOutputCallback(TraceResultBuffer::OutputCallback()); |
| *json_trace_output = output.json_output; |
| + |
| + // Watch notifications can occur during this method's message loop run, but |
| + // not after, so clear them here. |
| + watch_notification_count_ = 0; |
| return true; |
| } |
| private: |
| friend struct DefaultSingletonTraits<InProcessTraceController>; |
| - // TraceSubscriber |
| + // TraceSubscriber implementation |
| virtual void OnEndTracingComplete() OVERRIDE { |
| message_loop_runner_->Quit(); |
| } |
| - // TraceSubscriber |
| + // TraceSubscriber implementation |
| virtual void OnTraceDataCollected( |
| const scoped_refptr<base::RefCountedString>& trace_fragment) OVERRIDE { |
| trace_buffer_.AddFragment(trace_fragment->data()); |
| } |
| + // TraceSubscriber implementation |
| + virtual void OnEventWatchNotification() { |
|
sky
2012/08/29 16:05:09
OVERRIDE
jbates
2012/08/29 21:14:12
Done.
|
| + if (watch_notification_count_ == 0) |
| + return; |
| + if (--watch_notification_count_ == 0) { |
| + timer_.Stop(); |
| + if (is_waiting_on_watch_) |
| + message_loop_runner_->Quit(); |
|
sky
2012/08/29 16:05:09
Is it possible the timer is still running?
jbates
2012/08/29 21:14:12
It's stopped on line 110.
|
| + } |
| + } |
| + |
| + void Timeout() { |
| + DCHECK(is_waiting_on_watch_); |
| + message_loop_runner_->Quit(); |
| + } |
| + |
| // For collecting trace data asynchronously. |
| base::debug::TraceResultBuffer trace_buffer_; |
| scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
| + base::OneShotTimer<InProcessTraceController> timer_; |
| + |
| + bool is_waiting_on_watch_; |
| + int watch_notification_count_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(InProcessTraceController); |
| }; |
| @@ -77,6 +139,18 @@ bool BeginTracing(const std::string& categories) { |
| return InProcessTraceController::GetInstance()->BeginTracing(categories); |
| } |
| +bool BeginTracingWithWatch(const std::string& categories, |
| + const char* category_name, |
| + const char* event_name, |
| + int num_occurrences) { |
| + return InProcessTraceController::GetInstance()->BeginTracingWithWatch( |
| + categories, category_name, event_name, num_occurrences); |
| +} |
| + |
| +bool WaitForWatchEvent(base::TimeDelta timeout) { |
| + return InProcessTraceController::GetInstance()->WaitForWatchEvent(timeout); |
| +} |
| + |
| bool EndTracing(std::string* json_trace_output) { |
| return InProcessTraceController::GetInstance()->EndTracing(json_trace_output); |
| } |