Merge html-office-public repo into src
[chromium-blink-merge.git] / chrome / test / base / tracing.cc
blob6ed0f54a316b92f4a72e9aa2f30b842f93e6a4be
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/test/base/tracing.h"
7 #include "base/debug/trace_event.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/memory/singleton.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/strings/string_util.h"
13 #include "base/timer/timer.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/tracing_controller.h"
16 #include "content/public/test/test_utils.h"
18 namespace {
20 using content::BrowserThread;
22 class StringTraceSink : public content::TracingController::TraceDataSink {
23 public:
24 StringTraceSink(std::string* result, const base::Closure& callback)
25 : result_(result), completion_callback_(callback) {}
27 void AddTraceChunk(const std::string& chunk) override {
28 *result_ += result_->empty() ? "[" : ",";
29 *result_ += chunk;
31 void Close() override {
32 if (!result_->empty())
33 *result_ += "]";
34 completion_callback_.Run();
37 private:
38 ~StringTraceSink() override {}
40 std::string* result_;
41 base::Closure completion_callback_;
43 DISALLOW_COPY_AND_ASSIGN(StringTraceSink);
46 class InProcessTraceController {
47 public:
48 static InProcessTraceController* GetInstance() {
49 return Singleton<InProcessTraceController>::get();
52 InProcessTraceController()
53 : is_waiting_on_watch_(false),
54 watch_notification_count_(0) {}
55 virtual ~InProcessTraceController() {}
57 bool BeginTracing(const std::string& category_patterns) {
58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59 return content::TracingController::GetInstance()->EnableRecording(
60 base::debug::CategoryFilter(category_patterns),
61 base::debug::TraceOptions(),
62 content::TracingController::EnableRecordingDoneCallback());
65 bool BeginTracingWithWatch(const std::string& category_patterns,
66 const std::string& category_name,
67 const std::string& event_name,
68 int num_occurrences) {
69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
70 DCHECK(num_occurrences > 0);
71 watch_notification_count_ = num_occurrences;
72 if (!content::TracingController::GetInstance()->SetWatchEvent(
73 category_name, event_name,
74 base::Bind(&InProcessTraceController::OnWatchEventMatched,
75 base::Unretained(this)))) {
76 return false;
78 if (!content::TracingController::GetInstance()->EnableRecording(
79 base::debug::CategoryFilter(category_patterns),
80 base::debug::TraceOptions(),
81 base::Bind(&InProcessTraceController::OnEnableTracingComplete,
82 base::Unretained(this)))) {
83 return false;
86 message_loop_runner_ = new content::MessageLoopRunner;
87 message_loop_runner_->Run();
88 return true;
91 bool WaitForWatchEvent(base::TimeDelta timeout) {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93 if (watch_notification_count_ == 0)
94 return true;
96 if (timeout != base::TimeDelta()) {
97 timer_.Start(FROM_HERE, timeout, this,
98 &InProcessTraceController::Timeout);
101 is_waiting_on_watch_ = true;
102 message_loop_runner_ = new content::MessageLoopRunner;
103 message_loop_runner_->Run();
104 is_waiting_on_watch_ = false;
106 return watch_notification_count_ == 0;
109 bool EndTracing(std::string* json_trace_output) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
111 using namespace base::debug;
113 if (!content::TracingController::GetInstance()->DisableRecording(
114 new StringTraceSink(
115 json_trace_output,
116 base::Bind(&InProcessTraceController::OnTracingComplete,
117 base::Unretained(this))))) {
118 return false;
120 // Wait for OnEndTracingComplete() to quit the message loop.
121 message_loop_runner_ = new content::MessageLoopRunner;
122 message_loop_runner_->Run();
124 // Watch notifications can occur during this method's message loop run, but
125 // not after, so clear them here.
126 watch_notification_count_ = 0;
127 return true;
130 private:
131 friend struct DefaultSingletonTraits<InProcessTraceController>;
133 void OnEnableTracingComplete() {
134 message_loop_runner_->Quit();
137 void OnTracingComplete() { message_loop_runner_->Quit(); }
139 void OnWatchEventMatched() {
140 if (watch_notification_count_ == 0)
141 return;
142 if (--watch_notification_count_ == 0) {
143 timer_.Stop();
144 if (is_waiting_on_watch_)
145 message_loop_runner_->Quit();
149 void Timeout() {
150 DCHECK(is_waiting_on_watch_);
151 message_loop_runner_->Quit();
154 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
156 base::OneShotTimer<InProcessTraceController> timer_;
158 bool is_waiting_on_watch_;
159 int watch_notification_count_;
161 DISALLOW_COPY_AND_ASSIGN(InProcessTraceController);
164 } // namespace
166 namespace tracing {
168 bool BeginTracing(const std::string& category_patterns) {
169 return InProcessTraceController::GetInstance()->BeginTracing(
170 category_patterns);
173 bool BeginTracingWithWatch(const std::string& category_patterns,
174 const std::string& category_name,
175 const std::string& event_name,
176 int num_occurrences) {
177 return InProcessTraceController::GetInstance()->BeginTracingWithWatch(
178 category_patterns, category_name, event_name, num_occurrences);
181 bool WaitForWatchEvent(base::TimeDelta timeout) {
182 return InProcessTraceController::GetInstance()->WaitForWatchEvent(timeout);
185 bool EndTracing(std::string* json_trace_output) {
186 return InProcessTraceController::GetInstance()->EndTracing(json_trace_output);
189 } // namespace tracing