OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/test/base/tracing.h" | 5 #include "chrome/test/base/tracing.h" |
6 | 6 |
7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/singleton.h" | 10 #include "base/memory/singleton.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 DISALLOW_COPY_AND_ASSIGN(StringTraceSink); | 44 DISALLOW_COPY_AND_ASSIGN(StringTraceSink); |
45 }; | 45 }; |
46 | 46 |
47 class InProcessTraceController { | 47 class InProcessTraceController { |
48 public: | 48 public: |
49 static InProcessTraceController* GetInstance() { | 49 static InProcessTraceController* GetInstance() { |
50 return base::Singleton<InProcessTraceController>::get(); | 50 return base::Singleton<InProcessTraceController>::get(); |
51 } | 51 } |
52 | 52 |
53 InProcessTraceController() | 53 InProcessTraceController() {} |
54 : is_waiting_on_watch_(false), | |
55 watch_notification_count_(0) {} | |
56 virtual ~InProcessTraceController() {} | 54 virtual ~InProcessTraceController() {} |
57 | 55 |
58 bool BeginTracing(const base::trace_event::TraceConfig& trace_config) { | 56 bool BeginTracing(const base::trace_event::TraceConfig& trace_config) { |
59 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 57 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
60 return content::TracingController::GetInstance()->StartTracing( | 58 return content::TracingController::GetInstance()->StartTracing( |
61 trace_config, content::TracingController::StartTracingDoneCallback()); | 59 trace_config, content::TracingController::StartTracingDoneCallback()); |
62 } | 60 } |
63 | 61 |
64 bool BeginTracingWithWatch(const std::string& category_patterns, | |
65 const std::string& category_name, | |
66 const std::string& event_name, | |
67 int num_occurrences) { | |
68 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
69 DCHECK(num_occurrences > 0); | |
70 watch_notification_count_ = num_occurrences; | |
71 if (!content::TracingController::GetInstance()->SetWatchEvent( | |
72 category_name, event_name, | |
73 base::Bind(&InProcessTraceController::OnWatchEventMatched, | |
74 base::Unretained(this)))) { | |
75 return false; | |
76 } | |
77 if (!content::TracingController::GetInstance()->StartTracing( | |
78 base::trace_event::TraceConfig(category_patterns, ""), | |
79 base::Bind(&InProcessTraceController::OnEnableTracingComplete, | |
80 base::Unretained(this)))) { | |
81 return false; | |
82 } | |
83 | |
84 message_loop_runner_ = new content::MessageLoopRunner; | |
85 message_loop_runner_->Run(); | |
86 return true; | |
87 } | |
88 | |
89 bool WaitForWatchEvent(base::TimeDelta timeout) { | |
90 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
91 if (watch_notification_count_ == 0) | |
92 return true; | |
93 | |
94 if (!timeout.is_zero()) { | |
95 timer_.Start(FROM_HERE, timeout, this, | |
96 &InProcessTraceController::Timeout); | |
97 } | |
98 | |
99 is_waiting_on_watch_ = true; | |
100 message_loop_runner_ = new content::MessageLoopRunner; | |
101 message_loop_runner_->Run(); | |
102 is_waiting_on_watch_ = false; | |
103 | |
104 return watch_notification_count_ == 0; | |
105 } | |
106 | |
107 bool EndTracing(std::string* json_trace_output) { | 62 bool EndTracing(std::string* json_trace_output) { |
108 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 63 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
109 using namespace base::debug; | 64 using namespace base::debug; |
110 | 65 |
111 if (!content::TracingController::GetInstance()->StopTracing( | 66 if (!content::TracingController::GetInstance()->StopTracing( |
112 new StringTraceSink( | 67 new StringTraceSink( |
113 json_trace_output, | 68 json_trace_output, |
114 base::Bind(&InProcessTraceController::OnTracingComplete, | 69 base::Bind(&InProcessTraceController::OnTracingComplete, |
115 base::Unretained(this))))) { | 70 base::Unretained(this))))) { |
116 return false; | 71 return false; |
117 } | 72 } |
118 // Wait for OnEndTracingComplete() to quit the message loop. | 73 // Wait for OnEndTracingComplete() to quit the message loop. |
119 message_loop_runner_ = new content::MessageLoopRunner; | 74 message_loop_runner_ = new content::MessageLoopRunner; |
120 message_loop_runner_->Run(); | 75 message_loop_runner_->Run(); |
121 | 76 |
122 // Watch notifications can occur during this method's message loop run, but | |
123 // not after, so clear them here. | |
124 watch_notification_count_ = 0; | |
125 return true; | 77 return true; |
126 } | 78 } |
127 | 79 |
128 private: | 80 private: |
129 friend struct base::DefaultSingletonTraits<InProcessTraceController>; | 81 friend struct base::DefaultSingletonTraits<InProcessTraceController>; |
130 | 82 |
131 void OnEnableTracingComplete() { | 83 void OnEnableTracingComplete() { |
132 message_loop_runner_->Quit(); | 84 message_loop_runner_->Quit(); |
133 } | 85 } |
134 | 86 |
135 void OnTracingComplete() { message_loop_runner_->Quit(); } | 87 void OnTracingComplete() { message_loop_runner_->Quit(); } |
136 | 88 |
137 void OnWatchEventMatched() { | |
138 if (watch_notification_count_ == 0) | |
139 return; | |
140 if (--watch_notification_count_ == 0) { | |
141 timer_.Stop(); | |
142 if (is_waiting_on_watch_) | |
143 message_loop_runner_->Quit(); | |
144 } | |
145 } | |
146 | |
147 void Timeout() { | |
148 DCHECK(is_waiting_on_watch_); | |
149 message_loop_runner_->Quit(); | |
150 } | |
151 | |
152 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | 89 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
153 | 90 |
154 base::OneShotTimer timer_; | 91 base::OneShotTimer timer_; |
155 | 92 |
156 bool is_waiting_on_watch_; | |
157 int watch_notification_count_; | |
158 | |
159 DISALLOW_COPY_AND_ASSIGN(InProcessTraceController); | 93 DISALLOW_COPY_AND_ASSIGN(InProcessTraceController); |
160 }; | 94 }; |
161 | 95 |
162 } // namespace | 96 } // namespace |
163 | 97 |
164 namespace tracing { | 98 namespace tracing { |
165 | 99 |
166 bool BeginTracing(const std::string& category_patterns) { | 100 bool BeginTracing(const std::string& category_patterns) { |
167 return InProcessTraceController::GetInstance()->BeginTracing( | 101 return InProcessTraceController::GetInstance()->BeginTracing( |
168 base::trace_event::TraceConfig(category_patterns, "")); | 102 base::trace_event::TraceConfig(category_patterns, "")); |
169 } | 103 } |
170 | 104 |
171 bool BeginTracingWithWatch(const std::string& category_patterns, | |
172 const std::string& category_name, | |
173 const std::string& event_name, | |
174 int num_occurrences) { | |
175 return InProcessTraceController::GetInstance()->BeginTracingWithWatch( | |
176 category_patterns, category_name, event_name, num_occurrences); | |
177 } | |
178 | |
179 bool BeginTracingWithTraceConfig( | 105 bool BeginTracingWithTraceConfig( |
180 const base::trace_event::TraceConfig& trace_config) { | 106 const base::trace_event::TraceConfig& trace_config) { |
181 return InProcessTraceController::GetInstance()->BeginTracing(trace_config); | 107 return InProcessTraceController::GetInstance()->BeginTracing(trace_config); |
182 } | 108 } |
183 | 109 |
184 bool WaitForWatchEvent(base::TimeDelta timeout) { | |
185 return InProcessTraceController::GetInstance()->WaitForWatchEvent(timeout); | |
186 } | |
187 | |
188 bool EndTracing(std::string* json_trace_output) { | 110 bool EndTracing(std::string* json_trace_output) { |
189 return InProcessTraceController::GetInstance()->EndTracing(json_trace_output); | 111 return InProcessTraceController::GetInstance()->EndTracing(json_trace_output); |
190 } | 112 } |
191 | 113 |
192 } // namespace tracing | 114 } // namespace tracing |
193 | |
OLD | NEW |