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/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/memory/singleton.h" | 10 #include "base/memory/singleton.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "base/timer/timer.h" | 13 #include "base/timer/timer.h" |
14 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/tracing_controller.h" | 15 #include "content/public/browser/tracing_controller.h" |
16 #include "content/public/test/test_utils.h" | 16 #include "content/public/test/test_utils.h" |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 using content::BrowserThread; | 20 using content::BrowserThread; |
21 | 21 |
| 22 class StringTraceSink : public content::TracingController::TraceDataSink { |
| 23 public: |
| 24 StringTraceSink(std::string* result, const base::Closure& callback) |
| 25 : result_(result), completion_callback_(callback) {} |
| 26 |
| 27 virtual void AddTraceChunk(const std::string& chunk) OVERRIDE { |
| 28 *result_ += result_->empty() ? "[" : ","; |
| 29 *result_ += chunk; |
| 30 } |
| 31 virtual void Close() OVERRIDE { |
| 32 if (!result_->empty()) |
| 33 *result_ += "]"; |
| 34 completion_callback_.Run(); |
| 35 } |
| 36 |
| 37 private: |
| 38 virtual ~StringTraceSink() {} |
| 39 |
| 40 std::string* result_; |
| 41 base::Closure completion_callback_; |
| 42 |
| 43 DISALLOW_COPY_AND_ASSIGN(StringTraceSink); |
| 44 }; |
| 45 |
22 class InProcessTraceController { | 46 class InProcessTraceController { |
23 public: | 47 public: |
24 static InProcessTraceController* GetInstance() { | 48 static InProcessTraceController* GetInstance() { |
25 return Singleton<InProcessTraceController>::get(); | 49 return Singleton<InProcessTraceController>::get(); |
26 } | 50 } |
27 | 51 |
28 InProcessTraceController() | 52 InProcessTraceController() |
29 : is_waiting_on_watch_(false), | 53 : is_waiting_on_watch_(false), |
30 watch_notification_count_(0) {} | 54 watch_notification_count_(0) {} |
31 virtual ~InProcessTraceController() {} | 55 virtual ~InProcessTraceController() {} |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 is_waiting_on_watch_ = false; | 104 is_waiting_on_watch_ = false; |
81 | 105 |
82 return watch_notification_count_ == 0; | 106 return watch_notification_count_ == 0; |
83 } | 107 } |
84 | 108 |
85 bool EndTracing(std::string* json_trace_output) { | 109 bool EndTracing(std::string* json_trace_output) { |
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
87 using namespace base::debug; | 111 using namespace base::debug; |
88 | 112 |
89 if (!content::TracingController::GetInstance()->DisableRecording( | 113 if (!content::TracingController::GetInstance()->DisableRecording( |
90 base::FilePath(), | 114 new StringTraceSink( |
91 base::Bind(&InProcessTraceController::OnTraceDataCollected, | 115 json_trace_output, |
92 base::Unretained(this), | 116 base::Bind(&InProcessTraceController::OnTracingComplete, |
93 base::Unretained(json_trace_output)))) | 117 base::Unretained(this))))) { |
94 return false; | 118 return false; |
95 | 119 } |
96 // Wait for OnEndTracingComplete() to quit the message loop. | 120 // Wait for OnEndTracingComplete() to quit the message loop. |
97 message_loop_runner_ = new content::MessageLoopRunner; | 121 message_loop_runner_ = new content::MessageLoopRunner; |
98 message_loop_runner_->Run(); | 122 message_loop_runner_->Run(); |
99 | 123 |
100 // Watch notifications can occur during this method's message loop run, but | 124 // Watch notifications can occur during this method's message loop run, but |
101 // not after, so clear them here. | 125 // not after, so clear them here. |
102 watch_notification_count_ = 0; | 126 watch_notification_count_ = 0; |
103 return true; | 127 return true; |
104 } | 128 } |
105 | 129 |
106 private: | 130 private: |
107 friend struct DefaultSingletonTraits<InProcessTraceController>; | 131 friend struct DefaultSingletonTraits<InProcessTraceController>; |
108 | 132 |
109 void OnEnableTracingComplete() { | 133 void OnEnableTracingComplete() { |
110 message_loop_runner_->Quit(); | 134 message_loop_runner_->Quit(); |
111 } | 135 } |
112 | 136 |
113 void OnEndTracingComplete() { | 137 void OnTracingComplete() { message_loop_runner_->Quit(); } |
114 message_loop_runner_->Quit(); | |
115 } | |
116 | |
117 void OnTraceDataCollected(std::string* json_trace_output, | |
118 const base::FilePath& path) { | |
119 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | |
120 base::Bind(&InProcessTraceController::ReadTraceData, | |
121 base::Unretained(this), | |
122 base::Unretained(json_trace_output), | |
123 path)); | |
124 } | |
125 | |
126 void ReadTraceData(std::string* json_trace_output, | |
127 const base::FilePath& path) { | |
128 json_trace_output->clear(); | |
129 bool ok = base::ReadFileToString(path, json_trace_output); | |
130 DCHECK(ok); | |
131 base::DeleteFile(path, false); | |
132 | |
133 // The callers expect an array of trace events. | |
134 const char* preamble = "{\"traceEvents\": "; | |
135 const char* trailout = "}"; | |
136 DCHECK(StartsWithASCII(*json_trace_output, preamble, true)); | |
137 DCHECK(EndsWith(*json_trace_output, trailout, true)); | |
138 json_trace_output->erase(0, strlen(preamble)); | |
139 json_trace_output->erase(json_trace_output->end() - 1); | |
140 | |
141 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
142 base::Bind(&InProcessTraceController::OnEndTracingComplete, | |
143 base::Unretained(this))); | |
144 } | |
145 | 138 |
146 void OnWatchEventMatched() { | 139 void OnWatchEventMatched() { |
147 if (watch_notification_count_ == 0) | 140 if (watch_notification_count_ == 0) |
148 return; | 141 return; |
149 if (--watch_notification_count_ == 0) { | 142 if (--watch_notification_count_ == 0) { |
150 timer_.Stop(); | 143 timer_.Stop(); |
151 if (is_waiting_on_watch_) | 144 if (is_waiting_on_watch_) |
152 message_loop_runner_->Quit(); | 145 message_loop_runner_->Quit(); |
153 } | 146 } |
154 } | 147 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 bool WaitForWatchEvent(base::TimeDelta timeout) { | 181 bool WaitForWatchEvent(base::TimeDelta timeout) { |
189 return InProcessTraceController::GetInstance()->WaitForWatchEvent(timeout); | 182 return InProcessTraceController::GetInstance()->WaitForWatchEvent(timeout); |
190 } | 183 } |
191 | 184 |
192 bool EndTracing(std::string* json_trace_output) { | 185 bool EndTracing(std::string* json_trace_output) { |
193 return InProcessTraceController::GetInstance()->EndTracing(json_trace_output); | 186 return InProcessTraceController::GetInstance()->EndTracing(json_trace_output); |
194 } | 187 } |
195 | 188 |
196 } // namespace tracing | 189 } // namespace tracing |
197 | 190 |
OLD | NEW |