Chromium Code Reviews| Index: content/browser/devtools/protocol/tracing_handler.cc |
| diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc |
| index d85695731cd3410809e28c56421b338f7b71dd0d..70f9056f35827d123e55911627b39c89f46da8b7 100644 |
| --- a/content/browser/devtools/protocol/tracing_handler.cc |
| +++ b/content/browser/devtools/protocol/tracing_handler.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/bind.h" |
| #include "base/format_macros.h" |
| +#include "base/json/json_writer.h" |
| #include "base/memory/ref_counted_memory.h" |
| #include "base/strings/string_split.h" |
| #include "base/strings/stringprintf.h" |
| @@ -30,6 +31,47 @@ namespace { |
| const double kMinimumReportingInterval = 250.0; |
| +const char kRecordModeParam[] = "record_mode"; |
| + |
| +// Convert from camel case to separator + lowercase. |
| +std::string ConvertFromCamelCase(const std::string& in_str, |
| + const char separator) { |
|
caseq
2016/03/12 00:13:32
nit: nuke const from parameter passed by value.
Zhen Wang
2016/03/13 18:17:06
Done.
|
| + std::string out_str; |
| + for (const char& c : in_str) { |
| + if (isupper(c)) { |
| + out_str.push_back(separator); |
| + out_str.push_back(tolower(c)); |
| + } else { |
| + out_str.push_back(c); |
| + } |
| + } |
| + return out_str; |
| +} |
| + |
| +scoped_ptr<base::Value> ConvertDictKeyStyle(const base::Value& value) { |
| + const base::DictionaryValue* dict = nullptr; |
| + if (value.GetAsDictionary(&dict)) { |
| + scoped_ptr<base::DictionaryValue> out_dict(new base::DictionaryValue()); |
| + for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); |
| + it.Advance()) { |
| + out_dict->Set(ConvertFromCamelCase(it.key(), '_'), |
| + ConvertDictKeyStyle(it.value())); |
| + } |
| + return std::move(out_dict); |
| + } |
| + |
| + const base::ListValue* list = nullptr; |
| + if (value.GetAsList(&list)) { |
| + scoped_ptr<base::ListValue> out_list(new base::ListValue()); |
| + for (const auto& value : *list) { |
| + out_list->Append(ConvertDictKeyStyle(*value)); |
| + } |
| + return std::move(out_list); |
| + } |
| + |
| + return value.CreateDeepCopy(); |
| +} |
| + |
| class DevToolsTraceSinkProxy : public TracingController::TraceDataSink { |
| public: |
| explicit DevToolsTraceSinkProxy(base::WeakPtr<TracingHandler> handler) |
| @@ -130,23 +172,37 @@ void TracingHandler::OnTraceToStreamComplete(const std::string& stream_handle) { |
| TracingCompleteParams::Create()->set_stream(stream_handle)); |
| } |
| -Response TracingHandler::Start(DevToolsCommandId command_id, |
| - const std::string* categories, |
| - const std::string* options, |
| - const double* buffer_usage_reporting_interval, |
| - const std::string* transfer_mode) { |
| +Response TracingHandler::Start( |
| + DevToolsCommandId command_id, |
| + const std::string* categories, |
| + const std::string* options, |
| + const double* buffer_usage_reporting_interval, |
| + const std::string* transfer_mode, |
| + const scoped_ptr<base::DictionaryValue>& config) { |
| if (IsTracing()) |
| return Response::InternalError("Tracing is already started"); |
| + if (config && (categories || options)) { |
| + return Response::InternalError( |
| + "Both trace config and categories/options are specified. Only one way " |
|
caseq
2016/03/12 00:13:32
nit: "Either trace config (preferred) or categorie
Zhen Wang
2016/03/13 18:17:06
Done.
|
| + "should be used; and using trace config is preferred."); |
| + } |
| + |
| did_initiate_recording_ = true; |
| return_as_stream_ = |
| transfer_mode && *transfer_mode == start::kTransferModeReturnAsStream; |
| - base::trace_event::TraceConfig trace_config( |
| - categories ? *categories : std::string(), |
| - options ? *options : std::string()); |
| if (buffer_usage_reporting_interval) |
| SetupTimer(*buffer_usage_reporting_interval); |
| + base::trace_event::TraceConfig trace_config; |
| + if (config) { |
| + trace_config = GetTraceConfigFromDevtoolsConfig(*config); |
| + } else if (categories || options) { |
| + trace_config = base::trace_event::TraceConfig( |
| + categories ? *categories : std::string(), |
| + options ? *options : std::string()); |
| + } |
| + |
| // If inspected target is a render process Tracing.start will be handled by |
| // tracing agent in the renderer. |
| TracingController::GetInstance()->StartTracing( |
| @@ -281,6 +337,21 @@ bool TracingHandler::IsStartupTracingActive() { |
| TracingController::GetInstance()->IsTracing(); |
| } |
| +// static |
| +base::trace_event::TraceConfig TracingHandler::GetTraceConfigFromDevtoolsConfig( |
| + const base::DictionaryValue& devtools_config) { |
| + scoped_ptr<base::Value> value = ConvertDictKeyStyle(devtools_config); |
| + DCHECK(value && value->IsType(base::Value::TYPE_DICTIONARY)); |
| + scoped_ptr<base::DictionaryValue> tracing_dict( |
| + static_cast<base::DictionaryValue*>(value.release())); |
| + |
| + std::string mode; |
| + if (tracing_dict->GetString(kRecordModeParam, &mode)) |
| + tracing_dict->SetString(kRecordModeParam, ConvertFromCamelCase(mode, '-')); |
| + |
| + return base::trace_event::TraceConfig(*tracing_dict); |
| +} |
| + |
| } // namespace tracing |
| } // namespace devtools |
| } // namespace content |