Add long running gmail memory benchmark for background tab.
[chromium-blink-merge.git] / content / browser / devtools / protocol / tracing_handler.cc
blob66f54d21de2b8fdaf523f92f73f28fbebd2b845e
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
3 // found in the LICENSE file.
5 #include "content/browser/devtools/protocol/tracing_handler.h"
7 #include <cmath>
9 #include "base/bind.h"
10 #include "base/format_macros.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
15 #include "base/trace_event/memory_dump_manager.h"
16 #include "base/trace_event/trace_event_impl.h"
18 namespace content {
19 namespace devtools {
20 namespace tracing {
22 typedef DevToolsProtocolClient::Response Response;
24 namespace {
26 const double kMinimumReportingInterval = 250.0;
28 class DevToolsTraceSinkProxy : public TracingController::TraceDataSink {
29 public:
30 explicit DevToolsTraceSinkProxy(base::WeakPtr<TracingHandler> handler)
31 : tracing_handler_(handler) {}
33 void AddTraceChunk(const std::string& chunk) override {
34 if (TracingHandler* h = tracing_handler_.get())
35 h->OnTraceDataCollected(chunk);
37 void Close() override {
38 if (TracingHandler* h = tracing_handler_.get())
39 h->OnTraceComplete();
42 private:
43 ~DevToolsTraceSinkProxy() override {}
45 base::WeakPtr<TracingHandler> tracing_handler_;
48 } // namespace
50 TracingHandler::TracingHandler(TracingHandler::Target target)
51 : target_(target),
52 did_initiate_recording_(false),
53 weak_factory_(this) {
56 TracingHandler::~TracingHandler() {
59 void TracingHandler::SetClient(scoped_ptr<Client> client) {
60 client_.swap(client);
63 void TracingHandler::Detached() {
64 if (IsRecording())
65 DisableRecording(true);
68 void TracingHandler::OnTraceDataCollected(const std::string& trace_fragment) {
69 // Hand-craft protocol notification message so we can substitute JSON
70 // that we already got as string as a bare object, not a quoted string.
71 std::string message(
72 "{ \"method\": \"Tracing.dataCollected\", \"params\": { \"value\": [");
73 const size_t messageSuffixSize = 10;
74 message.reserve(message.size() + trace_fragment.size() + messageSuffixSize);
75 message += trace_fragment;
76 message += "] } }";
77 client_->SendRawMessage(message);
80 void TracingHandler::OnTraceComplete() {
81 client_->TracingComplete(TracingCompleteParams::Create());
84 Response TracingHandler::Start(DevToolsCommandId command_id,
85 const std::string* categories,
86 const std::string* options,
87 const double* buffer_usage_reporting_interval) {
88 if (IsRecording())
89 return Response::InternalError("Tracing is already started");
91 did_initiate_recording_ = true;
93 base::trace_event::TraceConfig trace_config(
94 categories ? *categories : std::string(),
95 options ? *options : std::string());
96 if (buffer_usage_reporting_interval)
97 SetupTimer(*buffer_usage_reporting_interval);
99 // If inspected target is a render process Tracing.start will be handled by
100 // tracing agent in the renderer.
101 if (target_ == Renderer) {
102 TracingController::GetInstance()->EnableRecording(
103 trace_config,
104 TracingController::EnableRecordingDoneCallback());
105 return Response::FallThrough();
108 TracingController::GetInstance()->EnableRecording(
109 trace_config,
110 base::Bind(&TracingHandler::OnRecordingEnabled,
111 weak_factory_.GetWeakPtr(),
112 command_id));
113 return Response::OK();
116 Response TracingHandler::End(DevToolsCommandId command_id) {
117 if (!IsRecording())
118 return Response::InternalError("Tracing is not started");
120 DisableRecording(false);
121 // If inspected target is a render process Tracing.end will be handled by
122 // tracing agent in the renderer.
123 return target_ == Renderer ? Response::FallThrough() : Response::OK();
126 Response TracingHandler::GetCategories(DevToolsCommandId command_id) {
127 TracingController::GetInstance()->GetCategories(
128 base::Bind(&TracingHandler::OnCategoriesReceived,
129 weak_factory_.GetWeakPtr(),
130 command_id));
131 return Response::OK();
134 void TracingHandler::OnRecordingEnabled(DevToolsCommandId command_id) {
135 client_->SendStartResponse(command_id, StartResponse::Create());
138 void TracingHandler::OnBufferUsage(float percent_full,
139 size_t approximate_event_count) {
140 // TODO(crbug426117): remove set_value once all clients have switched to
141 // the new interface of the event.
142 client_->BufferUsage(BufferUsageParams::Create()
143 ->set_value(percent_full)
144 ->set_percent_full(percent_full)
145 ->set_event_count(approximate_event_count));
148 void TracingHandler::OnCategoriesReceived(
149 DevToolsCommandId command_id,
150 const std::set<std::string>& category_set) {
151 std::vector<std::string> categories;
152 for (const std::string& category : category_set)
153 categories.push_back(category);
154 client_->SendGetCategoriesResponse(command_id,
155 GetCategoriesResponse::Create()->set_categories(categories));
158 Response TracingHandler::RequestMemoryDump(DevToolsCommandId command_id) {
159 if (!did_initiate_recording_)
160 return Response::InternalError("Tracing is not started");
162 base::trace_event::MemoryDumpManager::GetInstance()->RequestGlobalDump(
163 base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED,
164 base::Bind(&TracingHandler::OnMemoryDumpFinished,
165 weak_factory_.GetWeakPtr(), command_id));
166 return Response::OK();
169 void TracingHandler::OnMemoryDumpFinished(DevToolsCommandId command_id,
170 uint64 dump_guid,
171 bool success) {
172 client_->SendRequestMemoryDumpResponse(
173 command_id,
174 RequestMemoryDumpResponse::Create()
175 ->set_dump_guid(base::StringPrintf("0x%" PRIx64, dump_guid))
176 ->set_success(success));
179 void TracingHandler::SetupTimer(double usage_reporting_interval) {
180 if (usage_reporting_interval == 0) return;
182 if (usage_reporting_interval < kMinimumReportingInterval)
183 usage_reporting_interval = kMinimumReportingInterval;
185 base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
186 std::ceil(usage_reporting_interval));
187 buffer_usage_poll_timer_.reset(new base::Timer(
188 FROM_HERE, interval,
189 base::Bind(base::IgnoreResult(&TracingController::GetTraceBufferUsage),
190 base::Unretained(TracingController::GetInstance()),
191 base::Bind(&TracingHandler::OnBufferUsage,
192 weak_factory_.GetWeakPtr())),
193 true));
194 buffer_usage_poll_timer_->Reset();
197 void TracingHandler::DisableRecording(bool abort) {
198 buffer_usage_poll_timer_.reset();
199 TracingController::GetInstance()->DisableRecording(
200 abort ? nullptr : new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr()));
201 did_initiate_recording_ = false;
204 bool TracingHandler::IsRecording() const {
205 return TracingController::GetInstance()->IsRecording();
208 } // namespace tracing
209 } // namespace devtools
210 } // namespace content