blob: 0657b8e48d2a9c83cc2d171630eddcefc77913b4 [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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
3// found in the LICENSE file.
4
5#include "content/browser/devtools/devtools_tracing_handler.h"
6
7#include "base/bind.h"
8#include "base/callback.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00009#include "base/location.h"
10#include "base/strings/string_split.h"
Ben Murdoch558790d2013-07-30 15:19:42 +010011#include "base/strings/stringprintf.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000012#include "base/values.h"
13#include "content/browser/devtools/devtools_http_handler_impl.h"
Ben Murdochca12bfa2013-07-23 11:17:05 +010014#include "content/browser/devtools/devtools_protocol_constants.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000015#include "content/public/browser/trace_controller.h"
16#include "content/public/browser/trace_subscriber.h"
17
18namespace content {
19
20namespace {
21
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000022const char kRecordUntilFull[] = "record-until-full";
23const char kRecordContinuously[] = "record-continuously";
Ben Murdocheb525c52013-07-10 11:40:50 +010024const char kEnableSampling[] = "enable-sampling";
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000025
26} // namespace
27
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000028DevToolsTracingHandler::DevToolsTracingHandler()
29 : is_running_(false) {
Ben Murdochca12bfa2013-07-23 11:17:05 +010030 RegisterCommandHandler(devtools::Tracing::start::kName,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000031 base::Bind(&DevToolsTracingHandler::OnStart,
32 base::Unretained(this)));
Ben Murdochca12bfa2013-07-23 11:17:05 +010033 RegisterCommandHandler(devtools::Tracing::end::kName,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000034 base::Bind(&DevToolsTracingHandler::OnEnd,
35 base::Unretained(this)));
36}
37
38DevToolsTracingHandler::~DevToolsTracingHandler() {
39}
40
41void DevToolsTracingHandler::OnEndTracingComplete() {
42 is_running_ = false;
Ben Murdochca12bfa2013-07-23 11:17:05 +010043 SendNotification(devtools::Tracing::tracingComplete::kName, NULL);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000044}
45
46void DevToolsTracingHandler::OnTraceDataCollected(
47 const scoped_refptr<base::RefCountedString>& trace_fragment) {
48 if (is_running_) {
Ben Murdoch558790d2013-07-30 15:19:42 +010049 // Hand-craft protocol notification message so we can substitute JSON
50 // that we already got as string as a bare object, not a quoted string.
51 std::string message = base::StringPrintf(
52 "{ \"method\": \"%s\", \"params\": { \"%s\": [ %s ] } }",
53 devtools::Tracing::dataCollected::kName,
54 devtools::Tracing::dataCollected::kValue,
55 trace_fragment->data().c_str());
56 SendRawMessage(message);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000057 }
58}
59
60// Note, if you add more options here you also need to update:
61// base/debug/trace_event_impl:TraceOptionsFromString
62base::debug::TraceLog::Options DevToolsTracingHandler::TraceOptionsFromString(
63 const std::string& options) {
64 std::vector<std::string> split;
65 std::vector<std::string>::iterator iter;
66 int ret = 0;
67
68 base::SplitString(options, ',', &split);
69 for (iter = split.begin(); iter != split.end(); ++iter) {
70 if (*iter == kRecordUntilFull) {
71 ret |= base::debug::TraceLog::RECORD_UNTIL_FULL;
72 } else if (*iter == kRecordContinuously) {
73 ret |= base::debug::TraceLog::RECORD_CONTINUOUSLY;
Ben Murdocheb525c52013-07-10 11:40:50 +010074 } else if (*iter == kEnableSampling) {
75 ret |= base::debug::TraceLog::ENABLE_SAMPLING;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000076 }
77 }
78 if (!(ret & base::debug::TraceLog::RECORD_UNTIL_FULL) &&
79 !(ret & base::debug::TraceLog::RECORD_CONTINUOUSLY))
80 ret |= base::debug::TraceLog::RECORD_UNTIL_FULL;
81
82 return static_cast<base::debug::TraceLog::Options>(ret);
83}
84
Ben Murdochbb1529c2013-08-08 10:24:53 +010085scoped_refptr<DevToolsProtocol::Response>
86DevToolsTracingHandler::OnStart(
87 scoped_refptr<DevToolsProtocol::Command> command) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000088 std::string categories;
89 base::DictionaryValue* params = command->params();
Ben Murdochca12bfa2013-07-23 11:17:05 +010090 if (params)
91 params->GetString(devtools::Tracing::start::kCategories, &categories);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000092
93 base::debug::TraceLog::Options options =
94 base::debug::TraceLog::RECORD_UNTIL_FULL;
Ben Murdochca12bfa2013-07-23 11:17:05 +010095 if (params && params->HasKey(devtools::Tracing::start::kTraceOptions)) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000096 std::string options_param;
Ben Murdochca12bfa2013-07-23 11:17:05 +010097 params->GetString(devtools::Tracing::start::kTraceOptions, &options_param);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000098 options = TraceOptionsFromString(options_param);
99 }
100
101 TraceController::GetInstance()->BeginTracing(this, categories, options);
102 is_running_ = true;
103 return command->SuccessResponse(NULL);
104}
105
Ben Murdochbb1529c2013-08-08 10:24:53 +0100106scoped_refptr<DevToolsProtocol::Response>
107DevToolsTracingHandler::OnEnd(
108 scoped_refptr<DevToolsProtocol::Command> command) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000109 TraceController::GetInstance()->EndTracingAsync(this);
110 return command->SuccessResponse(NULL);
111}
112
113} // namespace content