Commit f7762cb9 authored by dgozman's avatar dgozman Committed by Commit bot

[DevTools] Migrate DevToolsTracingHandler to generated handler.

This patch also adds SendRawMessage, which is used for performance
in tracing handler.

BUG=405566

Review URL: https://codereview.chromium.org/635733003

Cr-Commit-Position: refs/heads/master@{#300711}
parent 6ab66362
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
#include "content/browser/devtools/devtools_protocol.h" #include "content/browser/devtools/devtools_protocol.h"
#include "content/browser/devtools/devtools_protocol_constants.h" #include "content/browser/devtools/devtools_protocol_constants.h"
#include "content/browser/devtools/devtools_system_info_handler.h" #include "content/browser/devtools/devtools_system_info_handler.h"
#include "content/browser/devtools/devtools_tracing_handler.h" #include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
#include "content/browser/devtools/protocol/tracing_handler.h"
#include "content/browser/devtools/tethering_handler.h" #include "content/browser/devtools/tethering_handler.h"
#include "content/common/devtools_messages.h" #include "content/common/devtools_messages.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -158,7 +159,13 @@ class DevToolsHttpHandlerImpl::BrowserTarget { ...@@ -158,7 +159,13 @@ class DevToolsHttpHandlerImpl::BrowserTarget {
int connection_id) int connection_id)
: message_loop_(message_loop), : message_loop_(message_loop),
server_(server), server_(server),
connection_id_(connection_id) { connection_id_(connection_id),
tracing_handler_(new devtools::tracing::TracingHandler(
devtools::tracing::TracingHandler::Browser)),
protocol_handler_(new DevToolsProtocolHandlerImpl()) {
protocol_handler_->SetNotifier(
base::Bind(&BrowserTarget::Respond, base::Unretained(this)));
protocol_handler_->SetTracingHandler(tracing_handler_.get());
} }
~BrowserTarget() { ~BrowserTarget() {
...@@ -183,17 +190,20 @@ class DevToolsHttpHandlerImpl::BrowserTarget { ...@@ -183,17 +190,20 @@ class DevToolsHttpHandlerImpl::BrowserTarget {
return; return;
} }
scoped_refptr<DevToolsProtocol::Response> response =
protocol_handler_->HandleCommand(command);
for (const auto& handler : handlers_) { for (const auto& handler : handlers_) {
scoped_refptr<DevToolsProtocol::Response> response = if (response.get())
handler->HandleCommand(command); break;
if (response.get()) { response = handler->HandleCommand(command);
if (!response->is_async_promise())
Respond(response->Serialize());
return;
}
} }
Respond(command->NoSuchMethodErrorResponse()->Serialize()); if (response.get()) {
if (!response->is_async_promise())
Respond(response->Serialize());
} else {
Respond(command->NoSuchMethodErrorResponse()->Serialize());
}
} }
void Respond(const std::string& message) { void Respond(const std::string& message) {
...@@ -210,6 +220,8 @@ class DevToolsHttpHandlerImpl::BrowserTarget { ...@@ -210,6 +220,8 @@ class DevToolsHttpHandlerImpl::BrowserTarget {
base::MessageLoop* const message_loop_; base::MessageLoop* const message_loop_;
net::HttpServer* const server_; net::HttpServer* const server_;
const int connection_id_; const int connection_id_;
scoped_ptr<devtools::tracing::TracingHandler> tracing_handler_;
scoped_ptr<DevToolsProtocolHandlerImpl> protocol_handler_;
std::vector<DevToolsProtocol::Handler*> handlers_; std::vector<DevToolsProtocol::Handler*> handlers_;
}; };
...@@ -690,8 +702,6 @@ void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( ...@@ -690,8 +702,6 @@ void DevToolsHttpHandlerImpl::OnWebSocketRequestUI(
if (browser_pos == 0) { if (browser_pos == 0) {
BrowserTarget* browser_target = new BrowserTarget( BrowserTarget* browser_target = new BrowserTarget(
thread_->message_loop(), server_.get(), connection_id); thread_->message_loop(), server_.get(), connection_id);
browser_target->RegisterHandler(
new DevToolsTracingHandler(DevToolsTracingHandler::Browser));
browser_target->RegisterHandler( browser_target->RegisterHandler(
new TetheringHandler(delegate_.get(), thread_->message_loop_proxy())); new TetheringHandler(delegate_.get(), thread_->message_loop_proxy()));
browser_target->RegisterHandler( browser_target->RegisterHandler(
......
...@@ -113,6 +113,7 @@ class DevToolsProtocol { ...@@ -113,6 +113,7 @@ class DevToolsProtocol {
private: private:
friend class DevToolsProtocol; friend class DevToolsProtocol;
friend class DevToolsProtocolClient;
~Notification() override; ~Notification() override;
// Takes ownership of |params|. // Takes ownership of |params|.
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/devtools/devtools_tracing_handler.h"
#include <cmath>
#include "base/bind.h"
#include "base/debug/trace_event_impl.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_http_handler_impl.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/tracing_controller.h"
namespace content {
namespace {
const char kRecordUntilFull[] = "record-until-full";
const char kRecordContinuously[] = "record-continuously";
const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
const char kEnableSampling[] = "enable-sampling";
class DevToolsTraceSinkProxy : public TracingController::TraceDataSink {
public:
explicit DevToolsTraceSinkProxy(base::WeakPtr<DevToolsTracingHandler> handler)
: tracing_handler_(handler) {}
void AddTraceChunk(const std::string& chunk) override {
if (DevToolsTracingHandler* h = tracing_handler_.get())
h->OnTraceDataCollected(chunk);
}
void Close() override {
if (DevToolsTracingHandler* h = tracing_handler_.get())
h->OnTraceComplete();
}
private:
~DevToolsTraceSinkProxy() override {}
base::WeakPtr<DevToolsTracingHandler> tracing_handler_;
};
} // namespace
const char* DevToolsTracingHandler::kDefaultCategories =
"-*,disabled-by-default-devtools.timeline*";
const double DevToolsTracingHandler::kDefaultReportingInterval = 1000.0;
const double DevToolsTracingHandler::kMinimumReportingInterval = 250.0;
DevToolsTracingHandler::DevToolsTracingHandler(
DevToolsTracingHandler::Target target)
: target_(target), is_recording_(false), weak_factory_(this) {
RegisterCommandHandler(devtools::Tracing::start::kName,
base::Bind(&DevToolsTracingHandler::OnStart,
base::Unretained(this)));
RegisterCommandHandler(devtools::Tracing::end::kName,
base::Bind(&DevToolsTracingHandler::OnEnd,
base::Unretained(this)));
RegisterCommandHandler(devtools::Tracing::getCategories::kName,
base::Bind(&DevToolsTracingHandler::OnGetCategories,
base::Unretained(this)));
}
DevToolsTracingHandler::~DevToolsTracingHandler() {
}
void DevToolsTracingHandler::OnTraceDataCollected(
const std::string& trace_fragment) {
// Hand-craft protocol notification message so we can substitute JSON
// that we already got as string as a bare object, not a quoted string.
std::string message =
base::StringPrintf("{ \"method\": \"%s\", \"params\": { \"%s\": [",
devtools::Tracing::dataCollected::kName,
devtools::Tracing::dataCollected::kParamValue);
const size_t messageSuffixSize = 10;
message.reserve(message.size() + trace_fragment.size() + messageSuffixSize);
message += trace_fragment;
message += "] } }", SendRawMessage(message);
}
void DevToolsTracingHandler::OnTraceComplete() {
SendNotification(devtools::Tracing::tracingComplete::kName, NULL);
}
base::debug::TraceOptions DevToolsTracingHandler::TraceOptionsFromString(
const std::string& options) {
std::vector<std::string> split;
std::vector<std::string>::iterator iter;
base::debug::TraceOptions ret;
base::SplitString(options, ',', &split);
for (iter = split.begin(); iter != split.end(); ++iter) {
if (*iter == kRecordUntilFull) {
ret.record_mode = base::debug::RECORD_UNTIL_FULL;
} else if (*iter == kRecordContinuously) {
ret.record_mode = base::debug::RECORD_CONTINUOUSLY;
} else if (*iter == kRecordAsMuchAsPossible) {
ret.record_mode = base::debug::RECORD_AS_MUCH_AS_POSSIBLE;
} else if (*iter == kEnableSampling) {
ret.enable_sampling = true;
}
}
return ret;
}
scoped_refptr<DevToolsProtocol::Response>
DevToolsTracingHandler::OnStart(
scoped_refptr<DevToolsProtocol::Command> command) {
if (is_recording_) {
return command->InternalErrorResponse("Tracing is already started");
}
is_recording_ = true;
std::string categories;
base::debug::TraceOptions options;
double usage_reporting_interval = 0.0;
base::DictionaryValue* params = command->params();
if (params) {
params->GetString(devtools::Tracing::start::kParamCategories, &categories);
std::string options_param;
if (params->GetString(devtools::Tracing::start::kParamOptions,
&options_param)) {
options = TraceOptionsFromString(options_param);
}
params->GetDouble(
devtools::Tracing::start::kParamBufferUsageReportingInterval,
&usage_reporting_interval);
}
SetupTimer(usage_reporting_interval);
// If inspected target is a render process Tracing.start will be handled by
// tracing agent in the renderer.
if (target_ == Renderer) {
TracingController::GetInstance()->EnableRecording(
base::debug::CategoryFilter(categories),
options,
TracingController::EnableRecordingDoneCallback());
return NULL;
}
TracingController::GetInstance()->EnableRecording(
base::debug::CategoryFilter(categories),
options,
base::Bind(&DevToolsTracingHandler::OnRecordingEnabled,
weak_factory_.GetWeakPtr(),
command));
return command->AsyncResponsePromise();
}
void DevToolsTracingHandler::SetupTimer(double usage_reporting_interval) {
if (usage_reporting_interval == 0) return;
if (usage_reporting_interval < kMinimumReportingInterval)
usage_reporting_interval = kMinimumReportingInterval;
base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
std::ceil(usage_reporting_interval));
buffer_usage_poll_timer_.reset(new base::Timer(
FROM_HERE,
interval,
base::Bind(
base::IgnoreResult(&TracingController::GetTraceBufferPercentFull),
base::Unretained(TracingController::GetInstance()),
base::Bind(&DevToolsTracingHandler::OnBufferUsage,
weak_factory_.GetWeakPtr())),
true));
buffer_usage_poll_timer_->Reset();
}
void DevToolsTracingHandler::OnRecordingEnabled(
scoped_refptr<DevToolsProtocol::Command> command) {
SendAsyncResponse(command->SuccessResponse(NULL));
}
void DevToolsTracingHandler::OnBufferUsage(float usage) {
base::DictionaryValue* params = new base::DictionaryValue();
params->SetDouble(devtools::Tracing::bufferUsage::kParamValue, usage);
SendNotification(devtools::Tracing::bufferUsage::kName, params);
}
scoped_refptr<DevToolsProtocol::Response>
DevToolsTracingHandler::OnEnd(
scoped_refptr<DevToolsProtocol::Command> command) {
if (!is_recording_) {
return command->InternalErrorResponse("Tracing is not started");
}
DisableRecording(false);
// If inspected target is a render process Tracing.end will be handled by
// tracing agent in the renderer.
if (target_ == Renderer)
return NULL;
return command->SuccessResponse(NULL);
}
void DevToolsTracingHandler::DisableRecording(bool abort) {
is_recording_ = false;
buffer_usage_poll_timer_.reset();
TracingController::GetInstance()->DisableRecording(
abort ? NULL : new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr()));
}
void DevToolsTracingHandler::OnClientDetached() {
if (is_recording_)
DisableRecording(true);
}
scoped_refptr<DevToolsProtocol::Response>
DevToolsTracingHandler::OnGetCategories(
scoped_refptr<DevToolsProtocol::Command> command) {
TracingController::GetInstance()->GetCategories(
base::Bind(&DevToolsTracingHandler::OnCategoriesReceived,
weak_factory_.GetWeakPtr(),
command));
return command->AsyncResponsePromise();
}
void DevToolsTracingHandler::OnCategoriesReceived(
scoped_refptr<DevToolsProtocol::Command> command,
const std::set<std::string>& category_set) {
base::DictionaryValue* response = new base::DictionaryValue;
base::ListValue* category_list = new base::ListValue;
for (std::set<std::string>::const_iterator it = category_set.begin();
it != category_set.end(); ++it) {
category_list->AppendString(*it);
}
response->Set(devtools::Tracing::getCategories::kResponseCategories,
category_list);
SendAsyncResponse(command->SuccessResponse(response));
}
} // namespace content
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
#include <set>
#include <string>
#include "base/debug/trace_event.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/public/browser/tracing_controller.h"
namespace base {
class RefCountedString;
class Timer;
}
namespace content {
// This class bridges DevTools remote debugging server with the trace
// infrastructure.
class DevToolsTracingHandler : public DevToolsProtocol::Handler {
public:
enum Target { Browser, Renderer };
explicit DevToolsTracingHandler(Target target);
~DevToolsTracingHandler() override;
void OnClientDetached();
void OnTraceDataCollected(const std::string& trace_fragment);
void OnTraceComplete();
private:
void OnRecordingEnabled(scoped_refptr<DevToolsProtocol::Command> command);
void OnBufferUsage(float usage);
scoped_refptr<DevToolsProtocol::Response> OnStart(
scoped_refptr<DevToolsProtocol::Command> command);
scoped_refptr<DevToolsProtocol::Response> OnEnd(
scoped_refptr<DevToolsProtocol::Command> command);
scoped_refptr<DevToolsProtocol::Response> OnGetCategories(
scoped_refptr<DevToolsProtocol::Command> command);
void OnCategoriesReceived(scoped_refptr<DevToolsProtocol::Command> command,
const std::set<std::string>& category_set);
base::debug::TraceOptions TraceOptionsFromString(const std::string& options);
void SetupTimer(double usage_reporting_interval);
void DisableRecording(bool abort);
scoped_ptr<base::Timer> buffer_usage_poll_timer_;
Target target_;
bool is_recording_;
static const char* kDefaultCategories;
static const double kDefaultReportingInterval;
static const double kMinimumReportingInterval;
base::WeakPtrFactory<DevToolsTracingHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DevToolsTracingHandler);
};
} // namespace content
#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
...@@ -7,10 +7,8 @@ ...@@ -7,10 +7,8 @@
namespace content { namespace content {
DevToolsProtocolClient::DevToolsProtocolClient( DevToolsProtocolClient::DevToolsProtocolClient(
const EventCallback& event_callback, const RawMessageCallback& raw_message_callback)
const ResponseCallback& response_callback) : raw_message_callback_(raw_message_callback) {
: event_callback_(event_callback),
response_callback_(response_callback) {
} }
DevToolsProtocolClient::~DevToolsProtocolClient() { DevToolsProtocolClient::~DevToolsProtocolClient() {
...@@ -18,12 +16,18 @@ DevToolsProtocolClient::~DevToolsProtocolClient() { ...@@ -18,12 +16,18 @@ DevToolsProtocolClient::~DevToolsProtocolClient() {
void DevToolsProtocolClient::SendNotification(const std::string& method, void DevToolsProtocolClient::SendNotification(const std::string& method,
base::DictionaryValue* params) { base::DictionaryValue* params) {
event_callback_.Run(method, params); scoped_refptr<DevToolsProtocol::Notification> notification =
new DevToolsProtocol::Notification(method, params);
SendRawMessage(notification->Serialize());
} }
void DevToolsProtocolClient::SendAsyncResponse( void DevToolsProtocolClient::SendAsyncResponse(
scoped_refptr<DevToolsProtocol::Response> response) { scoped_refptr<DevToolsProtocol::Response> response) {
response_callback_.Run(response); SendRawMessage(response->Serialize());
}
void DevToolsProtocolClient::SendRawMessage(const std::string& message) {
raw_message_callback_.Run(message);
} }
void DevToolsProtocolClient::SendInvalidParamsResponse( void DevToolsProtocolClient::SendInvalidParamsResponse(
......
...@@ -11,11 +11,8 @@ namespace content { ...@@ -11,11 +11,8 @@ namespace content {
class DevToolsProtocolClient { class DevToolsProtocolClient {
public: public:
typedef base::Callback<void(const std::string& event, typedef base::Callback<void(const std::string& message)>
base::DictionaryValue* params)> EventCallback; RawMessageCallback;
typedef base::Callback<void(scoped_refptr<DevToolsProtocol::Response>)>
ResponseCallback;
enum ResponseStatus { enum ResponseStatus {
RESPONSE_STATUS_FALLTHROUGH, RESPONSE_STATUS_FALLTHROUGH,
...@@ -53,9 +50,12 @@ class DevToolsProtocolClient { ...@@ -53,9 +50,12 @@ class DevToolsProtocolClient {
scoped_refptr<DevToolsProtocol::Command> command, scoped_refptr<DevToolsProtocol::Command> command,
const std::string& message); const std::string& message);
// Sends message to client, the caller is presumed to properly
// format the message. Do not use unless you must.
void SendRawMessage(const std::string& message);
protected: protected:
DevToolsProtocolClient(const EventCallback& event_callback, DevToolsProtocolClient(const RawMessageCallback& raw_message_callback);
const ResponseCallback& response_callback);
virtual ~DevToolsProtocolClient(); virtual ~DevToolsProtocolClient();
...@@ -65,8 +65,7 @@ class DevToolsProtocolClient { ...@@ -65,8 +65,7 @@ class DevToolsProtocolClient {
void SendAsyncResponse(scoped_refptr<DevToolsProtocol::Response> response); void SendAsyncResponse(scoped_refptr<DevToolsProtocol::Response> response);
private: private:
EventCallback event_callback_; RawMessageCallback raw_message_callback_;
ResponseCallback response_callback_;
DISALLOW_COPY_AND_ASSIGN(DevToolsProtocolClient); DISALLOW_COPY_AND_ASSIGN(DevToolsProtocolClient);
}; };
......
...@@ -120,8 +120,7 @@ tmpl_client = string.Template("""\ ...@@ -120,8 +120,7 @@ tmpl_client = string.Template("""\
namespace ${domain} { namespace ${domain} {
class Client : public DevToolsProtocolClient { class Client : public DevToolsProtocolClient {
public: public:
Client(const EventCallback& event_callback, Client(const RawMessageCallback& raw_message_callback);
const ResponseCallback& response_callback);
virtual ~Client(); virtual ~Client();
${methods}\ ${methods}\
...@@ -246,9 +245,7 @@ tmpl_register = string.Template("""\ ...@@ -246,9 +245,7 @@ tmpl_register = string.Template("""\
tmpl_init_client = string.Template("""\ tmpl_init_client = string.Template("""\
${domain}_handler_->SetClient(make_scoped_ptr( ${domain}_handler_->SetClient(make_scoped_ptr(
new devtools::${domain}::Client( new devtools::${domain}::Client(
base::Bind(&DevToolsProtocolHandlerImpl::SendNotification, base::Bind(&DevToolsProtocolHandlerImpl::SendRawMessage,
base::Unretained(this)),
base::Bind(&DevToolsProtocolHandlerImpl::SendAsyncResponse,
base::Unretained(this))))); base::Unretained(this)))));
""") """)
...@@ -358,9 +355,8 @@ void ${declared_name}::set_${param}( ...@@ -358,9 +355,8 @@ void ${declared_name}::set_${param}(
tmpl_client_impl = string.Template("""\ tmpl_client_impl = string.Template("""\
namespace ${domain} { namespace ${domain} {
Client::Client(const EventCallback& event_callback, Client::Client(const RawMessageCallback& raw_message_callback)
const ResponseCallback& response_callback) : DevToolsProtocolClient(raw_message_callback) {
: DevToolsProtocolClient(event_callback, response_callback) {
} }
Client::~Client() { Client::~Client() {
......
...@@ -4,13 +4,55 @@ ...@@ -4,13 +4,55 @@
#include "content/browser/devtools/protocol/tracing_handler.h" #include "content/browser/devtools/protocol/tracing_handler.h"
#include <cmath>
#include "base/bind.h"
#include "base/debug/trace_event_impl.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
namespace content { namespace content {
namespace devtools { namespace devtools {
namespace tracing { namespace tracing {
typedef DevToolsProtocolClient::Response Response; typedef DevToolsProtocolClient::Response Response;
TracingHandler::TracingHandler() { namespace {
const char kRecordUntilFull[] = "record-until-full";
const char kRecordContinuously[] = "record-continuously";
const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
const char kEnableSampling[] = "enable-sampling";
const double kMinimumReportingInterval = 250.0;
class DevToolsTraceSinkProxy : public TracingController::TraceDataSink {
public:
explicit DevToolsTraceSinkProxy(base::WeakPtr<TracingHandler> handler)
: tracing_handler_(handler) {}
virtual void AddTraceChunk(const std::string& chunk) override {
if (TracingHandler* h = tracing_handler_.get())
h->OnTraceDataCollected(chunk);
}
virtual void Close() override {
if (TracingHandler* h = tracing_handler_.get())
h->OnTraceComplete();
}
private:
virtual ~DevToolsTraceSinkProxy() {}
base::WeakPtr<TracingHandler> tracing_handler_;
};
} // namespace
TracingHandler::TracingHandler(TracingHandler::Target target)
: target_(target),
is_recording_(false),
weak_factory_(this) {
} }
TracingHandler::~TracingHandler() { TracingHandler::~TracingHandler() {
...@@ -20,30 +62,152 @@ void TracingHandler::SetClient(scoped_ptr<Client> client) { ...@@ -20,30 +62,152 @@ void TracingHandler::SetClient(scoped_ptr<Client> client) {
client_.swap(client); client_.swap(client);
} }
scoped_refptr<DevToolsProtocol::Response> TracingHandler::Start( void TracingHandler::Detached() {
const std::string& categories, if (is_recording_)
const std::string& options, DisableRecording(true);
const double* buffer_usage_reporting_interval, }
scoped_refptr<DevToolsProtocol::Command> command) {
return NULL; void TracingHandler::OnTraceDataCollected(const std::string& trace_fragment) {
// Hand-craft protocol notification message so we can substitute JSON
// that we already got as string as a bare object, not a quoted string.
std::string message(
"{ \"method\": \"Tracing.dataCollected\", \"params\": { \"value\": [");
const size_t messageSuffixSize = 10;
message.reserve(message.size() + trace_fragment.size() + messageSuffixSize);
message += trace_fragment;
message += "] } }";
client_->SendRawMessage(message);
}
void TracingHandler::OnTraceComplete() {
TracingCompleteParams params;
client_->TracingComplete(params);
} }
scoped_refptr<DevToolsProtocol::Response> TracingHandler::Start( scoped_refptr<DevToolsProtocol::Response> TracingHandler::Start(
const std::string* categories, const std::string* categories,
const std::string* options, const std::string* options_str,
const double* buffer_usage_reporting_interval, const double* buffer_usage_reporting_interval,
scoped_refptr<DevToolsProtocol::Command> command) { scoped_refptr<DevToolsProtocol::Command> command) {
return NULL; if (is_recording_)
return command->InternalErrorResponse("Tracing is already started");
is_recording_ = true;
base::debug::TraceOptions options = TraceOptionsFromString(options_str);
base::debug::CategoryFilter filter(categories ? *categories : std::string());
if (buffer_usage_reporting_interval)
SetupTimer(*buffer_usage_reporting_interval);
// If inspected target is a render process Tracing.start will be handled by
// tracing agent in the renderer.
if (target_ == Renderer) {
TracingController::GetInstance()->EnableRecording(
filter,
options,
TracingController::EnableRecordingDoneCallback());
return nullptr;
}
TracingController::GetInstance()->EnableRecording(
filter,
options,
base::Bind(&TracingHandler::OnRecordingEnabled,
weak_factory_.GetWeakPtr(),
command));
return command->AsyncResponsePromise();
} }
scoped_refptr<DevToolsProtocol::Response> TracingHandler::End( scoped_refptr<DevToolsProtocol::Response> TracingHandler::End(
scoped_refptr<DevToolsProtocol::Command> command) { scoped_refptr<DevToolsProtocol::Command> command) {
return NULL; if (!is_recording_)
return command->InternalErrorResponse("Tracing is not started");
DisableRecording(false);
// If inspected target is a render process Tracing.end will be handled by
// tracing agent in the renderer.
if (target_ == Renderer)
return nullptr;
return command->SuccessResponse(nullptr);
} }
scoped_refptr<DevToolsProtocol::Response> TracingHandler::GetCategories( scoped_refptr<DevToolsProtocol::Response> TracingHandler::GetCategories(
scoped_refptr<DevToolsProtocol::Command> command) { scoped_refptr<DevToolsProtocol::Command> command) {
return NULL; TracingController::GetInstance()->GetCategories(
base::Bind(&TracingHandler::OnCategoriesReceived,
weak_factory_.GetWeakPtr(),
command));
return command->AsyncResponsePromise();
}
void TracingHandler::OnRecordingEnabled(
scoped_refptr<DevToolsProtocol::Command> command) {
StartResponse response;
client_->SendStartResponse(command, response);
}
void TracingHandler::OnBufferUsage(float usage) {
BufferUsageParams params;
params.set_value(usage);
client_->BufferUsage(params);
}
void TracingHandler::OnCategoriesReceived(
scoped_refptr<DevToolsProtocol::Command> command,
const std::set<std::string>& category_set) {
std::vector<std::string> categories(category_set.begin(), category_set.end());
GetCategoriesResponse response;
response.set_categories(categories);
client_->SendGetCategoriesResponse(command, response);
}
base::debug::TraceOptions TracingHandler::TraceOptionsFromString(
const std::string* options) {
base::debug::TraceOptions ret;
if (!options)
return ret;
std::vector<std::string> split;
std::vector<std::string>::iterator iter;
base::SplitString(*options, ',', &split);
for (iter = split.begin(); iter != split.end(); ++iter) {
if (*iter == kRecordUntilFull) {
ret.record_mode = base::debug::RECORD_UNTIL_FULL;
} else if (*iter == kRecordContinuously) {
ret.record_mode = base::debug::RECORD_CONTINUOUSLY;
} else if (*iter == kRecordAsMuchAsPossible) {
ret.record_mode = base::debug::RECORD_AS_MUCH_AS_POSSIBLE;
} else if (*iter == kEnableSampling) {
ret.enable_sampling = true;
}
}
return ret;
}
void TracingHandler::SetupTimer(double usage_reporting_interval) {
if (usage_reporting_interval == 0) return;
if (usage_reporting_interval < kMinimumReportingInterval)
usage_reporting_interval = kMinimumReportingInterval;
base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
std::ceil(usage_reporting_interval));
buffer_usage_poll_timer_.reset(new base::Timer(
FROM_HERE,
interval,
base::Bind(
base::IgnoreResult(&TracingController::GetTraceBufferPercentFull),
base::Unretained(TracingController::GetInstance()),
base::Bind(&TracingHandler::OnBufferUsage,
weak_factory_.GetWeakPtr())),
true));
buffer_usage_poll_timer_->Reset();
}
void TracingHandler::DisableRecording(bool abort) {
is_recording_ = false;
buffer_usage_poll_timer_.reset();
TracingController::GetInstance()->DisableRecording(
abort ? nullptr : new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr()));
} }
} // namespace tracing } // namespace tracing
......
...@@ -5,7 +5,18 @@ ...@@ -5,7 +5,18 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_ #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_ #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_
#include <set>
#include <string>
#include "base/debug/trace_event.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h" #include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
#include "content/public/browser/tracing_controller.h"
namespace base {
class RefCountedString;
class Timer;
}
namespace content { namespace content {
namespace devtools { namespace devtools {
...@@ -15,16 +26,16 @@ class TracingHandler { ...@@ -15,16 +26,16 @@ class TracingHandler {
public: public:
typedef DevToolsProtocolClient::Response Response; typedef DevToolsProtocolClient::Response Response;
TracingHandler(); enum Target { Browser, Renderer };
explicit TracingHandler(Target target);
virtual ~TracingHandler(); virtual ~TracingHandler();
void SetClient(scoped_ptr<Client> client); void SetClient(scoped_ptr<Client> client);
void Detached();
void OnTraceDataCollected(const std::string& trace_fragment);
void OnTraceComplete();
scoped_refptr<DevToolsProtocol::Response> Start(
const std::string& categories,
const std::string& options,
const double* buffer_usage_reporting_interval,
scoped_refptr<DevToolsProtocol::Command> command);
scoped_refptr<DevToolsProtocol::Response> Start( scoped_refptr<DevToolsProtocol::Response> Start(
const std::string* categories, const std::string* categories,
const std::string* options, const std::string* options,
...@@ -33,12 +44,28 @@ class TracingHandler { ...@@ -33,12 +44,28 @@ class TracingHandler {
scoped_refptr<DevToolsProtocol::Response> End( scoped_refptr<DevToolsProtocol::Response> End(
scoped_refptr<DevToolsProtocol::Command> command); scoped_refptr<DevToolsProtocol::Command> command);
scoped_refptr<DevToolsProtocol::Response> GetCategories( scoped_refptr<DevToolsProtocol::Response> GetCategories(
scoped_refptr<DevToolsProtocol::Command> command); scoped_refptr<DevToolsProtocol::Command> command);
private: private:
void OnRecordingEnabled(scoped_refptr<DevToolsProtocol::Command> command);
void OnBufferUsage(float usage);
void OnCategoriesReceived(scoped_refptr<DevToolsProtocol::Command> command,
const std::set<std::string>& category_set);
base::debug::TraceOptions TraceOptionsFromString(const std::string* options);
void SetupTimer(double usage_reporting_interval);
void DisableRecording(bool abort);
scoped_ptr<base::Timer> buffer_usage_poll_timer_;
Target target_;
bool is_recording_;
scoped_ptr<Client> client_; scoped_ptr<Client> client_;
base::WeakPtrFactory<TracingHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TracingHandler); DISALLOW_COPY_AND_ASSIGN(TracingHandler);
}; };
......
...@@ -11,8 +11,13 @@ ...@@ -11,8 +11,13 @@
#include "content/browser/devtools/devtools_manager.h" #include "content/browser/devtools/devtools_manager.h"
#include "content/browser/devtools/devtools_protocol.h" #include "content/browser/devtools/devtools_protocol.h"
#include "content/browser/devtools/devtools_protocol_constants.h" #include "content/browser/devtools/devtools_protocol_constants.h"
#include "content/browser/devtools/devtools_tracing_handler.h"
#include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h" #include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
#include "content/browser/devtools/protocol/dom_handler.h"
#include "content/browser/devtools/protocol/input_handler.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/devtools/protocol/page_handler.h"
#include "content/browser/devtools/protocol/power_handler.h"
#include "content/browser/devtools/protocol/tracing_handler.h"
#include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h" #include "content/browser/site_instance_impl.h"
...@@ -113,21 +118,21 @@ RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(RenderViewHost* rvh) ...@@ -113,21 +118,21 @@ RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(RenderViewHost* rvh)
network_handler_(new devtools::network::NetworkHandler()), network_handler_(new devtools::network::NetworkHandler()),
page_handler_(new devtools::page::PageHandler()), page_handler_(new devtools::page::PageHandler()),
power_handler_(new devtools::power::PowerHandler()), power_handler_(new devtools::power::PowerHandler()),
tracing_handler_(new devtools::tracing::TracingHandler(
devtools::tracing::TracingHandler::Renderer)),
handler_impl_(new DevToolsProtocolHandlerImpl()), handler_impl_(new DevToolsProtocolHandlerImpl()),
tracing_handler_(
new DevToolsTracingHandler(DevToolsTracingHandler::Renderer)),
reattaching_(false) { reattaching_(false) {
handler_impl_->SetDOMHandler(dom_handler_.get()); handler_impl_->SetDOMHandler(dom_handler_.get());
handler_impl_->SetInputHandler(input_handler_.get()); handler_impl_->SetInputHandler(input_handler_.get());
handler_impl_->SetNetworkHandler(network_handler_.get()); handler_impl_->SetNetworkHandler(network_handler_.get());
handler_impl_->SetPageHandler(page_handler_.get()); handler_impl_->SetPageHandler(page_handler_.get());
handler_impl_->SetPowerHandler(power_handler_.get()); handler_impl_->SetPowerHandler(power_handler_.get());
handler_impl_->SetTracingHandler(tracing_handler_.get());
SetRenderViewHost(rvh); SetRenderViewHost(rvh);
DevToolsProtocol::Notifier notifier(base::Bind( DevToolsProtocol::Notifier notifier(base::Bind(
&RenderViewDevToolsAgentHost::DispatchOnInspectorFrontend, &RenderViewDevToolsAgentHost::DispatchOnInspectorFrontend,
base::Unretained(this))); base::Unretained(this)));
handler_impl_->SetNotifier(notifier); handler_impl_->SetNotifier(notifier);
tracing_handler_->SetNotifier(notifier);
g_instances.Get().push_back(this); g_instances.Get().push_back(this);
AddRef(); // Balanced in RenderViewHostDestroyed. AddRef(); // Balanced in RenderViewHostDestroyed.
DevToolsManager::GetInstance()->AgentHostChanged(this); DevToolsManager::GetInstance()->AgentHostChanged(this);
...@@ -158,8 +163,6 @@ void RenderViewDevToolsAgentHost::DispatchProtocolMessage( ...@@ -158,8 +163,6 @@ void RenderViewDevToolsAgentHost::DispatchProtocolMessage(
overridden_response = DevToolsProtocol::ParseResponse( overridden_response = DevToolsProtocol::ParseResponse(
overridden_response_value.get()); overridden_response_value.get());
} }
if (!overridden_response.get())
overridden_response = tracing_handler_->HandleCommand(command);
if (!overridden_response.get()) if (!overridden_response.get())
overridden_response = handler_impl_->HandleCommand(command); overridden_response = handler_impl_->HandleCommand(command);
if (overridden_response.get()) { if (overridden_response.get()) {
...@@ -212,9 +215,9 @@ void RenderViewDevToolsAgentHost::OnClientDetached() { ...@@ -212,9 +215,9 @@ void RenderViewDevToolsAgentHost::OnClientDetached() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
power_save_blocker_.reset(); power_save_blocker_.reset();
#endif #endif
tracing_handler_->OnClientDetached();
page_handler_->Detached(); page_handler_->Detached();
power_handler_->Detached(); power_handler_->Detached();
tracing_handler_->Detached();
ClientDetachedFromRenderer(); ClientDetachedFromRenderer();
// TODO(kaznacheev): Move this call back to DevToolsManager when // TODO(kaznacheev): Move this call back to DevToolsManager when
......
...@@ -11,11 +11,6 @@ ...@@ -11,11 +11,6 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "content/browser/devtools/ipc_devtools_agent_host.h" #include "content/browser/devtools/ipc_devtools_agent_host.h"
#include "content/browser/devtools/protocol/dom_handler.h"
#include "content/browser/devtools/protocol/input_handler.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/devtools/protocol/page_handler.h"
#include "content/browser/devtools/protocol/power_handler.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
...@@ -28,7 +23,6 @@ class CompositorFrameMetadata; ...@@ -28,7 +23,6 @@ class CompositorFrameMetadata;
namespace content { namespace content {
class DevToolsProtocolHandlerImpl; class DevToolsProtocolHandlerImpl;
class DevToolsTracingHandler;
class RenderViewHost; class RenderViewHost;
class RenderViewHostImpl; class RenderViewHostImpl;
...@@ -36,6 +30,15 @@ class RenderViewHostImpl; ...@@ -36,6 +30,15 @@ class RenderViewHostImpl;
class PowerSaveBlockerImpl; class PowerSaveBlockerImpl;
#endif #endif
namespace devtools {
namespace dom { class DOMHandler; }
namespace input { class InputHandler; }
namespace network { class NetworkHandler; }
namespace page { class PageHandler; }
namespace power { class PowerHandler; }
namespace tracing { class TracingHandler; }
}
class CONTENT_EXPORT RenderViewDevToolsAgentHost class CONTENT_EXPORT RenderViewDevToolsAgentHost
: public IPCDevToolsAgentHost, : public IPCDevToolsAgentHost,
private WebContentsObserver, private WebContentsObserver,
...@@ -118,8 +121,8 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost ...@@ -118,8 +121,8 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost
scoped_ptr<devtools::network::NetworkHandler> network_handler_; scoped_ptr<devtools::network::NetworkHandler> network_handler_;
scoped_ptr<devtools::page::PageHandler> page_handler_; scoped_ptr<devtools::page::PageHandler> page_handler_;
scoped_ptr<devtools::power::PowerHandler> power_handler_; scoped_ptr<devtools::power::PowerHandler> power_handler_;
scoped_ptr<devtools::tracing::TracingHandler> tracing_handler_;
scoped_ptr<DevToolsProtocolHandlerImpl> handler_impl_; scoped_ptr<DevToolsProtocolHandlerImpl> handler_impl_;
scoped_ptr<DevToolsTracingHandler> tracing_handler_;
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
scoped_ptr<PowerSaveBlockerImpl> power_save_blocker_; scoped_ptr<PowerSaveBlockerImpl> power_save_blocker_;
#endif #endif
......
...@@ -447,8 +447,6 @@ ...@@ -447,8 +447,6 @@
'browser/devtools/devtools_protocol.h', 'browser/devtools/devtools_protocol.h',
'browser/devtools/devtools_system_info_handler.cc', 'browser/devtools/devtools_system_info_handler.cc',
'browser/devtools/devtools_system_info_handler.h', 'browser/devtools/devtools_system_info_handler.h',
'browser/devtools/devtools_tracing_handler.h',
'browser/devtools/devtools_tracing_handler.cc',
'browser/devtools/forwarding_agent_host.cc', 'browser/devtools/forwarding_agent_host.cc',
'browser/devtools/forwarding_agent_host.h', 'browser/devtools/forwarding_agent_host.h',
'browser/devtools/ipc_devtools_agent_host.cc', 'browser/devtools/ipc_devtools_agent_host.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment