OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/devtools/protocol/tracing_handler.h" | 5 #include "content/browser/devtools/protocol/tracing_handler.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "base/timer/timer.h" | 13 #include "base/timer/timer.h" |
14 #include "base/trace_event/trace_event_impl.h" | 14 #include "base/trace_event/trace_event_impl.h" |
15 | 15 |
16 namespace content { | 16 namespace content { |
17 namespace devtools { | 17 namespace devtools { |
18 namespace tracing { | 18 namespace tracing { |
19 | 19 |
20 typedef DevToolsProtocolClient::Response Response; | 20 typedef DevToolsProtocolClient::Response Response; |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 const char kRecordUntilFull[] = "record-until-full"; | |
25 const char kRecordContinuously[] = "record-continuously"; | |
26 const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible"; | |
27 const char kEnableSampling[] = "enable-sampling"; | |
28 const double kMinimumReportingInterval = 250.0; | 24 const double kMinimumReportingInterval = 250.0; |
29 | 25 |
30 class DevToolsTraceSinkProxy : public TracingController::TraceDataSink { | 26 class DevToolsTraceSinkProxy : public TracingController::TraceDataSink { |
31 public: | 27 public: |
32 explicit DevToolsTraceSinkProxy(base::WeakPtr<TracingHandler> handler) | 28 explicit DevToolsTraceSinkProxy(base::WeakPtr<TracingHandler> handler) |
33 : tracing_handler_(handler) {} | 29 : tracing_handler_(handler) {} |
34 | 30 |
35 void AddTraceChunk(const std::string& chunk) override { | 31 void AddTraceChunk(const std::string& chunk) override { |
36 if (TracingHandler* h = tracing_handler_.get()) | 32 if (TracingHandler* h = tracing_handler_.get()) |
37 h->OnTraceDataCollected(chunk); | 33 h->OnTraceDataCollected(chunk); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 message += "] } }"; | 74 message += "] } }"; |
79 client_->SendRawMessage(message); | 75 client_->SendRawMessage(message); |
80 } | 76 } |
81 | 77 |
82 void TracingHandler::OnTraceComplete() { | 78 void TracingHandler::OnTraceComplete() { |
83 client_->TracingComplete(TracingCompleteParams::Create()); | 79 client_->TracingComplete(TracingCompleteParams::Create()); |
84 } | 80 } |
85 | 81 |
86 Response TracingHandler::Start(DevToolsCommandId command_id, | 82 Response TracingHandler::Start(DevToolsCommandId command_id, |
87 const std::string* categories, | 83 const std::string* categories, |
88 const std::string* options_str, | 84 const std::string* options, |
89 const double* buffer_usage_reporting_interval) { | 85 const double* buffer_usage_reporting_interval) { |
90 if (is_recording_) | 86 if (is_recording_) |
91 return Response::InternalError("Tracing is already started"); | 87 return Response::InternalError("Tracing is already started"); |
92 | 88 |
93 is_recording_ = true; | 89 is_recording_ = true; |
94 base::trace_event::TraceOptions options = TraceOptionsFromString(options_str); | 90 base::trace_event::TraceConfig trace_config( |
95 base::trace_event::CategoryFilter filter(categories ? *categories | 91 categories ? *categories : std::string(), |
96 : std::string()); | 92 options ? *options : std::string()); |
97 if (buffer_usage_reporting_interval) | 93 if (buffer_usage_reporting_interval) |
98 SetupTimer(*buffer_usage_reporting_interval); | 94 SetupTimer(*buffer_usage_reporting_interval); |
99 | 95 |
100 // If inspected target is a render process Tracing.start will be handled by | 96 // If inspected target is a render process Tracing.start will be handled by |
101 // tracing agent in the renderer. | 97 // tracing agent in the renderer. |
102 if (target_ == Renderer) { | 98 if (target_ == Renderer) { |
103 TracingController::GetInstance()->EnableRecording( | 99 TracingController::GetInstance()->EnableRecording( |
104 filter, | 100 trace_config, |
105 options, | |
106 TracingController::EnableRecordingDoneCallback()); | 101 TracingController::EnableRecordingDoneCallback()); |
107 return Response::FallThrough(); | 102 return Response::FallThrough(); |
108 } | 103 } |
109 | 104 |
110 TracingController::GetInstance()->EnableRecording( | 105 TracingController::GetInstance()->EnableRecording( |
111 filter, | 106 trace_config, |
112 options, | |
113 base::Bind(&TracingHandler::OnRecordingEnabled, | 107 base::Bind(&TracingHandler::OnRecordingEnabled, |
114 weak_factory_.GetWeakPtr(), | 108 weak_factory_.GetWeakPtr(), |
115 command_id)); | 109 command_id)); |
116 return Response::OK(); | 110 return Response::OK(); |
117 } | 111 } |
118 | 112 |
119 Response TracingHandler::End(DevToolsCommandId command_id) { | 113 Response TracingHandler::End(DevToolsCommandId command_id) { |
120 if (!is_recording_) | 114 if (!is_recording_) |
121 return Response::InternalError("Tracing is not started"); | 115 return Response::InternalError("Tracing is not started"); |
122 | 116 |
(...skipping 28 matching lines...) Expand all Loading... |
151 void TracingHandler::OnCategoriesReceived( | 145 void TracingHandler::OnCategoriesReceived( |
152 DevToolsCommandId command_id, | 146 DevToolsCommandId command_id, |
153 const std::set<std::string>& category_set) { | 147 const std::set<std::string>& category_set) { |
154 std::vector<std::string> categories; | 148 std::vector<std::string> categories; |
155 for (const std::string& category : category_set) | 149 for (const std::string& category : category_set) |
156 categories.push_back(category); | 150 categories.push_back(category); |
157 client_->SendGetCategoriesResponse(command_id, | 151 client_->SendGetCategoriesResponse(command_id, |
158 GetCategoriesResponse::Create()->set_categories(categories)); | 152 GetCategoriesResponse::Create()->set_categories(categories)); |
159 } | 153 } |
160 | 154 |
161 base::trace_event::TraceOptions TracingHandler::TraceOptionsFromString( | |
162 const std::string* options) { | |
163 base::trace_event::TraceOptions ret; | |
164 if (!options) | |
165 return ret; | |
166 | |
167 std::vector<std::string> split; | |
168 std::vector<std::string>::iterator iter; | |
169 | |
170 base::SplitString(*options, ',', &split); | |
171 for (iter = split.begin(); iter != split.end(); ++iter) { | |
172 if (*iter == kRecordUntilFull) { | |
173 ret.record_mode = base::trace_event::RECORD_UNTIL_FULL; | |
174 } else if (*iter == kRecordContinuously) { | |
175 ret.record_mode = base::trace_event::RECORD_CONTINUOUSLY; | |
176 } else if (*iter == kRecordAsMuchAsPossible) { | |
177 ret.record_mode = base::trace_event::RECORD_AS_MUCH_AS_POSSIBLE; | |
178 } else if (*iter == kEnableSampling) { | |
179 ret.enable_sampling = true; | |
180 } | |
181 } | |
182 return ret; | |
183 } | |
184 | |
185 void TracingHandler::SetupTimer(double usage_reporting_interval) { | 155 void TracingHandler::SetupTimer(double usage_reporting_interval) { |
186 if (usage_reporting_interval == 0) return; | 156 if (usage_reporting_interval == 0) return; |
187 | 157 |
188 if (usage_reporting_interval < kMinimumReportingInterval) | 158 if (usage_reporting_interval < kMinimumReportingInterval) |
189 usage_reporting_interval = kMinimumReportingInterval; | 159 usage_reporting_interval = kMinimumReportingInterval; |
190 | 160 |
191 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( | 161 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( |
192 std::ceil(usage_reporting_interval)); | 162 std::ceil(usage_reporting_interval)); |
193 buffer_usage_poll_timer_.reset(new base::Timer( | 163 buffer_usage_poll_timer_.reset(new base::Timer( |
194 FROM_HERE, interval, | 164 FROM_HERE, interval, |
195 base::Bind(base::IgnoreResult(&TracingController::GetTraceBufferUsage), | 165 base::Bind(base::IgnoreResult(&TracingController::GetTraceBufferUsage), |
196 base::Unretained(TracingController::GetInstance()), | 166 base::Unretained(TracingController::GetInstance()), |
197 base::Bind(&TracingHandler::OnBufferUsage, | 167 base::Bind(&TracingHandler::OnBufferUsage, |
198 weak_factory_.GetWeakPtr())), | 168 weak_factory_.GetWeakPtr())), |
199 true)); | 169 true)); |
200 buffer_usage_poll_timer_->Reset(); | 170 buffer_usage_poll_timer_->Reset(); |
201 } | 171 } |
202 | 172 |
203 void TracingHandler::DisableRecording(bool abort) { | 173 void TracingHandler::DisableRecording(bool abort) { |
204 is_recording_ = false; | 174 is_recording_ = false; |
205 buffer_usage_poll_timer_.reset(); | 175 buffer_usage_poll_timer_.reset(); |
206 TracingController::GetInstance()->DisableRecording( | 176 TracingController::GetInstance()->DisableRecording( |
207 abort ? nullptr : new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr())); | 177 abort ? nullptr : new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr())); |
208 } | 178 } |
209 | 179 |
210 } // namespace tracing | 180 } // namespace tracing |
211 } // namespace devtools | 181 } // namespace devtools |
212 } // namespace content | 182 } // namespace content |
OLD | NEW |